mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-23 10:00:25 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60faa9dd9b | ||
|
|
75f8f86f86 | ||
|
|
0ee1307e75 | ||
|
|
f0c38305b5 | ||
|
|
e07dda6991 | ||
|
|
b10ce9a426 | ||
|
|
2ac2800ecb | ||
|
|
e59200a7de | ||
|
|
a7902a8837 | ||
|
|
615726cc75 | ||
|
|
839abf6076 | ||
|
|
c7c8d4580d | ||
|
|
2cc47e10f9 | ||
|
|
8fc5dacebf | ||
|
|
cb23f3bb70 | ||
|
|
d7350d8629 | ||
|
|
ac6b5ef1f7 | ||
|
|
7fdd26c59e | ||
|
|
fad555308b | ||
|
|
969255c48e | ||
|
|
433305617c | ||
|
|
5418d84c7e | ||
|
|
cca37e3dfe | ||
|
|
0e9d83ee14 | ||
|
|
ecbf7f6caa | ||
|
|
5a3638fa68 | ||
|
|
111088b540 | ||
|
|
ba1703ebf0 | ||
|
|
825df20a72 | ||
|
|
0a42fd79d2 | ||
|
|
e50a041c12 | ||
|
|
ce0e9fe77e | ||
|
|
5105dcce04 | ||
|
|
58b4a9a676 | ||
|
|
1146c834fb | ||
|
|
9068264132 | ||
|
|
59ac8ea437 | ||
|
|
afafacaeec | ||
|
|
baf451d2a2 | ||
|
|
d588012168 | ||
|
|
a3ed25cb2e | ||
|
|
c399f45841 | ||
|
|
6a6eeae4ee | ||
|
|
65f36505d1 | ||
|
|
b852980842 | ||
|
|
d351ced78b | ||
|
|
4cd45c63c4 | ||
|
|
de16a72aed | ||
|
|
4b29c63fc9 | ||
|
|
770e832592 | ||
|
|
14f9acdb57 | ||
|
|
573a6f5bd5 | ||
|
|
8c64b7aa89 | ||
|
|
8d49f8935c | ||
|
|
ff8ec63e95 | ||
|
|
771ee1b5a9 | ||
|
|
096692fec8 | ||
|
|
d29454b44d | ||
|
|
30a1ccb2e2 | ||
|
|
ea1b411cc0 | ||
|
|
7794ee8aea | ||
|
|
99a9022b53 | ||
|
|
1255964e6b | ||
|
|
37de859bee | ||
|
|
990aa5cdb2 | ||
|
|
befcedcf58 | ||
|
|
eeb697570d | ||
|
|
6410567e9a | ||
|
|
bde7242cc7 | ||
|
|
e8aad97975 | ||
|
|
0662359776 | ||
|
|
5568d160ab | ||
|
|
defa297a56 | ||
|
|
782c37c4fe | ||
|
|
6f03c88ad5 | ||
|
|
3ec980c8ec | ||
|
|
c0a50eb2ff | ||
|
|
f73e4b6f22 | ||
|
|
096972827e | ||
|
|
08c040d4ea | ||
|
|
6d8b6b5f29 | ||
|
|
410f1c0ed8 | ||
|
|
cb73cfd57b | ||
|
|
8cb8a7f370 | ||
|
|
8c893acfff | ||
|
|
e453d1fa17 | ||
|
|
a7301ed7b6 | ||
|
|
42ebfd5394 | ||
|
|
cdf2f84b14 | ||
|
|
2592aeab8b | ||
|
|
34d4225ea0 | ||
|
|
17dcb4b00e | ||
|
|
eb1d096539 | ||
|
|
05c74655be | ||
|
|
3e0e0ba3b1 | ||
|
|
f90b6cd18c | ||
|
|
f0ecfcb708 | ||
|
|
177702d027 | ||
|
|
64429232f8 | ||
|
|
d6b7fecb69 | ||
|
|
51a0ee56aa | ||
|
|
2ed369568c | ||
|
|
e5b7e16d1a | ||
|
|
4a9f676d5d | ||
|
|
0e0da3d767 | ||
|
|
343ce4a6a7 | ||
|
|
df8b854cb7 | ||
|
|
831dc770d8 | ||
|
|
8a9285c64f | ||
|
|
7e4e06b09d | ||
|
|
96748b3fbc | ||
|
|
f1325048e9 | ||
|
|
deee21eb68 | ||
|
|
2f43e5c5ea | ||
|
|
4766067edb | ||
|
|
bc54f22639 | ||
|
|
20c8c87e79 | ||
|
|
3a5dcd6a3c | ||
|
|
a5ba02c2bb | ||
|
|
e1554efc08 | ||
|
|
9d652dd41b | ||
|
|
22eadf2c08 | ||
|
|
d3f1b62208 | ||
|
|
affc28ab79 | ||
|
|
41be7f44ab | ||
|
|
646c1f0f16 | ||
|
|
3cea097b48 | ||
|
|
786d72575e | ||
|
|
6d9a794aaf | ||
|
|
9e69df1e94 | ||
|
|
72d4bb0206 | ||
|
|
f68e06a949 | ||
|
|
f4da539d95 | ||
|
|
17af75a9bb | ||
|
|
dcbb39d640 | ||
|
|
d0ba1df4e0 | ||
|
|
2b92869683 | ||
|
|
379a4b0ce4 | ||
|
|
d4c7d4a7e1 | ||
|
|
dcac24c9e2 | ||
|
|
753589d840 | ||
|
|
382903c9e1 | ||
|
|
f29fec0b31 | ||
|
|
f9dc37d60a | ||
|
|
c5e48c67bb | ||
|
|
cc62ebcffc | ||
|
|
0f36504959 | ||
|
|
1fb8e25209 | ||
|
|
260876b1a2 | ||
|
|
e4fc074f09 | ||
|
|
7899e5161e | ||
|
|
95603b1142 | ||
|
|
bf8e0eb812 | ||
|
|
0c04ffc1e8 | ||
|
|
bd86acf118 | ||
|
|
6caa16444e | ||
|
|
94d4cbeb82 | ||
|
|
b31f4bc00c | ||
|
|
cf0808e119 | ||
|
|
92333909fd | ||
|
|
9c68af92be | ||
|
|
bc5d7f5e93 | ||
|
|
f2ba9a88be | ||
|
|
81b711364e | ||
|
|
554e0c7fac | ||
|
|
bd2c1c387b | ||
|
|
f19edac9ca | ||
|
|
1698f6d1bf | ||
|
|
2c3180813a | ||
|
|
a262fe5d9d | ||
|
|
a69249ee22 | ||
|
|
393c2a81d1 | ||
|
|
3a6be342ce | ||
|
|
6616bfe53e | ||
|
|
bafe60f48f | ||
|
|
e306c415f0 | ||
|
|
56a8c8d48d | ||
|
|
421f1d39a4 | ||
|
|
7c655944a5 | ||
|
|
0a27f37dc0 | ||
|
|
4695932ea1 | ||
|
|
7fe7a12167 | ||
|
|
f9487b0ba3 | ||
|
|
7c5c34741c | ||
|
|
d09459f4bf | ||
|
|
c0c6598151 | ||
|
|
f52fcc6f0e | ||
|
|
2e9ef64bd2 | ||
|
|
ff3ee39830 | ||
|
|
abd757f3bc | ||
|
|
c741591a36 | ||
|
|
78c481d725 | ||
|
|
b2ece37819 | ||
|
|
a557b29ecf | ||
|
|
1184843318 | ||
|
|
dd1f8bd92a | ||
|
|
220c82954c | ||
|
|
8879bacb1d | ||
|
|
5824022745 | ||
|
|
3ecb5bd06a | ||
|
|
7de31a776b | ||
|
|
503320d13f | ||
|
|
bd263c5d22 | ||
|
|
b0201aef5d | ||
|
|
31014808c8 | ||
|
|
0906124867 | ||
|
|
43bb5ce653 | ||
|
|
7e66483b1a | ||
|
|
f96b606a1a | ||
|
|
30d26c3e44 | ||
|
|
57e450a745 | ||
|
|
24297bf396 | ||
|
|
481cd760a9 | ||
|
|
6d6043775e | ||
|
|
bb97ec8933 | ||
|
|
dc028b87e4 | ||
|
|
0d1b7a9c8a | ||
|
|
a6e602af1d | ||
|
|
04a6012e5d | ||
|
|
0f7691c722 | ||
|
|
f01a0a17c1 | ||
|
|
b291ab92b6 | ||
|
|
fb4bf4fcaa | ||
|
|
98816156d7 | ||
|
|
92bfb4c426 | ||
|
|
cac883c4a0 | ||
|
|
5a4fb90c96 | ||
|
|
c4f9eb65ae | ||
|
|
9f5557b33c | ||
|
|
4d876fdf5d | ||
|
|
978666c946 | ||
|
|
9b9fa696e8 | ||
|
|
088b22073c | ||
|
|
4f9831faa4 | ||
|
|
3373caa939 | ||
|
|
dc1be17b2a | ||
|
|
64a3b04181 | ||
|
|
57e1920b9c | ||
|
|
ddb6236eb9 | ||
|
|
4e4af590e5 | ||
|
|
a249f6b29b | ||
|
|
7787729b24 | ||
|
|
45c8c704af | ||
|
|
31fde1ad94 | ||
|
|
bfb0fbd656 | ||
|
|
8afb7457c2 | ||
|
|
0ae1c8f771 | ||
|
|
6ff046ae29 | ||
|
|
6f9f845bb2 | ||
|
|
00033c3a70 | ||
|
|
acf71610df | ||
|
|
86e9ae343a | ||
|
|
9bbd546d4c | ||
|
|
31f2573b28 | ||
|
|
4d7fcb77c2 | ||
|
|
da02a8c73a | ||
|
|
dd0b4505a6 | ||
|
|
eaff26216a | ||
|
|
e850dd1963 | ||
|
|
cf61ae0332 | ||
|
|
5cffe3fb05 | ||
|
|
b996918d3b | ||
|
|
4a9f9a45c2 | ||
|
|
3a75772005 | ||
|
|
c196e31c6c | ||
|
|
60ceff5ae0 | ||
|
|
34a4a0c892 | ||
|
|
2a3c42d47b | ||
|
|
0b1f796e0a | ||
|
|
766d4d23bf | ||
|
|
6860a1e992 | ||
|
|
70c628d759 | ||
|
|
6eff8bc273 | ||
|
|
0b1e8cdbf3 | ||
|
|
6f58b34f87 | ||
|
|
adf081ba3c | ||
|
|
6d4a9fde3f | ||
|
|
5a5cc4ea17 | ||
|
|
69df583508 | ||
|
|
18506d9932 | ||
|
|
f076e7609e | ||
|
|
0b0d053044 | ||
|
|
ce7dfdd986 | ||
|
|
50e589f27c | ||
|
|
e904dafa38 | ||
|
|
6a210fa212 | ||
|
|
ae33155ed3 | ||
|
|
d3d44001ef | ||
|
|
c2aec1ff57 | ||
|
|
d5f08fe950 | ||
|
|
bdf4df9fd0 | ||
|
|
7481b0939e | ||
|
|
346e59f18a | ||
|
|
4725aad3e9 | ||
|
|
59fd1bfdb2 | ||
|
|
7546d91580 | ||
|
|
c81df27470 | ||
|
|
bd6232d913 | ||
|
|
7f6b73e60f | ||
|
|
e3562f9e56 | ||
|
|
40141c55de | ||
|
|
a6f6cbd9b5 | ||
|
|
e9ffb4b9b5 | ||
|
|
1f0418a9cd | ||
|
|
e76837b42c | ||
|
|
87be7068c9 | ||
|
|
49cb5af265 | ||
|
|
f0fe93429f | ||
|
|
c2461f1219 | ||
|
|
f82b6b75ff | ||
|
|
3486b590eb | ||
|
|
5730af672c | ||
|
|
4daff05142 | ||
|
|
e930768c67 | ||
|
|
6f03e388bf | ||
|
|
9b340e03c5 | ||
|
|
d5b61fe5cc | ||
|
|
5b46e48a17 | ||
|
|
585221f7cc | ||
|
|
77eb7a5259 | ||
|
|
77bfc4b599 | ||
|
|
95bbfba1b8 | ||
|
|
844a50dfd8 | ||
|
|
cd2fea5262 | ||
|
|
79d8b4bb0b | ||
|
|
531825545d | ||
|
|
daab5b9238 | ||
|
|
ce59e5e6a7 | ||
|
|
ea0c4b5060 | ||
|
|
9b9908b660 | ||
|
|
101894be37 | ||
|
|
3e314251f2 | ||
|
|
1995c75006 | ||
|
|
ff85986c44 | ||
|
|
9131297d43 | ||
|
|
301f3091d1 | ||
|
|
b59bd449d4 | ||
|
|
5e510ef0e2 | ||
|
|
c7c3fcd0e0 | ||
|
|
a5532ad67b | ||
|
|
290cd5501c | ||
|
|
8d1b1410cd | ||
|
|
df9aead324 | ||
|
|
851fd240d3 | ||
|
|
2da03c89d1 | ||
|
|
89cd12d2c1 | ||
|
|
e21d2a0adb | ||
|
|
2fad64b08a | ||
|
|
97fd147fbe | ||
|
|
0f01f6af11 | ||
|
|
a9892c88be | ||
|
|
f1d76a042d | ||
|
|
77d4e5d051 | ||
|
|
7041acfd51 | ||
|
|
b27bfbe189 | ||
|
|
1c10e7a63d | ||
|
|
0a7c324d48 | ||
|
|
c81d247fbb | ||
|
|
82294b7b2e | ||
|
|
d80f55d5bf | ||
|
|
7930cda277 | ||
|
|
7870db7202 | ||
|
|
407538fd85 | ||
|
|
1a293420c0 | ||
|
|
1e94cdd8ca | ||
|
|
7a2311d6e6 | ||
|
|
e686937ae9 | ||
|
|
8dca8988fe | ||
|
|
c890ac5944 | ||
|
|
56e52fda80 | ||
|
|
e7786b3192 | ||
|
|
4cc3a84e98 | ||
|
|
6e0b048ae7 | ||
|
|
115786798d | ||
|
|
376db9e9e6 | ||
|
|
8abdb80e85 | ||
|
|
656f212608 | ||
|
|
60e07cc4ff | ||
|
|
e132c0a015 | ||
|
|
8e63526f2a | ||
|
|
a5b7c774c1 | ||
|
|
130a5bb8c4 | ||
|
|
3802dd9984 | ||
|
|
7d37397222 | ||
|
|
932454d7b2 | ||
|
|
5d2e6c46aa | ||
|
|
38089195be | ||
|
|
85a6c1d145 | ||
|
|
85d034b7fb | ||
|
|
82b5468fb4 | ||
|
|
89759c44af | ||
|
|
6f66a1d1c3 | ||
|
|
d4bac185f6 | ||
|
|
658bba576e | ||
|
|
31f3c25b18 | ||
|
|
4a1f149051 | ||
|
|
c55a78b8b4 | ||
|
|
3dbf957304 | ||
|
|
8f98f49f1b | ||
|
|
0a8322960b | ||
|
|
63d73c6f86 | ||
|
|
f8cbbe78a2 | ||
|
|
2bb09503c6 | ||
|
|
ba313decd1 | ||
|
|
0d6847c76c | ||
|
|
7b721c7849 | ||
|
|
1fb073fd6a | ||
|
|
484272aed4 | ||
|
|
57422ce793 | ||
|
|
ba855cd064 | ||
|
|
39ac9f7de6 | ||
|
|
4368035da4 | ||
|
|
4391912ee3 | ||
|
|
fc17536f55 | ||
|
|
3bae4338c3 | ||
|
|
f59bdd6b9f | ||
|
|
03f3676b00 | ||
|
|
e0d7079745 | ||
|
|
b7f421481f | ||
|
|
3506cb3f94 | ||
|
|
7280acee42 | ||
|
|
d757fa6306 | ||
|
|
475fc92629 | ||
|
|
f24303dd78 | ||
|
|
180a20f561 | ||
|
|
2e5ca5b9dc | ||
|
|
decee20fd8 | ||
|
|
3d9a60c415 | ||
|
|
a4a7002867 | ||
|
|
96c9a014e6 | ||
|
|
11b4471be9 | ||
|
|
17aea205f7 | ||
|
|
739f54ed87 | ||
|
|
01be5bee72 | ||
|
|
dfcf0da710 | ||
|
|
f47fb87d1b | ||
|
|
bd639ba936 | ||
|
|
e784e62a4e | ||
|
|
e4425dcbf8 | ||
|
|
0dcffe8771 | ||
|
|
2b27f6c452 | ||
|
|
3ba3c728bc | ||
|
|
7193198af2 | ||
|
|
6691afd160 | ||
|
|
59fb220197 | ||
|
|
ff7651d4c8 | ||
|
|
b02abb1f18 | ||
|
|
9f42da4686 | ||
|
|
58e3056374 | ||
|
|
3142865fef | ||
|
|
06e3497a57 | ||
|
|
e49833737d | ||
|
|
7eedc5fef8 | ||
|
|
c442942022 | ||
|
|
2c2652ed1d | ||
|
|
97bcc07aab | ||
|
|
001704b22e | ||
|
|
f1d9cd93ce | ||
|
|
49aa2aa858 | ||
|
|
6274d9a1e9 | ||
|
|
5fa9d91401 | ||
|
|
9acb803ffe | ||
|
|
105924bca3 | ||
|
|
5f12be2037 | ||
|
|
13931c40cb | ||
|
|
ada5d614c5 | ||
|
|
7323d51219 | ||
|
|
f5071f2667 | ||
|
|
0ca0a81644 | ||
|
|
e1bd69b467 | ||
|
|
b17494519e | ||
|
|
13555f505c | ||
|
|
2a65f53084 | ||
|
|
71fe83083e | ||
|
|
0ddb5c859f | ||
|
|
f7b12d5108 | ||
|
|
baa8f4334b | ||
|
|
24a211b190 | ||
|
|
6e82f254b7 | ||
|
|
fbfedcf8d6 | ||
|
|
5b06a0c2a4 | ||
|
|
f3204b0845 | ||
|
|
334314a137 | ||
|
|
8ecc8122b8 | ||
|
|
eb9a119dfe | ||
|
|
313ece62f7 | ||
|
|
5799bcceb2 | ||
|
|
61e7571388 | ||
|
|
6cfd99e40a | ||
|
|
b3bdd9d563 | ||
|
|
5bec3d8471 | ||
|
|
711e46ecfb | ||
|
|
ddd127352f | ||
|
|
784fd825bb | ||
|
|
673a42242d | ||
|
|
3317345d92 | ||
|
|
7958ba38d8 | ||
|
|
2dd7e0c03f | ||
|
|
b94f021567 | ||
|
|
cf50c5b535 | ||
|
|
1b71169565 | ||
|
|
30f2b9d5ed | ||
|
|
999d6a449b | ||
|
|
a65aa2a0d0 | ||
|
|
36fc0b6e8a | ||
|
|
f97362cdb1 | ||
|
|
6398484459 | ||
|
|
07e8c6feaa | ||
|
|
faf351a496 | ||
|
|
cd9315852e | ||
|
|
8c8487231a | ||
|
|
65ebdf0862 | ||
|
|
9704362501 | ||
|
|
f0e87cd85a | ||
|
|
f6e6bf1d6b | ||
|
|
4b4e8f806b | ||
|
|
4141cee13f | ||
|
|
b2ee346f68 | ||
|
|
2220f1ff05 | ||
|
|
7ba48dd666 | ||
|
|
2a48e2fd27 | ||
|
|
63a24c4448 | ||
|
|
787df3362b | ||
|
|
5ad0f60ee3 | ||
|
|
d42f92361a | ||
|
|
0693db3ef5 | ||
|
|
fafb0e2793 | ||
|
|
0a4819d172 | ||
|
|
ee03f32a3e | ||
|
|
f4e01917a2 | ||
|
|
eed9b36c9f | ||
|
|
055192c2a8 | ||
|
|
cca39108dc | ||
|
|
b1bbd5e366 | ||
|
|
afb718f01f | ||
|
|
653b4e0ab7 | ||
|
|
c3d228a9f5 | ||
|
|
15e10caca0 | ||
|
|
46efa85441 | ||
|
|
bb42456653 | ||
|
|
38bf80aa52 | ||
|
|
c5c2aa5348 | ||
|
|
1e67aeb667 | ||
|
|
9ac7bccba5 | ||
|
|
610b82cfb7 | ||
|
|
c8144539d0 | ||
|
|
60f83597ee | ||
|
|
46c0c6085d | ||
|
|
36d4c4af61 | ||
|
|
7406c3dc23 | ||
|
|
24bb15ce29 | ||
|
|
f3ad05dc85 | ||
|
|
bbae3223cb | ||
|
|
8cedb24d31 | ||
|
|
528414dfef | ||
|
|
6e1c58e343 | ||
|
|
002e935193 | ||
|
|
e26d7d346a | ||
|
|
5d917f2578 | ||
|
|
8aecff1879 | ||
|
|
718672119e | ||
|
|
6ec7482662 | ||
|
|
5f3ea7c634 | ||
|
|
1c813a59d0 | ||
|
|
a66236fc3d | ||
|
|
ef9b7022df | ||
|
|
ad7efce855 | ||
|
|
78a9990c3a | ||
|
|
422b9eb6c0 | ||
|
|
703eb271f9 | ||
|
|
2aca32c44a | ||
|
|
56c30bddb1 | ||
|
|
1179b50ad1 | ||
|
|
6ad44441a6 | ||
|
|
2455c09475 | ||
|
|
7a1e07e72a | ||
|
|
aa8e95885a | ||
|
|
54bae94ad9 | ||
|
|
98b7e01069 | ||
|
|
12c7707bc3 | ||
|
|
a8a2c7e345 | ||
|
|
6c7542ec0c | ||
|
|
5ec56cbe77 | ||
|
|
6b79770783 | ||
|
|
e125a83625 | ||
|
|
d05b47e996 | ||
|
|
e1093d0c0c | ||
|
|
25690648d6 | ||
|
|
5c3c4f6288 | ||
|
|
9dec5e9e54 | ||
|
|
ae1fa808da | ||
|
|
ed6839dc99 | ||
|
|
e95d71da0d | ||
|
|
128c8f3c06 | ||
|
|
04f61a1af7 | ||
|
|
974e86b698 | ||
|
|
12c03384b2 | ||
|
|
99ba912d7b | ||
|
|
7607932216 | ||
|
|
acc9c241a3 | ||
|
|
5f5055f4fc | ||
|
|
fc3749e008 | ||
|
|
155734370c | ||
|
|
1095e3d509 | ||
|
|
f7bfa47f2e | ||
|
|
9f6ef14ea1 | ||
|
|
15de08556e | ||
|
|
e7dfa8fcfe | ||
|
|
7a67dc5dfd | ||
|
|
7eb8ef42b7 | ||
|
|
c9c7a4beed | ||
|
|
bcf3aad1b2 | ||
|
|
ad75363028 | ||
|
|
f4ec3939a5 | ||
|
|
aead97d29d | ||
|
|
f468305a2c | ||
|
|
a962f469eb | ||
|
|
63e025cc02 | ||
|
|
b2d332f152 | ||
|
|
e160cf240c | ||
|
|
19a4f70c44 | ||
|
|
dcca3901d5 | ||
|
|
0ee4ffbfbc | ||
|
|
776bc781cd | ||
|
|
b1bb79e19f | ||
|
|
76c69b7bd1 | ||
|
|
15a25a412f | ||
|
|
b511d89dcc | ||
|
|
9512ae7aeb | ||
|
|
5db086e470 | ||
|
|
d63f668291 | ||
|
|
35c72a9570 | ||
|
|
b29f62ddd4 | ||
|
|
525dc17573 | ||
|
|
4d8ed24833 | ||
|
|
aa15d996e0 | ||
|
|
0ec846945d | ||
|
|
03ff158e76 | ||
|
|
b3371b2d63 | ||
|
|
ed64d03bf5 | ||
|
|
3d936dede1 | ||
|
|
33e9c5b1ea | ||
|
|
078c90bbc9 | ||
|
|
2caf2cad5a | ||
|
|
5dec21dd43 | ||
|
|
36aa9bd802 | ||
|
|
bed2f15a72 | ||
|
|
f949f1e88d | ||
|
|
8af202bd5f | ||
|
|
67556a88f1 | ||
|
|
4f8573784d | ||
|
|
c5a46be23e | ||
|
|
47a3c0bf55 | ||
|
|
e8d2a2a461 | ||
|
|
7b72a3fba4 | ||
|
|
dda79e7f27 | ||
|
|
9a104566ba | ||
|
|
b4d8982341 | ||
|
|
5ea3fc28f7 | ||
|
|
0bbf39660e | ||
|
|
791f38762b | ||
|
|
c296b909c7 | ||
|
|
9c7a54f8fc | ||
|
|
4289eab72b | ||
|
|
7b0dbc7445 | ||
|
|
02db904336 | ||
|
|
55140fee3a | ||
|
|
96d881a1f1 | ||
|
|
260a95c05e | ||
|
|
99d633587f | ||
|
|
cf2f0256a2 | ||
|
|
dae8e8dfbd | ||
|
|
6d2d35e82d | ||
|
|
5e23a6b640 | ||
|
|
f2ec502dc2 | ||
|
|
be04f31256 | ||
|
|
85dd881c97 | ||
|
|
0ef2dccd90 | ||
|
|
000ec39c81 | ||
|
|
3160c6ee0b | ||
|
|
9da403e534 | ||
|
|
f19c3408e1 | ||
|
|
38c0e09e8a | ||
|
|
2be4f7cdaf | ||
|
|
cd48272fbb | ||
|
|
a5a146bb02 | ||
|
|
c901bcf321 | ||
|
|
8f3142e532 | ||
|
|
88438d6db4 | ||
|
|
7348734070 | ||
|
|
a99a4a3a2b | ||
|
|
7bc8c3ab5b | ||
|
|
2a58fbdd22 | ||
|
|
d102f5a88a | ||
|
|
8227f7125b | ||
|
|
673535dc08 | ||
|
|
9750489d07 | ||
|
|
53c6224ed0 | ||
|
|
f84794acbe | ||
|
|
9e535e509a | ||
|
|
489210424f | ||
|
|
394abbdb6f | ||
|
|
5fdeb92429 | ||
|
|
11cc39e41b | ||
|
|
b3d5851fdc | ||
|
|
5c25839bab | ||
|
|
fbd314b447 | ||
|
|
86888a32d4 | ||
|
|
37c2d22b10 | ||
|
|
19758ef75d | ||
|
|
519ccc90f7 | ||
|
|
b592d15d1f | ||
|
|
78d70a892c | ||
|
|
dbcf4c1800 | ||
|
|
cbd4630b3c | ||
|
|
92fdfe3f35 | ||
|
|
8b563e5232 | ||
|
|
aeb4875fa5 | ||
|
|
5ebb9c61f9 | ||
|
|
c0e5b8fe15 | ||
|
|
f852efea7d | ||
|
|
664ae905bb | ||
|
|
243b0fd109 | ||
|
|
43b0944403 | ||
|
|
ecc3c9f7b4 | ||
|
|
296249b203 | ||
|
|
8c1145bb9f | ||
|
|
7ad18a68f8 | ||
|
|
99ba396c24 | ||
|
|
f88e9960f2 | ||
|
|
b53466ea0d | ||
|
|
2afda6a470 | ||
|
|
acc8081ef2 | ||
|
|
7433677ead | ||
|
|
4132f7efe6 | ||
|
|
56e0f5797e | ||
|
|
54c142ce78 | ||
|
|
c106aeef2b | ||
|
|
66bde85807 | ||
|
|
08363511a7 | ||
|
|
d6b93b712c | ||
|
|
a85d6d0f4c | ||
|
|
2c1f341099 | ||
|
|
52bb709ca5 | ||
|
|
24ea958748 | ||
|
|
b6143ce54c | ||
|
|
463ea7d34b | ||
|
|
1015302a7f | ||
|
|
c73f5917f8 | ||
|
|
9315cfa488 | ||
|
|
0f58b5780a | ||
|
|
edd5f07d48 | ||
|
|
a7f258f2b1 | ||
|
|
65dcb72cba | ||
|
|
4885c536c8 | ||
|
|
b6204dab78 | ||
|
|
5b5951483a | ||
|
|
194d53569f | ||
|
|
5e8b54be7e | ||
|
|
8dc91e413e | ||
|
|
57cf513b39 | ||
|
|
bb1326860b | ||
|
|
136838e40b | ||
|
|
30d9483504 | ||
|
|
05d3c50866 | ||
|
|
d5e93d863a | ||
|
|
d3f93aae15 | ||
|
|
963e4aa7ec | ||
|
|
5a250ea247 | ||
|
|
bc8d8aafc0 | ||
|
|
f67ab4ec7f | ||
|
|
cf9af20fbd | ||
|
|
3be2a3eb79 | ||
|
|
7dfd18f4fb | ||
|
|
05fc960338 | ||
|
|
21d41ce14b | ||
|
|
1562ba3f97 | ||
|
|
2798e73707 | ||
|
|
89aeee4269 | ||
|
|
d50302fa41 | ||
|
|
8efae54450 | ||
|
|
2785a72789 | ||
|
|
ac55a44761 | ||
|
|
42f1a286a8 | ||
|
|
241fa5d485 | ||
|
|
e87f9c5710 | ||
|
|
c95a6ee3fd | ||
|
|
10b954cb1a | ||
|
|
cf7914b6f8 | ||
|
|
e58e048f00 | ||
|
|
b92cd8a64f | ||
|
|
317aead26d | ||
|
|
e93780c66c | ||
|
|
af8990acf0 | ||
|
|
e41dcf03ad | ||
|
|
0209e8f782 | ||
|
|
50d935171e | ||
|
|
86ee9089e9 | ||
|
|
ba6fe112bb | ||
|
|
15860a7795 | ||
|
|
78b3ad8075 | ||
|
|
f61bda330e | ||
|
|
5c9fceea2c | ||
|
|
32cceebc47 | ||
|
|
9d921df733 | ||
|
|
428f8c183d | ||
|
|
45aae54b32 | ||
|
|
d9ca73bc4c | ||
|
|
c2e24da9bd | ||
|
|
c6ae5ed551 | ||
|
|
0f86a5ee8a | ||
|
|
803e53869b | ||
|
|
a4fc25cca8 | ||
|
|
28fbcf5628 | ||
|
|
3ea73febe4 | ||
|
|
9eb3b3e1c3 | ||
|
|
48e1c39320 | ||
|
|
fe38c7650f | ||
|
|
5e2f5010f8 | ||
|
|
efce4703ca | ||
|
|
94ab4a5ac5 | ||
|
|
58321be1ce |
No files matched your search
+10
-1
@@ -11,7 +11,7 @@ if(TARGET_GAME_TYPE)
|
||||
endif()
|
||||
|
||||
|
||||
set(TARGET_BASE_GAME "main")
|
||||
set(TARGET_BASE_GAME "./")
|
||||
set(CMAKE_DEBUG_POSTFIX "-dbg")
|
||||
|
||||
if(MSVC)
|
||||
@@ -22,6 +22,13 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
add_compile_options(-Wno-pointer-bool-conversion)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
# Add this option on gcc to prevent functions from having the STB_GNU_UNIQUE binding
|
||||
# Otherwise, it would prevent libraries from being unloaded
|
||||
# which will cause undefined behavior and crashes due to memory corruption
|
||||
add_compile_options(-fno-gnu-unique)
|
||||
endif()
|
||||
|
||||
if(DEBUG_MEMORY)
|
||||
add_definitions(-D_DEBUG_MEM)
|
||||
endif()
|
||||
@@ -47,6 +54,7 @@ ENDIF()
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
add_definitions(-D_DEBUG)
|
||||
|
||||
# NOTE: The following may mess up function importation
|
||||
#if(UNIX)
|
||||
# # Enable all exports so all functions name can be seen during executable crash
|
||||
# set(CMAKE_ENABLE_EXPORTS ON)
|
||||
@@ -73,6 +81,7 @@ target_compile_features(omohaaded PUBLIC c_variadic_macros)
|
||||
target_link_libraries(omohaaded PRIVATE omohserver)
|
||||
target_link_libraries(omohaaded PRIVATE syslib)
|
||||
target_link_libraries(omohaaded PRIVATE qcommon qcommon_standalone)
|
||||
|
||||
# Gamespy dependency
|
||||
target_include_directories(omohaaded PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server")
|
||||
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
|
||||
|
||||
@@ -17,25 +17,49 @@
|
||||
|
||||
## Current State
|
||||
|
||||
OpenMoHAA is still under development. The single-player campaign is not yet functional due to AI not being fully implemented, and due to the script engine having a few issues. But the `training` map can be played from start to end. The current focus is on multiplayer.
|
||||
OpenMoHAA is still under development. The single-player campaign is not yet functional due to AI not being fully stable. But the `training` map can be played from start to end. The current focus is on multiplayer.
|
||||
|
||||
## Intro
|
||||
|
||||
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault**. It has always been a dream in the community to provide patches and security fixes for the game. Thanks to the ioquake3 project, F.A.K.K SDK and other quality tools, OpenMoHAA has already reached more than half of its goal: to create an open-source version of MoH:AA (based on version 2.40) that is fully compatible with the original game (in terms of protocol, assets, and scripts).
|
||||
|
||||
## Running
|
||||
|
||||
Backup existing mohaa files, **cgamex86.dll** and **gamex86.dll** (set their extension to **.bak**)
|
||||
Ensure that you download the binaries compatible with your platform.
|
||||
|
||||
### Requirements
|
||||
|
||||
You may need to install Microsoft Visual C++ 2015/2017/2019/2022 Redistributable from https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
|
||||
|
||||
### Client
|
||||
|
||||
a) extract archive to your MOHAA installation directory.
|
||||
|
||||
-or-
|
||||
|
||||
b) Copy all pak*.pk3 files and the sound/ directory from your **MOHAA/main** directory into openmohaa's 'main' directory.
|
||||
b) extract archive somewhere on your hard drive, create a shortcut to openmohaa (or omohaaded), and set the start directory to your MOHAA installation directory.
|
||||
|
||||
If you have problems running the game :
|
||||
### Server
|
||||
|
||||
You may need to install Microsoft Visual C++ 2015/2017/2019/2022 Redistributable from
|
||||
Extract the archive to your MOHAA server installation directory. Then proceed like you would do with mohaa server:
|
||||
|
||||
https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
|
||||
- `.\omohaaded.exe +exec server.cfg` on Windows
|
||||
- `./omohaaded +exec server.cfg` on Linux
|
||||
|
||||
You can now start a local OpenMOHAA server or play on a server.
|
||||
Only `omohaaded*` and `game*` binaries are required for the server version, other binaries can be omitted.
|
||||
|
||||
### Config file
|
||||
|
||||
The config file can be found in different locations depending on the platform:
|
||||
|
||||
- `%APPDATA%\openmohaa\<game_name>\configs\omconfig.cfg` on Windows
|
||||
- `~/.openmohaa/<game_name>/configs/omconfig.cfg` on Linux
|
||||
|
||||
This has two advantages:
|
||||
- On a multi-user system, each user will have their own configuration file
|
||||
- It doesn't overwrite the existing MOHAA configuration in the MOHAA installation directory.
|
||||
|
||||
### Game selection
|
||||
|
||||
**Medal of Honor: Allied Assault Spearhead** and **Medal of Honor: Allied Assault Breakthrough** are supported in OpenMoHAA using the `com_target_game` variable. To play an expansion, append the following command-line arguments to the executable:
|
||||
|
||||
@@ -43,9 +67,11 @@ You can now start a local OpenMOHAA server or play on a server.
|
||||
- `+set com_target_game 2` for Breakthrough (mohaab/mohtt)
|
||||
|
||||
On Windows, you can create a shortcut to OpenMoHAA with these command-line arguments.
|
||||
The default value of `com_target_game` is 0 for the base game.
|
||||
The default value of `com_target_game` is 0 for the base game (main).
|
||||
|
||||
With `com_target_game`, OpenMoHAA will support the network protocol accordingly
|
||||
With `com_target_game`, OpenMoHAA will support the network protocol accordingly.
|
||||
|
||||
You can now start a local OpenMOHAA server or play on a server.
|
||||
|
||||
### Playing with bots
|
||||
|
||||
@@ -57,7 +83,7 @@ This feature is a great way to test the gameplay and mods.
|
||||
|
||||
### Server
|
||||
|
||||
The server version can be built successfully, but some features are not functional. For example, the Actor and Vehicle systems are almost fully implemented, but they are not yet stable. This means that they may not work as expected and could cause crashes.
|
||||
The server version can be built successfully, but some features are not functional. For example, the Actor system is almost fully implemented, but it is not yet stable. This means that Actor may not work as expected and could cause crashes.
|
||||
|
||||
Overall, the server and the fgame components are almost fully implemented, but they may not be completely stable. There could be some minor bugs (and rare crashes), but the game should be playable.
|
||||
|
||||
@@ -76,7 +102,7 @@ The current operational status for each component is as follow:
|
||||
| Model/TIKI/Skeletor | x | | | | | | |
|
||||
| Renderer | | x | | | | | Missing ghost, marks, sphere lights, sky portal, sun flare, swipe |
|
||||
| Server | | x | | | | | Probably a few bugs remaining |
|
||||
| Server module (fgame) | | x | | | | | Actor, vehicle, and few gameplay bugs |
|
||||
| Server module (fgame) | | x | | | | | Actor, and few gameplay bugs |
|
||||
| UI | | | x | | | | Has core features only (menu, widgets, console, hud, urc loading) |
|
||||
|
||||
## Compiling
|
||||
@@ -85,30 +111,36 @@ OpenMoHAA supports any architecture, thanks to the CMake build system and cross-
|
||||
|
||||
The following tools are required for all platforms:
|
||||
- CMake >= 3.5
|
||||
- Flex and Bison
|
||||
- Flex (>= 2.6.4) and Bison (>= 3.5.1)
|
||||
- A C++11 compiler is also required.
|
||||
|
||||
The installation directory can be set to the MOHAA directory.
|
||||
|
||||
By default, the build will produce both the client and dedicated server versions. The client build can be excluded by appending `-DBUILD_NO_CLIENT=1` to the CMake command-line arguments. Using this parameter will result in only the server portion being built.
|
||||
By default, the build will produce both the client and dedicated server versions. The client can be omitted from the build by appending `-DBUILD_NO_CLIENT=1` to the CMake command-line arguments. Using this parameter will result in only the server portion being built.
|
||||
|
||||
### Linux
|
||||
|
||||
These are the tools required on Linux :
|
||||
- Clang >= 3.3 or GCC >= 4.8.1
|
||||
- Clang >= 3.3 or GCC >= 4.8.5
|
||||
- libsdl2-dev
|
||||
|
||||
**clang-3.5** and **gcc-4.8.5** should work (tested on Ubuntu 16.04). Use the latest possible version of those compilers.
|
||||
**clang-3.5** and **gcc-4.8.5** should work (tested on Ubuntu 16.04), but the latest version should be used.
|
||||
|
||||
SDL2 library is required (libsdl2-dev).
|
||||
Ubuntu 20.04 is the minimum version required to fully compile the project successfully.
|
||||
|
||||
1 line install command with latest clang version : `sudo apt-get install -y ninja-build cmake make clang-15 lld-15 flex bison libsdl2-dev`
|
||||
1 line install command with clang:
|
||||
```sh
|
||||
sudo apt-get install -y cmake ninja-build clang lld flex bison libsdl2-dev
|
||||
```
|
||||
|
||||
Example with **CMake**, **clang-15** and **ninja-build** installed:
|
||||
Example with **CMake** and **ninja-build** installed:
|
||||
```sh
|
||||
mkdir .cmake && cd .cmake
|
||||
cmake -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 -G Ninja
|
||||
cmake -G Ninja ../
|
||||
```
|
||||
|
||||
Other compilers can be specified by appending `-DCMAKE_C_COMPILER=/path/to/compiler -DCMAKE_CXX_COMPILER=path/to/compiler` to the CMake command-line.
|
||||
|
||||
### Windows
|
||||
|
||||
Visual Studio (2019 or 2022) is generally preferred.
|
||||
@@ -119,12 +151,48 @@ Append `-DFLEX_EXECUTABLE=...\win_flex.exe -DBISON_EXECUTABLE=...\win_bison.exe`
|
||||
|
||||
## Screenshots
|
||||
|
||||
| | |
|
||||
|-------------------------------------------------------------------------------|----------------------------------------------------------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
| | |
|
||||
|-----------------------------------------------------------------------------------|----------------------------------------------------------------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
*More screenshots [here](docs/images)*
|
||||
|
||||
## Features
|
||||
|
||||
### Features added and not present in MOH:AA
|
||||
|
||||
#### Server-side
|
||||
|
||||
- Bots
|
||||
- Spectate players in first-person
|
||||
- Demo recording
|
||||
- More script commands for mods
|
||||
- Non-PVS optimization
|
||||
|
||||
##### Non-PVS optimization
|
||||
|
||||
For each client, the server optimizes by only sending them information about other players that they can see. Clients won't see other players they can't see.
|
||||
|
||||
Enable this feature with `set sv_netoptimize 2`.
|
||||
|
||||
#### Client-side and server-side
|
||||
|
||||
- Security fixes and features from ioquake3
|
||||
- IPv6 support (from ioquake3)
|
||||
|
||||
### Objectives / planned features
|
||||
|
||||
This is a non-exhaustive list of objectives and planned features.
|
||||
|
||||
#### Server-side
|
||||
|
||||
- 100% compatibility with mohaa content
|
||||
- More feature for mods
|
||||
- Anticheat
|
||||
- Stats system
|
||||
- Multiple roles/abilities for server admins to reduce password-stealing
|
||||
|
||||
## Third party
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ set(SOURCES_SHARED
|
||||
"../script/scriptvariable.cpp"
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SOURCES_BG "../fgame/bg_misc.cpp" "../fgame/bg_pmove.cpp" "../fgame/bg_slidemove.cpp")
|
||||
file(GLOB_RECURSE SOURCES_BG "../fgame/bg_misc.cpp" "../fgame/bg_pmove.cpp" "../fgame/bg_slidemove.cpp" "../fgame/bg_voteoptions.cpp")
|
||||
file(GLOB_RECURSE SOURCES_CGAME "./*.c" "./*.cpp")
|
||||
|
||||
add_library(cgame SHARED ${SOURCES_CGAME} ${SOURCES_BG})
|
||||
|
||||
+142
-10
@@ -22,43 +22,175 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_archive.h"
|
||||
#include "cg_commands.h"
|
||||
#include "memarchiver.h"
|
||||
#include "../qcommon/tiki.h"
|
||||
|
||||
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
archiver.SetBaseTime(svsTime);
|
||||
commandManager.ArchiveToMemory(archiver);
|
||||
CG_ArchiveVSSGlobals(archiver);
|
||||
}
|
||||
|
||||
void CG_SaveStateToBuffer(void** out, int svsTime)
|
||||
size_t CG_SaveStateToBuffer(void** out, int svsTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
MemArchiver archiver;
|
||||
size_t size;
|
||||
|
||||
archiver.SetupForWriting(0x200000);
|
||||
CG_ArchiveStuff(archiver, svsTime);
|
||||
size = archiver.BufferSize();
|
||||
if (size && out) {
|
||||
*out = archiver.ConfiscateBuffer();
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void CG_LoadStateToBuffer(void* state, int size, int svsTime)
|
||||
qboolean CG_LoadStateToBuffer(void* state, size_t size, int svsTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
MemArchiver archiver;
|
||||
|
||||
archiver.SetupForReading((byte*)state, size);
|
||||
CG_ArchiveStuff(archiver, svsTime);
|
||||
|
||||
return archiver.FinishedReading();
|
||||
}
|
||||
|
||||
void CG_ArchiveStringContainer(MemArchiver& archiver, Container<str>* container)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
int num;
|
||||
int i;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
str tmp;
|
||||
|
||||
archiver.ArchiveInteger(&num);
|
||||
container->ClearObjectList();
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
container->AddObject(tmp);
|
||||
}
|
||||
} else {
|
||||
num = container->NumObjects();
|
||||
archiver.ArchiveInteger(&num);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
str& tmp = container->ObjectAt(i + 1);
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveTikiPointer(MemArchiver& archiver, dtiki_t** pTiki)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
str tmp;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
if (tmp.length()) {
|
||||
*pTiki = cgi.R_Model_GetHandle(cgi.R_RegisterModel(tmp.c_str()));
|
||||
} else {
|
||||
*pTiki = NULL;
|
||||
}
|
||||
} else {
|
||||
if (*pTiki) {
|
||||
tmp = (*pTiki)->name;
|
||||
}
|
||||
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
str tmp;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
if (tmp.length()) {
|
||||
*handle = cgi.R_RegisterModel(tmp.c_str());
|
||||
} else {
|
||||
*handle = NULL;
|
||||
}
|
||||
} else {
|
||||
if (*handle) {
|
||||
tmp = cgi.R_GetModelName(*handle);
|
||||
} else {
|
||||
tmp = "";
|
||||
}
|
||||
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
str tmp;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
if (tmp.length()) {
|
||||
*handle = cgi.R_RegisterShader(tmp.c_str());
|
||||
} else {
|
||||
*handle = NULL;
|
||||
}
|
||||
} else {
|
||||
if (*handle) {
|
||||
tmp = cgi.R_GetShaderName(*handle);
|
||||
} else {
|
||||
tmp = "";
|
||||
}
|
||||
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
archiver.ArchiveRaw(&ref->reType, sizeof(ref->reType));
|
||||
archiver.ArchiveInteger(&ref->renderfx);
|
||||
|
||||
CG_ArchiveModelHandle(archiver, &ref->hModel);
|
||||
CG_ArchiveModelHandle(archiver, &ref->hOldModel);
|
||||
|
||||
archiver.ArchiveVec3(ref->lightingOrigin);
|
||||
archiver.ArchiveInteger(&ref->parentEntity);
|
||||
archiver.ArchiveVec3(ref->axis[0]);
|
||||
archiver.ArchiveVec3(ref->axis[1]);
|
||||
archiver.ArchiveVec3(ref->axis[2]);
|
||||
archiver.ArchiveBoolean(&ref->nonNormalizedAxes);
|
||||
archiver.ArchiveVec3(ref->origin);
|
||||
archiver.ArchiveRaw(ref->frameInfo, 192);
|
||||
archiver.ArchiveFloat(&ref->actionWeight);
|
||||
archiver.ArchiveShort(&ref->wasframe);
|
||||
archiver.ArchiveFloat(&ref->scale);
|
||||
archiver.ArchiveVec3(ref->oldorigin);
|
||||
archiver.ArchiveInteger(&ref->skinNum);
|
||||
|
||||
CG_ArchiveShaderHandle(archiver, &ref->customShader);
|
||||
archiver.ArchiveRaw(ref->shaderRGBA, 4);
|
||||
archiver.ArchiveFloat(ref->shaderTexCoord);
|
||||
archiver.ArchiveFloat(&ref->shaderTexCoord[1]);
|
||||
archiver.ArchiveFloat(&ref->shaderTime);
|
||||
|
||||
archiver.ArchiveInteger(&ref->entityNumber);
|
||||
archiver.ArchiveRaw(ref->surfaces, 32);
|
||||
archiver.ArchiveFloat(ref->shader_data);
|
||||
archiver.ArchiveFloat(&ref->shader_data[1]);
|
||||
|
||||
ref->bone_tag = NULL;
|
||||
ref->bone_quat = NULL;
|
||||
ref->of = NULL;
|
||||
ref->nf = NULL;
|
||||
|
||||
CG_ArchiveTikiPointer(archiver, &ref->tiki);
|
||||
|
||||
archiver.ArchiveInteger(&ref->bonestart);
|
||||
archiver.ArchiveInteger(&ref->morphstart);
|
||||
archiver.ArchiveBoolean(&ref->hasMorph);
|
||||
archiver.ArchiveFloat(&ref->radius);
|
||||
archiver.ArchiveFloat(&ref->rotation);
|
||||
}
|
||||
@@ -30,15 +30,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "../qcommon/container.h"
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
class MemArchiver {
|
||||
|
||||
};
|
||||
class MemArchiver;
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void CG_SaveStateToBuffer(void** out, int svsTime);
|
||||
void CG_LoadStateToBuffer(void* state, int size, int svsTime);
|
||||
size_t CG_SaveStateToBuffer(void** out, int svsTime);
|
||||
qboolean CG_LoadStateToBuffer(void* state, size_t size, int svsTime);
|
||||
|
||||
#ifdef __cplusplus
|
||||
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime);
|
||||
|
||||
+1143
-306
File diff suppressed because it is too large.
Load diff
+94
-19
@@ -116,6 +116,7 @@ TIKI file, similar to ScriptMaster in the server game dll.
|
||||
|
||||
class spawnthing_t;
|
||||
class specialeffect_t;
|
||||
class MemArchiver;
|
||||
|
||||
typedef enum {
|
||||
NOT_RANDOM,
|
||||
@@ -181,6 +182,9 @@ public:
|
||||
float decal_orientation;
|
||||
float decal_radius;
|
||||
float spin_rotation;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline cg_common_data::cg_common_data()
|
||||
@@ -249,6 +253,9 @@ public:
|
||||
spawnthing_t *m_spawnthing;
|
||||
|
||||
void (*touchfcn)(ctempmodel_t *ct, trace_t *trace);
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline ctempmodel_t::ctempmodel_t()
|
||||
@@ -315,8 +322,44 @@ public:
|
||||
int lastPhysicsTime;
|
||||
int lastLightingTime;
|
||||
qboolean lastValid;
|
||||
|
||||
public:
|
||||
cvssource_t();
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline cvssource_t::cvssource_t()
|
||||
: next(NULL)
|
||||
, prev(NULL)
|
||||
, stnext(NULL)
|
||||
, stindex(0)
|
||||
, lastRadius(0)
|
||||
, lastDensity(0)
|
||||
, lastColor {0}
|
||||
, lastLighting {0}
|
||||
, newRadius(0)
|
||||
, newDensity(0)
|
||||
, newColor {0}
|
||||
, newLighting {0}
|
||||
, ooRadius(0)
|
||||
, startAlpha(0)
|
||||
, roll(0)
|
||||
, lifeTime(0)
|
||||
, collisionmask(0)
|
||||
, parent(0)
|
||||
, flags(0)
|
||||
, flags2(0)
|
||||
, smokeType(0)
|
||||
, typeInfo(0)
|
||||
, fadeMult(0)
|
||||
, scaleMult(0)
|
||||
, lastPhysicsTime(0)
|
||||
, lastLightingTime(0)
|
||||
, lastValid(qfalse)
|
||||
{}
|
||||
|
||||
class cvssourcestate_t
|
||||
{
|
||||
public:
|
||||
@@ -387,6 +430,9 @@ public:
|
||||
protected:
|
||||
qboolean usedNumbers[256];
|
||||
virtual void RemoveEntity(int entnum);
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline enttracker_t::enttracker_t()
|
||||
@@ -437,6 +483,9 @@ public:
|
||||
Vector oldorigin;
|
||||
qboolean active;
|
||||
qboolean lerp_emitter;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
// emitterthing_t is used to keep track of the last time and emitter was updated
|
||||
@@ -452,6 +501,9 @@ public:
|
||||
emittertime_t *GetEmitTime(int entnum);
|
||||
virtual void RemoveEntity(int entnum);
|
||||
qboolean startoff;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline void emitterthing_t::RemoveEntity(int entnum)
|
||||
@@ -510,18 +562,23 @@ public:
|
||||
int entity_number;
|
||||
int command_number;
|
||||
int last_command_time;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
// This class is used for keeping track of the last time an entity executed a
|
||||
// particular command. A command number must be assigned externally by the user
|
||||
class commandthing_t : public enttracker_t
|
||||
{
|
||||
Container<commandtime_t *> m_commandtimes; // A list of entity numbers and the last time they
|
||||
// executed a command
|
||||
Container<commandtime_t> m_commandtimes; // A list of entity numbers and the last time they
|
||||
// executed a command
|
||||
|
||||
public:
|
||||
commandtime_t *GetLastCommandTime(int entnum, int commandnum);
|
||||
virtual void RemoveEntity(int entnum);
|
||||
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline void commandthing_t::RemoveEntity(int entnum)
|
||||
@@ -532,7 +589,7 @@ inline void commandthing_t::RemoveEntity(int entnum)
|
||||
count = m_commandtimes.NumObjects();
|
||||
|
||||
for (num = count; num >= 1; num--) {
|
||||
ct = m_commandtimes.ObjectAt(num);
|
||||
ct = &m_commandtimes.ObjectAt(num);
|
||||
if (ct->entity_number == entnum) {
|
||||
m_commandtimes.RemoveObjectAt(num);
|
||||
}
|
||||
@@ -543,28 +600,27 @@ inline void commandthing_t::RemoveEntity(int entnum)
|
||||
|
||||
inline commandtime_t *commandthing_t::GetLastCommandTime(int entnum, int commandnum)
|
||||
{
|
||||
int num, count;
|
||||
commandtime_t *ct;
|
||||
int num, count;
|
||||
|
||||
// Search for this entity number
|
||||
count = m_commandtimes.NumObjects();
|
||||
|
||||
for (num = 1; num <= count; num++) {
|
||||
ct = m_commandtimes.ObjectAt(num);
|
||||
commandtime_t *ct = &m_commandtimes.ObjectAt(num);
|
||||
if ((ct->entity_number == entnum) && (ct->command_number == commandnum)) {
|
||||
return ct;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new entry if we didn't find it
|
||||
ct = new commandtime_t;
|
||||
ct->entity_number = entnum;
|
||||
ct->command_number = commandnum;
|
||||
ct->last_command_time = 0;
|
||||
commandtime_t ct;
|
||||
ct.entity_number = entnum;
|
||||
ct.command_number = commandnum;
|
||||
ct.last_command_time = 0;
|
||||
|
||||
m_commandtimes.AddObject(ct);
|
||||
|
||||
return ct;
|
||||
return &m_commandtimes.ObjectAt(m_commandtimes.NumObjects());
|
||||
}
|
||||
|
||||
class spawnthing_t : public emitterthing_t
|
||||
@@ -625,6 +681,9 @@ public:
|
||||
void (*touchfcn)(ctempmodel_t *ct, trace_t *trace);
|
||||
str GetModel(void);
|
||||
void SetModel(str model);
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline void spawnthing_t::SetModel(str model)
|
||||
@@ -824,8 +883,8 @@ private:
|
||||
void SetClampVel(Event *ev);
|
||||
void SetClampVelAxis(Event *ev);
|
||||
ctempmodel_t *AllocateTempModel(void);
|
||||
qboolean TempModelPhysics(ctempmodel_t *p, float ftime, float time2, float scale);
|
||||
qboolean TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float time2, float scale);
|
||||
qboolean TempModelPhysics(ctempmodel_t *p, float ftime, float scale);
|
||||
qboolean TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float scale);
|
||||
qboolean LerpTempModel(refEntity_t *newEnt, ctempmodel_t *p, float frac);
|
||||
void SpawnEffect(int count, int timealive);
|
||||
void SpawnTempModel(int count);
|
||||
@@ -871,13 +930,13 @@ public:
|
||||
void UpdateEmitter(dtiki_t *tiki, vec3_t axis[3], int entity_number, int parent_number, Vector entity_origin);
|
||||
void UpdateBeam(dtiki_t *tiki, int entity_number, spawnthing_t *beamthing);
|
||||
void PlaySound(
|
||||
str sound_name,
|
||||
str sound_name,
|
||||
const vec3_t origin = NULL,
|
||||
int channel = CHAN_AUTO,
|
||||
float volume = -1,
|
||||
float min_distance = -1,
|
||||
float pitch = -1,
|
||||
int argstype = 0
|
||||
int channel = CHAN_AUTO,
|
||||
float volume = -1,
|
||||
float min_distance = -1,
|
||||
float pitch = -1,
|
||||
int argstype = 0
|
||||
);
|
||||
|
||||
spawnthing_t *InitializeSpawnthing(spawnthing_t *ep);
|
||||
@@ -891,6 +950,7 @@ public:
|
||||
void InitializeEmitters(void);
|
||||
void RemoveClientEntity(int number, dtiki_t *tiki, centity_t *cent, ctempmodel_t *p = NULL);
|
||||
void ClearSwipes(void);
|
||||
void FreeSpawnthing(spawnthing_t *sp);
|
||||
void ResetTempModels(void);
|
||||
void SpawnTempModel(int count, spawnthing_t *sp);
|
||||
|
||||
@@ -921,6 +981,21 @@ public:
|
||||
void ResetTreadMarkSources(Event *ev);
|
||||
void InitializeRainCvars();
|
||||
void InitializeBeams();
|
||||
|
||||
//
|
||||
// archive stuff
|
||||
//
|
||||
int IdForTempModel(const ctempmodel_t *model);
|
||||
ctempmodel_t *TempModelForId(int id);
|
||||
int IdForSpawnThing(const spawnthing_t *sp);
|
||||
spawnthing_t *SpawnThingForId(int id);
|
||||
int IdForVssSource(const cvssource_t *source);
|
||||
cvssource_t *VssSourceForId(int id);
|
||||
|
||||
void ArchiveTempModelPointerToMemory(MemArchiver& archiver, ctempmodel_t **model);
|
||||
void ArchiveSpawnThingPointerToMemory(MemArchiver& archiver, spawnthing_t **sp);
|
||||
void ArchiveVssSourcePointerToMemory(MemArchiver& archiver, cvssource_t **source);
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
class EmitterLoader : public Listener
|
||||
|
||||
+169
-6
@@ -323,8 +323,12 @@ static void CG_DrawPauseIcon()
|
||||
}
|
||||
w = cgi.R_GetShaderWidth(handle);
|
||||
h = cgi.R_GetShaderHeight(handle);
|
||||
x = w / 4;
|
||||
y = cgs.glconfig.vidHeight - (1.25f * h);
|
||||
if (cg.snap && cg.snap->ps.blend[3] > 0) {
|
||||
y = cgs.glconfig.vidHeight * 0.45f - h / 2.f;
|
||||
} else {
|
||||
y = cgs.glconfig.vidHeight * 0.75f - h / 2.f;
|
||||
}
|
||||
x = (cgs.glconfig.vidWidth - w) / 2.f;
|
||||
|
||||
cgi.R_SetColor(colorWhite);
|
||||
cgi.R_DrawStretchPic(x, y, w, h, 0, 0, 1, 1, handle);
|
||||
@@ -682,11 +686,11 @@ void CG_DrawObjectives()
|
||||
|
||||
iTotalNumLines = 0;
|
||||
for (i = CS_OBJECTIVES; i < CS_OBJECTIVES + MAX_OBJECTIVES; ++i) {
|
||||
CG_ProcessConfigString(i);
|
||||
CG_ProcessConfigString(i, qfalse);
|
||||
}
|
||||
|
||||
iCurrentObjective = atoi(CG_ConfigString(CS_CURRENT_OBJECTIVE));
|
||||
fTimeDelta = cg.ObjectivesAlphaTime - cg.time;
|
||||
iCurrentObjective = atoi(CG_ConfigString(CS_CURRENT_OBJECTIVE));
|
||||
fTimeDelta = cg.ObjectivesAlphaTime - cg.time;
|
||||
cg.ObjectivesCurrentAlpha = cg.ObjectivesDesiredAlpha;
|
||||
if (fTimeDelta > 0) {
|
||||
cg.ObjectivesCurrentAlpha =
|
||||
@@ -1083,7 +1087,7 @@ void CG_DrawSpectatorView_ver_15()
|
||||
iClientNum = cg.snap->ps.stats[STAT_INFOCLIENT];
|
||||
sprintf(buf, "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]);
|
||||
|
||||
hShader = 0;
|
||||
hShader = 0;
|
||||
color[0] = 0.5;
|
||||
color[1] = 1.0;
|
||||
color[2] = 0.5;
|
||||
@@ -1165,6 +1169,163 @@ void CG_DrawSpectatorView()
|
||||
}
|
||||
}
|
||||
|
||||
void CG_DrawCrosshair()
|
||||
{
|
||||
centity_t *friendEnt;
|
||||
qhandle_t shader;
|
||||
vec3_t forward;
|
||||
vec3_t end;
|
||||
vec3_t mins, maxs;
|
||||
trace_t trace;
|
||||
float x, y;
|
||||
float width, height;
|
||||
|
||||
shader = NULL;
|
||||
|
||||
if (!cg_hud->integer || !ui_crosshair->integer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cg.snap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cg.snap->ps.pm_flags & PMF_NO_LEAN) || (cg.snap->ps.pm_flags & PMF_INTERMISSION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cg.snap->ps.stats[STAT_CROSSHAIR]
|
||||
&& (!cg.snap->ps.stats[STAT_INZOOM] || cg.snap->ps.stats[STAT_INZOOM] > 30)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgs.gametype != GT_FFA) {
|
||||
AngleVectorsLeft(cg.refdefViewAngles, forward, NULL, NULL);
|
||||
|
||||
VectorMA(cg.refdef.vieworg, 8192, forward, end);
|
||||
VectorClear(mins);
|
||||
VectorClear(maxs);
|
||||
|
||||
CG_Trace(&trace, cg.refdef.vieworg, mins, maxs, end, 9999, MASK_SOLID, qfalse, qtrue, "CG_DrawCrosshair");
|
||||
|
||||
// ENTITYNUM_WORLD check added in OPM
|
||||
if ((trace.entityNum != ENTITYNUM_NONE && trace.entityNum != ENTITYNUM_WORLD)
|
||||
&& trace.entityNum != cg.snap->ps.clientNum) {
|
||||
int myFlags;
|
||||
|
||||
friendEnt = &cg_entities[trace.entityNum];
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
myFlags = cg_entities[cg.snap->ps.clientNum].currentState.eFlags & EF_ANY_TEAM;
|
||||
} else {
|
||||
// the player will always be considered as an allied
|
||||
// in single-player
|
||||
myFlags = EF_ALLIES;
|
||||
}
|
||||
|
||||
if (((myFlags & EF_ALLIES) && (friendEnt->currentState.eFlags & EF_ALLIES))
|
||||
|| ((myFlags & EF_AXIS) && (friendEnt->currentState.eFlags & EF_AXIS))) {
|
||||
// friend
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair_friend->string);
|
||||
}
|
||||
} else {
|
||||
// enemy
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// FFA
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
|
||||
if (shader) {
|
||||
width = cgi.R_GetShaderWidth(shader);
|
||||
height = cgi.R_GetShaderHeight(shader);
|
||||
x = (cgs.glconfig.vidWidth - width) * 0.5f;
|
||||
y = (cgs.glconfig.vidHeight - height) * 0.5f;
|
||||
|
||||
cgi.R_SetColor(NULL);
|
||||
cgi.R_DrawStretchPic(x, y, width, height, 0, 0, 1, 1, shader);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_DrawVote()
|
||||
{
|
||||
const char *text;
|
||||
int seconds;
|
||||
int percentYes;
|
||||
int percentNo;
|
||||
int percentUndecided;
|
||||
float x, y;
|
||||
vec4_t col;
|
||||
|
||||
if (!cgs.voteTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgs.voteRefreshed) {
|
||||
cgs.voteRefreshed = qfalse;
|
||||
}
|
||||
|
||||
seconds = (30000 - (cg.time - cgs.voteTime)) / 1000 + 1;
|
||||
if (seconds < 0) {
|
||||
seconds = 0;
|
||||
}
|
||||
|
||||
percentYes = cgs.numVotesYes * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
|
||||
percentNo = cgs.numVotesNo * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
|
||||
percentUndecided = cgs.numUndecidedVotes * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
|
||||
|
||||
x = 8;
|
||||
y = (cgs.glconfig.vidHeight > 480) ? (cgs.glconfig.vidHeight * 0.725f) : (cgs.glconfig.vidHeight * 0.75f);
|
||||
|
||||
cgi.R_SetColor(NULL);
|
||||
|
||||
text = va("%s: %s", cgi.LV_ConvertString("Vote Running"), cgs.voteString);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
|
||||
y += 12;
|
||||
|
||||
text =
|
||||
va("%s: %isec %s: %i%% %s: %i%% %s: %i%%",
|
||||
cgi.LV_ConvertString("Time"),
|
||||
seconds,
|
||||
cgi.LV_ConvertString("Yes"),
|
||||
percentYes,
|
||||
cgi.LV_ConvertString("No"),
|
||||
percentNo,
|
||||
cgi.LV_ConvertString("Undecided"),
|
||||
percentUndecided);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
|
||||
if (cg.snap && !cg.snap->ps.voted) {
|
||||
col[0] = 0.5;
|
||||
col[1] = 1.0;
|
||||
col[2] = 0.5;
|
||||
col[3] = 1.0;
|
||||
cgi.R_SetColor(col);
|
||||
|
||||
y += 12;
|
||||
|
||||
text = cgi.LV_ConvertString("Vote now, it's your patriotic duty!");
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
|
||||
y += 12;
|
||||
|
||||
text = cgi.LV_ConvertString("To vote Yes, press F1. To vote No, press F2.");
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
cgi.R_SetColor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
CG_Draw2D
|
||||
@@ -1183,5 +1344,7 @@ void CG_Draw2D(void)
|
||||
CG_DrawPlayerTeam();
|
||||
CG_DrawPlayerEntInfo();
|
||||
CG_UpdateAttackerDisplay();
|
||||
CG_DrawVote();
|
||||
CG_DrawInstantMessageMenu();
|
||||
CG_DrawCrosshair();
|
||||
}
|
||||
+22
-1
@@ -35,6 +35,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "cg_public.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
class MemArchiver;
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -394,8 +396,19 @@ extern "C" {
|
||||
int maxclients;
|
||||
int cinematic;
|
||||
int mapChecksum;
|
||||
qboolean useMapChecksum;
|
||||
char mapname[MAX_QPATH];
|
||||
|
||||
//
|
||||
// vote
|
||||
//
|
||||
int voteTime;
|
||||
int numVotesYes;
|
||||
int numVotesNo;
|
||||
int numUndecidedVotes;
|
||||
qboolean voteRefreshed;
|
||||
char voteString[1024];
|
||||
|
||||
//
|
||||
// locally derived information from gamestate
|
||||
//
|
||||
@@ -458,6 +471,9 @@ extern "C" {
|
||||
extern cvar_t *cg_hud;
|
||||
extern cvar_t *cg_huddraw_force;
|
||||
extern cvar_t *cg_drawsvlag;
|
||||
extern cvar_t *cg_crosshair;
|
||||
extern cvar_t *cg_crosshair_friend;
|
||||
extern cvar_t *ui_crosshair;
|
||||
extern cvar_t *vm_offset_max;
|
||||
extern cvar_t *vm_offset_speed;
|
||||
extern cvar_t *vm_sway_front;
|
||||
@@ -488,7 +504,7 @@ extern "C" {
|
||||
//
|
||||
// cg_main.c
|
||||
//
|
||||
void CG_ProcessConfigString(int num);
|
||||
void CG_ProcessConfigString(int num, qboolean modelOnly);
|
||||
const char *CG_ConfigString(int index);
|
||||
void CG_AddToTeamChat(const char *str);
|
||||
void CG_NewClientinfo(int clientNum);
|
||||
@@ -530,6 +546,8 @@ extern "C" {
|
||||
// cg_tempmodels.cpp
|
||||
//
|
||||
extern cvar_t *cg_showtempmodels;
|
||||
extern cvar_t *cg_max_tempmodels;
|
||||
extern cvar_t *cg_reserve_tempmodels;
|
||||
extern cvar_t *cg_detail;
|
||||
extern cvar_t *cg_effectdetail;
|
||||
extern cvar_t *cg_effect_physicsrate;
|
||||
@@ -911,6 +929,9 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
|
||||
//
|
||||
// cg_volumetricsmoke.cpp
|
||||
void CG_ResetVSSSources(void);
|
||||
#ifdef __cplusplus
|
||||
void CG_ArchiveVSSGlobals(MemArchiver& archiver);
|
||||
#endif
|
||||
void CG_AddVSSSources(void);
|
||||
|
||||
extern cvar_t *vss_draw;
|
||||
|
||||
+198
-122
@@ -80,6 +80,9 @@ cvar_t *cg_acidtrip;
|
||||
cvar_t *cg_hud;
|
||||
cvar_t *cg_huddraw_force;
|
||||
cvar_t *cg_drawsvlag;
|
||||
cvar_t *cg_crosshair;
|
||||
cvar_t *cg_crosshair_friend;
|
||||
cvar_t *ui_crosshair;
|
||||
cvar_t *vm_offset_max;
|
||||
cvar_t *vm_offset_speed;
|
||||
cvar_t *vm_sway_front;
|
||||
@@ -159,6 +162,15 @@ void CG_RegisterCvars(void)
|
||||
cg_hud = cgi.Cvar_Get("cg_hud", "0", 0);
|
||||
cg_huddraw_force = cgi.Cvar_Get("cg_huddraw_force", "0", CVAR_SAVEGAME);
|
||||
cg_drawsvlag = cgi.Cvar_Get("cg_drawsvlag", "1", CVAR_ARCHIVE);
|
||||
cg_crosshair = cgi.Cvar_Get("cg_crosshair", "textures/hud/crosshair", CVAR_ARCHIVE);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cg_crosshair_friend = cgi.Cvar_Get("cg_crosshair_friend", "textures/hud/crosshair_friend", CVAR_ARCHIVE);
|
||||
} else {
|
||||
// on 1.11 and below, fallback to standard crosshair
|
||||
// as it doesn't have crosshair_friend texture
|
||||
cg_crosshair_friend = cgi.Cvar_Get("cg_crosshair_friend", "textures/hud/crosshair", CVAR_ARCHIVE);
|
||||
}
|
||||
ui_crosshair = cgi.Cvar_Get("ui_crosshair", "1", CVAR_ARCHIVE);
|
||||
vm_offset_max = cgi.Cvar_Get("vm_offset_max", "8.0", 0);
|
||||
vm_offset_speed = cgi.Cvar_Get("vm_offset_speed", "8.0", 0);
|
||||
vm_sway_front = cgi.Cvar_Get("vm_sway_front", "0.1", 0);
|
||||
@@ -233,91 +245,48 @@ void CG_RegisterSounds(void)
|
||||
Com_Printf("-------------UBERDIALOG DONE---------------\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_IsHandleUnique
|
||||
|
||||
Check if the model handle is unique
|
||||
================
|
||||
*/
|
||||
static qboolean CG_IsHandleUnique(int num) {
|
||||
qhandle_t handle;
|
||||
int i;
|
||||
int numRef;
|
||||
|
||||
numRef = 0;
|
||||
handle = cgs.model_draw[num];
|
||||
for (i = 0; i < MAX_MODELS; i++) {
|
||||
if (cgs.model_draw[i] == handle) {
|
||||
numRef++;
|
||||
if (numRef >= 2) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_ProcessConfigString
|
||||
================
|
||||
*/
|
||||
void CG_ProcessConfigString(int num)
|
||||
void CG_ProcessConfigString(int num, qboolean modelOnly)
|
||||
{
|
||||
const char *str = CG_ConfigString(num);
|
||||
int i;
|
||||
const char* str;
|
||||
int i;
|
||||
|
||||
switch (num) {
|
||||
case CS_RAIN_DENSITY:
|
||||
cg.rain.density = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEED:
|
||||
cg.rain.speed = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEEDVARY:
|
||||
cg.rain.speed_vary = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_SLANT:
|
||||
cg.rain.slant = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_LENGTH:
|
||||
cg.rain.length = atof(str);
|
||||
return;
|
||||
case CS_RAIN_MINDIST:
|
||||
cg.rain.min_dist = atof(str);
|
||||
return;
|
||||
case CS_RAIN_WIDTH:
|
||||
cg.rain.width = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SHADER:
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
}
|
||||
} else {
|
||||
strcpy(cg.rain.shader[0], str);
|
||||
}
|
||||
return;
|
||||
case CS_RAIN_NUMSHADERS:
|
||||
cg.rain.numshaders = atoi(str);
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
|
||||
cobjective_t *objective = &cg.Objectives[num - CS_OBJECTIVES];
|
||||
objective->flags = atoi(Info_ValueForKey(str, "flags"));
|
||||
strcpy(objective->text, Info_ValueForKey(str, "text"));
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
case CS_MUSIC:
|
||||
cgi.MUSIC_NewSoundtrack(str);
|
||||
return;
|
||||
case CS_WARMUP:
|
||||
cg.matchStartTime = atoi(str);
|
||||
return;
|
||||
case CS_FOGINFO:
|
||||
CG_ParseFogInfo(str);
|
||||
return;
|
||||
case CS_SKYINFO:
|
||||
sscanf(str, "%f %d", &cg.sky_alpha, &cg.sky_portal);
|
||||
return;
|
||||
case CS_SERVERINFO:
|
||||
CG_ParseServerinfo();
|
||||
return;
|
||||
case CS_LEVEL_START_TIME:
|
||||
cgs.levelStartTime = atoi(str);
|
||||
return;
|
||||
case CS_MATCHEND:
|
||||
cgs.matchEndTime = atoi(str);
|
||||
return;
|
||||
}
|
||||
str = CG_ConfigString(num);
|
||||
|
||||
if (num >= CS_MODELS && num < CS_MODELS + MAX_MODELS) {
|
||||
qhandle_t hOldModel = cgs.model_draw[num - CS_MODELS];
|
||||
|
||||
if (str && str[0]) {
|
||||
if (str && str[0] && !modelOnly) {
|
||||
qhandle_t hModel = cgi.R_RegisterServerModel(str);
|
||||
dtiki_t *tiki;
|
||||
|
||||
@@ -334,43 +303,142 @@ void CG_ProcessConfigString(int num)
|
||||
}
|
||||
} else {
|
||||
// clear out the model
|
||||
if (hOldModel) {
|
||||
if (hOldModel && CG_IsHandleUnique(hOldModel)) {
|
||||
// Handle uniqueness added in OPM
|
||||
cgi.R_UnregisterServerModel(hOldModel);
|
||||
}
|
||||
cgs.model_draw[num - CS_MODELS] = 0;
|
||||
}
|
||||
} else if (num >= CS_SOUNDS && num < CS_SOUNDS + MAX_SOUNDS) {
|
||||
size_t len = strlen(str);
|
||||
if (len) {
|
||||
qboolean streamed;
|
||||
char buf[1024];
|
||||
strcpy(buf, str);
|
||||
}
|
||||
|
||||
streamed = buf[len - 1] != '0';
|
||||
buf[len - 1] = 0;
|
||||
if (buf[0] != '*') {
|
||||
cgs.sound_precache[num - CS_SOUNDS] = cgi.S_RegisterSound(buf, streamed);
|
||||
if (!modelOnly) {
|
||||
switch (num) {
|
||||
case CS_RAIN_DENSITY:
|
||||
cg.rain.density = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEED:
|
||||
cg.rain.speed = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEEDVARY:
|
||||
cg.rain.speed_vary = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_SLANT:
|
||||
cg.rain.slant = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_LENGTH:
|
||||
cg.rain.length = atof(str);
|
||||
return;
|
||||
case CS_RAIN_MINDIST:
|
||||
cg.rain.min_dist = atof(str);
|
||||
return;
|
||||
case CS_RAIN_WIDTH:
|
||||
cg.rain.width = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SHADER:
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
}
|
||||
} else {
|
||||
strcpy(cg.rain.shader[0], str);
|
||||
}
|
||||
}
|
||||
} else if (num >= CS_LIGHTSTYLES && num < CS_LIGHTSTYLES + MAX_LIGHTSTYLES) {
|
||||
CG_SetLightStyle(num - CS_LIGHTSTYLES, str);
|
||||
} else if (num >= CS_PLAYERS && num < CS_PLAYERS + MAX_CLIENTS) {
|
||||
const char *value;
|
||||
|
||||
value = Info_ValueForKey(str, "name");
|
||||
if (value) {
|
||||
strncpy(cg.clientinfo[num - CS_PLAYERS].name, value, sizeof(cg.clientinfo[num - CS_PLAYERS].name));
|
||||
} else {
|
||||
strncpy(
|
||||
cg.clientinfo[num - CS_PLAYERS].name, "UnnamedSoldier", sizeof(cg.clientinfo[num - CS_PLAYERS].name)
|
||||
);
|
||||
return;
|
||||
case CS_RAIN_NUMSHADERS:
|
||||
cg.rain.numshaders = atoi(str);
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
value = Info_ValueForKey(str, "team");
|
||||
if (value) {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = atoi(value);
|
||||
} else {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = TEAM_NONE;
|
||||
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
|
||||
cobjective_t *objective = &cg.Objectives[num - CS_OBJECTIVES];
|
||||
objective->flags = atoi(Info_ValueForKey(str, "flags"));
|
||||
strcpy(objective->text, Info_ValueForKey(str, "text"));
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
case CS_MUSIC:
|
||||
cgi.MUSIC_NewSoundtrack(str);
|
||||
return;
|
||||
case CS_WARMUP:
|
||||
cg.matchStartTime = atoi(str);
|
||||
return;
|
||||
case CS_FOGINFO:
|
||||
cg.farclipOverride = 0;
|
||||
cg.farplaneColorOverride[0] = -1;
|
||||
cg.farplaneColorOverride[1] = -1;
|
||||
cg.farplaneColorOverride[2] = -1;
|
||||
CG_ParseFogInfo(str);
|
||||
return;
|
||||
case CS_SKYINFO:
|
||||
sscanf(str, "%f %d", &cg.sky_alpha, &cg.sky_portal);
|
||||
return;
|
||||
case CS_SERVERINFO:
|
||||
CG_ParseServerinfo();
|
||||
return;
|
||||
case CS_LEVEL_START_TIME:
|
||||
cgs.levelStartTime = atoi(str);
|
||||
return;
|
||||
case CS_VOTE_TIME:
|
||||
cgs.voteTime = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_VOTE_STRING:
|
||||
Q_strncpyz(cgs.voteString, str, sizeof(cgs.voteString));
|
||||
break;
|
||||
case CS_VOTE_YES:
|
||||
cgs.numVotesYes = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_VOTE_NO:
|
||||
cgs.numVotesNo = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_VOTE_UNDECIDED:
|
||||
cgs.numUndecidedVotes = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_MATCHEND:
|
||||
cgs.matchEndTime = atoi(str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (num >= CS_SOUNDS && num < CS_SOUNDS + MAX_SOUNDS) {
|
||||
size_t len = strlen(str);
|
||||
if (len) {
|
||||
qboolean streamed;
|
||||
char buf[1024];
|
||||
strcpy(buf, str);
|
||||
|
||||
streamed = buf[len - 1] != '0';
|
||||
buf[len - 1] = 0;
|
||||
if (buf[0] != '*') {
|
||||
cgs.sound_precache[num - CS_SOUNDS] = cgi.S_RegisterSound(buf, streamed);
|
||||
}
|
||||
}
|
||||
} else if (num >= CS_LIGHTSTYLES && num < CS_LIGHTSTYLES + MAX_LIGHTSTYLES) {
|
||||
CG_SetLightStyle(num - CS_LIGHTSTYLES, str);
|
||||
} else if (num >= CS_PLAYERS && num < CS_PLAYERS + MAX_CLIENTS) {
|
||||
const char *value;
|
||||
|
||||
value = Info_ValueForKey(str, "name");
|
||||
if (value) {
|
||||
strncpy(cg.clientinfo[num - CS_PLAYERS].name, value, sizeof(cg.clientinfo[num - CS_PLAYERS].name));
|
||||
} else {
|
||||
strncpy(
|
||||
cg.clientinfo[num - CS_PLAYERS].name, "UnnamedSoldier", sizeof(cg.clientinfo[num - CS_PLAYERS].name)
|
||||
);
|
||||
}
|
||||
|
||||
value = Info_ValueForKey(str, "team");
|
||||
if (value) {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = atoi(value);
|
||||
} else {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = TEAM_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -423,14 +491,14 @@ void CG_PrepRefresh(void)
|
||||
cgs.media.binocularsOverlayShader = cgi.R_RegisterShaderNoMip("textures/hud/binocularsoverlay");
|
||||
cgs.media.hudDrawFont = cgi.R_LoadFont("verdana-14");
|
||||
cgs.media.attackerFont = cgi.R_LoadFont("facfont-20");
|
||||
cgs.media.objectiveFont = cgi.R_LoadFont("courier-16");
|
||||
cgs.media.objectiveFont = cgi.R_LoadFont("facfont-20"); // was courier-16 before 2.0
|
||||
cgs.media.objectivesBackShader = cgi.R_RegisterShaderNoMip("textures/hud/objectives_backdrop");
|
||||
cgs.media.checkedBoxShader = cgi.R_RegisterShaderNoMip("textures/objectives/filledbox");
|
||||
cgs.media.uncheckedBoxShader = cgi.R_RegisterShaderNoMip("textures/objectives/emptybox");
|
||||
|
||||
// go through all the configstrings and process them
|
||||
for (i = CS_SYSTEMINFO + 1; i < MAX_CONFIGSTRINGS; i++) {
|
||||
CG_ProcessConfigString(i);
|
||||
CG_ProcessConfigString(i, qfalse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,6 +537,7 @@ Displays the info screen while loading media
|
||||
void CG_GameStateReceived(void)
|
||||
{
|
||||
const char *s;
|
||||
int checksum;
|
||||
|
||||
// clear everything
|
||||
memset(&cg, 0, sizeof(cg));
|
||||
@@ -495,7 +564,10 @@ void CG_GameStateReceived(void)
|
||||
CG_ParseServerinfo();
|
||||
|
||||
// load the new map
|
||||
cgi.CM_LoadMap(cgs.mapname);
|
||||
cgi.CM_LoadMap(cgs.mapname, &checksum);
|
||||
if (cgs.useMapChecksum && checksum != cgs.mapChecksum && cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
cgi.Error(ERR_DROP, "Client/Server map checksum mismatch: %x/%x", checksum, cgs.mapChecksum);
|
||||
}
|
||||
|
||||
CG_InitMarks();
|
||||
|
||||
@@ -539,16 +611,6 @@ void CG_ServerRestarted(void)
|
||||
CG_InitializeObjectives();
|
||||
}
|
||||
|
||||
void *CG_Malloc(int size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void CG_Free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_Init
|
||||
@@ -559,10 +621,6 @@ Called after every level change or subsystem restart
|
||||
void CG_Init(clientGameImport_t *imported, int serverMessageNum, int serverCommandSequence, int clientNum)
|
||||
{
|
||||
cgi = *imported;
|
||||
#if _DEBUG
|
||||
cgi.Malloc = &CG_Malloc;
|
||||
cgi.Free = &CG_Free;
|
||||
#endif
|
||||
|
||||
cg_protocol = cgi.Cvar_Get("com_protocol", "", 0)->integer;
|
||||
CG_InitCGMessageAPI(&cge);
|
||||
@@ -570,6 +628,11 @@ void CG_Init(clientGameImport_t *imported, int serverMessageNum, int serverComma
|
||||
|
||||
memset(&cg, 0, sizeof(cg));
|
||||
memset(&cgs, 0, sizeof(cgs));
|
||||
// clear fog values
|
||||
cg.farclipOverride = 0;
|
||||
cg.farplaneColorOverride[0] = -1;
|
||||
cg.farplaneColorOverride[1] = -1;
|
||||
cg.farplaneColorOverride[2] = -1;
|
||||
|
||||
cg.clientNum = clientNum;
|
||||
cgs.processedSnapshotNum = serverMessageNum;
|
||||
@@ -626,11 +689,14 @@ Called before every level change or subsystem restart
|
||||
void CG_Shutdown(void)
|
||||
{
|
||||
L_ShutdownEvents();
|
||||
// Shutdown radar
|
||||
cgi.CL_InitRadar(NULL, NULL, -1);
|
||||
|
||||
// some mods may need to do cleanup work here,
|
||||
// like closing files or archiving session data
|
||||
|
||||
// hide the stats screen
|
||||
cgi.UI_HideMenu("StatsScreen", 1);
|
||||
cgi.UI_HideMenu("StatsScreen", qtrue);
|
||||
|
||||
// reset the scoreboard
|
||||
CG_PrepScoreBoardInfo();
|
||||
@@ -788,10 +854,20 @@ void CG_ParseFogInfo_ver_15(const char *str)
|
||||
|
||||
void CG_ParseFogInfo_ver_6(const char *str)
|
||||
{
|
||||
cg.farclipOverride = 0.0;
|
||||
//
|
||||
// clear all unsupported fields in protocol below version 15
|
||||
//
|
||||
|
||||
// don't set the farplane_bias 0, otherwise the renderer will set a minimum value
|
||||
cg.farplane_bias = 0.001f;
|
||||
cg.skyboxFarplane = 0;
|
||||
cg.skyboxSpeed = 0;
|
||||
cg.renderTerrain = qtrue;
|
||||
cg.farclipOverride = -1.0;
|
||||
cg.farplaneColorOverride[0] = -1.0;
|
||||
cg.farplaneColorOverride[1] = -1.0;
|
||||
cg.farplaneColorOverride[2] = -1.0;
|
||||
|
||||
sscanf(
|
||||
str,
|
||||
"%d %f %f %f %f",
|
||||
|
||||
@@ -685,9 +685,9 @@ void CG_ImpactMark(
|
||||
// create the full polygon
|
||||
for (i = 0; i < 3; i++) {
|
||||
originalPoints[0][i] = origin[i] - fSScale2 * info.axis[1][i] - fTScale2 * info.axis[2][i];
|
||||
originalPoints[1][i] = origin[i] + fSScale3 * info.axis[1][i] - fTScale3 * info.axis[2][i];
|
||||
originalPoints[1][i] = origin[i] + fSScale3 * info.axis[1][i] - fTScale2 * info.axis[2][i];
|
||||
originalPoints[2][i] = origin[i] + fSScale3 * info.axis[1][i] + fTScale3 * info.axis[2][i];
|
||||
originalPoints[3][i] = origin[i] - fSScale2 * info.axis[1][i] + fTScale2 * info.axis[2][i];
|
||||
originalPoints[3][i] = origin[i] - fSScale2 * info.axis[1][i] + fTScale3 * info.axis[2][i];
|
||||
}
|
||||
|
||||
// get the fragments
|
||||
|
||||
+286
-20
@@ -180,6 +180,226 @@ void CG_PlayerTeamIcon(refEntity_t *pModel, entityState_t *pPlayerState)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CastFootShadow
|
||||
|
||||
Cast complex foot shadow using lights
|
||||
===============
|
||||
*/
|
||||
void CG_CastFootShadow(const vec_t* vLightPos, vec_t* vLightIntensity, int iTag, refEntity_t* model)
|
||||
{
|
||||
int i;
|
||||
float fAlpha;
|
||||
float fLength;
|
||||
float fWidth;
|
||||
float fAlphaOfs;
|
||||
float fOfs;
|
||||
float fPitchCos;
|
||||
vec3_t vPos;
|
||||
vec3_t vEnd;
|
||||
vec3_t vDelta;
|
||||
vec3_t vLightAngles;
|
||||
trace_t trace;
|
||||
orientation_t oFoot;
|
||||
|
||||
VectorCopy(model->origin, vPos);
|
||||
oFoot = cgi.TIKI_Orientation(model, iTag);
|
||||
VectorMA(oFoot.origin, 2, oFoot.axis[1], vEnd);
|
||||
for (i = 0; i < 3; i++) {
|
||||
VectorMA(vPos, vEnd[i], model->axis[i], vPos);
|
||||
}
|
||||
|
||||
if (cg_shadowdebug->integer)
|
||||
{
|
||||
vec3_t vDir;
|
||||
|
||||
//
|
||||
// show debug lines
|
||||
//
|
||||
memset(vDir, 0, sizeof(vDir));
|
||||
for (i = 0; i < 3; ++i) {
|
||||
VectorMA(vDir, oFoot.axis[0][i], model->axis[i], vDir);
|
||||
}
|
||||
VectorMA(vPos, 32.0, vDir, vEnd);
|
||||
cgi.R_DebugLine(vPos, vEnd, 1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
memset(vDir, 0, sizeof(vDir));
|
||||
for (i = 0; i < 3; ++i) {
|
||||
VectorMA(vDir, oFoot.axis[1][i], model->axis[i], vDir);
|
||||
}
|
||||
VectorMA(vPos, 32.0, vDir, vEnd);
|
||||
cgi.R_DebugLine(vPos, vEnd, 0.0, 1.0, 0.0, 1.0);
|
||||
|
||||
memset(vDir, 0, sizeof(vDir));
|
||||
for (i = 0; i < 3; ++i) {
|
||||
VectorMA(vDir, oFoot.axis[2][i], model->axis[i], vDir);
|
||||
}
|
||||
VectorMA(vPos, 32.0, vDir, vEnd);
|
||||
cgi.R_DebugLine(vPos, vEnd, 0.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
// calculate the direction
|
||||
VectorSubtract(vLightPos, vPos, vDelta);
|
||||
VectorNormalizeFast(vDelta);
|
||||
vectoangles(vDelta, vLightAngles);
|
||||
|
||||
// normalize to 180 degrees
|
||||
if (vLightAngles[0] > 180) {
|
||||
vLightAngles[0] -= 360;
|
||||
}
|
||||
|
||||
if (vLightAngles[0] > -5.7319679) {
|
||||
// FIXME: what is -5.7319679?
|
||||
return;
|
||||
}
|
||||
|
||||
fPitchCos = cos(DEG2RAD(vLightAngles[0]));
|
||||
if (fPitchCos > 0.955) {
|
||||
fAlpha = 1.0 - (fPitchCos - 0.955) * 25;
|
||||
} else {
|
||||
fAlpha = 1.0;
|
||||
}
|
||||
|
||||
fLength = fPitchCos * fPitchCos * 32.0 + fPitchCos * 8.0 + 10.0;
|
||||
fOfs = 0.5 - (-4.1 / tan(DEG2RAD(vLightAngles[0])) + 4.0 - fLength) / fLength * 0.5;
|
||||
VectorMA(vPos, -96.0, vDelta, vEnd);
|
||||
CG_Trace(&trace, vPos, vec3_origin, vec3_origin, vEnd, 0, MASK_FOOTSHADOW, qfalse, qtrue, "CG_CastFootShadow");
|
||||
|
||||
if (cg_shadowdebug->integer)
|
||||
{
|
||||
cgi.R_DebugLine(vPos, vLightPos, 0.75, 0.75, 0.5, 1.0);
|
||||
cgi.R_DebugLine(vPos, vEnd, 1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
if (trace.fraction == 1.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
trace.fraction -= 0.0427f;
|
||||
if (trace.fraction < 0) {
|
||||
trace.fraction = 0;
|
||||
}
|
||||
|
||||
fWidth = 10.f - (1.f - trace.fraction) * 6.f;
|
||||
fAlphaOfs = (1.f - trace.fraction) * fAlpha;
|
||||
|
||||
fAlpha = Q_max(vLightIntensity[0], Q_max(vLightIntensity[1], vLightIntensity[2]));
|
||||
|
||||
if (fAlpha < 0.1) {
|
||||
vLightIntensity[0] *= 0.1 / fAlpha * fAlphaOfs;
|
||||
vLightIntensity[1] *= 0.1 / fAlpha * fAlphaOfs;
|
||||
vLightIntensity[2] *= 0.1 / fAlpha * fAlphaOfs;
|
||||
} else {
|
||||
vLightIntensity[0] *= fAlphaOfs;
|
||||
vLightIntensity[1] *= fAlphaOfs;
|
||||
vLightIntensity[2] *= fAlphaOfs;
|
||||
}
|
||||
|
||||
fAlpha = Q_max(vLightIntensity[0], Q_max(vLightIntensity[1], vLightIntensity[2]));
|
||||
if (fAlpha > 0.6) {
|
||||
vLightIntensity[0] *= 0.6 / fAlpha;
|
||||
vLightIntensity[1] *= 0.6 / fAlpha;
|
||||
vLightIntensity[2] *= 0.6 / fAlpha;
|
||||
}
|
||||
|
||||
if (vLightIntensity[0] <= 0.01 && vLightIntensity[1] <= 0.01 && vLightIntensity[2] <= 0.01) {
|
||||
return;
|
||||
}
|
||||
|
||||
CG_ImpactMark(
|
||||
cgs.media.footShadowMarkShader,
|
||||
trace.endpos,
|
||||
trace.plane.normal,
|
||||
vLightAngles[1],
|
||||
fWidth,
|
||||
fLength,
|
||||
vLightIntensity[0],
|
||||
vLightIntensity[1],
|
||||
vLightIntensity[2],
|
||||
1.0,
|
||||
qfalse,
|
||||
qtrue,
|
||||
qfalse,
|
||||
qfalse,
|
||||
0.5,
|
||||
fOfs
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CastSimpleFeetShadow
|
||||
|
||||
Cast basic feet shadow
|
||||
===============
|
||||
*/
|
||||
void CG_CastSimpleFeetShadow(const trace_t* pTrace, float fWidth, float fAlpha, int iRightTag, int iLeftTag, const dtiki_t* tiki, refEntity_t* model)
|
||||
{
|
||||
int i;
|
||||
float fShadowYaw;
|
||||
float fLength;
|
||||
vec3_t vPos, vRightPos, vLeftPos;
|
||||
vec3_t vDelta;
|
||||
orientation_t oFoot;
|
||||
|
||||
//
|
||||
// right foot
|
||||
//
|
||||
VectorCopy(pTrace->endpos, vRightPos);
|
||||
oFoot = cgi.TIKI_Orientation(model, iRightTag);
|
||||
VectorMA(oFoot.origin, 3, oFoot.axis[1], vPos);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
VectorMA(vRightPos, vPos[i], model->axis[i], vRightPos);
|
||||
}
|
||||
|
||||
VectorMA(vRightPos, -2, oFoot.axis[1], vRightPos);
|
||||
|
||||
//
|
||||
// left foot
|
||||
//
|
||||
VectorCopy(pTrace->endpos, vLeftPos);
|
||||
oFoot = cgi.TIKI_Orientation(model, iLeftTag);
|
||||
VectorMA(oFoot.origin, 3, oFoot.axis[1], vPos);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
VectorMA(vLeftPos, vPos[i], model->axis[i], vLeftPos);
|
||||
}
|
||||
|
||||
VectorAdd(vRightPos, vLeftPos, vPos);
|
||||
VectorScale(vPos, 0.5, vPos);
|
||||
VectorSubtract(vRightPos, vLeftPos, vDelta);
|
||||
VectorMA(vLeftPos, 0.5, vDelta, vPos);
|
||||
|
||||
// get the facing yaw
|
||||
fShadowYaw = vectoyaw(vDelta);
|
||||
fLength = VectorNormalize(vDelta) * 0.5 + 12;
|
||||
if (fLength < fWidth * 0.7) {
|
||||
fLength = fWidth * 0.7;
|
||||
}
|
||||
|
||||
// add the mark
|
||||
CG_ImpactMark(
|
||||
cgs.media.shadowMarkShader,
|
||||
vPos,
|
||||
pTrace->plane.normal,
|
||||
fShadowYaw,
|
||||
fWidth * 0.7,
|
||||
fLength,
|
||||
fAlpha,
|
||||
fAlpha,
|
||||
fAlpha,
|
||||
1.0,
|
||||
qfalse,
|
||||
qtrue,
|
||||
qfalse,
|
||||
qfalse,
|
||||
0.5,
|
||||
0.5
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_EntityShadow
|
||||
@@ -193,9 +413,15 @@ Returns the Z component of the surface being shadowed
|
||||
|
||||
qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
{
|
||||
int iTagL, iTagR;
|
||||
float alpha;
|
||||
float fWidth;
|
||||
vec3_t end;
|
||||
vec3_t vMins, vMaxs;
|
||||
vec3_t vSize;
|
||||
trace_t trace;
|
||||
float alpha, radius;
|
||||
|
||||
iTagR = -1;
|
||||
|
||||
if (cg_shadows->integer == 0) {
|
||||
return qfalse;
|
||||
@@ -206,10 +432,31 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// no shadows when invisible
|
||||
// if ( cent->currentState.powerups & ( 1 << PW_INVIS ) ) {
|
||||
// return qfalse;
|
||||
// }
|
||||
if (cg_shadows->integer == 2 && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
iTagL = cgi.Tag_NumForName(model->tiki, "Bip01 L Foot");
|
||||
if (iTagL != -1) {
|
||||
iTagR = cgi.Tag_NumForName(model->tiki, "Bip01 R Foot");
|
||||
}
|
||||
|
||||
if (iTagR != -1) {
|
||||
int iNumLights, iCurrLight;
|
||||
vec3_t avLightPos[16], avLightIntensity[16];
|
||||
|
||||
iNumLights = Q_clamp(cg_shadowscount->integer, 1, 8);
|
||||
iNumLights = cgi.R_GatherLightSources(model->origin, avLightPos, avLightIntensity, iNumLights);
|
||||
if (iNumLights)
|
||||
{
|
||||
for (iCurrLight = 0; iCurrLight < iNumLights; iCurrLight++)
|
||||
{
|
||||
CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagL, model);
|
||||
CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagR, model);
|
||||
}
|
||||
|
||||
// shadow was casted properly
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send a trace down from the player to the ground
|
||||
VectorCopy(model->origin, end);
|
||||
@@ -222,29 +469,46 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ((cg_shadows->integer == 2) && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
// since 2.0: no shadow if solid
|
||||
if (trace.startsolid || trace.allsolid) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ((cg_shadows->integer == 3) && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
//
|
||||
// get the bounds of the current frame
|
||||
//
|
||||
radius = model->scale * cgi.R_ModelRadius(model->hModel);
|
||||
|
||||
if (radius < 1) {
|
||||
fWidth = model->scale * cgi.R_ModelRadius(model->hModel);
|
||||
if (fWidth < 1) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// fade the shadow out with height
|
||||
alpha = (1.0 - trace.fraction) * 0.8f;
|
||||
alpha = (1.0 - trace.fraction) * 0.65f;
|
||||
|
||||
if ((cg_shadows->integer == 3) && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
if (model->shaderRGBA[3] == 255) {
|
||||
model->shaderRGBA[3] = alpha * 255;
|
||||
if (model->renderfx & RF_SHADOW_PRECISE) {
|
||||
iTagL = cgi.Tag_NumForName(model->tiki, "Bip01 L Foot");
|
||||
if (iTagL != -1) {
|
||||
iTagR = cgi.Tag_NumForName(model->tiki, "Bip01 R Foot");
|
||||
}
|
||||
|
||||
if (iTagR != -1) {
|
||||
if (cg_shadows->integer == 2) {
|
||||
alpha *= 0.6f;
|
||||
}
|
||||
|
||||
CG_CastSimpleFeetShadow(&trace, fWidth, alpha, iTagR, iTagL, model->tiki, model);
|
||||
return qtrue;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
cgi.R_ModelBounds(model->hModel, vMins, vMaxs);
|
||||
VectorSubtract(vMaxs, vMins, vSize);
|
||||
VectorScale(vSize, 0.6f, vSize);
|
||||
|
||||
// add the mark as a temporary, so it goes directly to the renderer
|
||||
// without taking a spot in the cg_marks array
|
||||
CG_ImpactMark(
|
||||
@@ -252,15 +516,15 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
trace.endpos,
|
||||
trace.plane.normal,
|
||||
cent->lerpAngles[YAW],
|
||||
radius,
|
||||
radius,
|
||||
vSize[1],
|
||||
vSize[0],
|
||||
alpha,
|
||||
alpha,
|
||||
alpha,
|
||||
1,
|
||||
qfalse,
|
||||
qtrue,
|
||||
qtrue,
|
||||
qfalse,
|
||||
qfalse,
|
||||
0.5f,
|
||||
0.5f
|
||||
@@ -316,10 +580,12 @@ void CG_AttachEntity(
|
||||
orientation_t or ;
|
||||
vec3_t tempAxis[3];
|
||||
vec3_t vOrigin;
|
||||
vec3_t vDeltaLightOrg;
|
||||
|
||||
or = cgi.TIKI_Orientation(parent, tagnum);
|
||||
//cgi.Printf( "th = %d %.2f %.2f %.2f\n", tikihandle, or.origin[ 0 ], or.origin[ 1 ], or.origin[ 2 ] );
|
||||
|
||||
VectorSubtract(entity->lightingOrigin, entity->origin, vDeltaLightOrg);
|
||||
VectorCopy(parent->origin, entity->origin);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -337,14 +603,14 @@ void CG_AttachEntity(
|
||||
VectorCopy(entity->origin, entity->oldorigin);
|
||||
|
||||
if (use_angles) {
|
||||
MatrixMultiply(entity->axis, parent->axis, tempAxis);
|
||||
MatrixMultiply(or.axis, tempAxis, entity->axis);
|
||||
MatrixMultiply(entity->axis, or.axis, tempAxis);
|
||||
MatrixMultiply(tempAxis, parent->axis, entity->axis);
|
||||
}
|
||||
|
||||
entity->scale *= parent->scale;
|
||||
entity->renderfx |= (parent->renderfx & ~(RF_FLAGS_NOT_INHERITED | RF_LIGHTING_ORIGIN));
|
||||
|
||||
MatrixTransformVectorRight(entity->axis, entity->lightingOrigin, vOrigin);
|
||||
MatrixTransformVectorRight(entity->axis, vDeltaLightOrg, vOrigin);
|
||||
VectorAdd(entity->origin, vOrigin, entity->lightingOrigin);
|
||||
}
|
||||
|
||||
|
||||
+183
-224
@@ -37,6 +37,7 @@ typedef struct {
|
||||
vec3_t *i_vEnd;
|
||||
int i_iNumBullets;
|
||||
qboolean iLarge;
|
||||
float alpha;
|
||||
int iTracerVisible;
|
||||
qboolean bIgnoreEntities;
|
||||
} bullet_tracer_t;
|
||||
@@ -60,21 +61,22 @@ static vec3_t flesh_impact_pos[MAX_IMPACTS];
|
||||
static vec3_t flesh_impact_norm[MAX_IMPACTS];
|
||||
static int flesh_impact_large[MAX_IMPACTS];
|
||||
|
||||
void CG_MakeBulletHoleSound(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t* pPreTrace) {
|
||||
|
||||
int iSurfType;
|
||||
float fVolume;
|
||||
str sSoundName;
|
||||
vec3_t vFrom, vDest;
|
||||
void CG_MakeBulletHoleSound(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t *pPreTrace)
|
||||
{
|
||||
int iSurfType;
|
||||
float fVolume;
|
||||
str sSoundName;
|
||||
vec3_t vFrom, vDest;
|
||||
trace_t trace;
|
||||
|
||||
if (pPreTrace) {
|
||||
trace = *pPreTrace;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
VectorMA(i_vPos, 2.0f, i_vNorm, vFrom);
|
||||
VectorMA(i_vPos, -4.0f, i_vNorm, vDest);
|
||||
CG_Trace(&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole");
|
||||
CG_Trace(
|
||||
&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole"
|
||||
);
|
||||
}
|
||||
|
||||
iSurfType = trace.surfaceFlags & MASK_SURF_TYPE;
|
||||
@@ -149,9 +151,12 @@ void CG_MakeBulletHoleSound(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarg
|
||||
commandManager.PlaySound(sSoundName, vFrom, -1, fVolume, -1.f, -1.f, 1);
|
||||
}
|
||||
|
||||
static void CG_MakeBulletHoleType(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, int iEffectNum, float fRadius, qboolean bMakeSound) {
|
||||
static void CG_MakeBulletHoleType(
|
||||
const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, int iEffectNum, float fRadius, qboolean bMakeSound
|
||||
)
|
||||
{
|
||||
if (bMakeSound) {
|
||||
str sBulletHole = "snd_bh_";
|
||||
str sBulletHole = "snd_bh_";
|
||||
float fVolume;
|
||||
|
||||
switch (iEffectNum) {
|
||||
@@ -221,14 +226,15 @@ static void CG_MakeBulletHoleType(const vec3_t i_vPos, const vec3_t i_vNorm, int
|
||||
sfxManager.MakeEffect_Normal(iEffectNum, i_vPos, i_vNorm);
|
||||
}
|
||||
|
||||
static void CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t *pPreTrace, qboolean bMakeSound)
|
||||
static void
|
||||
CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t *pPreTrace, qboolean bMakeSound)
|
||||
{
|
||||
int iSurfType;
|
||||
int iEffect;
|
||||
float fRadius;
|
||||
str sEffectModel;
|
||||
str sBulletHole;
|
||||
vec3_t vFrom, vDest;
|
||||
int iSurfType;
|
||||
int iEffect;
|
||||
float fRadius;
|
||||
str sEffectModel;
|
||||
str sBulletHole;
|
||||
vec3_t vFrom, vDest;
|
||||
trace_t trace;
|
||||
|
||||
if (pPreTrace) {
|
||||
@@ -236,7 +242,9 @@ static void CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLa
|
||||
} else {
|
||||
VectorMA(i_vPos, 2.0f, i_vNorm, vFrom);
|
||||
VectorMA(i_vPos, -4.0f, i_vNorm, vDest);
|
||||
CG_Trace(&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole");
|
||||
CG_Trace(
|
||||
&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole"
|
||||
);
|
||||
}
|
||||
|
||||
iSurfType = trace.surfaceFlags & MASK_SURF_TYPE;
|
||||
@@ -249,7 +257,7 @@ static void CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLa
|
||||
}
|
||||
|
||||
VectorAdd(trace.endpos, trace.plane.normal, vFrom);
|
||||
fRadius = 2.0f;
|
||||
fRadius = 2.0f;
|
||||
sBulletHole = "bhole_";
|
||||
|
||||
switch (iSurfType) {
|
||||
@@ -347,36 +355,48 @@ static void CG_MakeBubbleTrail(const vec3_t i_vStart, const vec3_t i_vEnd, int i
|
||||
{
|
||||
vec3_t vDir;
|
||||
vec3_t vPos;
|
||||
float fDist;
|
||||
float fMove;
|
||||
float fDist;
|
||||
float fMove;
|
||||
|
||||
VectorSubtract(i_vEnd, i_vStart, vDir);
|
||||
fDist = VectorNormalize(vDir);
|
||||
VectorCopy(i_vStart, vPos);
|
||||
|
||||
fMove = random() * 8.f;
|
||||
fMove = random() * 8.f * alpha;
|
||||
fDist -= fMove;
|
||||
while (fDist > 0.f) {
|
||||
VectorMA(vPos, fMove, vDir, vPos);
|
||||
sfxManager.MakeEffect_Angles(32, vPos, vec_zero);
|
||||
|
||||
fMove = 16.f + crandom() * 8.f;
|
||||
fMove = 16.f + crandom() * 8.f * alpha;
|
||||
fDist -= fMove;
|
||||
}
|
||||
}
|
||||
|
||||
static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd)
|
||||
static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd, int iLarge, float alpha)
|
||||
{
|
||||
int iLife;
|
||||
int iTracerLength;
|
||||
float fLength, fDist;
|
||||
int iLife;
|
||||
int iTracerLength;
|
||||
float fLength, fDist;
|
||||
vec4_t fTracerColor;
|
||||
vec3_t vDir, vNewStart;
|
||||
float alphaMult;
|
||||
float scale;
|
||||
|
||||
iTracerLength = 450.0f + random() * 150.f;
|
||||
VectorSubtract(i_vEnd, i_vStart, vDir);
|
||||
fLength = VectorNormalize(vDir);
|
||||
|
||||
if (iLarge > 1) {
|
||||
alphaMult = random() * 0.2f + 0.9f;
|
||||
scale = iLarge * 2;
|
||||
} else {
|
||||
alphaMult = 1;
|
||||
scale = 1;
|
||||
}
|
||||
|
||||
fDist = 450.0f + random() * 150.f;
|
||||
|
||||
if (fLength < fDist + 150.f) {
|
||||
float fFrac;
|
||||
|
||||
@@ -384,13 +404,15 @@ static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd)
|
||||
return;
|
||||
}
|
||||
|
||||
fFrac = fLength / (fDist + 150.0);
|
||||
fFrac = fLength / (fDist + 150.0);
|
||||
iTracerLength = (int)((float)iTracerLength * fFrac + 0.5f);
|
||||
fDist *= fFrac;
|
||||
}
|
||||
|
||||
iLife = (int)((fLength - fDist) / 12000.f * 1000.f);
|
||||
if (iLife < 20) iLife = 20;
|
||||
iLife = (int)((fLength - fDist) / 12000.f * 1000.f / (alpha * alphaMult));
|
||||
if (iLife < 20) {
|
||||
iLife = 20;
|
||||
}
|
||||
|
||||
VectorMA(i_vStart, fDist, vDir, vNewStart);
|
||||
fTracerColor[0] = 1.f;
|
||||
@@ -427,53 +449,54 @@ static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd)
|
||||
}
|
||||
|
||||
static void CG_MakeBulletTracerInternal(
|
||||
const vec3_t i_vBarrel,
|
||||
const vec3_t i_vStart,
|
||||
const vec3_t *i_vEnd,
|
||||
int i_iNumBullets,
|
||||
qboolean iLarge,
|
||||
int iTracerVisible,
|
||||
qboolean bIgnoreEntities
|
||||
const vec3_t i_vBarrel,
|
||||
const vec3_t i_vStart,
|
||||
const vec3_t *i_vEnd,
|
||||
int i_iNumBullets,
|
||||
qboolean iLarge,
|
||||
int iTracerVisible,
|
||||
qboolean bIgnoreEntities,
|
||||
float alpha
|
||||
)
|
||||
{
|
||||
vec3_t vPos;
|
||||
int iBullet;
|
||||
int iContinueCount;
|
||||
int iDist;
|
||||
int iHeadDist;
|
||||
int iTravelDist;
|
||||
float fLen, fDist;
|
||||
trace_t trace;
|
||||
qboolean bStartInWater, bInWater;
|
||||
qboolean bBulletDone;
|
||||
qboolean bMadeTracer;
|
||||
vec3_t vDir;
|
||||
vec3_t vTrailStart;
|
||||
vec3_t vTraceStart;
|
||||
vec3_t vTraceEnd;
|
||||
vec3_t vTmp;
|
||||
int iNumImpacts;
|
||||
trace_t tImpacts[128];
|
||||
float fImpSndDistRA;
|
||||
vec3_t vPos;
|
||||
int iBullet;
|
||||
int iContinueCount;
|
||||
int iDist;
|
||||
int iHeadDist;
|
||||
int iTravelDist;
|
||||
float fLen, fDist;
|
||||
trace_t trace;
|
||||
qboolean bStartInWater, bInWater;
|
||||
qboolean bBulletDone;
|
||||
qboolean bMadeTracer;
|
||||
vec3_t vDir;
|
||||
vec3_t vTrailStart;
|
||||
vec3_t vTraceStart;
|
||||
vec3_t vTraceEnd;
|
||||
vec3_t vTmp;
|
||||
int iNumImpacts;
|
||||
trace_t tImpacts[128];
|
||||
float fImpSndDistRA;
|
||||
static float fImpSndDistLA;
|
||||
float fImpSndDistRB;
|
||||
float fImpSndDistLB;
|
||||
int iImpSndIndexRA;
|
||||
int iImpSndIndexRB;
|
||||
int iImpSndIndexLB;
|
||||
float fVolume;
|
||||
float fPitch;
|
||||
float fZingDistA, fZingDistB, fZingDistC;
|
||||
vec3_t vZingPosA, vZingPosB, vZingPosC;
|
||||
float fImpSndDistRB;
|
||||
float fImpSndDistLB;
|
||||
int iImpSndIndexRA;
|
||||
int iImpSndIndexRB;
|
||||
int iImpSndIndexLB;
|
||||
float fVolume;
|
||||
float fPitch;
|
||||
float fZingDistA, fZingDistB, fZingDistC;
|
||||
vec3_t vZingPosA, vZingPosB, vZingPosC;
|
||||
|
||||
fZingDistB = 9999.0;
|
||||
fZingDistA = 9999.0;
|
||||
fZingDistC = 9999.0;
|
||||
fZingDistB = 9999.0;
|
||||
fZingDistA = 9999.0;
|
||||
fZingDistC = 9999.0;
|
||||
iNumImpacts = 0;
|
||||
|
||||
// check to see if it starts in water
|
||||
bStartInWater = (cgi.CM_PointContents(i_vStart, 0) & CONTENTS_FLUID) != 0;
|
||||
|
||||
|
||||
for (iBullet = 0; iBullet < i_iNumBullets; iBullet++) {
|
||||
bInWater = bStartInWater;
|
||||
VectorCopy(i_vBarrel, vTrailStart);
|
||||
@@ -481,8 +504,8 @@ static void CG_MakeBulletTracerInternal(
|
||||
fLen = VectorNormalize(vDir);
|
||||
|
||||
trace.fraction = 0;
|
||||
iDist = (int)fLen + 32;
|
||||
bBulletDone = qfalse;
|
||||
iDist = (int)fLen + 32;
|
||||
bBulletDone = qfalse;
|
||||
iContinueCount = 0;
|
||||
|
||||
if (bStartInWater) {
|
||||
@@ -501,8 +524,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
if (iDist > BULLET_TRAVEL_DIST) {
|
||||
iTravelDist += BULLET_TRAVEL_DIST;
|
||||
iDist -= BULLET_TRAVEL_DIST;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
iTravelDist += iDist;
|
||||
iDist = 0;
|
||||
}
|
||||
@@ -513,16 +535,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
|
||||
while (trace.fraction < 1) {
|
||||
if (bIgnoreEntities) {
|
||||
cgi.CM_BoxTrace(
|
||||
&trace,
|
||||
vTraceStart,
|
||||
vTraceEnd,
|
||||
vec_zero,
|
||||
vec_zero,
|
||||
0,
|
||||
MASK_SHOT,
|
||||
qfalse
|
||||
);
|
||||
cgi.CM_BoxTrace(&trace, vTraceStart, vTraceEnd, vec_zero, vec_zero, 0, MASK_SHOT, qfalse);
|
||||
|
||||
if (trace.fraction == 1.0f) {
|
||||
trace.entityNum = ENTITYNUM_NONE;
|
||||
@@ -533,8 +546,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
if (trace.startsolid) {
|
||||
trace.entityNum = ENTITYNUM_WORLD;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
CG_Trace(
|
||||
&trace,
|
||||
vTraceStart,
|
||||
@@ -556,35 +568,29 @@ static void CG_MakeBulletTracerInternal(
|
||||
VectorNormalizeFast(trace.plane.normal);
|
||||
}
|
||||
|
||||
if (!bInWater && trace.fraction < 1.0f && iNumImpacts <= 127)
|
||||
{
|
||||
if (!bInWater && trace.fraction < 1.0f && iNumImpacts <= 127) {
|
||||
memcpy(&tImpacts[iNumImpacts], &trace, sizeof(trace_t));
|
||||
iNumImpacts++;
|
||||
}
|
||||
|
||||
if (iTracerVisible && !bMadeTracer)
|
||||
{
|
||||
CG_BulletTracerEffect(vTrailStart, trace.endpos);
|
||||
if (iTracerVisible && !bMadeTracer) {
|
||||
CG_BulletTracerEffect(vTrailStart, trace.endpos, iLarge, alpha);
|
||||
bMadeTracer = qtrue;
|
||||
}
|
||||
|
||||
if (trace.fraction < 1.0f) {
|
||||
if (((trace.surfaceFlags & (SURF_HINT | SURF_NODLIGHT | SURF_SNOW | SURF_FOLIAGE | SURF_DIRT)) || (trace.contents & CONTENTS_WATER))
|
||||
&& iContinueCount < 5)
|
||||
{
|
||||
if (bInWater)
|
||||
{
|
||||
if (((trace.surfaceFlags & (SURF_HINT | SURF_NODLIGHT | SURF_SNOW | SURF_FOLIAGE | SURF_DIRT))
|
||||
|| (trace.contents & CONTENTS_WATER))
|
||||
&& iContinueCount < 5) {
|
||||
if (bInWater) {
|
||||
VectorSubtract(trace.endpos, vDir, vTmp);
|
||||
if (!(trace.contents & CONTENTS_FLUID)
|
||||
&& !(trace.surfaceFlags & SURF_PUDDLE)
|
||||
&& !(cgi.CM_PointContents(vTmp, 0) & CONTENTS_FLUID))
|
||||
{
|
||||
CG_MakeBubbleTrail(vTrailStart, trace.endpos, iLarge);
|
||||
if (!(trace.contents & CONTENTS_FLUID) && !(trace.surfaceFlags & SURF_PUDDLE)
|
||||
&& !(cgi.CM_PointContents(vTmp, 0) & CONTENTS_FLUID)) {
|
||||
CG_MakeBubbleTrail(vTrailStart, trace.endpos, iLarge, alpha);
|
||||
VectorCopy(trace.endpos, vTrailStart);
|
||||
bInWater = qfalse;
|
||||
}
|
||||
}
|
||||
else if ((trace.contents & CONTENTS_FLUID) || (trace.surfaceFlags & SURF_PUDDLE)) {
|
||||
} else if ((trace.contents & CONTENTS_FLUID) || (trace.surfaceFlags & SURF_PUDDLE)) {
|
||||
VectorCopy(trace.endpos, vTrailStart);
|
||||
bInWater = qtrue;
|
||||
}
|
||||
@@ -593,11 +599,9 @@ static void CG_MakeBulletTracerInternal(
|
||||
VectorAdd(vTraceStart, vTraceStart, trace.endpos);
|
||||
|
||||
iContinueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
trace.fraction = 1.0f;
|
||||
bBulletDone = qtrue;
|
||||
bBulletDone = qtrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,14 +609,14 @@ static void CG_MakeBulletTracerInternal(
|
||||
}
|
||||
|
||||
if (bInWater) {
|
||||
CG_MakeBubbleTrail(vTraceStart, trace.endpos, iLarge);
|
||||
CG_MakeBubbleTrail(vTraceStart, trace.endpos, iLarge, alpha);
|
||||
}
|
||||
|
||||
if (iTracerVisible) {
|
||||
iTracerVisible--;
|
||||
}
|
||||
|
||||
fLen = ProjectPointOnLine(i_vStart, i_vEnd[iBullet], cg.SoundOrg, vPos);
|
||||
fLen = ProjectPointOnLine(i_vStart, i_vEnd[iBullet], cg.SoundOrg, vPos);
|
||||
iHeadDist = (int)Distance(vPos, cg.SoundOrg);
|
||||
if (iHeadDist > 255) {
|
||||
continue;
|
||||
@@ -629,7 +633,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
|
||||
if (fLen < 0.f) {
|
||||
VectorCopy(i_vStart, vPos);
|
||||
} else if(fDist >= fLen) {
|
||||
} else if (fDist >= fLen) {
|
||||
VectorCopy(i_vEnd[iBullet], vPos);
|
||||
}
|
||||
|
||||
@@ -652,11 +656,11 @@ static void CG_MakeBulletTracerInternal(
|
||||
}
|
||||
|
||||
if (iNumImpacts > 2) {
|
||||
fImpSndDistRA = 9999.0f;
|
||||
fImpSndDistRB = 9999.0f;
|
||||
fImpSndDistRA = 9999.0f;
|
||||
fImpSndDistRB = 9999.0f;
|
||||
iImpSndIndexRA = 0;
|
||||
iImpSndIndexRB = 0;
|
||||
fImpSndDistLB = 9999.0f;
|
||||
fImpSndDistLB = 9999.0f;
|
||||
iImpSndIndexLB = 0;
|
||||
|
||||
for (iBullet = 0; iBullet < iNumImpacts; iBullet++) {
|
||||
@@ -671,27 +675,23 @@ static void CG_MakeBulletTracerInternal(
|
||||
VectorSubtract(tImpacts[iImpSndIndexLB].endpos, cg.SoundOrg, vTmp);
|
||||
iHeadDist = VectorLength(vTmp);
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) <= 0.f)
|
||||
{
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) <= 0.f) {
|
||||
if (iHeadDist < 9999.0f || iHeadDist < fImpSndDistLB) {
|
||||
if (iHeadDist < 9999.0f) {
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistLB = 9999.0;
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistLB = 9999.0;
|
||||
iImpSndIndexRA = iBullet;
|
||||
} else if (iHeadDist < fImpSndDistLB) {
|
||||
fImpSndDistLB = iHeadDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB)
|
||||
{
|
||||
} else {
|
||||
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB) {
|
||||
if (iHeadDist < fImpSndDistRA) {
|
||||
iImpSndIndexRB = iImpSndIndexRA;
|
||||
iImpSndIndexRA = iBullet;
|
||||
} else if (iHeadDist < fImpSndDistRB) {
|
||||
fImpSndDistRB = iHeadDist;
|
||||
fImpSndDistRB = iHeadDist;
|
||||
iImpSndIndexRB = iBullet;
|
||||
}
|
||||
}
|
||||
@@ -720,11 +720,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
} else {
|
||||
for (iBullet = 0; iBullet < iNumImpacts; iBullet++) {
|
||||
CG_MakeBulletHole(
|
||||
tImpacts[iBullet].endpos,
|
||||
tImpacts[iBullet].plane.normal,
|
||||
iNumImpacts,
|
||||
&tImpacts[iBullet],
|
||||
qtrue
|
||||
tImpacts[iBullet].endpos, tImpacts[iBullet].plane.normal, iNumImpacts, &tImpacts[iBullet], qtrue
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -732,10 +728,10 @@ static void CG_MakeBulletTracerInternal(
|
||||
if (fZingDistA < 9999.0f) {
|
||||
if (iLarge) {
|
||||
fVolume = 1.0f;
|
||||
fPitch = 0.8f;
|
||||
fPitch = 0.8f;
|
||||
} else {
|
||||
fVolume = 0.8f;
|
||||
fPitch = 1.0f;
|
||||
fPitch = 1.0f;
|
||||
}
|
||||
|
||||
commandManager.PlaySound("snd_b_zing", vZingPosA, -1, fVolume, -1.0f, fPitch, 1);
|
||||
@@ -774,13 +770,14 @@ static void CG_MakeBulletTracer(
|
||||
bullet_tracer->i_vEnd = &bullet_tracer_bullets[bullet_tracers_count];
|
||||
bullet_tracer->i_iNumBullets = i_iNumBullets;
|
||||
|
||||
for (i = 0; i < i_iNumBullets; ++i) {
|
||||
bullet_tracer_bullets[bullet_tracers_count][0] = (*i_vEnd)[i];
|
||||
bullet_tracer_bullets[bullet_tracers_count][1] = (*i_vEnd)[i + 1];
|
||||
bullet_tracer_bullets[bullet_tracers_count++][2] = (*i_vEnd)[i + 2];
|
||||
for (i = 0; i < i_iNumBullets; i++, bullet_tracers_count++) {
|
||||
bullet_tracer_bullets[bullet_tracers_count][0] = i_vEnd[i][0];
|
||||
bullet_tracer_bullets[bullet_tracers_count][1] = i_vEnd[i][1];
|
||||
bullet_tracer_bullets[bullet_tracers_count][2] = i_vEnd[i][2];
|
||||
}
|
||||
|
||||
bullet_tracer->iLarge = iLarge;
|
||||
bullet_tracer->alpha = alpha;
|
||||
bullet_tracer->iTracerVisible = iTracerVisible;
|
||||
bullet_tracer->bIgnoreEntities = bIgnoreEntities;
|
||||
}
|
||||
@@ -797,7 +794,8 @@ void CG_AddBulletTracers()
|
||||
bullet_tracers[i].i_iNumBullets,
|
||||
bullet_tracers[i].iLarge,
|
||||
bullet_tracers[i].iTracerVisible,
|
||||
bullet_tracers[i].bIgnoreEntities
|
||||
bullet_tracers[i].bIgnoreEntities,
|
||||
bullet_tracers[i].alpha
|
||||
);
|
||||
}
|
||||
|
||||
@@ -807,26 +805,24 @@ void CG_AddBulletTracers()
|
||||
|
||||
void CG_AddBulletImpacts()
|
||||
{
|
||||
int i;
|
||||
int iHeadDist;
|
||||
float fVolume;
|
||||
float fImpSndDistRA;
|
||||
int i;
|
||||
int iHeadDist;
|
||||
float fVolume;
|
||||
float fImpSndDistRA;
|
||||
static float fImpSndDistLA = 9999.f;
|
||||
float fImpSndDistRB;
|
||||
float fImpSndDistLB;
|
||||
int iImpSndIndexRA;
|
||||
int iImpSndIndexRB;
|
||||
int iImpSndIndexLB;
|
||||
vec3_t vTmp;
|
||||
str sSoundName;
|
||||
float fImpSndDistRB;
|
||||
float fImpSndDistLB;
|
||||
int iImpSndIndexRA;
|
||||
int iImpSndIndexRB;
|
||||
int iImpSndIndexLB;
|
||||
vec3_t vTmp;
|
||||
str sSoundName;
|
||||
|
||||
if (wall_impact_count)
|
||||
{
|
||||
if (wall_impact_count > 4)
|
||||
{
|
||||
fImpSndDistRA = fImpSndDistLA;
|
||||
fImpSndDistRB = fImpSndDistLA;
|
||||
fImpSndDistLB = fImpSndDistLA;
|
||||
if (wall_impact_count) {
|
||||
if (wall_impact_count > 4) {
|
||||
fImpSndDistRA = fImpSndDistLA;
|
||||
fImpSndDistRB = fImpSndDistLA;
|
||||
fImpSndDistLB = fImpSndDistLA;
|
||||
iImpSndIndexRA = 0;
|
||||
iImpSndIndexRB = 0;
|
||||
iImpSndIndexLB = 0;
|
||||
@@ -834,33 +830,28 @@ void CG_AddBulletImpacts()
|
||||
for (i = 0; i < wall_impact_count; i++) {
|
||||
VectorSubtract(wall_impact_pos[i], cg.SoundOrg, vTmp);
|
||||
iHeadDist = VectorLength(vTmp);
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f)
|
||||
{
|
||||
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB)
|
||||
{
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f) {
|
||||
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB) {
|
||||
if (iHeadDist < fImpSndDistRA) {
|
||||
fImpSndDistRB = fImpSndDistRA;
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistRB = fImpSndDistRA;
|
||||
fImpSndDistRA = iHeadDist;
|
||||
iImpSndIndexRB = iImpSndIndexRA;
|
||||
iImpSndIndexRA = i;
|
||||
} else if (iHeadDist < fImpSndDistRB) {
|
||||
fImpSndDistRB = iHeadDist;
|
||||
fImpSndDistRB = iHeadDist;
|
||||
iImpSndIndexRB = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iHeadDist < fImpSndDistLA || iHeadDist < fImpSndDistLB)
|
||||
{
|
||||
} else {
|
||||
if (iHeadDist < fImpSndDistLA || iHeadDist < fImpSndDistLB) {
|
||||
if (iHeadDist < fImpSndDistLA) {
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistLB = fImpSndDistLA;
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistLB = fImpSndDistLA;
|
||||
iImpSndIndexLB = 0;
|
||||
iImpSndIndexRA = i;
|
||||
} else if (iHeadDist < fImpSndDistLB) {
|
||||
fImpSndDistLB = iHeadDist;
|
||||
fImpSndDistLB = iHeadDist;
|
||||
iImpSndIndexLB = i;
|
||||
}
|
||||
}
|
||||
@@ -908,8 +899,7 @@ void CG_AddBulletImpacts()
|
||||
|
||||
if (wall_impact_type[iImpSndIndexRB] == 2 || wall_impact_type[iImpSndIndexRB] == 3) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
}
|
||||
|
||||
@@ -942,26 +932,15 @@ void CG_AddBulletImpacts()
|
||||
|
||||
if (wall_impact_type[0] == 2 || wall_impact_type[0] == 3) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
}
|
||||
|
||||
commandManager.PlaySound(sSoundName, wall_impact_pos[0], -1, fVolume, -1, -1, 1);
|
||||
|
||||
sfxManager.MakeEffect_Normal(
|
||||
wall_impact_type[0],
|
||||
wall_impact_pos[0],
|
||||
wall_impact_norm[0]
|
||||
);
|
||||
sfxManager.MakeEffect_Normal(wall_impact_type[0], wall_impact_pos[0], wall_impact_norm[0]);
|
||||
} else {
|
||||
CG_MakeBulletHole(
|
||||
wall_impact_pos[0],
|
||||
wall_impact_norm[0],
|
||||
wall_impact_large[0],
|
||||
NULL,
|
||||
qtrue
|
||||
);
|
||||
CG_MakeBulletHole(wall_impact_pos[0], wall_impact_norm[0], wall_impact_large[0], NULL, qtrue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -969,15 +948,13 @@ void CG_AddBulletImpacts()
|
||||
if (wall_impact_type[iImpSndIndexLB]) {
|
||||
if (wall_impact_large[iImpSndIndexLB]) {
|
||||
fVolume = 1.f;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fVolume = 0.75f;
|
||||
}
|
||||
|
||||
if (wall_impact_type[iImpSndIndexLB] == 2 || wall_impact_type[iImpSndIndexLB] == 3) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
}
|
||||
|
||||
@@ -998,45 +975,31 @@ void CG_AddBulletImpacts()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
for (i = 0; i < wall_impact_count; i++) {
|
||||
CG_MakeBulletHole(
|
||||
wall_impact_pos[i],
|
||||
wall_impact_norm[i],
|
||||
wall_impact_large[i],
|
||||
NULL,
|
||||
qtrue
|
||||
);
|
||||
CG_MakeBulletHole(wall_impact_pos[i], wall_impact_norm[i], wall_impact_large[i], NULL, qtrue);
|
||||
}
|
||||
}
|
||||
|
||||
wall_impact_count = 0;
|
||||
}
|
||||
|
||||
if (flesh_impact_count)
|
||||
{
|
||||
if (flesh_impact_count > 1)
|
||||
{
|
||||
fImpSndDistRA = 9999.0;
|
||||
if (flesh_impact_count) {
|
||||
if (flesh_impact_count > 1) {
|
||||
fImpSndDistRA = 9999.0;
|
||||
iImpSndIndexRA = 0;
|
||||
|
||||
for (i = 0; i < flesh_impact_count; i++) {
|
||||
VectorSubtract(wall_impact_pos[i], cg.SoundOrg, vTmp);
|
||||
iHeadDist = VectorLength(vTmp);
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f)
|
||||
{
|
||||
if (iHeadDist < fImpSndDistRA)
|
||||
{
|
||||
fImpSndDistRA = iHeadDist;
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f) {
|
||||
if (iHeadDist < fImpSndDistRA) {
|
||||
fImpSndDistRA = iHeadDist;
|
||||
iImpSndIndexRA = i;
|
||||
}
|
||||
}
|
||||
else if (iHeadDist < fImpSndDistLA)
|
||||
{
|
||||
fImpSndDistRA = iHeadDist;
|
||||
} else if (iHeadDist < fImpSndDistLA) {
|
||||
fImpSndDistRA = iHeadDist;
|
||||
iImpSndIndexRA = i;
|
||||
}
|
||||
}
|
||||
@@ -1105,8 +1068,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_SNOW:
|
||||
switch (iBaseEffect)
|
||||
{
|
||||
switch (iBaseEffect) {
|
||||
case SFX_EXP_TANK_BASE:
|
||||
iSurfEffect = SFX_EXP_TANK_SNOW;
|
||||
break;
|
||||
@@ -1122,7 +1084,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
iBaseEffect = -1;
|
||||
break;
|
||||
}
|
||||
fRadius = 0;
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_CARPET:
|
||||
iSurfEffect = SFX_EXP_GREN_CARPET;
|
||||
@@ -1147,8 +1109,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_DIRT:
|
||||
switch (iBaseEffect)
|
||||
{
|
||||
switch (iBaseEffect) {
|
||||
case SFX_EXP_TANK_BASE:
|
||||
iSurfEffect = SFX_EXP_TANK_DIRT;
|
||||
break;
|
||||
@@ -1164,15 +1125,14 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
iBaseEffect = -1;
|
||||
break;
|
||||
}
|
||||
fRadius = 0;
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_GRILL:
|
||||
iSurfEffect = SFX_EXP_GREN_GRILL;
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_GRASS:
|
||||
switch (iBaseEffect)
|
||||
{
|
||||
switch (iBaseEffect) {
|
||||
case SFX_EXP_TANK_BASE:
|
||||
iSurfEffect = SFX_EXP_TANK_DIRT;
|
||||
break;
|
||||
@@ -1190,8 +1150,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_ROCK:
|
||||
switch (iBaseEffect)
|
||||
{
|
||||
switch (iBaseEffect) {
|
||||
case SFX_EXP_TANK_BASE:
|
||||
iSurfEffect = SFX_EXP_TANK_STONE;
|
||||
break;
|
||||
|
||||
@@ -25,6 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// interpolating between snapshots from the server or locally predicting
|
||||
// ahead the client's movement. It also handles local physics interaction,
|
||||
// like fragments bouncing off walls
|
||||
//
|
||||
// ADDITIONS:
|
||||
// - CG_InterpolatePlayerState() footer: Interpolate the lean angles
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
@@ -405,6 +408,9 @@ static void CG_InterpolatePlayerState(qboolean grabAngles)
|
||||
}
|
||||
out->velocity[i] = prev->ps.velocity[i] + f * (next->ps.velocity[i] - prev->ps.velocity[i]);
|
||||
}
|
||||
|
||||
// interpolate the lean angle
|
||||
out->fLeanAngle = LerpAngle(prev->ps.fLeanAngle, next->ps.fLeanAngle, f);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -137,6 +137,8 @@ functions exported to the main executable
|
||||
void (*FS_FreeFile)(void *buf);
|
||||
int (*FS_WriteFile)(const char *qpath, const void *buffer, int size);
|
||||
void (*FS_WriteTextFile)(const char *qpath, const void *buffer, int size);
|
||||
char** (*FS_ListFilteredFiles)(const char* path, const char* extension, const char* filter, qboolean wantSubs, int* numfiles, qboolean allowNonPureFilesOnDisk);
|
||||
void (*FS_FreeFileList)(char **list);
|
||||
// add commands to the local console as if they were typed in
|
||||
// for map changing, etc. The command is not executed immediately,
|
||||
// but will be executed in order the next time console commands
|
||||
@@ -163,7 +165,7 @@ functions exported to the main executable
|
||||
void (*SendClientCommand)(const char *s);
|
||||
|
||||
// CM functions
|
||||
void (*CM_LoadMap)(const char *name);
|
||||
void (*CM_LoadMap)(const char *name, int* checksum);
|
||||
clipHandle_t (*CM_InlineModel)(int index); // 0 = world, 1+ = bmodels
|
||||
int (*CM_NumInlineModels)(void);
|
||||
int (*CM_PointContents)(const vec3_t p, int headnode);
|
||||
@@ -283,9 +285,11 @@ functions exported to the main executable
|
||||
qhandle_t (*R_RegisterModel)(const char *name);
|
||||
qhandle_t (*R_SpawnEffectModel)(const char *name, vec3_t pos, vec3_t axis[3]);
|
||||
qhandle_t (*R_RegisterServerModel)(const char *name);
|
||||
const char * (*R_GetModelName)(qhandle_t hModel);
|
||||
void (*R_UnregisterServerModel)(qhandle_t hModel);
|
||||
qhandle_t (*R_RegisterShader)(const char *name);
|
||||
qhandle_t (*R_RegisterShaderNoMip)(const char *name);
|
||||
const char* (*R_GetShaderName)(qhandle_t hShader);
|
||||
void (*R_AddRefEntityToScene)(const refEntity_t *ent, int parentEntityNumber);
|
||||
void (*R_AddRefSpriteToScene)(const refEntity_t *ent);
|
||||
void (*R_AddLightToScene)(const vec3_t origin, float intensity, float r, float g, float b, int type);
|
||||
@@ -499,8 +503,8 @@ functions exported to the main executable
|
||||
//
|
||||
void (*CG_ReadNonPVSClient)(radarUnpacked_t* radarUnpacked);
|
||||
void (*CG_UpdateRadar)();
|
||||
void (*CG_SaveStateToBuffer)(void** out, int svsTime);
|
||||
void (*CG_LoadStateToBuffer)(void** state, int size, int svsTime);
|
||||
size_t (*CG_SaveStateToBuffer)(void** out, int svsTime);
|
||||
qboolean (*CG_LoadStateToBuffer)(void* state, size_t size, int svsTime);
|
||||
void (*CG_CleanUpTempModels)();
|
||||
|
||||
// FIXME
|
||||
|
||||
+59
-13
@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// cg_servercmds.c -- text commands sent by the server
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "../fgame/bg_voteoptions.h"
|
||||
|
||||
static const char *IsWeaponAllowed(int dmFlags, int flags)
|
||||
{
|
||||
@@ -112,6 +113,7 @@ void CG_ParseServerinfo(void)
|
||||
char map[MAX_QPATH];
|
||||
char *spawnpos;
|
||||
const char *version;
|
||||
const char *mapChecksumStr;
|
||||
|
||||
info = CG_ConfigString(CS_SERVERINFO);
|
||||
cgs.gametype = atoi(Info_ValueForKey(info, "g_gametype"));
|
||||
@@ -135,12 +137,23 @@ void CG_ParseServerinfo(void)
|
||||
cgi.Cvar_Set("cg_obj_alliedtext1", Info_ValueForKey(info, "g_obj_alliedtext1"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext2", Info_ValueForKey(info, "g_obj_alliedtext2"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext3", Info_ValueForKey(info, "g_obj_alliedtext3"));
|
||||
cgi.Cvar_Set("cg_obj_axistext1", Info_ValueForKey(info, "cg_obj_axistext1"));
|
||||
cgi.Cvar_Set("cg_obj_axistext2", Info_ValueForKey(info, "cg_obj_axistext2"));
|
||||
cgi.Cvar_Set("cg_obj_axistext3", Info_ValueForKey(info, "cg_obj_axistext3"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext4", Info_ValueForKey(info, "g_obj_alliedtext4"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext5", Info_ValueForKey(info, "g_obj_alliedtext5"));
|
||||
cgi.Cvar_Set("cg_obj_axistext1", Info_ValueForKey(info, "g_obj_axistext1"));
|
||||
cgi.Cvar_Set("cg_obj_axistext2", Info_ValueForKey(info, "g_obj_axistext2"));
|
||||
cgi.Cvar_Set("cg_obj_axistext3", Info_ValueForKey(info, "g_obj_axistext3"));
|
||||
cgi.Cvar_Set("cg_obj_axistext4", Info_ValueForKey(info, "g_obj_axistext4"));
|
||||
cgi.Cvar_Set("cg_obj_axistext5", Info_ValueForKey(info, "g_obj_axistext5"));
|
||||
cgi.Cvar_Set("cg_scoreboardpic", Info_ValueForKey(info, "g_scoreboardpic"));
|
||||
cgi.Cvar_Set("cg_scoreboardpicover", Info_ValueForKey(info, "g_scoreboardpicover"));
|
||||
cgs.mapChecksum = atoi(Info_ValueForKey(info, "sv_mapChecksum"));
|
||||
mapChecksumStr = Info_ValueForKey(info, "sv_mapChecksum");
|
||||
if (mapChecksumStr && mapChecksumStr[0]) {
|
||||
cgs.mapChecksum = atoi(mapChecksumStr);
|
||||
cgs.useMapChecksum = qtrue;
|
||||
} else {
|
||||
cgs.mapChecksum = 0;
|
||||
cgs.useMapChecksum = qfalse;
|
||||
}
|
||||
|
||||
mapname = Info_ValueForKey(info, "mapname");
|
||||
|
||||
@@ -184,17 +197,13 @@ CG_ConfigStringModified
|
||||
|
||||
================
|
||||
*/
|
||||
static void CG_ConfigStringModified(void)
|
||||
static void CG_ConfigStringModified(int num, qboolean modelOnly)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = atoi(cgi.Argv(1));
|
||||
|
||||
// get the gamestate from the client system, which will have the
|
||||
// new configstring already integrated
|
||||
cgi.GetGameState(&cgs.gameState);
|
||||
|
||||
CG_ProcessConfigString(num);
|
||||
CG_ProcessConfigString(num, modelOnly);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -275,7 +284,7 @@ The string has been tokenized and can be retrieved with
|
||||
Cmd_Argc() / Cmd_Argv()
|
||||
=================
|
||||
*/
|
||||
static void CG_ServerCommand(void)
|
||||
static void CG_ServerCommand(qboolean modelOnly)
|
||||
{
|
||||
const char *cmd;
|
||||
|
||||
@@ -287,7 +296,11 @@ static void CG_ServerCommand(void)
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "cs")) {
|
||||
CG_ConfigStringModified();
|
||||
CG_ConfigStringModified(atoi(cgi.Argv(1)), modelOnly);
|
||||
return;
|
||||
}
|
||||
|
||||
if (modelOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -364,6 +377,28 @@ static void CG_ServerCommand(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "voteresult")) {
|
||||
cmd = cgi.Argv(1);
|
||||
if (*cmd) {
|
||||
strcmp(cmd, "passed");
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "vo0")) {
|
||||
CG_VoteOptions_StartReadFromServer(cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "vo1")) {
|
||||
CG_VoteOptions_ContinueReadFromServer(cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "vo2")) {
|
||||
CG_VoteOptions_FinishReadFromServer(cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
cgi.Printf("Unknown client game command: %s\n", cmd);
|
||||
}
|
||||
|
||||
@@ -377,9 +412,20 @@ with this this snapshot.
|
||||
*/
|
||||
void CG_ExecuteNewServerCommands(int latestSequence, qboolean differentServer)
|
||||
{
|
||||
int lastServerCommandSequence;
|
||||
|
||||
lastServerCommandSequence = cgs.serverCommandSequence;
|
||||
|
||||
while (cgs.serverCommandSequence < latestSequence) {
|
||||
if (cgi.GetServerCommand(++cgs.serverCommandSequence, differentServer)) {
|
||||
CG_ServerCommand();
|
||||
CG_ServerCommand(qtrue);
|
||||
}
|
||||
}
|
||||
|
||||
cgs.serverCommandSequence = lastServerCommandSequence;
|
||||
while (cgs.serverCommandSequence < latestSequence) {
|
||||
if (cgi.GetServerCommand(++cgs.serverCommandSequence, differentServer)) {
|
||||
CG_ServerCommand(qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// DESCRIPTION:
|
||||
// things that happen on snapshot transition, not necessarily every
|
||||
// single frame
|
||||
//
|
||||
// ADDITIONS:
|
||||
// - CG_TransitionSnapshot() footer: set ps.walking to true if the ps has a ground entity
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_radar.h"
|
||||
#include "tiki.h"
|
||||
|
||||
/*
|
||||
@@ -206,6 +210,9 @@ static void CG_TransitionSnapshot(qboolean differentServer)
|
||||
cent->teleported = qfalse;
|
||||
}
|
||||
CG_TransitionEntity(cent);
|
||||
|
||||
// remember time of snapshot this entity was last updated in
|
||||
cent->snapShotTime = cg.snap->serverTime;
|
||||
}
|
||||
|
||||
for (i = 0; i < cg.snap->number_of_sounds; i++) {
|
||||
@@ -243,6 +250,15 @@ static void CG_TransitionSnapshot(qboolean differentServer)
|
||||
CG_TransitionPlayerState(ps, ops);
|
||||
}
|
||||
}
|
||||
|
||||
if (differentServer) {
|
||||
cgi.CL_RestoreSavedCgameState();
|
||||
} else {
|
||||
cgi.CL_ClearSavedCgameState();
|
||||
}
|
||||
|
||||
// this allows the view model to still look normal when the player is on ground
|
||||
cg.snap->ps.walking = cg.snap->ps.groundEntityNum != ENTITYNUM_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+218
-114
@@ -28,6 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "tiki.h"
|
||||
|
||||
cvar_t *cg_showtempmodels;
|
||||
cvar_t *cg_max_tempmodels;
|
||||
cvar_t *cg_reserve_tempmodels;
|
||||
cvar_t *cg_detail;
|
||||
cvar_t *cg_effectdetail;
|
||||
cvar_t *cg_effect_physicsrate;
|
||||
@@ -86,6 +88,83 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
|
||||
m_free_tempmodels = p;
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeAllTempModels
|
||||
//===============
|
||||
void ClientGameCommandManager::FreeAllTempModels(void)
|
||||
{
|
||||
ctempmodel_t *p, *next;
|
||||
|
||||
// Go through all the temp models and run the physics if necessary,
|
||||
// then add them to the ref
|
||||
p = m_active_tempmodels.prev;
|
||||
for (; p != &m_active_tempmodels; p = next) {
|
||||
// grab next now, so if the local entity is freed we still have it
|
||||
next = p->prev;
|
||||
FreeTempModel(p);
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeSomeTempModels
|
||||
//===============
|
||||
void ClientGameCommandManager::FreeSomeTempModels(void)
|
||||
{
|
||||
ctempmodel_t* model;
|
||||
int count = 0;
|
||||
unsigned int i;
|
||||
unsigned int numToFree;
|
||||
|
||||
if (!m_free_tempmodels) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (model = m_active_tempmodels.prev; model != &m_active_tempmodels; model = model->prev) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (cg_reserve_tempmodels->integer <= (cg_max_tempmodels->integer - count)) {
|
||||
// nothing to free
|
||||
return;
|
||||
}
|
||||
|
||||
numToFree = cg_reserve_tempmodels->integer - (cg_max_tempmodels->integer - count);
|
||||
|
||||
for (i = 0; i < numToFree; i++) {
|
||||
FreeTempModel(m_active_tempmodels.prev);
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeSpawnthing
|
||||
//===============
|
||||
void ClientGameCommandManager::FreeSpawnthing(spawnthing_t* sp)
|
||||
{
|
||||
ctempmodel_t* model;
|
||||
ctempmodel_t* prev;
|
||||
|
||||
if (sp->numtempmodels) {
|
||||
for (model = m_active_tempmodels.prev; model != &m_active_tempmodels; model = prev) {
|
||||
prev = model->prev;
|
||||
|
||||
if (model->m_spawnthing == sp) {
|
||||
FreeTempModel(model);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_emitters.RemoveObject(sp);
|
||||
|
||||
if (sp == m_spawnthing) {
|
||||
m_spawnthing = NULL;
|
||||
}
|
||||
|
||||
delete sp;
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// ResetTempModels
|
||||
//===============
|
||||
void ClientGameCommandManager::ResetTempModels(void)
|
||||
{
|
||||
// Go through all the active tempmodels and free them
|
||||
@@ -99,6 +178,7 @@ void ClientGameCommandManager::ResetTempModels(void)
|
||||
}
|
||||
|
||||
static int lastTempModelFrameTime = 0;
|
||||
int next_tempmodel_warning = 0;
|
||||
|
||||
void CG_ResetTempModels(void)
|
||||
{
|
||||
@@ -128,9 +208,23 @@ void ClientGameCommandManager::InitializeTempModels(void)
|
||||
void ClientGameCommandManager::InitializeTempModelCvars(void)
|
||||
{
|
||||
cg_showtempmodels = cgi.Cvar_Get("cg_showtempmodels", "0", 0);
|
||||
cg_detail = cgi.Cvar_Get("detail", "1", 1);
|
||||
cg_effectdetail = cgi.Cvar_Get("cg_effectdetail", "0.2", 1);
|
||||
cg_effect_physicsrate = cgi.Cvar_Get("cg_effect_physicsrate", "10", 1);
|
||||
cg_detail = cgi.Cvar_Get("detail", "1", CVAR_ARCHIVE);
|
||||
cg_effectdetail = cgi.Cvar_Get("cg_effectdetail", "0.2", CVAR_ARCHIVE);
|
||||
cg_effect_physicsrate = cgi.Cvar_Get("cg_effect_physicsrate", "10", CVAR_ARCHIVE);
|
||||
cg_max_tempmodels = cgi.Cvar_Get("cg_max_tempmodels", "1100", CVAR_ARCHIVE);
|
||||
cg_reserve_tempmodels = cgi.Cvar_Get("cg_reserve_tempmodels", "200", CVAR_ARCHIVE);
|
||||
|
||||
if (cg_max_tempmodels->integer > MAX_TEMPMODELS) {
|
||||
// 2.40 sets the integer value directly rather than calling Cvar_Set()
|
||||
//cg_max_tempmodels->integer = MAX_TEMPMODELS
|
||||
cgi.Cvar_Set("cg_max_tempmodels", va("%i", MAX_TEMPMODELS));
|
||||
}
|
||||
|
||||
if (cg_reserve_tempmodels->integer * 5 > cg_max_tempmodels->integer) {
|
||||
// 2.40 sets the integer value directly rather than calling Cvar_Set()
|
||||
//cg_reserve_tempmodels->integer = cg_max_tempmodels->integer / 5;
|
||||
cgi.Cvar_Set("cg_reserve_tempmodels", va("%i", cg_max_tempmodels->integer / 5));
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
@@ -141,6 +235,7 @@ void ClientGameCommandManager::AnimateTempModel(ctempmodel_t *p, Vector origin,
|
||||
int numframes;
|
||||
int deltatime;
|
||||
int frametime;
|
||||
float prev;
|
||||
|
||||
// This code is for animating tempmodels that are spawned from the client
|
||||
// side
|
||||
@@ -165,10 +260,18 @@ void ClientGameCommandManager::AnimateTempModel(ctempmodel_t *p, Vector origin,
|
||||
|
||||
// Go through all the frames, and process any commands associated with the
|
||||
// tempmodel as well
|
||||
prev = deltatime;
|
||||
while (deltatime >= frametime) {
|
||||
deltatime -= frametime;
|
||||
p->lastAnimTime += frametime;
|
||||
p->ent.wasframe = (p->ent.wasframe + 1) % numframes;
|
||||
CG_ProcessEntityCommands(p->ent.wasframe, p->ent.frameInfo[0].index, -1, &p->ent, NULL);
|
||||
|
||||
if (deltatime == prev) {
|
||||
break;
|
||||
}
|
||||
|
||||
prev = deltatime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,9 +311,10 @@ void ClientGameCommandManager::UpdateSwarm(ctempmodel_t *p)
|
||||
}
|
||||
}
|
||||
|
||||
qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float dtime, float scale)
|
||||
qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float scale)
|
||||
{
|
||||
float fade, fadein;
|
||||
float dtime;
|
||||
byte tempColor[4];
|
||||
|
||||
if (p->cgd.flags & (T_FADE | T_SCALEUPDOWN)) {
|
||||
@@ -362,9 +466,19 @@ void ClientGameCommandManager::OtherTempModelEffects(ctempmodel_t *p, Vector ori
|
||||
vec3_t axis[3];
|
||||
|
||||
if (p->number != -1) {
|
||||
refEntity_t *old_entity;
|
||||
dtiki_t *old_tiki;
|
||||
int oldnum;
|
||||
float oldscale;
|
||||
|
||||
// Set the axis
|
||||
AnglesToAxis(p->cgd.angles, axis);
|
||||
|
||||
old_entity = current_entity;
|
||||
old_tiki = current_tiki;
|
||||
oldnum = current_entity_number;
|
||||
oldscale = current_scale;
|
||||
|
||||
current_scale = newEnt->scale;
|
||||
current_entity = newEnt;
|
||||
current_tiki = p->cgd.tiki;
|
||||
@@ -380,14 +494,23 @@ void ClientGameCommandManager::OtherTempModelEffects(ctempmodel_t *p, Vector ori
|
||||
commandManager.ProcessEvent(ev);
|
||||
}
|
||||
|
||||
current_entity_number = -1;
|
||||
current_tiki = NULL;
|
||||
current_entity = NULL;
|
||||
current_scale = -1;
|
||||
current_entity_number = oldnum;
|
||||
current_tiki = old_tiki;
|
||||
current_entity = old_entity;
|
||||
current_scale = oldscale;
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_ALIGNSTRETCH) {
|
||||
Vector vDelta;
|
||||
float fScale;
|
||||
|
||||
vDelta = p->cgd.origin - p->cgd.oldorigin;
|
||||
fScale = vDelta.length() * p->cgd.scale2;
|
||||
VectorScale(newEnt->axis[0], fScale, newEnt->axis[0]);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime, float time2, float scale)
|
||||
qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime, float scale)
|
||||
{
|
||||
int dtime;
|
||||
Vector parentOrigin(0, 0, 0);
|
||||
@@ -406,37 +529,41 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
|
||||
// Update based on swarm
|
||||
if (p->cgd.flags & T_SWARM) {
|
||||
p->cgd.origin += ftime * p->cgd.velocity * scale;
|
||||
p->cgd.origin += p->cgd.velocity * ftime * scale;
|
||||
}
|
||||
|
||||
// Update the orign and the angles based on velocities first
|
||||
if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL)) {
|
||||
p->cgd.origin = p->cgd.origin + (p->cgd.velocity * ftime * scale) + (time2 * p->cgd.accel);
|
||||
else if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL)) {
|
||||
p->cgd.origin += p->cgd.velocity * ftime * scale;
|
||||
}
|
||||
|
||||
// If linked to the parent or hardlinked, get the parent's origin
|
||||
if ((p->cgd.flags & (T_PARENTLINK | T_HARDLINK)) && (p->cgd.parent != ENTITYNUM_NONE)) {
|
||||
centity_t *pc;
|
||||
centity_t* pc;
|
||||
refEntity_t* e;
|
||||
|
||||
pc = &cg_entities[p->cgd.parent];
|
||||
|
||||
if (pc->currentValid) {
|
||||
refEntity_t *e;
|
||||
|
||||
e = cgi.R_GetRenderEntity(p->cgd.parent);
|
||||
|
||||
if (!e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parentOrigin = e->origin;
|
||||
vectoangles(e->axis[0], parentAngles);
|
||||
} else {
|
||||
if (!pc->currentValid) {
|
||||
return false;
|
||||
}
|
||||
} else if (p->cgd.flags & T_SWARM) {
|
||||
|
||||
e = cgi.R_GetRenderEntity(p->cgd.parent);
|
||||
if (!e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parentOrigin = e->origin;
|
||||
vectoangles(e->axis[0], parentAngles);
|
||||
}
|
||||
else if (p->cgd.flags & T_SWARM) {
|
||||
p->cgd.parentOrigin = p->cgd.velocity + p->cgd.accel * ftime * scale;
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_WATERONLY) {
|
||||
if (!(cgi.CM_PointContents(p->cgd.origin, 0) & (CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Align the object along it's traveling vector
|
||||
if (p->cgd.flags & T_ALIGN) {
|
||||
p->cgd.angles = p->cgd.velocity.toAngles();
|
||||
@@ -457,12 +584,12 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
p->cgd.angles[1] = AngleMod(p->cgd.angles[1]);
|
||||
p->cgd.angles[2] = AngleMod(p->cgd.angles[2]);
|
||||
|
||||
// Add in parent angles
|
||||
tempangles = p->cgd.angles + parentAngles;
|
||||
|
||||
// Convert to axis
|
||||
if ((p->cgd.flags & (T_ALIGN | T_RANDOMROLL | T_PARENTLINK | T_HARDLINK | T_ANGLES))
|
||||
|| (p->cgd.flags2 & T2_AMOVE)) {
|
||||
// Add in parent angles
|
||||
tempangles = p->cgd.angles + parentAngles;
|
||||
|
||||
AnglesToAxis(tempangles, p->ent.axis);
|
||||
}
|
||||
|
||||
@@ -503,25 +630,9 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_CLAMP_VEL) {
|
||||
if (p->cgd.velocity.x < p->cgd.minVel.x) {
|
||||
p->cgd.velocity.x = p->cgd.minVel.x;
|
||||
}
|
||||
if (p->cgd.velocity.y < p->cgd.minVel.y) {
|
||||
p->cgd.velocity.y = p->cgd.minVel.y;
|
||||
}
|
||||
if (p->cgd.velocity.z < p->cgd.minVel.z) {
|
||||
p->cgd.velocity.z = p->cgd.minVel.z;
|
||||
}
|
||||
|
||||
if (p->cgd.velocity.x > p->cgd.maxVel.x) {
|
||||
p->cgd.velocity.x = p->cgd.maxVel.x;
|
||||
}
|
||||
if (p->cgd.velocity.y > p->cgd.maxVel.y) {
|
||||
p->cgd.velocity.y = p->cgd.maxVel.y;
|
||||
}
|
||||
if (p->cgd.velocity.z > p->cgd.maxVel.z) {
|
||||
p->cgd.velocity.z = p->cgd.maxVel.z;
|
||||
}
|
||||
p->cgd.velocity.x = Q_clamp_float(p->cgd.velocity.x, p->cgd.minVel.x, p->cgd.maxVel.x);
|
||||
p->cgd.velocity.y = Q_clamp_float(p->cgd.velocity.y, p->cgd.minVel.y, p->cgd.maxVel.y);
|
||||
p->cgd.velocity.z = Q_clamp_float(p->cgd.velocity.z, p->cgd.minVel.z, p->cgd.maxVel.z);
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_CLAMP_VEL_AXIS) {
|
||||
@@ -530,25 +641,9 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
localVelocity.y = DotProduct(p->cgd.velocity, p->ent.axis[1]);
|
||||
localVelocity.z = DotProduct(p->cgd.velocity, p->ent.axis[2]);
|
||||
|
||||
if (localVelocity.x < p->cgd.minVel.x) {
|
||||
localVelocity.x = p->cgd.minVel.x;
|
||||
}
|
||||
if (localVelocity.y < p->cgd.minVel.y) {
|
||||
localVelocity.y = p->cgd.minVel.y;
|
||||
}
|
||||
if (localVelocity.z < p->cgd.minVel.z) {
|
||||
localVelocity.z = p->cgd.minVel.z;
|
||||
}
|
||||
|
||||
if (localVelocity.x > p->cgd.maxVel.x) {
|
||||
localVelocity.x = p->cgd.maxVel.x;
|
||||
}
|
||||
if (localVelocity.y > p->cgd.maxVel.y) {
|
||||
localVelocity.y = p->cgd.maxVel.y;
|
||||
}
|
||||
if (localVelocity.z > p->cgd.maxVel.z) {
|
||||
localVelocity.z = p->cgd.maxVel.z;
|
||||
}
|
||||
localVelocity.x = Q_clamp_float(localVelocity.x, p->cgd.minVel.x, p->cgd.maxVel.x);
|
||||
localVelocity.y = Q_clamp_float(localVelocity.y, p->cgd.minVel.y, p->cgd.maxVel.y);
|
||||
localVelocity.z = Q_clamp_float(localVelocity.z, p->cgd.minVel.z, p->cgd.maxVel.z);
|
||||
|
||||
p->cgd.velocity.x = DotProduct(localVelocity, p->ent.axis[0]);
|
||||
p->cgd.velocity.y = DotProduct(localVelocity, p->ent.axis[1]);
|
||||
@@ -559,14 +654,6 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
// FIXME: vss wind
|
||||
}
|
||||
} else {
|
||||
if (p->touchfcn) {
|
||||
p->touchfcn(p, &trace);
|
||||
}
|
||||
|
||||
if (p->cgd.flags & T_DIETOUCH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector normal;
|
||||
|
||||
// Set the origin
|
||||
@@ -581,14 +668,14 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
trace.endpos,
|
||||
trace.plane.normal,
|
||||
p->cgd.decal_orientation,
|
||||
p->cgd.decal_radius,
|
||||
p->cgd.color[0],
|
||||
p->cgd.color[1],
|
||||
p->cgd.color[2],
|
||||
p->cgd.alpha,
|
||||
p->cgd.flags & T_FADE,
|
||||
p->cgd.decal_radius,
|
||||
p->cgd.flags2 & T2_TEMPORARY_DECAL,
|
||||
p->cgd.lightstyle,
|
||||
qtrue,
|
||||
p->cgd.flags & T_FADEIN
|
||||
);
|
||||
|
||||
@@ -610,9 +697,10 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
dot = p->cgd.velocity * normal;
|
||||
p->cgd.velocity = p->cgd.velocity + ((-2 * dot) * normal);
|
||||
p->cgd.velocity *= p->cgd.bouncefactor;
|
||||
p->cgd.avelocity *= -p->cgd.bouncefactor;
|
||||
|
||||
// check for stop
|
||||
if (trace.plane.normal[2] > 0 && p->cgd.velocity[2] < 40) {
|
||||
if (trace.plane.normal[2] > 0 && p->cgd.velocity[2] < 45) {
|
||||
p->cgd.velocity = Vector(0, 0, 0);
|
||||
p->cgd.avelocity = Vector(0, 0, 0);
|
||||
p->cgd.flags &= ~T_WAVE;
|
||||
@@ -685,7 +773,7 @@ qboolean ClientGameCommandManager::LerpTempModel(refEntity_t *newEnt, ctempmodel
|
||||
// Add the parent ent's origin to the local origin
|
||||
VectorAdd(newEnt->origin, parentOrigin, newEnt->origin);
|
||||
} else {
|
||||
if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL)) {
|
||||
if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL) || (p->cgd.flags & T_SWARM)) {
|
||||
// Lerp the ent's origin
|
||||
for (i = 0; i < 3; i++) {
|
||||
newEnt->origin[i] = p->lastEnt.origin[i] + frac * (p->ent.origin[i] - p->lastEnt.origin[i]);
|
||||
@@ -741,16 +829,17 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
refEntity_t *old_ent;
|
||||
|
||||
// To counteract cg.time going backwards
|
||||
if (lastTempModelFrameTime) {
|
||||
if ((cg.time < lastTempModelFrameTime) || (cg.time - lastTempModelFrameTime > TOO_MUCH_TIME_PASSED)) {
|
||||
p = m_active_tempmodels.prev;
|
||||
for (; p != &m_active_tempmodels; p = next) {
|
||||
next = p->prev;
|
||||
p->lastPhysicsTime = cg.time;
|
||||
}
|
||||
lastTempModelFrameTime = cg.time;
|
||||
return;
|
||||
if (lastTempModelFrameTime && ((cg.time < lastTempModelFrameTime) || (cg.time - lastTempModelFrameTime > TOO_MUCH_TIME_PASSED))) {
|
||||
p = m_active_tempmodels.prev;
|
||||
for (; p != &m_active_tempmodels; p = next) {
|
||||
next = p->prev;
|
||||
p->lastPhysicsTime = cg.time;
|
||||
}
|
||||
lastTempModelFrameTime = cg.time;
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastTempModelFrameTime) {
|
||||
frameTime = cg.time - lastTempModelFrameTime;
|
||||
} else {
|
||||
frameTime = 0;
|
||||
@@ -763,6 +852,7 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
}
|
||||
|
||||
memset(&newEnt, 0, sizeof(newEnt));
|
||||
newEnt.parentEntity = ENTITYNUM_NONE;
|
||||
// Set this frame time for the next one
|
||||
effectTime = (float)frameTime / 1000.0f;
|
||||
effectTime2 = effectTime * effectTime;
|
||||
@@ -793,7 +883,7 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
current_tiki = p->cgd.tiki;
|
||||
current_entity_number = p->number;
|
||||
|
||||
TempModelRealtimeEffects(p, effectTime, effectTime2, scale);
|
||||
TempModelRealtimeEffects(p, effectTime, scale);
|
||||
|
||||
if (p->lastPhysicsTime) {
|
||||
mstime = cg.time - p->lastPhysicsTime;
|
||||
@@ -808,8 +898,7 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
|
||||
if ((mstime >= physics_rate) || (p->cgd.flags2 & T2_PHYSICS_EVERYFRAME)) {
|
||||
ftime = mstime / 1000.0f;
|
||||
time2 = ftime * ftime;
|
||||
ret = TempModelPhysics(p, ftime, time2, scale);
|
||||
ret = TempModelPhysics(p, ftime, scale);
|
||||
|
||||
if (!ret) {
|
||||
FreeTempModel(p);
|
||||
@@ -823,14 +912,8 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
// Calculate the lerp value based on the time passed since last physics
|
||||
// time of this tempmodel
|
||||
lerpfrac = (float)(cg.time - p->lastPhysicsTime) / (float)physics_rate;
|
||||
|
||||
// Clamp
|
||||
if (lerpfrac > 1) {
|
||||
lerpfrac = 1;
|
||||
}
|
||||
if (lerpfrac < 0) {
|
||||
lerpfrac = 0;
|
||||
}
|
||||
lerpfrac = Q_clamp_float(lerpfrac, 0, 1);
|
||||
|
||||
// Increment the time this tempmodel has been alive
|
||||
p->aliveTime += frameTime;
|
||||
@@ -843,11 +926,10 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
|
||||
// Run physics if the lastEnt is not valid to get a valid lerp
|
||||
if (!p->lastEntValid) {
|
||||
float t, t2;
|
||||
float t;
|
||||
t = physics_rate / 1000.0f;
|
||||
t2 = t * t;
|
||||
|
||||
ret = TempModelPhysics(p, t, t2, scale);
|
||||
ret = TempModelPhysics(p, t, scale);
|
||||
if (!ret) {
|
||||
FreeTempModel(p);
|
||||
continue;
|
||||
@@ -872,12 +954,12 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
}
|
||||
|
||||
if (p->cgd.flags & T_WAVE) {
|
||||
Vector origin;
|
||||
vec3_t origin;
|
||||
float axis[3][3];
|
||||
|
||||
origin = Vector(p->m_spawnthing->linked_origin) + Vector(p->m_spawnthing->linked_axis[0]) * newEnt.origin[0]
|
||||
+ Vector(p->m_spawnthing->linked_axis[1]) * newEnt.origin[1]
|
||||
+ Vector(p->m_spawnthing->linked_axis[2]) * newEnt.origin[2];
|
||||
VectorMA(p->m_spawnthing->linked_origin, newEnt.origin[0], p->m_spawnthing->linked_axis[0], origin);
|
||||
VectorMA(origin, newEnt.origin[1], p->m_spawnthing->linked_axis[1], origin);
|
||||
VectorMA(origin, newEnt.origin[2], p->m_spawnthing->linked_axis[2], origin);
|
||||
|
||||
VectorCopy(origin, newEnt.origin);
|
||||
|
||||
@@ -891,7 +973,10 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
newEnt.reType = p->ent.reType;
|
||||
newEnt.shaderTime = p->ent.shaderTime;
|
||||
|
||||
newEnt.frameInfo[0] = p->ent.frameInfo[0];
|
||||
newEnt.frameInfo[0].index = p->ent.frameInfo[0].index;
|
||||
newEnt.frameInfo[0].weight = 1.0;
|
||||
newEnt.frameInfo[0].time = 0.0;
|
||||
|
||||
newEnt.wasframe = p->ent.wasframe;
|
||||
newEnt.actionWeight = 1.0;
|
||||
newEnt.entityNumber = ENTITYNUM_NONE;
|
||||
@@ -901,6 +986,9 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
|
||||
OtherTempModelEffects(p, newEnt.origin, &newEnt);
|
||||
|
||||
VectorCopy(newEnt.origin, newEnt.lightingOrigin);
|
||||
newEnt.radius = 4.0;
|
||||
|
||||
// Add to the ref
|
||||
if (p->cgd.flags & T_DLIGHT) {
|
||||
// Tempmodel is a Dynamic Light
|
||||
@@ -960,6 +1048,14 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
Vector delta;
|
||||
Vector start;
|
||||
Vector vForward, vLeft, vUp;
|
||||
float fDist;
|
||||
|
||||
delta = m_spawnthing->cgd.origin - cg.refdef.vieworg;
|
||||
fDist = delta * delta * (cg.refdef.fov_x * cg.refdef.fov_x / 6400.0);
|
||||
if (fDist >= m_spawnthing->fMaxRangeSquared || fDist < m_spawnthing->fMinRangeSquared) {
|
||||
// don't draw above the distance
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_entity) {
|
||||
current_entity_scale = current_entity->scale;
|
||||
@@ -1003,7 +1099,11 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
p = AllocateTempModel();
|
||||
|
||||
if (!p) {
|
||||
cgi.DPrintf("Out of tempmodels\n");
|
||||
if (cgi.Milliseconds() >= next_tempmodel_warning) {
|
||||
// make sure to not spam the console with this message
|
||||
cgi.DPrintf("Out of tempmodels\n");
|
||||
next_tempmodel_warning = cgi.Milliseconds() + 1000;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1027,9 +1127,11 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
|
||||
// Set up the origin of the tempmodel
|
||||
if (m_spawnthing->cgd.flags & T_SPHERE) {
|
||||
// Create a random forward vector so the particles burst out in a
|
||||
// sphere
|
||||
newForward = Vector(crandom(), crandom(), crandom());
|
||||
do {
|
||||
// Create a random forward vector so the particles burst out in a
|
||||
// sphere
|
||||
newForward = Vector(crandom(), crandom(), crandom());
|
||||
} while (newForward * newForward > 1.0);
|
||||
} else if (m_spawnthing->cgd.flags & T_CIRCLE) {
|
||||
if (m_spawnthing->sphereRadius != 0) // Offset by the radius
|
||||
{
|
||||
@@ -1049,7 +1151,9 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
// vector pointing back to the origin
|
||||
Vector dir, end;
|
||||
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
do {
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
} while (dir * dir > 1.0);
|
||||
|
||||
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius * current_entity_scale;
|
||||
VectorCopy(end, p->cgd.origin);
|
||||
@@ -1092,7 +1196,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
VectorCopy(end, p->cgd.origin);
|
||||
newForward = dir;
|
||||
} else {
|
||||
VectorCopy(m_spawnthing->cgd.origin, p->cgd.origin);
|
||||
VectorCopy(start, p->cgd.origin);
|
||||
}
|
||||
|
||||
if (m_spawnthing->cgd.flags & T_SWARM && !(m_spawnthing->cgd.flags & (T_HARDLINK | T_PARENTLINK))) {
|
||||
|
||||
@@ -189,7 +189,7 @@ void CG_InstaMessageGroupE_f(void)
|
||||
|
||||
void CG_HudPrint_f(void)
|
||||
{
|
||||
cgi.Printf("\x1%s", cgi.Argv(0));
|
||||
cgi.Printf("\x1%s", cgi.Argv(1));
|
||||
}
|
||||
|
||||
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time)
|
||||
|
||||
+127
-7
@@ -504,6 +504,44 @@ static int CG_CalcFov(void)
|
||||
return inwater;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_SetupFog
|
||||
|
||||
Prepares fog values for rendering
|
||||
===============
|
||||
*/
|
||||
void CG_SetupFog() {
|
||||
cg.refdef.farplane_distance = cg.farplane_distance;
|
||||
cg.refdef.farplane_bias = cg.farplane_bias;
|
||||
cg.refdef.farplane_color[0] = cg.farplane_color[0];
|
||||
cg.refdef.farplane_color[1] = cg.farplane_color[1];
|
||||
cg.refdef.farplane_color[2] = cg.farplane_color[2];
|
||||
cg.refdef.farplane_cull = cg.farplane_cull;
|
||||
cg.refdef.skybox_farplane = cg.skyboxFarplane;
|
||||
cg.refdef.renderTerrain = cg.renderTerrain;
|
||||
cg.refdef.farclipOverride = cg.farclipOverride;
|
||||
cg.refdef.farplaneColorOverride[0] = cg.farplaneColorOverride[0];
|
||||
cg.refdef.farplaneColorOverride[1] = cg.farplaneColorOverride[1];
|
||||
cg.refdef.farplaneColorOverride[2] = cg.farplaneColorOverride[2];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_SetupPortalSky
|
||||
|
||||
Sets portalsky values for rendering
|
||||
===============
|
||||
*/
|
||||
void CG_SetupPortalSky() {
|
||||
cg.refdef.sky_alpha = cg.sky_alpha;
|
||||
cg.refdef.sky_portal = cg.sky_portal;
|
||||
VectorCopy(cg.sky_axis[0], cg.refdef.sky_axis[0]);
|
||||
VectorCopy(cg.sky_axis[1], cg.refdef.sky_axis[1]);
|
||||
VectorCopy(cg.sky_axis[2], cg.refdef.sky_axis[2]);
|
||||
VectorMA(cg.sky_origin, cg.skyboxSpeed, cg.refdef.vieworg, cg.refdef.sky_origin);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CalcViewValues
|
||||
@@ -520,6 +558,7 @@ static int CG_CalcViewValues(void)
|
||||
|
||||
// calculate size of 3D view
|
||||
CG_CalcVrect();
|
||||
CG_SetupFog();
|
||||
|
||||
// setup fog and far clipping plane
|
||||
cg.refdef.farplane_distance = cg.farplane_distance;
|
||||
@@ -604,7 +643,9 @@ static int CG_CalcViewValues(void)
|
||||
// Set the aural axis of the player
|
||||
VectorCopy(cg.refdefViewAngles, SoundAngles);
|
||||
// yaw is purposely inverted because of the miles sound system
|
||||
SoundAngles[YAW] = -SoundAngles[YAW];
|
||||
// Commented out in OPM
|
||||
// Useless as SDL audio/AL is used
|
||||
//SoundAngles[YAW] = -SoundAngles[YAW];
|
||||
AnglesToAxis(SoundAngles, cg.SoundAxis);
|
||||
|
||||
// decide on third person view
|
||||
@@ -623,6 +664,11 @@ static int CG_CalcViewValues(void)
|
||||
// Set the aural axis to the camera's angles
|
||||
VectorCopy(cg.camera_angles, cg.refdefViewAngles);
|
||||
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN && (ps->pm_flags & PMF_DAMAGE_ANGLES)) {
|
||||
// Handle camera shake
|
||||
VectorSubtract(cg.refdefViewAngles, cg.predicted_player_state.damage_angles, cg.refdefViewAngles);
|
||||
}
|
||||
|
||||
if (ps->camera_posofs[0] || ps->camera_posofs[1] || ps->camera_posofs[2]) {
|
||||
vec3_t vAxis[3], vOrg;
|
||||
AnglesToAxis(cg.refdefViewAngles, vAxis);
|
||||
@@ -633,6 +679,9 @@ static int CG_CalcViewValues(void)
|
||||
// copy view values
|
||||
VectorCopy(cg.refdef.vieworg, cg.currentViewPos);
|
||||
VectorCopy(cg.refdefViewAngles, cg.currentViewAngles);
|
||||
// since 2.0: also copy location data for sound
|
||||
VectorCopy(cg.refdef.vieworg, cg.SoundOrg);
|
||||
AnglesToAxis(cg.refdefViewAngles, cg.SoundAxis);
|
||||
}
|
||||
|
||||
// position eye reletive to origin
|
||||
@@ -774,10 +823,46 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
CG_ScoresDown_f();
|
||||
} else if (cg.bIntermissionDisplay) {
|
||||
if (cg.nextSnap) {
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cvar_t* pMission = cgi.Cvar_Get("g_mission", "", CVAR_ARCHIVE);
|
||||
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_ShowMenu("mission_success_1", 0);
|
||||
cgi.Cvar_Set("g_t2l1", "1");
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_ShowMenu("mission_success_2", 0);
|
||||
cgi.Cvar_Set("g_t3l1", "1");
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_ShowMenu("mission_success_3", 0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_ShowMenu("mission_failed_1", 0);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_ShowMenu("mission_failed_2", 0);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_ShowMenu("mission_failed_3", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
|
||||
} else {
|
||||
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -789,10 +874,44 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
CG_ScoresUp_f();
|
||||
} else {
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cvar_t* pMission = cgi.Cvar_Get("g_mission", "", CVAR_ARCHIVE);
|
||||
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_HideMenu("mission_success_1", CVAR_ARCHIVE);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_HideMenu("mission_success_2", CVAR_ARCHIVE);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_HideMenu("mission_success_3", CVAR_ARCHIVE);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_HideMenu("mission_failed_1", CVAR_ARCHIVE);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_HideMenu("mission_failed_2", CVAR_ARCHIVE);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_HideMenu("mission_failed_3", CVAR_ARCHIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_HideMenu("StatsScreen_Success", qfalse);
|
||||
} else {
|
||||
cgi.UI_HideMenu("StatsScreen_Failed", qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,6 +925,7 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
}
|
||||
|
||||
// finish up the rest of the refdef
|
||||
CG_SetupPortalSky();
|
||||
|
||||
cg.refdef.time = cg.time;
|
||||
memcpy(cg.refdef.areamask, cg.snap->areamask, sizeof(cg.refdef.areamask));
|
||||
|
||||
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_commands.h"
|
||||
#include "memarchiver.h"
|
||||
|
||||
const char *cg_vsstypes[] = {
|
||||
"default",
|
||||
@@ -214,6 +215,11 @@ void CG_ResetVSSSources()
|
||||
lastVSSFrameTime = cg.time;
|
||||
}
|
||||
|
||||
void CG_ArchiveVSSGlobals(MemArchiver& archiver)
|
||||
{
|
||||
archiver.ArchiveTime(&lastVSSFrameTime);
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::InitializeVSSSources()
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "memarchiver.h"
|
||||
#include "../qcommon/vector.h"
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
MemArchiver::MemArchiver()
|
||||
{
|
||||
state = MEMARC_WRITING;
|
||||
buffer = 0;
|
||||
allocatedSize = 0;
|
||||
bufferSize = 0;
|
||||
}
|
||||
|
||||
MemArchiver::~MemArchiver()
|
||||
{
|
||||
if (state == MEMARC_WRITING && buffer) {
|
||||
cgi.Free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::SetupForWriting(size_t initialSize)
|
||||
{
|
||||
state = MEMARC_WRITING;
|
||||
buffer = (byte*)cgi.Malloc(initialSize);
|
||||
allocatedSize = initialSize;
|
||||
bufferSize = 0;
|
||||
}
|
||||
|
||||
void MemArchiver::SetupForReading(byte* buffer, size_t size)
|
||||
{
|
||||
state = MEMARC_READING;
|
||||
buffer = buffer;
|
||||
allocatedSize = size;
|
||||
bufferSize = 0;
|
||||
}
|
||||
|
||||
void MemArchiver::SetBaseTime(unsigned int time)
|
||||
{
|
||||
svsTime = time;
|
||||
}
|
||||
|
||||
size_t MemArchiver::BufferSize() const
|
||||
{
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
byte* MemArchiver::ConfiscateBuffer()
|
||||
{
|
||||
byte* confiscatedBuffer = buffer;
|
||||
|
||||
buffer = NULL;
|
||||
allocatedSize = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
return confiscatedBuffer;
|
||||
}
|
||||
|
||||
bool MemArchiver::IsReading() const
|
||||
{
|
||||
return !IsWriting();
|
||||
}
|
||||
|
||||
bool MemArchiver::IsWriting() const
|
||||
{
|
||||
return state == MEMARC_WRITING;
|
||||
}
|
||||
|
||||
bool MemArchiver::FinishedReading() const
|
||||
{
|
||||
return bufferSize == allocatedSize;
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveByte(byte* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(byte));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveBoolean(qboolean* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(qboolean));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveChar(char* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(char));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveUChar(unsigned char* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveShort(short* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(short));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveInteger(int* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(int));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveSize(size_t* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(size_t));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveFloat(float* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(float));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveVec3(vec3_t value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(vec3_t));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveVector(Vector* value)
|
||||
{
|
||||
ArchiveFloat(&value->x);
|
||||
ArchiveFloat(&value->y);
|
||||
ArchiveFloat(&value->z);
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveString(str* value)
|
||||
{
|
||||
char tmp[4096];
|
||||
int current = 0;
|
||||
|
||||
if (IsReading()) {
|
||||
for (current = 0; current < 4096; current++) {
|
||||
ArchiveReadRaw(&tmp[current], sizeof(char));
|
||||
if (!tmp[current]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (current == 4096) {
|
||||
tmp[current - 1] = 0;
|
||||
}
|
||||
|
||||
*value = tmp;
|
||||
} else {
|
||||
ArchiveWriteRaw(value->c_str(), value->length() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveTime(int* value)
|
||||
{
|
||||
int time;
|
||||
|
||||
if (IsReading()) {
|
||||
ArchiveReadRaw(&time, sizeof(time));
|
||||
|
||||
if (time) {
|
||||
time += svsTime;
|
||||
}
|
||||
|
||||
*value = time;
|
||||
} else {
|
||||
time = *value;
|
||||
if (time) {
|
||||
time -= svsTime;
|
||||
}
|
||||
|
||||
ArchiveWriteRaw(&time, sizeof(time));
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveRaw(void* buffer, size_t size)
|
||||
{
|
||||
if (IsReading()) {
|
||||
ArchiveReadRaw(buffer, size);
|
||||
} else {
|
||||
ArchiveWriteRaw(buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveReadRaw(void* buffer, size_t size)
|
||||
{
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (size + this->bufferSize > this->allocatedSize) {
|
||||
Com_Error(ERR_DROP, "MemArchiver: tried to read past end of buffer");
|
||||
}
|
||||
|
||||
memcpy(buffer, this->buffer + this->bufferSize, size);
|
||||
this->bufferSize += size;
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveWriteRaw(const void* buffer, size_t size)
|
||||
{
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (size + this->bufferSize > this->allocatedSize) {
|
||||
if (!this->allocatedSize) {
|
||||
this->allocatedSize = 1024;
|
||||
this->buffer = (byte*)cgi.Malloc(this->allocatedSize);
|
||||
} else {
|
||||
byte* newBuffer;
|
||||
|
||||
do {
|
||||
this->allocatedSize *= 2;
|
||||
} while (size + this->bufferSize > this->allocatedSize);
|
||||
|
||||
newBuffer = (byte*)cgi.Malloc(this->allocatedSize);
|
||||
memcpy(newBuffer, this->buffer, this->bufferSize);
|
||||
cgi.Free(this->buffer);
|
||||
this->buffer = newBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(this->buffer + this->bufferSize, buffer, size);
|
||||
this->bufferSize += size;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// DESCRIPTION:
|
||||
// In-memory archiver
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
class Vector;
|
||||
class str;
|
||||
|
||||
typedef enum {
|
||||
MEMARC_WRITING,
|
||||
MEMARC_READING
|
||||
} archiverState_e;
|
||||
|
||||
class MemArchiver {
|
||||
public:
|
||||
MemArchiver();
|
||||
~MemArchiver();
|
||||
|
||||
void SetupForWriting(size_t initialSize);
|
||||
void SetupForReading(byte* buffer, size_t size);
|
||||
void SetBaseTime(unsigned int time);
|
||||
size_t BufferSize() const;
|
||||
byte* ConfiscateBuffer();
|
||||
bool IsReading() const;
|
||||
bool IsWriting() const;
|
||||
bool FinishedReading() const;
|
||||
|
||||
void ArchiveByte(byte* value);
|
||||
void ArchiveBoolean(qboolean* value);
|
||||
void ArchiveChar(char* value);
|
||||
void ArchiveUChar(unsigned char* value);
|
||||
void ArchiveShort(short* value);
|
||||
void ArchiveInteger(int* value);
|
||||
void ArchiveSize(size_t* value);
|
||||
void ArchiveFloat(float* value);
|
||||
void ArchiveVec3(vec3_t value);
|
||||
void ArchiveVector(Vector* value);
|
||||
void ArchiveString(str* value);
|
||||
void ArchiveTime(int* value);
|
||||
void ArchiveRaw(void* buffer, size_t size);
|
||||
void ArchiveReadRaw(void* buffer, size_t size);
|
||||
void ArchiveWriteRaw(const void* buffer, size_t size);
|
||||
|
||||
private:
|
||||
archiverState_e state;
|
||||
byte* buffer;
|
||||
size_t bufferSize;
|
||||
size_t allocatedSize;
|
||||
int svsTime;
|
||||
};
|
||||
@@ -435,10 +435,10 @@ CL_CM_LoadMap
|
||||
Just adds default parameters that cgame doesn't need to know about
|
||||
====================
|
||||
*/
|
||||
void CL_CM_LoadMap( const char *mapname ) {
|
||||
int checksum;
|
||||
|
||||
CM_LoadMap( mapname, qtrue, &checksum );
|
||||
void CL_CM_LoadMap( const char *mapname, int *checksum ) {
|
||||
CM_LoadMap( mapname, qtrue, checksum );
|
||||
// prepare world vis data
|
||||
re.SetWorldVisData(CM_VisibilityPointer());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -580,6 +580,7 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
|
||||
cgi->Printf = Com_Printf;
|
||||
cgi->DPrintf = Com_DPrintf;
|
||||
cgi->DebugPrintf = Com_DebugPrintf;
|
||||
|
||||
cgi->Malloc = CL_CG_Malloc;
|
||||
cgi->Free = CL_CG_Free;
|
||||
@@ -605,6 +606,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->FS_FreeFile = FS_FreeFile;
|
||||
cgi->FS_WriteFile = FS_WriteFile;
|
||||
cgi->FS_WriteTextFile = FS_WriteTextFile;
|
||||
cgi->FS_ListFilteredFiles = FS_ListFilteredFiles;
|
||||
cgi->FS_FreeFileList = FS_FreeFileList;
|
||||
|
||||
cgi->SendConsoleCommand = Cbuf_AddText;
|
||||
|
||||
@@ -676,9 +679,11 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->R_RegisterModel = re.RegisterModel;
|
||||
cgi->R_SpawnEffectModel = re.SpawnEffectModel;
|
||||
cgi->R_RegisterServerModel = re.RegisterServerModel;
|
||||
cgi->R_GetModelName = re.GetModelName;
|
||||
cgi->R_UnregisterServerModel = re.UnregisterServerModel;
|
||||
cgi->R_RegisterShader = re.RegisterShader;
|
||||
cgi->R_RegisterShaderNoMip = re.RegisterShaderNoMip;
|
||||
cgi->R_GetShaderName = re.GetShaderName;
|
||||
|
||||
cgi->R_AddRefEntityToScene = re.AddRefEntityToScene;
|
||||
cgi->R_AddRefSpriteToScene = re.AddRefSpriteToScene;
|
||||
|
||||
@@ -1612,7 +1612,7 @@ void CL_PlayCinematic_f(void) {
|
||||
bits |= CIN_loop;
|
||||
}
|
||||
|
||||
S_StopAllSounds( qtrue );
|
||||
S_StopAllSounds2( qtrue );
|
||||
|
||||
CL_handle = CIN_PlayCinematic( arg, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, bits );
|
||||
if (CL_handle >= 0) {
|
||||
@@ -1639,7 +1639,7 @@ void SCR_RunCinematic (void)
|
||||
void SCR_StopCinematic(void) {
|
||||
if (CL_handle >= 0 && CL_handle < MAX_VIDEO_HANDLES) {
|
||||
CIN_StopCinematic(CL_handle);
|
||||
S_StopAllSounds( qtrue );
|
||||
S_StopAllSounds2( qtrue );
|
||||
CL_handle = -1;
|
||||
}
|
||||
}
|
||||
+90
-39
@@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "../qcommon/tiki.h"
|
||||
#include "../qcommon/cm_terrain.h"
|
||||
#include "../qcommon/localization.h"
|
||||
#include "../qcommon/bg_compat.h"
|
||||
#include "../sys/sys_local.h"
|
||||
#ifdef USE_RENDERER_DLL
|
||||
#include "../sys/sys_loadlib.h"
|
||||
@@ -366,14 +367,14 @@ void CL_Record_f( void ) {
|
||||
if ( Cmd_Argc() == 2 ) {
|
||||
s = Cmd_Argv(1);
|
||||
Q_strncpyz( demoName, s, sizeof( demoName ) );
|
||||
Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", demoName, PROTOCOL_VERSION );
|
||||
Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", demoName, com_protocol->integer );
|
||||
} else {
|
||||
int number;
|
||||
|
||||
// scan for a free demo name
|
||||
for ( number = 0 ; number <= 9999 ; number++ ) {
|
||||
CL_DemoFilename( number, demoName );
|
||||
Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", demoName, PROTOCOL_VERSION );
|
||||
Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", demoName, com_protocol->integer );
|
||||
|
||||
if (!FS_FileExists(name))
|
||||
break; // file doesn't exist
|
||||
@@ -408,8 +409,8 @@ void CL_Record_f( void ) {
|
||||
// NOTE, MRE: all server->client messages now acknowledge
|
||||
MSG_WriteLong( &buf, clc.reliableSequence );
|
||||
|
||||
MSG_WriteByte (&buf, svc_gamestate);
|
||||
MSG_WriteLong (&buf, clc.serverCommandSequence );
|
||||
MSG_WriteByte ( &buf, svc_gamestate );
|
||||
MSG_WriteLong ( &buf, clc.serverCommandSequence );
|
||||
|
||||
// configstrings
|
||||
for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) {
|
||||
@@ -417,21 +418,20 @@ void CL_Record_f( void ) {
|
||||
continue;
|
||||
}
|
||||
s = cl.gameState.stringData + cl.gameState.stringOffsets[i];
|
||||
MSG_WriteByte (&buf, svc_configstring);
|
||||
MSG_WriteShort (&buf, i);
|
||||
MSG_WriteBigString (&buf, s);
|
||||
MSG_WriteByte ( &buf, svc_configstring );
|
||||
MSG_WriteShort ( &buf, CPT_DenormalizeConfigstring( i ) );
|
||||
MSG_WriteScrambledBigString ( &buf, s );
|
||||
}
|
||||
|
||||
// baselines
|
||||
Com_Memset (&nullstate, 0, sizeof(nullstate));
|
||||
MSG_GetNullEntityState(&nullstate);
|
||||
for ( i = 0; i < MAX_GENTITIES ; i++ ) {
|
||||
ent = &cl.entityBaselines[i];
|
||||
if ( !ent->number ) {
|
||||
continue;
|
||||
}
|
||||
MSG_WriteByte (&buf, svc_baseline);
|
||||
// FIXME
|
||||
MSG_WriteDeltaEntity (&buf, &nullstate, ent, qtrue, 0.0 );
|
||||
MSG_WriteByte ( &buf, svc_baseline );
|
||||
MSG_WriteDeltaEntity ( &buf, &nullstate, ent, qtrue, cls.serverFrameTime );
|
||||
}
|
||||
|
||||
MSG_WriteByte( &buf, svc_EOF );
|
||||
@@ -441,7 +441,10 @@ void CL_Record_f( void ) {
|
||||
// write the client num
|
||||
MSG_WriteLong(&buf, clc.clientNum);
|
||||
// write the checksum feed
|
||||
MSG_WriteLong(&buf, clc.checksumFeed);
|
||||
MSG_WriteLong(&buf, clc.checksumFeed);
|
||||
|
||||
// write the server frametime to the client (only on TA/TT)
|
||||
MSG_WriteServerFrameTime( &buf, cls.serverFrameTime );
|
||||
|
||||
// finished writing the client packet
|
||||
MSG_WriteByte( &buf, svc_EOF );
|
||||
@@ -596,7 +599,7 @@ void CL_ReadDemoMessage( void ) {
|
||||
return;
|
||||
}
|
||||
buf.cursize = LittleLong( buf.cursize );
|
||||
if ( buf.cursize == -1 ) {
|
||||
if ( buf.cursize == (uint32_t)-1) {
|
||||
CL_DemoCompleted ();
|
||||
return;
|
||||
}
|
||||
@@ -798,7 +801,7 @@ void CL_FlushMemory( void ) {
|
||||
|
||||
// shutdown all the client stuff
|
||||
CL_ShutdownCGame();
|
||||
S_StopAllSounds( qtrue );
|
||||
S_StopAllSounds2( qtrue );
|
||||
UI_ClearState();
|
||||
cls.rendererRegistered = qfalse;
|
||||
}
|
||||
@@ -865,7 +868,7 @@ void CL_ClearState( void )
|
||||
CL_ShutdownCGame();
|
||||
|
||||
if( !com_sv_running->integer ) {
|
||||
S_StopAllSounds( qtrue );
|
||||
S_StopAllSounds2( qtrue );
|
||||
}
|
||||
|
||||
UI_ClearState();
|
||||
@@ -880,7 +883,7 @@ CL_UpdateGUID
|
||||
update cl_guid using QKEY_FILE and optional prefix
|
||||
====================
|
||||
*/
|
||||
static void CL_UpdateGUID( char *prefix, int prefix_len )
|
||||
static void CL_UpdateGUID( const char *prefix, int prefix_len )
|
||||
{
|
||||
fileHandle_t f;
|
||||
int len;
|
||||
@@ -1207,7 +1210,7 @@ void CL_Disconnect_f( void ) {
|
||||
CL_AbnormalDisconnect();
|
||||
CL_FlushMemory();
|
||||
CL_StartHunkUsers(qfalse);
|
||||
S_StopAllSounds(1);
|
||||
S_StopAllSounds2(1);
|
||||
S_TriggeredMusic_PlayIntroMusic();
|
||||
}
|
||||
|
||||
@@ -1239,12 +1242,12 @@ void CL_Reconnect_f( void ) {
|
||||
|
||||
/*
|
||||
================
|
||||
CL_Connect_f
|
||||
CL_Connect
|
||||
|
||||
================
|
||||
*/
|
||||
void CL_Connect( const char *server ) {
|
||||
char serverString[ 22 ];
|
||||
void CL_Connect( const char *server, netadrtype_t family ) {
|
||||
const char *serverString;
|
||||
|
||||
Cvar_Set( "ui_singlePlayerActive", "0" );
|
||||
|
||||
@@ -1272,21 +1275,24 @@ void CL_Connect( const char *server ) {
|
||||
|
||||
Q_strncpyz( cls.servername, server, sizeof( cls.servername ) );
|
||||
|
||||
if( !NET_StringToAdr( cls.servername, &clc.serverAddress, NA_IP ) ) {
|
||||
if( !NET_StringToAdr( cls.servername, &clc.serverAddress, family ) ) {
|
||||
Com_Printf( "Bad server address\n" );
|
||||
clc.state = CA_DISCONNECTED;
|
||||
UI_PushMenu("badserveraddy");
|
||||
return;
|
||||
}
|
||||
if( clc.serverAddress.port == 0 ) {
|
||||
clc.serverAddress.port = BigShort( PORT_SERVER );
|
||||
}
|
||||
Com_sprintf( serverString, sizeof( serverString ), "%i.%i.%i.%i:%i",
|
||||
clc.serverAddress.ip[ 0 ], clc.serverAddress.ip[ 1 ],
|
||||
clc.serverAddress.ip[ 2 ], clc.serverAddress.ip[ 3 ],
|
||||
BigShort( clc.serverAddress.port ) );
|
||||
serverString = NET_AdrToStringwPort(clc.serverAddress);
|
||||
|
||||
Com_Printf( "%s resolved to %s\n", cls.servername, serverString );
|
||||
|
||||
if (cl_guidServerUniq->integer)
|
||||
CL_UpdateGUID(serverString, strlen(serverString));
|
||||
else
|
||||
CL_UpdateGUID(NULL, 0);
|
||||
|
||||
// if we aren't playing on a lan, we need to authenticate
|
||||
// with the cd key
|
||||
// wombat: no authorization in mohaa. need to send challenge to server though
|
||||
@@ -1295,11 +1301,14 @@ void CL_Connect( const char *server ) {
|
||||
}
|
||||
else {
|
||||
clc.state = CA_CONNECTING;
|
||||
|
||||
// Set a client challenge number that ideally is mirrored back by the server.
|
||||
clc.challenge = (((unsigned int)rand() << 16) ^ (unsigned int)rand()) ^ Com_Milliseconds();
|
||||
}
|
||||
|
||||
clc.connectTime = -99999; // CL_CheckForResend() will fire immediately
|
||||
clc.connectPacketCount = 0;
|
||||
clc.connectStartTime = 0;
|
||||
clc.connectStartTime = cls.realtime;
|
||||
|
||||
// server connection string
|
||||
Cvar_Set( "cl_currentServerAddress", server );
|
||||
@@ -1312,17 +1321,36 @@ CL_Connect_f
|
||||
================
|
||||
*/
|
||||
// we have our own server provided to us by mohaaaa.co.uk
|
||||
void CL_Connect_f( void ) {
|
||||
char *server;
|
||||
void CL_Connect_f(void) {
|
||||
const char *server;
|
||||
int argc = Cmd_Argc();
|
||||
netadrtype_t family = NA_UNSPEC;
|
||||
|
||||
if ( Cmd_Argc() != 2 ) {
|
||||
Com_Printf( "usage: connect [server]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
server = Cmd_Argv (1);
|
||||
|
||||
CL_Connect( server );
|
||||
if (argc != 2 && argc != 3) {
|
||||
Com_Printf("usage: connect [-4|-6] server\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (argc == 2)
|
||||
server = Cmd_Argv(1);
|
||||
else
|
||||
{
|
||||
if (!strcmp(Cmd_Argv(1), "-4"))
|
||||
family = NA_IP;
|
||||
else if (!strcmp(Cmd_Argv(1), "-6"))
|
||||
family = NA_IP6;
|
||||
else
|
||||
Com_Printf("warning: only -4 or -6 as address type understood.\n");
|
||||
|
||||
server = Cmd_Argv(2);
|
||||
}
|
||||
|
||||
CL_Connect( server, family );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1340,7 +1368,7 @@ void CL_MenuConnect_f( void ) {
|
||||
|
||||
server = Cmd_Argv( 1 );
|
||||
|
||||
CL_Connect( Cvar_VariableString( server ) );
|
||||
CL_Connect( Cvar_VariableString( server ), NA_UNSPEC );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1360,7 +1388,7 @@ void CL_FastConnect_f( void ) {
|
||||
Com_Printf( "Server %i - '%s'\n", i, NET_AdrToString( cls.localServers[ i ].adr ) );
|
||||
}
|
||||
|
||||
CL_Connect( cls.localServers[ 0 ].hostName );
|
||||
CL_Connect( cls.localServers[ 0 ].hostName, NA_UNSPEC );
|
||||
Cbuf_AddText( "popmenu 0 ; wait 500 ; popmenu 0 ; wait 500 ; popmenu 0\n" );
|
||||
endTime = 123456789;
|
||||
}
|
||||
@@ -1493,7 +1521,7 @@ void CL_Vid_Restart_f( void ) {
|
||||
cls.vid_restart = qtrue;
|
||||
|
||||
// don't let them loop during the restart
|
||||
S_StopAllSounds(qtrue);
|
||||
S_StopAllSounds2(qtrue);
|
||||
|
||||
SV_ClearSvsTimeFixups();
|
||||
|
||||
@@ -1507,6 +1535,8 @@ void CL_Vid_Restart_f( void ) {
|
||||
CL_InitRef();
|
||||
// initialize the ui library
|
||||
UI_ResolutionChange();
|
||||
// clear aliases
|
||||
Alias_Clear();
|
||||
|
||||
cls.rendererRegistered = qfalse;
|
||||
|
||||
@@ -1519,6 +1549,12 @@ void CL_Vid_Restart_f( void ) {
|
||||
|
||||
S_Init();
|
||||
|
||||
if (clc.state > CA_CONNECTED && clc.state != CA_CINEMATIC)
|
||||
{
|
||||
// send pure checksums
|
||||
CL_SendPureChecksums();
|
||||
}
|
||||
|
||||
cls.vid_restart = qfalse;
|
||||
Com_Printf("----- finished CL_Vid_Restart_f ----\n");
|
||||
}
|
||||
@@ -1658,6 +1694,13 @@ void CL_DownloadsComplete( void ) {
|
||||
Com_EventLoop();
|
||||
|
||||
CL_StartHunkUsers(qfalse);
|
||||
|
||||
// set pure checksums
|
||||
CL_SendPureChecksums();
|
||||
|
||||
CL_WritePacket();
|
||||
CL_WritePacket();
|
||||
CL_WritePacket();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2434,7 +2477,7 @@ void CL_Frame ( int msec ) {
|
||||
if ( clc.state == CA_DISCONNECTED && !UI_MenuActive()
|
||||
&& !com_sv_running->integer ) {
|
||||
// if disconnected, bring up the menu
|
||||
S_StopAllSounds( qtrue );
|
||||
S_StopAllSounds2( qtrue );
|
||||
UI_MenuEscape( "main" );
|
||||
}
|
||||
|
||||
@@ -2650,6 +2693,15 @@ void *CL_RefMalloc(int size) {
|
||||
return Z_TagMalloc( size, TAG_RENDERER );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefFree
|
||||
============
|
||||
*/
|
||||
void CL_RefFree(void* ptr) {
|
||||
Z_Free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_RefClear
|
||||
@@ -2808,7 +2860,7 @@ void CL_InitRef( void ) {
|
||||
ri.Milliseconds = CL_ScaledMilliseconds;
|
||||
ri.LV_ConvertString = Sys_LV_CL_ConvertString;
|
||||
ri.Malloc = CL_RefMalloc;
|
||||
ri.Free = Z_Free;
|
||||
ri.Free = CL_RefFree;
|
||||
ri.Clear = CL_RefClear;
|
||||
ri.Hunk_Clear = CL_RefStaticClear;
|
||||
#ifdef HUNK_DEBUG
|
||||
@@ -3136,7 +3188,7 @@ void CL_Init( void ) {
|
||||
start = Sys_Milliseconds();
|
||||
|
||||
CL_ClearState ();
|
||||
S_StopAllSounds( qtrue );
|
||||
S_StopAllSounds2( qtrue );
|
||||
|
||||
clc.state = CA_DISCONNECTED; // no longer CA_UNINITIALIZED
|
||||
Key_SetCatcher(KEYCATCH_UI);
|
||||
@@ -3338,7 +3390,6 @@ void CL_Init( void ) {
|
||||
|
||||
Cvar_Set( "cl_running", "1" );
|
||||
|
||||
NET_Init();
|
||||
S_Init2();
|
||||
|
||||
// fixme: should we leave it?
|
||||
@@ -4261,7 +4312,7 @@ CL_ServerRestarted
|
||||
==================
|
||||
*/
|
||||
void CL_ServerRestarted( void ) {
|
||||
S_StopAllSounds( qfalse );
|
||||
S_StopAllSounds2( qfalse );
|
||||
|
||||
UI_ServerLoaded();
|
||||
UI_ClearState();
|
||||
|
||||
@@ -514,40 +514,6 @@ static void CL_ParseServerInfo(void)
|
||||
sizeof(clc.sv_dlURL));
|
||||
}
|
||||
|
||||
char* MSG_ReadGameStateChar_ver_15(msg_t* msg) {
|
||||
return MSG_ReadScrambledBigString(msg);
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime_ver_15(msg_t* msg) {
|
||||
return MSG_ReadFloat(msg);
|
||||
}
|
||||
|
||||
char* MSG_ReadGameStateChar_ver_6(msg_t* msg) {
|
||||
return MSG_ReadString(msg);
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime_ver_6(msg_t* msg) {
|
||||
return 1.f / atof(Info_ValueForKey(cl.gameState.stringData + cl.gameState.stringOffsets[CS_SYSTEMINFO], "sv_fps"));
|
||||
}
|
||||
|
||||
char* MSG_ReadGameStateChar(msg_t* msg) {
|
||||
if (MSG_IsProtocolVersion15()) {
|
||||
return MSG_ReadGameStateChar_ver_15(msg);
|
||||
} else {
|
||||
// smaller below version 15
|
||||
return MSG_ReadGameStateChar_ver_6(msg);
|
||||
}
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime(msg_t* msg) {
|
||||
if (MSG_IsProtocolVersion15()) {
|
||||
return MSG_ReadServerFrameTime_ver_15(msg);
|
||||
} else {
|
||||
// smaller below version 15
|
||||
return MSG_ReadServerFrameTime_ver_6(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseGamestate
|
||||
@@ -591,7 +557,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
if (csNum < 0 || csNum >= MAX_CONFIGSTRINGS) {
|
||||
Com_Error(ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
|
||||
}
|
||||
s = MSG_ReadGameStateChar(msg);
|
||||
s = MSG_ReadScrambledBigString(msg);
|
||||
len = strlen(s);
|
||||
|
||||
if (len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS) {
|
||||
@@ -620,7 +586,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
clc.clientNum = MSG_ReadLong(msg);
|
||||
// read the checksum feed
|
||||
clc.checksumFeed = MSG_ReadLong( msg );
|
||||
cls.serverFrameTime = MSG_ReadServerFrameTime(msg);
|
||||
cls.serverFrameTime = MSG_ReadServerFrameTime(msg, &cl.gameState);
|
||||
|
||||
// parse serverId and other cvars
|
||||
CL_SystemInfoChanged();
|
||||
|
||||
+3833
-4028
File diff suppressed because it is too large.
Load diff
+85
-68
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,112 +20,129 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UI_H__
|
||||
#define __CL_UI_H__
|
||||
#pragma once
|
||||
|
||||
#include "../uilib/ui_extern.h"
|
||||
#include "../uilib/uiwidget.h"
|
||||
|
||||
typedef struct {
|
||||
UIReggedMaterial *loading;
|
||||
UIReggedMaterial *loading;
|
||||
} static_media_t;
|
||||
|
||||
//
|
||||
// cvars
|
||||
//
|
||||
extern cvar_t* ui_health_start;
|
||||
extern cvar_t* ui_health_end;
|
||||
extern cvar_t* sound_overlay;
|
||||
extern cvar_t *ui_health_start;
|
||||
extern cvar_t *ui_health_end;
|
||||
extern cvar_t *sound_overlay;
|
||||
|
||||
//
|
||||
// initialization
|
||||
//
|
||||
void CL_FillUIDef( void );
|
||||
void CL_InitializeUI( void );
|
||||
void CL_ShutdownUI( void );
|
||||
void CL_FillUIDef(void);
|
||||
void CL_InitializeUI(void);
|
||||
void CL_ShutdownUI(void);
|
||||
|
||||
//
|
||||
// general ui stuff
|
||||
//
|
||||
extern inventory_t client_inv;
|
||||
extern bind_t client_bind;
|
||||
extern cvar_t* cl_greenfps;
|
||||
extern bind_t client_bind;
|
||||
extern cvar_t *cl_greenfps;
|
||||
|
||||
const char *CvarGetForUI( const char *name, const char *defval );
|
||||
void UI_ClearState( void );
|
||||
void CL_BeginRegistration( void );
|
||||
void CL_EndRegistration(void);
|
||||
const char *CvarGetForUI(const char *name, const char *defval);
|
||||
void UI_ClearState(void);
|
||||
void CL_BeginRegistration(void);
|
||||
void CL_EndRegistration(void);
|
||||
|
||||
//
|
||||
// menu
|
||||
//
|
||||
extern Menu *ui_pLoadingMenu;
|
||||
|
||||
void UI_ShowMenu( const char *name, qboolean bForce );
|
||||
void UI_HideMenu( const char *name, qboolean bForce );
|
||||
void UI_ForceMenuOff( bool force );
|
||||
void UI_PushMenu( const char *name );
|
||||
void UI_ForceMenu( const char *name );
|
||||
qboolean UI_BindActive( void );
|
||||
void UI_SetReturnMenuToCurrent(void);
|
||||
void UI_ActivateView3D( void );
|
||||
void UI_MenuEscape( const char *name );
|
||||
void UI_CreateScoreboard( void );
|
||||
qboolean UI_MenuActive( void );
|
||||
qboolean UI_MenuUp( void );
|
||||
void UI_FocusMenuIfExists(void);
|
||||
void UI_DrawConnect( void );
|
||||
void UI_CreateDialog( const char *title, char *cvarname, const char *command, const char *cancelCommand, int width, int height, const char *shader, const char *okshader, const char *cancelshader );
|
||||
void UI_ToggleDMConsole( int iMode );
|
||||
void UI_ShowScoreboard_f( const char *pszMenuName );
|
||||
void UI_HideScoreboard_f( void );
|
||||
void UI_SetScoreBoardItem( int iItemNumber,
|
||||
const char *pszData1, const char *pszData2, const char *pszData3, const char *pszData4,
|
||||
const char *pszData5, const char *pszData6, const char *pszData7, const char *pszData8,
|
||||
const vec4_t pTextColor, const vec4_t pBackColor, qboolean bIsHeader );
|
||||
void UI_DeleteScoreBoardItems( int iMaxIndex );
|
||||
void UI_ShowMenu(const char *name, qboolean bForce);
|
||||
void UI_HideMenu(const char *name, qboolean bForce);
|
||||
void UI_ForceMenuOff(bool force);
|
||||
void UI_PushMenu(const char *name);
|
||||
void UI_ForceMenu(const char *name);
|
||||
qboolean UI_BindActive(void);
|
||||
void UI_SetReturnMenuToCurrent(void);
|
||||
void UI_ActivateView3D(void);
|
||||
void UI_MenuEscape(const char *name);
|
||||
void UI_CreateScoreboard(void);
|
||||
qboolean UI_MenuActive(void);
|
||||
qboolean UI_MenuUp(void);
|
||||
void UI_FocusMenuIfExists(void);
|
||||
void UI_DrawConnect(void);
|
||||
void UI_CreateDialog(
|
||||
const char *title,
|
||||
char *cvarname,
|
||||
const char *command,
|
||||
const char *cancelCommand,
|
||||
int width,
|
||||
int height,
|
||||
const char *shader,
|
||||
const char *okshader,
|
||||
const char *cancelshader
|
||||
);
|
||||
void UI_ToggleDMConsole(int iMode);
|
||||
void UI_ShowScoreboard_f(const char *pszMenuName);
|
||||
void UI_HideScoreboard_f(void);
|
||||
void UI_SetScoreBoardItem(
|
||||
int iItemNumber,
|
||||
const char *pszData1,
|
||||
const char *pszData2,
|
||||
const char *pszData3,
|
||||
const char *pszData4,
|
||||
const char *pszData5,
|
||||
const char *pszData6,
|
||||
const char *pszData7,
|
||||
const char *pszData8,
|
||||
const vec4_t pTextColor,
|
||||
const vec4_t pBackColor,
|
||||
qboolean bIsHeader
|
||||
);
|
||||
void UI_DeleteScoreBoardItems(int iMaxIndex);
|
||||
|
||||
//
|
||||
// ressources
|
||||
//
|
||||
void UI_BeginLoad( const char *pszMapName );
|
||||
void UI_EndLoad( void );
|
||||
void UI_AbortLoad( void );
|
||||
void UI_BeginLoadResource( void );
|
||||
void UI_EndLoadResource( void );
|
||||
void UI_EndLoadResource( const char *name );
|
||||
qboolean UI_IsResourceLoaded( const char *name );
|
||||
void UI_RegisterLoadResource( const char *name );
|
||||
void UI_ClearResource( void );
|
||||
void UI_LoadResource( const char *name );
|
||||
void UI_BeginLoad(const char *pszMapName);
|
||||
void UI_EndLoad(void);
|
||||
void UI_AbortLoad(void);
|
||||
void UI_BeginLoadResource(void);
|
||||
void UI_EndLoadResource(void);
|
||||
void UI_EndLoadResource(const char *name);
|
||||
qboolean UI_IsResourceLoaded(const char *name);
|
||||
void UI_RegisterLoadResource(const char *name);
|
||||
void UI_ClearResource(void);
|
||||
void UI_LoadResource(const char *name);
|
||||
|
||||
//
|
||||
// windows
|
||||
//
|
||||
void UI_DeactiveFloatingWindows( void );
|
||||
void UI_DeactiveFloatingWindows(void);
|
||||
|
||||
//
|
||||
// console
|
||||
//
|
||||
void UI_OpenConsole( void );
|
||||
qboolean UI_ConsoleIsVisible( void );
|
||||
qboolean UI_ConsoleIsOpen( void );
|
||||
void UI_CloseConsole( void );
|
||||
void UI_ToggleConsole( void );
|
||||
void UI_OpenDMConsole( int iMode );
|
||||
void UI_CloseDMConsole( void );
|
||||
void UI_ToggleDMConsole( int iMode );
|
||||
void UI_OpenDeveloperConsole( void );
|
||||
void UI_CloseDeveloperConsole( void );
|
||||
void UI_PrintConsole(const char* msg);
|
||||
void UI_OpenConsole(void);
|
||||
qboolean UI_ConsoleIsVisible(void);
|
||||
qboolean UI_ConsoleIsOpen(void);
|
||||
void UI_CloseConsole(void);
|
||||
void UI_ToggleConsole(void);
|
||||
void UI_OpenDMConsole(int iMode);
|
||||
void UI_CloseDMConsole(void);
|
||||
void UI_ToggleDMConsole(int iMode);
|
||||
void UI_OpenDeveloperConsole(void);
|
||||
void UI_CloseDeveloperConsole(void);
|
||||
void UI_PrintConsole(const char *msg);
|
||||
|
||||
//
|
||||
// callbacks
|
||||
//
|
||||
void UI_Update( void );
|
||||
void UI_ServerLoaded( void );
|
||||
void UI_ResolutionChange( void );
|
||||
void UI_KeyEvent( int key, unsigned int time );
|
||||
void UI_CharEvent( int ch );
|
||||
|
||||
#endif /* __CL_UI_H__ */
|
||||
void UI_Update(void);
|
||||
void UI_ServerLoaded(void);
|
||||
void UI_ResolutionChange(void);
|
||||
void UI_KeyEvent(int key, unsigned int time);
|
||||
void UI_CharEvent(int ch);
|
||||
@@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UILOADSAVE_H__
|
||||
#define __CL_UILOADSAVE_H__
|
||||
#pragma once
|
||||
|
||||
class UIFAKKLoadGameClass : public UIListCtrl {
|
||||
bool m_bRemovePending;
|
||||
@@ -43,15 +42,3 @@ public:
|
||||
|
||||
void SetupFiles( void );
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void UI_SetupFiles( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1009,7 +1009,7 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
return;
|
||||
}
|
||||
|
||||
Cvar_Set("dm_serverstatusbar", va("%i", param2));
|
||||
Cvar_Set("dm_serverstatusbar", va("%i", (int)(uintptr_t)param2));
|
||||
}
|
||||
|
||||
if (msg == LIST_PROGRESS)
|
||||
|
||||
+1233
-1162
File diff suppressed because it is too large.
Load diff
+71
-70
@@ -20,85 +20,86 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UISTD_H__
|
||||
#define __CL_UISTD_H__
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
L_STATBAR_NONE,
|
||||
L_STATBAR_HORIZONTAL,
|
||||
L_STATBAR_VERTICAL,
|
||||
L_STATBAR_VERTICAL_REVERSE,
|
||||
L_STATBAR_VERTICAL_STAGGER_EVEN,
|
||||
L_STATBAR_VERTICAL_STAGGER_ODD,
|
||||
L_STATBAR_CIRCULAR,
|
||||
L_STATBAR_NEEDLE,
|
||||
L_STATBAR_ROTATOR,
|
||||
L_STATBAR_COMPASS,
|
||||
L_STATBAR_SPINNER,
|
||||
L_STATBAR_HEADING_SPINNER
|
||||
L_STATBAR_NONE,
|
||||
L_STATBAR_HORIZONTAL,
|
||||
L_STATBAR_VERTICAL,
|
||||
L_STATBAR_VERTICAL_REVERSE,
|
||||
L_STATBAR_VERTICAL_STAGGER_EVEN,
|
||||
L_STATBAR_VERTICAL_STAGGER_ODD,
|
||||
L_STATBAR_CIRCULAR,
|
||||
L_STATBAR_NEEDLE,
|
||||
L_STATBAR_ROTATOR,
|
||||
L_STATBAR_COMPASS,
|
||||
L_STATBAR_SPINNER,
|
||||
L_STATBAR_HEADING_SPINNER
|
||||
} statbar_orientation_t;
|
||||
|
||||
class UIFakkLabel : public UILabel {
|
||||
class UIFakkLabel : public UILabel
|
||||
{
|
||||
protected:
|
||||
SafePtr<inventory_item_t> m_lastitem;
|
||||
int m_lastitemindex;
|
||||
int m_stat;
|
||||
int m_stat_configstring;
|
||||
int m_maxstat;
|
||||
int m_itemindex;
|
||||
int m_inventoryrendermodelindex;
|
||||
str m_sDrawModelName;
|
||||
qboolean m_rendermodel;
|
||||
statbar_orientation_t m_statbar_or;
|
||||
float m_statbar_min;
|
||||
float m_statbar_max;
|
||||
float m_lastfrac;
|
||||
float m_flashtime;
|
||||
vec3_t m_offset;
|
||||
vec3_t m_rotateoffset;
|
||||
vec3_t m_angles;
|
||||
float m_scale;
|
||||
str m_anim;
|
||||
UIReggedMaterial *m_statbar_material;
|
||||
UIReggedMaterial *m_statbar_material_flash;
|
||||
SafePtr<inventory_item_t> m_lastitem;
|
||||
int m_lastitemindex;
|
||||
int m_stat;
|
||||
int m_stat_alpha;
|
||||
int m_stat_configstring;
|
||||
int m_maxstat;
|
||||
int m_itemindex;
|
||||
int m_inventoryrendermodelindex;
|
||||
str m_sDrawModelName;
|
||||
qboolean m_rendermodel;
|
||||
statbar_orientation_t m_statbar_or;
|
||||
float m_statbar_min;
|
||||
float m_statbar_max;
|
||||
float m_lastfrac;
|
||||
float m_flashtime;
|
||||
vec3_t m_offset;
|
||||
vec3_t m_rotateoffset;
|
||||
vec3_t m_angles;
|
||||
float m_scale;
|
||||
str m_anim;
|
||||
UIReggedMaterial *m_statbar_material;
|
||||
UIReggedMaterial *m_statbar_material_flash;
|
||||
UIReggedMaterial *m_statbar_material_marker;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIFakkLabel );
|
||||
CLASS_PROTOTYPE(UIFakkLabel);
|
||||
|
||||
UIFakkLabel();
|
||||
UIFakkLabel();
|
||||
|
||||
void LayoutPlayerStat( Event *ev );
|
||||
void LayoutPlayerStatConfigstring( Event *ev );
|
||||
void LayoutMaxPlayerStat( Event *ev );
|
||||
void LayoutItemIndex( Event *ev );
|
||||
void InventoryRenderModelIndex( Event *ev );
|
||||
void LayoutModelName( Event *ev );
|
||||
void ClearInvItemReference( Event *ev );
|
||||
void LayoutStatbar( Event *ev );
|
||||
void LayoutStatbarShader( Event *ev );
|
||||
void LayoutStatbarTileShader( Event *ev );
|
||||
void LayoutStatbarShader_Flash( Event *ev );
|
||||
void LayoutStatbarEndAngles( Event *ev );
|
||||
void LayoutStatbarNeedleWidth( Event *ev );
|
||||
void LayoutStatbarRotatorSize( Event *ev );
|
||||
void LayoutStatbarTileShader_Flash( Event *ev );
|
||||
void LayoutRenderModel( Event *ev );
|
||||
void LayoutRenderModelOffset( Event *ev );
|
||||
void LayoutRenderModelRotateOffset( Event *ev );
|
||||
void LayoutRenderModelAngles( Event *ev );
|
||||
void LayoutRenderModelScale( Event *ev );
|
||||
void LayoutRenderModelAnim( Event *ev );
|
||||
void LayoutPlayerStat(Event *ev);
|
||||
void LayoutPlayerStatAlpha(Event *ev); // Added in 2.0
|
||||
void LayoutPlayerStatConfigstring(Event *ev);
|
||||
void LayoutMaxPlayerStat(Event *ev);
|
||||
void LayoutItemIndex(Event *ev);
|
||||
void InventoryRenderModelIndex(Event *ev);
|
||||
void LayoutModelName(Event *ev);
|
||||
void ClearInvItemReference(Event *ev);
|
||||
void LayoutStatbar(Event *ev);
|
||||
void LayoutStatbarShader(Event *ev);
|
||||
void LayoutStatbarTileShader(Event *ev);
|
||||
void LayoutStatbarShader_Flash(Event *ev);
|
||||
void LayoutStatbarShader_Marker(Event *ev); // Added in 2.0
|
||||
void LayoutStatbarEndAngles(Event *ev);
|
||||
void LayoutStatbarNeedleWidth(Event *ev);
|
||||
void LayoutStatbarRotatorSize(Event *ev);
|
||||
void LayoutStatbarTileShader_Flash(Event *ev);
|
||||
void LayoutRenderModel(Event *ev);
|
||||
void LayoutRenderModelOffset(Event *ev);
|
||||
void LayoutRenderModelRotateOffset(Event *ev);
|
||||
void LayoutRenderModelAngles(Event *ev);
|
||||
void LayoutRenderModelScale(Event *ev);
|
||||
void LayoutRenderModelAnim(Event *ev);
|
||||
|
||||
void DrawStatbar( float frac );
|
||||
void DrawStatCircle( float frac );
|
||||
void DrawStatNeedle( float frac );
|
||||
void DrawStatRotator( float frac );
|
||||
void DrawStatCompass( float frac );
|
||||
void DrawStatSpinner( float frac );
|
||||
void StatCircleTexCoord( float fAng, vec3_t vTexCoord );
|
||||
void DrawStatbar(float frac);
|
||||
void DrawStatCircle(float frac);
|
||||
void DrawStatNeedle(float frac);
|
||||
void DrawStatRotator(float frac);
|
||||
void DrawStatCompass(float frac);
|
||||
void DrawStatSpinner(float frac);
|
||||
void StatCircleTexCoord(float fAng, vec3_t vTexCoord);
|
||||
|
||||
void Draw( void ) override;
|
||||
void Draw(void) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,8 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// client.h -- primary header for client
|
||||
|
||||
#ifndef __CLIENT_H__
|
||||
#define __CLIENT_H__
|
||||
#pragma once
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
@@ -352,7 +351,7 @@ typedef struct {
|
||||
clientAnim_t anim;
|
||||
stopWatch_t stopwatch;
|
||||
void* savedCgameState;
|
||||
int savedCgameStateSize;
|
||||
size_t savedCgameStateSize;
|
||||
char gcdResponse[73];
|
||||
int unknown3_0;
|
||||
int currentRate;
|
||||
@@ -471,7 +470,7 @@ void CL_AddReliableCommand(const char *cmd, qboolean isDisconnectCmd);
|
||||
|
||||
void CL_StartHunkUsers( qboolean rendererOnly );
|
||||
|
||||
void CL_Connect( const char *server );
|
||||
void CL_Connect( const char *server, netadrtype_t family );
|
||||
|
||||
void CL_Disconnect_f (void);
|
||||
void CL_GetChallengePacket (void);
|
||||
@@ -690,5 +689,3 @@ void CL_InitConsoleCommands( void );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __CLIENT_H__
|
||||
@@ -58,6 +58,7 @@ typedef struct {
|
||||
|
||||
void S_ChannelFree_Callback(channel_t* v);
|
||||
void S_LoadData(soundsystemsavegame_t* pSave);
|
||||
void S_SaveData(soundsystemsavegame_t* pSave);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t s
|
||||
S_StopAllSounds
|
||||
=================
|
||||
*/
|
||||
void S_StopAllSounds(qboolean stop_music)
|
||||
void S_StopAllSounds2(qboolean stop_music)
|
||||
{
|
||||
// Call the original function
|
||||
S_StopAllSounds();
|
||||
@@ -83,12 +83,23 @@ void S_Respatialize(int entityNum, const vec3_t origin,
|
||||
{
|
||||
S_Respatialize(entityNum, origin, axis, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartLocalSoundChannel
|
||||
=================
|
||||
*/
|
||||
void S_StartLocalSound(const char* sound_name, qboolean force_load)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartLocalSound
|
||||
=================
|
||||
*/
|
||||
void S_StartLocalSound(const char* sound_name, qboolean force_load)
|
||||
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, int channel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
@@ -423,3 +434,7 @@ void S_ChannelFree_Callback(channel_t* v) {
|
||||
void S_LoadData(soundsystemsavegame_t* pSave) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_SaveData(soundsystemsavegame_t* pSave) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
@@ -30,8 +30,8 @@ void S_Respatialize(int entityNum, const vec3_t origin, vec3_t axis[3]);
|
||||
sfxHandle_t S_RegisterSound(const char* sample, qboolean compressed, qboolean streamed);
|
||||
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float minDist, float maxDist, float pitch, int flags);
|
||||
void S_StartLocalSound(const char* name, qboolean force_load);
|
||||
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, int channel);
|
||||
void S_StartSound(const vec3_t origin, int entNum, int entChannel, sfxHandle_t sfxHandle, float volume, float minDist, float pitch, float maxDist, qboolean streamed);
|
||||
void S_StopAllSounds(qboolean stop_music);
|
||||
void S_ClearLoopingSounds(void);
|
||||
qboolean S_IsSoundRegistered(const char* name);
|
||||
void S_Init2();
|
||||
@@ -65,6 +65,7 @@ void MUSIC_UpdateMusicVolumes(void);
|
||||
void MUSIC_CheckForStoppedSongs(void);
|
||||
|
||||
void S_StopSound(int entnum, int channel);
|
||||
void S_StopAllSounds2(qboolean stop_music);
|
||||
float S_GetSoundTime(sfxHandle_t handle);
|
||||
void S_SetGlobalAmbientVolumeLevel(float volume);
|
||||
void S_SetReverb(int reverb_type, float reverb_level);
|
||||
|
||||
@@ -120,7 +120,7 @@ bool UConnection::SendEvent
|
||||
ptr = m_listeners.ObjectAt( i );
|
||||
if( ptr )
|
||||
{
|
||||
Event *e = new Event( m_events.ObjectAt( i ) );
|
||||
Event *e = new Event( *m_events.ObjectAt( i ) );
|
||||
|
||||
for( j = 1; j < numargs; j++ )
|
||||
{
|
||||
|
||||
@@ -21,6 +21,46 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "DrivableVehicleTandem.h"
|
||||
#include "vehicleturret.h"
|
||||
|
||||
// FIXME: unimplemented
|
||||
CLASS_DECLARATION(DrivableVehicle, DrivableVehicleTandem, "DrivableVehicleTandem") {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
DrivableVehicleTandem::DrivableVehicleTandem()
|
||||
{
|
||||
}
|
||||
|
||||
DrivableVehicleTandem::~DrivableVehicleTandem()
|
||||
{
|
||||
}
|
||||
|
||||
void DrivableVehicleTandem::SpawnTurret(Event* ev)
|
||||
{
|
||||
VehicleTurretGunTandem* pTurret = new VehicleTurretGunTandem();
|
||||
int slot;
|
||||
|
||||
pTurret->SetBaseOrientation(orientation, NULL);
|
||||
pTurret->setModel(ev->GetString(2));
|
||||
|
||||
slot = ev->GetInteger(1);
|
||||
AttachTurretSlot(slot, pTurret, vec_zero, NULL);
|
||||
pTurret->SetVehicleOwner(this);
|
||||
|
||||
pTurret->PostEvent(EV_TakeDamage, EV_POSTSPAWN);
|
||||
|
||||
UpdateTurretSlot(slot);
|
||||
|
||||
pTurret->ProcessPendingEvents();
|
||||
}
|
||||
|
||||
void DrivableVehicleTandem::UpdateTurretSlot(int iSlot)
|
||||
{
|
||||
DrivableVehicle::UpdateTurretSlot(iSlot);
|
||||
|
||||
if (Turrets[iSlot].ent && Turrets[iSlot].ent->isSubclassOf(VehicleTurretGunTandem)) {
|
||||
VehicleTurretGunTandem* pTurret = static_cast<VehicleTurretGunTandem*>(Turrets[iSlot].ent.Pointer());
|
||||
pTurret->UpdateLinkedTurret();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,3 +21,17 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vehicle.h"
|
||||
|
||||
class DrivableVehicleTandem : public DrivableVehicle {
|
||||
private:
|
||||
CLASS_PROTOTYPE(DrivableVehicleTandem);
|
||||
|
||||
public:
|
||||
DrivableVehicleTandem();
|
||||
~DrivableVehicleTandem();
|
||||
|
||||
void SpawnTurret(Event* ev) override;
|
||||
void UpdateTurretSlot(int iSlot) override;
|
||||
};
|
||||
+1449
-414
File diff suppressed because it is too large.
Load diff
+17
-4
@@ -32,10 +32,11 @@ typedef enum {
|
||||
} eController;
|
||||
|
||||
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
|
||||
#define PT_SPAWNFLAG_PLAY_MOTION_SOUND 2
|
||||
#define PT_SPAWNFLAG_TARGET_RANDOM 4
|
||||
#define PT_SPAWNFLAG_TURN_ON 8
|
||||
#define PT_SPAWNFLAG_SET_YAW 16
|
||||
#define PT_SPAWNFLAG_SET_ROLL 32
|
||||
#define PT_SPAWNFLAG_ROTATE_YAW 16
|
||||
#define PT_SPAWNFLAG_ROTATE_ROLL 32
|
||||
#define PT_SPAWNFLAG_TARGET_PLAYER 64
|
||||
#define PT_SPAWNFLAG_HIDDEN 128
|
||||
|
||||
@@ -101,20 +102,28 @@ public:
|
||||
bool ShouldStartOn() const;
|
||||
bool ShouldHideModel() const;
|
||||
bool ShouldPlayFireSound() const;
|
||||
bool ShouldPlayMotionSound() const;
|
||||
bool ShouldRotateYaw() const;
|
||||
bool ShouldRotateRoll() const;
|
||||
|
||||
void EventIsTurnedOn(Event *ev);
|
||||
void EventGetTargetEntity(Event *ev);
|
||||
void EventLaunchSound(Event *ev);
|
||||
void SetTarget(Event *ev);
|
||||
void SetTarget(Entity* ent);
|
||||
void OnInitialize(Event *ev);
|
||||
void TurnOff(Event *ev);
|
||||
void TurnOn(Event *ev);
|
||||
bool ShouldTargetRandom() const;
|
||||
void ChooseTarget();
|
||||
Entity* ChooseTarget();
|
||||
|
||||
void GetLocalTargets();
|
||||
bool ShouldTargetPlayer() const;
|
||||
void GetTargetPos(Entity *target);
|
||||
Vector GetTargetPos(Entity *target);
|
||||
void GetMuzzlePos(Vector& pos);
|
||||
void Fire();
|
||||
void TryLaunchSound();
|
||||
void SetWeaponAnim(const char* name, Event* ev);
|
||||
void EventAccuracy(Event *ev);
|
||||
void EventMaxDelay(Event *ev);
|
||||
void EventMinDelay(Event *ev);
|
||||
@@ -154,6 +163,7 @@ public:
|
||||
void PlayPreImpactSound(Event *ev);
|
||||
void SetProjectileModel(Event *ev);
|
||||
|
||||
float EstimateImpactTime(const Vector& targetOrigin, const Vector& fromOrigin, float speed) const;
|
||||
bool Attack(int count) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
@@ -196,6 +206,7 @@ public:
|
||||
void SetBulletRange(Event *ev);
|
||||
|
||||
bool Attack(int count) override;
|
||||
bool TickWeaponAnim();
|
||||
void TickCycle(Event *ev) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
@@ -238,6 +249,8 @@ public:
|
||||
|
||||
ThrobbingBox_Explosive();
|
||||
|
||||
bool ShouldDoExplosion();
|
||||
|
||||
void SetExplosionOffset(Event *ev);
|
||||
void SetExplosionEffect(Event *ev);
|
||||
void SetTriggered(Event *ev);
|
||||
|
||||
+99
-12
@@ -114,19 +114,105 @@ void TOWObjectiveMan::TakeOverObjective(eController controller, eController cont
|
||||
}
|
||||
}
|
||||
|
||||
Event EV_SetController("ControlledBy", EV_DEFAULT, "i", "ControlledBy", "Sets the team controlling the objective");
|
||||
Event EV_TakeOver(
|
||||
"TakeOver", EV_DEFAULT, "i", "TeamNum", "Sets the team controlling the objective. 0 = Axis, 1 = Allies"
|
||||
//---------------------------------------------------------------------------------------------
|
||||
/*QUAKED func_TOWObjective (1.0 0.0 1.0) (-12 -12 -12) (12 12 12) StartOn Respawner
|
||||
|
||||
This object is an extension of the standard objective object. It is used for Tug of War
|
||||
Maps.
|
||||
|
||||
object used to simplify placing objectives. You may optionally connect this object to the
|
||||
target you want to use for the compass position....
|
||||
|
||||
Checkboxes:
|
||||
StartOn - check this if you want this objective to be displayed when the level first loads
|
||||
|
||||
Respawner - check this if the objective is the respawn point for a team. If you set this
|
||||
you must set ControlledBy to a valid team and not Neutral.
|
||||
|
||||
|
||||
Parameters:
|
||||
ControlledBy 0 = Axis, 1 = Allies, 2 = Neutral
|
||||
AxisObjNum 1 - 5. Set the objective number for the axis. This will associate the objective with
|
||||
the check box for the corresponding text in the score screen.
|
||||
AlliesObjNum 1 - 5. Set the objective number for the allies. This will associate the objective with
|
||||
the check box for the corresponding text in the score screen.
|
||||
|
||||
ObjectiveNbr <nObjNbr=0> Please ignore this for now.
|
||||
|
||||
Events:
|
||||
TurnOn
|
||||
TurnOff
|
||||
Complete
|
||||
Text <sNewText>
|
||||
SetCurrent
|
||||
SetController <ControlledBy> - This will set the starting controller default is neutral. See ControlledBy var above.
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Event EV_SetController
|
||||
(
|
||||
"ControlledBy",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"ControlledBy",
|
||||
"Sets the team controlling the objective",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_SetAxisObjNum("AxisObjNum", EV_DEFAULT, "i", "AxisObjNum", "Sets the objective number for the axis team");
|
||||
Event EV_SetAlliesObjNum(
|
||||
"AlliesObjNum", EV_DEFAULT, "i", "AlliesObjNum", "Sets the objective number for the allies team"
|
||||
Event EV_TakeOver
|
||||
(
|
||||
"TakeOver",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"TeamNum",
|
||||
"Sets the team controlling the objective. 0 = Axis, 1 = Allies",
|
||||
EV_NORMAL
|
||||
);
|
||||
static Event EV_Initialize("initialize", EV_DEFAULT, 0, 0, "Initialize object");
|
||||
static Event EV_SetCurrent(
|
||||
"SetCurrent", EV_DEFAULT, "i", "TeamNum", "Set this objective as the current objective for the specified team."
|
||||
Event EV_SetAxisObjNum
|
||||
(
|
||||
"AxisObjNum",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"AxisObjNum",
|
||||
"Sets the objective number for the axis team",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_SetAlliesObjNum
|
||||
(
|
||||
"AlliesObjNum",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"AlliesObjNum",
|
||||
"Sets the objective number for the allies team",
|
||||
EV_NORMAL
|
||||
);
|
||||
static Event EV_Initialize
|
||||
(
|
||||
"initialize",
|
||||
EV_DEFAULT,
|
||||
0,
|
||||
0,
|
||||
"Initialize object",
|
||||
EV_NORMAL
|
||||
);
|
||||
static Event EV_SetCurrent
|
||||
(
|
||||
"SetCurrent",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"TeamNum",
|
||||
"Set this objective as the current objective for the specified team.",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_GetController
|
||||
(
|
||||
"ControlledBy",
|
||||
EV_DEFAULT,
|
||||
0,
|
||||
0,
|
||||
"Objective controller",
|
||||
EV_GETTER
|
||||
);
|
||||
Event EV_GetController("ControlledBy", EV_DEFAULT, 0, 0, "Objective controller", EV_GETTER);
|
||||
|
||||
CLASS_DECLARATION(Objective, TOWObjective, "func_towobjective") {
|
||||
{&EV_SetController, &TOWObjective::SetController },
|
||||
@@ -195,6 +281,7 @@ void TOWObjective::TakeOver(Event *ev)
|
||||
}
|
||||
|
||||
g_TOWObjectiveMan.TakeOverObjective(m_eController, controller);
|
||||
m_eController = controller;
|
||||
|
||||
if (m_bNoRespawnForLeading) {
|
||||
//
|
||||
@@ -216,8 +303,8 @@ void TOWObjective::SetAxisObjNum(Event *ev)
|
||||
|
||||
void TOWObjective::OnInitialize(Event *ev)
|
||||
{
|
||||
m_sAlliesObjName = "tow_allied_obj" + str(m_iAlliesObjNum);
|
||||
m_sAxisObjName = "tow_allied_obj" + str(m_iAxisObjNum);
|
||||
m_sAlliesObjName = "tow_allied_obj" + str(m_iAlliesObjNum);
|
||||
m_sAxisObjName = "tow_axis_obj" + str(m_iAxisObjNum);
|
||||
|
||||
switch (m_eController) {
|
||||
case CONTROLLER_ALLIES:
|
||||
|
||||
@@ -45,12 +45,11 @@ VehicleCollisionEntity::VehicleCollisionEntity
|
||||
m_pOwner = ent;
|
||||
takedamage = DAMAGE_YES;
|
||||
|
||||
edict->s.renderfx &= ~RF_DONTDRAW;
|
||||
edict->r.svFlags &= ~SVF_NOCLIENT;
|
||||
|
||||
showModel();
|
||||
setMoveType( MOVETYPE_PUSH );
|
||||
setSolidType(SOLID_NOT);
|
||||
|
||||
edict->clipmask |= MASK_CLIP;
|
||||
edict->clipmask |= MASK_VEHICLE;
|
||||
edict->s.eFlags |= EF_LINKANGLES;
|
||||
}
|
||||
|
||||
@@ -72,9 +71,7 @@ void VehicleCollisionEntity::EventDamage
|
||||
Event *ev
|
||||
)
|
||||
{
|
||||
Event *event = new Event( ev );
|
||||
|
||||
m_pOwner->ProcessEvent( event );
|
||||
m_pOwner->ProcessEvent(*ev);
|
||||
}
|
||||
|
||||
void VehicleCollisionEntity::Solid
|
||||
|
||||
+124
-96
@@ -28,131 +28,159 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
cVehicleSlot::cVehicleSlot()
|
||||
{
|
||||
prev_takedamage = ( damage_t )-1;
|
||||
prev_solid = ( solid_t )-1;
|
||||
prev_contents = -1;
|
||||
prev_takedamage = (damage_t)-1;
|
||||
prev_solid = (solid_t)-1;
|
||||
prev_contents = -1;
|
||||
}
|
||||
|
||||
void cVehicleSlot::NotSolid
|
||||
(
|
||||
void
|
||||
)
|
||||
void cVehicleSlot::NotSolid(void)
|
||||
{
|
||||
if( !( flags & FL_SWIM ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(flags & SLOT_BUSY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save previous values
|
||||
prev_takedamage = ent->takedamage;
|
||||
prev_solid = ent->edict->solid;
|
||||
prev_contents = ent->edict->r.contents;
|
||||
|
||||
ent->takedamage = DAMAGE_NO;
|
||||
ent->setSolidType( SOLID_NOT );
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save previous values
|
||||
prev_takedamage = ent->takedamage;
|
||||
prev_solid = ent->edict->solid;
|
||||
prev_contents = ent->edict->r.contents;
|
||||
|
||||
ent->takedamage = DAMAGE_NO;
|
||||
ent->setSolidType(SOLID_NOT);
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ent->IsSubclassOfPlayer()) {
|
||||
ent->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
|
||||
void cVehicleSlot::Solid
|
||||
(
|
||||
void
|
||||
)
|
||||
void cVehicleSlot::Solid(void)
|
||||
{
|
||||
if( !( flags & FL_SWIM ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(flags & FL_SWIM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Restore previous values
|
||||
ent->takedamage = prev_takedamage;
|
||||
ent->setSolidType( prev_solid );
|
||||
ent->edict->r.contents = prev_contents;
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save previous values
|
||||
prev_takedamage = ( damage_t )-1;
|
||||
prev_solid = ( solid_t )-1;
|
||||
prev_contents = -1;
|
||||
// Restore previous values
|
||||
ent->takedamage = prev_takedamage;
|
||||
ent->setSolidType(prev_solid);
|
||||
ent->setContents(prev_contents);
|
||||
|
||||
// Save previous values
|
||||
prev_takedamage = (damage_t)-1;
|
||||
prev_solid = (solid_t)-1;
|
||||
prev_contents = -1;
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_BBOX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cTurretSlot::cTurretSlot()
|
||||
{
|
||||
owner_prev_takedamage = ( damage_t )-1;
|
||||
owner_prev_solid = ( solid_t )-1;
|
||||
owner_prev_contents = -1;
|
||||
owner_prev_takedamage = (damage_t)-1;
|
||||
owner_prev_solid = (solid_t)-1;
|
||||
owner_prev_contents = -1;
|
||||
}
|
||||
|
||||
void cTurretSlot::NotSolid
|
||||
(
|
||||
void
|
||||
)
|
||||
void cTurretSlot::NotSolid(void)
|
||||
{
|
||||
if( !( flags & FL_SWIM ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(flags & FL_SWIM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
cVehicleSlot::NotSolid();
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( ent->IsSubclassOfTurretGun() )
|
||||
{
|
||||
TurretGun *turret = ( TurretGun * )ent.Pointer();
|
||||
Entity *owner = turret->GetOwner();
|
||||
// Save previous values
|
||||
prev_takedamage = ent->takedamage;
|
||||
prev_solid = ent->edict->solid;
|
||||
prev_contents = ent->edict->r.contents;
|
||||
|
||||
if( owner )
|
||||
{
|
||||
owner_prev_takedamage = owner->takedamage;
|
||||
owner_prev_solid = owner->edict->solid;
|
||||
owner_prev_contents = owner->edict->r.contents;
|
||||
ent->takedamage = DAMAGE_NO;
|
||||
ent->setSolidType(SOLID_NOT);
|
||||
|
||||
owner->takedamage = DAMAGE_NO;
|
||||
owner->setSolidType( SOLID_NOT );
|
||||
}
|
||||
}
|
||||
if (ent->IsSubclassOfTurretGun()) {
|
||||
TurretGun *turret = static_cast<TurretGun *>(ent.Pointer());
|
||||
Entity *owner = turret->GetOwner();
|
||||
|
||||
if (owner) {
|
||||
owner_prev_takedamage = owner->takedamage;
|
||||
owner_prev_solid = owner->edict->solid;
|
||||
owner_prev_contents = owner->edict->r.contents;
|
||||
|
||||
owner->takedamage = DAMAGE_NO;
|
||||
owner->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cTurretSlot::Solid
|
||||
(
|
||||
void
|
||||
)
|
||||
void cTurretSlot::Solid(void)
|
||||
{
|
||||
if( !( flags & FL_SWIM ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(flags & FL_SWIM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
cVehicleSlot::NotSolid();
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( ent->IsSubclassOfTurretGun() )
|
||||
{
|
||||
TurretGun *turret = ( TurretGun * )ent.Pointer();
|
||||
Entity *owner = turret->GetOwner();
|
||||
// Restore previous values
|
||||
ent->takedamage = prev_takedamage;
|
||||
ent->setSolidType(prev_solid);
|
||||
|
||||
if( owner )
|
||||
{
|
||||
owner->takedamage = owner_prev_takedamage;
|
||||
owner->setSolidType( owner_prev_solid );
|
||||
// Save previous values
|
||||
prev_takedamage = (damage_t)-1;
|
||||
prev_solid = (solid_t)-1;
|
||||
|
||||
owner_prev_takedamage = ( damage_t )-1;
|
||||
owner_prev_solid = ( solid_t )-1;
|
||||
}
|
||||
}
|
||||
if (ent->IsSubclassOfTurretGun()) {
|
||||
TurretGun *turret = static_cast<TurretGun *>(ent.Pointer());
|
||||
Entity *owner = turret->GetOwner();
|
||||
|
||||
if (owner) {
|
||||
owner->takedamage = owner_prev_takedamage;
|
||||
owner->setSolidType(owner_prev_solid);
|
||||
|
||||
owner_prev_takedamage = (damage_t)-1;
|
||||
owner_prev_solid = (solid_t)-1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_BBOX);
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
-50
@@ -23,78 +23,69 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// VehicleSlot.h
|
||||
//
|
||||
|
||||
#ifndef __VEHICLESLOT_H__
|
||||
#define __VEHICLESLOT_H__
|
||||
#pragma once
|
||||
|
||||
#include "g_local.h"
|
||||
#include "class.h"
|
||||
#include "entity.h"
|
||||
|
||||
#define SLOT_FREE 1
|
||||
#define SLOT_BUSY 2
|
||||
#define SLOT_UNUSED 4
|
||||
#define SLOT_FREE 1
|
||||
#define SLOT_BUSY 2
|
||||
#define SLOT_UNUSED 4
|
||||
|
||||
class cVehicleSlot : public Class {
|
||||
class cVehicleSlot : public Class
|
||||
{
|
||||
public:
|
||||
SafePtr<Entity> ent;
|
||||
int flags;
|
||||
int boneindex;
|
||||
int enter_boneindex;
|
||||
SafePtr<Entity> ent;
|
||||
int flags;
|
||||
int boneindex;
|
||||
int enter_boneindex;
|
||||
|
||||
private:
|
||||
damage_t prev_takedamage;
|
||||
solid_t prev_solid;
|
||||
int prev_contents;
|
||||
protected:
|
||||
damage_t prev_takedamage;
|
||||
solid_t prev_solid;
|
||||
int prev_contents;
|
||||
|
||||
public:
|
||||
cVehicleSlot();
|
||||
cVehicleSlot();
|
||||
|
||||
virtual void NotSolid( void );
|
||||
virtual void Solid( void );
|
||||
void Archive( Archiver& arc ) override;
|
||||
virtual void NotSolid(void);
|
||||
virtual void Solid(void);
|
||||
void Archive(Archiver &arc) override;
|
||||
};
|
||||
|
||||
inline
|
||||
void cVehicleSlot::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline void cVehicleSlot::Archive(Archiver& arc)
|
||||
{
|
||||
Class::Archive( arc );
|
||||
Class::Archive(arc);
|
||||
|
||||
arc.ArchiveSafePointer( &ent );
|
||||
arc.ArchiveInteger( &flags );
|
||||
arc.ArchiveInteger( &boneindex );
|
||||
arc.ArchiveInteger( &enter_boneindex );
|
||||
ArchiveEnum( prev_takedamage, damage_t );
|
||||
ArchiveEnum( prev_solid, solid_t );
|
||||
arc.ArchiveInteger( &prev_contents );
|
||||
arc.ArchiveSafePointer(&ent);
|
||||
arc.ArchiveInteger(&flags);
|
||||
arc.ArchiveInteger(&boneindex);
|
||||
arc.ArchiveInteger(&enter_boneindex);
|
||||
ArchiveEnum(prev_takedamage, damage_t);
|
||||
ArchiveEnum(prev_solid, solid_t);
|
||||
arc.ArchiveInteger(&prev_contents);
|
||||
}
|
||||
|
||||
class cTurretSlot : public cVehicleSlot {
|
||||
damage_t owner_prev_takedamage;
|
||||
solid_t owner_prev_solid;
|
||||
int owner_prev_contents;
|
||||
class cTurretSlot : public cVehicleSlot
|
||||
{
|
||||
damage_t owner_prev_takedamage;
|
||||
solid_t owner_prev_solid;
|
||||
int owner_prev_contents;
|
||||
|
||||
public:
|
||||
cTurretSlot();
|
||||
cTurretSlot();
|
||||
|
||||
void NotSolid( void ) override;
|
||||
void Solid( void ) override;
|
||||
void Archive( Archiver& arc ) override;
|
||||
void NotSolid(void) override;
|
||||
void Solid(void) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline
|
||||
void cTurretSlot::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline void cTurretSlot::Archive(Archiver& arc)
|
||||
{
|
||||
cVehicleSlot::Archive( arc );
|
||||
cVehicleSlot::Archive(arc);
|
||||
|
||||
ArchiveEnum( owner_prev_takedamage, damage_t );
|
||||
ArchiveEnum( owner_prev_solid, solid_t );
|
||||
arc.ArchiveInteger( &owner_prev_contents );
|
||||
ArchiveEnum(owner_prev_takedamage, damage_t);
|
||||
ArchiveEnum(owner_prev_solid, solid_t);
|
||||
arc.ArchiveInteger(&owner_prev_contents);
|
||||
}
|
||||
|
||||
#endif // __VEHICLESLOT_H__
|
||||
+494
-74
@@ -23,127 +23,547 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "vehicle.h"
|
||||
#include "vehicleturret.h"
|
||||
#include "player.h"
|
||||
#include "g_phys.h"
|
||||
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleTank, "VehicleTank")
|
||||
{
|
||||
{ &EV_Damage, &VehicleTank::EventDamage },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleTank, "VehicleTank") {
|
||||
{&EV_Damage, &VehicleTank::EventDamage},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
VehicleTank::VehicleTank()
|
||||
{
|
||||
entflags |= FL_ROTATEDBOUNDS;
|
||||
entflags |= FL_ROTATEDBOUNDS;
|
||||
}
|
||||
|
||||
VehicleTank::~VehicleTank()
|
||||
{
|
||||
entflags &= ~FL_ROTATEDBOUNDS;
|
||||
entflags &= ~FL_ROTATEDBOUNDS;
|
||||
}
|
||||
|
||||
qboolean VehicleTank::Drive(usercmd_t *ucmd)
|
||||
{
|
||||
Vector i;
|
||||
Vector j;
|
||||
Vector k;
|
||||
Vector vTmp;
|
||||
Vector i;
|
||||
Vector j;
|
||||
Vector k;
|
||||
Vector vTmp;
|
||||
|
||||
vTmp = velocity;
|
||||
VectorNormalize(vTmp);
|
||||
vTmp = velocity;
|
||||
vTmp.normalize();
|
||||
|
||||
if (!driver.ent || !driver.ent->client)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
if (!driver.ent || !driver.ent->isClient()) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!drivable)
|
||||
{
|
||||
driver.ent->client->ps.pm_flags |= PMF_FROZEN;
|
||||
ucmd->forwardmove = 0;
|
||||
ucmd->rightmove = 0;
|
||||
ucmd->upmove = 0;
|
||||
return qfalse;
|
||||
}
|
||||
if (!drivable) {
|
||||
driver.ent->client->ps.pm_flags |= PMF_FROZEN;
|
||||
ucmd->forwardmove = 0;
|
||||
ucmd->rightmove = 0;
|
||||
ucmd->upmove = 0;
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
moveimpulse = ucmd->forwardmove * (vTmp.length() + 1.0);
|
||||
|
||||
m_bIsBraking = ucmd->forwardmove >> 31;
|
||||
if (!m_bAutoPilot) {
|
||||
//
|
||||
// ignore client's control if the vehicle is in auto-pilot mode
|
||||
//
|
||||
moveimpulse = ucmd->forwardmove * (vTmp.length() + 1.0);
|
||||
m_bIsBraking = ucmd->forwardmove < 0;
|
||||
m_fAccelerator += ucmd->forwardmove * 0.005;
|
||||
// acceleration must be an alpha value between [0, 1]
|
||||
m_fAccelerator = Q_clamp_float(m_fAccelerator, 0, 1);
|
||||
|
||||
m_fAccelerator += ucmd->forwardmove * 0.005;
|
||||
turnimpulse = -ucmd->rightmove;
|
||||
jumpimpulse = ucmd->upmove;
|
||||
}
|
||||
|
||||
if (m_fAccelerator < 0)
|
||||
{
|
||||
m_fAccelerator = 0.0;
|
||||
}
|
||||
VehicleTurretGun *vtg = (VehicleTurretGun *)Turrets[0].ent.Pointer();
|
||||
|
||||
turnimpulse = -ucmd->rightmove;
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient()) {
|
||||
vtg->RemoteControl(ucmd, (Sentient *)driver.ent.Pointer());
|
||||
|
||||
VehicleTurretGun *vtg = (VehicleTurretGun *)Turrets[0].ent.Pointer();
|
||||
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient())
|
||||
{
|
||||
vtg->RemoteControl(ucmd, (Sentient *)driver.ent.Pointer());
|
||||
|
||||
if (ucmd->upmove)
|
||||
turnimpulse -= AngleSubtract(angles[1], vtg->angles[1]);
|
||||
}
|
||||
return qtrue;
|
||||
if (ucmd->upmove) {
|
||||
turnimpulse -= AngleSubtract(angles[1], vtg->angles[1]);
|
||||
}
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
void VehicleTank::EventDamage(Event *ev)
|
||||
{
|
||||
int mod;
|
||||
mod = ev->GetInteger(9);
|
||||
int mod;
|
||||
mod = ev->GetInteger(9);
|
||||
|
||||
if (mod > MOD_VEHICLE && mod != MOD_SHOTGUN && mod != MOD_GRENADE)
|
||||
{
|
||||
Vehicle::EventDamage(ev);
|
||||
if (g_gametype->integer == GT_SINGLE_PLAYER)
|
||||
{
|
||||
Player *p = (Player *)driver.ent.Pointer();
|
||||
if (p)
|
||||
{
|
||||
if (p->IsSubclassOfPlayer())
|
||||
{
|
||||
p->m_iNumHitsTaken++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (g_gametype->integer == GT_TOW && !dmManager.RoundActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mod) {
|
||||
case MOD_BULLET:
|
||||
case MOD_BASH:
|
||||
case MOD_FAST_BULLET:
|
||||
case MOD_VEHICLE:
|
||||
case MOD_SHOTGUN:
|
||||
case MOD_GRENADE:
|
||||
return;
|
||||
}
|
||||
|
||||
Vehicle::EventDamage(ev);
|
||||
|
||||
if (g_gametype->integer == GT_SINGLE_PLAYER) {
|
||||
Player *p = (Player *)driver.ent.Pointer();
|
||||
if (p) {
|
||||
if (p->IsSubclassOfPlayer()) {
|
||||
p->m_iNumHitsTaken++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::Think()
|
||||
{
|
||||
flags |= FL_POSTTHINK;
|
||||
flags |= FL_POSTTHINK;
|
||||
}
|
||||
|
||||
void VehicleTank::Postthink()
|
||||
{
|
||||
// FIXME: STUB
|
||||
float turn;
|
||||
Vector i, j, k;
|
||||
Vector normalsum;
|
||||
Vector temp;
|
||||
Vector pitch, roll;
|
||||
Vector acceleration;
|
||||
Vector atmp, atmp2, aup;
|
||||
VehicleBase *v, *last;
|
||||
float drivespeed;
|
||||
Vector primal_angles, primal_origin;
|
||||
Vector vTmp;
|
||||
Vector vAddedAngles;
|
||||
Vector n_angles;
|
||||
float dot;
|
||||
Vector newvel, flatvel;
|
||||
Vector anglediff;
|
||||
|
||||
primal_angles = angles;
|
||||
primal_origin = origin;
|
||||
|
||||
if (!g_vehicle->integer || edict->s.renderfx & RF_DONTDRAW) {
|
||||
// don't process physics
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pCollisionEntity) {
|
||||
// use the collision entity for collision
|
||||
setSolidType(SOLID_NOT);
|
||||
m_pCollisionEntity->Solid();
|
||||
}
|
||||
|
||||
prev_velocity = velocity;
|
||||
SetSlotsNonSolid();
|
||||
|
||||
if (m_bAnimMove) {
|
||||
AnimMoveVehicle();
|
||||
} else {
|
||||
if (!m_bMovementLocked) {
|
||||
FactorOutAnglesOffset();
|
||||
FactorOutOriginOffset();
|
||||
}
|
||||
|
||||
MoveVehicle();
|
||||
}
|
||||
|
||||
SetSlotsSolid();
|
||||
|
||||
if (m_vOldMins != vec_zero && m_vOldMaxs != vec_zero) {
|
||||
mins = m_vOldMins;
|
||||
maxs = m_vOldMaxs;
|
||||
} else if (mins != vec_zero && maxs != vec_zero) {
|
||||
m_vOldMins = mins;
|
||||
m_vOldMaxs = maxs;
|
||||
}
|
||||
|
||||
if (m_bAnimMove) {
|
||||
moveimpulse = velocity.length() * level.frametime;
|
||||
turnimpulse = avelocity[1] * level.frametime;
|
||||
} else if (m_bAutoPilot) {
|
||||
AutoPilot();
|
||||
}
|
||||
|
||||
currentspeed = moveimpulse;
|
||||
turnangle = turnangle * 0.25 + turnimpulse;
|
||||
turnangle = Q_clamp_float(turnangle, -maxturnrate, maxturnrate);
|
||||
|
||||
real_velocity = origin - prev_origin;
|
||||
prev_origin = origin;
|
||||
prev_acceleration = real_acceleration;
|
||||
real_acceleration = real_velocity - prev_velocity;
|
||||
prev_velocity = real_velocity;
|
||||
acceleration = real_acceleration - prev_acceleration;
|
||||
|
||||
UpdateBones();
|
||||
UpdateShaderOffset();
|
||||
UpdateTires();
|
||||
UpdateNormals();
|
||||
|
||||
temp = angles;
|
||||
temp.AngleVectorsLeft(&i, &j, &k);
|
||||
|
||||
velocity[0] *= 0.925f;
|
||||
velocity[1] *= 0.925f;
|
||||
turn = turnangle / 200.0;
|
||||
|
||||
flatvel = orientation[0];
|
||||
velocity += flatvel * currentspeed;
|
||||
flatvel[2] = 0;
|
||||
|
||||
dot = velocity * flatvel;
|
||||
dot = Q_clamp_float(dot, -speed, speed);
|
||||
newvel = flatvel * dot;
|
||||
velocity[0] = newvel[0];
|
||||
velocity[1] = newvel[1];
|
||||
avelocity *= 0.05f;
|
||||
if (dot < 350) {
|
||||
dot = 350;
|
||||
}
|
||||
|
||||
avelocity.y += turn * dot;
|
||||
angles += avelocity * level.frametime;
|
||||
setAngles(angles);
|
||||
|
||||
if (Turrets[0].ent && Turrets[0].ent->IsSubclassOfVehicleTurretGun() && driver.ent
|
||||
&& driver.ent->IsSubclassOfSentient()) {
|
||||
VehicleTurretGun *pTurret = static_cast<VehicleTurretGun *>(Turrets[0].ent.Pointer());
|
||||
if (jumpimpulse != 0) {
|
||||
pTurret->SetUserViewAngles(pTurret->GetUserViewAngles() - Vector(0, avelocity[1] * level.frametime, 0));
|
||||
}
|
||||
}
|
||||
|
||||
drivespeed = acceleration * orientation[0];
|
||||
UpdateSound();
|
||||
|
||||
if (AssertRotation(angles, primal_angles) != true) {
|
||||
angles = primal_angles;
|
||||
}
|
||||
|
||||
CalculateAnglesOffset(acceleration);
|
||||
CalculateOriginOffset();
|
||||
|
||||
last_origin = origin;
|
||||
anglediff = (angles - primal_angles) * level.frametime;
|
||||
|
||||
if (anglediff.x > 180 || anglediff.x < -180) anglediff.x = 0;
|
||||
if (anglediff.y > 180 || anglediff.y < -180) anglediff.y = 0;
|
||||
if (anglediff.z > 180 || anglediff.z < -180) anglediff.z = 0;
|
||||
|
||||
if (anglediff.x > -1 || anglediff.x < 1) anglediff.x = 0;
|
||||
if (anglediff.y > -1 || anglediff.y < 1) anglediff.y = 0;
|
||||
if (anglediff.z > -1 || anglediff.z < 1) anglediff.z = 0;
|
||||
|
||||
avelocity = anglediff;
|
||||
|
||||
if (!m_bAnimMove && !m_bMovementLocked) {
|
||||
FactorInOriginOffset();
|
||||
FactorInAnglesOffset(&vAddedAngles);
|
||||
}
|
||||
|
||||
CalculateAnimationData(vAddedAngles, m_vOriginOffset + m_vOriginOffset2);
|
||||
if (m_pCollisionEntity) {
|
||||
Vector vaDelta;
|
||||
|
||||
SetSlotsNonSolid();
|
||||
|
||||
vaDelta[0] = angledist(angles[0] - m_pCollisionEntity->angles[0]);
|
||||
vaDelta[1] = angledist(angles[1] - m_pCollisionEntity->angles[1]);
|
||||
vaDelta[2] = angledist(angles[2] - m_pCollisionEntity->angles[2]);
|
||||
|
||||
m_pCollisionEntity->Solid();
|
||||
|
||||
G_PushMove(m_pCollisionEntity, origin - primal_origin, vaDelta);
|
||||
G_TouchTriggers(m_pCollisionEntity);
|
||||
|
||||
SetSlotsSolid();
|
||||
|
||||
m_pCollisionEntity->setOrigin(origin);
|
||||
m_pCollisionEntity->setAngles(angles);
|
||||
}
|
||||
|
||||
SetupVehicleSoundEntities();
|
||||
i = orientation[0];
|
||||
j = orientation[1];
|
||||
k = orientation[2];
|
||||
|
||||
//
|
||||
// update slots
|
||||
//
|
||||
for (int ii = 0; ii < MAX_PASSENGERS; ii++) {
|
||||
UpdatePassengerSlot(ii);
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < MAX_TURRETS; ii++) {
|
||||
UpdateTurretSlot(ii);
|
||||
}
|
||||
|
||||
for (last = this; last->vlink; last = v) {
|
||||
v = last->vlink;
|
||||
|
||||
v->setOrigin(origin + i * v->offset.x + j * v->offset.y + k * v->offset.z);
|
||||
v->avelocity = avelocity;
|
||||
v->velocity = velocity;
|
||||
|
||||
v->angles[ROLL] = angles[ROLL];
|
||||
v->angles[YAW] = angles[YAW];
|
||||
v->angles[PITCH] = (int)(drivespeed / 4.f + v->angles[PITCH]) % 360;
|
||||
v->setAngles(v->angles);
|
||||
}
|
||||
|
||||
CheckWater();
|
||||
WorldEffects();
|
||||
|
||||
if (m_pCollisionEntity) {
|
||||
setSolidType(SOLID_NOT);
|
||||
m_pCollisionEntity->Solid();
|
||||
} else {
|
||||
setSolidType(SOLID_BBOX);
|
||||
setContents(CONTENTS_UNKNOWN2);
|
||||
}
|
||||
|
||||
if ((driver.flags & SLOT_BUSY) && driver.ent) {
|
||||
if (driver.ent->IsSubclassOfPlayer()) {
|
||||
driver.ent->takedamage = DAMAGE_YES;
|
||||
// Fixed in OPM.
|
||||
// It's probably a mistake in moh 2.0 and above,
|
||||
// the tank was non-solid with a player driver,
|
||||
// instead of the driver being non-solid.
|
||||
//setSolidType(SOLID_NOT);
|
||||
driver.ent->setSolidType(SOLID_NOT);
|
||||
} else {
|
||||
driver.ent->takedamage = DAMAGE_NO;
|
||||
driver.ent->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::CalculateOriginOffset()
|
||||
{
|
||||
// FIXME: STUB
|
||||
int index;
|
||||
Vector vTireAvg;
|
||||
Vector vMissHit;
|
||||
Vector temp;
|
||||
int iNum = 0;
|
||||
Vector acceleration;
|
||||
Vector oldoffset;
|
||||
|
||||
oldoffset = m_vOriginOffset;
|
||||
m_vOriginOffset += m_vOriginOffset2;
|
||||
m_vOriginOffset2 = vec_zero;
|
||||
|
||||
for (index = 0; index < NUM_VEHICLE_TIRES; index++) {
|
||||
if (m_bTireHit[index]) {
|
||||
vTireAvg += origin - m_vTireEnd[index];
|
||||
iNum++;
|
||||
} else {
|
||||
vMissHit = Corners[index];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_iNumNormals > 0 && iNum == NUM_VEHICLE_TIRES - 1) {
|
||||
Vector point;
|
||||
|
||||
temp = m_vNormalSum * (1.f / m_iNumNormals);
|
||||
temp.normalize();
|
||||
ProjectPointOnPlane(point, vMissHit, temp);
|
||||
vTireAvg += point;
|
||||
|
||||
iNum++;
|
||||
}
|
||||
|
||||
if (iNum == NUM_VEHICLE_TIRES) {
|
||||
vec3_t vOriginCornerOffset;
|
||||
|
||||
vTireAvg *= 1.f / NUM_VEHICLE_TIRES;
|
||||
MatrixTransformVector(m_vOriginCornerOffset, orientation, vOriginCornerOffset);
|
||||
vTireAvg -= vOriginCornerOffset;
|
||||
m_vOriginOffset2 += vTireAvg;
|
||||
}
|
||||
|
||||
//m_vOriginOffset2 += vec_zero;
|
||||
m_vOriginOffset -= m_vOriginOffset2;
|
||||
|
||||
if (!isfinite(m_vOriginOffset[0]) || !isfinite(m_vOriginOffset[1]) || !isfinite(m_vOriginOffset[2])) {
|
||||
m_vOriginOffset = oldoffset;
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::UpdateSound()
|
||||
{
|
||||
// FIXME: STUB
|
||||
float pitch = 1.f;
|
||||
float volume = 1.f;
|
||||
|
||||
if (level.time < m_fNextSoundState) {
|
||||
return;
|
||||
}
|
||||
|
||||
pitch = (velocity.length() - m_fSoundMinSpeed) / (m_fSoundMaxSpeed - m_fSoundMinSpeed);
|
||||
pitch = Q_clamp_float(pitch, 0, 1);
|
||||
pitch = (m_fSoundMaxPitch - m_fSoundMinPitch) * pitch + m_fSoundMinPitch;
|
||||
|
||||
volume = (velocity.length() - m_fVolumeMinSpeed) / (m_fVolumeMaxSpeed - m_fVolumeMinSpeed);
|
||||
volume = Q_clamp_float(volume, 0, 1);
|
||||
volume = (m_fVolumeMaxPitch - m_fVolumeMinPitch) * volume + m_fVolumeMinPitch;
|
||||
|
||||
if (level.intermissiontime) {
|
||||
m_eSoundState = ST_OFF;
|
||||
}
|
||||
|
||||
switch (m_eSoundState) {
|
||||
case ST_OFF:
|
||||
StopLoopSound();
|
||||
TurnOffVehicleSoundEntities();
|
||||
m_fNextSoundState = level.time;
|
||||
if (driver.ent || m_bAutoPilot) {
|
||||
m_eSoundState = ST_OFF_TRANS_IDLE;
|
||||
}
|
||||
break;
|
||||
case ST_OFF_TRANS_IDLE:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_IDLE;
|
||||
Sound(m_sSoundSet + "snd_on", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_idle");
|
||||
break;
|
||||
case ST_IDLE_TRANS_OFF:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_OFF;
|
||||
Sound(m_sSoundSet + "snd_off", CHAN_AUTO);
|
||||
StopLoopSound();
|
||||
break;
|
||||
case ST_IDLE:
|
||||
m_fNextSoundState = level.time;
|
||||
if (driver.ent || m_bAutoPilot) {
|
||||
if (fabs(velocity * orientation[0]) > 150) {
|
||||
m_eSoundState = ST_IDLE_TRANS_RUN;
|
||||
} else if (fabs(turnimpulse) > 1) {
|
||||
m_eSoundState = ST_IDLE_TRANS_TURN;
|
||||
}
|
||||
} else {
|
||||
m_eSoundState = ST_IDLE_TRANS_OFF;
|
||||
}
|
||||
|
||||
LoopSound(m_sSoundSet + "snd_idle");
|
||||
TurnOffVehicleSoundEntities();
|
||||
break;
|
||||
case ST_IDLE_TRANS_RUN:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_RUN;
|
||||
Sound(m_sSoundSet + "snd_revup", CHAN_AUTO);
|
||||
Sound(m_sSoundSet + "snd_shift", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_run", volume, -1, -1, pitch);
|
||||
break;
|
||||
case ST_RUN:
|
||||
m_fNextSoundState = level.time;
|
||||
if (fabs(velocity * orientation[0]) < 150) {
|
||||
m_eSoundState = ST_RUN_TRANS_IDLE;
|
||||
}
|
||||
TurnOnVehicleSoundEntities();
|
||||
LoopSound(m_sSoundSet + "snd_run", volume, -1, -1, pitch);
|
||||
break;
|
||||
case ST_RUN_TRANS_IDLE:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_IDLE;
|
||||
Sound(m_sSoundSet + "snd_revdown", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_idle");
|
||||
break;
|
||||
case ST_IDLE_TRANS_TURN:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_TURN;
|
||||
Sound(m_sSoundSet + "snd_revup", CHAN_AUTO);
|
||||
Sound(m_sSoundSet + "snd_shift", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_run", volume, -1, -1, pitch);
|
||||
break;
|
||||
case ST_TURN:
|
||||
m_fNextSoundState = level.time;
|
||||
if (fabs(turnimpulse) < 1) {
|
||||
m_eSoundState = ST_TURN_TRANS_IDLE;
|
||||
}
|
||||
LoopSound(m_sSoundSet + "snd_run", volume, -1, -1, pitch);
|
||||
break;
|
||||
case ST_TURN_TRANS_IDLE:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_IDLE;
|
||||
Sound(m_sSoundSet + "snd_revdown", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_idle");
|
||||
break;
|
||||
default:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_OFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::AttachDriverSlot(Event* ev)
|
||||
//
|
||||
// Fixed in OPM:
|
||||
// This method only work when called from script.
|
||||
// But it is not called automatically when the player actually uses the vehicle
|
||||
// when that vehicle is unlocked.
|
||||
// So the other native method is overriden instead
|
||||
/*
|
||||
void VehicleTank::AttachDriverSlot(Event *ev)
|
||||
{
|
||||
Vehicle::AttachDriverSlot(ev);
|
||||
Vehicle::AttachDriverSlot(ev);
|
||||
|
||||
VehicleTurretGun *vtg = (VehicleTurretGun *)Turrets[0].ent.Pointer();
|
||||
if (!driver.ent) {
|
||||
//
|
||||
// Added in OPM.
|
||||
// original mohaa doesn't check if driver.ent is valid, which can cause crash if the attached entity is null.
|
||||
// on single-player, it would crash while loading m5l2a when sv_maxclients is above 1.
|
||||
// The reason of the crash is that attachdriverslot is called with $player which can be NULL on prespawn.
|
||||
// $player is not created on prespawn when sv_maxclients is above 1
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient())
|
||||
{
|
||||
vtg->SetOwner((Sentient *)driver.ent.Pointer());
|
||||
Think();
|
||||
Postthink();
|
||||
vtg->Think();
|
||||
}
|
||||
VehicleTurretGun *vtg = (VehicleTurretGun *)Turrets[0].ent.Pointer();
|
||||
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient()) {
|
||||
vtg->SetRemoteOwner(static_cast<Sentient *>(driver.ent.Pointer()));
|
||||
Think();
|
||||
Postthink();
|
||||
vtg->Think();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void VehicleTank::AttachDriverSlot(int slot, Entity* ent, Vector vExitPosition)
|
||||
{
|
||||
Vehicle::AttachDriverSlot(slot, ent, vExitPosition);
|
||||
|
||||
if (!driver.ent) {
|
||||
//
|
||||
// Added in OPM.
|
||||
// original mohaa doesn't check if driver.ent is valid, which can cause crash if the attached entity is null.
|
||||
// on single-player, it would crash while loading m5l2a when sv_maxclients is above 1.
|
||||
// The reason of the crash is that attachdriverslot is called with $player which can be NULL on prespawn.
|
||||
// $player is not created on prespawn when sv_maxclients is above 1
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
VehicleTurretGun* vtg = static_cast<VehicleTurretGun*>(Turrets[0].ent.Pointer());
|
||||
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient()) {
|
||||
vtg->SetRemoteOwner(static_cast<Sentient*>(driver.ent.Pointer()));
|
||||
Think();
|
||||
Postthink();
|
||||
vtg->Think();
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::DriverAdded()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_TURRETS; i++) {
|
||||
if (Turrets[i].flags & SLOT_BUSY && Turrets[i].ent && Turrets[i].ent->IsSubclassOfVehicleTurretGun()) {
|
||||
VehicleTurretGun *pTurret = static_cast<VehicleTurretGun *>(Turrets[i].ent.Pointer());
|
||||
pTurret->TurretHasBeenMounted();
|
||||
}
|
||||
}
|
||||
}
|
||||
+641
-38
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2018 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,64 +22,667 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "vehicle.h"
|
||||
#include "player.h"
|
||||
#include "debuglines.h"
|
||||
#include "g_phys.h"
|
||||
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleWheelsX2, "VehicleWheelsX2")
|
||||
{
|
||||
{ &EV_Damage, &VehicleWheelsX2::EventDamage },
|
||||
{ &EV_Killed, &VehicleWheelsX2::Killed },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleWheelsX2, "VehicleWheelsX2") {
|
||||
{&EV_Damage, &VehicleWheelsX2::EventDamage},
|
||||
{&EV_Killed, &VehicleWheelsX2::Killed },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
VehicleWheelsX2::VehicleWheelsX2()
|
||||
{
|
||||
m_iGear = 1;
|
||||
m_iRPM = 0;
|
||||
gravity = 1.0;
|
||||
m_fDifferentialRatio = 4.8800001f;
|
||||
m_fGearEfficiency = 0.69999999f;
|
||||
m_fGearRatio[0] = -2.9400001f;
|
||||
m_fGearRatio[1] = 2.9400001f;
|
||||
m_fGearRatio[2] = 1.9400001f;
|
||||
m_fGearRatio[3] = 1.0f;
|
||||
m_fAccelerator = 0.0f;
|
||||
m_bAutomatic = qtrue;
|
||||
m_bBackSlipping = qfalse;
|
||||
m_bFrontSlipping = qfalse;
|
||||
gravity = 1.0;
|
||||
m_fDifferentialRatio = 4.88f;
|
||||
m_fGearEfficiency = 0.7f;
|
||||
m_fGearRatio[0] = -2.95f;
|
||||
m_fGearRatio[1] = 2.95f;
|
||||
m_fGearRatio[2] = 1.95f;
|
||||
m_fGearRatio[3] = 1.0f;
|
||||
m_iGear = 1;
|
||||
m_iRPM = 0;
|
||||
m_fAccelerator = 0.0f;
|
||||
m_bAutomatic = qtrue;
|
||||
m_bBackSlipping = qfalse;
|
||||
m_bFrontSlipping = qfalse;
|
||||
}
|
||||
|
||||
void VehicleWheelsX2::UpdateVariables(Vector *acceleration, Vector *vpn, Vector *vup, Vector *vright, Vector *t_vpn, Vector *t_vup, Vector *t_vright)
|
||||
void VehicleWheelsX2::Killed(Event *ev)
|
||||
{
|
||||
// FIXME: STUB
|
||||
deadflag = DEAD_DEAD;
|
||||
}
|
||||
|
||||
float VehicleWheelsX2::TorqueLookup(int rpm)
|
||||
{
|
||||
if (rpm <= 2099)
|
||||
return 100.0;
|
||||
if (rpm > 3599)
|
||||
return 0.0;
|
||||
return (100 * (3600 - rpm)) * 0.001;
|
||||
if (rpm < 2100) {
|
||||
return 100.0;
|
||||
} else if (rpm >= 3600) {
|
||||
return 0.0;
|
||||
} else {
|
||||
return (100 * (3600 - rpm)) / 1000.f;
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleWheelsX2::UpdateVariables(
|
||||
Vector *acceleration, Vector *vpn, Vector *vup, Vector *vright, Vector *t_vpn, Vector *t_vup, Vector *t_vright
|
||||
)
|
||||
{
|
||||
int i;
|
||||
Vector vNewCG;
|
||||
Vector vBoxSize;
|
||||
float longspeed;
|
||||
Vector _i, _j, _k;
|
||||
Vector r_i, r_j, r_k;
|
||||
Vector r_velocity;
|
||||
float dots[4];
|
||||
|
||||
r_velocity = velocity;
|
||||
|
||||
m_bIsSkidding = false;
|
||||
vBoxSize = maxs - mins;
|
||||
|
||||
SetControllerAngles(0, Vector(0, turnangle, 0));
|
||||
SetControllerAngles(1, Vector(0, turnangle, 0));
|
||||
|
||||
vNewCG = localorigin;
|
||||
|
||||
if (vNewCG != m_vCG) {
|
||||
m_vCG = vNewCG;
|
||||
vNewCG -= localorigin;
|
||||
|
||||
m_fWheelBase = vBoxSize.x;
|
||||
m_fWheelFrontDist = vBoxSize.x * 0.5 - vNewCG.x;
|
||||
m_fWheelBackDist = vBoxSize.x * -0.5 + vNewCG.x;
|
||||
m_fTrackWidth = vBoxSize.y;
|
||||
}
|
||||
|
||||
Vector vNewVpn = angles;
|
||||
vNewVpn.AngleVectorsLeft(&r_i, &r_j, &r_k);
|
||||
vNewVpn.y += turnangle;
|
||||
vNewVpn.AngleVectorsLeft(&_i, &_j, &_k);
|
||||
|
||||
dots[3] = r_velocity * *vpn * 0.02;
|
||||
dots[2] = r_velocity * *vright * 0.02;
|
||||
dots[1] = r_velocity * *t_vpn * 0.02;
|
||||
dots[0] = r_velocity * *t_vright * 0.02;
|
||||
|
||||
m_sWheels[0].fTraction = 0.8f;
|
||||
m_sWheels[1].fTraction = 0.9f;
|
||||
m_sWheels[0].fYawOffset = 0;
|
||||
m_sWheels[1].fYawOffset = DEG2RAD(turnangle);
|
||||
m_sWheels[0].fLongDist = m_fWheelBackDist * 0.02;
|
||||
m_sWheels[1].fLongDist = m_fWheelFrontDist * 0.02;
|
||||
m_sWheels[0].fLatDist = m_fTrackWidth * -0.02;
|
||||
m_sWheels[1].fLatDist = m_fTrackWidth * 0.02;
|
||||
|
||||
// initialize the wheels
|
||||
for (i = 0; i < 2; i++) {
|
||||
m_sWheels[i].fLongForce = 0;
|
||||
m_sWheels[i].fForce = 0;
|
||||
|
||||
m_sWheels[i].vLongForce = vec_zero;
|
||||
m_sWheels[i].vLatForce = vec_zero;
|
||||
m_sWheels[i].vForce = vec_zero;
|
||||
m_sWheels[i].vVelocity = vec_zero;
|
||||
m_sWheels[i].bSkidding = false;
|
||||
m_sWheels[i].bSpinning = false;
|
||||
m_sWheels[i].fTorque = 0;
|
||||
m_sWheels[i].fLatTorque = 0;
|
||||
m_sWheels[i].fLongTorque = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
Vector p1, p3, p4;
|
||||
Vector vTp, vTr, vTu;
|
||||
vec3_t p2;
|
||||
|
||||
p3 = Corners[i];
|
||||
p3.normalize();
|
||||
|
||||
vectoangles(p3, p2);
|
||||
p1 = vec_zero;
|
||||
p1[1] = angles[1] + p2[1] + 90;
|
||||
p1.AngleVectorsLeft(&vTp, &vTr, &vTu);
|
||||
|
||||
m_sWheels[i].vVelocity = vTp * RAD2DEG(m_vAngularVelocity.y) * fabs(m_sWheels[i].fLongDist) * level.frametime;
|
||||
|
||||
G_LineWidth(5.0);
|
||||
|
||||
G_DebugLine(
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j,
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j + m_sWheels[i].vVelocity * 50,
|
||||
0.7f,
|
||||
0.5f,
|
||||
1.0f,
|
||||
1.0f
|
||||
);
|
||||
|
||||
p1 = vec_zero;
|
||||
p1[1] = angles[1] + RAD2DEG(m_sWheels[i].fYawOffset);
|
||||
p1.AngleVectorsLeft(&vTp, &vTr, &vTu);
|
||||
|
||||
m_sWheels[i].vOrientation = vTp;
|
||||
|
||||
G_LineWidth(5.0);
|
||||
|
||||
G_DebugLine(
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j,
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j + m_sWheels[i].vOrientation * 50,
|
||||
0.7f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
1.0f
|
||||
);
|
||||
}
|
||||
|
||||
Vector start, end;
|
||||
Vector boxoffset;
|
||||
Vector t_mins(-8, -8, -8);
|
||||
Vector t_maxs(8, 8, 8);
|
||||
trace_t trace;
|
||||
|
||||
start = origin + *vpn * (m_vCG[0] - localorigin[0]) + *vright * (m_vCG[1] - localorigin[1])
|
||||
+ *vup * (m_vCG[2] - localorigin[2]);
|
||||
|
||||
end = start;
|
||||
end[2] -= maxtracedist;
|
||||
|
||||
trace = G_Trace(start, t_mins, t_maxs, end, this, MASK_SOLID, qfalse, "Vehicle::PostThink Corners");
|
||||
|
||||
m_fInertia = m_fMass * 100;
|
||||
m_fWheelFrontLoad = m_fMass * 9.81 * fabs(m_fWheelFrontDist / m_fWheelBase);
|
||||
m_fWheelBackLoad = m_fMass * 9.81 * fabs(m_fWheelBackDist / m_fWheelBase);
|
||||
|
||||
longspeed = m_vAcceleration.length() * 0.02 * m_fMass / m_fWheelBase;
|
||||
m_fWheelFrontLoad -= longspeed;
|
||||
m_fWheelBackLoad += longspeed;
|
||||
m_sWheels[0].fLoad = m_fWheelBackLoad;
|
||||
m_sWheels[1].fLoad = m_fWheelFrontLoad;
|
||||
|
||||
float fMassShifted = m_fTireRadius * M_PI;
|
||||
m_fTireRotationalSpeed = dots[3] / (fMassShifted + fMassShifted);
|
||||
m_iRPM = m_fTireRotationalSpeed * m_fGearRatio[m_iGear] * m_fDifferentialRatio * 10;
|
||||
m_fMaxTraction =
|
||||
TorqueLookup(m_iRPM) * m_fGearRatio[m_iGear] * m_fDifferentialRatio * m_fGearEfficiency / m_fTireRadius;
|
||||
m_fTractionForce = m_fAccelerator * m_fMaxTraction;
|
||||
|
||||
if (m_bIsBraking && dots[3] > 0) {
|
||||
m_fTractionForce = -fSign(dots[3]) * 1000 * dots[3];
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
float maxgrip;
|
||||
|
||||
maxgrip = m_sWheels[i].fTraction * m_sWheels[i].fLoad * 9.81;
|
||||
if (m_fTractionForce > maxgrip) {
|
||||
m_fTractionForce = maxgrip * 0.6;
|
||||
m_sWheels[i].bSpinning = true;
|
||||
m_sWheels[i].bSkidding = true;
|
||||
Com_Printf("Skidding!\n");
|
||||
}
|
||||
|
||||
if (m_fTractionForce < -maxgrip) {
|
||||
m_fTractionForce = -maxgrip * 0.6;
|
||||
m_sWheels[i].bSkidding = true;
|
||||
Com_Printf("Skidding!\n");
|
||||
}
|
||||
|
||||
m_sWheels[i].fLongForce = this->m_sWheels[i].fLongForce + m_fTractionForce;
|
||||
m_sWheels[i].vLongForce += m_sWheels[i].vOrientation * m_sWheels[i].fLongForce;
|
||||
}
|
||||
|
||||
m_vResistance[0] =
|
||||
-(velocity[0] * 0.02 * m_fRollingResistance + velocity[0] * 0.02 * m_fDrag * fabs(velocity[0] * 0.02));
|
||||
m_vResistance[1] =
|
||||
-(velocity[1] * 0.02 * m_fRollingResistance + velocity[1] * 0.02 * m_fDrag * fabs(velocity[1] * 0.02));
|
||||
m_vResistance[2] =
|
||||
-(velocity[2] * 0.02 * m_fRollingResistance + velocity[2] * 0.02 * m_fDrag * fabs(velocity[2] * 0.02));
|
||||
|
||||
m_fBrakingPerformance = -m_fRollingResistance - *vpn * Vector(0, 0, -1) * m_fMass;
|
||||
if (dots[3] == 0) {
|
||||
m_fBrakingPerformance = 0;
|
||||
} else {
|
||||
m_fBrakingPerformance = (dots[3] - (m_fTireRotationalSpeed * m_fTireRadius - m_fBrakingPerformance)) / dots[3];
|
||||
m_fBrakingPerformance = (1.0 - m_fBrakingPerformance) * -(-m_fFrontBrakingForce - m_fBackBrakingForce);
|
||||
}
|
||||
|
||||
if (r_velocity.length() * 0.02 > 0.01) {
|
||||
m_fTangForce = 0;
|
||||
m_vTangForce = vec_zero;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
Vector va, vr;
|
||||
Vector vVel;
|
||||
Vector v1, v2;
|
||||
|
||||
va = angles;
|
||||
va.x = 0;
|
||||
va.y += RAD2DEG(m_sWheels[i].fYawOffset);
|
||||
va.z = 0;
|
||||
va.AngleVectorsLeft(NULL, &vr, NULL);
|
||||
|
||||
vVel = m_sWheels[i].vVelocity + velocity;
|
||||
// get the direction
|
||||
v1 = vVel;
|
||||
v1.normalize();
|
||||
// get the angles
|
||||
vectoangles(v1, v2);
|
||||
|
||||
m_sWheels[i].fSlipAngle = DEG2RAD(angledist(va.y - v2.y));
|
||||
m_sWheels[i].fGripCoef = m_sWheels[i].fSlipAngle * 0.15;
|
||||
m_sWheels[i].fGripCoef = Q_clamp_float(m_sWheels[i].fGripCoef, -1.2f, 1.2f);
|
||||
m_sWheels[i].fLatForce += m_sWheels[i].fGripCoef * m_sWheels[i].fLoad * 9.81;
|
||||
|
||||
if (m_sWheels[i].fLoad * 2 * m_sWheels[i].fTraction < fabs(m_sWheels[i].fLatForce)) {
|
||||
m_sWheels[i].fLatForce = m_sWheels[i].fLatForce / 9.81;
|
||||
m_sWheels[i].bSkidding = true;
|
||||
Com_Printf("Skidding %i!\n", i);
|
||||
}
|
||||
|
||||
m_sWheels[i].vLatForce += vr * m_sWheels[i].fLatForce;
|
||||
|
||||
G_LineWidth(3.0);
|
||||
|
||||
G_DebugLine(
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j,
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j + m_sWheels[i].vLatForce * 50 * (1.0 / m_fMass),
|
||||
0.7f,
|
||||
0.5f,
|
||||
0.2f,
|
||||
1.0f
|
||||
);
|
||||
}
|
||||
} else {
|
||||
m_fTangForce = 0;
|
||||
m_vTangForce = vec_zero;
|
||||
}
|
||||
|
||||
m_vForce = vec_zero;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
m_sWheels[i].vForce = m_sWheels[i].vLatForce + m_sWheels[i].vLongForce;
|
||||
m_vForce += m_sWheels[i].vForce;
|
||||
}
|
||||
|
||||
m_vForce += m_vResistance;
|
||||
|
||||
G_LineWidth(5.0);
|
||||
|
||||
G_DebugLine(origin, origin + m_vTangForce * (1.0 / m_fMass) * 50, 1.0, 0.0, 1.0, 1.0);
|
||||
|
||||
m_vAcceleration = m_vForce * (1.0 / m_fMass) * 50;
|
||||
m_fTorque = 0;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
m_sWheels[i].fTorque += m_sWheels[i].fLongTorque + m_sWheels[i].fLatTorque;
|
||||
m_fTorque += m_sWheels[i].fTorque;
|
||||
}
|
||||
|
||||
m_vAngularAcceleration[1] = angledist(RAD2DEG(m_fTorque));
|
||||
m_vAngularVelocity += m_vAngularAcceleration * level.frametime;
|
||||
m_vAngularVelocity *= 0.825f;
|
||||
avelocity = m_vAngularVelocity;
|
||||
|
||||
if (m_bAutomatic) {
|
||||
//
|
||||
// set the gear
|
||||
//
|
||||
if (m_iRPM >= 2100 && m_iGear <= 2) {
|
||||
m_iGear++;
|
||||
}
|
||||
if (m_iRPM <= 600 && m_iGear > 1) {
|
||||
m_iGear--;
|
||||
}
|
||||
}
|
||||
|
||||
prev_moveimpulse = moveimpulse;
|
||||
}
|
||||
|
||||
void VehicleWheelsX2::Think()
|
||||
{
|
||||
vmove_t vm;
|
||||
vmove_t vm;
|
||||
|
||||
flags |= FL_POSTTHINK;
|
||||
prev_velocity = velocity;
|
||||
flags |= FL_POSTTHINK;
|
||||
prev_velocity = velocity;
|
||||
|
||||
SetMoveInfo(&vm);
|
||||
VmoveSingle(&vm);
|
||||
GetMoveInfo(&vm);
|
||||
SetMoveInfo(&vm);
|
||||
VmoveSingle(&vm);
|
||||
GetMoveInfo(&vm);
|
||||
}
|
||||
|
||||
void VehicleWheelsX2::Postthink()
|
||||
{
|
||||
// FIXME: STUB
|
||||
}
|
||||
float turn;
|
||||
Vector i, j, k;
|
||||
int index;
|
||||
trace_t trace;
|
||||
Vector normalsum;
|
||||
Vector normalsum_Front;
|
||||
int numnormals_Front;
|
||||
Vector normalsum_Back;
|
||||
int numnormals_Back;
|
||||
Vector temp;
|
||||
Vector pitch, roll;
|
||||
Vector acceleration;
|
||||
Vector atmp, atmp2, aup;
|
||||
VehicleBase *v;
|
||||
VehicleBase *last;
|
||||
float drivespeed;
|
||||
Vector primal_angles;
|
||||
Vector vTmp;
|
||||
Vector n_angles;
|
||||
|
||||
void VehicleWheelsX2::Killed(Event* ev)
|
||||
{
|
||||
deadflag = DEAD_DEAD;
|
||||
}
|
||||
primal_angles = angles;
|
||||
|
||||
if (drivable) {
|
||||
currentspeed = moveimpulse;
|
||||
turnangle = turnangle * 0.25f + turnimpulse;
|
||||
turnangle = Q_clamp_float(turnangle, -maxturnrate, maxturnrate);
|
||||
|
||||
if (turnangle > maxturnrate) {
|
||||
turnangle = maxturnrate;
|
||||
} else if (turnangle < -maxturnrate) {
|
||||
turnangle = -maxturnrate;
|
||||
} else if (fabs(turnangle) < 2) {
|
||||
turnangle = 0;
|
||||
}
|
||||
|
||||
real_velocity = origin - prev_origin;
|
||||
prev_origin = origin;
|
||||
prev_acceleration = real_acceleration;
|
||||
real_acceleration = real_velocity - prev_velocity;
|
||||
prev_velocity = real_velocity;
|
||||
acceleration = real_acceleration - prev_acceleration;
|
||||
|
||||
angles[0] = 0;
|
||||
angles[2] = 0;
|
||||
|
||||
temp[0] = angles[0];
|
||||
temp[1] = angles[1];
|
||||
temp[2] = angles[2];
|
||||
temp.AngleVectorsLeft(&i, &j, &k);
|
||||
|
||||
j = vec_zero - j;
|
||||
|
||||
index = 0;
|
||||
numnormals_Front = 0;
|
||||
numnormals_Back = 0;
|
||||
|
||||
for (index = 0; index < 4; index++) {
|
||||
Vector start, end;
|
||||
Vector boxoffset;
|
||||
Vector t_mins(-8, -8, -8);
|
||||
Vector t_maxs(8, 8, 8);
|
||||
|
||||
boxoffset = Corners[index];
|
||||
|
||||
start = origin + i * boxoffset[0] + j * boxoffset[1] + k * boxoffset[2];
|
||||
end = start;
|
||||
end[2] -= maxtracedist;
|
||||
|
||||
trace = G_Trace(start, mins, maxs, end, this, MASK_SOLID, qfalse, "Vehicle::PostThink Corners");
|
||||
|
||||
if (trace.fraction != 1 && !trace.startsolid) {
|
||||
if (index > 2) {
|
||||
normalsum_Front += trace.plane.normal;
|
||||
numnormals_Front++;
|
||||
} else {
|
||||
normalsum_Back += trace.plane.normal;
|
||||
numnormals_Back++;
|
||||
}
|
||||
|
||||
normalsum += trace.plane.normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (angles[2] < 60 || angles[2] > 300) {
|
||||
if (numnormals_Front > 1) {
|
||||
m_vFrontNormal = normalsum_Front * (1.0 / numnormals_Front);
|
||||
|
||||
temp = m_vFrontNormal;
|
||||
m_vFrontAngles[0] = -temp.CrossProduct(temp, j).toPitch();
|
||||
// no yaw
|
||||
m_vFrontAngles[1] = 0;
|
||||
|
||||
temp = m_vFrontNormal;
|
||||
m_vFrontAngles[2] = temp.CrossProduct(temp, i).toPitch();
|
||||
}
|
||||
|
||||
if (numnormals_Back > 1) {
|
||||
m_vBackNormal = normalsum_Back * (1.0 / numnormals_Back);
|
||||
|
||||
temp = m_vBackNormal;
|
||||
m_vBackAngles[0] = -temp.CrossProduct(temp, j).toPitch();
|
||||
// no yaw
|
||||
m_vBackAngles[1] = 0;
|
||||
|
||||
temp = m_vBackNormal;
|
||||
m_vBackAngles[2] = temp.CrossProduct(temp, i).toPitch();
|
||||
}
|
||||
|
||||
if (numnormals_Front + numnormals_Back > 1) {
|
||||
m_vBaseNormal = (normalsum_Front + normalsum_Back) * (1.0 / numnormals_Front + numnormals_Back);
|
||||
|
||||
temp = m_vBaseNormal;
|
||||
m_vBaseAngles[0] = -temp.CrossProduct(temp, j).toPitch();
|
||||
// no yaw
|
||||
m_vBaseAngles[1] = 0;
|
||||
|
||||
temp = m_vBaseNormal;
|
||||
m_vBaseAngles[2] = temp.CrossProduct(temp, i).toPitch();
|
||||
}
|
||||
}
|
||||
|
||||
n_angles = m_vBaseAngles - angles;
|
||||
n_angles[0] = angledist(n_angles[0]);
|
||||
n_angles[1] = angledist(n_angles[1]);
|
||||
n_angles[2] = angledist(n_angles[2]);
|
||||
|
||||
angles[0] += n_angles[0] * 4.5 * level.frametime;
|
||||
angles[2] += n_angles[2] * 4.5 * level.frametime;
|
||||
|
||||
m_vPrevNormal = m_vBaseNormal;
|
||||
|
||||
if (currentspeed < 0 && velocity * i > 0) {
|
||||
m_fFrontBrakingForce = 0.2f;
|
||||
m_fBackBrakingForce = 0.1f;
|
||||
} else {
|
||||
m_fFrontBrakingForce = 0;
|
||||
m_fBackBrakingForce = 0;
|
||||
}
|
||||
|
||||
turn = turnangle * 0.005;
|
||||
|
||||
Vector _i, _j, _k;
|
||||
Vector vNewVpn = angles;
|
||||
vNewVpn.y += turnangle;
|
||||
|
||||
vNewVpn.AngleVectorsLeft(&_i, &_j, &_k);
|
||||
UpdateVariables(&acceleration, &i, &j, &k, &_i, &_j, &_k);
|
||||
|
||||
m_vAngles = angles;
|
||||
|
||||
if (currentspeed < 0 && velocity * i > 0) {
|
||||
currentspeed = 0;
|
||||
}
|
||||
|
||||
normalsum = vec_zero;
|
||||
|
||||
for (index = 0; index < 4; index++) {
|
||||
Vector start, end;
|
||||
Vector boxoffset;
|
||||
Vector t_mins(-8, -8, -8);
|
||||
Vector t_maxs(8, 8, 8);
|
||||
|
||||
boxoffset = Corners[index];
|
||||
|
||||
start = origin + i * boxoffset[0] + j * boxoffset[1] + k * boxoffset[2] + Vector(0, 0, 10);
|
||||
end = start;
|
||||
end[2] -= maxtracedist;
|
||||
|
||||
trace = G_Trace(start, mins, maxs, end, this, MASK_SOLID, qfalse, "Vehicle::PostThink Corners");
|
||||
|
||||
if (trace.fraction != 1.0) {
|
||||
float fCoef;
|
||||
|
||||
if (index > 2) {
|
||||
fCoef = m_fWheelFrontLoad / (m_fWheelFrontDist / m_fWheelBase * m_fMass);
|
||||
fCoef = Q_clamp_float(fCoef, 0, 1);
|
||||
|
||||
normalsum += _i * currentspeed * fCoef;
|
||||
normalsum += i * currentspeed * (1.0 - fCoef);
|
||||
} else {
|
||||
fCoef = m_fWheelBackLoad / (m_fWheelBackDist / m_fWheelBase * m_fMass);
|
||||
fCoef = Q_clamp_float(fCoef, 0, 1);
|
||||
|
||||
normalsum += i * currentspeed * fCoef;
|
||||
normalsum += _i * currentspeed * (1.0 - fCoef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnglesToAxis(angles, orientation);
|
||||
|
||||
vmove_t vm;
|
||||
SetMoveInfo(&vm);
|
||||
m_sMoveGrid->SetMoveInfo(&vm);
|
||||
m_sMoveGrid->SetOrientation(orientation);
|
||||
|
||||
if (m_sMoveGrid->CheckStuck()) {
|
||||
angles = primal_angles;
|
||||
AnglesToAxis(angles, orientation);
|
||||
}
|
||||
|
||||
if (groundentity && (angles[2] < 60 || angles[2] > 300)) {
|
||||
float dot;
|
||||
Vector newvel, flatvel;
|
||||
|
||||
velocity[0] *= 0.925f;
|
||||
velocity[1] *= 0.925f;
|
||||
|
||||
newvel = orientation[0];
|
||||
velocity += newvel * currentspeed;
|
||||
newvel[2] = 0;
|
||||
|
||||
dot = velocity * newvel;
|
||||
dot = Q_clamp_float(dot, -speed, speed);
|
||||
|
||||
if (dot > speed) {
|
||||
dot = speed;
|
||||
} else if (dot < -speed) {
|
||||
dot = -speed;
|
||||
} else if (fabs(dot) < 20) {
|
||||
dot = 0;
|
||||
}
|
||||
|
||||
flatvel = newvel * dot;
|
||||
|
||||
velocity[0] = flatvel[0];
|
||||
velocity[1] = flatvel[1];
|
||||
velocity[2] += jumpimpulse * dot;
|
||||
avelocity *= 0.05f;
|
||||
|
||||
if (steerinplace) {
|
||||
if (dot < 350) {
|
||||
dot = 350;
|
||||
}
|
||||
|
||||
avelocity.y += turn * dot;
|
||||
} else {
|
||||
avelocity.y += turn * dot;
|
||||
}
|
||||
} else {
|
||||
if (angles[2] > 60) {
|
||||
angles[2]; // FIXME: ??
|
||||
}
|
||||
|
||||
velocity += m_vAcceleration * level.frametime;
|
||||
}
|
||||
|
||||
angles += avelocity * level.frametime;
|
||||
setAngles(angles);
|
||||
|
||||
prev_origin = origin;
|
||||
}
|
||||
|
||||
drivespeed = acceleration * orientation[0];
|
||||
|
||||
if (drivable && driver.ent) {
|
||||
str sound_name;
|
||||
|
||||
if (currentspeed > 0) {
|
||||
sound_name = "snd_forward";
|
||||
} else if (currentspeed == 0) {
|
||||
sound_name = "snd_idle";
|
||||
} else {
|
||||
sound_name = "snd_backward";
|
||||
}
|
||||
|
||||
LoopSound(sound_name);
|
||||
}
|
||||
|
||||
i = orientation[0];
|
||||
j = orientation[1];
|
||||
k = orientation[2];
|
||||
|
||||
if (driver.ent) {
|
||||
driver.ent->setOrigin(origin + i * driveroffset[0] + j * driveroffset[1] + k * driveroffset[2]);
|
||||
|
||||
if (drivable) {
|
||||
// clear the driver velocity
|
||||
driver.ent->velocity = vec_zero;
|
||||
// set the driver angles to the vehicle's angle
|
||||
driver.ent->setAngles(angles);
|
||||
}
|
||||
}
|
||||
|
||||
vTmp = (angles - primal_angles) * level.frametime;
|
||||
if (vTmp.x > 180 || vTmp.x < -180) {
|
||||
vTmp.x = 0;
|
||||
}
|
||||
if (vTmp.y > 180 || vTmp.y < -180) {
|
||||
vTmp.y = 0;
|
||||
}
|
||||
if (vTmp.z > 180 || vTmp.z < -180) {
|
||||
vTmp.z = 0;
|
||||
}
|
||||
|
||||
if (vTmp.x > -1 || vTmp.x < 1) {
|
||||
vTmp.x = 0;
|
||||
}
|
||||
if (vTmp.y > -1 || vTmp.y < 1) {
|
||||
vTmp.y = 0;
|
||||
}
|
||||
if (vTmp.z > -1 || vTmp.z < 1) {
|
||||
vTmp.z = 0;
|
||||
}
|
||||
|
||||
avelocity = vTmp;
|
||||
|
||||
for (last = this; last->vlink; last = v) {
|
||||
v = last->vlink;
|
||||
|
||||
v->setOrigin(origin + i * v->offset.x + j * v->offset.y + k * v->offset.z);
|
||||
v->avelocity = avelocity;
|
||||
v->velocity = velocity;
|
||||
|
||||
v->angles[ROLL] = angles[ROLL];
|
||||
v->angles[YAW] = angles[YAW];
|
||||
v->angles[PITCH] = (int)(drivespeed / 4.f + v->angles[PITCH]) % 360;
|
||||
v->setAngles(v->angles);
|
||||
}
|
||||
|
||||
CheckWater();
|
||||
WorldEffects();
|
||||
|
||||
last_origin = origin;
|
||||
|
||||
if (!driver.ent && !velocity.length() && groundentity && !(watertype & CONTENTS_LAVA)) {
|
||||
// make the vehicle stationary if it's completely immobile
|
||||
flags &= ~FL_POSTTHINK;
|
||||
if (drivable) {
|
||||
setMoveType(MOVETYPE_STATIONARY);
|
||||
}
|
||||
}
|
||||
}
|
||||
+653
-42
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2018 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,69 +22,680 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "vehicle.h"
|
||||
#include "player.h"
|
||||
#include "debuglines.h"
|
||||
#include "g_phys.h"
|
||||
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleWheelsX4, "VehicleWheelsX4")
|
||||
{
|
||||
{ &EV_Damage, &VehicleWheelsX4::EventDamage },
|
||||
{ &EV_Killed, &VehicleWheelsX4::Killed },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleWheelsX4, "VehicleWheelsX4") {
|
||||
{&EV_Damage, &VehicleWheelsX4::EventDamage},
|
||||
{&EV_Killed, &VehicleWheelsX4::Killed },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
VehicleWheelsX4::VehicleWheelsX4()
|
||||
{
|
||||
m_iGear = 1;
|
||||
m_iRPM = 0;
|
||||
gravity = 1.0;
|
||||
m_fDifferentialRatio = 4.8800001f;
|
||||
m_fGearEfficiency = 0.69999999f;
|
||||
m_fGearRatio[0] = -2.9400001f;
|
||||
m_fGearRatio[1] = 2.9400001f;
|
||||
m_fGearRatio[2] = 1.9400001f;
|
||||
m_fGearRatio[3] = 1.0f;
|
||||
m_fAccelerator = 0.0f;
|
||||
m_bBackSlipping = qfalse;
|
||||
m_bAutomatic = qtrue;
|
||||
m_bFrontSlipping = qfalse;
|
||||
gravity = 1.0;
|
||||
m_fDifferentialRatio = 4.88f;
|
||||
m_fGearEfficiency = 0.7f;
|
||||
m_fGearRatio[0] = -2.95f;
|
||||
m_fGearRatio[1] = 2.95f;
|
||||
m_fGearRatio[2] = 1.95f;
|
||||
m_fGearRatio[3] = 1.0f;
|
||||
m_iGear = 1;
|
||||
m_iRPM = 0;
|
||||
m_fAccelerator = 0.0f;
|
||||
m_bAutomatic = qtrue;
|
||||
m_bBackSlipping = qfalse;
|
||||
m_bFrontSlipping = qfalse;
|
||||
}
|
||||
|
||||
void VehicleWheelsX4::UpdateVariables(Vector *acceleration, Vector *vpn, Vector *vup, Vector *vright, Vector *t_vpn, Vector *t_vup, Vector *t_vright)
|
||||
void VehicleWheelsX4::UpdateVariables(
|
||||
Vector *acceleration, Vector *vpn, Vector *vup, Vector *vright, Vector *t_vpn, Vector *t_vup, Vector *t_vright
|
||||
)
|
||||
{
|
||||
// FIXME: STUB
|
||||
int i;
|
||||
Vector vNewCG;
|
||||
Vector vBoxSize;
|
||||
float longspeed;
|
||||
Vector _i, _j, _k;
|
||||
Vector r_i, r_j, r_k;
|
||||
Vector r_velocity;
|
||||
float dots[4];
|
||||
|
||||
r_velocity = velocity;
|
||||
|
||||
m_bIsSkidding = false;
|
||||
vBoxSize = maxs - mins;
|
||||
|
||||
SetControllerAngles(0, Vector(0, turnangle, 0));
|
||||
SetControllerAngles(1, Vector(0, turnangle, 0));
|
||||
|
||||
vNewCG = localorigin;
|
||||
|
||||
if (vNewCG != m_vCG) {
|
||||
m_vCG = vNewCG;
|
||||
vNewCG -= localorigin;
|
||||
|
||||
m_fWheelBase = vBoxSize.x;
|
||||
m_fWheelFrontDist = vBoxSize.x * 0.5 - vNewCG.x;
|
||||
m_fWheelBackDist = vBoxSize.x * -0.5 + vNewCG.x;
|
||||
m_fTrackWidth = vBoxSize.y;
|
||||
}
|
||||
|
||||
Vector vNewVpn = angles;
|
||||
vNewVpn.AngleVectorsLeft(&r_i, &r_j, &r_k);
|
||||
vNewVpn.y += turnangle;
|
||||
vNewVpn.AngleVectorsLeft(&_i, &_j, &_k);
|
||||
|
||||
dots[3] = r_velocity * *vpn * 0.02;
|
||||
dots[2] = r_velocity * *vright * 0.02;
|
||||
dots[1] = r_velocity * *t_vpn * 0.02;
|
||||
dots[0] = r_velocity * *t_vright * 0.02;
|
||||
|
||||
m_sWheels[0].fTraction = 0.8f;
|
||||
m_sWheels[1].fTraction = 0.9f;
|
||||
m_sWheels[2].fTraction = 0.8f;
|
||||
m_sWheels[3].fTraction = 0.9f;
|
||||
m_sWheels[0].fYawOffset = 0;
|
||||
m_sWheels[1].fYawOffset = DEG2RAD(turnangle);
|
||||
m_sWheels[2].fYawOffset = 0;
|
||||
m_sWheels[3].fYawOffset = DEG2RAD(turnangle);
|
||||
m_sWheels[0].fLongDist = m_fWheelBackDist * 0.02;
|
||||
m_sWheels[1].fLongDist = m_fWheelFrontDist * 0.02;
|
||||
m_sWheels[2].fLongDist = m_fWheelBackDist * 0.02;
|
||||
m_sWheels[3].fLongDist = m_fWheelFrontDist * 0.02;
|
||||
m_sWheels[0].fLatDist = m_fTrackWidth * 0.5 * -0.02;
|
||||
m_sWheels[1].fLatDist = m_fTrackWidth * 0.5 * 0.02;
|
||||
m_sWheels[2].fLatDist = m_fTrackWidth * 0.5 * -0.02;
|
||||
m_sWheels[3].fLatDist = m_fTrackWidth * 0.5 * 0.02;
|
||||
|
||||
// initialize the wheels
|
||||
for (i = 0; i < 4; i++) {
|
||||
m_sWheels[i].fLongForce = 0;
|
||||
m_sWheels[i].fForce = 0;
|
||||
|
||||
m_sWheels[i].vLongForce = vec_zero;
|
||||
m_sWheels[i].vLatForce = vec_zero;
|
||||
m_sWheels[i].vForce = vec_zero;
|
||||
m_sWheels[i].vVelocity = vec_zero;
|
||||
m_sWheels[i].bSkidding = false;
|
||||
m_sWheels[i].bSpinning = false;
|
||||
m_sWheels[i].fTorque = 0;
|
||||
m_sWheels[i].fLatTorque = 0;
|
||||
m_sWheels[i].fLongTorque = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
Vector p1, p3, p4;
|
||||
Vector vTp, vTr, vTu;
|
||||
vec3_t p2;
|
||||
|
||||
p3 = Corners[i];
|
||||
p3.normalize();
|
||||
|
||||
vectoangles(p3, p2);
|
||||
p1 = vec_zero;
|
||||
p1[1] = angles[1] + p2[1] + 90;
|
||||
p1.AngleVectorsLeft(&vTp, &vTr, &vTu);
|
||||
|
||||
m_sWheels[i].vVelocity = vTp * RAD2DEG(m_vAngularVelocity.y) * fabs(m_sWheels[i].fLongDist) * level.frametime;
|
||||
|
||||
G_LineWidth(5.0);
|
||||
|
||||
G_DebugLine(
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j,
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j + m_sWheels[i].vVelocity * 50,
|
||||
0.7f,
|
||||
0.5f,
|
||||
1.0f,
|
||||
1.0f
|
||||
);
|
||||
|
||||
p1 = vec_zero;
|
||||
p1[1] = angles[1] + RAD2DEG(m_sWheels[i].fYawOffset);
|
||||
p1.AngleVectorsLeft(&vTp, &vTr, &vTu);
|
||||
|
||||
m_sWheels[i].vOrientation = vTp;
|
||||
|
||||
G_LineWidth(5.0);
|
||||
|
||||
G_DebugLine(
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j,
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j + m_sWheels[i].vOrientation * 50,
|
||||
0.7f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
1.0f
|
||||
);
|
||||
}
|
||||
|
||||
Vector start, end;
|
||||
Vector boxoffset;
|
||||
Vector t_mins(-8, -8, -8);
|
||||
Vector t_maxs(8, 8, 8);
|
||||
trace_t trace;
|
||||
|
||||
start = origin + *vpn * (m_vCG[0] - localorigin[0]) + *vright * (m_vCG[1] - localorigin[1])
|
||||
+ *vup * (m_vCG[2] - localorigin[2]);
|
||||
|
||||
end = start;
|
||||
end[2] -= maxtracedist;
|
||||
|
||||
trace = G_Trace(start, t_mins, t_maxs, end, this, MASK_SOLID, qfalse, "Vehicle::PostThink Corners");
|
||||
|
||||
m_fInertia = m_fMass * 100;
|
||||
m_fWheelFrontLoad = m_fMass * 9.81 * fabs(m_fWheelFrontDist / m_fWheelBase);
|
||||
m_fWheelBackLoad = m_fMass * 9.81 * fabs(m_fWheelBackDist / m_fWheelBase);
|
||||
|
||||
longspeed = m_vAcceleration.length() * 0.02 * m_fMass / m_fWheelBase;
|
||||
m_fWheelFrontLoad -= longspeed;
|
||||
m_fWheelBackLoad += longspeed;
|
||||
m_sWheels[0].fLoad = m_fWheelBackLoad / 2.0;
|
||||
m_sWheels[1].fLoad = m_fWheelBackLoad / 2.0;
|
||||
m_sWheels[2].fLoad = m_fWheelFrontLoad / 2.0;
|
||||
m_sWheels[3].fLoad = m_fWheelFrontLoad / 2.0;
|
||||
|
||||
float fMassShifted = m_fTireRadius * M_PI;
|
||||
m_fTireRotationalSpeed = dots[3] / (fMassShifted + fMassShifted);
|
||||
m_iRPM = m_fTireRotationalSpeed * m_fGearRatio[m_iGear] * m_fDifferentialRatio * 10;
|
||||
m_fMaxTraction =
|
||||
TorqueLookup(m_iRPM) * m_fGearRatio[m_iGear] * m_fDifferentialRatio * m_fGearEfficiency / m_fTireRadius;
|
||||
m_fTractionForce = m_fAccelerator * m_fMaxTraction;
|
||||
|
||||
if (m_bIsBraking && dots[3] > 0) {
|
||||
m_fTractionForce = -fSign(dots[3]) * 1000 * dots[3];
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
float maxgrip;
|
||||
|
||||
maxgrip = m_sWheels[i].fTraction * m_sWheels[i].fLoad * 9.81;
|
||||
if (m_fTractionForce > maxgrip) {
|
||||
m_fTractionForce = maxgrip * 0.6;
|
||||
m_sWheels[i].bSpinning = true;
|
||||
m_sWheels[i].bSkidding = true;
|
||||
Com_Printf("Skidding!\n");
|
||||
}
|
||||
|
||||
if (m_fTractionForce < -maxgrip) {
|
||||
m_fTractionForce = -maxgrip * 0.6;
|
||||
m_sWheels[i].bSkidding = true;
|
||||
Com_Printf("Skidding!\n");
|
||||
}
|
||||
|
||||
m_sWheels[i].fLongForce = this->m_sWheels[i].fLongForce + m_fTractionForce;
|
||||
m_sWheels[i].vLongForce += m_sWheels[i].vOrientation * m_sWheels[i].fLongForce;
|
||||
}
|
||||
|
||||
m_vResistance[0] =
|
||||
-(velocity[0] * 0.02 * m_fRollingResistance + velocity[0] * 0.02 * m_fDrag * fabs(velocity[0] * 0.02));
|
||||
m_vResistance[1] =
|
||||
-(velocity[1] * 0.02 * m_fRollingResistance + velocity[1] * 0.02 * m_fDrag * fabs(velocity[1] * 0.02));
|
||||
m_vResistance[2] =
|
||||
-(velocity[2] * 0.02 * m_fRollingResistance + velocity[2] * 0.02 * m_fDrag * fabs(velocity[2] * 0.02));
|
||||
|
||||
m_fBrakingPerformance = -m_fRollingResistance - *vpn * Vector(0, 0, -1) * m_fMass;
|
||||
if (dots[3] == 0) {
|
||||
m_fBrakingPerformance = 0;
|
||||
} else {
|
||||
m_fBrakingPerformance = (dots[3] - (m_fTireRotationalSpeed * m_fTireRadius - m_fBrakingPerformance)) / dots[3];
|
||||
m_fBrakingPerformance = (1.0 - m_fBrakingPerformance) * -(-m_fFrontBrakingForce - m_fBackBrakingForce);
|
||||
}
|
||||
|
||||
if (r_velocity.length() * 0.02 > 0.01) {
|
||||
m_fTangForce = 0;
|
||||
m_vTangForce = vec_zero;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
Vector va, vr;
|
||||
Vector vVel;
|
||||
Vector v1, v2;
|
||||
|
||||
va = angles;
|
||||
va.x = 0;
|
||||
va.y += RAD2DEG(m_sWheels[i].fYawOffset);
|
||||
va.z = 0;
|
||||
va.AngleVectorsLeft(NULL, &vr, NULL);
|
||||
|
||||
vVel = m_sWheels[i].vVelocity + velocity;
|
||||
// get the direction
|
||||
v1 = vVel;
|
||||
v1.normalize();
|
||||
// get the angles
|
||||
vectoangles(v1, v2);
|
||||
|
||||
m_sWheels[i].fSlipAngle = DEG2RAD(angledist(va.y - v2.y));
|
||||
m_sWheels[i].fGripCoef = m_sWheels[i].fSlipAngle * 0.15;
|
||||
m_sWheels[i].fGripCoef = Q_clamp_float(m_sWheels[i].fGripCoef, -1.2f, 1.2f);
|
||||
m_sWheels[i].fLatForce += m_sWheels[i].fGripCoef * m_sWheels[i].fLoad * 9.81;
|
||||
|
||||
if (m_sWheels[i].fLoad * 2 * m_sWheels[i].fTraction < fabs(m_sWheels[i].fLatForce)) {
|
||||
m_sWheels[i].fLatForce = m_sWheels[i].fLatForce / 9.81;
|
||||
m_sWheels[i].bSkidding = true;
|
||||
Com_Printf("Skidding %i!\n", i);
|
||||
}
|
||||
|
||||
m_sWheels[i].vLatForce += vr * m_sWheels[i].fLatForce;
|
||||
|
||||
G_LineWidth(3.0);
|
||||
|
||||
G_DebugLine(
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j,
|
||||
origin + Corners[i][0] * r_i + Corners[i][1] * r_j + m_sWheels[i].vLatForce * 50 * (1.0 / m_fMass),
|
||||
0.7f,
|
||||
0.5f,
|
||||
0.2f,
|
||||
1.0f
|
||||
);
|
||||
}
|
||||
} else {
|
||||
m_fTangForce = 0;
|
||||
m_vTangForce = vec_zero;
|
||||
}
|
||||
|
||||
m_vForce = vec_zero;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
m_sWheels[i].vForce = m_sWheels[i].vLatForce + m_sWheels[i].vLongForce;
|
||||
m_vForce += m_sWheels[i].vForce;
|
||||
}
|
||||
|
||||
m_vForce += m_vResistance;
|
||||
|
||||
G_LineWidth(5.0);
|
||||
|
||||
G_DebugLine(origin, origin + m_vTangForce * (1.0 / m_fMass) * 50, 1.0, 0.0, 1.0, 1.0);
|
||||
|
||||
m_vAcceleration = m_vForce * (1.0 / m_fMass) * 50;
|
||||
m_fTorque = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
m_sWheels[i].fTorque += m_sWheels[i].fLongTorque + m_sWheels[i].fLatTorque;
|
||||
m_fTorque += m_sWheels[i].fTorque;
|
||||
}
|
||||
|
||||
m_vAngularAcceleration[1] = angledist(RAD2DEG(m_fTorque));
|
||||
m_vAngularVelocity += m_vAngularAcceleration * level.frametime;
|
||||
m_vAngularVelocity *= 0.825f;
|
||||
avelocity = m_vAngularVelocity;
|
||||
|
||||
if (m_bAutomatic) {
|
||||
//
|
||||
// set the gear
|
||||
//
|
||||
if (m_iRPM >= 2100 && m_iGear <= 2) {
|
||||
m_iGear++;
|
||||
}
|
||||
if (m_iRPM <= 600 && m_iGear > 1) {
|
||||
m_iGear--;
|
||||
}
|
||||
}
|
||||
|
||||
prev_moveimpulse = moveimpulse;
|
||||
}
|
||||
|
||||
void VehicleWheelsX4::Killed(Event *ev)
|
||||
{
|
||||
deadflag = DEAD_DEAD;
|
||||
}
|
||||
|
||||
float VehicleWheelsX4::TorqueLookup(int rpm)
|
||||
{
|
||||
if (rpm <= 2099)
|
||||
return 20.0;
|
||||
if (rpm > 3599)
|
||||
return 0.0;
|
||||
return (20 * (3600 - rpm)) * 0.001;
|
||||
if (rpm <= 2099) {
|
||||
return 20.0;
|
||||
}
|
||||
if (rpm > 3599) {
|
||||
return 0.0;
|
||||
}
|
||||
return (20 * (3600 - rpm)) * 0.001;
|
||||
}
|
||||
|
||||
void VehicleWheelsX4::Think()
|
||||
{
|
||||
vmove_t vm;
|
||||
flags |= FL_POSTTHINK;
|
||||
|
||||
prev_velocity = velocity;
|
||||
vmove_t vm;
|
||||
flags |= FL_POSTTHINK;
|
||||
|
||||
angles -= m_vAnglesOffset;
|
||||
origin -= m_vOriginOffset;
|
||||
prev_velocity = velocity;
|
||||
|
||||
mins = m_vOldMins;
|
||||
maxs = m_vOldMaxs;
|
||||
angles -= m_vAnglesOffset;
|
||||
origin -= m_vOriginOffset;
|
||||
|
||||
SetMoveInfo(&vm);
|
||||
VmoveSingle(&vm);
|
||||
GetMoveInfo(&vm);
|
||||
mins = m_vOldMins;
|
||||
maxs = m_vOldMaxs;
|
||||
|
||||
SetMoveInfo(&vm);
|
||||
VmoveSingle(&vm);
|
||||
GetMoveInfo(&vm);
|
||||
}
|
||||
|
||||
void VehicleWheelsX4::Postthink()
|
||||
{
|
||||
// FIXME: STUB
|
||||
}
|
||||
float turn;
|
||||
Vector i, j, k;
|
||||
int index;
|
||||
trace_t trace;
|
||||
Vector normalsum;
|
||||
Vector normalsum_Front;
|
||||
int numnormals_Front;
|
||||
Vector normalsum_Back;
|
||||
int numnormals_Back;
|
||||
Vector temp;
|
||||
Vector pitch, roll;
|
||||
Vector acceleration;
|
||||
Vector atmp, atmp2, aup;
|
||||
VehicleBase *v;
|
||||
VehicleBase *last;
|
||||
float drivespeed;
|
||||
Vector primal_angles;
|
||||
Vector vTmp;
|
||||
Vector n_angles;
|
||||
|
||||
void VehicleWheelsX4::Killed(Event* ev)
|
||||
{
|
||||
deadflag = DEAD_DEAD;
|
||||
primal_angles = angles;
|
||||
|
||||
if (drivable) {
|
||||
if (m_bAutoPilot) {
|
||||
AutoPilot();
|
||||
} else {
|
||||
moveimpulse *= 0.825f;
|
||||
turnimpulse *= 0.825f;
|
||||
}
|
||||
|
||||
currentspeed = moveimpulse;
|
||||
turnangle = turnangle * 0.25f + turnimpulse;
|
||||
turnangle = Q_clamp_float(turnangle, -maxturnrate, maxturnrate);
|
||||
|
||||
if (turnangle > maxturnrate) {
|
||||
turnangle = maxturnrate;
|
||||
} else if (turnangle < -maxturnrate) {
|
||||
turnangle = -maxturnrate;
|
||||
} else if (fabs(turnangle) < 2) {
|
||||
turnangle = 0;
|
||||
}
|
||||
|
||||
real_velocity = origin - prev_origin;
|
||||
prev_origin = origin;
|
||||
prev_acceleration = real_acceleration;
|
||||
real_acceleration = real_velocity - prev_velocity;
|
||||
prev_velocity = real_velocity;
|
||||
acceleration = real_acceleration - prev_acceleration;
|
||||
|
||||
angles[0] = 0;
|
||||
angles[2] = 0;
|
||||
|
||||
temp[0] = angles[0];
|
||||
temp[1] = angles[1];
|
||||
temp[2] = angles[2];
|
||||
temp.AngleVectorsLeft(&i, &j, &k);
|
||||
|
||||
j = vec_zero - j;
|
||||
|
||||
index = 0;
|
||||
numnormals_Front = 0;
|
||||
numnormals_Back = 0;
|
||||
|
||||
for (index = 0; index < 4; index++) {
|
||||
Vector start, end;
|
||||
Vector boxoffset;
|
||||
Vector t_mins(-8, -8, -8);
|
||||
Vector t_maxs(8, 8, 8);
|
||||
|
||||
boxoffset = Corners[index];
|
||||
|
||||
start = origin + i * boxoffset[0] + j * boxoffset[1] + k * boxoffset[2];
|
||||
end = start;
|
||||
end[2] -= maxtracedist;
|
||||
|
||||
trace = G_Trace(start, mins, maxs, end, this, MASK_SOLID, qfalse, "Vehicle::PostThink Corners");
|
||||
|
||||
if (trace.fraction != 1 && !trace.startsolid) {
|
||||
if (index > 2) {
|
||||
normalsum_Front += trace.plane.normal;
|
||||
numnormals_Front++;
|
||||
} else {
|
||||
normalsum_Back += trace.plane.normal;
|
||||
numnormals_Back++;
|
||||
}
|
||||
|
||||
normalsum += trace.plane.normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (angles[2] < 60 || angles[2] > 300) {
|
||||
if (numnormals_Front > 1) {
|
||||
m_vFrontNormal = normalsum_Front * (1.0 / numnormals_Front);
|
||||
|
||||
temp = m_vFrontNormal;
|
||||
m_vFrontAngles[0] = -temp.CrossProduct(temp, j).toPitch();
|
||||
// no yaw
|
||||
m_vFrontAngles[1] = 0;
|
||||
|
||||
temp = m_vFrontNormal;
|
||||
m_vFrontAngles[2] = temp.CrossProduct(temp, i).toPitch();
|
||||
}
|
||||
|
||||
if (numnormals_Back > 1) {
|
||||
m_vBackNormal = normalsum_Back * (1.0 / numnormals_Back);
|
||||
|
||||
temp = m_vBackNormal;
|
||||
m_vBackAngles[0] = -temp.CrossProduct(temp, j).toPitch();
|
||||
// no yaw
|
||||
m_vBackAngles[1] = 0;
|
||||
|
||||
temp = m_vBackNormal;
|
||||
m_vBackAngles[2] = temp.CrossProduct(temp, i).toPitch();
|
||||
}
|
||||
|
||||
if (numnormals_Front + numnormals_Back > 1) {
|
||||
m_vBaseNormal = (normalsum_Front + normalsum_Back) * (1.0 / numnormals_Front + numnormals_Back);
|
||||
|
||||
temp = m_vBaseNormal;
|
||||
m_vBaseAngles[0] = -temp.CrossProduct(temp, j).toPitch();
|
||||
// no yaw
|
||||
m_vBaseAngles[1] = 0;
|
||||
|
||||
temp = m_vBaseNormal;
|
||||
m_vBaseAngles[2] = temp.CrossProduct(temp, i).toPitch();
|
||||
}
|
||||
}
|
||||
|
||||
n_angles = m_vBaseAngles - angles;
|
||||
n_angles[0] = angledist(n_angles[0]);
|
||||
n_angles[1] = angledist(n_angles[1]);
|
||||
n_angles[2] = angledist(n_angles[2]);
|
||||
|
||||
angles[0] += n_angles[0] * 4.5 * level.frametime;
|
||||
angles[2] += n_angles[2] * 4.5 * level.frametime;
|
||||
|
||||
m_vPrevNormal = m_vBaseNormal;
|
||||
|
||||
if (currentspeed < 0 && velocity * i > 0) {
|
||||
m_fFrontBrakingForce = 0.2f;
|
||||
m_fBackBrakingForce = 0.1f;
|
||||
} else {
|
||||
m_fFrontBrakingForce = 0;
|
||||
m_fBackBrakingForce = 0;
|
||||
}
|
||||
|
||||
turn = turnangle * 0.005;
|
||||
|
||||
Vector _i, _j, _k;
|
||||
Vector vNewVpn = angles;
|
||||
vNewVpn.y += turnangle;
|
||||
|
||||
vNewVpn.AngleVectorsLeft(&_i, &_j, &_k);
|
||||
UpdateVariables(&acceleration, &i, &j, &k, &_i, &_j, &_k);
|
||||
|
||||
m_vAngles = angles;
|
||||
|
||||
if (currentspeed < 0 && velocity * i > 0) {
|
||||
currentspeed = 0;
|
||||
}
|
||||
|
||||
normalsum = vec_zero;
|
||||
|
||||
for (index = 0; index < 4; index++) {
|
||||
Vector start, end;
|
||||
Vector boxoffset;
|
||||
Vector t_mins(-8, -8, -8);
|
||||
Vector t_maxs(8, 8, 8);
|
||||
|
||||
boxoffset = Corners[index];
|
||||
|
||||
start = origin + i * boxoffset[0] + j * boxoffset[1] + k * boxoffset[2] + Vector(0, 0, 10);
|
||||
end = start;
|
||||
end[2] -= maxtracedist;
|
||||
|
||||
trace = G_Trace(start, mins, maxs, end, this, MASK_SOLID, qfalse, "Vehicle::PostThink Corners");
|
||||
|
||||
if (trace.fraction != 1.0) {
|
||||
float fCoef;
|
||||
|
||||
if (index > 2) {
|
||||
fCoef = m_fWheelFrontLoad / (m_fWheelFrontDist / m_fWheelBase * m_fMass);
|
||||
fCoef = Q_clamp_float(fCoef, 0, 1);
|
||||
|
||||
normalsum += _i * currentspeed * fCoef;
|
||||
normalsum += i * currentspeed * (1.0 - fCoef);
|
||||
} else {
|
||||
fCoef = m_fWheelBackLoad / (m_fWheelBackDist / m_fWheelBase * m_fMass);
|
||||
fCoef = Q_clamp_float(fCoef, 0, 1);
|
||||
|
||||
normalsum += i * currentspeed * fCoef;
|
||||
normalsum += _i * currentspeed * (1.0 - fCoef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnglesToAxis(angles, orientation);
|
||||
|
||||
vmove_t vm;
|
||||
SetMoveInfo(&vm);
|
||||
m_sMoveGrid->SetMoveInfo(&vm);
|
||||
m_sMoveGrid->SetOrientation(orientation);
|
||||
|
||||
if (m_sMoveGrid->CheckStuck()) {
|
||||
angles = primal_angles;
|
||||
AnglesToAxis(angles, orientation);
|
||||
}
|
||||
|
||||
m_fForwardForce = acceleration * i * 0.1;
|
||||
m_fBackForce += -m_vAnglesOffset[0] * m_fBouncyCoef;
|
||||
m_fBackForce *= m_fSpringyCoef;
|
||||
|
||||
m_vAnglesOffset[0] += m_fForwardForce + m_fBackForce * 12.0 * level.frametime;
|
||||
m_vAnglesOffset[0] = Q_clamp_float(m_vAnglesOffset[0], m_fYawMin, m_fYawMax);
|
||||
|
||||
m_fLeftForce += acceleration * j * 0.1;
|
||||
m_fRightForce += -m_vAnglesOffset[2] * m_fBouncyCoef;
|
||||
m_fRightForce *= m_fSpringyCoef;
|
||||
|
||||
m_vAnglesOffset[2] += (m_fLeftForce + m_fRightForce) * 12.0 * level.frametime;
|
||||
m_vAnglesOffset[2] = Q_clamp_float(m_vAnglesOffset[2], m_fRollMin, m_fRollMax);
|
||||
|
||||
m_fDownForce = acceleration[2];
|
||||
m_fUpForce += -m_vOriginOffset[2] * m_fBouncyCoef;
|
||||
m_fUpForce *= m_fSpringyCoef;
|
||||
|
||||
m_vAnglesOffset[2] += (m_fDownForce + m_fUpForce) * 12.0 * level.frametime;
|
||||
m_vAnglesOffset[2] = Q_clamp_float(m_vAnglesOffset[2], m_fZMin, m_fZMax);
|
||||
|
||||
if (groundentity && (angles[2] < 60 || angles[2] > 300)) {
|
||||
velocity += m_vAcceleration * level.frametime;
|
||||
} else {
|
||||
if (angles[2] > 60) {
|
||||
angles[2]; // FIXME: ??
|
||||
}
|
||||
|
||||
velocity += m_vAcceleration * level.frametime;
|
||||
}
|
||||
|
||||
angles += avelocity * level.frametime;
|
||||
setAngles(angles);
|
||||
|
||||
prev_origin = origin;
|
||||
}
|
||||
|
||||
drivespeed = acceleration * orientation[0];
|
||||
|
||||
if (drivable && driver.ent) {
|
||||
str sound_name;
|
||||
|
||||
if (currentspeed > 0) {
|
||||
sound_name = "snd_forward";
|
||||
} else if (currentspeed == 0) {
|
||||
sound_name = "snd_idle";
|
||||
} else {
|
||||
sound_name = "snd_backward";
|
||||
}
|
||||
|
||||
LoopSound(sound_name);
|
||||
}
|
||||
|
||||
i = orientation[0];
|
||||
j = orientation[1];
|
||||
k = orientation[2];
|
||||
|
||||
last_origin = origin;
|
||||
|
||||
vTmp = (angles - primal_angles) * level.frametime;
|
||||
if (vTmp.x > 180 || vTmp.x < -180) {
|
||||
vTmp.x = 0;
|
||||
}
|
||||
if (vTmp.y > 180 || vTmp.y < -180) {
|
||||
vTmp.y = 0;
|
||||
}
|
||||
if (vTmp.z > 180 || vTmp.z < -180) {
|
||||
vTmp.z = 0;
|
||||
}
|
||||
|
||||
if (vTmp.x > -1 || vTmp.x < 1) {
|
||||
vTmp.x = 0;
|
||||
}
|
||||
if (vTmp.y > -1 || vTmp.y < 1) {
|
||||
vTmp.y = 0;
|
||||
}
|
||||
if (vTmp.z > -1 || vTmp.z < 1) {
|
||||
vTmp.z = 0;
|
||||
}
|
||||
|
||||
avelocity = vTmp;
|
||||
origin += m_vOriginOffset;
|
||||
setOrigin(origin);
|
||||
|
||||
angles += m_vAnglesOffset;
|
||||
setAngles(angles);
|
||||
|
||||
if (driver.ent) {
|
||||
driver.ent->setOrigin(origin + i * driveroffset[0] + j * driveroffset[1] + k * driveroffset[2]);
|
||||
|
||||
if (drivable) {
|
||||
// clear the driver velocity
|
||||
driver.ent->velocity = vec_zero;
|
||||
// set the driver angles to the vehicle's angle
|
||||
driver.ent->setAngles(angles);
|
||||
}
|
||||
}
|
||||
|
||||
for (last = this; last->vlink; last = v) {
|
||||
v = last->vlink;
|
||||
|
||||
v->setOrigin(origin + i * v->offset.x + j * v->offset.y + k * v->offset.z);
|
||||
v->avelocity = avelocity;
|
||||
v->velocity = velocity;
|
||||
|
||||
v->angles[ROLL] = angles[ROLL];
|
||||
v->angles[YAW] = angles[YAW];
|
||||
v->angles[PITCH] = (int)(drivespeed / 4.f + v->angles[PITCH]) % 360;
|
||||
v->setAngles(v->angles);
|
||||
}
|
||||
|
||||
CheckWater();
|
||||
WorldEffects();
|
||||
|
||||
if (!driver.ent && !velocity.length() && groundentity && !(watertype & CONTENTS_LAVA)) {
|
||||
// make the vehicle stationary if it's completely immobile
|
||||
flags &= ~FL_POSTTHINK;
|
||||
if (drivable) {
|
||||
setMoveType(MOVETYPE_STATIONARY);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10937
-13867
File diff suppressed because it is too large.
Load diff
+1920
-1346
File diff suppressed because it is too large.
Load diff
+35
-45
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,52 +24,42 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitAim
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitAim(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_Aim;
|
||||
func->ThinkState = &Actor::Think_Aim;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->ShowInfo = &Actor::ShowInfo_Aim;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
}
|
||||
void Actor::Begin_Aim
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
m_csMood = STRING_ALERT;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
ClearPath();
|
||||
}
|
||||
void Actor::Think_Aim
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
if( !RequireThink() )
|
||||
return;
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
m_pszDebugState = "";
|
||||
Anim_Aim();
|
||||
|
||||
if( m_aimNode )
|
||||
{
|
||||
AimAtAimNode();
|
||||
}
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink( true );
|
||||
func->BeginState = &Actor::Begin_Aim;
|
||||
func->ThinkState = &Actor::Think_Aim;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->ShowInfo = &Actor::ShowInfo_Aim;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
}
|
||||
|
||||
void Actor::ShowInfo_Aim
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Aim(void)
|
||||
{
|
||||
ShowInfo_AimNode();
|
||||
m_csMood = STRING_ALERT;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
ClearPath();
|
||||
}
|
||||
|
||||
void Actor::Think_Aim(void)
|
||||
{
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
m_pszDebugState = "";
|
||||
Anim_Aim();
|
||||
|
||||
if (m_aimNode) {
|
||||
AimAtAimNode();
|
||||
}
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(true);
|
||||
}
|
||||
|
||||
void Actor::ShowInfo_Aim(void)
|
||||
{
|
||||
ShowInfo_AimNode();
|
||||
}
|
||||
+73
-110
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,143 +24,106 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitAlarm
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitAlarm(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_Alarm;
|
||||
func->EndState = &Actor::End_Alarm;
|
||||
func->ThinkState = &Actor::Think_Alarm;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack;
|
||||
func->IsState = &Actor::IsAttackState;
|
||||
func->BeginState = &Actor::Begin_Alarm;
|
||||
func->EndState = &Actor::End_Alarm;
|
||||
func->ThinkState = &Actor::Think_Alarm;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack;
|
||||
func->IsState = &Actor::IsAttackState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Alarm
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Alarm(void)
|
||||
{
|
||||
DoForceActivate();
|
||||
DoForceActivate();
|
||||
|
||||
m_csMood = STRING_ALERT;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
m_csMood = STRING_ALERT;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
|
||||
if( m_AlarmNode )
|
||||
{
|
||||
SetPath( m_AlarmNode, "Actor::Begin_Alarm", 0 );
|
||||
if (!m_AlarmNode) {
|
||||
State_Alarm_StartThread();
|
||||
return;
|
||||
}
|
||||
|
||||
if( PathExists() )
|
||||
{
|
||||
TransitionState(601, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
TransitionState(600, 0);
|
||||
parm.movefail = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLeashHome( origin );
|
||||
TransitionState(600, 0);
|
||||
m_AlarmThread.Execute( this );
|
||||
}
|
||||
SetPath(m_AlarmNode, "Actor::Begin_Alarm", 0);
|
||||
|
||||
if (PathExists()) {
|
||||
TransitionState(ACTOR_STATE_ALARM_MOVE, 0);
|
||||
} else {
|
||||
TransitionState(ACTOR_STATE_ALARM_IDLE, 0);
|
||||
parm.movefail = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::End_Alarm
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_Alarm(void)
|
||||
{
|
||||
parm.movefail = true;
|
||||
parm.movefail = true;
|
||||
}
|
||||
|
||||
void Actor::State_Alarm_StartThread
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Alarm_StartThread(void)
|
||||
{
|
||||
if( m_AlarmNode )
|
||||
SetLeashHome( m_AlarmNode->origin );
|
||||
else
|
||||
SetLeashHome( origin );
|
||||
SetLeashHome(m_AlarmNode ? m_AlarmNode->origin : origin);
|
||||
// Added in 2.30.
|
||||
// Execute the pre-alarm thread
|
||||
m_PreAlarmThread.Execute(this);
|
||||
|
||||
TransitionState(600, 0);
|
||||
m_AlarmThread.Execute();
|
||||
TransitionState(ACTOR_STATE_ALARM_IDLE, 0);
|
||||
m_AlarmThread.Execute(this);
|
||||
}
|
||||
|
||||
void Actor::State_Alarm_Move
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Alarm_Move(void)
|
||||
{
|
||||
if( PathExists() )
|
||||
{
|
||||
if( PathComplete() )
|
||||
{
|
||||
Anim_Aim();
|
||||
AimAtTargetPos();
|
||||
}
|
||||
else
|
||||
{
|
||||
Anim_RunToAlarm( 2 );
|
||||
FaceMotion();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TransitionState(600, 0);
|
||||
parm.movefail = true;
|
||||
if (!PathExists()) {
|
||||
TransitionState(ACTOR_STATE_ALARM_IDLE, 0);
|
||||
parm.movefail = true;
|
||||
|
||||
Anim_Aim();
|
||||
AimAtTargetPos();
|
||||
}
|
||||
Anim_Aim();
|
||||
AimAtTargetPos();
|
||||
} else if (PathComplete()) {
|
||||
Anim_Aim();
|
||||
AimAtTargetPos();
|
||||
State_Alarm_StartThread();
|
||||
} else {
|
||||
Anim_RunToAlarm(ANIM_MODE_PATH);
|
||||
FaceMotion();
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Alarm_Idle
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Alarm_Idle(void)
|
||||
{
|
||||
AimAtTargetPos();
|
||||
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
|
||||
Anim_Aim();
|
||||
AimAtTargetPos();
|
||||
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
|
||||
}
|
||||
|
||||
void Actor::Think_Alarm
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_Alarm(void)
|
||||
{
|
||||
if( !RequireThink() )
|
||||
return;
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
parm.movefail = false;
|
||||
parm.movefail = false;
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
|
||||
if( m_State == 600 )
|
||||
{
|
||||
m_pszDebugState = "idle";
|
||||
State_Alarm_Idle();
|
||||
}
|
||||
else if( m_State == 601 )
|
||||
{
|
||||
m_pszDebugState = "move";
|
||||
State_Alarm_Move();
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf( "Actor::Think_Alarm: invalid think state %i\n", m_State );
|
||||
}
|
||||
switch (m_State) {
|
||||
case ACTOR_STATE_ALARM_IDLE:
|
||||
m_pszDebugState = "idle";
|
||||
State_Alarm_Idle();
|
||||
break;
|
||||
case ACTOR_STATE_ALARM_MOVE:
|
||||
m_pszDebugState = "move";
|
||||
State_Alarm_Move();
|
||||
break;
|
||||
default:
|
||||
Com_Printf("Actor::Think_Alarm: invalid think state %i\n", m_State);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_Alarm
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::FinishedAnimation_Alarm(void)
|
||||
{
|
||||
// not needed
|
||||
return;
|
||||
// not needed
|
||||
return;
|
||||
}
|
||||
+48
-63
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,81 +24,66 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitAnim
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitAnim(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_Anim;
|
||||
func->BeginState = &Actor::Begin_Anim;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Anim;
|
||||
func->ShowInfo = &Actor::ShowInfo_Anim;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
func->ThinkState = &Actor::Think_Anim;
|
||||
func->BeginState = &Actor::Begin_Anim;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Anim;
|
||||
func->ShowInfo = &Actor::ShowInfo_Anim;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Anim
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Anim(void)
|
||||
{
|
||||
m_csMood = m_csIdleMood;
|
||||
ClearPath();
|
||||
StopTurning();
|
||||
TransitionState(1000, 0);
|
||||
m_csMood = m_csIdleMood;
|
||||
ClearPath();
|
||||
StopTurning();
|
||||
TransitionState(ACTOR_STATE_ANIMATION_INITIAL, 0);
|
||||
}
|
||||
|
||||
void Actor::Think_Anim
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_Anim(void)
|
||||
{
|
||||
if (RequireThink())
|
||||
{
|
||||
UpdateEyeOrigin();
|
||||
IdlePoint();
|
||||
IdleLook();
|
||||
if (m_State == 1000)
|
||||
{
|
||||
m_bNextForceStart = true;
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_bAnimScriptSet = false;
|
||||
m_pszDebugState = "initial";
|
||||
TransitionState(1001, 0);
|
||||
}
|
||||
else if (m_State == 1001)
|
||||
{
|
||||
m_bNextForceStart = false;
|
||||
m_pszDebugState = "main";
|
||||
}
|
||||
m_eNextAnimMode = m_AnimMode;
|
||||
m_csNextAnimString = m_csAnimScript;
|
||||
UpdateEyeOrigin();
|
||||
IdlePoint();
|
||||
IdleLook();
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
IdleTurn();
|
||||
PostThink(false);
|
||||
}
|
||||
if (m_State == ACTOR_STATE_ANIMATION_INITIAL) {
|
||||
m_pszDebugState = "initial";
|
||||
m_bAnimScriptSet = false;
|
||||
StartAnimation(m_AnimMode, m_csAnimScript);
|
||||
TransitionState(ACTOR_STATE_ANIMATION_MAIN, 0);
|
||||
} else if (m_State == ACTOR_STATE_ANIMATION_MAIN) {
|
||||
m_bNextForceStart = false;
|
||||
m_pszDebugState = "main";
|
||||
DesiredAnimation(m_AnimMode, m_csAnimScript);
|
||||
}
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
IdleTurn();
|
||||
PostThink(false);
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_Anim
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::FinishedAnimation_Anim(void)
|
||||
{
|
||||
if (!m_bAnimScriptSet)
|
||||
{
|
||||
if (m_bNoIdleAfterAnim)
|
||||
m_csAnimScript = STRING_ANIM_CONTINUE_LAST_ANIM_SCR;
|
||||
else
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
Unregister(STRING_ANIMDONE);
|
||||
}
|
||||
if (m_bAnimScriptSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_bNoIdleAfterAnim) {
|
||||
m_csAnimScript = STRING_ANIM_CONTINUE_LAST_ANIM_SCR;
|
||||
} else {
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
}
|
||||
|
||||
Unregister(STRING_ANIMDONE);
|
||||
}
|
||||
|
||||
void Actor::ShowInfo_Anim
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::ShowInfo_Anim(void)
|
||||
{
|
||||
Com_Printf("anim script: %s, anim mode %d\n", Director.GetString(m_csAnimScript).c_str(), m_AnimMode);
|
||||
Com_Printf("anim script: %s, anim mode %d\n", Director.GetString(m_csAnimScript).c_str(), m_AnimMode);
|
||||
}
|
||||
+103
-191
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -23,289 +23,201 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// actor_animapi.cpp: Base actor animation script
|
||||
|
||||
#include "actor.h"
|
||||
#include "scriptthread.h"
|
||||
|
||||
const_str SimpleActor::GetRunAnim
|
||||
(
|
||||
void
|
||||
)
|
||||
const_str SimpleActor::GetRunAnim(void)
|
||||
{
|
||||
if( m_csCurrentPosition != STRING_PRONE && ( m_csCurrentPosition < STRING_PRONE || m_csCurrentPosition > STRING_CROUCHRUN ) )
|
||||
return STRING_ANIM_RUN_SCR;
|
||||
else
|
||||
return STRING_ANIM_CROUCH_RUN_SCR;
|
||||
if (m_csCurrentPosition == STRING_PRONE) {
|
||||
return STRING_ANIM_CROUCH_RUN_SCR;
|
||||
}
|
||||
|
||||
if (m_csCurrentPosition >= STRING_PRONE && m_csCurrentPosition <= STRING_CROUCHRUN && m_csCurrentPosition >= STRING_CROUCH) {
|
||||
return STRING_ANIM_CROUCH_RUN_SCR;
|
||||
} else {
|
||||
return STRING_ANIM_RUN_SCR;
|
||||
}
|
||||
}
|
||||
|
||||
const_str SimpleActor::GetWalkAnim
|
||||
(
|
||||
void
|
||||
)
|
||||
const_str SimpleActor::GetWalkAnim(void)
|
||||
{
|
||||
if( m_csCurrentPosition != STRING_PRONE && ( m_csCurrentPosition < STRING_PRONE || m_csCurrentPosition > STRING_CROUCHRUN ) )
|
||||
return STRING_ANIM_WALK_SCR;
|
||||
else
|
||||
return STRING_ANIM_CROUCH_WALK_SCR;
|
||||
if (m_csCurrentPosition == STRING_PRONE) {
|
||||
return STRING_ANIM_CROUCH_WALK_SCR;
|
||||
}
|
||||
|
||||
if (m_csCurrentPosition >= STRING_PRONE && m_csCurrentPosition <= STRING_CROUCHRUN && m_csCurrentPosition >= STRING_CROUCH) {
|
||||
return STRING_ANIM_CROUCH_WALK_SCR;
|
||||
} else {
|
||||
return STRING_ANIM_WALK_SCR;
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Attack
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Attack(void)
|
||||
{
|
||||
DesiredAnimation(1, m_AttackHandler);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, m_AttackHandler);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Sniper
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Suppress(void)
|
||||
{
|
||||
DesiredAnimation(1, m_SniperHandler);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_SUPPRESS_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Aim
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Sniper(void)
|
||||
{
|
||||
DesiredAnimation(1, STRING_ANIM_AIM_SCR);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, m_SniperHandler);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Shoot
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Aim(void)
|
||||
{
|
||||
DesiredAnimation(1, STRING_ANIM_SHOOT_SCR);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_AIM_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Idle
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Shoot(void)
|
||||
{
|
||||
DesiredAnimation(1, STRING_ANIM_IDLE_SCR);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_SHOOT_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Crouch
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Idle(void)
|
||||
{
|
||||
DesiredAnimation(1, STRING_ANIM_CROUCH_SCR);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_IDLE_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Prone
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Crouch(void)
|
||||
{
|
||||
DesiredAnimation(1, STRING_ANIM_PRONE_SCR);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_CROUCH_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Stand
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Prone(void)
|
||||
{
|
||||
DesiredAnimation(1, STRING_ANIM_STAND_SCR);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_PRONE_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Cower
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Stand(void)
|
||||
{
|
||||
DesiredAnimation(1, STRING_ANIM_COWER_SCR);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_STAND_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Killed
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Cower(void)
|
||||
{
|
||||
Com_Printf("m_eAnimMode Anim_Killed \n");
|
||||
DesiredAnimation(1, m_DeathHandler);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_COWER_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_StartPain
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_Killed(void)
|
||||
{
|
||||
Com_Printf("m_eAnimMode Anim_StartPain \n");
|
||||
StartAnimation(1, m_PainHandler);
|
||||
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, m_DeathHandler);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Pain
|
||||
(
|
||||
void
|
||||
)
|
||||
void SimpleActor::Anim_StartPain(void)
|
||||
{
|
||||
ContinueAnimation();
|
||||
StartAnimation(ANIM_MODE_NORMAL, m_PainHandler);
|
||||
}
|
||||
|
||||
|
||||
void SimpleActor::Anim_CrouchRunTo
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_Pain(void)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_CROUCH_RUN_SCR);
|
||||
ContinueAnimation();
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_CrouchWalkTo
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_CrouchRunTo(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_CROUCH_WALK_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_CROUCH_RUN_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_StandRunTo
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_CrouchWalkTo(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUN_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_CROUCH_WALK_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_StandWalkTo
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_StandRunTo(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_WALK_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUN_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunTo
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_StandWalkTo(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, GetRunAnim());
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_WALK_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_WalkTo
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunTo(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, GetWalkAnim());
|
||||
DesiredAnimation(eAnimMode, GetRunAnim());
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunAwayFiring
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunAwayFiring(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNAWAYFIRING_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNAWAYFIRING_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunToShooting
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunToShooting(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUN_SHOOT_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUN_SHOOT_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunToAlarm
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunToAlarm(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_ALARM_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_ALARM_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunToCasual
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunToCasual(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_CASUAL_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_CASUAL_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunToCover
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunToCover(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_COVER_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_COVER_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunToDanger
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunToDanger(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_DANGER_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_DANGER_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunToDive
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunToDive(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_DIVE_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_DIVE_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunToFlee
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunToFlee(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_FLEE_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_FLEE_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_RunToInOpen
|
||||
(
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_RunToInOpen(int eAnimMode)
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_INOPEN_SCR);
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_RUNTO_INOPEN_SCR);
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Emotion
|
||||
(
|
||||
eEmotionMode eEmotMode
|
||||
)
|
||||
void SimpleActor::Anim_WalkTo(int eAnimMode)
|
||||
{
|
||||
m_eEmotionMode = eEmotMode;
|
||||
DesiredAnimation(eAnimMode, GetWalkAnim());
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_Say
|
||||
(
|
||||
const_str csSayAnimScript,
|
||||
int iMinTimeSinceLastSay,
|
||||
bool bCanInterrupt
|
||||
)
|
||||
void SimpleActor::Anim_Emotion(eEmotionMode eEmotMode)
|
||||
{
|
||||
if (!m_bSayAnimSet || bCanInterrupt)
|
||||
{
|
||||
if (level.inttime > m_iVoiceTime + iMinTimeSinceLastSay)
|
||||
{
|
||||
ScriptThreadLabel label;
|
||||
|
||||
label.TrySetScript(csSayAnimScript);
|
||||
label.Execute(this);
|
||||
}
|
||||
}
|
||||
m_eEmotionMode = eEmotMode;
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_FullBody
|
||||
(
|
||||
const_str csFullBodyAnim,
|
||||
int eAnimMode
|
||||
)
|
||||
void SimpleActor::Anim_Say(const_str csSayAnimScript, int iMinTimeSinceLastSay, bool bCanInterrupt)
|
||||
{
|
||||
if( m_csAnimName == csFullBodyAnim )
|
||||
{
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_FULLBODY_SCR);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_csAnimName = csFullBodyAnim;
|
||||
StartAnimation(eAnimMode, STRING_ANIM_FULLBODY_SCR);
|
||||
}
|
||||
if (m_bSayAnimSet && !bCanInterrupt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (level.inttime <= iMinTimeSinceLastSay + m_iVoiceTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptThreadLabel label;
|
||||
|
||||
label.TrySetScript(csSayAnimScript);
|
||||
label.Create(this)->Execute();
|
||||
}
|
||||
|
||||
void SimpleActor::Anim_FullBody(const_str csFullBodyAnim, int eAnimMode)
|
||||
{
|
||||
if (m_csAnimName == csFullBodyAnim) {
|
||||
DesiredAnimation(eAnimMode, STRING_ANIM_FULLBODY_SCR);
|
||||
} else {
|
||||
m_csAnimName = csFullBodyAnim;
|
||||
StartAnimation(eAnimMode, STRING_ANIM_FULLBODY_SCR);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,56 +24,47 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitAnimCurious
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitAnimCurious(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_AnimCurious;
|
||||
func->BeginState = &Actor::Begin_AnimCurious;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Anim;
|
||||
func->ShowInfo = &Actor::ShowInfo_Anim;
|
||||
func->IsState = &Actor::IsCuriousState;
|
||||
func->ThinkState = &Actor::Think_AnimCurious;
|
||||
func->BeginState = &Actor::Begin_AnimCurious;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Anim;
|
||||
func->ShowInfo = &Actor::ShowInfo_Anim;
|
||||
func->IsState = &Actor::IsCuriousState;
|
||||
}
|
||||
|
||||
void Actor::Begin_AnimCurious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_AnimCurious(void)
|
||||
{
|
||||
DoForceActivate();
|
||||
DoForceActivate();
|
||||
|
||||
m_csMood = STRING_CURIOUS;
|
||||
StartAnimation(m_AnimMode, m_csAnimScript);
|
||||
StopTurning();
|
||||
m_iCuriousTime = level.inttime;
|
||||
m_csMood = STRING_CURIOUS;
|
||||
m_iCuriousTime = level.inttime;
|
||||
StopTurning();
|
||||
StartAnimation(m_AnimMode, m_csAnimScript);
|
||||
}
|
||||
|
||||
void Actor::Think_AnimCurious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_AnimCurious(void)
|
||||
{
|
||||
if( !RequireThink() )
|
||||
return;
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "";
|
||||
LookAtCuriosity();
|
||||
TimeOutCurious();
|
||||
DesiredAnimation(m_AnimMode, m_csAnimScript);
|
||||
CheckForThinkStateTransition();
|
||||
PostThink( false );
|
||||
UpdateEyeOrigin();
|
||||
|
||||
m_pszDebugState = "";
|
||||
LookAtCuriosity();
|
||||
TimeOutCurious();
|
||||
|
||||
DesiredAnimation(m_AnimMode, m_csAnimScript);
|
||||
CheckForThinkStateTransition();
|
||||
|
||||
PostThink(false);
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_AnimCurious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::FinishedAnimation_AnimCurious(void)
|
||||
{
|
||||
if( m_State == 1101 )
|
||||
{
|
||||
TransitionState(1100, 0);
|
||||
}
|
||||
if (m_State == ACTOR_STATE_CURIOUS_RUNNING) {
|
||||
TransitionState(ACTOR_STATE_CURIOUS_BEGIN, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// actor_badplace.cpp
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitBadPlace(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_BadPlace;
|
||||
func->BeginState = &Actor::Begin_BadPlace;
|
||||
func->EndState = &Actor::End_BadPlace;
|
||||
func->ResumeState = &Actor::Begin_BadPlace;
|
||||
func->SuspendState = &Actor::End_BadPlace;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_BadPlace;
|
||||
func->IsState = &Actor::IsBadPlaceState;
|
||||
}
|
||||
|
||||
void Actor::Begin_BadPlace(void)
|
||||
{
|
||||
DoForceActivate();
|
||||
|
||||
m_csMood = STRING_ALERT;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
|
||||
badplace_t& badplace = level.m_badPlaces.ObjectAt(m_iBadPlaceIndex);
|
||||
|
||||
FindPathAway(badplace.m_vOrigin, origin - badplace.m_vOrigin, badplace.m_fRadius + 64);
|
||||
}
|
||||
|
||||
void Actor::End_BadPlace(void)
|
||||
{
|
||||
m_iBadPlaceIndex = 0;
|
||||
}
|
||||
|
||||
void Actor::Think_BadPlace(void)
|
||||
{
|
||||
if (m_bEnableEnemy) {
|
||||
UpdateEnemy(200);
|
||||
}
|
||||
|
||||
m_pszDebugState = "";
|
||||
NoPoint();
|
||||
|
||||
if (!PathExists() || PathComplete() || !m_iBadPlaceIndex) {
|
||||
m_iBadPlaceIndex = 0;
|
||||
if (!m_Enemy || (m_Enemy->flags & FL_NOTARGET)) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
} else {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Enemy) {
|
||||
m_pszDebugState = "badplace_shoot";
|
||||
FaceEnemyOrMotion(m_iStateTime);
|
||||
Anim_RunAwayFiring(ANIM_MODE_PATH);
|
||||
} else {
|
||||
m_pszDebugState = "badplace_run";
|
||||
FaceMotion();
|
||||
Anim_RunToInOpen(ANIM_MODE_PATH);
|
||||
}
|
||||
|
||||
PostThink(false);
|
||||
}
|
||||
+322
-295
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -25,366 +25,393 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "actor.h"
|
||||
#include "scriptexception.h"
|
||||
|
||||
void Actor::InitBalconyIdle
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitBalconyIdle(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_Idle;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->Pain = &Actor::Pain_Balcony;
|
||||
func->Killed = &Actor::Killed_Balcony;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
func->ThinkState = &Actor::Think_Idle;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->Pain = &Actor::Pain_Balcony;
|
||||
func->Killed = &Actor::Killed_Balcony;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
}
|
||||
|
||||
void Actor::InitBalconyCurious
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitBalconyCurious(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_Curious;
|
||||
func->BeginState = &Actor::Begin_Curious;
|
||||
func->EndState = &Actor::End_Curious;
|
||||
func->ResumeState = &Actor::Resume_Curious;
|
||||
func->SuspendState = &Actor::Suspend_Curious;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Curious;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
|
||||
func->IsState = &Actor::IsCuriousState;
|
||||
func->Pain = &Actor::Pain_Balcony;
|
||||
func->Killed = &Actor::Killed_Balcony;
|
||||
func->ThinkState = &Actor::Think_Curious;
|
||||
func->BeginState = &Actor::Begin_Curious;
|
||||
func->EndState = &Actor::End_Curious;
|
||||
func->ResumeState = &Actor::Resume_Curious;
|
||||
func->SuspendState = &Actor::Suspend_Curious;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Curious;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
|
||||
func->IsState = &Actor::IsCuriousState;
|
||||
func->Pain = &Actor::Pain_Balcony;
|
||||
func->Killed = &Actor::Killed_Balcony;
|
||||
}
|
||||
|
||||
void Actor::InitBalconyAttack
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitBalconyAttack(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_BalconyAttack;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack;
|
||||
func->BeginState = &Actor::Begin_BalconyAttack;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_BalconyAttack;
|
||||
func->Pain = &Actor::Pain_Balcony;
|
||||
func->Killed = &Actor::Killed_Balcony;
|
||||
func->IsState = &Actor::IsAttackState;
|
||||
func->PostShoot = &Actor::State_Balcony_PostShoot;
|
||||
func->ThinkState = &Actor::Think_BalconyAttack;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack;
|
||||
func->BeginState = &Actor::Begin_BalconyAttack;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_BalconyAttack;
|
||||
func->Pain = &Actor::Pain_Balcony;
|
||||
func->Killed = &Actor::Killed_Balcony;
|
||||
func->IsState = &Actor::IsAttackState;
|
||||
func->PostShoot = &Actor::State_Balcony_PostShoot;
|
||||
}
|
||||
|
||||
void Actor::InitBalconyDisguise
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitBalconyDisguise(GlobalFuncs_t *func)
|
||||
{
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
}
|
||||
|
||||
void Actor::InitBalconyGrenade
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitBalconyGrenade(GlobalFuncs_t *func)
|
||||
{
|
||||
func->IsState = &Actor::IsGrenadeState;
|
||||
func->IsState = &Actor::IsGrenadeState;
|
||||
}
|
||||
|
||||
void Actor::InitBalconyPain
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitBalconyPain(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_Pain;
|
||||
func->ThinkState = &Actor::Think_Pain;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Pain;
|
||||
func->Pain = &Actor::Pain_Balcony;
|
||||
func->Killed = &Actor::Killed_Balcony;
|
||||
func->IsState = &Actor::IsPainState;
|
||||
func->BeginState = &Actor::Begin_Pain;
|
||||
func->ThinkState = &Actor::Think_Pain;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Pain;
|
||||
func->Pain = &Actor::Pain_Balcony;
|
||||
func->Killed = &Actor::Killed_Balcony;
|
||||
func->IsState = &Actor::IsPainState;
|
||||
}
|
||||
|
||||
void Actor::InitBalconyKilled
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitBalconyKilled(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_BalconyKilled;
|
||||
func->EndState = &Actor::End_BalconyKilled;
|
||||
func->ThinkState = &Actor::Think_BalconyKilled;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_BalconyKilled;
|
||||
func->IsState = &Actor::IsKilledState;
|
||||
func->BeginState = &Actor::Begin_BalconyKilled;
|
||||
func->EndState = &Actor::End_BalconyKilled;
|
||||
func->ThinkState = &Actor::Think_BalconyKilled;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_BalconyKilled;
|
||||
func->IsState = &Actor::IsKilledState;
|
||||
}
|
||||
|
||||
void Actor::Pain_Balcony
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void Actor::Pain_Balcony(Event *ev)
|
||||
{
|
||||
SetThink( THINKSTATE_PAIN, THINK_BALCONY_PAIN);
|
||||
HandlePain( ev );
|
||||
SetThink(THINKSTATE_PAIN, THINK_BALCONY_PAIN);
|
||||
HandlePain(ev);
|
||||
}
|
||||
|
||||
void Actor::Killed_Balcony
|
||||
(
|
||||
Event *ev,
|
||||
bool bPlayDeathAnim
|
||||
)
|
||||
void Actor::Killed_Balcony(Event *ev, bool bPlayDeathAnim)
|
||||
{
|
||||
ClearStates();
|
||||
SetThink( THINKSTATE_KILLED, THINK_BALCONY_KILLED);
|
||||
HandleKilled( ev, true );
|
||||
ClearStates();
|
||||
SetThink(THINKSTATE_KILLED, THINK_BALCONY_KILLED);
|
||||
HandleKilled(ev, true);
|
||||
|
||||
if( !bPlayDeathAnim )
|
||||
ScriptError( "cannot do 'bedead' on balcony guys" );
|
||||
if (!bPlayDeathAnim) {
|
||||
ScriptError("cannot do 'bedead' on balcony guys");
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::Begin_BalconyAttack
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_BalconyAttack(void)
|
||||
{
|
||||
TransitionState(200, 0);
|
||||
TransitionState(ACTOR_STATE_BALCONY_ATTACK_FIND_ENEMY, 0);
|
||||
}
|
||||
|
||||
void Actor::State_Balcony_PostShoot
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Balcony_PostShoot(void)
|
||||
{
|
||||
if( m_Enemy )
|
||||
{
|
||||
TransitionState(201, 0);
|
||||
}
|
||||
if (m_Enemy) {
|
||||
TransitionState(ACTOR_STATE_BALCONY_ATTACK_TARGET, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Balcony_FindEnemy
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Balcony_FindEnemy(void)
|
||||
{
|
||||
m_bHasDesiredLookAngles = false;
|
||||
Anim_Aim();
|
||||
m_bHasDesiredLookAngles = false;
|
||||
Anim_Aim();
|
||||
|
||||
if( CanSeeEnemy( 200 ) )
|
||||
{
|
||||
TransitionState(201, 0);
|
||||
}
|
||||
if (CanSeeEnemy(200)) {
|
||||
TransitionState(ACTOR_STATE_BALCONY_ATTACK_TARGET, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Balcony_Target
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Balcony_Target(void)
|
||||
{
|
||||
Anim_Aim();
|
||||
AimAtTargetPos();
|
||||
Anim_Aim();
|
||||
AimAtTargetPos();
|
||||
|
||||
if( level.inttime > m_iStateTime + 1000 )
|
||||
{
|
||||
if( CanSeeEnemy( 0 ) && CanShootEnemy( 0 ) )
|
||||
{
|
||||
TransitionState(202, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearPath();
|
||||
TransitionState(200, 0);
|
||||
}
|
||||
}
|
||||
if (level.inttime > m_iStateTime + 1000) {
|
||||
if (CanSeeEnemy(0) && CanShootEnemy(0)) {
|
||||
TransitionState(ACTOR_STATE_BALCONY_ATTACK_SHOOT, 0);
|
||||
} else {
|
||||
ClearPath();
|
||||
TransitionState(ACTOR_STATE_BALCONY_ATTACK_FIND_ENEMY, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Balcony_Shoot
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Balcony_Shoot(void)
|
||||
{
|
||||
Anim_Shoot();
|
||||
AimAtTargetPos();
|
||||
Anim_Shoot();
|
||||
AimAtTargetPos();
|
||||
}
|
||||
|
||||
void Actor::Think_BalconyAttack
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_BalconyAttack(void)
|
||||
{
|
||||
if( !RequireThink() )
|
||||
return;
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
UpdateEnemy( 500 );
|
||||
UpdateEyeOrigin();
|
||||
UpdateEnemy(500);
|
||||
|
||||
if( !m_Enemy )
|
||||
{
|
||||
SetThinkState( THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
IdleThink();
|
||||
return;
|
||||
}
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
IdleThink();
|
||||
return;
|
||||
}
|
||||
|
||||
NoPoint();
|
||||
NoPoint();
|
||||
|
||||
if( m_State == 201 )
|
||||
{
|
||||
m_pszDebugState = "target";
|
||||
State_Balcony_Target();
|
||||
}
|
||||
else if( m_State == 202 )
|
||||
{
|
||||
m_pszDebugState = "shoot";
|
||||
State_Balcony_Shoot();
|
||||
}
|
||||
else if( m_State == 200 )
|
||||
{
|
||||
m_pszDebugState = "findenemy";
|
||||
State_Balcony_FindEnemy();
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf( "Actor::Think_BalconyAttack: invalid think state %i\n", m_State );
|
||||
assert( 0 );
|
||||
}
|
||||
switch (m_State) {
|
||||
case ACTOR_STATE_BALCONY_ATTACK_TARGET:
|
||||
m_pszDebugState = "target";
|
||||
State_Balcony_Target();
|
||||
break;
|
||||
case ACTOR_STATE_BALCONY_ATTACK_SHOOT:
|
||||
m_pszDebugState = "shoot";
|
||||
State_Balcony_Shoot();
|
||||
break;
|
||||
case ACTOR_STATE_BALCONY_ATTACK_FIND_ENEMY:
|
||||
m_pszDebugState = "findenemy";
|
||||
State_Balcony_FindEnemy();
|
||||
break;
|
||||
default:
|
||||
Com_Printf("Actor::Think_BalconyAttack: invalid think state %i\n", m_State);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
PostThink( true );
|
||||
PostThink(true);
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_BalconyAttack
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::FinishedAnimation_BalconyAttack(void)
|
||||
{
|
||||
if( m_State == 202 )
|
||||
State_Balcony_PostShoot();
|
||||
if (m_State == ACTOR_STATE_BALCONY_ATTACK_SHOOT) {
|
||||
State_Balcony_PostShoot();
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::Begin_BalconyKilled
|
||||
(
|
||||
void
|
||||
)
|
||||
bool Actor::CalcFallPath(void)
|
||||
{
|
||||
ClearPath();
|
||||
ResetBoneControllers();
|
||||
mmove_t mm;
|
||||
int currentPos = 0;
|
||||
int loop;
|
||||
vec3_t pos[200];
|
||||
float startDeltaTime;
|
||||
float nextTime;
|
||||
vec3_t vRelDelta;
|
||||
vec3_t vAbsDelta;
|
||||
float animTime;
|
||||
int anim;
|
||||
int i;
|
||||
float startTime;
|
||||
|
||||
PostEvent( EV_Actor_DeathEmbalm, 0.05f );
|
||||
SetMoveInfo(&mm);
|
||||
|
||||
if( CalcFallPath() )
|
||||
TransitionState(800, 0);
|
||||
else
|
||||
TransitionState(806, 0);
|
||||
mm.tracemask &= ~(CONTENTS_BODY | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX);
|
||||
mm.desired_speed = 80;
|
||||
VectorCopy2D(orientation[0], mm.desired_dir);
|
||||
|
||||
anim = gi.Anim_NumForName(edict->tiki, "death_balcony_intro");
|
||||
animTime = gi.Anim_Time(edict->tiki, anim);
|
||||
startTime = 0.65f;
|
||||
|
||||
for (;;) {
|
||||
MmoveSingle(&mm);
|
||||
VectorCopy(mm.origin, pos[currentPos]);
|
||||
|
||||
currentPos++;
|
||||
if (currentPos >= ARRAY_LEN(pos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mm.hit_obstacle) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mm.groundPlane) {
|
||||
return false;
|
||||
}
|
||||
|
||||
startTime -= level.frametime;
|
||||
if (startTime < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (startDeltaTime = 0.65f; startDeltaTime < animTime; startDeltaTime = nextTime) {
|
||||
nextTime = startDeltaTime + level.frametime;
|
||||
if (nextTime >= animTime - 0.01f) {
|
||||
nextTime = animTime;
|
||||
}
|
||||
|
||||
gi.Anim_DeltaOverTime(edict->tiki, anim, startDeltaTime, nextTime, vRelDelta);
|
||||
MatrixTransformVector(vRelDelta, orientation, vAbsDelta);
|
||||
|
||||
VectorAdd(mm.origin, vAbsDelta, mm.origin);
|
||||
VectorCopy(mm.origin, pos[currentPos]);
|
||||
|
||||
currentPos++;
|
||||
if (currentPos >= ARRAY_LEN(pos)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
loop = currentPos;
|
||||
|
||||
mm.desired_speed = 0;
|
||||
mm.groundPlane = NULL;
|
||||
mm.walking = false;
|
||||
VectorSet(mm.velocity, 0, 0, -171);
|
||||
|
||||
do {
|
||||
MmoveSingle(&mm);
|
||||
VectorCopy(mm.origin, pos[currentPos]);
|
||||
|
||||
currentPos++;
|
||||
if (currentPos >= ARRAY_LEN(pos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mm.hit_obstacle) {
|
||||
return false;
|
||||
}
|
||||
} while (!mm.groundPlane);
|
||||
|
||||
if (origin[2] - pos[currentPos - 1][2] < m_fBalconyHeight) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pFallPath = (FallPath*)gi.Malloc(sizeof(FallPath) + sizeof(FallPath::pos) * (currentPos - 1));
|
||||
m_pFallPath->length = currentPos;
|
||||
m_pFallPath->currentPos = 0;
|
||||
m_pFallPath->startTime = startTime;
|
||||
m_pFallPath->loop = loop;
|
||||
|
||||
for (i = 0; i < currentPos; i++) {
|
||||
VectorCopy(pos[i], m_pFallPath->pos[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Actor::End_BalconyKilled
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_BalconyKilled(void)
|
||||
{
|
||||
if( m_pFallPath )
|
||||
{
|
||||
gi.Free(m_pFallPath);
|
||||
m_pFallPath = NULL;
|
||||
}
|
||||
ClearPath();
|
||||
ResetBoneControllers();
|
||||
|
||||
PostEvent(EV_Actor_DeathEmbalm, 0.05f);
|
||||
|
||||
if (CalcFallPath()) {
|
||||
TransitionState(ACTOR_STATE_BALCONY_KILLED_BEGIN, 0);
|
||||
} else {
|
||||
TransitionState(ACTOR_STATE_BALCONY_KILLED_NORMAL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::Think_BalconyKilled
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_BalconyKilled(void)
|
||||
{
|
||||
int animnum;
|
||||
|
||||
Unregister( STRING_ANIMDONE );
|
||||
|
||||
if( m_State == 805 )
|
||||
{
|
||||
m_pszDebugState = "end";
|
||||
}
|
||||
else
|
||||
{
|
||||
NoPoint();
|
||||
m_bHasDesiredLookAngles = false;
|
||||
StopTurning();
|
||||
|
||||
switch( m_State )
|
||||
{
|
||||
case 800:
|
||||
m_bNextForceStart = true;
|
||||
m_eNextAnimMode = 7;
|
||||
m_pszDebugState = "begin";
|
||||
m_csNextAnimString = STRING_ANIM_NO_KILLED_SCR;
|
||||
|
||||
animnum = gi.Anim_NumForName(edict->tiki, "death_balcony_intro");
|
||||
|
||||
ChangeMotionAnim();
|
||||
|
||||
m_bMotionAnimSet = true;
|
||||
m_iMotionSlot = GetMotionSlot(0);
|
||||
m_weightType[m_iMotionSlot] = 1;
|
||||
m_weightCrossBlend[m_iMotionSlot] = 0.0;
|
||||
m_weightBase[m_iMotionSlot] = 1.0;
|
||||
|
||||
NewAnim( animnum, m_iMotionSlot );
|
||||
SetTime( m_iMotionSlot, m_pFallPath->startTime );
|
||||
UpdateNormalAnimSlot( m_iMotionSlot );
|
||||
TransitionState(801, 0);
|
||||
break;
|
||||
case 801:
|
||||
m_bNextForceStart = false;
|
||||
m_pszDebugState = "intro";
|
||||
m_eNextAnimMode = 7;
|
||||
m_csNextAnimString = STRING_ANIM_NO_KILLED_SCR;
|
||||
break;
|
||||
case 802:
|
||||
m_pszDebugState = "loop";
|
||||
Anim_FullBody( STRING_DEATH_BALCONY_LOOP, 7 );
|
||||
break;
|
||||
case 803:
|
||||
TransitionState(804, 0);
|
||||
StopAllAnimating();
|
||||
case 804:
|
||||
m_pszDebugState = "outtro";
|
||||
Anim_FullBody( STRING_DEATH_BALCONY_OUTTRO, 1 );
|
||||
break;
|
||||
case 806:
|
||||
m_pszDebugState = "normal";
|
||||
Anim_Killed();
|
||||
break;
|
||||
default:
|
||||
Com_Printf( "Actor::Think_BalconyKilled: invalid think state %i\n", m_State );
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
PostThink( false );
|
||||
|
||||
if( m_State >= 800 )
|
||||
{
|
||||
if( m_State == 801 )
|
||||
{
|
||||
if( m_pFallPath->currentPos >= m_pFallPath->length )
|
||||
{
|
||||
TransitionState(803, 0);
|
||||
}
|
||||
else if (m_pFallPath->currentPos >= m_pFallPath->loop)
|
||||
{
|
||||
TransitionState(802, 0);
|
||||
}
|
||||
}
|
||||
else if( m_State == 802 )
|
||||
{
|
||||
if (m_pFallPath->currentPos >= m_pFallPath->length)
|
||||
{
|
||||
TransitionState(803, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_pFallPath) {
|
||||
gi.Free(m_pFallPath);
|
||||
m_pFallPath = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_BalconyKilled
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_BalconyKilled(void)
|
||||
{
|
||||
if( m_State == 804 || m_State == 806 )
|
||||
{
|
||||
BecomeCorpse();
|
||||
TransitionState(805, 0);
|
||||
}
|
||||
else if( m_State == 801 )
|
||||
{
|
||||
TransitionState(802, 0);
|
||||
StopAllAnimating();
|
||||
}
|
||||
int animnum;
|
||||
|
||||
Unregister(STRING_ANIMDONE);
|
||||
|
||||
if (m_State == ACTOR_STATE_BALCONY_KILLED_END) {
|
||||
m_pszDebugState = "";
|
||||
return;
|
||||
}
|
||||
|
||||
NoPoint();
|
||||
ForwardLook();
|
||||
|
||||
switch (m_State) {
|
||||
case ACTOR_STATE_BALCONY_KILLED_BEGIN:
|
||||
m_bNextForceStart = true;
|
||||
m_eNextAnimMode = ANIM_MODE_FALLING_PATH;
|
||||
m_pszDebugState = "begin";
|
||||
m_csNextAnimString = STRING_ANIM_NO_KILLED_SCR;
|
||||
|
||||
animnum = gi.Anim_NumForName(edict->tiki, "death_balcony_intro");
|
||||
|
||||
ChangeMotionAnim();
|
||||
|
||||
m_bMotionAnimSet = true;
|
||||
m_iMotionSlot = GetMotionSlot(0);
|
||||
m_weightType[m_iMotionSlot] = ANIM_WEIGHT_MOTION;
|
||||
m_weightCrossBlend[m_iMotionSlot] = 0.0;
|
||||
m_weightBase[m_iMotionSlot] = 1.0;
|
||||
|
||||
NewAnim(animnum, m_iMotionSlot);
|
||||
SetTime(m_iMotionSlot, m_pFallPath->startTime);
|
||||
UpdateNormalAnimSlot(m_iMotionSlot);
|
||||
TransitionState(ACTOR_STATE_BALCONY_KILLED_INTRO, 0);
|
||||
break;
|
||||
case ACTOR_STATE_BALCONY_KILLED_INTRO:
|
||||
m_bNextForceStart = false;
|
||||
m_pszDebugState = "intro";
|
||||
m_eNextAnimMode = ANIM_MODE_FALLING_PATH;
|
||||
m_csNextAnimString = STRING_ANIM_NO_KILLED_SCR;
|
||||
break;
|
||||
case ACTOR_STATE_BALCONY_KILLED_LOOP:
|
||||
m_pszDebugState = "loop";
|
||||
Anim_FullBody(STRING_DEATH_BALCONY_LOOP, 7);
|
||||
break;
|
||||
case ACTOR_STATE_BALCONY_KILLED_LOOP_END:
|
||||
TransitionState(804, 0);
|
||||
StopAllAnimating();
|
||||
case ACTOR_STATE_BALCONY_KILLED_OUTTRO:
|
||||
m_pszDebugState = "outtro";
|
||||
Anim_FullBody(STRING_DEATH_BALCONY_OUTTRO, 1);
|
||||
break;
|
||||
case ACTOR_STATE_BALCONY_KILLED_NORMAL:
|
||||
m_pszDebugState = "normal";
|
||||
Anim_Killed();
|
||||
break;
|
||||
default:
|
||||
Com_Printf("Actor::Think_BalconyKilled: invalid think state %i\n", m_State);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
PostThink(false);
|
||||
|
||||
if (m_State >= ACTOR_STATE_BALCONY_KILLED_BEGIN) {
|
||||
if (m_State == ACTOR_STATE_BALCONY_KILLED_INTRO) {
|
||||
if (m_pFallPath->currentPos >= m_pFallPath->length) {
|
||||
TransitionState(ACTOR_STATE_BALCONY_KILLED_LOOP_END, 0);
|
||||
}
|
||||
else if (m_pFallPath->currentPos >= m_pFallPath->loop) {
|
||||
TransitionState(ACTOR_STATE_BALCONY_KILLED_LOOP, 0);
|
||||
}
|
||||
} else if (m_State == ACTOR_STATE_BALCONY_KILLED_LOOP) {
|
||||
if (m_pFallPath->currentPos >= m_pFallPath->length) {
|
||||
TransitionState(ACTOR_STATE_BALCONY_KILLED_LOOP_END, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_BalconyKilled(void)
|
||||
{
|
||||
switch (m_State) {
|
||||
case ACTOR_STATE_BALCONY_KILLED_OUTTRO:
|
||||
case ACTOR_STATE_BALCONY_KILLED_NORMAL:
|
||||
BecomeCorpse();
|
||||
TransitionState(ACTOR_STATE_BALCONY_KILLED_END, 0);
|
||||
break;
|
||||
case ACTOR_STATE_BALCONY_KILLED_INTRO:
|
||||
TransitionState(ACTOR_STATE_BALCONY_KILLED_LOOP, 0);
|
||||
StopAllAnimating();
|
||||
break;
|
||||
}
|
||||
}
|
||||
+621
-827
File diff suppressed because it is too large.
Load diff
+219
-450
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,485 +24,254 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitCurious
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitCurious(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_Curious;
|
||||
func->BeginState = &Actor::Begin_Curious;
|
||||
func->EndState = &Actor::End_Curious;
|
||||
func->ResumeState = &Actor::Resume_Curious;
|
||||
func->SuspendState = &Actor::Suspend_Curious;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Cover;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
|
||||
func->IsState = &Actor::IsCuriousState;
|
||||
func->ThinkState = &Actor::Think_Curious;
|
||||
func->BeginState = &Actor::Begin_Curious;
|
||||
func->EndState = &Actor::End_Curious;
|
||||
func->ResumeState = &Actor::Resume_Curious;
|
||||
func->SuspendState = &Actor::Suspend_Curious;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Cover;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
|
||||
func->IsState = &Actor::IsCuriousState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Curious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::SetCuriousAnimHint(int iAnimHint)
|
||||
{
|
||||
Vector vDelta;
|
||||
//float fDistSquared;
|
||||
|
||||
DoForceActivate();
|
||||
m_csMood = STRING_CURIOUS;
|
||||
Anim_Emotion(EMOTION_CURIOUS);
|
||||
|
||||
if (level.inttime > level.m_iCuriousVoiceTime + 3000)
|
||||
{
|
||||
if (m_iCuriousAnimHint == 5)
|
||||
{
|
||||
Anim_Say(
|
||||
STRING_ANIM_SAY_CURIOUS_SOUND_SCR,
|
||||
8000,
|
||||
false);
|
||||
level.m_iCuriousVoiceTime = level.inttime;
|
||||
}
|
||||
else if (m_iCuriousAnimHint == 6)
|
||||
{
|
||||
Anim_Say(
|
||||
STRING_ANIM_SAY_CURIOUS_SIGHT_SCR,
|
||||
8000,
|
||||
false);
|
||||
level.m_iCuriousVoiceTime = level.inttime;
|
||||
}
|
||||
}
|
||||
|
||||
m_iCuriousTime = level.inttime;
|
||||
|
||||
SetLeashHome(origin);
|
||||
if (m_bScriptGoalValid)
|
||||
{
|
||||
SetPath(
|
||||
m_vScriptGoal,
|
||||
"",
|
||||
0,
|
||||
NULL,
|
||||
0.0);
|
||||
ShortenPathToAvoidSquadMates();
|
||||
if (!PathExists())
|
||||
{
|
||||
m_bScriptGoalValid = false;
|
||||
}
|
||||
}
|
||||
TransitionState(1100, 0);
|
||||
|
||||
if (!m_bScriptGoalValid)
|
||||
{
|
||||
//check if last enemy pos is within leash area (distance to m_vHome is <= m_fLeash)
|
||||
vDelta = m_vLastEnemyPos - m_vHome;
|
||||
if (vDelta.lengthSquared() <= m_fLeashSquared)
|
||||
{
|
||||
//it's within leash area, go check it.
|
||||
SetPath(m_vLastEnemyPos, NULL, 0, NULL, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//it's NOT within leash area,
|
||||
|
||||
//am I within leash area ?
|
||||
if ((origin - m_vHome).lengthSquared() <= m_fLeashSquared)
|
||||
{
|
||||
//I'm inside leash area,
|
||||
//Try to go towards enemy as much as possible without leaving leash area.
|
||||
//vDest = vHome + U * leash
|
||||
//U = unit vector of vDelta.
|
||||
SetPath(vDelta * sqrt(m_fLeashSquared / vDelta.lengthSquared()) + m_vHome, NULL, 0, NULL, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//I'm outside leash area,
|
||||
//go to enemy, it doesn't matter.
|
||||
SetPath(m_vLastEnemyPos, NULL, 0, NULL, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
ShortenPathToAvoidSquadMates();
|
||||
if (m_iCuriousAnimHint <= 3)
|
||||
{
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_STANDFLINCH_SCR;
|
||||
|
||||
m_bNextForceStart = true;
|
||||
m_bLockThinkState = true;
|
||||
TransitionState(1101, 0);
|
||||
}
|
||||
else if(m_Enemy && m_PotentialEnemies.GetCurrentVisibility() < 0.1)
|
||||
{
|
||||
vec2_t vDel;
|
||||
VectorSub2D(m_vLastEnemyPos, origin, vDel);
|
||||
if (vDel[0] != 0 || vDel[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(vDel);
|
||||
}
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_SURPRISE_SCR;
|
||||
|
||||
m_bNextForceStart = true;
|
||||
m_bLockThinkState = true;
|
||||
TransitionState(1101, 0);
|
||||
}
|
||||
}
|
||||
|
||||
m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF);
|
||||
m_iCuriousAnimHint = iAnimHint;
|
||||
}
|
||||
|
||||
|
||||
void Actor::End_Curious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Curious(void)
|
||||
{
|
||||
m_iCuriousTime = 0;
|
||||
m_iCuriousLevel = 0;
|
||||
float fDistSquared;
|
||||
Vector vDelta;
|
||||
|
||||
DoForceActivate();
|
||||
m_csMood = STRING_CURIOUS;
|
||||
Anim_Emotion(EMOTION_CURIOUS);
|
||||
|
||||
if (level.inttime > level.m_iCuriousVoiceTime + 3000) {
|
||||
if (m_iCuriousAnimHint == 5) {
|
||||
Anim_Say(STRING_ANIM_SAY_CURIOUS_SOUND_SCR, 8000, false);
|
||||
level.m_iCuriousVoiceTime = level.inttime;
|
||||
} else if (m_iCuriousAnimHint == 6) {
|
||||
Anim_Say(STRING_ANIM_SAY_CURIOUS_SIGHT_SCR, 8000, false);
|
||||
level.m_iCuriousVoiceTime = level.inttime;
|
||||
}
|
||||
}
|
||||
|
||||
m_iCuriousTime = level.inttime;
|
||||
|
||||
SetLeashHome(origin);
|
||||
if (m_bScriptGoalValid) {
|
||||
SetPath(m_vScriptGoal, NULL, 0, NULL, 0.0);
|
||||
ShortenPathToAvoidSquadMates();
|
||||
if (!PathExists()) {
|
||||
m_bScriptGoalValid = false;
|
||||
}
|
||||
}
|
||||
TransitionState(ACTOR_STATE_CURIOUS_BEGIN, 0);
|
||||
|
||||
if (!m_bScriptGoalValid) {
|
||||
//check if last enemy pos is within leash area (distance to m_vHome is <= m_fLeash)
|
||||
vDelta = m_vLastEnemyPos - m_vHome;
|
||||
fDistSquared = vDelta.lengthSquared();
|
||||
|
||||
if (fDistSquared > m_fLeashSquared && (origin - m_vHome).lengthSquared() <= m_fLeashSquared) {
|
||||
//I'm inside leash area,
|
||||
//Try to go towards enemy as much as possible without leaving leash area.
|
||||
//vDest = vHome + U * leash
|
||||
//U = unit vector of vDelta.
|
||||
SetPath(m_vHome + sqrt(m_fLeashSquared / fDistSquared) * vDelta, NULL, 0, NULL, 0);
|
||||
ShortenPathToAvoidSquadMates();
|
||||
} else {
|
||||
//I'm outside leash area,
|
||||
//go to enemy, it doesn't matter.
|
||||
SetPath(m_vLastEnemyPos, NULL, 0, NULL, 0);
|
||||
ShortenPathToAvoidSquadMates();
|
||||
}
|
||||
|
||||
if (m_iCuriousAnimHint <= 3 && m_iCuriousAnimHint >= 1) {
|
||||
StartAnimation(ANIM_MODE_NORMAL, STRING_ANIM_STANDFLINCH_SCR);
|
||||
TransitionState(ACTOR_STATE_CURIOUS_RUNNING);
|
||||
m_bLockThinkState = true;
|
||||
} else if (m_Enemy && m_PotentialEnemies.GetCurrentVisibility() < 0.1) {
|
||||
SetDesiredYawDest(m_vLastEnemyPos);
|
||||
StartAnimation(ANIM_MODE_NORMAL, STRING_ANIM_SURPRISE_SCR);
|
||||
TransitionState(ACTOR_STATE_CURIOUS_RUNNING);
|
||||
m_bLockThinkState = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF);
|
||||
}
|
||||
|
||||
void Actor::Resume_Curious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_Curious(void)
|
||||
{
|
||||
Begin_Curious();
|
||||
m_iCuriousTime = 0;
|
||||
m_iCuriousLevel = 0;
|
||||
}
|
||||
|
||||
void Actor::Suspend_Curious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Resume_Curious(void)
|
||||
{
|
||||
End_Curious();
|
||||
Begin_Curious();
|
||||
}
|
||||
|
||||
void Actor::Think_Curious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Suspend_Curious(void)
|
||||
{
|
||||
//horrible function!
|
||||
if (RequireThink())
|
||||
{
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
UpdateEnemy(100);
|
||||
|
||||
if(m_State == 1101)
|
||||
{
|
||||
ContinueAnimation();
|
||||
//LABEL_16:
|
||||
CheckForThinkStateTransition();
|
||||
glbs.Printf("Think_Curious CheckForThinkStateTransition 1\n");
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_bLockThinkState = false;
|
||||
|
||||
if (!PathExists() || PathComplete())
|
||||
{
|
||||
//v1 = &this->baseSimpleActor.baseSentient.m_Enemy;
|
||||
//goto LABEL_6;
|
||||
|
||||
ClearPath();
|
||||
Anim_Stand();
|
||||
LookAtCuriosity();
|
||||
|
||||
if (!m_Enemy || EnemyIsDisguised())
|
||||
{
|
||||
if (level.inttime > m_iCuriousTime + 500)
|
||||
{
|
||||
glbs.Printf("Think_Curious m_Enemy: %s EnemyIsDisguised: %s\n", m_Enemy ? "true": "false", EnemyIsDisguised() ? "true" : "false");
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
m_iCuriousTime = 0;
|
||||
}
|
||||
}
|
||||
CheckForThinkStateTransition();
|
||||
glbs.Printf("Think_Curious CheckForThinkStateTransition 2\n");
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_Enemy || CanSeeEnemy(100))
|
||||
{
|
||||
ClearPath();
|
||||
Anim_Stand();
|
||||
LookAtCuriosity();
|
||||
if (!m_Enemy || EnemyIsDisguised())
|
||||
{
|
||||
if (level.inttime > m_iCuriousTime + 500)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
m_iCuriousTime = 0;
|
||||
}
|
||||
}
|
||||
CheckForThinkStateTransition();
|
||||
glbs.Printf("Think_Curious CheckForThinkStateTransition 3\n");
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_iCuriousLevel <= 5)
|
||||
{
|
||||
if (!InFOV(m_vLastEnemyPos, m_fFov, m_fFovDot))
|
||||
{
|
||||
|
||||
if ((m_bScriptGoalValid || CanMovePathWithLeash())
|
||||
&& MoveOnPathWithSquad())
|
||||
{
|
||||
if (PatrolNextNodeExists())
|
||||
{
|
||||
m_eNextAnimMode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//v11 = SimpleActor::GetRunAnim(this);
|
||||
m_eNextAnimMode = 3;
|
||||
}
|
||||
m_csNextAnimString = GetRunAnim();
|
||||
m_bNextForceStart = false;
|
||||
|
||||
FaceMotion();
|
||||
}
|
||||
else
|
||||
{
|
||||
Anim_Stand();
|
||||
}
|
||||
|
||||
if (level.inttime >= m_iNextWatchStepTime
|
||||
&& velocity.lengthSquared() >= 4.0)
|
||||
{
|
||||
SetDesiredLookDir(velocity);
|
||||
|
||||
m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500;
|
||||
}
|
||||
else
|
||||
{
|
||||
LookAtCuriosity();
|
||||
}
|
||||
CheckForThinkStateTransition();
|
||||
glbs.Printf("Think_Curious CheckForThinkStateTransition 4\n");
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Vector vEnd = EyePosition() - m_vLastEnemyPos;
|
||||
VectorNormalizeFast(vEnd);
|
||||
|
||||
vEnd += m_vLastEnemyPos;
|
||||
if (!G_SightTrace(EyePosition(), vec_zero, vec_zero, vEnd, this, NULL, 33819417, qfalse, "Actor::Think_Curious"))
|
||||
{
|
||||
if ((m_bScriptGoalValid || CanMovePathWithLeash())
|
||||
&& MoveOnPathWithSquad())
|
||||
{
|
||||
if (PatrolNextNodeExists())
|
||||
{
|
||||
m_eNextAnimMode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//v11 = SimpleActor::GetRunAnim(this);
|
||||
m_eNextAnimMode = 3;
|
||||
}
|
||||
m_csNextAnimString = GetRunAnim();
|
||||
m_bNextForceStart = false;
|
||||
|
||||
FaceMotion();
|
||||
}
|
||||
else
|
||||
{
|
||||
Anim_Stand();
|
||||
}
|
||||
|
||||
if (level.inttime >= m_iNextWatchStepTime
|
||||
&& velocity.lengthSquared() >= 4.0)
|
||||
{
|
||||
SetDesiredLookDir(velocity);
|
||||
|
||||
m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500;
|
||||
}
|
||||
else
|
||||
{
|
||||
LookAtCuriosity();
|
||||
}
|
||||
CheckForThinkStateTransition();
|
||||
glbs.Printf("Think_Curious CheckForThinkStateTransition 5\n");
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
ClearPath();
|
||||
Anim_Stand();
|
||||
LookAtCuriosity();
|
||||
if (!m_Enemy || EnemyIsDisguised())
|
||||
{
|
||||
if (level.inttime > m_iCuriousTime + 500)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
m_iCuriousTime = 0;
|
||||
}
|
||||
}
|
||||
CheckForThinkStateTransition();
|
||||
glbs.Printf("Think_Curious CheckForThinkStateTransition 6\n");
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((PathGoal()-origin).lengthSquared() >= 2304)
|
||||
{
|
||||
if ((m_bScriptGoalValid || CanMovePathWithLeash())
|
||||
&& MoveOnPathWithSquad())
|
||||
{
|
||||
if (PatrolNextNodeExists())
|
||||
{
|
||||
m_eNextAnimMode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//v11 = SimpleActor::GetRunAnim(this);
|
||||
m_eNextAnimMode = 3;
|
||||
}
|
||||
m_csNextAnimString = GetRunAnim();
|
||||
m_bNextForceStart = false;
|
||||
|
||||
FaceMotion();
|
||||
}
|
||||
else
|
||||
{
|
||||
Anim_Stand();
|
||||
}
|
||||
|
||||
if (level.inttime >= m_iNextWatchStepTime
|
||||
&& velocity.lengthSquared() >= 4.0)
|
||||
{
|
||||
SetDesiredLookDir(velocity);
|
||||
|
||||
m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500;
|
||||
}
|
||||
else
|
||||
{
|
||||
LookAtCuriosity();
|
||||
}
|
||||
CheckForThinkStateTransition();
|
||||
glbs.Printf("Think_Curious CheckForThinkStateTransition 7\n");
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ClearPath();
|
||||
Anim_Stand();
|
||||
LookAtCuriosity();
|
||||
if (!m_Enemy || EnemyIsDisguised())
|
||||
{
|
||||
if (level.inttime > m_iCuriousTime + 500)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
m_iCuriousTime = 0;
|
||||
}
|
||||
}
|
||||
CheckForThinkStateTransition();
|
||||
glbs.Printf("Think_Curious CheckForThinkStateTransition 8\n");
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
End_Curious();
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_Curious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_Curious(void)
|
||||
{
|
||||
FinishedAnimation_AnimCurious();
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
UpdateEnemy(100);
|
||||
|
||||
if (m_State == ACTOR_STATE_CURIOUS_RUNNING) {
|
||||
ContinueAnimation();
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_bLockThinkState = false;
|
||||
|
||||
if (!PathExists() || PathComplete()) {
|
||||
ClearPath();
|
||||
Anim_Stand();
|
||||
LookAtCuriosity();
|
||||
TimeOutCurious();
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Enemy && CanSeeEnemy(100)) {
|
||||
ClearPath();
|
||||
Anim_Stand();
|
||||
LookAtCuriosity();
|
||||
TimeOutCurious();
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_iCuriousLevel <= 5) {
|
||||
if (InFOV(m_vLastEnemyPos, m_fFov, m_fFovDot)) {
|
||||
Vector vEnd;
|
||||
|
||||
vEnd = EyePosition() - m_vLastEnemyPos;
|
||||
vEnd.normalizefast();
|
||||
vEnd += m_vLastEnemyPos;
|
||||
|
||||
if (G_SightTrace(
|
||||
EyePosition(), vec_zero, vec_zero, vEnd, this, NULL, MASK_CANSEE, qfalse, "Actor::Think_Curious"
|
||||
)) {
|
||||
ClearPath();
|
||||
Anim_Stand();
|
||||
LookAtCuriosity();
|
||||
TimeOutCurious();
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ((PathGoal() - origin).lengthSquared() < Square(48)) {
|
||||
ClearPath();
|
||||
Anim_Stand();
|
||||
LookAtCuriosity();
|
||||
TimeOutCurious();
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m_bScriptGoalValid || CanMovePathWithLeash()) && MoveOnPathWithSquad()) {
|
||||
if (PatrolNextNodeExists()) {
|
||||
DesiredAnimation(ANIM_MODE_PATH, GetRunAnim());
|
||||
} else {
|
||||
DesiredAnimation(ANIM_MODE_PATH_GOAL, GetRunAnim());
|
||||
}
|
||||
|
||||
FaceMotion();
|
||||
} else {
|
||||
Anim_Stand();
|
||||
}
|
||||
|
||||
if (level.inttime >= m_iNextWatchStepTime && velocity.lengthSquared() >= Square(2)) {
|
||||
SetDesiredLookDir(velocity);
|
||||
m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500;
|
||||
} else {
|
||||
LookAtCuriosity();
|
||||
}
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(true);
|
||||
}
|
||||
|
||||
|
||||
void Actor::LookAtCuriosity
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::LookAtCuriosity(void)
|
||||
{
|
||||
Vector vAngles;
|
||||
float fLookScale;
|
||||
unsigned int iSeed;
|
||||
if (m_Enemy && EnemyIsDisguised())
|
||||
{
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
fLookScale = 0.25;
|
||||
}
|
||||
else
|
||||
{
|
||||
vAngles = m_vLastEnemyPos - origin;
|
||||
if (vAngles.x < 15.0 && vAngles.x > -15.0 && vAngles.y < 15.0 && vAngles.y > -15.0)
|
||||
{
|
||||
SetDesiredLookAnglesRelative(vec_zero);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDesiredLookDir(vAngles);
|
||||
if (velocity.x == 0.0
|
||||
&& velocity.y == 0.0)
|
||||
{
|
||||
SetDesiredYawDir(vAngles);
|
||||
}
|
||||
else
|
||||
{
|
||||
FaceMotion();
|
||||
}
|
||||
}
|
||||
fLookScale = 1;
|
||||
}
|
||||
|
||||
//FIXME: wth is this ! @_@
|
||||
iSeed = 1664525 * (-783751945 * ((level.inttime - m_iCuriousTime) & 0xFFFFFF00) + m_iCuriousTime);
|
||||
unsigned int iSeed;
|
||||
float fLookScale;
|
||||
vec3_t vAngles;
|
||||
|
||||
vAngles.x = fLookScale * ((1664525 * (iSeed + 1013904223) + 1013904223) * 0.000000013969839) + m_DesiredLookAngles[0];
|
||||
vAngles.y = (iSeed + 1013904223) * 0.000000027939677 * fLookScale + m_DesiredLookAngles[1];
|
||||
vAngles.z = m_DesiredLookAngles[2];
|
||||
if (m_Enemy && !EnemyIsDisguised()) {
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
fLookScale = 0.25;
|
||||
} else {
|
||||
Vector v;
|
||||
|
||||
if (vAngles.x >= -90.0)
|
||||
{
|
||||
if (vAngles.x > 90.0)
|
||||
vAngles.x = 90.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vAngles.x = -90.0;
|
||||
}
|
||||
v = m_vLastEnemyPos - origin;
|
||||
if (v[0] < 15 && v[0] > -15 && v[1] < 15 && v[1] > -15) {
|
||||
SetDesiredLookAnglesRelative(vec_zero);
|
||||
} else {
|
||||
SetDesiredLookDir(v);
|
||||
if (velocity.x || velocity.y) {
|
||||
FaceMotion();
|
||||
} else {
|
||||
SetDesiredYawDir(v);
|
||||
}
|
||||
}
|
||||
fLookScale = 1;
|
||||
}
|
||||
|
||||
SetDesiredLookAnglesRelative(vAngles);
|
||||
iSeed = 0x19660D * (m_iCuriousTime - 0x2EB71B09 * ((level.inttime - m_iCuriousTime) & 0xFFFFFF00)) + 0x3C6EF35F;
|
||||
|
||||
vAngles[0] = m_DesiredLookAngles[0] + (float)iSeed / 0x4444444 * fLookScale;
|
||||
vAngles[1] = m_DesiredLookAngles[1] + (float)iSeed / 0x2222222 * fLookScale;
|
||||
vAngles[2] = m_DesiredLookAngles[2];
|
||||
// clamp
|
||||
vAngles[0] = Q_clamp_float(vAngles[0], -90, 90);
|
||||
|
||||
SetDesiredLookAnglesRelative(vAngles);
|
||||
}
|
||||
|
||||
void Actor::TimeOutCurious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::TimeOutCurious(void)
|
||||
{
|
||||
//FIXME: macros
|
||||
if (!m_Enemy || EnemyIsDisguised())
|
||||
{
|
||||
if (level.inttime > m_iCuriousTime + 500)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
m_iCuriousTime = 0;
|
||||
}
|
||||
}
|
||||
if (m_Enemy && !EnemyIsDisguised()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (level.inttime <= m_iCuriousTime + 500) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
m_iCuriousTime = 0;
|
||||
}
|
||||
|
||||
void Actor::SetCuriousAnimHint
|
||||
(
|
||||
int iAnimHint
|
||||
)
|
||||
void Actor::FinishedAnimation_Curious(void)
|
||||
{
|
||||
m_iCuriousAnimHint = iAnimHint;
|
||||
if (m_State == ACTOR_STATE_CURIOUS_RUNNING) {
|
||||
TransitionState(ACTOR_STATE_CURIOUS_BEGIN, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,174 +24,115 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
|
||||
void Actor::InitDisguiseNone
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitDisguiseNone(GlobalFuncs_t *func)
|
||||
{
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
}
|
||||
|
||||
void Actor::State_Disguise_Wait
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Disguise_Wait(void)
|
||||
{
|
||||
vec2_t vDelta;
|
||||
float fDistSquared;
|
||||
VectorSub2D(origin, m_Enemy->origin, vDelta);
|
||||
float fDistSquared;
|
||||
vec2_t vDelta;
|
||||
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_WAIT_SCR;
|
||||
m_bNextForceStart = false;
|
||||
VectorSub2D(origin, m_Enemy->origin, vDelta);
|
||||
fDistSquared = VectorLength2DSquared(vDelta);
|
||||
|
||||
fDistSquared = VectorLength2DSquared(vDelta);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_WAIT_SCR);
|
||||
|
||||
if (m_fMaxDisguiseDistSquared > fDistSquared * 4)
|
||||
{
|
||||
TransitionState(1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (level.inttime > m_iStateTime + 3000)
|
||||
{
|
||||
if (fDistSquared <= 65536)
|
||||
{
|
||||
TransitionState(1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fDistSquared * 4 < m_fMaxDisguiseDistSquared) {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_PAPERS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (level.inttime <= m_iStateTime + 3000) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fDistSquared > Square(256)) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
} else {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_PAPERS);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Disguise_Papers
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Disguise_Papers(void)
|
||||
{
|
||||
vec2_t vDelta;
|
||||
vec2_t vDelta;
|
||||
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_PAPERS_SCR;
|
||||
m_eNextAnimMode = 1;
|
||||
m_bNextForceStart = false;
|
||||
if (m_iEnemyShowPapersTime < m_Enemy->m_ShowPapersTime)
|
||||
{
|
||||
if (level.m_iPapersLevel < m_iDisguiseLevel)
|
||||
{
|
||||
m_State = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_DisguiseAcceptThread.IsSet())
|
||||
m_DisguiseAcceptThread.Execute(this);
|
||||
TransitionState(2, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (level.inttime > m_iStateTime + 12000)
|
||||
{
|
||||
TransitionState(3, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSub2D(origin, m_Enemy->origin, vDelta);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_PAPERS_SCR);
|
||||
|
||||
if (VectorLength2DSquared(vDelta) > 65536)
|
||||
{
|
||||
TransitionState(4, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_iEnemyShowPapersTime >= m_Enemy->m_ShowPapersTime) {
|
||||
if (level.inttime > m_iStateTime + 12000) {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_ENEMY);
|
||||
} else {
|
||||
VectorSub2D(origin, m_Enemy->origin, vDelta);
|
||||
|
||||
if (VectorLength2DSquared(vDelta) > Square(256)) {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_HALT, 0);
|
||||
}
|
||||
}
|
||||
} else if (level.m_iPapersLevel < m_iDisguiseLevel) {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_DENY);
|
||||
} else {
|
||||
if (m_DisguiseAcceptThread.IsSet()) {
|
||||
m_DisguiseAcceptThread.Execute(this);
|
||||
}
|
||||
|
||||
TransitionState(ACTOR_STATE_DISGUISE_ACCEPT);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Disguise_Fake_Papers
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Disguise_Fake_Papers(void)
|
||||
{
|
||||
vec2_t vDelta;
|
||||
vec2_t vDelta;
|
||||
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_PAPERS_SCR;
|
||||
m_eNextAnimMode = 1;
|
||||
m_bNextForceStart = false;
|
||||
if (m_iEnemyShowPapersTime < m_Enemy->m_ShowPapersTime || level.inttime > m_iStateTime + 12000)
|
||||
{
|
||||
TransitionState(3, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSub2D(origin, m_Enemy->origin, vDelta);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_PAPERS_SCR);
|
||||
|
||||
if (VectorLength2DSquared(vDelta) > 65536)
|
||||
{
|
||||
TransitionState(4, 0);
|
||||
}
|
||||
}
|
||||
if (m_iEnemyShowPapersTime < m_Enemy->m_ShowPapersTime || level.inttime > m_iStateTime + 12000) {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_ENEMY);
|
||||
return;
|
||||
}
|
||||
|
||||
VectorSub2D(origin, m_Enemy->origin, vDelta);
|
||||
|
||||
if (VectorLength2DSquared(vDelta) > Square(256)) {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_HALT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Disguise_Enemy
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Disguise_Enemy(void)
|
||||
{
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_ENEMY_SCR;
|
||||
m_bNextForceStart = false;
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_ENEMY_SCR);
|
||||
|
||||
if (level.inttime > m_iStateTime + 3000 && !m_Enemy->IsSubclassOfActor())
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
}
|
||||
if (level.inttime > m_iStateTime + 3000 && !(m_Enemy->flags & FL_NOTARGET)) {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Disguise_Halt
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Disguise_Halt(void)
|
||||
{
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_HALT_SCR;
|
||||
m_bNextForceStart = false;
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_HALT_SCR);
|
||||
|
||||
if (level.inttime > m_iStateTime + 1500 && !m_Enemy->IsSubclassOfActor())
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
}
|
||||
if (level.inttime > m_iStateTime + 1500 && !(m_Enemy->flags & FL_NOTARGET)) {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Disguise_Accept
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Disguise_Accept(void)
|
||||
{
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_ACCEPT_SCR;
|
||||
m_bNextForceStart = false;
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_ACCEPT_SCR);
|
||||
|
||||
if (level.inttime > m_iStateTime + 3000 )
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
SetThink(THINKSTATE_DISGUISE, THINK_DISGUISE_SALUTE);
|
||||
}
|
||||
if (level.inttime > m_iStateTime + 3000) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
SetThink(THINKSTATE_DISGUISE, THINK_DISGUISE_SALUTE);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Disguise_Deny
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Disguise_Deny(void)
|
||||
{
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_DENY_SCR;
|
||||
m_bNextForceStart = false;
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_DENY_SCR);
|
||||
|
||||
if (level.inttime > m_iStateTime + 3000)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
}
|
||||
if (level.inttime > m_iStateTime + 3000) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// actor_disguise_officier.cpp
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitDisguiseOfficer(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_DisguiseOfficer;
|
||||
func->BeginState = &Actor::Begin_DisguiseOfficer;
|
||||
func->EndState = &Actor::End_DisguiseOfficer;
|
||||
func->ResumeState = &Actor::Resume_DisguiseOfficer;
|
||||
func->SuspendState = &Actor::Suspend_DisguiseOfficer;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
}
|
||||
|
||||
void Actor::Begin_DisguiseOfficer(void)
|
||||
{
|
||||
m_csMood = STRING_BORED;
|
||||
assert(m_Enemy);
|
||||
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((EnemyIsDisguised() || (m_Enemy->flags & FL_NOTARGET)) && level.m_bAlarm != qtrue) {
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_PAPERS_SCR);
|
||||
m_iEnemyShowPapersTime = m_Enemy->m_ShowPapersTime;
|
||||
|
||||
TransitionState(ACTOR_STATE_DISGUISE_PAPERS);
|
||||
} else {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::End_DisguiseOfficer(void)
|
||||
{
|
||||
m_iNextDisguiseTime = level.inttime + (m_State ? m_iDisguisePeriod : 500);
|
||||
}
|
||||
|
||||
void Actor::Resume_DisguiseOfficer(void)
|
||||
{
|
||||
Begin_DisguiseOfficer();
|
||||
}
|
||||
|
||||
void Actor::Suspend_DisguiseOfficer(void)
|
||||
{
|
||||
End_DisguiseOfficer();
|
||||
}
|
||||
|
||||
void Actor::Think_DisguiseOfficer(void)
|
||||
{
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
ContinueAnimation();
|
||||
UpdateEnemy(1500);
|
||||
|
||||
assert(m_Enemy);
|
||||
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET) && m_State != ACTOR_STATE_DISGUISE_ENEMY) {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_ENEMY, 0);
|
||||
}
|
||||
|
||||
if (level.m_bAlarm == qtrue) {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
switch (m_State) {
|
||||
case ACTOR_STATE_DISGUISE_ENEMY:
|
||||
m_pszDebugState = "enemy";
|
||||
State_Disguise_Enemy();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_HALT:
|
||||
m_pszDebugState = "halt";
|
||||
State_Disguise_Halt();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_PAPERS:
|
||||
m_pszDebugState = "papers";
|
||||
State_Disguise_Fake_Papers();
|
||||
break;
|
||||
default:
|
||||
{
|
||||
Com_Printf("Actor::Think_DisguiseOfficer: invalid think state %i\n", m_State);
|
||||
char assertStr[16317] = {0};
|
||||
strcpy(assertStr, "\"invalid think state\"\n\tMessage: ");
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("thinkstate = %i", m_State));
|
||||
assert(!assertStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_IDLE)) {
|
||||
CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_IDLE);
|
||||
}
|
||||
|
||||
PostThink(true);
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// actor_disguise_officier.cpp
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
|
||||
void Actor::InitDisguiseOfficer
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_DisguiseOfficer;
|
||||
func->BeginState = &Actor::Begin_DisguiseOfficer;
|
||||
func->EndState = &Actor::End_DisguiseOfficer;
|
||||
func->ResumeState = &Actor::Resume_DisguiseOfficer;
|
||||
func->SuspendState = &Actor::Suspend_DisguiseOfficer;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
}
|
||||
|
||||
void Actor::Begin_DisguiseOfficer
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
vec2_t vDelta;
|
||||
m_csMood = STRING_BORED;
|
||||
assert(m_Enemy);
|
||||
|
||||
if (m_Enemy)
|
||||
{
|
||||
if ( (EnemyIsDisguised() || m_Enemy->IsSubclassOfActor()) && !level.m_bAlarm)
|
||||
{
|
||||
VectorSub2D(m_Enemy->origin, origin, vDelta);
|
||||
|
||||
if (vDelta[0] != 0 || vDelta[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(vDelta);
|
||||
}
|
||||
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_PAPERS_SCR;
|
||||
m_bNextForceStart = false;
|
||||
|
||||
|
||||
m_iEnemyShowPapersTime = m_Enemy->m_ShowPapersTime;
|
||||
TransitionState(1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::End_DisguiseOfficer
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
m_iNextDisguiseTime = level.inttime + (m_State ? m_iDisguisePeriod : 500);
|
||||
}
|
||||
|
||||
void Actor::Resume_DisguiseOfficer
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
Begin_DisguiseOfficer();
|
||||
}
|
||||
|
||||
void Actor::Suspend_DisguiseOfficer
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
End_DisguiseOfficer();
|
||||
}
|
||||
|
||||
void Actor::Think_DisguiseOfficer
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
if (RequireThink())
|
||||
{
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
ContinueAnimation();
|
||||
UpdateEnemy(1500);
|
||||
assert(m_Enemy);
|
||||
|
||||
if (!m_Enemy)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
return;
|
||||
}
|
||||
if (!EnemyIsDisguised() && !(m_Enemy->IsSubclassOfActor()) && m_State != 3)
|
||||
{
|
||||
TransitionState(3, 0);
|
||||
}
|
||||
if (level.m_bAlarm)
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
return;
|
||||
}
|
||||
vec2_t vDelta;
|
||||
|
||||
VectorSub2D(m_Enemy->origin, origin, vDelta);
|
||||
|
||||
if (vDelta[0] != 0 || vDelta[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(vDelta);
|
||||
}
|
||||
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
if (m_State == 3)
|
||||
{
|
||||
m_pszDebugState = "enemy";
|
||||
State_Disguise_Enemy();
|
||||
}
|
||||
else if (m_State > 3)
|
||||
{
|
||||
if (m_State != 4)
|
||||
{
|
||||
Com_Printf("Actor::Think_DisguiseOfficer: invalid think state %i\n", m_State);
|
||||
char assertStr[16317] = { 0 };
|
||||
strcpy(assertStr, "\"invalid think state\"\n\tMessage: ");
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("thinkstate = %i", m_State));
|
||||
assert(!assertStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pszDebugState = "halt";
|
||||
Actor::State_Disguise_Halt();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_State == 1)
|
||||
{
|
||||
m_pszDebugState = "papers";
|
||||
State_Disguise_Fake_Papers();
|
||||
}
|
||||
else
|
||||
{
|
||||
char assertStr[16317] = { 0 };
|
||||
strcpy(assertStr, "\"invalid think state\"\n\tMessage: ");
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("thinkstate = %i", m_State));
|
||||
assert(!assertStr);
|
||||
}
|
||||
}
|
||||
CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_NORMAL);
|
||||
PostThink(true);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,163 +24,116 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitDisguiseRover
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitDisguiseRover(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_DisguiseRover;
|
||||
func->BeginState = &Actor::Begin_DisguiseRover;
|
||||
func->EndState = &Actor::End_DisguiseRover;
|
||||
func->ResumeState = &Actor::Resume_DisguiseRover;
|
||||
func->SuspendState = &Actor::Suspend_DisguiseRover;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
func->ThinkState = &Actor::Think_DisguiseRover;
|
||||
func->BeginState = &Actor::Begin_DisguiseRover;
|
||||
func->EndState = &Actor::End_DisguiseRover;
|
||||
func->ResumeState = &Actor::Resume_DisguiseRover;
|
||||
func->SuspendState = &Actor::Suspend_DisguiseRover;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
}
|
||||
|
||||
void Actor::Begin_DisguiseRover
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_DisguiseRover(void)
|
||||
{
|
||||
m_csMood = STRING_BORED;
|
||||
assert(m_Enemy);
|
||||
|
||||
vec2_t vDelta;
|
||||
m_csMood = STRING_BORED;
|
||||
assert(m_Enemy);
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Enemy)
|
||||
{
|
||||
if ((EnemyIsDisguised() || m_Enemy->IsSubclassOfActor()) && !level.m_bAlarm)
|
||||
{
|
||||
VectorSub2D(m_Enemy->origin, origin, vDelta);
|
||||
if ((EnemyIsDisguised() || (m_Enemy->flags & FL_NOTARGET)) && level.m_bAlarm != qtrue) {
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
if (vDelta[0] != 0 || vDelta[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(vDelta);
|
||||
}
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_PAPERS_SCR);
|
||||
m_iEnemyShowPapersTime = m_Enemy->m_ShowPapersTime;
|
||||
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_PAPERS_SCR;
|
||||
m_bNextForceStart = false;
|
||||
|
||||
m_iEnemyShowPapersTime = m_Enemy->m_ShowPapersTime;
|
||||
TransitionState(1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
}
|
||||
TransitionState(ACTOR_STATE_DISGUISE_PAPERS);
|
||||
} else {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::End_DisguiseRover
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_DisguiseRover(void)
|
||||
{
|
||||
m_iNextDisguiseTime = level.inttime + (m_State ? m_iDisguisePeriod : 500);
|
||||
m_iNextDisguiseTime = level.inttime + (m_State ? m_iDisguisePeriod : 500);
|
||||
}
|
||||
|
||||
void Actor::Resume_DisguiseRover
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Resume_DisguiseRover(void)
|
||||
{
|
||||
Begin_DisguiseRover();
|
||||
Begin_DisguiseRover();
|
||||
}
|
||||
|
||||
void Actor::Suspend_DisguiseRover
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Suspend_DisguiseRover(void)
|
||||
{
|
||||
End_DisguiseRover();
|
||||
End_DisguiseRover();
|
||||
}
|
||||
|
||||
void Actor::Think_DisguiseRover
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_DisguiseRover(void)
|
||||
{
|
||||
if (!RequireThink())
|
||||
{
|
||||
return;
|
||||
}
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
ContinueAnimation();
|
||||
UpdateEnemy(1500);
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(m_Enemy != NULL);
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
ContinueAnimation();
|
||||
UpdateEnemy(1500);
|
||||
|
||||
if (!m_Enemy)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
return;
|
||||
}
|
||||
assert(m_Enemy);
|
||||
|
||||
if (!EnemyIsDisguised() && !m_Enemy->IsSubclassOfActor() && m_State != 3)
|
||||
{
|
||||
TransitionState(3, 0);
|
||||
}
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (level.m_bAlarm)
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
vec2_t facedir;
|
||||
facedir[0] = m_Enemy->origin[0] - origin[0];
|
||||
facedir[1] = m_Enemy->origin[1] - origin[1];
|
||||
if (facedir[0] != 0 || facedir[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(facedir);
|
||||
}
|
||||
if (!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET) && m_State != ACTOR_STATE_DISGUISE_ENEMY) {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_ENEMY, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
if (level.m_bAlarm == qtrue) {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_State == 2)
|
||||
{
|
||||
m_pszDebugState = "accept";
|
||||
State_Disguise_Accept();
|
||||
}
|
||||
else if(m_State > 2)
|
||||
{
|
||||
if (m_State == 3)
|
||||
{
|
||||
m_pszDebugState = "enemy";
|
||||
State_Disguise_Enemy();
|
||||
}
|
||||
else if (m_State == 4)
|
||||
{
|
||||
m_pszDebugState = "halt";
|
||||
State_Disguise_Halt();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!"invalid think state");
|
||||
}
|
||||
}
|
||||
else if (m_State == 1)
|
||||
{
|
||||
m_pszDebugState = "papers";
|
||||
State_Disguise_Papers();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!"invalid think state");
|
||||
}
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_NORMAL);
|
||||
PostThink(true);
|
||||
switch (m_State) {
|
||||
case ACTOR_STATE_DISGUISE_ACCEPT:
|
||||
m_pszDebugState = "accept";
|
||||
State_Disguise_Accept();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_ENEMY:
|
||||
m_pszDebugState = "enemy";
|
||||
State_Disguise_Enemy();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_HALT:
|
||||
m_pszDebugState = "halt";
|
||||
State_Disguise_Halt();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_PAPERS:
|
||||
m_pszDebugState = "papers";
|
||||
State_Disguise_Fake_Papers();
|
||||
break;
|
||||
default:
|
||||
{
|
||||
Com_Printf("Actor::Think_DisguiseOfficer: invalid think state %i\n", m_State);
|
||||
char assertStr[16317] = {0};
|
||||
strcpy(assertStr, "\"invalid think state\"\n\tMessage: ");
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("thinkstate = %i", m_State));
|
||||
assert(!assertStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_IDLE)) {
|
||||
CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_IDLE);
|
||||
}
|
||||
|
||||
PostThink(true);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,133 +24,79 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitDisguiseSalute
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitDisguiseSalute(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_DisguiseSalute;
|
||||
func->BeginState = &Actor::Begin_DisguiseSalute;
|
||||
func->EndState = &Actor::End_DisguiseSalute;
|
||||
func->ResumeState = &Actor::Resume_DisguiseSalute;
|
||||
func->SuspendState = &Actor::Suspend_DisguiseSalute;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
func->ThinkState = &Actor::Think_DisguiseSalute;
|
||||
func->BeginState = &Actor::Begin_DisguiseSalute;
|
||||
func->EndState = &Actor::End_DisguiseSalute;
|
||||
func->ResumeState = &Actor::Resume_DisguiseSalute;
|
||||
func->SuspendState = &Actor::Suspend_DisguiseSalute;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
}
|
||||
|
||||
void Actor::Begin_DisguiseSalute
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_DisguiseSalute(void)
|
||||
{
|
||||
vec2_t vDelta;
|
||||
|
||||
Com_Printf("Saluting guy....\n");
|
||||
|
||||
m_csMood = STRING_BORED;
|
||||
assert(m_Enemy);
|
||||
Com_Printf("Saluting guy....\n");
|
||||
|
||||
m_csMood = STRING_BORED;
|
||||
assert(m_Enemy);
|
||||
|
||||
if (m_Enemy)
|
||||
{
|
||||
if ((EnemyIsDisguised() || m_Enemy->IsSubclassOfActor()) && !level.m_bAlarm)
|
||||
{
|
||||
VectorSub2D(m_Enemy->origin, origin, vDelta);
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vDelta[0] != 0 || vDelta[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(vDelta);
|
||||
}
|
||||
if ((EnemyIsDisguised() || (m_Enemy->flags & FL_NOTARGET)) && level.m_bAlarm != qtrue) {
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_SALUTE_SCR;
|
||||
m_bNextForceStart = false;
|
||||
|
||||
|
||||
m_iEnemyShowPapersTime = m_Enemy->m_ShowPapersTime;
|
||||
TransitionState(1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
}
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_PAPERS_SCR);
|
||||
} else {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::End_DisguiseSalute
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_DisguiseSalute(void)
|
||||
{
|
||||
m_iNextDisguiseTime = level.inttime + m_iDisguisePeriod;
|
||||
m_iNextDisguiseTime = level.inttime + m_iDisguisePeriod;
|
||||
}
|
||||
|
||||
void Actor::Resume_DisguiseSalute
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Resume_DisguiseSalute(void)
|
||||
{
|
||||
Begin_DisguiseSalute();
|
||||
Begin_DisguiseSalute();
|
||||
}
|
||||
|
||||
void Actor::Suspend_DisguiseSalute
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Suspend_DisguiseSalute(void)
|
||||
{
|
||||
End_DisguiseSalute();
|
||||
End_DisguiseSalute();
|
||||
}
|
||||
|
||||
void Actor::Think_DisguiseSalute
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_DisguiseSalute(void)
|
||||
{
|
||||
NoPoint();
|
||||
ContinueAnimation();
|
||||
UpdateEnemy(2000);
|
||||
NoPoint();
|
||||
ContinueAnimation();
|
||||
UpdateEnemy(2000);
|
||||
|
||||
assert(m_Enemy != NULL);
|
||||
assert(m_Enemy != NULL);
|
||||
|
||||
if (m_Enemy)
|
||||
{
|
||||
if (!EnemyIsDisguised() && !m_Enemy->IsSubclassOfActor() && level.m_bAlarm)
|
||||
{
|
||||
{
|
||||
vec2_t facedir;
|
||||
facedir[0] = m_Enemy->origin[0] - origin[0];
|
||||
facedir[1] = m_Enemy->origin[1] - origin[1];
|
||||
if (facedir[0] != 0 || facedir[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(facedir);
|
||||
}
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
if ((!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET)) || level.m_bAlarm != qtrue) {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
PostThink(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
}
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
PostThink(true);
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_DisguiseSalute
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::FinishedAnimation_DisguiseSalute(void)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,164 +24,118 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitDisguiseSentry
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitDisguiseSentry(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_DisguiseSentry;
|
||||
func->BeginState = &Actor::Begin_DisguiseSentry;
|
||||
func->EndState = &Actor::End_DisguiseSentry;
|
||||
func->ResumeState = &Actor::Resume_DisguiseSentry;
|
||||
func->SuspendState = &Actor::Suspend_DisguiseSentry;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
func->ThinkState = &Actor::Think_DisguiseSentry;
|
||||
func->BeginState = &Actor::Begin_DisguiseSentry;
|
||||
func->EndState = &Actor::End_DisguiseSentry;
|
||||
func->ResumeState = &Actor::Resume_DisguiseSentry;
|
||||
func->SuspendState = &Actor::Suspend_DisguiseSentry;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
|
||||
func->IsState = &Actor::IsDisguiseState;
|
||||
}
|
||||
|
||||
void Actor::Begin_DisguiseSentry
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_DisguiseSentry(void)
|
||||
{
|
||||
vec2_t vDelta;
|
||||
m_csMood = STRING_BORED;
|
||||
assert(m_Enemy);
|
||||
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
m_csMood = STRING_BORED;
|
||||
if ((EnemyIsDisguised() || (m_Enemy->flags & FL_NOTARGET)) && level.m_bAlarm != qtrue) {
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
assert(m_Enemy);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_WAIT_SCR);
|
||||
m_iEnemyShowPapersTime = m_Enemy->m_ShowPapersTime;
|
||||
|
||||
if (m_Enemy)
|
||||
{
|
||||
if ((EnemyIsDisguised() || m_Enemy->IsSubclassOfActor()) && !level.m_bAlarm)
|
||||
{
|
||||
VectorSub2D(m_Enemy->origin, origin, vDelta);
|
||||
|
||||
if (vDelta[0] != 0 || vDelta[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(vDelta);
|
||||
}
|
||||
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DISGUISE_WAIT_SCR;
|
||||
m_bNextForceStart = false;
|
||||
|
||||
m_iEnemyShowPapersTime = m_Enemy->m_ShowPapersTime;
|
||||
TransitionState(1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
}
|
||||
TransitionState(ACTOR_STATE_DISGUISE_WAIT);
|
||||
} else {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::End_DisguiseSentry
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_DisguiseSentry(void)
|
||||
{
|
||||
m_iNextDisguiseTime = level.inttime + (m_State ? m_iDisguisePeriod : 500);
|
||||
m_iNextDisguiseTime = level.inttime + (m_State ? m_iDisguisePeriod : 500);
|
||||
}
|
||||
|
||||
void Actor::Resume_DisguiseSentry
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Resume_DisguiseSentry(void)
|
||||
{
|
||||
Begin_DisguiseSentry();
|
||||
Begin_DisguiseSentry();
|
||||
}
|
||||
|
||||
void Actor::Suspend_DisguiseSentry
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Suspend_DisguiseSentry(void)
|
||||
{
|
||||
End_DisguiseSentry();
|
||||
End_DisguiseSentry();
|
||||
}
|
||||
|
||||
void Actor::Think_DisguiseSentry
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_DisguiseSentry(void)
|
||||
{
|
||||
if (RequireThink())
|
||||
{
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
ContinueAnimation();
|
||||
UpdateEnemy(1500);
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(m_Enemy != NULL);
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
ContinueAnimation();
|
||||
UpdateEnemy(1500);
|
||||
|
||||
if (!m_Enemy)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
return;
|
||||
}
|
||||
if (!EnemyIsDisguised() && !m_Enemy->IsSubclassOfActor() && m_State != 3)
|
||||
{
|
||||
TransitionState(3, 0);
|
||||
}
|
||||
assert(m_Enemy != NULL);
|
||||
|
||||
if (level.m_bAlarm)
|
||||
{
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
if (!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET) && m_State != ACTOR_STATE_DISGUISE_ENEMY) {
|
||||
TransitionState(ACTOR_STATE_DISGUISE_ENEMY, 0);
|
||||
}
|
||||
|
||||
{
|
||||
vec2_t facedir;
|
||||
facedir[0] = m_Enemy->origin[0] - origin[0];
|
||||
facedir[1] = m_Enemy->origin[1] - origin[1];
|
||||
if (facedir[0] != 0 || facedir[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(facedir);
|
||||
}
|
||||
if (level.m_bAlarm) {
|
||||
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
switch (m_State) {
|
||||
case ACTOR_STATE_DISGUISE_WAIT:
|
||||
m_pszDebugState = "wait";
|
||||
State_Disguise_Wait();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_PAPERS:
|
||||
m_pszDebugState = "papers";
|
||||
State_Disguise_Papers();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_ACCEPT:
|
||||
m_pszDebugState = "accept";
|
||||
State_Disguise_Accept();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_ENEMY:
|
||||
m_pszDebugState = "enemy";
|
||||
State_Disguise_Enemy();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_HALT:
|
||||
m_pszDebugState = "halt";
|
||||
State_Disguise_Halt();
|
||||
break;
|
||||
case ACTOR_STATE_DISGUISE_DENY:
|
||||
m_pszDebugState = "deny";
|
||||
State_Disguise_Deny();
|
||||
break;
|
||||
default:
|
||||
Com_Printf("Actor::Think_DisguiseSentry: invalid think state %i\n", m_State);
|
||||
assert(!"invalid think state");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (m_State)
|
||||
{
|
||||
case 0:
|
||||
m_pszDebugState = "wait";
|
||||
State_Disguise_Wait();
|
||||
break;
|
||||
case 1:
|
||||
m_pszDebugState = "papers";
|
||||
State_Disguise_Papers();
|
||||
break;
|
||||
case 2:
|
||||
m_pszDebugState = "accept";
|
||||
State_Disguise_Accept();
|
||||
break;
|
||||
case 3:
|
||||
m_pszDebugState = "enemy";
|
||||
State_Disguise_Enemy();
|
||||
break;
|
||||
case 4:
|
||||
m_pszDebugState = "halt";
|
||||
State_Disguise_Halt();
|
||||
break;
|
||||
case 5:
|
||||
m_pszDebugState = "deny";
|
||||
State_Disguise_Deny();
|
||||
break;
|
||||
default:
|
||||
Com_Printf("Actor::Think_DisguiseSentry: invalid think state %i\n", m_State);
|
||||
assert(!"invalid think state");
|
||||
break;
|
||||
}
|
||||
CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_NORMAL);
|
||||
PostThink(true);
|
||||
}
|
||||
}
|
||||
if (!CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_IDLE)) {
|
||||
CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_IDLE);
|
||||
}
|
||||
|
||||
PostThink(true);
|
||||
}
|
||||
+91
-142
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,176 +24,125 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitDogIdle
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitDogIdle(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_Dog;
|
||||
func->EndState = &Actor::End_Dog;
|
||||
func->ThinkState = &Actor::Think_Dog_Idle;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->IsState = &Actor::IsDogState;
|
||||
func->BeginState = &Actor::Begin_Dog;
|
||||
func->EndState = &Actor::End_Dog;
|
||||
func->ThinkState = &Actor::Think_Dog_Idle;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->IsState = &Actor::IsDogState;
|
||||
}
|
||||
|
||||
void Actor::InitDogAttack
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitDogAttack(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_Dog;
|
||||
func->EndState = &Actor::End_Dog;
|
||||
func->ThinkState = &Actor::Think_Dog_Attack;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack;
|
||||
func->IsState = &Actor::IsDogState;
|
||||
func->BeginState = &Actor::Begin_Dog;
|
||||
func->EndState = &Actor::End_Dog;
|
||||
func->ThinkState = &Actor::Think_Dog_Attack;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack;
|
||||
func->IsState = &Actor::IsDogState;
|
||||
}
|
||||
|
||||
void Actor::InitDogCurious
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitDogCurious(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_Dog;
|
||||
func->EndState = &Actor::End_Dog;
|
||||
func->ThinkState = &Actor::Think_Dog_Curious;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
|
||||
func->IsState = &Actor::IsDogState;
|
||||
func->BeginState = &Actor::Begin_Dog;
|
||||
func->EndState = &Actor::End_Dog;
|
||||
func->ThinkState = &Actor::Think_Dog_Curious;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
|
||||
func->IsState = &Actor::IsDogState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Dog
|
||||
(
|
||||
void
|
||||
)
|
||||
bool Actor::IsDogState(int state)
|
||||
{
|
||||
m_bDog = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Actor::End_Dog
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Dog(void)
|
||||
{
|
||||
;
|
||||
m_bIsAnimal = true;
|
||||
}
|
||||
|
||||
void Actor::Think_Dog_Idle
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_Dog(void)
|
||||
{
|
||||
if( !RequireThink() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "Dog_Idle";
|
||||
m_bHasDesiredLookAngles = false;
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DOG_IDLE_SCR;
|
||||
CheckForThinkStateTransition();
|
||||
PostThink( false );
|
||||
;
|
||||
}
|
||||
|
||||
void Actor::Think_Dog_Attack
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_Dog_Idle(void)
|
||||
{
|
||||
if (!RequireThink())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "Dog_Attack";
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "Dog_Idle";
|
||||
|
||||
if (m_Enemy && !(m_Enemy->IsSubclassOfActor()))
|
||||
{
|
||||
NoPoint();
|
||||
ForwardLook();
|
||||
|
||||
SetPath(m_Enemy->origin, NULL, 0, NULL, 0.0);
|
||||
if (PathExists())
|
||||
{
|
||||
vec2_t delta;
|
||||
VectorSub2D(m_Enemy->origin, origin, delta);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DOG_IDLE_SCR);
|
||||
|
||||
if (VectorLength2DSquared(delta) >= 8000)
|
||||
{
|
||||
FaceMotion();
|
||||
m_csNextAnimString = STRING_ANIM_DOG_CHASE_SCR;
|
||||
m_eNextAnimMode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
vec2_t facedir;
|
||||
facedir[0] = m_Enemy->origin[0] - origin[0];
|
||||
facedir[1] = m_Enemy->origin[1] - origin[1];
|
||||
if (facedir[0] != 0 || facedir[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(facedir);
|
||||
}
|
||||
|
||||
}
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DOG_ATTACK_SCR;
|
||||
}
|
||||
m_bNextForceStart = false;
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(false);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
vec2_t facedir;
|
||||
facedir[0] = m_Enemy->origin[0] - origin[0];
|
||||
facedir[1] = m_Enemy->origin[1] - origin[1];
|
||||
if (facedir[0] != 0 || facedir[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(facedir);
|
||||
}
|
||||
|
||||
}
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
}
|
||||
m_bNextForceStart = false;
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DOG_CURIOUS_SCR;
|
||||
TransitionState(20, 0);
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(false);
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(false);
|
||||
}
|
||||
|
||||
void Actor::Think_Dog_Curious
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_Dog_Attack(void)
|
||||
{
|
||||
if (RequireThink())
|
||||
{
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "Dog_Curious";
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Enemy && !m_Enemy->IsSubclassOfActor())
|
||||
{
|
||||
vec2_t vDelta;
|
||||
VectorSub2D(m_Enemy->origin, origin, vDelta);
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "Dog_Attack";
|
||||
|
||||
if (vDelta[0] != 0 || vDelta[1] != 0)
|
||||
{
|
||||
SetDesiredYawDir(vDelta);
|
||||
}
|
||||
if (!m_Enemy || (m_Enemy->flags & FL_NOTARGET)) {
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DOG_CURIOUS_SCR);
|
||||
TransitionState(20);
|
||||
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(false);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
m_bNextForceStart = false;
|
||||
m_eNextAnimMode = 1;
|
||||
m_csNextAnimString = STRING_ANIM_DOG_CURIOUS_SCR;
|
||||
SetPath(m_Enemy->origin, NULL, 0, NULL, 0.0);
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(false);
|
||||
}
|
||||
if (PathExists()) {
|
||||
vec2_t delta;
|
||||
VectorSub2D(m_Enemy->origin, origin, delta);
|
||||
|
||||
if (VectorLength2DSquared(delta) >= 8000) {
|
||||
FaceMotion();
|
||||
DesiredAnimation(ANIM_MODE_PATH, STRING_ANIM_DOG_CHASE_SCR);
|
||||
} else {
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DOG_ATTACK_SCR);
|
||||
}
|
||||
} else {
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DOG_CURIOUS_SCR);
|
||||
TransitionState(20);
|
||||
}
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(false);
|
||||
}
|
||||
|
||||
void Actor::Think_Dog_Curious(void)
|
||||
{
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "Dog_Curious";
|
||||
|
||||
if (m_Enemy && !(m_Enemy->flags & FL_NOTARGET)) {
|
||||
SetDesiredYawDest(m_Enemy->origin);
|
||||
SetDesiredLookDir(m_Enemy->origin - origin);
|
||||
}
|
||||
|
||||
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DOG_CURIOUS_SCR);
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
PostThink(false);
|
||||
}
|
||||
+442
-573
File diff suppressed because it is too large.
Load diff
+42
-90
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,105 +24,57 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitIdle
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitIdle(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_Idle;
|
||||
func->ThinkState = &Actor::Think_Idle;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
func->BeginState = &Actor::Begin_Idle;
|
||||
func->ThinkState = &Actor::Think_Idle;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Idle
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Idle(void)
|
||||
{
|
||||
glbs.Printf("Begin_Idle\n");
|
||||
m_csMood = m_csIdleMood;
|
||||
ClearPath();
|
||||
m_csMood = m_csIdleMood;
|
||||
ClearPath();
|
||||
}
|
||||
|
||||
void Actor::Think_Idle
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::IdleThink(void)
|
||||
{
|
||||
if (RequireThink())
|
||||
{
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "";
|
||||
CheckForThinkStateTransition();
|
||||
IdleThink();
|
||||
}
|
||||
IdlePoint();
|
||||
IdleLook();
|
||||
|
||||
if (PathExists() && PathComplete()) {
|
||||
ClearPath();
|
||||
}
|
||||
|
||||
if (m_bAutoAvoidPlayer && !PathExists()) {
|
||||
SetPathToNotBlockSentient(static_cast<Sentient *>(G_GetEntity(0)));
|
||||
}
|
||||
|
||||
if (PathExists()) {
|
||||
Anim_WalkTo(ANIM_MODE_PATH);
|
||||
if (PathDist() > 128.0) {
|
||||
FaceMotion();
|
||||
} else {
|
||||
IdleTurn();
|
||||
}
|
||||
} else {
|
||||
Anim_Idle();
|
||||
IdleTurn();
|
||||
}
|
||||
|
||||
PostThink(true);
|
||||
}
|
||||
|
||||
void Actor::IdleThink
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_Idle(void)
|
||||
{
|
||||
IdlePoint();
|
||||
IdleLook();
|
||||
if (PathExists() && PathComplete())
|
||||
{
|
||||
ClearPath();
|
||||
}
|
||||
if (m_bAutoAvoidPlayer && !PathExists())
|
||||
{
|
||||
SetPathToNotBlockSentient((Sentient *)G_GetEntity(0));
|
||||
}
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PathExists())
|
||||
{
|
||||
Anim_WalkTo(2);
|
||||
if (PathDist() <= 128.0)
|
||||
IdleTurn();
|
||||
else
|
||||
FaceMotion();
|
||||
}
|
||||
else
|
||||
{
|
||||
Anim_Idle();
|
||||
IdleTurn();
|
||||
}
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "";
|
||||
|
||||
PostThink(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
Actor::PassesTransitionConditions_Idle
|
||||
|
||||
Should actor transition think state to idle ?
|
||||
===============
|
||||
*/
|
||||
bool Actor::PassesTransitionConditions_Idle
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
glbs.Printf("PassesTransitionConditions_Idle\n");
|
||||
|
||||
UpdateEnemy(500);
|
||||
|
||||
if (m_bLockThinkState)
|
||||
return false;
|
||||
|
||||
if (!m_Enemy && !m_iCuriousTime)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Actor::IsIdleState
|
||||
(
|
||||
int state
|
||||
)
|
||||
{
|
||||
return state == THINKSTATE_IDLE;
|
||||
CheckForThinkStateTransition();
|
||||
IdleThink();
|
||||
}
|
||||
+32
-50
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,67 +24,49 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitDead
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitDead(GlobalFuncs_t *func)
|
||||
{
|
||||
func->IsState = &Actor::IsKilledState;
|
||||
func->IsState = &Actor::IsKilledState;
|
||||
}
|
||||
|
||||
void Actor::InitKilled
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitKilled(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_Killed;
|
||||
func->ThinkState = &Actor::Think_Killed;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Killed;
|
||||
func->IsState = &Actor::IsKilledState;
|
||||
func->BeginState = &Actor::Begin_Killed;
|
||||
func->ThinkState = &Actor::Think_Killed;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Killed;
|
||||
func->IsState = &Actor::IsKilledState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Killed
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Killed(void)
|
||||
{
|
||||
Event e1(EV_Actor_DeathEmbalm); // ebx
|
||||
ClearPath();
|
||||
ResetBoneControllers();
|
||||
|
||||
ClearPath();
|
||||
ResetBoneControllers();
|
||||
|
||||
PostEvent(
|
||||
e1,
|
||||
0.05f);
|
||||
TransitionState(700, 0);
|
||||
PostEvent(EV_Actor_DeathEmbalm, 0.05f);
|
||||
TransitionState(ACTOR_STATE_KILLED_BEGIN, 0);
|
||||
}
|
||||
|
||||
void Actor::Think_Killed
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_Killed(void)
|
||||
{
|
||||
Unregister(STRING_ANIMDONE);
|
||||
if (m_State == 700)
|
||||
{
|
||||
m_pszDebugState = "begin";
|
||||
NoPoint();
|
||||
m_bHasDesiredLookAngles = false;
|
||||
StopTurning();
|
||||
Anim_Killed();
|
||||
PostThink(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pszDebugState = "end";
|
||||
}
|
||||
Unregister(STRING_ANIMDONE);
|
||||
|
||||
if (m_State != ACTOR_STATE_KILLED_BEGIN) {
|
||||
m_pszDebugState = "end";
|
||||
return;
|
||||
}
|
||||
|
||||
m_pszDebugState = "begin";
|
||||
|
||||
NoPoint();
|
||||
ForwardLook();
|
||||
StopTurning();
|
||||
|
||||
Anim_Killed();
|
||||
PostThink(false);
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_Killed
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::FinishedAnimation_Killed(void)
|
||||
{
|
||||
BecomeCorpse();
|
||||
TransitionState(701, 0);
|
||||
BecomeCorpse();
|
||||
TransitionState(ACTOR_STATE_KILLED_END);
|
||||
}
|
||||
+251
-310
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,337 +24,278 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
#include "weapturret.h"
|
||||
#include "bg_local.h"
|
||||
|
||||
extern Vector MINS;
|
||||
extern Vector MAXS;
|
||||
|
||||
void Actor::InitMachineGunner
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitMachineGunner(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_MachineGunner;
|
||||
func->EndState = &Actor::End_MachineGunner;
|
||||
func->ThinkState = &Actor::Think_MachineGunner;
|
||||
func->IsState = &Actor::IsMachineGunnerState;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_MachineGunner;
|
||||
func->BeginState = &Actor::Begin_MachineGunner;
|
||||
func->EndState = &Actor::End_MachineGunner;
|
||||
func->ThinkState = &Actor::Think_MachineGunner;
|
||||
func->IsState = &Actor::IsMachineGunnerState;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_MachineGunner;
|
||||
}
|
||||
|
||||
void Actor::Begin_MachineGunner
|
||||
(
|
||||
void
|
||||
)
|
||||
bool Actor::IsMachineGunnerState(int state)
|
||||
{
|
||||
m_csMood = STRING_ALERT;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
|
||||
if (m_pTurret)
|
||||
{
|
||||
Sentient *pOwner;
|
||||
m_pTurret->m_bHadOwner = true;
|
||||
pOwner = m_pTurret->GetOwner();
|
||||
if (pOwner)
|
||||
{
|
||||
Com_Printf(
|
||||
"^~^~^ Actor (entnum %d, radnum %d, targetname '%s') cannot use turret (entnum %d, radnum %d, targetname '%s')"
|
||||
" since it is already being used by Actor (entnum %d, radnum %d, targetname '%s')\n",
|
||||
entnum,
|
||||
radnum,
|
||||
targetname.c_str(),
|
||||
m_pTurret->entnum,
|
||||
m_pTurret->radnum,
|
||||
m_pTurret->TargetName().c_str(),
|
||||
pOwner->entnum,
|
||||
pOwner->radnum,
|
||||
pOwner->TargetName().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Holster();
|
||||
|
||||
m_pTurret->TurretBeginUsed(this);
|
||||
TransitionState(1200, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf(
|
||||
"^~^~^ Actor (entnum %d, radnum %d, targetname '%s') has no turret specified\n",
|
||||
entnum,
|
||||
radnum,
|
||||
targetname.c_str());
|
||||
}
|
||||
}
|
||||
void Actor::End_MachineGunner
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
if (!GetWeapon(WEAPON_MAIN))
|
||||
giveItem("models/weapons/mp40.tik");
|
||||
|
||||
Unholster();
|
||||
if (m_pTurret)
|
||||
{
|
||||
if (m_pTurret->GetOwner() == this)
|
||||
{
|
||||
m_pTurret->TurretEndUsed();
|
||||
}
|
||||
}
|
||||
}
|
||||
void Actor::BecomeTurretGuy
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
|
||||
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
|
||||
SetThink(THINKSTATE_DISGUISE, THINK_DISGUISE_SALUTE);
|
||||
SetThink(THINKSTATE_GRENADE, THINK_GRENADE);
|
||||
|
||||
if (CurrentThink() == THINK_IDLE && Turret_DecideToSelectState())
|
||||
{
|
||||
TransitionState(100, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Actor::Think_MachineGunner
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_MachineGunner(void)
|
||||
{
|
||||
if (RequireThink())
|
||||
{
|
||||
if (m_pTurret && m_pTurret->GetOwner() == this && !m_bNoPlayerCollision)
|
||||
{
|
||||
if (!m_bEnableEnemy)
|
||||
{
|
||||
ThinkHoldGun();
|
||||
return;
|
||||
}
|
||||
m_csMood = STRING_ALERT;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
|
||||
if (level.inttime < m_iEnemyCheckTime + 200)
|
||||
{
|
||||
ThinkHoldGun();
|
||||
return;
|
||||
}
|
||||
|
||||
m_iEnemyCheckTime = level.inttime;
|
||||
if (!m_pTurret) {
|
||||
Com_Printf(
|
||||
"^~^~^ Actor (entnum %d, radnum %d, targetname '%s') has no turret specified\n",
|
||||
entnum,
|
||||
radnum,
|
||||
targetname.c_str()
|
||||
);
|
||||
|
||||
if (m_pTurret->CanTarget(G_GetEntity(0)->centroid))
|
||||
{
|
||||
ThinkHoldGun();
|
||||
return;
|
||||
}
|
||||
if (!m_pGrenade || m_fGrenadeAwareness < rand() * 0.000000046566129)
|
||||
{
|
||||
if (!G_SightTrace(
|
||||
EyePosition(),
|
||||
vec_zero,
|
||||
vec_zero,
|
||||
G_GetEntity(0)->centroid,
|
||||
this,
|
||||
G_GetEntity(0),
|
||||
33819417,
|
||||
qfalse,
|
||||
"Actor::Think_MachineGunner"))
|
||||
{
|
||||
ThinkHoldGun();
|
||||
return;
|
||||
}
|
||||
if (m_ThinkStates[THINKLEVEL_NORMAL] != THINKSTATE_IDLE)
|
||||
{
|
||||
BecomeTurretGuy();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Enemy && !m_Enemy->IsSubclassOfActor() && !EnemyIsDisguised() && m_PotentialEnemies.GetCurrentVisibility() >= 1)
|
||||
{
|
||||
BecomeTurretGuy();
|
||||
return;
|
||||
}
|
||||
Sentient *pOwner;
|
||||
m_pTurret->m_bHadOwner = true;
|
||||
pOwner = m_pTurret->GetOwner();
|
||||
if (m_pTurret->GetOwner()) {
|
||||
Com_Printf(
|
||||
"^~^~^ Actor (entnum %d, radnum %d, targetname '%s') cannot use turret (entnum %d, radnum %d, "
|
||||
"targetname '%s')"
|
||||
" since it is already being used by Actor (entnum %d, radnum %d, targetname '%s')\n",
|
||||
entnum,
|
||||
radnum,
|
||||
targetname.c_str(),
|
||||
m_pTurret->entnum,
|
||||
m_pTurret->radnum,
|
||||
m_pTurret->targetname.c_str(),
|
||||
m_pTurret->GetOwner()->entnum,
|
||||
m_pTurret->GetOwner()->radnum,
|
||||
m_pTurret->GetOwner()->targetname.c_str()
|
||||
);
|
||||
} else {
|
||||
Holster();
|
||||
|
||||
if (!m_Enemy || !m_Enemy->IsSubclassOfActor() || EnemyIsDisguised() || m_PotentialEnemies.GetCurrentVisibility() > 1)
|
||||
{
|
||||
ThinkHoldGun();
|
||||
return;
|
||||
}
|
||||
|
||||
SetCuriousAnimHint(6);
|
||||
}
|
||||
}
|
||||
BecomeTurretGuy();
|
||||
}
|
||||
m_pTurret->TurretBeginUsed(this);
|
||||
TransitionState(ACTOR_STATE_MACHINE_GUNNER_READY);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::ThinkHoldGun
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_MachineGunner(void)
|
||||
{
|
||||
Vector end;
|
||||
trace_t trace;
|
||||
float temp;
|
||||
float temp2;
|
||||
float machine_gunner_hands_up_stand;
|
||||
float heightDiff;
|
||||
float right;
|
||||
//vec3_t newOrigin;
|
||||
Vector offset;
|
||||
Vector start;
|
||||
//vec3_t new_angles;
|
||||
Vector vForward;
|
||||
|
||||
UpdateEyeOrigin();
|
||||
m_pszDebugState = "";
|
||||
if (m_State == 1200)
|
||||
{
|
||||
if (m_pTurret->IsFiring())
|
||||
{
|
||||
if (m_pTurret->aim_target == G_GetEntity(0))
|
||||
{
|
||||
m_bNoSurprise = true;
|
||||
}
|
||||
m_csNextAnimString = STRING_ANIM_MG42_SHOOT_SCR;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_csNextAnimString = STRING_ANIM_MG42_IDLE_SCR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_csNextAnimString = STRING_ANIM_MG42_RELOAD_SCR;
|
||||
m_bAnimScriptSet = false;
|
||||
}
|
||||
m_eNextAnimMode = 8;
|
||||
m_bNextForceStart = false;
|
||||
|
||||
CheckUnregister();
|
||||
|
||||
StopTurning();
|
||||
|
||||
setAngles(Vector(0,m_pTurret->angles[1],0));
|
||||
|
||||
vForward = Vector(m_pTurret->orientation[0]) * -39 + m_pTurret->origin;
|
||||
|
||||
if (m_State == 1201)
|
||||
{
|
||||
heightDiff = 71.6f;
|
||||
}
|
||||
else
|
||||
{
|
||||
heightDiff = 71.8f;
|
||||
}
|
||||
|
||||
machine_gunner_hands_up_stand = origin[2] - (m_pTurret->origin[2] - heightDiff);
|
||||
|
||||
|
||||
if (machine_gunner_hands_up_stand < 0)
|
||||
{
|
||||
if (m_State == 1201)
|
||||
{
|
||||
temp = (machine_gunner_hands_up_stand - m_pTurret->origin[2]) / 39;
|
||||
if (temp >= -1.0 && temp <= 1.0)
|
||||
{
|
||||
right = atan2(temp / sqrt(temp*-temp + 1), 1) * 180 / M_PI;
|
||||
m_pTurret->setAngles(Vector(right, m_pTurret->angles[1], m_pTurret->angles[2]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fCrouchWeight = machine_gunner_hands_up_stand / 17.1;
|
||||
if (m_fCrouchWeight < -1.0)
|
||||
{
|
||||
m_fCrouchWeight = -1.0;
|
||||
}
|
||||
|
||||
}
|
||||
temp2 = m_fCrouchWeight * 2.6;
|
||||
offset.x = (-(-9.3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.x;
|
||||
offset.y = (-(-9.3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fCrouchWeight = machine_gunner_hands_up_stand / (heightDiff - 38.7);
|
||||
if (m_fCrouchWeight > 1.0)
|
||||
{
|
||||
m_fCrouchWeight = 1.0;
|
||||
}
|
||||
|
||||
temp2 = m_fCrouchWeight * -1.6;
|
||||
offset.x = (-(-3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.x;
|
||||
offset.y = (-(-3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.y;
|
||||
}
|
||||
|
||||
start.x = (temp2 + 10.3) * orientation[1][0] + offset.x;
|
||||
start.y = (temp2 + 10.3) * orientation[1][1] + offset.y;
|
||||
|
||||
if (m_fCrouchWeight >= 0.5)
|
||||
m_csCurrentPosition = STRING_CROUCH;
|
||||
else
|
||||
m_csCurrentPosition = STRING_STAND;
|
||||
|
||||
UpdateAimMotion();
|
||||
UpdateAnim();
|
||||
start.z = origin.z + 18.0;
|
||||
|
||||
end = start;
|
||||
end.z = origin.z - 94.0;
|
||||
|
||||
trace = G_Trace(start, MINS, MAXS, end, this, 1107437825, qfalse, "Actor::ThinkHoldGun");
|
||||
|
||||
if (trace.fraction != 1.0 && !trace.startsolid && !trace.allsolid && trace.ent)
|
||||
SafeSetOrigin(trace.endpos);
|
||||
|
||||
velocity = vec_zero;
|
||||
|
||||
UpdateBoneControllers();
|
||||
UpdateFootsteps();
|
||||
if (!GetWeapon(WEAPON_MAIN)) {
|
||||
giveItem("models/weapons/mp40.tik");
|
||||
}
|
||||
|
||||
Unholster();
|
||||
if (m_pTurret && m_pTurret->GetOwner() == this) {
|
||||
m_pTurret->TurretEndUsed();
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_MachineGunner
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::ThinkHoldGun_TurretGun(void)
|
||||
{
|
||||
if (!m_bAnimScriptSet && m_State == 1201)
|
||||
{
|
||||
TransitionState(1200, 0);
|
||||
Unregister(STRING_ANIMDONE);
|
||||
}
|
||||
Vector vForward;
|
||||
vec3_t new_angles;
|
||||
vec3_t offset;
|
||||
vec3_t newOrigin;
|
||||
float right;
|
||||
float heightDiff;
|
||||
float machine_gunner_hands_up_stand;
|
||||
float temp;
|
||||
trace_t trace;
|
||||
Vector end;
|
||||
|
||||
if (m_State != ACTOR_STATE_MACHINE_GUNNER_READY) {
|
||||
DesiredAnimation(ANIM_MODE_FROZEN, STRING_ANIM_MG42_RELOAD_SCR);
|
||||
m_bAnimScriptSet = false;
|
||||
} else if (m_pTurret->IsFiring()) {
|
||||
if (m_pTurret->aim_target == G_GetEntity(0)) {
|
||||
m_bNoSurprise = true;
|
||||
}
|
||||
|
||||
DesiredAnimation(ANIM_MODE_FROZEN, STRING_ANIM_MG42_SHOOT_SCR);
|
||||
} else {
|
||||
DesiredAnimation(ANIM_MODE_FROZEN, STRING_ANIM_MG42_IDLE_SCR);
|
||||
}
|
||||
|
||||
CheckUnregister();
|
||||
StopTurning();
|
||||
|
||||
VectorSet(new_angles, 0, m_pTurret->angles[1], 0);
|
||||
setAngles(new_angles);
|
||||
|
||||
VectorScale(m_pTurret->orientation[0], -39, offset);
|
||||
VectorAdd(m_pTurret->origin, offset, newOrigin);
|
||||
|
||||
if (m_State == ACTOR_STATE_MACHINE_GUNNER_RELOADING) {
|
||||
heightDiff = 71.6f;
|
||||
} else {
|
||||
heightDiff = 71.8f;
|
||||
}
|
||||
|
||||
newOrigin[2] -= heightDiff;
|
||||
machine_gunner_hands_up_stand = origin[2] - newOrigin[2];
|
||||
|
||||
if (machine_gunner_hands_up_stand < 0) {
|
||||
if (m_State == ACTOR_STATE_MACHINE_GUNNER_RELOADING) {
|
||||
m_fCrouchWeight = 0;
|
||||
|
||||
temp = (origin[2] + 71.6f - m_pTurret->origin[2]) / 39.f;
|
||||
if (temp >= -1.0 && temp <= 1.0) {
|
||||
m_pTurret->angles[0] = RAD2DEG(atan(temp / sqrt(temp * -temp + 1)));
|
||||
m_pTurret->setAngles(m_pTurret->angles);
|
||||
}
|
||||
} else {
|
||||
m_fCrouchWeight = machine_gunner_hands_up_stand / 17.1f;
|
||||
if (m_fCrouchWeight < -1.0) {
|
||||
m_fCrouchWeight = -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
VectorScale2D(orientation[0], m_fCrouchWeight * -9.3f + 23.4f, offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
VectorScale2D(orientation[1], m_fCrouchWeight * 2.6f + 10.3f, offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
} else {
|
||||
m_fCrouchWeight = machine_gunner_hands_up_stand / (heightDiff - 38.7f);
|
||||
if (m_fCrouchWeight > 1.0) {
|
||||
m_fCrouchWeight = 1.0;
|
||||
}
|
||||
|
||||
VectorScale2D(orientation[0], m_fCrouchWeight * -3.f + 23.4f, offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
VectorScale2D(orientation[1], m_fCrouchWeight * -1.6f + 10.3f, offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
}
|
||||
|
||||
if (m_fCrouchWeight >= 0.5) {
|
||||
m_csCurrentPosition = STRING_CROUCH;
|
||||
} else {
|
||||
m_csCurrentPosition = STRING_STAND;
|
||||
}
|
||||
|
||||
UpdateAimMotion();
|
||||
UpdateAnim();
|
||||
|
||||
end[0] = newOrigin[0];
|
||||
end[1] = newOrigin[1];
|
||||
end[2] = newOrigin[2] - 94;
|
||||
trace = G_Trace(newOrigin, MINS, MAXS, end, this, MASK_PATHSOLID, qfalse, "Actor::ThinkHoldGun_TurretGun");
|
||||
|
||||
if (trace.fraction != 1.0 && !trace.startsolid && !trace.allsolid && trace.ent) {
|
||||
SafeSetOrigin(trace.endpos);
|
||||
}
|
||||
|
||||
VectorClear(velocity);
|
||||
UpdateBoneControllers();
|
||||
UpdateFootsteps();
|
||||
}
|
||||
|
||||
bool Actor::MachineGunner_CanSee
|
||||
(
|
||||
Entity *ent,
|
||||
float fov,
|
||||
float vision_distance
|
||||
)
|
||||
void Actor::Think_MachineGunner_TurretGun(void)
|
||||
{
|
||||
float delta[2];
|
||||
if (!m_bEnableEnemy) {
|
||||
ThinkHoldGun_TurretGun();
|
||||
return;
|
||||
}
|
||||
|
||||
delta[0] = ent->centroid[0] - centroid[0];
|
||||
delta[1] = ent->centroid[1] - centroid[1];
|
||||
if ((vision_distance <= 0.0f) || (delta[0] * delta[0] + delta[1] * delta[1]) <= (vision_distance * vision_distance))
|
||||
{
|
||||
if (gi.AreasConnected(edict->r.areanum, ent->edict->r.areanum) &&
|
||||
((fov <= 0.0f || fov >= 360.0f) ||
|
||||
(FovCheck(delta, cos(fov * (0.5 * M_PI / 180.0))))))
|
||||
{
|
||||
return G_SightTrace(centroid,
|
||||
vec_zero,
|
||||
vec_zero,
|
||||
ent->centroid,
|
||||
m_pTurret,
|
||||
ent,
|
||||
MASK_CANSEE,
|
||||
0,
|
||||
"Actor::MachineGunner_CanSee");
|
||||
}
|
||||
}
|
||||
if (level.inttime < m_iEnemyCheckTime + 200) {
|
||||
ThinkHoldGun_TurretGun();
|
||||
return;
|
||||
}
|
||||
|
||||
return false;
|
||||
UpdateEnemyInternal();
|
||||
|
||||
if (m_pTurret->AI_CanTarget(G_GetEntity(0)->centroid)) {
|
||||
ThinkHoldGun_TurretGun();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pGrenade && rand() / 21474836.f <= m_fGrenadeAwareness) {
|
||||
BecomeTurretGuy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!G_SightTrace(
|
||||
EyePosition(),
|
||||
vec_zero,
|
||||
vec_zero,
|
||||
static_cast<Sentient *>(G_GetEntity(0))->EyePosition(),
|
||||
this,
|
||||
G_GetEntity(0),
|
||||
MASK_CANSEE,
|
||||
qfalse,
|
||||
"Actor::Think_MachineGunner"
|
||||
)) {
|
||||
ThinkHoldGun_TurretGun();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ThinkStates[THINKLEVEL_IDLE] != THINKSTATE_IDLE) {
|
||||
BecomeTurretGuy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Enemy && !(m_Enemy->flags & FL_NOTARGET) && !EnemyIsDisguised() && m_PotentialEnemies.IsEnemyConfirmed()) {
|
||||
BecomeTurretGuy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Enemy && m_iCuriousTime || (m_Enemy && !EnemyIsDisguised() && !m_PotentialEnemies.IsEnemyConfirmed())) {
|
||||
m_iCuriousAnimHint = 6;
|
||||
BecomeTurretGuy();
|
||||
return;
|
||||
}
|
||||
|
||||
ThinkHoldGun_TurretGun();
|
||||
}
|
||||
|
||||
void Actor::Think_MachineGunner(void)
|
||||
{
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pTurret && m_pTurret->GetOwner() == this && !m_bNoPlayerCollision) {
|
||||
UpdateEyeOrigin();
|
||||
Think_MachineGunner_TurretGun();
|
||||
} else {
|
||||
BecomeTurretGuy();
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_MachineGunner(void)
|
||||
{
|
||||
if (!m_bAnimScriptSet && m_State == ACTOR_STATE_MACHINE_GUNNER_RELOADING) {
|
||||
TransitionState(ACTOR_STATE_MACHINE_GUNNER_READY, 0);
|
||||
Unregister(STRING_ANIMDONE);
|
||||
}
|
||||
}
|
||||
|
||||
bool Actor::MachineGunner_CanSee(Entity *ent, float fov, float vision_distance)
|
||||
{
|
||||
float delta[2];
|
||||
|
||||
delta[0] = ent->centroid[0] - centroid[0];
|
||||
delta[1] = ent->centroid[1] - centroid[1];
|
||||
if ((vision_distance <= 0.0f)
|
||||
|| (delta[0] * delta[0] + delta[1] * delta[1]) <= (vision_distance * vision_distance)) {
|
||||
if (gi.AreasConnected(edict->r.areanum, ent->edict->r.areanum)
|
||||
&& ((fov <= 0.0f || fov >= 360.0f) || (FovCheck(delta, cos(fov * (0.5 * M_PI / 180.0)))))) {
|
||||
return G_SightTrace(
|
||||
centroid,
|
||||
vec_zero,
|
||||
vec_zero,
|
||||
ent->centroid,
|
||||
m_pTurret,
|
||||
ent,
|
||||
MASK_CANSEE,
|
||||
0,
|
||||
"Actor::MachineGunner_CanSee"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
+55
-80
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,87 +24,62 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitNoClip
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitNoClip(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_NoClip;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
func->ThinkState = &Actor::Think_NoClip;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
}
|
||||
|
||||
bool Actor::IsNoClipState
|
||||
(
|
||||
int state
|
||||
)
|
||||
void Actor::Think_NoClip(void)
|
||||
{
|
||||
return state == THINKSTATE_NOCLIP;
|
||||
}
|
||||
|
||||
void Actor::Think_NoClip
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
//FIXME: not sure of naming
|
||||
bool done = false;
|
||||
Vector newOrigin = vec_zero;
|
||||
Vector total_offset;
|
||||
Vector total_offset_unit;
|
||||
float total_dist;
|
||||
//vec3_t frame_offset;
|
||||
float frame_dist;
|
||||
|
||||
m_pszDebugState = "";
|
||||
|
||||
ContinueAnimationAllowNoPath();
|
||||
|
||||
CheckUnregister();
|
||||
UpdateAngles();
|
||||
UpdateAnim();
|
||||
|
||||
total_offset = m_NoClipDest - origin;
|
||||
total_dist = VectorNormalize2(total_offset, total_offset_unit);
|
||||
|
||||
frame_dist = level.frametime * m_maxspeed;
|
||||
|
||||
if (frame_dist >= frame_delta.lengthSquared())
|
||||
{
|
||||
frame_dist = frame_delta.lengthSquared();
|
||||
}
|
||||
|
||||
if (frame_dist < total_dist)
|
||||
{
|
||||
newOrigin = total_offset_unit * frame_dist + origin;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
done = true;
|
||||
newOrigin = m_NoClipDest;
|
||||
}
|
||||
|
||||
SafeSetOrigin(newOrigin);
|
||||
|
||||
velocity = total_offset_unit / level.frametime;
|
||||
|
||||
if (velocity.lengthSquared() < 1)
|
||||
{
|
||||
done = true;
|
||||
velocity = vec_zero;
|
||||
}
|
||||
groundentity = NULL;
|
||||
|
||||
if (done)
|
||||
{
|
||||
Com_Printf(
|
||||
"(entnum %d, radnum %d) failsafe finished\n",
|
||||
entnum,
|
||||
radnum);
|
||||
EndCurrentThinkState();
|
||||
}
|
||||
|
||||
UpdateBoneControllers();
|
||||
UpdateFootsteps();
|
||||
|
||||
float frame_dist;
|
||||
vec3_t frame_offset;
|
||||
float total_dist;
|
||||
vec3_t total_offset;
|
||||
Vector newOrigin;
|
||||
bool done = false;
|
||||
|
||||
m_pszDebugState = "";
|
||||
|
||||
ContinueAnimationAllowNoPath();
|
||||
|
||||
CheckUnregister();
|
||||
UpdateAngles();
|
||||
UpdateAnim();
|
||||
|
||||
VectorSubtract(m_NoClipDest, origin, total_offset);
|
||||
total_dist = VectorNormalize2(total_offset, frame_offset);
|
||||
frame_dist = VectorLength(frame_delta);
|
||||
|
||||
if (frame_dist > m_maxspeed * level.frametime) {
|
||||
frame_dist = m_maxspeed * level.frametime;
|
||||
}
|
||||
|
||||
if (frame_dist < total_dist) {
|
||||
VectorScale(frame_offset, frame_dist, frame_offset);
|
||||
VectorAdd(origin, frame_offset, newOrigin);
|
||||
} else {
|
||||
VectorCopy(m_NoClipDest, newOrigin);
|
||||
done = true;
|
||||
}
|
||||
|
||||
SafeSetOrigin(newOrigin);
|
||||
|
||||
velocity[0] = frame_offset[0] / level.frametime;
|
||||
velocity[1] = frame_offset[1] / level.frametime;
|
||||
velocity[2] = frame_offset[2] / level.frametime;
|
||||
|
||||
if (VectorLengthSquared(velocity) < 1) {
|
||||
VectorClear(velocity);
|
||||
done = true;
|
||||
}
|
||||
groundentity = NULL;
|
||||
|
||||
if (done) {
|
||||
Com_Printf("(entnum %d, radnum %d) failsafe finished\n", entnum, radnum);
|
||||
EndCurrentThinkState();
|
||||
}
|
||||
|
||||
UpdateBoneControllers();
|
||||
UpdateFootsteps();
|
||||
}
|
||||
+25
-40
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,55 +24,40 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitPain
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitPain(GlobalFuncs_t *func)
|
||||
{
|
||||
func->BeginState = &Actor::Begin_Pain;
|
||||
func->ThinkState = &Actor::Think_Pain;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Pain;
|
||||
func->IsState = &Actor::IsPainState;
|
||||
func->BeginState = &Actor::Begin_Pain;
|
||||
func->ThinkState = &Actor::Think_Pain;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Pain;
|
||||
func->IsState = &Actor::IsPainState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Pain
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Pain(void)
|
||||
{
|
||||
m_PainState = 500;
|
||||
m_PainState = ACTOR_STATE_PAIN_INITIAL;
|
||||
}
|
||||
|
||||
void Actor::Think_Pain
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_Pain(void)
|
||||
{
|
||||
NoPoint();
|
||||
NoPoint();
|
||||
ForwardLook();
|
||||
UpdateEyeOrigin();
|
||||
|
||||
m_bHasDesiredLookAngles = false;
|
||||
if (m_PainState == ACTOR_STATE_PAIN_INITIAL) {
|
||||
m_pszDebugState = "initial";
|
||||
Anim_StartPain();
|
||||
m_PainState = ACTOR_STATE_PAIN_MAIN;
|
||||
} else if (m_PainState == ACTOR_STATE_PAIN_MAIN) {
|
||||
m_pszDebugState = "main";
|
||||
Anim_Pain();
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
|
||||
if (m_PainState == 500)
|
||||
{
|
||||
m_pszDebugState = "initial";
|
||||
Anim_StartPain();
|
||||
m_PainState = 501;
|
||||
}
|
||||
else if (m_PainState == 501)
|
||||
{
|
||||
m_pszDebugState = "main";
|
||||
Anim_Pain();
|
||||
}
|
||||
PostThink(false);
|
||||
PostThink(false);
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_Pain
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::FinishedAnimation_Pain(void)
|
||||
{
|
||||
if (m_PainState != 500)
|
||||
EndCurrentThinkState();
|
||||
if (m_PainState != ACTOR_STATE_PAIN_START) {
|
||||
EndCurrentThinkState();
|
||||
}
|
||||
}
|
||||
+56
-76
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,92 +24,72 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitPatrol
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitPatrol(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_Patrol;
|
||||
func->BeginState = &Actor::Begin_Patrol;
|
||||
func->EndState = &Actor::End_Patrol;
|
||||
func->ResumeState = &Actor::Resume_Patrol;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->ShowInfo = &Actor::ShowInfo_Patrol;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
func->ThinkState = &Actor::Think_Patrol;
|
||||
func->BeginState = &Actor::Begin_Patrol;
|
||||
func->EndState = &Actor::End_Patrol;
|
||||
func->ResumeState = &Actor::Resume_Patrol;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->ShowInfo = &Actor::ShowInfo_Patrol;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Patrol
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Patrol(void)
|
||||
{
|
||||
m_csMood = STRING_BORED;
|
||||
StopTurning();
|
||||
ClearPath();
|
||||
m_csMood = STRING_BORED;
|
||||
StopTurning();
|
||||
ClearPath();
|
||||
}
|
||||
|
||||
void Actor::End_Patrol
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_Patrol(void)
|
||||
{
|
||||
|
||||
parm.movefail = true;
|
||||
parm.movefail = true;
|
||||
}
|
||||
|
||||
void Actor::Resume_Patrol
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Resume_Patrol(void) {}
|
||||
|
||||
void Actor::Think_Patrol(void)
|
||||
{
|
||||
;
|
||||
bool bMoveInRadius;
|
||||
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
parm.movefail = false;
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
|
||||
m_pszDebugState = "";
|
||||
m_csPatrolCurrentAnim = STRING_ANIM_PATROL_SCR;
|
||||
bMoveInRadius = MoveToPatrolCurrentNode();
|
||||
|
||||
if (m_fLookAroundFov > 1.0) {
|
||||
LookAround(m_fLookAroundFov);
|
||||
}
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
|
||||
if (!m_patrolCurrentNode) {
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
m_bScriptGoalValid = false;
|
||||
|
||||
parm.movedone = true;
|
||||
Unregister(STRING_MOVEDONE);
|
||||
} else if (bMoveInRadius) {
|
||||
ClearPatrolCurrentNode();
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
|
||||
parm.movedone = true;
|
||||
Unregister(STRING_MOVEDONE);
|
||||
}
|
||||
|
||||
PostThink(true);
|
||||
}
|
||||
|
||||
void Actor::Think_Patrol
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::ShowInfo_Patrol(void)
|
||||
{
|
||||
if (Actor::RequireThink())
|
||||
{
|
||||
parm.movefail = false;
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
|
||||
m_pszDebugState = "";
|
||||
m_csPatrolCurrentAnim = STRING_ANIM_PATROL_SCR;
|
||||
|
||||
if (m_fLookAroundFov > 1.0)
|
||||
LookAround(m_fLookAroundFov);
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
if (m_patrolCurrentNode)
|
||||
{
|
||||
if (!MoveToPatrolCurrentNode())
|
||||
{
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
m_bScriptGoalValid = false;
|
||||
}
|
||||
parm.movedone = true;
|
||||
|
||||
Unregister(STRING_MOVEDONE);
|
||||
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::ShowInfo_Patrol
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
ShowInfo_PatrolCurrentNode();
|
||||
ShowInfo_PatrolCurrentNode();
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// actor_runandshoot.cpp
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitRunAndShoot(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_RunAndShoot;
|
||||
func->BeginState = &Actor::Begin_RunAndShoot;
|
||||
func->EndState = &Actor::End_RunAndShoot;
|
||||
func->ResumeState = &Actor::Resume_RunAndShoot;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack;
|
||||
func->ShowInfo = &Actor::ShowInfo_RunAndShoot;
|
||||
func->IsState = &Actor::IsAttackState;
|
||||
}
|
||||
|
||||
void Actor::Begin_RunAndShoot(void)
|
||||
{
|
||||
m_State = ACTOR_STATE_RUN_AND_SHOOT_RUN;
|
||||
if (m_patrolCurrentNode) {
|
||||
m_State = ACTOR_STATE_RUN_AND_SHOOT_RUNNING;
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::End_RunAndShoot(void)
|
||||
{
|
||||
m_vHome = origin;
|
||||
m_pTetherEnt = NULL;
|
||||
}
|
||||
|
||||
void Actor::Resume_RunAndShoot(void) {}
|
||||
|
||||
void Actor::Think_RunAndShoot(void)
|
||||
{
|
||||
if (m_State == ACTOR_STATE_RUN_AND_SHOOT_RUNNING) {
|
||||
State_RunAndShoot_Running();
|
||||
} else if (m_State == ACTOR_STATE_RUN_AND_SHOOT_RUN) {
|
||||
SetThink(THINKSTATE_ATTACK, THINK_COVER);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::ShowInfo_RunAndShoot(void) {}
|
||||
|
||||
void Actor::State_RunAndShoot_Running(void)
|
||||
{
|
||||
Entity *player;
|
||||
bool bMoveDone;
|
||||
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
parm.movefail = false;
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
|
||||
m_pszDebugState = "";
|
||||
bMoveDone = RunAndShoot_MoveToPatrolCurrentNode();
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
player = G_GetEntity(0);
|
||||
if (player) {
|
||||
vec2_t delta;
|
||||
|
||||
VectorSub2D(player->origin, origin, delta);
|
||||
|
||||
if (VectorLength2DSquared(delta) < Square(150)) {
|
||||
ClearPatrolCurrentNode();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_patrolCurrentNode) {
|
||||
if (m_Enemy) {
|
||||
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
|
||||
} else {
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
}
|
||||
|
||||
m_bScriptGoalValid = false;
|
||||
parm.movedone = true;
|
||||
|
||||
Unregister(STRING_MOVEDONE);
|
||||
} else if (bMoveDone) {
|
||||
ClearPatrolCurrentNode();
|
||||
|
||||
if (m_Enemy) {
|
||||
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
|
||||
} else {
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
}
|
||||
|
||||
parm.movedone = true;
|
||||
|
||||
Unregister(STRING_MOVEDONE);
|
||||
}
|
||||
|
||||
Unregister(STRING_MOVE);
|
||||
|
||||
CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_IDLE);
|
||||
PostThink(true);
|
||||
}
|
||||
|
||||
bool Actor::RunAndShoot_MoveToPatrolCurrentNode(void)
|
||||
{
|
||||
UpdatePatrolCurrentNode();
|
||||
|
||||
if (!m_patrolCurrentNode && m_bPatrolWaitTrigger) {
|
||||
IdleLook();
|
||||
Anim_Idle();
|
||||
return false;
|
||||
}
|
||||
|
||||
SetPath(m_patrolCurrentNode->origin, "Actor::RunAndShoot_MoveToPatrolCurrentNode", 0, NULL, 0);
|
||||
|
||||
if (!PathExists()) {
|
||||
IdleLook();
|
||||
Anim_Idle();
|
||||
|
||||
parm.movefail = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MoveOnPathWithSquad()) {
|
||||
if (m_Enemy) {
|
||||
m_eNextAnimMode = ANIM_MODE_PATH;
|
||||
m_csNextAnimString = STRING_ANIM_RUNTO_INOPEN_SCR;
|
||||
m_bNextForceStart = false;
|
||||
|
||||
Vector delta;
|
||||
Vector lookDir;
|
||||
|
||||
delta = mTargetPos - EyePosition();
|
||||
lookDir = delta;
|
||||
lookDir[2] += 16;
|
||||
SetDesiredLookDir(lookDir);
|
||||
|
||||
m_DesiredGunDir[0] = 360 - delta.toPitch();
|
||||
m_DesiredGunDir[1] = delta.toYaw();
|
||||
m_DesiredGunDir[2] = 0;
|
||||
SetDesiredYaw(m_DesiredGunDir[1]);
|
||||
} else {
|
||||
m_eNextAnimMode = ANIM_MODE_PATH;
|
||||
m_csNextAnimString = STRING_ANIM_CROUCH_RUN_SCR;
|
||||
m_bNextForceStart = false;
|
||||
FaceMotion();
|
||||
}
|
||||
} else if (m_Enemy) {
|
||||
Vector delta;
|
||||
Vector lookDir;
|
||||
|
||||
delta = mTargetPos - EyePosition();
|
||||
lookDir = delta;
|
||||
lookDir[2] += 16;
|
||||
SetDesiredLookDir(lookDir);
|
||||
|
||||
m_DesiredGunDir[0] = 360 - delta.toPitch();
|
||||
m_DesiredGunDir[1] = delta.toYaw();
|
||||
m_DesiredGunDir[2] = 0;
|
||||
SetDesiredYaw(m_DesiredGunDir[1]);
|
||||
Anim_Attack();
|
||||
} else {
|
||||
Anim_Stand();
|
||||
IdleLook();
|
||||
}
|
||||
|
||||
if (!m_fMoveDoneRadiusSquared) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PathComplete()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m_Path.HasCompleteLookahead() || m_patrolCurrentNode->Next()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (VectorLength2DSquared(PathDelta()) > m_fMoveDoneRadiusSquared) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
+53
-74
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,90 +24,69 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitRunner
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitRunner(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_Runner;
|
||||
func->BeginState = &Actor::Begin_Runner;
|
||||
func->EndState = &Actor::End_Runner;
|
||||
func->ResumeState = &Actor::Resume_Runner;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->ShowInfo = &Actor::ShowInfo_Runner;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
func->ThinkState = &Actor::Think_Runner;
|
||||
func->BeginState = &Actor::Begin_Runner;
|
||||
func->EndState = &Actor::End_Runner;
|
||||
func->ResumeState = &Actor::Resume_Runner;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle;
|
||||
func->ShowInfo = &Actor::ShowInfo_Runner;
|
||||
func->IsState = &Actor::IsIdleState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Runner
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Runner(void)
|
||||
{
|
||||
m_csMood = STRING_NERVOUS;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
StopTurning();
|
||||
ClearPath();
|
||||
m_csMood = STRING_NERVOUS;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
StopTurning();
|
||||
ClearPath();
|
||||
}
|
||||
|
||||
void Actor::End_Runner
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::End_Runner(void)
|
||||
{
|
||||
parm.movefail = true;
|
||||
parm.movefail = true;
|
||||
}
|
||||
|
||||
void Actor::Resume_Runner
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Resume_Runner(void) {}
|
||||
|
||||
void Actor::Think_Runner(void)
|
||||
{
|
||||
;
|
||||
bool bMoveInRadius;
|
||||
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
parm.movefail = false;
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
m_pszDebugState = "";
|
||||
|
||||
bMoveInRadius = MoveToPatrolCurrentNode();
|
||||
CheckForThinkStateTransition();
|
||||
|
||||
if (!m_patrolCurrentNode) {
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
m_bScriptGoalValid = false;
|
||||
|
||||
parm.movedone = true;
|
||||
Unregister(STRING_MOVEDONE);
|
||||
} else if (bMoveInRadius) {
|
||||
ClearPatrolCurrentNode();
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
|
||||
parm.movedone = true;
|
||||
Unregister(STRING_MOVEDONE);
|
||||
}
|
||||
|
||||
Unregister(STRING_MOVE);
|
||||
|
||||
PostThink(true);
|
||||
}
|
||||
|
||||
void Actor::Think_Runner
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::ShowInfo_Runner(void)
|
||||
{
|
||||
if (RequireThink())
|
||||
{
|
||||
parm.movefail = false;
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
m_pszDebugState = "";
|
||||
|
||||
CheckForThinkStateTransition();
|
||||
|
||||
if (m_patrolCurrentNode)
|
||||
{
|
||||
if (!MoveToPatrolCurrentNode())
|
||||
{
|
||||
Unregister(STRING_MOVE);
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThinkIdle(THINK_IDLE);
|
||||
m_bScriptGoalValid = false;
|
||||
}
|
||||
|
||||
parm.movedone = true;
|
||||
Unregister(STRING_MOVEDONE);
|
||||
|
||||
Unregister(STRING_MOVE);
|
||||
PostThink(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::ShowInfo_Runner
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
ShowInfo_PatrolCurrentNode();
|
||||
ShowInfo_PatrolCurrentNode();
|
||||
}
|
||||
+836
-1093
File diff suppressed because it is too large.
Load diff
+100
-140
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,168 +24,128 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "actor.h"
|
||||
|
||||
void Actor::InitWeaponless
|
||||
(
|
||||
GlobalFuncs_t *func
|
||||
)
|
||||
void Actor::InitWeaponless(GlobalFuncs_t *func)
|
||||
{
|
||||
func->ThinkState = &Actor::Think_Weaponless;
|
||||
func->BeginState = &Actor::Begin_Weaponless;
|
||||
func->SuspendState = &Actor::Suspend_Weaponless;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Weaponless;
|
||||
func->IsState = &Actor::IsAttackState;
|
||||
func->ThinkState = &Actor::Think_Weaponless;
|
||||
func->BeginState = &Actor::Begin_Weaponless;
|
||||
func->SuspendState = &Actor::Suspend_Weaponless;
|
||||
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack;
|
||||
func->FinishedAnimation = &Actor::FinishedAnimation_Weaponless;
|
||||
func->IsState = &Actor::IsAttackState;
|
||||
}
|
||||
|
||||
void Actor::Begin_Weaponless
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Begin_Weaponless(void)
|
||||
{
|
||||
DoForceActivate();
|
||||
|
||||
DoForceActivate();
|
||||
m_csMood = STRING_ALERT;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
|
||||
m_csMood = STRING_ALERT;
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
if (level.inttime < m_iEnemyChangeTime + 200) {
|
||||
SetLeashHome(origin);
|
||||
if (AttackEntryAnimation()) {
|
||||
m_bLockThinkState = true;
|
||||
|
||||
if (level.inttime < m_iEnemyChangeTime + 200)
|
||||
{
|
||||
SetLeashHome(origin);
|
||||
if (AttackEntryAnimation())
|
||||
{
|
||||
m_bLockThinkState = true;
|
||||
|
||||
TransitionState(902, 0);
|
||||
}
|
||||
}
|
||||
TransitionState(900, 0);
|
||||
TransitionState(ACTOR_STATE_WEAPONLESS_LOOP, 0);
|
||||
}
|
||||
}
|
||||
TransitionState(ACTOR_STATE_WEAPONLESS_START, 0);
|
||||
}
|
||||
|
||||
void Actor::Suspend_Weaponless
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Suspend_Weaponless(void)
|
||||
{
|
||||
if (m_State <= 902)
|
||||
{
|
||||
TransitionState(900, 0);
|
||||
}
|
||||
|
||||
if (m_State == ACTOR_STATE_WEAPONLESS_GRENADE || m_State == ACTOR_STATE_WEAPONLESS_LOOP) {
|
||||
TransitionState(ACTOR_STATE_WEAPONLESS_START, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::Think_Weaponless
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Weaponless_Normal(void)
|
||||
{
|
||||
int iStateTime;
|
||||
if (m_bScriptGoalValid) {
|
||||
SetPath(m_vScriptGoal, NULL, 0, NULL, 0);
|
||||
}
|
||||
|
||||
if (RequireThink())
|
||||
{
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
UpdateEnemy(500);
|
||||
if (PathExists() && !PathComplete()) {
|
||||
FaceMotion();
|
||||
Anim_RunToDanger(ANIM_MODE_PATH_GOAL);
|
||||
return;
|
||||
}
|
||||
|
||||
m_bScriptGoalValid = false;
|
||||
|
||||
if (m_State == 902)
|
||||
{
|
||||
ContinueAnimation();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bLockThinkState = false;
|
||||
if (!m_Enemy)
|
||||
{
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
|
||||
IdleThink();
|
||||
return;
|
||||
}
|
||||
if (m_State == 900)
|
||||
{
|
||||
State_Weaponless_Normal();
|
||||
}
|
||||
else if (m_State == 901)
|
||||
{
|
||||
State_Weaponless_Grenade();
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf("Think_Weaponless: invalid think state %i\n", m_State);
|
||||
char assertStr[16317] = { 0 };
|
||||
strcpy(assertStr, "\"invalid think state\"\n\tMessage: ");
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("thinkstate = %i", m_State));
|
||||
assert(!assertStr);
|
||||
}
|
||||
CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_NORMAL);
|
||||
}
|
||||
PostThink(true);
|
||||
if (GetWeapon(WEAPON_MAIN))
|
||||
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
|
||||
}
|
||||
AimAtTargetPos();
|
||||
Anim_Stand();
|
||||
|
||||
if (level.inttime < m_iStateTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (DecideToThrowGrenade(m_Enemy->origin + m_Enemy->velocity, &m_vGrenadeVel, &m_eGrenadeMode, false)) {
|
||||
SetDesiredYawDir(m_vGrenadeVel);
|
||||
DesiredAnimation(
|
||||
ANIM_MODE_NORMAL,
|
||||
m_eGrenadeMode == AI_GREN_TOSS_ROLL ? STRING_ANIM_GRENADETOSS_SCR : STRING_ANIM_GRENADETHROW_SCR
|
||||
);
|
||||
TransitionState(ACTOR_STATE_WEAPONLESS_GRENADE);
|
||||
} else {
|
||||
TransitionState(ACTOR_STATE_WEAPONLESS_START, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::FinishedAnimation_Weaponless
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::Think_Weaponless(void)
|
||||
{
|
||||
if (m_State <= 902)
|
||||
{
|
||||
TransitionState(900, 4000);
|
||||
}
|
||||
if (!RequireThink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEyeOrigin();
|
||||
NoPoint();
|
||||
UpdateEnemy(500);
|
||||
|
||||
if (m_State == ACTOR_STATE_WEAPONLESS_LOOP) {
|
||||
ContinueAnimation();
|
||||
} else {
|
||||
m_bLockThinkState = false;
|
||||
|
||||
if (!m_Enemy) {
|
||||
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_IDLE);
|
||||
IdleThink();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_State == ACTOR_STATE_WEAPONLESS_START) {
|
||||
State_Weaponless_Normal();
|
||||
} else if (m_State == ACTOR_STATE_WEAPONLESS_GRENADE) {
|
||||
State_Weaponless_Grenade();
|
||||
} else {
|
||||
Com_Printf("Think_Weaponless: invalid think state %i\n", m_State);
|
||||
char assertStr[16317] = {0};
|
||||
strcpy(assertStr, "\"invalid think state\"\n\tMessage: ");
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("thinkstate = %i", m_State));
|
||||
assert(!assertStr);
|
||||
}
|
||||
|
||||
if (!CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_IDLE)) {
|
||||
CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
PostThink(true);
|
||||
|
||||
if (GetWeapon(WEAPON_MAIN)) {
|
||||
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::State_Weaponless_Normal
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::FinishedAnimation_Weaponless(void)
|
||||
{
|
||||
int iStateTime;
|
||||
if (m_bScriptGoalValid)
|
||||
SetPath(
|
||||
m_vScriptGoal,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
if (PathExists() && !PathComplete())
|
||||
{
|
||||
FaceMotion();
|
||||
Anim_RunToDanger(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bScriptGoalValid = false;
|
||||
|
||||
AimAtTargetPos();
|
||||
|
||||
Anim_Stand();
|
||||
if (level.inttime >= m_iStateTime)
|
||||
{
|
||||
if (DecideToThrowGrenade(m_Enemy->velocity + m_Enemy->origin, &m_vGrenadeVel, &m_eGrenadeMode))
|
||||
{
|
||||
SetDesiredYawDir(m_vGrenadeVel);
|
||||
|
||||
m_State = 901;
|
||||
m_eNextAnimMode = 1;
|
||||
m_bNextForceStart = false;
|
||||
m_csNextAnimString = (m_eGrenadeMode == AI_GREN_TOSS_ROLL) ? STRING_ANIM_GRENADETOSS_SCR : STRING_ANIM_GRENADETHROW_SCR;
|
||||
iStateTime = level.inttime;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_State = 900;
|
||||
iStateTime = level.inttime + 1000;
|
||||
}
|
||||
m_iStateTime = iStateTime;
|
||||
}
|
||||
}
|
||||
if (m_State == ACTOR_STATE_WEAPONLESS_GRENADE || m_State == ACTOR_STATE_WEAPONLESS_LOOP) {
|
||||
TransitionState(ACTOR_STATE_WEAPONLESS_NORMAL, 4000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Actor::State_Weaponless_Grenade
|
||||
(
|
||||
void
|
||||
)
|
||||
void Actor::State_Weaponless_Grenade(void)
|
||||
{
|
||||
GenericGrenadeTossThink();
|
||||
GenericGrenadeTossThink();
|
||||
}
|
||||
+479
-633
File diff suppressed because it is too large.
Load diff
+103
-71
@@ -22,8 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
// actorenemy.h
|
||||
|
||||
#ifndef __ACTORENEMY_H__
|
||||
#define __ACTORENEMY_H__
|
||||
#pragma once
|
||||
|
||||
#include "g_local.h"
|
||||
#include "class.h"
|
||||
@@ -32,92 +31,125 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
class Actor;
|
||||
class Sentient;
|
||||
|
||||
class ActorEnemy : public Class {
|
||||
class ActorEnemy : public Class
|
||||
{
|
||||
public:
|
||||
int m_iAddTime;
|
||||
float m_fLastLookTime;
|
||||
float m_fVisibility;
|
||||
float m_fTotalVisibility;
|
||||
int m_iThreat;
|
||||
SafePtr<Sentient> m_pEnemy;
|
||||
float m_fCurrentRangeSquared;
|
||||
Vector m_vLastKnownPos;
|
||||
int m_iLastSightChangeTime;
|
||||
bool m_bVisible;
|
||||
int m_iAddTime;
|
||||
int m_iNextEnemyTime; // Added in 2.0
|
||||
float m_fLastLookTime;
|
||||
float m_fVisibility;
|
||||
float m_fTotalVisibility;
|
||||
int m_iThreat;
|
||||
SafePtr<Sentient> m_pEnemy;
|
||||
float m_fCurrentRangeSquared;
|
||||
Vector m_vLastKnownPos;
|
||||
int m_iLastSightChangeTime;
|
||||
bool m_bVisible;
|
||||
|
||||
ActorEnemy();
|
||||
virtual ~ActorEnemy();
|
||||
float UpdateVisibility( Actor *pSelf, bool *pbInFovAndRange, bool *pbVisible );
|
||||
int UpdateThreat( Actor *pSelf );
|
||||
Sentient *GetEnemy( void ) const;
|
||||
float GetVisibility( void ) const;
|
||||
int GetThreat( void ) const;
|
||||
float GetRangeSquared( void ) const;
|
||||
float UpdateVisibility(Actor *pSelf, bool *pbInFovAndRange, bool *pbVisible);
|
||||
int UpdateThreat(Actor *pSelf);
|
||||
Sentient *GetEnemy(void) const;
|
||||
float GetVisibility(void) const;
|
||||
int GetThreat(void) const;
|
||||
float GetRangeSquared(void) const;
|
||||
|
||||
void Archive( Archiver & ) override;
|
||||
void Archive(Archiver&) override;
|
||||
|
||||
protected:
|
||||
float UpdateLMRF( Actor *pSelf, bool *pbInFovAndRange, bool *pbVisible );
|
||||
float UpdateLMRF(Actor *pSelf, bool *pbInFovAndRange, bool *pbVisible);
|
||||
};
|
||||
|
||||
inline void ActorEnemy::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline void ActorEnemy::Archive(Archiver& arc)
|
||||
{
|
||||
Class::Archive( arc );
|
||||
Class::Archive(arc);
|
||||
|
||||
arc.ArchiveInteger( &m_iAddTime );
|
||||
arc.ArchiveFloat( &m_fLastLookTime );
|
||||
arc.ArchiveFloat( &m_fVisibility );
|
||||
arc.ArchiveFloat( &m_fTotalVisibility );
|
||||
arc.ArchiveInteger( &m_iThreat );
|
||||
arc.ArchiveSafePointer( &m_pEnemy );
|
||||
arc.ArchiveFloat( &m_fCurrentRangeSquared );
|
||||
arc.ArchiveVector( &m_vLastKnownPos );
|
||||
arc.ArchiveInteger( &m_iLastSightChangeTime );
|
||||
arc.ArchiveBool( &m_bVisible );
|
||||
arc.ArchiveInteger(&m_iAddTime);
|
||||
arc.ArchiveFloat(&m_fLastLookTime);
|
||||
arc.ArchiveFloat(&m_fVisibility);
|
||||
arc.ArchiveFloat(&m_fTotalVisibility);
|
||||
arc.ArchiveInteger(&m_iThreat);
|
||||
arc.ArchiveSafePointer(&m_pEnemy);
|
||||
arc.ArchiveFloat(&m_fCurrentRangeSquared);
|
||||
arc.ArchiveVector(&m_vLastKnownPos);
|
||||
arc.ArchiveInteger(&m_iLastSightChangeTime);
|
||||
arc.ArchiveBool(&m_bVisible);
|
||||
}
|
||||
|
||||
class ActorEnemySet : public Class {
|
||||
inline Sentient *ActorEnemy::GetEnemy(void) const
|
||||
{
|
||||
return m_pEnemy;
|
||||
}
|
||||
|
||||
inline float ActorEnemy::GetVisibility(void) const
|
||||
{
|
||||
return m_fVisibility;
|
||||
}
|
||||
|
||||
inline int ActorEnemy::GetThreat(void) const
|
||||
{
|
||||
return m_iThreat;
|
||||
}
|
||||
|
||||
inline float ActorEnemy::GetRangeSquared(void) const
|
||||
{
|
||||
return m_fCurrentRangeSquared;
|
||||
}
|
||||
|
||||
class ActorEnemySet : public Class
|
||||
{
|
||||
protected:
|
||||
Container<ActorEnemy> m_Enemies;
|
||||
int m_iCheckCount;
|
||||
SafePtr<Sentient> m_pCurrentEnemy;
|
||||
float m_fCurrentVisibility;
|
||||
int m_iCurrentThreat;
|
||||
Container<ActorEnemy> m_Enemies;
|
||||
int m_iCheckCount;
|
||||
SafePtr<Sentient> m_pCurrentEnemy;
|
||||
float m_fCurrentVisibility;
|
||||
int m_iCurrentThreat;
|
||||
|
||||
public:
|
||||
ActorEnemySet();
|
||||
virtual ~ActorEnemySet();
|
||||
ActorEnemySet();
|
||||
|
||||
ActorEnemy *AddPotentialEnemy( Sentient *pEnemy );
|
||||
void FlagBadEnemy( Sentient *pEnemy );
|
||||
void CheckEnemies( Actor *pSelf );
|
||||
Sentient *GetCurrentEnemy( void ) const;
|
||||
float GetCurrentVisibility( void ) const;
|
||||
int GetCurrentThreat( void ) const;
|
||||
qboolean IsEnemyConfirmed( void ) const;
|
||||
bool HasAlternateEnemy( void ) const;
|
||||
void RemoveAll( void );
|
||||
void ConfirmEnemy( Actor *pSelf, Sentient *pEnemy );
|
||||
void ConfirmEnemyIfCanSeeSharerOrEnemy( Actor *pSelf, Actor *pSharer, Sentient *pEnemy );
|
||||
bool CaresAboutPerfectInfo( Sentient *pEnemy );
|
||||
ActorEnemy *AddPotentialEnemy(Sentient *pEnemy);
|
||||
void FlagBadEnemy(Sentient *pEnemy);
|
||||
void CheckEnemies(Actor *pSelf);
|
||||
Sentient *GetCurrentEnemy(void) const;
|
||||
float GetCurrentVisibility(void) const;
|
||||
int GetCurrentThreat(void) const;
|
||||
qboolean IsEnemyConfirmed(void) const;
|
||||
bool HasAlternateEnemy(void) const;
|
||||
void RemoveAll(void);
|
||||
void ConfirmEnemy(Actor *pSelf, Sentient *pEnemy);
|
||||
void ConfirmEnemyIfCanSeeSharerOrEnemy(Actor *pSelf, Actor *pSharer, Sentient *pEnemy);
|
||||
bool CaresAboutPerfectInfo(Sentient *pEnemy);
|
||||
|
||||
void Archive( Archiver& arc ) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline void ActorEnemySet::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline Sentient *ActorEnemySet::GetCurrentEnemy(void) const
|
||||
{
|
||||
Class::Archive( arc );
|
||||
|
||||
m_Enemies.Archive( arc, ArchiveClass< ActorEnemy > );
|
||||
arc.ArchiveInteger( &m_iCheckCount );
|
||||
arc.ArchiveSafePointer( &m_pCurrentEnemy );
|
||||
arc.ArchiveFloat( &m_fCurrentVisibility );
|
||||
arc.ArchiveInteger( &m_iCurrentThreat );
|
||||
return m_pCurrentEnemy;
|
||||
}
|
||||
|
||||
#endif /* actorenemy.h */
|
||||
inline float ActorEnemySet::GetCurrentVisibility(void) const
|
||||
{
|
||||
return m_fCurrentVisibility;
|
||||
}
|
||||
|
||||
inline int ActorEnemySet::GetCurrentThreat(void) const
|
||||
{
|
||||
return m_iCurrentThreat;
|
||||
}
|
||||
|
||||
inline qboolean ActorEnemySet::IsEnemyConfirmed(void) const
|
||||
{
|
||||
return m_fCurrentVisibility > 0.999f;
|
||||
}
|
||||
|
||||
inline void ActorEnemySet::Archive(Archiver& arc)
|
||||
{
|
||||
Class::Archive(arc);
|
||||
|
||||
m_Enemies.Archive(arc);
|
||||
arc.ArchiveInteger(&m_iCheckCount);
|
||||
arc.ArchiveSafePointer(&m_pCurrentEnemy);
|
||||
arc.ArchiveFloat(&m_fCurrentVisibility);
|
||||
arc.ArchiveInteger(&m_iCurrentThreat);
|
||||
}
|
||||
+414
-521
File diff suppressed because it is too large.
Load diff
+120
-111
@@ -22,138 +22,147 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
// actorpath.h: Actor path
|
||||
|
||||
#ifndef __ACTORPATH_H__
|
||||
#define __ACTORPATH_H__
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MIN_FALLHEIGHT 18
|
||||
#define MAX_FALLHEIGHT 1024
|
||||
class ActorPath {
|
||||
// path list
|
||||
PathInfo *m_path;
|
||||
int m_pathlen;
|
||||
|
||||
// path position
|
||||
PathInfo *m_pathpos;
|
||||
class ActorPath
|
||||
{
|
||||
// path list
|
||||
PathInfo *m_path;
|
||||
int m_pathlen;
|
||||
|
||||
// starting path position
|
||||
PathInfo *m_startpathpos;
|
||||
vec2_t m_delta;
|
||||
bool m_Side;
|
||||
int m_Time;
|
||||
float m_TotalDist;
|
||||
short int m_FallHeight;
|
||||
bool m_HasCompleteLookahead;
|
||||
float m_fLookAhead;
|
||||
bool m_bChangeLookAhead;
|
||||
// path position
|
||||
PathInfo *m_pathpos;
|
||||
|
||||
// starting path position
|
||||
PathInfo *m_startpathpos;
|
||||
vec2_t m_delta;
|
||||
bool m_Side;
|
||||
int m_Time;
|
||||
float m_TotalDist;
|
||||
short int m_FallHeight;
|
||||
bool m_HasCompleteLookahead;
|
||||
float m_fLookAhead;
|
||||
bool m_bChangeLookAhead;
|
||||
|
||||
private:
|
||||
float PathLookAhead( float total_area, Vector& end, float *origin );
|
||||
float PathLookAhead(float total_area, Vector& end, float *origin);
|
||||
|
||||
public:
|
||||
ActorPath();
|
||||
~ActorPath();
|
||||
ActorPath();
|
||||
~ActorPath();
|
||||
|
||||
void Clear( void );
|
||||
bool DoesTheoreticPathExist( float *start, float *end, class SimpleActor *ent, float maxPath, float *vLeashHome, float fLeashDistSquared );
|
||||
void FindPath( float *start, float *end, Entity *ent, float maxPath, float *vLeashHome, float fLeashDistSquared );
|
||||
void FindPathAway( float *start, float *avoid, float *vPreferredDir, Entity *ent, float fMinSafeDist, float *vLeashHome, float fLeashDistSquared );
|
||||
void FindPathNear( float *start, float *nearby, Entity *ent, float maxPath, float fRadiusSquared, float *vLeashHome, float fLeashDistSquared );
|
||||
void ReFindPath( float *start, Entity *ent );
|
||||
void UpdatePos( float *origin, float fNodeRadius = 0.0f );
|
||||
bool Complete( const float *origin ) const;
|
||||
PathInfo *StartNode( void ) const;
|
||||
PathInfo *CurrentNode( void ) const;
|
||||
int CurrentNodeIndex( void ) const;
|
||||
PathInfo *NextNode( void ) const;
|
||||
PathInfo *LastNode( void ) const;
|
||||
Vector CurrentPathDir( void ) const;
|
||||
float *CurrentPathGoal( void ) const;
|
||||
int Time( void ) const;
|
||||
Vector CurrentDelta( void ) const;
|
||||
bool IsAccurate( void ) const;
|
||||
float TotalDist( void ) const;
|
||||
void SetFallHeight( float fHeight );
|
||||
float GetFallHeight( void ) const;
|
||||
void TrimPathFromEnd( int nNodesPop );
|
||||
void Shorten( float fDistRemove );
|
||||
bool HasCompleteLookahead( void ) const;
|
||||
bool IsSide( void ) const;
|
||||
void ForceShortLookahead( void );
|
||||
void Clear(void);
|
||||
bool DoesTheoreticPathExist(
|
||||
float *start, float *end, class SimpleActor *ent, float maxPath, float *vLeashHome, float fLeashDistSquared
|
||||
);
|
||||
void FindPath(float *start, float *end, Entity *ent, float maxPath, float *vLeashHome, float fLeashDistSquared);
|
||||
void FindPathAway(
|
||||
float *start,
|
||||
float *avoid,
|
||||
float *vPreferredDir,
|
||||
Entity *ent,
|
||||
float fMinSafeDist,
|
||||
float *vLeashHome,
|
||||
float fLeashDistSquared
|
||||
);
|
||||
void FindPathNear(
|
||||
float *start,
|
||||
float *nearby,
|
||||
Entity *ent,
|
||||
float maxPath,
|
||||
float fRadiusSquared,
|
||||
float *vLeashHome,
|
||||
float fLeashDistSquared
|
||||
);
|
||||
void ReFindPath(float *start, Entity *ent);
|
||||
void UpdatePos(float *origin, float fNodeRadius = 0.0f);
|
||||
bool Complete(const float *origin) const;
|
||||
PathInfo *StartNode(void) const;
|
||||
PathInfo *CurrentNode(void) const;
|
||||
int CurrentNodeIndex(void) const;
|
||||
PathInfo *NextNode(void) const;
|
||||
PathInfo *LastNode(void) const;
|
||||
const float *CurrentPathDir(void) const;
|
||||
const float *CurrentPathGoal(void) const;
|
||||
int Time(void) const;
|
||||
const float *CurrentDelta(void) const;
|
||||
bool IsAccurate(void) const;
|
||||
float TotalDist(void) const;
|
||||
void SetFallHeight(float fHeight);
|
||||
float GetFallHeight(void) const;
|
||||
void TrimPathFromEnd(int nNodesPop);
|
||||
void Shorten(float fDistRemove);
|
||||
bool HasCompleteLookahead(void) const;
|
||||
void ForceShortLookahead(void);
|
||||
|
||||
virtual void Archive( Archiver& arc );
|
||||
virtual void Archive(Archiver& arc);
|
||||
|
||||
bool IsSide(void) const;
|
||||
};
|
||||
|
||||
inline void ActorPath::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline void ActorPath::Archive(Archiver& arc)
|
||||
{
|
||||
int pos;
|
||||
int startpathpos;
|
||||
int pos;
|
||||
int startpathpos;
|
||||
|
||||
arc.ArchiveInteger( &m_pathlen );
|
||||
arc.ArchiveInteger(&m_pathlen);
|
||||
|
||||
if( m_pathlen )
|
||||
{
|
||||
if( arc.Loading() )
|
||||
{
|
||||
m_path = new PathInfo[ m_pathlen ];
|
||||
}
|
||||
if (m_pathlen) {
|
||||
if (arc.Loading()) {
|
||||
m_path = new PathInfo[m_pathlen];
|
||||
}
|
||||
|
||||
if( m_pathlen > 0 )
|
||||
{
|
||||
for( int i = 0; i < m_pathlen; i++ )
|
||||
{
|
||||
m_path->Archive( arc );
|
||||
}
|
||||
}
|
||||
if (m_pathlen > 0) {
|
||||
for (int i = 0; i < m_pathlen; i++) {
|
||||
m_path->Archive(arc);
|
||||
}
|
||||
}
|
||||
|
||||
if( !arc.Saving() )
|
||||
{
|
||||
arc.ArchiveInteger( &pos );
|
||||
if( pos == -1 )
|
||||
m_pathpos = NULL;
|
||||
else
|
||||
m_pathpos = &m_path[ pos ];
|
||||
if (!arc.Saving()) {
|
||||
arc.ArchiveInteger(&pos);
|
||||
if (pos == -1) {
|
||||
m_pathpos = NULL;
|
||||
} else {
|
||||
m_pathpos = &m_path[pos];
|
||||
}
|
||||
|
||||
arc.ArchiveInteger( &startpathpos );
|
||||
if( startpathpos == -1 )
|
||||
m_startpathpos = NULL;
|
||||
else
|
||||
m_startpathpos = &m_path[ pos ];
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_pathpos )
|
||||
pos = m_pathpos - m_path;
|
||||
else
|
||||
pos = -1;
|
||||
arc.ArchiveInteger(&startpathpos);
|
||||
if (startpathpos == -1) {
|
||||
m_startpathpos = NULL;
|
||||
} else {
|
||||
m_startpathpos = &m_path[pos];
|
||||
}
|
||||
} else {
|
||||
if (m_pathpos) {
|
||||
pos = m_pathpos - m_path;
|
||||
} else {
|
||||
pos = -1;
|
||||
}
|
||||
|
||||
arc.ArchiveInteger( &pos );
|
||||
arc.ArchiveInteger(&pos);
|
||||
|
||||
if( m_startpathpos )
|
||||
pos = m_startpathpos - m_path;
|
||||
else
|
||||
pos = -1;
|
||||
if (m_startpathpos) {
|
||||
pos = m_startpathpos - m_path;
|
||||
} else {
|
||||
pos = -1;
|
||||
}
|
||||
|
||||
arc.ArchiveInteger( &pos );
|
||||
}
|
||||
}
|
||||
else if( arc.Loading() )
|
||||
{
|
||||
m_pathpos = 0;
|
||||
}
|
||||
arc.ArchiveInteger(&pos);
|
||||
}
|
||||
} else if (arc.Loading()) {
|
||||
m_pathpos = 0;
|
||||
}
|
||||
|
||||
arc.ArchiveVec2( m_delta );
|
||||
arc.ArchiveBool( &m_Side );
|
||||
arc.ArchiveInteger( &m_Time );
|
||||
arc.ArchiveFloat( &m_TotalDist );
|
||||
arc.ArchiveShort( &m_FallHeight );
|
||||
arc.ArchiveShort( &m_FallHeight );
|
||||
arc.ArchiveBool( &m_HasCompleteLookahead );
|
||||
arc.ArchiveFloat( &m_fLookAhead );
|
||||
arc.ArchiveBool( &m_bChangeLookAhead );
|
||||
arc.ArchiveVec2(m_delta);
|
||||
arc.ArchiveBool(&m_Side);
|
||||
arc.ArchiveInteger(&m_Time);
|
||||
arc.ArchiveFloat(&m_TotalDist);
|
||||
arc.ArchiveShort(&m_FallHeight);
|
||||
arc.ArchiveShort(&m_FallHeight);
|
||||
arc.ArchiveBool(&m_HasCompleteLookahead);
|
||||
arc.ArchiveFloat(&m_fLookAhead);
|
||||
arc.ArchiveBool(&m_bChangeLookAhead);
|
||||
}
|
||||
|
||||
#endif /* actorpath.h */
|
||||
+103
-119
@@ -21,163 +21,147 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// ammo.cpp: Base class for all ammunition for entities derived from the Weapon class.
|
||||
//
|
||||
//
|
||||
// AmmoEntity is the Class which represents ammo that the player "sees" and "
|
||||
// picks up" in the game
|
||||
//
|
||||
// Ammo is the Class which is used to keep track of how much ammo a player has
|
||||
// Ammo is the Class which is used to keep track of how much ammo a player has
|
||||
// in his inventory
|
||||
|
||||
#include "ammo.h"
|
||||
#include "player.h"
|
||||
|
||||
CLASS_DECLARATION( Item, AmmoEntity, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
};
|
||||
CLASS_DECLARATION(Item, AmmoEntity, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
AmmoEntity::AmmoEntity
|
||||
(
|
||||
)
|
||||
AmmoEntity::AmmoEntity()
|
||||
|
||||
{
|
||||
if ( LoadingSavegame )
|
||||
{
|
||||
// all data will be setup by the archive function
|
||||
return;
|
||||
}
|
||||
setName( "UnknownAmmo" );
|
||||
amount = 0;
|
||||
}
|
||||
{
|
||||
if (LoadingSavegame) {
|
||||
// all data will be setup by the archive function
|
||||
return;
|
||||
}
|
||||
setName("UnknownAmmo");
|
||||
amount = 0;
|
||||
}
|
||||
|
||||
Item *AmmoEntity::ItemPickup
|
||||
(
|
||||
Entity *other,
|
||||
qboolean add_to_inventory
|
||||
)
|
||||
Item *AmmoEntity::ItemPickup(Entity *other, qboolean add_to_inventory)
|
||||
|
||||
{
|
||||
Sentient *player;
|
||||
str realname;
|
||||
AliasListNode_t *ret;
|
||||
{
|
||||
Sentient *player;
|
||||
Weapon* pWeap;
|
||||
|
||||
if ( !other->isSubclassOf( Player ) )
|
||||
return NULL;
|
||||
if (!other->IsSubclassOfPlayer()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
player = ( Sentient * )other;
|
||||
player = (Sentient *)other;
|
||||
|
||||
// Play pickup sound
|
||||
realname = GetRandomAlias( "snd_pickup", &ret );
|
||||
if ( realname.length() > 1 )
|
||||
player->Sound( realname, CHAN_ITEM );
|
||||
if (player->AmmoCount(item_name.c_str()) == player->MaxAmmoCount(item_name.c_str())) {
|
||||
// don't pickup if the player already has max ammo
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Cancel some events
|
||||
CancelEventsOfType( EV_Item_DropToFloor );
|
||||
CancelEventsOfType( EV_Item_Respawn );
|
||||
CancelEventsOfType( EV_FadeOut );
|
||||
// Play pickup sound
|
||||
player->Sound(sPickupSound, CHAN_ITEM);
|
||||
|
||||
// Hide the model
|
||||
setSolidType( SOLID_NOT );
|
||||
hideModel();
|
||||
// Cancel some events
|
||||
CancelEventsOfType(EV_Item_DropToFloor);
|
||||
CancelEventsOfType(EV_Item_Respawn);
|
||||
CancelEventsOfType(EV_FadeOut);
|
||||
|
||||
// Respawn?
|
||||
if ( !Respawnable() )
|
||||
PostEvent( EV_Remove, FRAMETIME );
|
||||
else
|
||||
PostEvent( EV_Item_Respawn, RespawnTime() );
|
||||
// Hide the model
|
||||
setSolidType(SOLID_NOT);
|
||||
hideModel();
|
||||
|
||||
// Give the ammo to the player
|
||||
player->GiveAmmo( item_name, amount );
|
||||
return NULL; // This doesn't create any items
|
||||
}
|
||||
// Respawn?
|
||||
if (!Respawnable()) {
|
||||
PostEvent(EV_Remove, FRAMETIME);
|
||||
} else {
|
||||
PostEvent(EV_Item_Respawn, RespawnTime());
|
||||
}
|
||||
|
||||
// Notify scripts about the pickup
|
||||
Unregister(STRING_PICKUP);
|
||||
|
||||
// Tell the player about the ammo being picked
|
||||
gi.SendServerCommand(other->edict - g_entities, "print \"" HUD_MESSAGE_YELLOW "%s\"", gi.LV_ConvertString(va("Got %d %s Rounds", amount, item_name.c_str())));
|
||||
|
||||
// Give the ammo to the player
|
||||
player->GiveAmmo(item_name, amount);
|
||||
|
||||
// Make the weapon reload if the weapon has an empty clip
|
||||
pWeap = player->GetActiveWeapon(WEAPON_MAIN);
|
||||
if (pWeap && !pWeap->HasAmmoInClip(FIRE_PRIMARY) && pWeap->CheckReload(FIRE_PRIMARY)) {
|
||||
pWeap->SetShouldReload(qtrue);
|
||||
}
|
||||
|
||||
return NULL; // This doesn't create any items
|
||||
}
|
||||
|
||||
// This is the Class that is used to keep track of ammo in the player's inventory.
|
||||
// It is not an entit, just a name and an amount.
|
||||
|
||||
CLASS_DECLARATION( Class, Ammo, NULL )
|
||||
{
|
||||
{NULL, NULL}
|
||||
};
|
||||
CLASS_DECLARATION(Class, Ammo, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
Ammo::Ammo
|
||||
(
|
||||
)
|
||||
Ammo::Ammo()
|
||||
|
||||
{
|
||||
if ( LoadingSavegame )
|
||||
{
|
||||
// all data will be setup by the archive function
|
||||
return;
|
||||
}
|
||||
setName( "UnknownAmmo" );
|
||||
setAmount( 0 );
|
||||
setMaxAmount( 100 );
|
||||
}
|
||||
{
|
||||
if (LoadingSavegame) {
|
||||
// all data will be setup by the archive function
|
||||
return;
|
||||
}
|
||||
setName("UnknownAmmo");
|
||||
setAmount(0);
|
||||
setMaxAmount(100);
|
||||
}
|
||||
|
||||
void Ammo::setAmount
|
||||
(
|
||||
int a
|
||||
)
|
||||
void Ammo::setAmount(int a)
|
||||
|
||||
{
|
||||
amount = a;
|
||||
{
|
||||
amount = a;
|
||||
|
||||
if ( ( maxamount > 0 ) && ( amount > maxamount ) )
|
||||
amount = maxamount;
|
||||
}
|
||||
if ((maxamount > 0) && (amount > maxamount)) {
|
||||
amount = maxamount;
|
||||
}
|
||||
}
|
||||
|
||||
int Ammo::getAmount
|
||||
(
|
||||
void
|
||||
)
|
||||
int Ammo::getAmount(void)
|
||||
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
|
||||
void Ammo::setMaxAmount
|
||||
(
|
||||
int a
|
||||
)
|
||||
void Ammo::setMaxAmount(int a)
|
||||
|
||||
{
|
||||
maxamount = a;
|
||||
}
|
||||
{
|
||||
maxamount = a;
|
||||
}
|
||||
|
||||
int Ammo::getMaxAmount
|
||||
(
|
||||
void
|
||||
)
|
||||
int Ammo::getMaxAmount(void)
|
||||
|
||||
{
|
||||
return maxamount;
|
||||
}
|
||||
{
|
||||
return maxamount;
|
||||
}
|
||||
|
||||
void Ammo::setName
|
||||
(
|
||||
str n
|
||||
)
|
||||
void Ammo::setName(str n)
|
||||
|
||||
{
|
||||
name = n;
|
||||
name_index = gi.itemindex( name ) + CS_WEAPONS;
|
||||
}
|
||||
{
|
||||
name = n;
|
||||
name_index = gi.itemindex(name) + CS_WEAPONS;
|
||||
}
|
||||
|
||||
str Ammo::getName
|
||||
(
|
||||
void
|
||||
)
|
||||
str Ammo::getName(void)
|
||||
|
||||
{
|
||||
return name;
|
||||
}
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
int Ammo::getIndex
|
||||
(
|
||||
void
|
||||
)
|
||||
int Ammo::getIndex(void)
|
||||
|
||||
{
|
||||
return name_index;
|
||||
}
|
||||
{
|
||||
return name_index;
|
||||
}
|
||||
+37
-41
@@ -29,55 +29,51 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "item.h"
|
||||
|
||||
class AmmoEntity : public Item
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( AmmoEntity );
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(AmmoEntity);
|
||||
|
||||
AmmoEntity();
|
||||
Item *ItemPickup( Entity *other, qboolean add_to_inventory ) override;
|
||||
};
|
||||
AmmoEntity();
|
||||
Item *ItemPickup(Entity *other, qboolean add_to_inventory) override;
|
||||
};
|
||||
|
||||
class Ammo : public Class
|
||||
{
|
||||
int amount;
|
||||
int maxamount;
|
||||
str name;
|
||||
int name_index;
|
||||
{
|
||||
int amount;
|
||||
int maxamount;
|
||||
str name;
|
||||
int name_index;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( Ammo );
|
||||
public:
|
||||
CLASS_PROTOTYPE(Ammo);
|
||||
|
||||
Ammo();
|
||||
Ammo(str name, int amount, int name_index );
|
||||
Ammo();
|
||||
Ammo(str name, int amount, int name_index);
|
||||
|
||||
void setAmount( int a );
|
||||
int getAmount( void );
|
||||
void setMaxAmount( int a );
|
||||
int getMaxAmount( void );
|
||||
void setName( str name);
|
||||
str getName( void );
|
||||
int getIndex( void );
|
||||
void Archive( Archiver &arc ) override;
|
||||
};
|
||||
void setAmount(int a);
|
||||
int getAmount(void);
|
||||
void setMaxAmount(int a);
|
||||
int getMaxAmount(void);
|
||||
void setName(str name);
|
||||
str getName(void);
|
||||
int getIndex(void);
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline void Ammo::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
inline void Ammo::Archive(Archiver& arc)
|
||||
|
||||
{
|
||||
Class::Archive( arc );
|
||||
{
|
||||
Class::Archive(arc);
|
||||
|
||||
arc.ArchiveInteger( &amount );
|
||||
arc.ArchiveInteger( &maxamount );
|
||||
arc.ArchiveString( &name );
|
||||
//
|
||||
// name_index not archived, because it is auto-generated by gi.itemindex
|
||||
//
|
||||
if ( arc.Loading() )
|
||||
{
|
||||
setName( name );
|
||||
}
|
||||
}
|
||||
arc.ArchiveInteger(&amount);
|
||||
arc.ArchiveInteger(&maxamount);
|
||||
arc.ArchiveString(&name);
|
||||
//
|
||||
// name_index not archived, because it is auto-generated by gi.itemindex
|
||||
//
|
||||
if (arc.Loading()) {
|
||||
setName(name);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ammo.h */
|
||||
+316
-149
@@ -32,48 +32,35 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
extern Event EV_Entity_Start;
|
||||
|
||||
// Leg Animation events
|
||||
Event EV_SetAnim("anim", EV_ZERO, "s", "animName", "Exec anim commands on server or client.", EV_NORMAL);
|
||||
Event EV_SetSyncTime("setsynctime", EV_ZERO, "f", "synctime", "Set sync time for entity.");
|
||||
Event EV_SetFrame(
|
||||
"setframe",
|
||||
Event EV_SetAnim
|
||||
(
|
||||
"anim",
|
||||
EV_ZERO,
|
||||
"iS",
|
||||
"frameNumber animName",
|
||||
"Set the frame on the legs, if anim is not specified, current is assumed.",
|
||||
"s",
|
||||
"animName",
|
||||
"Exec anim commands on server or client.",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_AnimDone("animdone", EV_ZERO, NULL, NULL, "Legs animation has finished, not for script use.", EV_NORMAL);
|
||||
Event EV_FrameDelta(
|
||||
"setmovedelta", EV_ZERO, "vf", "moveDelta moveTime", "movement from animation, not for script use.", EV_NORMAL
|
||||
);
|
||||
Event EV_Torso_Anim("torso_anim", EV_ZERO, "s", "animName", "set the torso animation to animName.", EV_NORMAL);
|
||||
Event EV_Torso_SetFrame(
|
||||
"torso_setframe",
|
||||
Event EV_SetSyncTime
|
||||
(
|
||||
"setsynctime",
|
||||
EV_ZERO,
|
||||
"iS",
|
||||
"frameNumber animName",
|
||||
"Set the frame on the torso, if anim is not specified, current is assumed.",
|
||||
"f",
|
||||
"synctime",
|
||||
"Set sync time for entity.",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_Torso_AnimDone(
|
||||
"torso_animdone", EV_ZERO, NULL, NULL, "Torso animation has finished, not for script use.", EV_NORMAL
|
||||
Event EV_Animate_IsLoopingAnim
|
||||
(
|
||||
"isloopinganim",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"anim_name",
|
||||
"returns 1 if the anim is a looping anim, or 0 otherwise",
|
||||
EV_RETURN
|
||||
);
|
||||
Event EV_Torso_StopAnimating(
|
||||
"torso_stopanimating",
|
||||
EV_ZERO,
|
||||
NULL,
|
||||
NULL,
|
||||
"stop the torso from animating. Animation will end at the end of current cycle.",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_NewAnim(
|
||||
"animate_newanim", EV_ZERO, "ii", "animNum slot", "Start a new animation, not for script use.", EV_NORMAL
|
||||
);
|
||||
Event EV_ViewAnim("viewanim", EV_DEFAULT, "s", "anim", "testing");
|
||||
Event EV_Animate_IsLoopingAnim(
|
||||
"isloopinganim", EV_DEFAULT, "s", "anim_name", "returns 1 if the anim is a looping anim, or 0 otherwise", EV_RETURN
|
||||
);
|
||||
Event EV_Animate_SetYawfromBone(
|
||||
Event EV_Animate_SetYawfromBone
|
||||
(
|
||||
"setyawfrombone",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
@@ -81,7 +68,8 @@ Event EV_Animate_SetYawfromBone(
|
||||
"Set the yaw of the model based on the current animation time",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_Animate_PlayerSpawn(
|
||||
Event EV_Animate_PlayerSpawn
|
||||
(
|
||||
"playerspawn",
|
||||
EV_DEFAULT,
|
||||
"sFVFF",
|
||||
@@ -101,10 +89,33 @@ Event EV_Animate_PlayerSpawn(
|
||||
"one second later.",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_Animate_PlayerSpawn_Utility(
|
||||
"testmojo", EV_DEFAULT, "sv", "model_name vector_offset", "INTERNAL EVENT", EV_NORMAL
|
||||
Event EV_Animate_PlayerSpawn_Utility
|
||||
(
|
||||
"testmojo",
|
||||
EV_DEFAULT,
|
||||
"sv",
|
||||
"model_name vector_offset",
|
||||
"INTERNAL EVENT",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_Animate_PauseAnim
|
||||
(
|
||||
"pauseanims",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"pause",
|
||||
"Pause (or unpause) animations",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_Animate_Client_Sound
|
||||
(
|
||||
"_client_sound",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_Animate_PauseAnim("pauseanims", EV_DEFAULT, "i", "pause", "Pause (or unpause) animations");
|
||||
|
||||
CLASS_DECLARATION(Entity, Animate, "animate") {
|
||||
{&EV_SetControllerAngles, &Animate::SetControllerAngles },
|
||||
@@ -115,16 +126,54 @@ CLASS_DECLARATION(Entity, Animate, "animate") {
|
||||
{&EV_Animate_PlayerSpawn, &Animate::EventPlayerSpawn },
|
||||
{&EV_Animate_PlayerSpawn_Utility, &Animate::EventPlayerSpawnUtility},
|
||||
{&EV_Animate_PauseAnim, &Animate::EventPauseAnim },
|
||||
{&EV_Animate_Client_Sound, &Animate::ClientSound },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
static size_t GetLongestClientCmdLength(const tiki_cmd_t& cmds)
|
||||
{
|
||||
size_t ii;
|
||||
size_t longest = 0;
|
||||
|
||||
for (ii = 0; ii < cmds.num_cmds; ii++) {
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
size_t length = strlen(single_cmd.args[0]);
|
||||
if (length > longest) {
|
||||
longest = length;
|
||||
}
|
||||
}
|
||||
|
||||
return longest;
|
||||
}
|
||||
|
||||
static size_t GetLongestClientCmdAllFramesLength(dtiki_t *tiki, int animnum, int numframes)
|
||||
{
|
||||
tiki_cmd_t cmds;
|
||||
size_t longest = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numframes; i++) {
|
||||
// we want normal frame commands to occur right on the frame
|
||||
if (gi.Frame_Commands_Client(tiki, animnum, i, &cmds)) {
|
||||
size_t length = GetLongestClientCmdLength(cmds);
|
||||
if (length > longest) {
|
||||
longest = length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return longest;
|
||||
}
|
||||
|
||||
Animate::Animate()
|
||||
{
|
||||
entflags |= EF_ANIMATE;
|
||||
entflags |= ECF_ANIMATE;
|
||||
|
||||
syncTime = 0.0f;
|
||||
syncRate = 1.0f;
|
||||
|
||||
pauseSyncTime = 0.0f;
|
||||
syncTime = 0.0f;
|
||||
syncRate = 1.0f;
|
||||
is_paused = false;
|
||||
|
||||
frame_delta = vec_zero;
|
||||
angular_delta = 0;
|
||||
@@ -149,7 +198,7 @@ Animate::Animate()
|
||||
|
||||
Animate::~Animate()
|
||||
{
|
||||
entflags &= ~EF_ANIMATE;
|
||||
entflags &= ~ECF_ANIMATE;
|
||||
}
|
||||
|
||||
void Animate::ForwardExec(Event *ev)
|
||||
@@ -164,7 +213,6 @@ void Animate::ForwardExec(Event *ev)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
NewAnim(ev->GetString(1), 0);
|
||||
RestartAnimSlot(0);
|
||||
}
|
||||
@@ -217,11 +265,10 @@ void Animate::NewAnim(int animnum, int slot, float weight)
|
||||
animFlags[slot] = ANIM_LOOP | ANIM_NODELTA | ANIM_NOEXIT;
|
||||
|
||||
if (!(gi.Anim_FlagsSkel(edict->tiki, animnum) & ANIM_LOOP)) {
|
||||
animFlags[slot] &= ~ANIM_LOOP;
|
||||
SetOnceType(slot);
|
||||
}
|
||||
|
||||
edict->s.frameInfo[slot].weight = weight;
|
||||
|
||||
SetWeight(slot, weight);
|
||||
animtimes[slot] = gi.Anim_Time(edict->tiki, animnum);
|
||||
frametimes[slot] = gi.Anim_Frametime(edict->tiki, animnum);
|
||||
|
||||
@@ -229,7 +276,8 @@ void Animate::NewAnim(int animnum, int slot, float weight)
|
||||
edict->s.eType = ET_MODELANIM;
|
||||
}
|
||||
|
||||
qboolean hascommands = gi.Anim_HasCommands(edict->tiki, animnum);
|
||||
qboolean hascommands =
|
||||
gi.Anim_HasCommands(edict->tiki, animnum) || gi.Anim_HasCommands_Client(edict->tiki, animnum);
|
||||
|
||||
// enter this animation
|
||||
if (newanim) {
|
||||
@@ -241,18 +289,53 @@ void Animate::NewAnim(int animnum, int slot, float weight)
|
||||
int ii, j;
|
||||
|
||||
for (ii = 0; ii < cmds.num_cmds; ii++) {
|
||||
ev = new AnimationEvent(cmds.cmds[ii].args[0]);
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
|
||||
ev->SetAnimationNumber(animnum);
|
||||
ev->SetAnimationFrame(0);
|
||||
AnimationEvent ev(single_cmd.args[0], single_cmd.num_args);
|
||||
|
||||
for (j = 1; j < cmds.cmds[ii].num_args; j++) {
|
||||
ev->AddToken(cmds.cmds[ii].args[j]);
|
||||
ev.SetAnimationNumber(animnum);
|
||||
ev.SetAnimationFrame(0);
|
||||
|
||||
for (j = 1; j < single_cmd.num_args; j++) {
|
||||
ev.AddToken(single_cmd.args[j]);
|
||||
}
|
||||
|
||||
ProcessEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
if (gi.Frame_Commands_Client(edict->tiki, animnum, TIKI_FRAME_ENTRY, &cmds)) {
|
||||
size_t longest = GetLongestClientCmdLength(cmds);
|
||||
int ii, j;
|
||||
|
||||
if (longest) {
|
||||
char *cmdName = (char *)alloca(longest + 8 + 1);
|
||||
|
||||
for (ii = 0; ii < cmds.num_cmds; ii++) {
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
int eventNum;
|
||||
|
||||
strcpy(cmdName, "_client_");
|
||||
strcpy(cmdName + 8, single_cmd.args[0]);
|
||||
|
||||
eventNum = Event::FindEventNum(cmdName);
|
||||
|
||||
AnimationEvent ev(eventNum, single_cmd.num_args);
|
||||
if (!ev.eventnum) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ev.SetAnimationNumber(animnum);
|
||||
ev.SetAnimationFrame(0);
|
||||
|
||||
for (j = 1; j < single_cmd.num_args; j++) {
|
||||
ev.AddToken(single_cmd.args[j]);
|
||||
}
|
||||
|
||||
ProcessEvent(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hascommands) {
|
||||
@@ -272,37 +355,75 @@ void Animate::NewAnim(int animnum, int slot, float weight)
|
||||
int ii, j;
|
||||
|
||||
for (ii = 0; ii < cmds.num_cmds; ii++) {
|
||||
ev = new AnimationEvent(cmds.cmds[ii].args[0]);
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
|
||||
ev = new AnimationEvent(single_cmd.args[0], single_cmd.num_args);
|
||||
|
||||
ev->SetAnimationNumber(animnum);
|
||||
ev->SetAnimationFrame(i);
|
||||
|
||||
for (j = 1; j < cmds.cmds[ii].num_args; j++) {
|
||||
ev->AddToken(cmds.cmds[ii].args[j]);
|
||||
for (j = 1; j < single_cmd.num_args; j++) {
|
||||
ev->AddToken(single_cmd.args[j]);
|
||||
}
|
||||
|
||||
PostEvent(ev, time, 1 << slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
time = 0.0f;
|
||||
|
||||
const size_t longestAllFrames = GetLongestClientCmdAllFramesLength(edict->tiki, animnum, numframes);
|
||||
if (longestAllFrames) {
|
||||
char *cmdName = (char *)alloca(longestAllFrames + 8 + 1);
|
||||
|
||||
for (i = 0; i < numframes; i++, time += frametimes[slot]) {
|
||||
// we want normal frame commands to occur right on the frame
|
||||
if (gi.Frame_Commands_Client(edict->tiki, animnum, i, &cmds)) {
|
||||
int ii, j;
|
||||
|
||||
for (ii = 0; ii < cmds.num_cmds; ii++) {
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
int eventNum;
|
||||
|
||||
strcpy(cmdName, "_client_");
|
||||
strcpy(cmdName + 8, single_cmd.args[0]);
|
||||
|
||||
eventNum = Event::FindEventNum(cmdName);
|
||||
|
||||
AnimationEvent ev(eventNum, single_cmd.num_args);
|
||||
if (!ev.eventnum) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ev.SetAnimationNumber(animnum);
|
||||
ev.SetAnimationFrame(i);
|
||||
|
||||
for (j = 1; j < single_cmd.num_args; j++) {
|
||||
ev.AddToken(single_cmd.args[j]);
|
||||
}
|
||||
|
||||
PostEvent(ev, time, 1 << slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Animate::NewAnim(int animnum, Event& newevent, int slot, float weight)
|
||||
{
|
||||
if (animnum == -1) {
|
||||
if (animnum != -1) {
|
||||
NewAnim(animnum, slot);
|
||||
SetAnimDoneEvent(newevent, slot);
|
||||
} else {
|
||||
PostEvent(newevent, level.frametime);
|
||||
}
|
||||
|
||||
NewAnim(animnum, slot);
|
||||
SetAnimDoneEvent(newevent, slot);
|
||||
}
|
||||
|
||||
void Animate::NewAnim(int animnum, Event *newevent, int slot, float weight)
|
||||
{
|
||||
if (animnum == -1) {
|
||||
if (newevent) {
|
||||
PostEvent(newevent, level.frametime);
|
||||
}
|
||||
if (animnum == -1 && newevent) {
|
||||
PostEvent(newevent, level.frametime);
|
||||
}
|
||||
|
||||
NewAnim(animnum, slot);
|
||||
@@ -311,7 +432,7 @@ void Animate::NewAnim(int animnum, Event *newevent, int slot, float weight)
|
||||
|
||||
void Animate::NewAnim(const char *animname, int slot, float weight)
|
||||
{
|
||||
int animnum = gi.Anim_Random(edict->tiki, animname);
|
||||
int animnum = gi.Anim_NumForName(edict->tiki, animname);
|
||||
|
||||
if (animnum != -1) {
|
||||
NewAnim(animnum, slot);
|
||||
@@ -320,19 +441,25 @@ void Animate::NewAnim(const char *animname, int slot, float weight)
|
||||
|
||||
void Animate::NewAnim(const char *animname, Event *endevent, int slot, float weight)
|
||||
{
|
||||
int animnum = gi.Anim_Random(edict->tiki, animname);
|
||||
int animnum = gi.Anim_NumForName(edict->tiki, animname);
|
||||
|
||||
if (animnum != -1) {
|
||||
NewAnim(animnum, endevent, slot);
|
||||
NewAnim(animnum, slot, weight);
|
||||
SetAnimDoneEvent(endevent, slot);
|
||||
} else if (endevent) {
|
||||
PostEvent(endevent, level.frametime);
|
||||
}
|
||||
}
|
||||
|
||||
void Animate::NewAnim(const char *animname, Event& endevent, int slot, float weight)
|
||||
{
|
||||
int animnum = gi.Anim_Random(edict->tiki, animname);
|
||||
int animnum = gi.Anim_NumForName(edict->tiki, animname);
|
||||
|
||||
if (animnum != -1) {
|
||||
NewAnim(animnum, endevent, slot);
|
||||
NewAnim(animnum, slot, weight);
|
||||
SetAnimDoneEvent(endevent, slot);
|
||||
} else {
|
||||
PostEvent(endevent, level.frametime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,7 +530,8 @@ void Animate::DoExitCommands(int slot)
|
||||
int ii, j;
|
||||
|
||||
for (ii = 0; ii < cmds.num_cmds; ii++) {
|
||||
tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
|
||||
ev = new AnimationEvent(single_cmd.args[0], single_cmd.num_args);
|
||||
|
||||
ev->SetAnimationNumber(edict->s.frameInfo[slot].index);
|
||||
@@ -417,6 +545,38 @@ void Animate::DoExitCommands(int slot)
|
||||
}
|
||||
}
|
||||
|
||||
if (gi.Frame_Commands_Client(edict->tiki, edict->s.frameInfo[slot].index, TIKI_FRAME_EXIT, &cmds)) {
|
||||
size_t longest = GetLongestClientCmdLength(cmds);
|
||||
if (longest) {
|
||||
char *cmdName = (char *)alloca(longest + 8 + 1);
|
||||
int ii, j;
|
||||
|
||||
for (ii = 0; ii < cmds.num_cmds; ii++) {
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
int eventNum;
|
||||
|
||||
strcpy(cmdName, "_client_");
|
||||
strcpy(cmdName + 8, single_cmd.args[0]);
|
||||
|
||||
eventNum = Event::FindEventNum(cmdName);
|
||||
|
||||
AnimationEvent ev(eventNum, single_cmd.num_args);
|
||||
if (!ev.eventnum) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ev.SetAnimationNumber(edict->s.frameInfo[slot].index);
|
||||
ev.SetAnimationFrame(0);
|
||||
|
||||
for (j = 1; j < single_cmd.num_args; j++) {
|
||||
ev.AddToken(single_cmd.args[j]);
|
||||
}
|
||||
|
||||
PostEvent(ev, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
animFlags[slot] |= ANIM_NOEXIT;
|
||||
}
|
||||
|
||||
@@ -465,12 +625,12 @@ void Animate::PreAnimate(void)
|
||||
|
||||
void Animate::PostAnimate(void)
|
||||
{
|
||||
float startTime;
|
||||
float deltaSyncTime;
|
||||
float total_weight;
|
||||
float total_angular_delta;
|
||||
Vector vFrameDelta;
|
||||
bool hasAction = false;
|
||||
float startTime;
|
||||
float deltaSyncTime;
|
||||
float total_weight;
|
||||
float total_angular_delta;
|
||||
Vector vFrameDelta;
|
||||
bool hasAction = false;
|
||||
|
||||
if (!edict->tiki) {
|
||||
return;
|
||||
@@ -482,14 +642,12 @@ void Animate::PostAnimate(void)
|
||||
syncTime = 1.0f / syncRate * level.frametime + deltaSyncTime;
|
||||
}
|
||||
|
||||
total_weight = 0;
|
||||
total_weight = 0;
|
||||
total_angular_delta = 0;
|
||||
|
||||
for (int i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
if (edict->s.frameInfo[i].weight > 0.0f) {
|
||||
if (!(animFlags[i] & ANIM_NOACTION)) {
|
||||
hasAction = true;
|
||||
}
|
||||
if (edict->s.frameInfo[i].weight > 0.0f && !(animFlags[i] & ANIM_NOACTION)) {
|
||||
hasAction = true;
|
||||
}
|
||||
|
||||
if (animFlags[i] & ANIM_PAUSED) {
|
||||
@@ -509,84 +667,88 @@ void Animate::PostAnimate(void)
|
||||
animFlags[i] |= ANIM_FINISHED;
|
||||
RestartAnimSlot(i);
|
||||
} else {
|
||||
if (!(animFlags[i] & ANIM_NODELTA)) {
|
||||
if (gi.Anim_HasDelta(edict->tiki, edict->s.frameInfo[i].index)) {
|
||||
float vDelta[3];
|
||||
float angleDelta;
|
||||
if (!(animFlags[i] & ANIM_NODELTA) && gi.Anim_HasDelta(edict->tiki, edict->s.frameInfo[i].index)) {
|
||||
vec3_t vDelta;
|
||||
float angleDelta;
|
||||
|
||||
//
|
||||
// Get the animation's delta position from start time
|
||||
//
|
||||
gi.Anim_DeltaOverTime(edict->tiki, edict->s.frameInfo[i].index, startTime, edict->s.frameInfo[i].time, vDelta);
|
||||
vFrameDelta += Vector(vDelta) * edict->s.frameInfo[i].weight;
|
||||
total_weight += edict->s.frameInfo[i].weight;
|
||||
//
|
||||
// Get the animation's delta position from start time
|
||||
//
|
||||
gi.Anim_DeltaOverTime(
|
||||
edict->tiki, edict->s.frameInfo[i].index, startTime, edict->s.frameInfo[i].time, vDelta
|
||||
);
|
||||
VectorScale(vDelta, edict->s.frameInfo[i].weight, vDelta);
|
||||
vFrameDelta += vDelta;
|
||||
total_weight += edict->s.frameInfo[i].weight;
|
||||
|
||||
//
|
||||
// Get the animation's delta angle from start time
|
||||
//
|
||||
gi.Anim_AngularDeltaOverTime(edict->tiki, edict->s.frameInfo[i].index, startTime, edict->s.frameInfo[i].time, &angleDelta);
|
||||
total_angular_delta += angleDelta * edict->s.frameInfo[i].weight;
|
||||
|
||||
}
|
||||
//
|
||||
// Get the animation's delta angle from start time
|
||||
//
|
||||
gi.Anim_AngularDeltaOverTime(
|
||||
edict->tiki, edict->s.frameInfo[i].index, startTime, edict->s.frameInfo[i].time, &angleDelta
|
||||
);
|
||||
angleDelta *= edict->s.frameInfo[i].weight;
|
||||
total_angular_delta += angleDelta;
|
||||
}
|
||||
|
||||
animFlags[i] &= ~ANIM_NODELTA;
|
||||
|
||||
float animTime;
|
||||
if (animFlags[i] & ANIM_SYNC) {
|
||||
animTime = animtimes[i];
|
||||
if (edict->s.frameInfo[i].time < animtimes[i]) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
animTime = animtimes[i] - 0.01f;
|
||||
}
|
||||
|
||||
if (edict->s.frameInfo[i].time >= animTime) {
|
||||
if (animFlags[i] & ANIM_LOOP) {
|
||||
animFlags[i] |= ANIM_FINISHED;
|
||||
|
||||
do {
|
||||
edict->s.frameInfo[i].time -= animtimes[i];
|
||||
} while (edict->s.frameInfo[i].time >= animtimes[i]);
|
||||
|
||||
if (edict->s.frameInfo[i].time < 0) {
|
||||
edict->s.frameInfo[i].time = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (startTime != animtimes[i]) {
|
||||
animFlags[i] |= ANIM_FINISHED;
|
||||
}
|
||||
|
||||
edict->s.frameInfo[i].time = animtimes[i];
|
||||
if (edict->s.frameInfo[i].time < (animtimes[i] - 0.01f)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (total_weight) {
|
||||
vFrameDelta *= 1.f / total_weight;
|
||||
total_angular_delta *= 1.f / total_weight;
|
||||
}
|
||||
if (IsRepeatType(i)) {
|
||||
animFlags[i] |= ANIM_FINISHED;
|
||||
|
||||
MatrixTransformVector(vFrameDelta, orientation, frame_delta);
|
||||
angular_delta = total_angular_delta;
|
||||
do {
|
||||
edict->s.frameInfo[i].time -= animtimes[i];
|
||||
} while (edict->s.frameInfo[i].time >= animtimes[i]);
|
||||
|
||||
while (syncTime > 1.0f) {
|
||||
syncTime -= 1.0f;
|
||||
}
|
||||
if (edict->s.frameInfo[i].time < 0) {
|
||||
edict->s.frameInfo[i].time = 0;
|
||||
}
|
||||
|
||||
total_weight = level.frametime * 4.0f;
|
||||
} else {
|
||||
if (startTime != animtimes[i]) {
|
||||
animFlags[i] |= ANIM_FINISHED;
|
||||
}
|
||||
|
||||
if (hasAction) {
|
||||
edict->s.actionWeight += total_weight;
|
||||
|
||||
if (edict->s.actionWeight > 1.0f) {
|
||||
edict->s.actionWeight = 1.0f;
|
||||
edict->s.frameInfo[i].time = animtimes[i];
|
||||
}
|
||||
} else {
|
||||
edict->s.actionWeight -= total_weight;
|
||||
}
|
||||
}
|
||||
|
||||
if (edict->s.actionWeight < 0.0f) {
|
||||
edict->s.actionWeight = 0.0f;
|
||||
}
|
||||
if (total_weight) {
|
||||
vFrameDelta *= 1.f / total_weight;
|
||||
total_angular_delta *= 1.f / total_weight;
|
||||
}
|
||||
|
||||
MatrixTransformVector(vFrameDelta, orientation, frame_delta);
|
||||
angular_delta = total_angular_delta;
|
||||
|
||||
while (syncTime >= 1.0f) {
|
||||
syncTime -= 1.0f;
|
||||
}
|
||||
|
||||
total_weight = level.frametime * 4.0f;
|
||||
|
||||
if (hasAction) {
|
||||
edict->s.actionWeight += total_weight;
|
||||
|
||||
if (edict->s.actionWeight > 1.0f) {
|
||||
edict->s.actionWeight = 1.0f;
|
||||
}
|
||||
} else {
|
||||
edict->s.actionWeight -= total_weight;
|
||||
|
||||
if (edict->s.actionWeight < 0.0f) {
|
||||
edict->s.actionWeight = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -630,8 +792,8 @@ void Animate::Pause(int slot, int pause)
|
||||
if (pause) {
|
||||
animFlags[slot] |= ANIM_PAUSED;
|
||||
} else {
|
||||
if ((animFlags[slot] & ANIM_PAUSED)) {
|
||||
if ((animFlags[slot] & ANIM_SYNC)) {
|
||||
if (animFlags[slot] & ANIM_PAUSED) {
|
||||
if (animFlags[slot] & ANIM_SYNC) {
|
||||
SlotChanged(animFlags[slot]);
|
||||
}
|
||||
|
||||
@@ -643,14 +805,14 @@ void Animate::Pause(int slot, int pause)
|
||||
void Animate::UseSyncTime(int slot, int sync)
|
||||
{
|
||||
if (sync) {
|
||||
if (animFlags[slot] & ANIM_SYNC) {
|
||||
return;
|
||||
if (!(animFlags[slot] & ANIM_SYNC)) {
|
||||
animFlags[slot] |= ANIM_SYNC;
|
||||
SlotChanged(slot);
|
||||
}
|
||||
|
||||
animFlags[slot] = (animFlags[slot] | (ANIM_SYNC | ANIM_NODELTA)) & ~ANIM_FINISHED;
|
||||
} else {
|
||||
if (animFlags[slot] & ANIM_SYNC) {
|
||||
animFlags[slot] = (animFlags[slot] | ANIM_NODELTA) & ~(ANIM_FINISHED | ANIM_SYNC);
|
||||
animFlags[slot] &= ~ANIM_SYNC;
|
||||
SlotChanged(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -880,6 +1042,11 @@ void Animate::DumpAnimInfo(void)
|
||||
MPrintf("actionWeight: %f\n", edict->s.actionWeight);
|
||||
}
|
||||
|
||||
void Animate::ClientSound(Event *ev)
|
||||
{
|
||||
PlayNonPvsSound(ev->GetString(1));
|
||||
}
|
||||
|
||||
void Animate::EventPauseAnim(Event *ev)
|
||||
{
|
||||
is_paused = ev->GetInteger(1) ? true : false;
|
||||
|
||||
@@ -21,8 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// animate.h -- Animate class
|
||||
|
||||
#ifndef __ANIMATE_H__
|
||||
#define __ANIMATE_H__
|
||||
#pragma once
|
||||
|
||||
#if defined(GAME_DLL)
|
||||
# include "entity.h"
|
||||
@@ -132,6 +131,8 @@ public:
|
||||
virtual void DumpAnimInfo();
|
||||
void SlotChanged(int slot);
|
||||
|
||||
void ClientSound(Event *ev);
|
||||
|
||||
// FIXME: delete this, fakk2 remnant
|
||||
int NumFrames(int slot = 0);
|
||||
};
|
||||
@@ -168,22 +169,24 @@ inline void Animate::PauseSyncTime(int pause)
|
||||
|
||||
inline void Animate::Archive(Archiver& arc)
|
||||
{
|
||||
int i;
|
||||
|
||||
Entity::Archive(arc);
|
||||
|
||||
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
arc.ArchiveInteger(&animFlags[i]);
|
||||
}
|
||||
arc.ArchiveFloat(&syncTime);
|
||||
arc.ArchiveFloat(&syncRate);
|
||||
arc.ArchiveInteger(&pauseSyncTime);
|
||||
arc.ArchiveBool(&is_paused);
|
||||
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
arc.ArchiveEventPointer(&doneEvents[i]);
|
||||
}
|
||||
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
arc.ArchiveFloat(&animtimes[i]);
|
||||
}
|
||||
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
arc.ArchiveFloat(&frametimes[i]);
|
||||
}
|
||||
arc.ArchiveVector(&frame_delta);
|
||||
@@ -209,5 +212,3 @@ inline int Animate::NumFrames(int slot)
|
||||
{
|
||||
return gi.Anim_NumFrames(edict->tiki, edict->s.frameInfo[slot].index);
|
||||
}
|
||||
|
||||
#endif /* animate.h */
|
||||
@@ -29,13 +29,20 @@ CLASS_DECLARATION(Event, AnimationEvent, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
AnimationEvent::AnimationEvent(str command, int numArgs)
|
||||
AnimationEvent::AnimationEvent(const char* command, int numArgs)
|
||||
: Event(command, numArgs)
|
||||
{
|
||||
anim_number = 0;
|
||||
anim_frame = 0;
|
||||
}
|
||||
|
||||
AnimationEvent::AnimationEvent(int eventNum, int numArgs)
|
||||
: Event(eventNum, numArgs)
|
||||
{
|
||||
anim_number = 0;
|
||||
anim_frame = 0;
|
||||
}
|
||||
|
||||
AnimationEvent::AnimationEvent(const Event& ev)
|
||||
: Event(ev)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,8 @@ public:
|
||||
void *operator new(size_t size);
|
||||
void operator delete(void *ptr);
|
||||
|
||||
AnimationEvent(str command, int numArgs = 0);
|
||||
AnimationEvent(const char* command, int numArgs = 0);
|
||||
AnimationEvent(int eventNum, int numArgs = 0);
|
||||
AnimationEvent(const Event& ev);
|
||||
AnimationEvent();
|
||||
|
||||
|
||||
+880
-1011
File diff suppressed because it is too large.
Load diff
+235
-300
@@ -30,382 +30,317 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "str.h"
|
||||
#include "vector.h"
|
||||
|
||||
#define ARCHIVE_NULL_POINTER ( -654321 )
|
||||
#define ARCHIVE_POINTER_VALID ( 0 )
|
||||
#define ARCHIVE_POINTER_NULL ( ARCHIVE_NULL_POINTER )
|
||||
#define ARCHIVE_POINTER_SELF_REFERENTIAL ( -123456 )
|
||||
#define ARCHIVE_NULL_POINTER (-654321)
|
||||
#define ARCHIVE_POINTER_VALID (0)
|
||||
#define ARCHIVE_POINTER_NULL (ARCHIVE_NULL_POINTER)
|
||||
#define ARCHIVE_POINTER_SELF_REFERENTIAL (-123456)
|
||||
#define ARCHIVE_USE_TYPES
|
||||
|
||||
#define ARCHIVE_WRITE 0
|
||||
#define ARCHIVE_READ 1
|
||||
typedef enum {
|
||||
ARCHIVE_NONE,
|
||||
ARCHIVE_WRITE,
|
||||
ARCHIVE_READ
|
||||
} archivemode_e;
|
||||
|
||||
enum
|
||||
{
|
||||
pointer_fixup_normal,
|
||||
pointer_fixup_safe
|
||||
enum {
|
||||
pointer_fixup_ptr,
|
||||
pointer_fixup_normal,
|
||||
pointer_fixup_safe
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void **ptr;
|
||||
int index;
|
||||
int type;
|
||||
typedef struct {
|
||||
void **ptr;
|
||||
int index;
|
||||
int type;
|
||||
} pointer_fixup_t;
|
||||
|
||||
using fileSize_t = uint32_t;
|
||||
|
||||
class FileRead : public Class
|
||||
class ArchiveFile
|
||||
{
|
||||
protected:
|
||||
str filename;
|
||||
size_t length;
|
||||
byte *buffer;
|
||||
byte *pos;
|
||||
str filename;
|
||||
size_t length;
|
||||
byte *buffer;
|
||||
byte *pos;
|
||||
size_t bufferlength;
|
||||
bool writing;
|
||||
bool opened;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( FileRead );
|
||||
|
||||
FileRead();
|
||||
~FileRead();
|
||||
void Close( bool bDoCompression = false );
|
||||
const char *Filename( void );
|
||||
size_t Length( void );
|
||||
size_t Pos( void );
|
||||
qboolean Seek( size_t newpos );
|
||||
qboolean Open( const char *name );
|
||||
qboolean Read( void *dest, size_t size );
|
||||
ArchiveFile();
|
||||
~ArchiveFile();
|
||||
void Close();
|
||||
const char *Filename(void);
|
||||
qboolean Compress();
|
||||
size_t Length(void);
|
||||
size_t Pos(void);
|
||||
size_t Tell(void);
|
||||
qboolean Seek(size_t newpos);
|
||||
qboolean OpenRead(const char *name);
|
||||
qboolean OpenWrite(const char *name);
|
||||
qboolean Read(void *dest, size_t size);
|
||||
qboolean Write(const void *source, size_t size);
|
||||
};
|
||||
|
||||
class Archiver : public Class
|
||||
class Archiver
|
||||
{
|
||||
private:
|
||||
Container<Class *> classpointerList;
|
||||
Container<pointer_fixup_t *> fixupList;
|
||||
Container<LightClass *> classpointerList;
|
||||
Container<pointer_fixup_t *> fixupList;
|
||||
|
||||
protected:
|
||||
str filename;
|
||||
qboolean fileerror;
|
||||
fileHandle_t file;
|
||||
FileRead readfile;
|
||||
int archivemode;
|
||||
int numclassespos;
|
||||
qboolean harderror;
|
||||
size_t m_iNumBytesIO;
|
||||
qboolean silent;
|
||||
str filename;
|
||||
qboolean fileerror;
|
||||
ArchiveFile archivefile;
|
||||
int archivemode;
|
||||
int numclassespos;
|
||||
qboolean harderror;
|
||||
size_t m_iNumBytesIO;
|
||||
qboolean silent;
|
||||
|
||||
void CheckRead( void );
|
||||
void CheckType( int type );
|
||||
int ReadType( void );
|
||||
fileSize_t ReadSize( void );
|
||||
void CheckSize( int type, fileSize_t size );
|
||||
void ArchiveData( int type, void *data, size_t size );
|
||||
void CheckRead(void);
|
||||
void CheckType(int type);
|
||||
int ReadType(void);
|
||||
fileSize_t ReadSize(void);
|
||||
void CheckSize(int type, fileSize_t size);
|
||||
void ArchiveData(int type, void *data, size_t size);
|
||||
|
||||
void CheckWrite( void );
|
||||
void WriteType( int type );
|
||||
void WriteSize(fileSize_t size );
|
||||
void CheckWrite(void);
|
||||
void WriteType(int type);
|
||||
void WriteSize(fileSize_t size);
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( Archiver );
|
||||
Archiver();
|
||||
~Archiver();
|
||||
void FileError(const char *fmt, ...);
|
||||
void Close(void);
|
||||
|
||||
Archiver();
|
||||
~Archiver();
|
||||
void FileError( const char *fmt, ... );
|
||||
void Close( void );
|
||||
qboolean Read(str& name, qboolean harderror = qtrue);
|
||||
qboolean Read(const char *name, qboolean harderror = qtrue);
|
||||
Class *ReadObject(void);
|
||||
|
||||
qboolean Read( str &name, qboolean harderror = qtrue );
|
||||
qboolean Read( const char *name, qboolean harderror = qtrue );
|
||||
Class *ReadObject( void );
|
||||
qboolean Create(str& name, qboolean harderror = qtrue);
|
||||
qboolean Create(const char *name, qboolean harderror = qtrue);
|
||||
|
||||
qboolean Create( str &name, qboolean harderror = qtrue );
|
||||
qboolean Create( const char *name, qboolean harderror = qtrue );
|
||||
qboolean Loading(void);
|
||||
qboolean Saving(void);
|
||||
qboolean NoErrors(void);
|
||||
|
||||
qboolean Loading( void );
|
||||
qboolean Saving( void );
|
||||
qboolean NoErrors( void );
|
||||
void ArchiveVector(Vector *vec);
|
||||
void ArchiveQuat(Quat *quat);
|
||||
void ArchiveInteger(int *num);
|
||||
void ArchiveUnsigned(unsigned *unum);
|
||||
void ArchiveSize(long *unum);
|
||||
void ArchiveByte(byte *num);
|
||||
void ArchiveChar(char *ch);
|
||||
void ArchiveShort(short *num);
|
||||
void ArchiveUnsignedShort(unsigned short *num);
|
||||
void ArchiveFloat(float *num);
|
||||
void ArchiveDouble(double *num);
|
||||
void ArchiveBoolean(qboolean *boolean);
|
||||
void ArchiveString(str *string);
|
||||
void ArchiveObjectPointer(LightClass **ptr);
|
||||
void ArchiveObjectPointer(Class **ptr);
|
||||
void ArchiveObjectPosition(LightClass *obj);
|
||||
void ArchiveSafePointer(SafePtrBase *ptr);
|
||||
void ArchiveEventPointer(Event **ev);
|
||||
void ArchiveBool(bool *boolean);
|
||||
void ArchivePosition(int *pos);
|
||||
void ArchiveSvsTime(int *time);
|
||||
void ArchiveVec2(vec2_t vec);
|
||||
void ArchiveVec3(vec3_t vec);
|
||||
void ArchiveVec4(vec4_t vec);
|
||||
|
||||
void ArchiveVector( Vector * vec );
|
||||
void ArchiveQuat( Quat * quat );
|
||||
void ArchiveInteger( int * num );
|
||||
void ArchiveUnsigned( unsigned * unum );
|
||||
void ArchiveSize( long * unum );
|
||||
void ArchiveByte( byte * num );
|
||||
void ArchiveChar( char * ch );
|
||||
void ArchiveShort( short * num );
|
||||
void ArchiveUnsignedShort( unsigned short * num );
|
||||
void ArchiveFloat( float * num );
|
||||
void ArchiveDouble( double * num );
|
||||
void ArchiveBoolean( qboolean * boolean );
|
||||
void ArchiveString( str * string );
|
||||
void ArchiveConfigString( int cs );
|
||||
void ArchiveObjectPointer( Class ** ptr );
|
||||
void ArchiveObjectPosition( void *obj );
|
||||
void ArchiveSafePointer( SafePtrBase * ptr );
|
||||
void ArchiveEventPointer( Event ** ev );
|
||||
void ArchiveBool( bool * boolean );
|
||||
void ArchivePosition( int * pos );
|
||||
void ArchiveSvsTime( int * time );
|
||||
void ArchiveVec2( vec2_t vec );
|
||||
void ArchiveVec3( vec3_t vec );
|
||||
void ArchiveVec4( vec4_t vec );
|
||||
void ArchiveRaw(void *data, size_t size);
|
||||
void ArchiveObject(Class *obj);
|
||||
|
||||
void ArchiveRaw( void *data, size_t size );
|
||||
void ArchiveObject( Class *obj );
|
||||
qboolean ObjectPositionExists(void *obj);
|
||||
|
||||
qboolean ObjectPositionExists( void * obj );
|
||||
|
||||
void SetSilent( bool bSilent );
|
||||
void Reset();
|
||||
size_t Counter() const;
|
||||
|
||||
void ArchiveConfigString(int cs);
|
||||
void SetSilent(bool bSilent);
|
||||
};
|
||||
|
||||
inline qboolean Archiver::Read
|
||||
(
|
||||
str &name,
|
||||
qboolean harderror
|
||||
)
|
||||
template<class Type>
|
||||
inline void Container<Type>::Archive(Archiver& arc, void (*ArchiveFunc)(Archiver& arc, Type *obj))
|
||||
{
|
||||
return Read( name.c_str(), harderror );
|
||||
}
|
||||
int num;
|
||||
int i;
|
||||
|
||||
inline qboolean Archiver::Create
|
||||
(
|
||||
str &name,
|
||||
qboolean harderror
|
||||
)
|
||||
{
|
||||
return Create( name.c_str(), harderror );
|
||||
}
|
||||
if (arc.Loading()) {
|
||||
arc.ArchiveInteger(&num);
|
||||
Resize(num);
|
||||
} else {
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger(&num);
|
||||
}
|
||||
|
||||
inline qboolean Archiver::Loading
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return (archivemode == ARCHIVE_READ) ? qtrue : qfalse;
|
||||
}
|
||||
for (i = 1; i <= num; i++) {
|
||||
if (num > numobjects) {
|
||||
numobjects = num;
|
||||
}
|
||||
|
||||
inline qboolean Archiver::Saving
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return (archivemode == ARCHIVE_WRITE) ? qtrue : qfalse;
|
||||
}
|
||||
|
||||
inline qboolean Archiver::NoErrors
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return fileerror ? qfalse : qtrue;
|
||||
}
|
||||
|
||||
template< class Type >
|
||||
inline void Container<Type>::Archive
|
||||
(
|
||||
Archiver& arc,
|
||||
void( *ArchiveFunc )( Archiver& arc, Type *obj )
|
||||
)
|
||||
{
|
||||
int num;
|
||||
int i;
|
||||
|
||||
if( arc.Loading() )
|
||||
{
|
||||
arc.ArchiveInteger( &num );
|
||||
Resize( num );
|
||||
}
|
||||
else
|
||||
{
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger( &num );
|
||||
}
|
||||
|
||||
for( i = 1; i <= num; i++ )
|
||||
{
|
||||
if( num > numobjects ) {
|
||||
numobjects = num;
|
||||
}
|
||||
|
||||
ArchiveFunc( arc, &objlist[ i - 1 ] );
|
||||
}
|
||||
ArchiveFunc(arc, &objlist[i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void Container<str>::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
inline void Container<str>::Archive(Archiver& arc)
|
||||
{
|
||||
int i, num;
|
||||
int i, num;
|
||||
|
||||
if( arc.Loading() )
|
||||
{
|
||||
ClearObjectList();
|
||||
arc.ArchiveInteger( &num );
|
||||
Resize( num );
|
||||
}
|
||||
else
|
||||
{
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger( &num );
|
||||
}
|
||||
for( i = 1; i <= num; i++ )
|
||||
{
|
||||
arc.ArchiveString( AddressOfObjectAt( i ) );
|
||||
}
|
||||
if (arc.Loading()) {
|
||||
ClearObjectList();
|
||||
arc.ArchiveInteger(&num);
|
||||
Resize(num);
|
||||
} else {
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger(&num);
|
||||
}
|
||||
for (i = 1; i <= num; i++) {
|
||||
arc.ArchiveString(AddressOfObjectAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void Container<Vector>::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
inline void Container<Vector>::Archive(Archiver& arc)
|
||||
{
|
||||
int i, num;
|
||||
int i, num;
|
||||
|
||||
if( arc.Loading() )
|
||||
{
|
||||
ClearObjectList();
|
||||
arc.ArchiveInteger( &num );
|
||||
Resize( num );
|
||||
}
|
||||
else
|
||||
{
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger( &num );
|
||||
}
|
||||
for( i = 1; i <= num; i++ )
|
||||
{
|
||||
arc.ArchiveVector( AddressOfObjectAt( i ) );
|
||||
}
|
||||
if (arc.Loading()) {
|
||||
ClearObjectList();
|
||||
arc.ArchiveInteger(&num);
|
||||
Resize(num);
|
||||
} else {
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger(&num);
|
||||
}
|
||||
for (i = 1; i <= num; i++) {
|
||||
arc.ArchiveVector(AddressOfObjectAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void Container<int>::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
inline void Container<int>::Archive(Archiver& arc)
|
||||
{
|
||||
int i, num;
|
||||
int i, num;
|
||||
|
||||
if( arc.Loading() )
|
||||
{
|
||||
ClearObjectList();
|
||||
arc.ArchiveInteger( &num );
|
||||
Resize( num );
|
||||
}
|
||||
else
|
||||
{
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger( &num );
|
||||
}
|
||||
for( i = 1; i <= num; i++ )
|
||||
{
|
||||
arc.ArchiveInteger( AddressOfObjectAt( i ) );
|
||||
}
|
||||
if (arc.Loading()) {
|
||||
ClearObjectList();
|
||||
arc.ArchiveInteger(&num);
|
||||
Resize(num);
|
||||
} else {
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger(&num);
|
||||
}
|
||||
for (i = 1; i <= num; i++) {
|
||||
arc.ArchiveInteger(AddressOfObjectAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void Container<float>::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
inline void Container<float>::Archive(Archiver& arc)
|
||||
{
|
||||
int i, num;
|
||||
int i, num;
|
||||
|
||||
if( arc.Loading() )
|
||||
{
|
||||
ClearObjectList();
|
||||
arc.ArchiveInteger( &num );
|
||||
Resize( num );
|
||||
}
|
||||
else
|
||||
{
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger( &num );
|
||||
}
|
||||
for( i = 1; i <= num; i++ )
|
||||
{
|
||||
arc.ArchiveFloat( AddressOfObjectAt( i ) );
|
||||
}
|
||||
if (arc.Loading()) {
|
||||
ClearObjectList();
|
||||
arc.ArchiveInteger(&num);
|
||||
Resize(num);
|
||||
} else {
|
||||
num = numobjects;
|
||||
arc.ArchiveInteger(&num);
|
||||
}
|
||||
for (i = 1; i <= num; i++) {
|
||||
arc.ArchiveFloat(AddressOfObjectAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
template< typename c >
|
||||
inline void ArchiveClass
|
||||
(
|
||||
Archiver& arc,
|
||||
c *obj
|
||||
)
|
||||
template<typename c>
|
||||
inline void ArchiveClass(Archiver& arc, c *obj)
|
||||
{
|
||||
arc.ArchiveObject( obj );
|
||||
arc.ArchiveObject(obj);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void Container<Type>::Archive(Archiver& arc)
|
||||
{
|
||||
Archive(arc, ArchiveClass<Type>);
|
||||
}
|
||||
|
||||
#ifndef NO_ARCHIVE
|
||||
|
||||
template< typename key, typename value >
|
||||
void con_set< key, value >::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
template<typename key, typename value>
|
||||
void con_set<key, value>::Archive(Archiver& arc)
|
||||
{
|
||||
Entry *e;
|
||||
int hash;
|
||||
int i;
|
||||
Entry *e = NULL;
|
||||
int hash;
|
||||
int i;
|
||||
|
||||
arc.ArchiveUnsigned( &tableLength );
|
||||
arc.ArchiveUnsigned( &threshold );
|
||||
arc.ArchiveUnsigned( &count );
|
||||
arc.ArchiveUnsignedShort( &tableLengthIndex );
|
||||
arc.ArchiveUnsigned(&tableLength);
|
||||
arc.ArchiveUnsigned(&threshold);
|
||||
arc.ArchiveUnsigned(&count);
|
||||
arc.ArchiveUnsignedShort(&tableLengthIndex);
|
||||
|
||||
if( arc.Loading() )
|
||||
{
|
||||
if( tableLength != 1 )
|
||||
{
|
||||
table = new Entry *[ tableLength ]();
|
||||
memset( table, 0, tableLength * sizeof( Entry * ) );
|
||||
}
|
||||
if (arc.Loading()) {
|
||||
if (tableLength != 1) {
|
||||
table = new Entry *[tableLength]();
|
||||
memset(table, 0, tableLength * sizeof(Entry *));
|
||||
}
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
e = new Entry;
|
||||
e->Archive( arc );
|
||||
for (i = 0; i < count; i++) {
|
||||
e = new Entry;
|
||||
e->Archive(arc);
|
||||
|
||||
hash = HashCode< key >( e->key ) % tableLength;
|
||||
hash = HashCode<key>(e->GetKey()) % tableLength;
|
||||
|
||||
e->next = table[ hash ];
|
||||
table[ hash ] = e;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = tableLength - 1; i >= 0; i-- )
|
||||
{
|
||||
for( e = table[ i ]; e != NULL; e = e->next )
|
||||
{
|
||||
e->Archive( arc );
|
||||
}
|
||||
}
|
||||
}
|
||||
e->next = table[hash];
|
||||
table[hash] = e;
|
||||
}
|
||||
|
||||
defaultEntry = e;
|
||||
} else {
|
||||
#ifndef NDEBUG
|
||||
int total;
|
||||
|
||||
total = 0;
|
||||
|
||||
for (i = 0; i < tableLength; i++) {
|
||||
for (e = table[i]; e != NULL; e = e->next) {
|
||||
e->Archive(arc);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
// it must match the number of elements
|
||||
assert(total == count);
|
||||
#else
|
||||
for (i = 0; i < tableLength; i++) {
|
||||
for (e = table[i]; e != NULL; e = e->next) {
|
||||
e->Archive(arc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template< typename key, typename value >
|
||||
void con_map< key, value >::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
template<typename key, typename value>
|
||||
void con_map<key, value>::Archive(Archiver& arc)
|
||||
{
|
||||
m_con_set.Archive( arc );
|
||||
m_con_set.Archive(arc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define ArchiveEnum( thing, type ) \
|
||||
{ \
|
||||
int tempInt; \
|
||||
\
|
||||
tempInt = ( int )( thing ); \
|
||||
arc.ArchiveInteger( &tempInt ); \
|
||||
( thing ) = ( type )tempInt; \
|
||||
}
|
||||
#define ArchiveEnum(thing, type) \
|
||||
{ \
|
||||
int tempInt; \
|
||||
\
|
||||
tempInt = (int)(thing); \
|
||||
arc.ArchiveInteger(&tempInt); \
|
||||
(thing) = (type)tempInt; \
|
||||
}
|
||||
|
||||
#endif // __ARCHIVE_H__
|
||||
+14
-13
@@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "beam.h"
|
||||
#include "../qcommon/qfiles.h"
|
||||
#include "game.h"
|
||||
#include <utility>
|
||||
|
||||
/*****************************************************************************/
|
||||
/*QUAKED func_beam (0 0.25 .5) (-8 -8 -8) (8 8 8) START_ON PERSIST WAVE NOISE
|
||||
@@ -765,19 +766,19 @@ void FuncBeam::Activate
|
||||
}
|
||||
|
||||
void FuncBeam::UpdateEndpoint
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
(
|
||||
Event* ev
|
||||
)
|
||||
|
||||
{
|
||||
if ( end )
|
||||
{
|
||||
Event *ev1 = new Event( ev );
|
||||
{
|
||||
if (end)
|
||||
{
|
||||
Event* ev1 = new Event(std::move(*ev));
|
||||
|
||||
VectorCopy( end->origin, edict->s.origin2 );
|
||||
PostEvent( ev1, level.frametime );
|
||||
}
|
||||
}
|
||||
VectorCopy(end->origin, edict->s.origin2);
|
||||
PostEvent(ev1, level.frametime);
|
||||
}
|
||||
}
|
||||
|
||||
void FuncBeam::UpdateOrigin
|
||||
(
|
||||
@@ -786,8 +787,8 @@ void FuncBeam::UpdateOrigin
|
||||
|
||||
{
|
||||
if ( origin_target )
|
||||
{
|
||||
Event *ev1 = new Event( ev );
|
||||
{
|
||||
Event* ev1 = new Event(std::move(*ev));
|
||||
|
||||
setOrigin( origin_target->centroid );
|
||||
PostEvent( ev1, level.frametime );
|
||||
|
||||
@@ -76,6 +76,9 @@ extern float pm_friction;
|
||||
extern float pm_waterfriction;
|
||||
extern float pm_flightfriction;
|
||||
|
||||
extern const vec3_t MINS;
|
||||
extern const vec3_t MAXS;
|
||||
|
||||
extern int c_pmove;
|
||||
|
||||
void PM_ClipVelocity( vec3_t in, vec3_t normal, vec3_t out, float overbounce );
|
||||
|
||||
+12
-4
@@ -48,6 +48,9 @@ float pm_backspeed = 0.80f;
|
||||
float pm_flightfriction = 3.0f;
|
||||
float PM_NOCLIPfriction = 5.0f;
|
||||
|
||||
const vec3_t MINS = { -15, -15, 0 };
|
||||
const vec3_t MAXS = { 15, 15, 94 };
|
||||
|
||||
int c_pmove = 0;
|
||||
|
||||
/*
|
||||
@@ -1520,22 +1523,27 @@ void PmoveSingle( pmove_t *pmove )
|
||||
{
|
||||
float fLeanAngle = pml.frametime * -pm->leanSpeed;
|
||||
|
||||
if( fAngle <= fLeanAngle )
|
||||
{
|
||||
if(fLeanAngle >= fAngle) {
|
||||
fLeanAngle = fAngle;
|
||||
}
|
||||
|
||||
pm->ps->fLeanAngle -= fLeanAngle;
|
||||
if (pm->ps->fLeanAngle > 0) {
|
||||
pm->ps->fLeanAngle = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float fLeanAngle = pml.frametime * pm->leanSpeed;
|
||||
|
||||
if(fAngle >= fLeanAngle) {
|
||||
if(fLeanAngle <= fAngle) {
|
||||
fLeanAngle = fAngle;
|
||||
}
|
||||
|
||||
pm->ps->fLeanAngle -= fLeanAngle;
|
||||
pm->ps->fLeanAngle -= fLeanAngle;
|
||||
if (pm->ps->fLeanAngle < 0) {
|
||||
pm->ps->fLeanAngle = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+154
-197
@@ -25,34 +25,25 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// because games can change separately from the main system version, we need a
|
||||
// second version that must match between game and cgame
|
||||
|
||||
#ifndef __BG_PUBLIC_H__
|
||||
#define __BG_PUBLIC_H__
|
||||
#pragma once
|
||||
|
||||
#define GAME_VERSION "mohaa-base-1"
|
||||
#define GAME_VERSION "mohaa-base-1"
|
||||
|
||||
#define DEFAULT_GRAVITY 800
|
||||
static const unsigned int MINS_X = -15;
|
||||
static const unsigned int MINS_Y = -15;
|
||||
static const unsigned int MINS_Z = 0; // IneQuation: bounding box and viewheights to match MoHAA
|
||||
static const unsigned int MAXS_X = 15;
|
||||
static const unsigned int MAXS_Y = 15;
|
||||
static const unsigned int MAXS_Z = 96;
|
||||
|
||||
#define SCORE_NOT_PRESENT -9999 // for the CS_SCORES[12] when only one player is present
|
||||
|
||||
#define VOTE_TIME 30000 // 30 seconds before vote times out
|
||||
|
||||
#define MINS_Z 0
|
||||
#define MINS_X -15
|
||||
#define MINS_Y -15
|
||||
#define MAXS_X 15
|
||||
#define MAXS_Y 15
|
||||
|
||||
#define MINS_Z 0 // IneQuation: bounding box and viewheights to match MoHAA
|
||||
#define MAXS_Z 96
|
||||
|
||||
#define DEAD_MINS_Z 32
|
||||
#define CROUCH_MAXS_Z 49
|
||||
#define DEFAULT_VIEWHEIGHT 82
|
||||
#define CROUCH_RUN_VIEWHEIGHT 64
|
||||
#define JUMP_START_VIEWHEIGHT 52
|
||||
#define CROUCH_VIEWHEIGHT 48
|
||||
#define PRONE_VIEWHEIGHT 16
|
||||
#define DEAD_VIEWHEIGHT 8
|
||||
static const unsigned int DEAD_MINS_Z = 32;
|
||||
static const unsigned int CROUCH_MAXS_Z = 49;
|
||||
static const unsigned int DEFAULT_VIEWHEIGHT = 82;
|
||||
static const unsigned int CROUCH_RUN_VIEWHEIGHT = 64;
|
||||
static const unsigned int JUMP_START_VIEWHEIGHT = 52;
|
||||
static const unsigned int CROUCH_VIEWHEIGHT = 48;
|
||||
static const unsigned int PRONE_VIEWHEIGHT = 16;
|
||||
static const unsigned int DEAD_VIEWHEIGHT = 8;
|
||||
|
||||
//
|
||||
// config strings are a general means of communicating variable length strings
|
||||
@@ -140,10 +131,10 @@ extern "C" {
|
||||
GT_MAX_GAME_TYPE
|
||||
} gametype_t;
|
||||
|
||||
//
|
||||
// scale to use when evaluating entityState_t::constantLight scale
|
||||
//
|
||||
#define CONSTANTLIGHT_RADIUS_SCALE 8
|
||||
//
|
||||
// scale to use when evaluating entityState_t::constantLight scale
|
||||
//
|
||||
static const float CONSTANTLIGHT_RADIUS_SCALE = 8;
|
||||
|
||||
typedef enum {
|
||||
GENDER_MALE,
|
||||
@@ -151,30 +142,31 @@ extern "C" {
|
||||
GENDER_NEUTER
|
||||
} gender_t;
|
||||
|
||||
// su44: vma indexes are sent as 4 bits
|
||||
// see playerState_t::iViewModelAnim
|
||||
typedef enum {
|
||||
VMA_IDLE,
|
||||
VMA_CHARGE,
|
||||
VMA_FIRE,
|
||||
VMA_FIRE_SECONDARY,
|
||||
VMA_RECHAMBER,
|
||||
VMA_RELOAD,
|
||||
VMA_RELOAD_SINGLE,
|
||||
VMA_RELOAD_END,
|
||||
VMA_PULLOUT,
|
||||
VMA_PUTAWAY,
|
||||
VMA_LADDERSTEP,
|
||||
VMA_ENABLE,
|
||||
VMA_CUSTOMANIMATION,
|
||||
VMA_NUMANIMATIONS
|
||||
} viewmodelanim_t;
|
||||
enum vmAnim_e {
|
||||
VM_ANIM_DISABLED,
|
||||
VM_ANIM_IDLE,
|
||||
VM_ANIM_CHARGE,
|
||||
VM_ANIM_FIRE,
|
||||
VM_ANIM_FIRE_SECONDARY,
|
||||
VM_ANIM_RECHAMBER,
|
||||
VM_ANIM_RELOAD,
|
||||
VM_ANIM_RELOAD_SINGLE,
|
||||
VM_ANIM_RELOAD_END,
|
||||
VM_ANIM_PULLOUT,
|
||||
VM_ANIM_PUTAWAY,
|
||||
VM_ANIM_LADDERSTEP,
|
||||
VM_ANIM_IDLE_0,
|
||||
VM_ANIM_IDLE_1,
|
||||
VM_ANIM_IDLE_2,
|
||||
};
|
||||
|
||||
// su44: playerState_t::activeItems[8] slots
|
||||
// they are sent as 16 bits
|
||||
// TODO: find out rest of them
|
||||
#define ITEM_AMMO 0 // current ammo
|
||||
#define ITEM_WEAPON 1 // current mainhand weapon
|
||||
// su44: playerState_t::activeItems[8] slots
|
||||
// they are sent as 16 bits
|
||||
// TODO: find out rest of them
|
||||
enum itemtype_e {
|
||||
ITEM_AMMO,
|
||||
ITEM_WEAPON
|
||||
};
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
@@ -187,17 +179,12 @@ movement on the server game.
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
#define MAX_CLIP_PLANES 5
|
||||
#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes
|
||||
static const unsigned int MAX_CLIP_PLANES = 5;
|
||||
static const float MIN_WALK_NORMAL = 0.7f; // can't walk on very steep slopes
|
||||
|
||||
#define STEPSIZE 18
|
||||
static const float STEPSIZE = 18;
|
||||
|
||||
#define WATER_TURBO_SPEED 1.35f
|
||||
#define WATER_TURBO_TIME 1200
|
||||
#define MINIMUM_RUNNING_TIME 800
|
||||
#define MINIMUM_WATER_FOR_TURBO 90
|
||||
|
||||
#define OVERCLIP 1.001f
|
||||
static const float OVERCLIP = 1.001f;
|
||||
|
||||
// su44: our pmtype_t enum must be the same
|
||||
// as in MoHAA, because playerState_t::pm_type
|
||||
@@ -251,8 +238,9 @@ movement on the server game.
|
||||
#endif
|
||||
|
||||
// moh pm_flags
|
||||
#define PMF_DUCKED (1 << 0)
|
||||
#define PMF_VIEW_PRONE (1 << 1)
|
||||
#define PMF_DUCKED (1 << 0)
|
||||
#define PMF_VIEW_PRONE (1 << 1)
|
||||
#define PMF_DAMAGE_ANGLES (1 << 1) // in protocol >= 15
|
||||
//
|
||||
// 2 Flags removed in team tactics
|
||||
//
|
||||
@@ -272,22 +260,25 @@ movement on the server game.
|
||||
#define PMF_UNKNOWN (1 << 14)
|
||||
#define PMF_NO_LEAN (1 << 15)
|
||||
|
||||
// moveposflags
|
||||
#define MPF_POSITION_STANDING (1 << 0)
|
||||
#define MPF_POSITION_CROUCHING (1 << 1)
|
||||
#define MPF_POSITION_PRONE (1 << 2)
|
||||
#define MPF_POSITION_OFFGROUND (1 << 3)
|
||||
// moveposflags
|
||||
enum moveposflags_e {
|
||||
MPF_POSITION_STANDING = (1 << 0),
|
||||
MPF_POSITION_CROUCHING = (1 << 1),
|
||||
MPF_POSITION_PRONE = (1 << 2),
|
||||
MPF_POSITION_OFFGROUND = (1 << 3),
|
||||
MPF_MOVEMENT_WALKING = (1 << 4),
|
||||
MPF_MOVEMENT_RUNNING = (1 << 5),
|
||||
MPF_MOVEMENT_FALLING = (1 << 6),
|
||||
};
|
||||
|
||||
#define MPF_MOVEMENT_WALKING (1 << 4)
|
||||
#define MPF_MOVEMENT_RUNNING (1 << 5)
|
||||
#define MPF_MOVEMENT_FALLING (1 << 6)
|
||||
#define MAXTOUCH 32
|
||||
|
||||
#define MAXTOUCH 32
|
||||
|
||||
#define MOVERESULT_NONE 0 // nothing blocking
|
||||
#define MOVERESULT_TURNED 1 // move blocked, but player turned to avoid it
|
||||
#define MOVERESULT_BLOCKED 2 // move blocked by slope or wall
|
||||
#define MOVERESULT_HITWALL 3 // player ran into wall
|
||||
enum moveresult_e {
|
||||
MOVERESULT_NONE, // nothing blocking
|
||||
MOVERESULT_TURNED, // move blocked, but player turned to avoid it
|
||||
MOVERESULT_BLOCKED, // move blocked by slope or wall
|
||||
MOVERESULT_HITWALL // player ran into wall
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
// state (in / out)
|
||||
@@ -339,7 +330,7 @@ movement on the server game.
|
||||
//
|
||||
// Openmohaa addition
|
||||
//
|
||||
int protocol;
|
||||
int protocol;
|
||||
float leanSpeed;
|
||||
float leanRecoverSpeed;
|
||||
float leanAdd;
|
||||
@@ -359,35 +350,33 @@ movement on the server game.
|
||||
|
||||
//===================================================================================
|
||||
|
||||
#define MAX_LETTERBOX_SIZE 0x7fff
|
||||
static const unsigned int MAX_LETTERBOX_SIZE = 0x7fff;
|
||||
|
||||
#define ITEM_NAME_AMMO 0
|
||||
#define ITEM_NAME_WEAPON 1
|
||||
|
||||
#define WEAPON_CLASS_PISTOL (1 << 0)
|
||||
#define WEAPON_CLASS_RIFLE (1 << 1)
|
||||
#define WEAPON_CLASS_SMG (1 << 2)
|
||||
#define WEAPON_CLASS_MG (1 << 3)
|
||||
#define WEAPON_CLASS_GRENADE (1 << 4)
|
||||
#define WEAPON_CLASS_HEAVY (1 << 5)
|
||||
#define WEAPON_CLASS_CANNON (1 << 6)
|
||||
#define WEAPON_CLASS_ITEM (1 << 7)
|
||||
#define WEAPON_CLASS_ITEM1 (1 << 8)
|
||||
#define WEAPON_CLASS_ITEM2 (1 << 9)
|
||||
#define WEAPON_CLASS_ITEM3 (1 << 10)
|
||||
#define WEAPON_CLASS_ITEM4 (1 << 11)
|
||||
#define WEAPON_CLASS_ANY_ITEM \
|
||||
(WEAPON_CLASS_ITEM | WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4)
|
||||
|
||||
#define WEAPON_CLASS_PRIMARY (!(WEAPON_CLASS_PISTOL | WEAPON_CLASS_GRENADE))
|
||||
#define WEAPON_CLASS_SECONDARY (WEAPON_CLASS_PISTOL | WEAPON_CLASS_GRENADE)
|
||||
#define WEAPON_CLASS_THROWABLE (WEAPON_CLASS_GRENADE | WEAPON_CLASS_ITEM)
|
||||
#define WEAPON_CLASS_MISC \
|
||||
(WEAPON_CLASS_CANNON | WEAPON_CLASS_ITEM | WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 \
|
||||
| WEAPON_CLASS_ITEM4)
|
||||
#define WEAPON_CLASS_ITEMINDEX (WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4)
|
||||
|
||||
#define STAT_DEAD_YAW 5 // su44: Is there a DEAD_YAW stat in MoHAA?
|
||||
enum weaponclass_e {
|
||||
WEAPON_CLASS_PISTOL = (1 << 0),
|
||||
WEAPON_CLASS_RIFLE = (1 << 1),
|
||||
WEAPON_CLASS_SMG = (1 << 2),
|
||||
WEAPON_CLASS_MG = (1 << 3),
|
||||
WEAPON_CLASS_GRENADE = (1 << 4),
|
||||
WEAPON_CLASS_HEAVY = (1 << 5),
|
||||
WEAPON_CLASS_CANNON = (1 << 6),
|
||||
WEAPON_CLASS_ITEM = (1 << 7),
|
||||
WEAPON_CLASS_ITEM1 = (1 << 8),
|
||||
WEAPON_CLASS_ITEM2 = (1 << 9),
|
||||
WEAPON_CLASS_ITEM3 = (1 << 10),
|
||||
WEAPON_CLASS_ITEM4 = (1 << 11),
|
||||
WEAPON_CLASS_ANY_ITEM =
|
||||
(WEAPON_CLASS_ITEM | WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4),
|
||||
WEAPON_CLASS_ITEM_SLOT_BITS =
|
||||
(WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4),
|
||||
WEAPON_CLASS_PRIMARY = (!(WEAPON_CLASS_PISTOL | WEAPON_CLASS_GRENADE)),
|
||||
WEAPON_CLASS_SECONDARY = (WEAPON_CLASS_PISTOL | WEAPON_CLASS_GRENADE),
|
||||
WEAPON_CLASS_THROWABLE = (WEAPON_CLASS_GRENADE | WEAPON_CLASS_ITEM),
|
||||
WEAPON_CLASS_MISC =
|
||||
(WEAPON_CLASS_CANNON | WEAPON_CLASS_ITEM | WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3
|
||||
| WEAPON_CLASS_ITEM4),
|
||||
WEAPON_CLASS_ITEMINDEX = (WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4)
|
||||
};
|
||||
|
||||
// player_state->persistant[] indexes
|
||||
// these fields are the only part of player_state that isn't
|
||||
@@ -400,6 +389,7 @@ movement on the server game.
|
||||
|
||||
// entityState_t->eFlags
|
||||
// su44: eFlags used in MoHAA
|
||||
#define EF_EVERYFRAME 0x00000008
|
||||
#define EF_CLIMBWALL 0x00000010
|
||||
#define EF_UNARMED 0x00000020 // su44: this player has his weapon holstered
|
||||
#define EF_LINKANGLES 0x00000040
|
||||
@@ -407,6 +397,8 @@ movement on the server game.
|
||||
#define EF_AXIS 0x00000100 // su44: this player is in axis team
|
||||
#define EF_ANY_TEAM (EF_ALLIES | EF_AXIS)
|
||||
#define EF_DEAD 0x00000200 // don't draw a foe marker over players with EF_DEAD
|
||||
#define EF_NO_LERP 0x00001000 // don't lerp animations
|
||||
|
||||
//
|
||||
// Team assault flags
|
||||
//
|
||||
@@ -431,33 +423,11 @@ movement on the server game.
|
||||
#define EF_AWARD_ASSIST 0x00020000 // draw a assist sprite
|
||||
#define EF_AWARD_DENIED 0x00040000 // denied
|
||||
#define EF_TEAMVOTED 0x00080000 // already cast a team vote
|
||||
#define EF_EVERYFRAME 0x00100000 // def commands will be run every client frame
|
||||
#define EF_ANTISBJUICE 0x00200000 // anti sucknblow juice
|
||||
#define EF_DONT_PROCESS_COMMANDS 0x00400000 // don't process client commands for this entity
|
||||
|
||||
// these defines could be deleted sometime when code/game/ is cleared of Q3A stuff
|
||||
#define TEAM_FREE 0
|
||||
#define TEAM_RED 4
|
||||
#define TEAM_BLUE 3
|
||||
#define TEAM_NUM_TEAMS 5
|
||||
|
||||
//===================================================================================
|
||||
|
||||
// flip the togglebit every time an animation
|
||||
// changes so a restart of the same anim can be detected
|
||||
#define ANIM_TOGGLEBIT (1 << 9)
|
||||
#define ANIM_BLEND (1 << 10)
|
||||
#define ANIM_NUMBITS 11
|
||||
|
||||
// server side anim bits
|
||||
#define ANIM_SERVER_EXITCOMMANDS_PROCESSED (1 << 12)
|
||||
|
||||
#define ANIM_MASK (~(ANIM_TOGGLEBIT | ANIM_BLEND | ANIM_SERVER_EXITCOMMANDS_PROCESSED))
|
||||
|
||||
// if FRAME_EXPLICIT is set, don't auto animate
|
||||
#define FRAME_EXPLICIT 512
|
||||
#define FRAME_MASK (~FRAME_EXPLICIT)
|
||||
|
||||
//
|
||||
// Tag specific flags
|
||||
//
|
||||
@@ -558,8 +528,8 @@ movement on the server game.
|
||||
STAT_MAXCLIPAMMO,
|
||||
STAT_INZOOM,
|
||||
STAT_CROSSHAIR,
|
||||
STAT_LAST_PAIN,
|
||||
STAT_NEXTHEALTH, // was unused until 2.0
|
||||
STAT_LAST_PAIN,
|
||||
STAT_NEXTHEALTH, // was unused until 2.0
|
||||
STAT_BOSSHEALTH,
|
||||
STAT_CINEMATIC,
|
||||
STAT_ADDFADE,
|
||||
@@ -570,9 +540,9 @@ movement on the server game.
|
||||
STAT_OBJECTIVECENTER,
|
||||
STAT_TEAM,
|
||||
STAT_KILLS,
|
||||
STAT_DEATHS,
|
||||
STAT_VEHICLE_HEALTH, // was unused until 2.0
|
||||
STAT_VEHICLE_MAX_HEALTH, // was unused until 2.0
|
||||
STAT_DEATHS,
|
||||
STAT_VEHICLE_HEALTH, // was unused until 2.0
|
||||
STAT_VEHICLE_MAX_HEALTH, // was unused until 2.0
|
||||
STAT_HIGHEST_SCORE,
|
||||
STAT_ATTACKERCLIENT,
|
||||
STAT_INFOCLIENT,
|
||||
@@ -598,9 +568,6 @@ movement on the server game.
|
||||
SWT_FUSE_WET
|
||||
} stopWatchType_t;
|
||||
|
||||
// How many players on the overlay
|
||||
#define TEAM_MAXOVERLAY 32
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
// g_dmflags->integer flags
|
||||
@@ -635,28 +602,34 @@ movement on the server game.
|
||||
#define DF_WEAPON_NO_SHOTGUN (1 << 27)
|
||||
#define DF_WEAPON_NO_LANDMINE (1 << 28)
|
||||
|
||||
#define DM_FLAG(flag) (g_gametype->integer && ((int)dmflags->integer & (flag)))
|
||||
#define DM_FLAG(flag) (g_gametype->integer != GT_SINGLE_PLAYER && ((int)dmflags->integer & (flag)))
|
||||
|
||||
// content masks
|
||||
#define MASK_ALL (-1)
|
||||
#define MASK_SOLID (CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
|
||||
#define MASK_ALL (-1)
|
||||
#define MASK_SOLID \
|
||||
(CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX | CONTENTS_FENCE)
|
||||
#define MASK_SAFESOLID (CONTENTS_BODY | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
|
||||
#define MASK_USABLE (CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_BODY)
|
||||
#define MASK_PLAYERSOLID \
|
||||
(CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_BODY | CONTENTS_TRIGGER | CONTENTS_FENCE | CONTENTS_UNKNOWN2 \
|
||||
| CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
|
||||
#define MASK_PLAYERSTART (CONTENTS_SOLID|CONTENTS_BBOX|CONTENTS_NOBOTCLIP|CONTENTS_UNKNOWN2|CONTENTS_BODY)
|
||||
#define MASK_GUNTARGET \
|
||||
(CONTENTS_SOLID | CONTENTS_LADDER | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_CLAYPIDGEON | CONTENTS_BBOX \
|
||||
| CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_UNKNOWN3 | CONTENTS_FENCE | CONTENTS_BODY | CONTENTS_CORPSE \
|
||||
| CONTENTS_TRIGGER)
|
||||
#define MASK_FOOTSHADOW (CONTENTS_FENCE | CONTENTS_SLIME | CONTENTS_LAVA | CONTENTS_SOLID)
|
||||
#define MASK_PLAYERSTART (CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_BODY)
|
||||
#define MASK_VIEWSOLID (CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_FENCE | CONTENTS_TRIGGER)
|
||||
#define MASK_DEADSOLID (CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_CORPSE | CONTENTS_NOTTEAM2 | CONTENTS_FENCE)
|
||||
#define MASK_MONSTERSOLID (CONTENTS_SOLID | CONTENTS_MONSTERCLIP | CONTENTS_BODY)
|
||||
#define MASK_WATER (CONTENTS_WATER | CONTENTS_LAVA | CONTENTS_SLIME)
|
||||
#define MASK_OPAQUE (CONTENTS_SOLID | CONTENTS_SLIME | CONTENTS_LAVA)
|
||||
#define MASK_SHOT \
|
||||
(CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_FENCE \
|
||||
| CONTENTS_WEAPONCLIP | CONTENTS_BODY | CONTENTS_TRIGGER)
|
||||
#define MASK_SHOT_TRIG \
|
||||
(CONTENTS_SOLID | CONTENTS_CLAYPIDGEON | CONTENTS_WATER | CONTENTS_BBOX | CONTENTS_NOBOTCLIP \
|
||||
| CONTENTS_UNKNOWN2 | CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_BODY | CONTENTS_TRIGGER)
|
||||
#define MASK_SHOT \
|
||||
(CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_FENCE | CONTENTS_WEAPONCLIP \
|
||||
| CONTENTS_BODY | CONTENTS_TRIGGER)
|
||||
#define MASK_SHOT_TRIG \
|
||||
(CONTENTS_SOLID | CONTENTS_CLAYPIDGEON | CONTENTS_WATER | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 \
|
||||
| CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_BODY | CONTENTS_TRIGGER)
|
||||
#define MASK_PROJECTILE \
|
||||
(CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_TRIGGER | CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_UNKNOWN2 \
|
||||
| CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
|
||||
@@ -666,6 +639,7 @@ movement on the server game.
|
||||
#define MASK_PATHSOLID \
|
||||
(CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_BODY | CONTENTS_FENCE | CONTENTS_UNKNOWN2 | CONTENTS_BBOX \
|
||||
| CONTENTS_MONSTERCLIP)
|
||||
#define MASK_LOOK (CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_FENCE)
|
||||
#define MASK_CAMERASOLID (CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_BODY | MASK_WATER)
|
||||
#define MASK_BEAM (CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_PLAYERCLIP | CONTENTS_BODY | CONTENTS_FENCE)
|
||||
#define MASK_LADDER \
|
||||
@@ -673,17 +647,24 @@ movement on the server game.
|
||||
#define MASK_AUTOCALCLIFE (CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_FENCE)
|
||||
#define MASK_EXPLOSION (CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_WEAPONCLIP)
|
||||
#define MASK_SOUND (CONTENTS_SOLID | CONTENTS_TRANSLUCENT)
|
||||
#define MASK_VEHICLE (CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_FENCE | CONTENTS_VEHICLECLIP | CONTENTS_BODY | CONTENTS_TRIGGER)
|
||||
#define MASK_VEHICLE \
|
||||
(CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_FENCE | CONTENTS_VEHICLECLIP \
|
||||
| CONTENTS_BODY | CONTENTS_TRIGGER)
|
||||
#define MASK_VEHICLE_TIRES (CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_FENCE | CONTENTS_VEHICLECLIP | CONTENTS_TRIGGER)
|
||||
#define MASK_CLICK \
|
||||
(CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_UNKNOWN3 | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
|
||||
#define MASK_CANSEE \
|
||||
(CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_WEAPONCLIP | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_SLIME \
|
||||
| CONTENTS_LAVA | CONTENTS_BBOX)
|
||||
#define MASK_ITEM (CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_PLAYERCLIP | CONTENTS_FENCE)
|
||||
#define MASK_CANSEE \
|
||||
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_BODY)
|
||||
#define MASK_CANSEE_NOENTS (CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_FENCE | CONTENTS_WEAPONCLIP)
|
||||
#define MASK_ITEM (CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_PLAYERCLIP | CONTENTS_FENCE)
|
||||
#define MASK_TRANSITION \
|
||||
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_UNKNOWN2 | CONTENTS_NOTTEAM1 | CONTENTS_WEAPONCLIP)
|
||||
#define MASK_TARGETPATH \
|
||||
(CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_MONSTERCLIP | CONTENTS_FENCE | CONTENTS_UNKNOWN2 | CONTENTS_BBOX)
|
||||
#define MASK_ACTORPATH (CONTENTS_SOLID | CONTENTS_FENCE | CONTENTS_MONSTERCLIP | CONTENTS_TRIGGER)
|
||||
#define MASK_GRENADEPATH \
|
||||
(CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_FENCE | CONTENTS_WEAPONCLIP \
|
||||
| CONTENTS_BODY | CONTENTS_TRIGGER)
|
||||
#define MASK_LINE (CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
|
||||
#define MASK_VEHICLETURRET \
|
||||
(CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_FENCE | CONTENTS_VEHICLECLIP | CONTENTS_MONSTERCLIP \
|
||||
@@ -700,52 +681,30 @@ movement on the server game.
|
||||
#define MASK_BATTLELANGUAGE \
|
||||
(CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_PLAYERCLIP \
|
||||
| CONTENTS_WEAPONCLIP | CONTENTS_BODY | CONTENTS_TRIGGER)
|
||||
#define MASK_SCRIPT_SLAVE (CONTENTS_LADDER|CONTENTS_CLAYPIDGEON|CONTENTS_BBOX|CONTENTS_NOBOTCLIP|CONTENTS_UNKNOWN2|CONTENTS_UNKNOWN3|CONTENTS_BODY|CONTENTS_CORPSE)
|
||||
|
||||
// mohaa mask
|
||||
/*
|
||||
#define MASK_ALL -1
|
||||
#define MASK_SOLID 1
|
||||
|
||||
#define MASK_COLLISION 0x26000B21
|
||||
#define MASK_PERMANENTMARK 0x40000001
|
||||
#define MASK_AUTOCALCLIFE 0x40002021
|
||||
#define MASK_EXPLOSION 0x40040001
|
||||
#define MASK_TREADMARK 0x42012B01
|
||||
#define MASK_THIRDPERSON 0x42012B39
|
||||
#define MASK_FOOTSTEP 0x42022901
|
||||
#define MASK_BEAM 0x42042B01
|
||||
#define MASK_VISIBLE 0x42042B01
|
||||
#define MASK_VEHICLE 0x42042B01
|
||||
#define MASK_BULLET 0x42042B21
|
||||
#define MASK_SHOT 0x42042BA1
|
||||
#define MASK_CROSSHAIRSHADER 0x42092B01
|
||||
#define MASK_TRACER 0x42142B21
|
||||
*/
|
||||
#define MASK_SCRIPT_SLAVE \
|
||||
(CONTENTS_LADDER | CONTENTS_CLAYPIDGEON | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 \
|
||||
| CONTENTS_UNKNOWN3 | CONTENTS_BODY | CONTENTS_CORPSE)
|
||||
#define MASK_CARRYABLETURRET \
|
||||
(CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_FENCE | CONTENTS_BODY)
|
||||
#define MASK_AITURRET \
|
||||
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 \
|
||||
| CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_BODY)
|
||||
#define MASK_TRANSPARENT (CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_BBOX | CONTENTS_FENCE)
|
||||
#define MASK_MOVEVEHICLE \
|
||||
(CONTENTS_LADDER | CONTENTS_CLAYPIDGEON | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN3 | CONTENTS_BODY \
|
||||
| CONTENTS_CORPSE)
|
||||
#define MASK_MOVEINFO (CONTENTS_SOLID | CONTENTS_FENCE)
|
||||
#define MASK_AI_CANSEE \
|
||||
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_BBOX | CONTENTS_UNKNOWN2 | CONTENTS_FENCE \
|
||||
| CONTENTS_WEAPONCLIP)
|
||||
#define MASK_CORNER_NODE \
|
||||
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_UNKNOWN2 | CONTENTS_WEAPONCLIP | CONTENTS_BODY)
|
||||
|
||||
void BG_EvaluateTrajectoryDelta(const trajectory_t *tr, int atTime, vec3_t result);
|
||||
|
||||
void BG_PlayerStateToEntityState(playerState_t *ps, entityState_t *s, qboolean snap);
|
||||
void BG_PlayerStateToEntityStateExtraPolate(playerState_t *ps, entityState_t *s, int time, qboolean snap);
|
||||
|
||||
enum vmAnim_e {
|
||||
VM_ANIM_DISABLED,
|
||||
VM_ANIM_IDLE,
|
||||
VM_ANIM_CHARGE,
|
||||
VM_ANIM_FIRE,
|
||||
VM_ANIM_FIRE_SECONDARY,
|
||||
VM_ANIM_RECHAMBER,
|
||||
VM_ANIM_RELOAD,
|
||||
VM_ANIM_RELOAD_SINGLE,
|
||||
VM_ANIM_RELOAD_END,
|
||||
VM_ANIM_PULLOUT,
|
||||
VM_ANIM_PUTAWAY,
|
||||
VM_ANIM_LADDERSTEP,
|
||||
VM_ANIM_IDLE_0,
|
||||
VM_ANIM_IDLE_1,
|
||||
VM_ANIM_IDLE_2,
|
||||
};
|
||||
|
||||
enum cg_message_ver_15_e {
|
||||
CGM_NONE,
|
||||
CGM_BULLET_1,
|
||||
@@ -839,10 +798,10 @@ movement on the server game.
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
OBJ_FLAG_NONE,
|
||||
OBJ_FLAG_HIDDEN = 1,
|
||||
OBJ_FLAG_CURRENT = 2,
|
||||
OBJ_FLAG_COMPLETED = 4
|
||||
OBJ_FLAG_NONE,
|
||||
OBJ_FLAG_HIDDEN = 1,
|
||||
OBJ_FLAG_CURRENT = 2,
|
||||
OBJ_FLAG_COMPLETED = 4
|
||||
} objective_flags_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -851,5 +810,3 @@ typedef enum {
|
||||
OBJ_STATUS_CURRENT,
|
||||
OBJ_STATUS_COMPLETED
|
||||
} objective_status_t;
|
||||
|
||||
#endif /* bg_public.h */
|
||||
@@ -21,5 +21,720 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "bg_voteoptions.h"
|
||||
#include "../qcommon/script.h"
|
||||
|
||||
// FIXME: unimplemented
|
||||
#if defined(GAME_DLL)
|
||||
# define VO_FS_FreeFile gi.FS_FreeFile
|
||||
# define VO_FS_ReadFile(a, b) gi.FS_ReadFile(a, b, true)
|
||||
# define VO_SendRemoteCommand(s) // ?
|
||||
# define VO_ExecuteCommand(s) gi.Cmd_Execute(EXEC_NOW, s)
|
||||
# define VO_Cvar_Set(name, value) gi.cvar_set(name, value)
|
||||
# define VO_Cvar_Get(name, value, flags) gi.Cvar_Get(name, value, flags)
|
||||
# define VO_LV_ConvertString(s) gi.LV_ConvertString(s)
|
||||
#elif defined(CGAME_DLL)
|
||||
# define VO_FS_FreeFile cgi.FS_FreeFile
|
||||
# define VO_FS_ReadFile(a, b) cgi.FS_ReadFile(a, b, qtrue)
|
||||
# define VO_SendRemoteCommand(s) cgi.SendClientCommand(s)
|
||||
# define VO_ExecuteCommand(s) cgi.Cmd_Execute(EXEC_NOW, s)
|
||||
# define VO_Cvar_Set(name, value) cgi.Cvar_Set(name, value)
|
||||
# define VO_Cvar_Get(name, value, flags) cgi.Cvar_Get(name, value, flags)
|
||||
# define VO_LV_ConvertString(s) cgi.LV_ConvertString(s)
|
||||
#else
|
||||
# pragma error("VoteOptions can must be used with fgame or cgame")
|
||||
#endif
|
||||
|
||||
CLASS_DECLARATION(Class, VoteOptions, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
VoteOptionListItem::VoteOptionListItem()
|
||||
: m_pNext(NULL)
|
||||
{}
|
||||
|
||||
SingleVoteOption::SingleVoteOption()
|
||||
: m_optionType(VOTE_NO_CHOICES)
|
||||
, m_pListItem(NULL)
|
||||
, m_pNext(NULL)
|
||||
{}
|
||||
|
||||
SingleVoteOption::~SingleVoteOption()
|
||||
{
|
||||
VoteOptionListItem *item;
|
||||
VoteOptionListItem *next;
|
||||
|
||||
for (item = m_pListItem; item; item = next) {
|
||||
next = item->m_pNext;
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
VoteOptions::VoteOptions()
|
||||
{
|
||||
m_pHeadOption = NULL;
|
||||
}
|
||||
|
||||
VoteOptions::~VoteOptions()
|
||||
{
|
||||
ClearOptions();
|
||||
}
|
||||
|
||||
void VoteOptions::ClearOptions()
|
||||
{
|
||||
SingleVoteOption *option;
|
||||
SingleVoteOption *next;
|
||||
|
||||
for (option = m_pHeadOption; option; option = next) {
|
||||
next = option->m_pNext;
|
||||
delete option;
|
||||
}
|
||||
|
||||
m_pHeadOption = NULL;
|
||||
}
|
||||
|
||||
void VoteOptions::SetupVoteOptions(const char *configFileName)
|
||||
{
|
||||
char *buffer;
|
||||
int compressedLength;
|
||||
long length;
|
||||
|
||||
length = VO_FS_ReadFile(configFileName, (void **)&buffer);
|
||||
if (length == -1 || !length) {
|
||||
Com_Printf("WARNING: Couldn't find voting options file: %s\n", configFileName);
|
||||
return;
|
||||
}
|
||||
|
||||
// compress the buffer before setting up
|
||||
compressedLength = COM_Compress(buffer);
|
||||
SetupVoteOptions(configFileName, compressedLength, buffer);
|
||||
VO_FS_FreeFile(buffer);
|
||||
}
|
||||
|
||||
void VoteOptions::SetupVoteOptions(const char *configFileName, int length, const char *buffer)
|
||||
{
|
||||
if (length >= MAX_VOTEOPTIONS_BUFFER_LENGTH) {
|
||||
Com_Error(
|
||||
ERR_DROP,
|
||||
"VoteOptions: Options file '%s' is too big. Max size is %i bytes\n",
|
||||
configFileName,
|
||||
MAX_VOTEOPTIONS_BUFFER_LENGTH
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
m_sFileName = configFileName;
|
||||
m_sBuffer = buffer;
|
||||
|
||||
ParseVoteOptions();
|
||||
}
|
||||
|
||||
void VoteOptions::ParseVoteOptions()
|
||||
{
|
||||
SingleVoteOption *option;
|
||||
SingleVoteOption *newOption;
|
||||
VoteOptionListItem *listItem;
|
||||
VoteOptionListItem *newListItem;
|
||||
str token;
|
||||
Script script;
|
||||
|
||||
ClearOptions();
|
||||
script.LoadFile(m_sFileName.c_str(), m_sBuffer.length(), m_sBuffer.c_str());
|
||||
|
||||
option = m_pHeadOption;
|
||||
|
||||
while (script.TokenAvailable(true)) {
|
||||
token = script.GetToken(true);
|
||||
|
||||
if (!str::icmp(token, "{")) {
|
||||
Com_Error(
|
||||
ERR_DROP,
|
||||
"Vote Options %s: Found choices list without option header on line %d.\n",
|
||||
m_sFileName.c_str(),
|
||||
script.GetLineNumber()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!str::icmp(token, "}")) {
|
||||
Com_Error(
|
||||
ERR_DROP,
|
||||
"Vote Options %s: Illegal end of choices list without list being started on line %d.\n",
|
||||
m_sFileName.c_str(),
|
||||
script.GetLineNumber()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!token.length()) {
|
||||
Com_Error(
|
||||
ERR_DROP,
|
||||
"Vote Options %s: Empty option name on line %d.\n",
|
||||
m_sFileName.c_str(),
|
||||
script.GetLineNumber()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
newOption = new SingleVoteOption();
|
||||
|
||||
if (option) {
|
||||
option->m_pNext = newOption;
|
||||
} else {
|
||||
m_pHeadOption = newOption;
|
||||
}
|
||||
option = newOption;
|
||||
|
||||
newOption->m_sOptionName = token;
|
||||
|
||||
if (!script.TokenAvailable(false)) {
|
||||
Com_Error(
|
||||
ERR_DROP,
|
||||
"Vote Options %s: Option without a command specified on line %d.\n",
|
||||
m_sFileName.c_str(),
|
||||
script.GetLineNumber()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
newOption->m_sCommand = script.GetToken(false);
|
||||
|
||||
if (script.TokenAvailable(false)) {
|
||||
token = script.GetToken(false);
|
||||
|
||||
if (!str::icmp(token, "nochoices")) {
|
||||
newOption->m_optionType = VOTE_NO_CHOICES;
|
||||
} else if (!str::icmp(token, "list")) {
|
||||
newOption->m_optionType = VOTE_OPTION_LIST;
|
||||
} else if (!str::icmp(token, "text")) {
|
||||
newOption->m_optionType = VOTE_OPTION_TEXT;
|
||||
} else if (!str::icmp(token, "integer")) {
|
||||
newOption->m_optionType = VOTE_OPTION_INTEGER;
|
||||
} else if (!str::icmp(token, "float")) {
|
||||
newOption->m_optionType = VOTE_OPTION_FLOAT;
|
||||
} else if (!str::icmp(token, "client")) {
|
||||
newOption->m_optionType = VOTE_OPTION_CLIENT;
|
||||
} else if (!str::icmp(token, "clientnotself")) {
|
||||
newOption->m_optionType = VOTE_OPTION_CLIENT_NOT_SELF;
|
||||
} else {
|
||||
Com_Error(
|
||||
ERR_DROP,
|
||||
"Vote Options %s: Illegal option type '%s' specified on line %d.\n"
|
||||
" Valid types are nochoices, list, text, & number.\n",
|
||||
m_sFileName.c_str(),
|
||||
token.c_str(),
|
||||
script.GetLineNumber()
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (newOption->m_optionType == VOTE_OPTION_LIST) {
|
||||
if (!script.TokenAvailable(true) || Q_stricmp(script.GetToken(true), "{")) {
|
||||
Com_Error(
|
||||
ERR_DROP,
|
||||
"Vote Options %s: Missing '{'. No choices list specified for list option on line %d.\n",
|
||||
m_sFileName.c_str(),
|
||||
script.GetLineNumber()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
listItem = NULL;
|
||||
|
||||
while (script.TokenAvailable(true)) {
|
||||
token = script.GetToken(true);
|
||||
|
||||
if (!str::icmp(token, "}")) {
|
||||
break;
|
||||
}
|
||||
|
||||
newListItem = new VoteOptionListItem();
|
||||
|
||||
if (listItem) {
|
||||
listItem->m_pNext = newListItem;
|
||||
} else {
|
||||
newOption->m_pListItem = newListItem;
|
||||
}
|
||||
listItem = newListItem;
|
||||
|
||||
if (!script.TokenAvailable(false)) {
|
||||
Com_Error(
|
||||
ERR_DROP,
|
||||
"Vote Options %s: List choice without vote string specified on line %d.\n",
|
||||
m_sFileName.c_str(),
|
||||
script.GetLineNumber()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
newListItem->m_sCommand = script.GetToken(false);
|
||||
}
|
||||
} else if (script.TokenAvailable(true)) {
|
||||
token = script.GetToken(true);
|
||||
|
||||
if (!str::icmp(token, "{")) {
|
||||
Com_Error(
|
||||
ERR_DROP,
|
||||
"Vote Options %s: Choices list specified for non-list option on line %d.\n",
|
||||
m_sFileName.c_str(),
|
||||
script.GetLineNumber()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
script.UnGetToken();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *VoteOptions::GetVoteOptionsFile(int *outLen) const
|
||||
{
|
||||
if (outLen) {
|
||||
*outLen = m_sBuffer.length();
|
||||
}
|
||||
|
||||
return m_sBuffer.c_str();
|
||||
}
|
||||
|
||||
bool VoteOptions::GetVoteOptionsMain(int index, str *outOptionCommand, voteoptiontype_t *outOptionType) const
|
||||
{
|
||||
SingleVoteOption *option;
|
||||
int optionIndex;
|
||||
|
||||
if (index < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
optionIndex = 1;
|
||||
for (option = m_pHeadOption; optionIndex < index && option != NULL; option = option->m_pNext) {
|
||||
optionIndex++;
|
||||
}
|
||||
|
||||
if (!option) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*outOptionCommand = option->m_sCommand;
|
||||
*outOptionType = option->m_optionType;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VoteOptions::GetVoteOptionSub(int index, int listIndex, str *outCommand) const
|
||||
{
|
||||
SingleVoteOption *option;
|
||||
VoteOptionListItem *item;
|
||||
int optionIndex;
|
||||
int itemIndex;
|
||||
|
||||
if (index < 1 || listIndex < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
optionIndex = 1;
|
||||
for (option = m_pHeadOption; optionIndex < index && option != NULL; option = option->m_pNext) {
|
||||
optionIndex++;
|
||||
}
|
||||
|
||||
if (!option) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (option->m_optionType != VOTE_OPTION_LIST) {
|
||||
return false;
|
||||
}
|
||||
|
||||
itemIndex = 1;
|
||||
for (item = option->m_pListItem; itemIndex < listIndex && option != NULL; item = item->m_pNext) {
|
||||
itemIndex++;
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*outCommand = item->m_sCommand;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VoteOptions::GetVoteOptionMainName(int index, str *outVoteName) const
|
||||
{
|
||||
SingleVoteOption *option;
|
||||
int optionIndex;
|
||||
|
||||
if (index < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
optionIndex = 1;
|
||||
for (option = m_pHeadOption; optionIndex < index && option != NULL; option = option->m_pNext) {
|
||||
optionIndex++;
|
||||
}
|
||||
|
||||
if (!option) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*outVoteName = option->m_sOptionName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VoteOptions::GetVoteOptionSubName(int index, int listIndex, str *outName) const
|
||||
{
|
||||
SingleVoteOption *option;
|
||||
VoteOptionListItem *item;
|
||||
int optionIndex;
|
||||
int itemIndex;
|
||||
|
||||
if (index < 1 || listIndex < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
optionIndex = 1;
|
||||
for (option = m_pHeadOption; optionIndex < index && option != NULL; option = option->m_pNext) {
|
||||
optionIndex++;
|
||||
}
|
||||
|
||||
if (!option) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (option->m_optionType != VOTE_OPTION_LIST) {
|
||||
return false;
|
||||
}
|
||||
|
||||
itemIndex = 1;
|
||||
for (item = option->m_pListItem; itemIndex < listIndex && option != NULL; item = item->m_pNext) {
|
||||
itemIndex++;
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*outName = item->m_sItemName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(CGAME_DLL)
|
||||
|
||||
static str g_sVoteString;
|
||||
static VoteOptions g_voteOptions;
|
||||
|
||||
void CG_VoteOptions_StartReadFromServer(const char *string)
|
||||
{
|
||||
g_sVoteString = string;
|
||||
}
|
||||
|
||||
void CG_VoteOptions_ContinueReadFromServer(const char *string)
|
||||
{
|
||||
if (g_sVoteString.length() >= MAX_VOTEOPTIONS_BUFFER_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_sVoteString += string;
|
||||
}
|
||||
|
||||
void CG_VoteOptions_FinishReadFromServer(const char *string)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (g_sVoteString.length() >= MAX_VOTEOPTIONS_BUFFER_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_sVoteString += va("%s\n", string);
|
||||
if (!str::cmp(g_sVoteString, "\n")) {
|
||||
VO_SendRemoteCommand("wait 250;gvo\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < g_sVoteString.length(); i++) {
|
||||
if (g_sVoteString[i] == 1) {
|
||||
g_sVoteString[i] = '"';
|
||||
}
|
||||
}
|
||||
|
||||
g_voteOptions.SetupVoteOptions("ServerVoteOptions", g_sVoteString.length(), g_sVoteString.c_str());
|
||||
g_sVoteString = "";
|
||||
g_voteOptions.SetupMainOptionsList();
|
||||
}
|
||||
|
||||
void CG_PushCallVote_f()
|
||||
{
|
||||
g_voteOptions.SetupMainOptionsList();
|
||||
}
|
||||
|
||||
void CG_PushCallVoteSubList_f()
|
||||
{
|
||||
g_voteOptions.SetupSubOptionsList(atoi(cgi.Argv(1)));
|
||||
}
|
||||
|
||||
void CG_PushCallVoteSubText_f()
|
||||
{
|
||||
str command;
|
||||
str name;
|
||||
voteoptiontype_t type;
|
||||
|
||||
if (!g_voteOptions.GetVoteOptionsMain(atoi(cgi.Argv(1)), &command, &type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != voteoptiontype_t::VOTE_OPTION_TEXT) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_voteOptions.GetVoteOptionMainName(atoi(cgi.Argv(1)), &name);
|
||||
VO_ExecuteCommand("forcemenu votesubtext\n");
|
||||
VO_Cvar_Set("ui_votesubtitle", name.c_str());
|
||||
VO_Cvar_Set("ui_votestringentry", "");
|
||||
}
|
||||
|
||||
void CG_PushCallVoteSubInteger_f()
|
||||
{
|
||||
str command;
|
||||
str name;
|
||||
voteoptiontype_t type;
|
||||
|
||||
if (!g_voteOptions.GetVoteOptionsMain(atoi(cgi.Argv(1)), &command, &type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != voteoptiontype_t::VOTE_OPTION_INTEGER) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_voteOptions.GetVoteOptionMainName(atoi(cgi.Argv(1)), &name);
|
||||
VO_ExecuteCommand("forcemenu votesubinteger\n");
|
||||
VO_Cvar_Set("ui_votesubtitle", name.c_str());
|
||||
VO_Cvar_Set("ui_votestringentry", "");
|
||||
}
|
||||
|
||||
void CG_PushCallVoteSubFloat_f()
|
||||
{
|
||||
str command;
|
||||
str name;
|
||||
voteoptiontype_t type;
|
||||
|
||||
if (!g_voteOptions.GetVoteOptionsMain(atoi(cgi.Argv(1)), &command, &type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != voteoptiontype_t::VOTE_OPTION_FLOAT) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_voteOptions.GetVoteOptionMainName(atoi(cgi.Argv(1)), &name);
|
||||
VO_ExecuteCommand("forcemenu votesubfloat\n");
|
||||
VO_Cvar_Set("ui_votesubtitle", name.c_str());
|
||||
VO_Cvar_Set("ui_votestringentry", "");
|
||||
}
|
||||
|
||||
void CG_PushCallVoteSubClient_f()
|
||||
{
|
||||
str command;
|
||||
str name;
|
||||
int index;
|
||||
int i;
|
||||
voteoptiontype_t type;
|
||||
|
||||
index = atoi(cgi.Argv(1));
|
||||
|
||||
if (!g_voteOptions.GetVoteOptionsMain(index, &command, &type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != voteoptiontype_t::VOTE_OPTION_CLIENT && type != voteoptiontype_t::VOTE_OPTION_CLIENT_NOT_SELF) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_voteOptions.GetVoteOptionMainName(index, &name);
|
||||
VO_ExecuteCommand("forcemenu votesubclient\n");
|
||||
VO_Cvar_Set("ui_votesubtitle", name.c_str());
|
||||
VO_ExecuteCommand("globalwidgetcommand voteclientlist deleteallitems\n");
|
||||
|
||||
for (i = 0; i < cgs.maxclients; i++) {
|
||||
if (type == VOTE_OPTION_CLIENT_NOT_SELF && cg.snap && i == cg.snap->ps.clientNum) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strlen(cg.clientinfo[i].name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand voteclientlist additem \"%i: %s\" \"callvote %i %i;popmenu 0\"\n",
|
||||
i,
|
||||
cg.clientinfo[i],
|
||||
index,
|
||||
i)
|
||||
);
|
||||
}
|
||||
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand voteclientlist additem \"%s\" \"popmenu 0\"\n", VO_LV_ConvertString("[Cancel Vote]"))
|
||||
);
|
||||
}
|
||||
|
||||
void CG_PushVote_f()
|
||||
{
|
||||
VO_Cvar_Set("ui_votesubtitle", cgs.voteString);
|
||||
VO_ExecuteCommand("forcemenu votecast\n");
|
||||
}
|
||||
|
||||
void CG_CallEntryVote_f()
|
||||
{
|
||||
str command;
|
||||
str name;
|
||||
const char *entry;
|
||||
int index;
|
||||
voteoptiontype_t type;
|
||||
|
||||
index = VO_Cvar_Get("ui_votetype", "0", 0)->integer;
|
||||
|
||||
if (!g_voteOptions.GetVoteOptionsMain(index, &command, &type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != voteoptiontype_t::VOTE_OPTION_TEXT && type != voteoptiontype_t::VOTE_OPTION_INTEGER
|
||||
&& type != voteoptiontype_t::VOTE_OPTION_FLOAT) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry = VO_Cvar_Get("ui_votestringentry", "", 0)->string;
|
||||
VO_ExecuteCommand(va("callvote %i \"%s\"\n", index, entry));
|
||||
}
|
||||
|
||||
void VoteOptions::SetupMainOptionsList()
|
||||
{
|
||||
SingleVoteOption *option;
|
||||
int count;
|
||||
|
||||
VO_ExecuteCommand("forcemenu votemain\n");
|
||||
VO_ExecuteCommand("globalwidgetcommand votelistmain deleteallitems\n");
|
||||
|
||||
if (!IsSetup()) {
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistmain additem \"%s\" \"popmenu 0\"\n",
|
||||
VO_LV_ConvertString("Retrieving voting options from server..."))
|
||||
);
|
||||
VO_SendRemoteCommand("gvo\n");
|
||||
return;
|
||||
}
|
||||
|
||||
count = 1;
|
||||
|
||||
for (option = m_pHeadOption; option; option = option->m_pNext, count++) {
|
||||
switch (option->m_optionType) {
|
||||
case VOTE_NO_CHOICES:
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistmain additem \"%s\" \"callvote %i;popmenu 0\"\n",
|
||||
option->m_sOptionName.c_str(),
|
||||
count)
|
||||
);
|
||||
break;
|
||||
case VOTE_OPTION_LIST:
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistmain additem \"%s\" \"popmenu 0;wait 100;pushcallvotesublist %i\"\n",
|
||||
option->m_sOptionName.c_str(),
|
||||
count)
|
||||
);
|
||||
break;
|
||||
case VOTE_OPTION_TEXT:
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistmain additem \"%s\" \"popmenu 0;wait 100;set ui_votetype "
|
||||
"%i;pushcallvotesubtext %i\"\n",
|
||||
option->m_sOptionName.c_str(),
|
||||
count,
|
||||
count)
|
||||
);
|
||||
break;
|
||||
case VOTE_OPTION_INTEGER:
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistmain additem \"%s\" \"popmenu 0;wait 100;set ui_votetype "
|
||||
"%i;pushcallvotesubinteger %i\"\n",
|
||||
option->m_sOptionName.c_str(),
|
||||
count,
|
||||
count)
|
||||
);
|
||||
break;
|
||||
case VOTE_OPTION_FLOAT:
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistmain additem \"%s\" \"popmenu 0;wait 100;set ui_votetype "
|
||||
"%i;pushcallvotesubfloat %i\"\n",
|
||||
option->m_sOptionName.c_str(),
|
||||
count,
|
||||
count)
|
||||
);
|
||||
break;
|
||||
case VOTE_OPTION_CLIENT:
|
||||
case VOTE_OPTION_CLIENT_NOT_SELF:
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistmain additem \"%s\" \"popmenu 0;wait 100;set ui_votetype "
|
||||
"%i;pushcallvotesubclient %i\"\n",
|
||||
option->m_sOptionName.c_str(),
|
||||
count,
|
||||
count)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistmain additem \"%s\" \"popmenu 0\"\n", VO_LV_ConvertString("[Cancel Vote]"))
|
||||
);
|
||||
}
|
||||
|
||||
void VoteOptions::SetupSubOptionsList(int index)
|
||||
{
|
||||
SingleVoteOption *option;
|
||||
VoteOptionListItem *item;
|
||||
int count;
|
||||
int numItems;
|
||||
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
count = 1;
|
||||
for (option = m_pHeadOption; count < index && option; option = option->m_pNext) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (option->m_optionType != VOTE_OPTION_LIST || !option->m_pListItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
VO_ExecuteCommand("forcemenu votesublist\n");
|
||||
VO_Cvar_Set("ui_votesubtitle", option->m_sOptionName.c_str());
|
||||
VO_ExecuteCommand("globalwidgetcommand votelistsub deleteallitems\n");
|
||||
|
||||
if (IsSetup()) {
|
||||
numItems = 1;
|
||||
|
||||
for (item = option->m_pListItem; item; item = item->m_pNext, numItems++) {
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistsub additem \"%s\" \"callvote %i %i;popmenu 0\"\n",
|
||||
item->m_sItemName.c_str(),
|
||||
index,
|
||||
numItems)
|
||||
);
|
||||
}
|
||||
|
||||
VO_ExecuteCommand(
|
||||
va("globalwidgetcommand votelistsub additem \"%s\" \"popmenu 0\"\n", VO_LV_ConvertString("[Cancel Vote]"))
|
||||
);
|
||||
} else {
|
||||
VO_ExecuteCommand(
|
||||
"globalwidgetcommand votelistsub additem \"Retrieving voting options from server...\" \"popmenu 0\"\n"
|
||||
);
|
||||
VO_SendRemoteCommand("gvo\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+72
-13
@@ -22,9 +22,17 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "listener.h"
|
||||
#ifdef __cplusplus
|
||||
# include "listener.h"
|
||||
#endif
|
||||
|
||||
#include "g_public.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
static const unsigned long MAX_VOTEOPTIONS_UPLOAD_BUFFER_LENGTH = 2024;
|
||||
static const unsigned long MAX_VOTEOPTIONS_BUFFER_LENGTH = 0x100000;
|
||||
|
||||
typedef enum voteoptiontype_e {
|
||||
/** No input. */
|
||||
VOTE_NO_CHOICES,
|
||||
@@ -44,18 +52,27 @@ typedef enum voteoptiontype_e {
|
||||
|
||||
class VoteOptionListItem
|
||||
{
|
||||
public:
|
||||
str m_sItemName;
|
||||
str m_sCommand;
|
||||
class VoteOptionListItem *m_pNext;
|
||||
|
||||
public:
|
||||
VoteOptionListItem();
|
||||
};
|
||||
|
||||
class SingleVoteOption
|
||||
{
|
||||
str m_sVoteName;
|
||||
str m_sCommand;
|
||||
voteoptiontype_t m_optionType;
|
||||
VoteOptionListItem *m_pListItem;
|
||||
class SingleVoteOption *m_pNext;
|
||||
public:
|
||||
str m_sOptionName;
|
||||
str m_sCommand;
|
||||
voteoptiontype_t m_optionType;
|
||||
VoteOptionListItem *m_pListItem;
|
||||
SingleVoteOption *m_pNext;
|
||||
|
||||
public:
|
||||
SingleVoteOption();
|
||||
~SingleVoteOption();
|
||||
};
|
||||
|
||||
class VoteOptions : public Class
|
||||
@@ -63,14 +80,56 @@ class VoteOptions : public Class
|
||||
public:
|
||||
CLASS_PROTOTYPE(VoteOptions);
|
||||
|
||||
public:
|
||||
private:
|
||||
str m_sFileName;
|
||||
str m_sBuffer;
|
||||
SingleVoteOption *m_pHeadOption;
|
||||
int field_5;
|
||||
float field_6;
|
||||
float field_7;
|
||||
float field_8;
|
||||
float field_9;
|
||||
float field_10;
|
||||
|
||||
public:
|
||||
VoteOptions();
|
||||
~VoteOptions();
|
||||
|
||||
bool IsSetup() const;
|
||||
|
||||
void ClearOptions();
|
||||
void SetupVoteOptions(const char *configFileName);
|
||||
void SetupVoteOptions(const char *configFileName, int length, const char *buffer);
|
||||
void ParseVoteOptions();
|
||||
const char *GetVoteOptionsFile(int *outLen) const;
|
||||
bool GetVoteOptionsMain(int index, str *outOptionCommand, voteoptiontype_t *outOptionType) const;
|
||||
bool GetVoteOptionSub(int index, int listIndex, str *outCommand) const;
|
||||
bool GetVoteOptionMainName(int index, str *outVoteName) const;
|
||||
bool GetVoteOptionSubName(int index, int listIndex, str *outName) const;
|
||||
|
||||
void SetupMainOptionsList();
|
||||
void SetupSubOptionsList(int index);
|
||||
};
|
||||
|
||||
inline bool VoteOptions::IsSetup() const
|
||||
{
|
||||
return m_pHeadOption != NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(CGAME_DLL)
|
||||
void CG_VoteOptions_StartReadFromServer(const char *string);
|
||||
void CG_VoteOptions_ContinueReadFromServer(const char *string);
|
||||
void CG_VoteOptions_FinishReadFromServer(const char *string);
|
||||
void CG_PushCallVote_f();
|
||||
void CG_PushCallVoteSubList_f();
|
||||
void CG_PushCallVoteSubText_f();
|
||||
void CG_PushCallVoteSubInteger_f();
|
||||
void CG_PushCallVoteSubFloat_f();
|
||||
void CG_PushCallVoteSubClient_f();
|
||||
void CG_PushVote_f();
|
||||
void CG_CallEntryVote_f();
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+653
-886
File diff suppressed because it is too large.
Load diff
+2633
-3309
File diff suppressed because it is too large.
Load diff
+335
-359
@@ -21,10 +21,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// camera.h: Camera. Duh.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __CAMERA_H__
|
||||
#define __CAMERA_H__
|
||||
#pragma once
|
||||
|
||||
#include "g_local.h"
|
||||
#include "entity.h"
|
||||
@@ -34,13 +33,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#define CAMERA_SWITCHTIME 0.5f
|
||||
|
||||
#define ORBIT ( 1 << 0 )
|
||||
#define START_ON ( 1 << 1 )
|
||||
#define AUTOMATIC ( 1 << 2 )
|
||||
#define NO_TRACE ( 1 << 3 )
|
||||
#define NO_WATCH ( 1 << 4 )
|
||||
#define LEVEL_EXIT ( 1 << 5 )
|
||||
|
||||
#define ORBIT (1 << 0)
|
||||
#define START_ON (1 << 1)
|
||||
#define AUTOMATIC (1 << 2)
|
||||
#define NO_TRACE (1 << 3)
|
||||
#define NO_WATCH (1 << 4)
|
||||
#define LEVEL_EXIT (1 << 5)
|
||||
|
||||
extern Event EV_Camera_CameraThink;
|
||||
extern Event EV_Camera_StartMoving;
|
||||
@@ -69,408 +67,386 @@ extern Event EV_Camera_Cut;
|
||||
class Camera;
|
||||
|
||||
class CameraMoveState : public Class
|
||||
{
|
||||
public:
|
||||
Vector pos;
|
||||
Vector movedir; // direction of travel
|
||||
Vector angles; // angles from spline camera
|
||||
{
|
||||
public:
|
||||
Vector pos;
|
||||
Vector movedir; // direction of travel
|
||||
Vector angles; // angles from spline camera
|
||||
|
||||
BSpline cameraPath;
|
||||
SplinePathPtr splinePath;
|
||||
SplinePathPtr currentNode;
|
||||
SplinePathPtr loopNode;
|
||||
BSpline cameraPath;
|
||||
SplinePathPtr splinePath;
|
||||
SplinePathPtr currentNode;
|
||||
SplinePathPtr loopNode;
|
||||
|
||||
float cameraTime;
|
||||
int lastTime;
|
||||
int newTime;
|
||||
float cameraTime;
|
||||
int lastTime;
|
||||
int newTime;
|
||||
|
||||
qboolean followingpath;
|
||||
EntityPtr followEnt;
|
||||
EntityPtr orbitEnt;
|
||||
qboolean followingpath;
|
||||
EntityPtr followEnt;
|
||||
EntityPtr orbitEnt;
|
||||
|
||||
void operator=( CameraMoveState &newstate );
|
||||
void Evaluate( Camera * camera );
|
||||
void Initialize( Camera * camera );
|
||||
void DoNodeEvents( Camera * camera );
|
||||
void Archive( Archiver &arc ) override;
|
||||
};
|
||||
void operator=(CameraMoveState& newstate);
|
||||
void Evaluate(Camera *camera);
|
||||
void Initialize(Camera *camera);
|
||||
void DoNodeEvents(Camera *camera);
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline void CameraMoveState::operator=
|
||||
(
|
||||
CameraMoveState &newstate
|
||||
)
|
||||
inline void CameraMoveState::operator=(CameraMoveState& newstate)
|
||||
|
||||
{
|
||||
movedir = newstate.movedir;
|
||||
pos = newstate.pos;
|
||||
angles = newstate.angles;
|
||||
{
|
||||
movedir = newstate.movedir;
|
||||
pos = newstate.pos;
|
||||
angles = newstate.angles;
|
||||
|
||||
cameraPath = newstate.cameraPath;
|
||||
splinePath = newstate.splinePath;
|
||||
currentNode = newstate.currentNode;
|
||||
loopNode = newstate.loopNode;
|
||||
cameraPath = newstate.cameraPath;
|
||||
splinePath = newstate.splinePath;
|
||||
currentNode = newstate.currentNode;
|
||||
loopNode = newstate.loopNode;
|
||||
|
||||
cameraTime = newstate.cameraTime;
|
||||
lastTime = newstate.lastTime;
|
||||
newTime = newstate.newTime;
|
||||
cameraTime = newstate.cameraTime;
|
||||
lastTime = newstate.lastTime;
|
||||
newTime = newstate.newTime;
|
||||
|
||||
followEnt = newstate.followEnt;
|
||||
orbitEnt = newstate.orbitEnt;
|
||||
followEnt = newstate.followEnt;
|
||||
orbitEnt = newstate.orbitEnt;
|
||||
|
||||
followingpath = newstate.followingpath;
|
||||
}
|
||||
followingpath = newstate.followingpath;
|
||||
}
|
||||
|
||||
inline void CameraMoveState::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
{
|
||||
arc.ArchiveVector( &movedir );
|
||||
arc.ArchiveVector( &pos );
|
||||
arc.ArchiveVector( &angles );
|
||||
inline void CameraMoveState::Archive(Archiver& arc)
|
||||
{
|
||||
arc.ArchiveVector(&movedir);
|
||||
arc.ArchiveVector(&pos);
|
||||
arc.ArchiveVector(&angles);
|
||||
|
||||
cameraPath.Archive( arc );
|
||||
cameraPath.Archive(arc);
|
||||
|
||||
arc.ArchiveSafePointer( &splinePath );
|
||||
arc.ArchiveSafePointer( ¤tNode );
|
||||
arc.ArchiveSafePointer( &loopNode );
|
||||
arc.ArchiveSafePointer(&splinePath);
|
||||
arc.ArchiveSafePointer(¤tNode);
|
||||
arc.ArchiveSafePointer(&loopNode);
|
||||
|
||||
arc.ArchiveFloat( &cameraTime );
|
||||
arc.ArchiveInteger( &lastTime );
|
||||
arc.ArchiveInteger( &newTime );
|
||||
arc.ArchiveFloat(&cameraTime);
|
||||
arc.ArchiveInteger(&lastTime);
|
||||
arc.ArchiveInteger(&newTime);
|
||||
|
||||
arc.ArchiveSafePointer( &followEnt );
|
||||
arc.ArchiveSafePointer( &orbitEnt );
|
||||
arc.ArchiveSafePointer(&followEnt);
|
||||
arc.ArchiveSafePointer(&orbitEnt);
|
||||
|
||||
arc.ArchiveBoolean( &followingpath );
|
||||
}
|
||||
arc.ArchiveBoolean(&followingpath);
|
||||
}
|
||||
|
||||
class CameraWatchState : public Class
|
||||
{
|
||||
public:
|
||||
Vector watchAngles;
|
||||
class CameraWatchState : public Class
|
||||
{
|
||||
public:
|
||||
Vector watchAngles;
|
||||
|
||||
EntityPtr watchEnt;
|
||||
qboolean watchNodes;
|
||||
qboolean watchPath;
|
||||
EntityPtr watchEnt;
|
||||
qboolean watchNodes;
|
||||
qboolean watchPath;
|
||||
|
||||
void Evaluate( Camera * camera, CameraMoveState * move );
|
||||
void Initialize( Camera * camera );
|
||||
void Archive( Archiver &arc ) override;
|
||||
};
|
||||
void Evaluate(Camera *camera, CameraMoveState *move);
|
||||
void Initialize(Camera *camera);
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline void CameraWatchState::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
{
|
||||
arc.ArchiveVector( &watchAngles );
|
||||
arc.ArchiveSafePointer( &watchEnt );
|
||||
arc.ArchiveBoolean( &watchNodes );
|
||||
arc.ArchiveBoolean( &watchPath );
|
||||
}
|
||||
inline void CameraWatchState::Archive(Archiver& arc)
|
||||
{
|
||||
arc.ArchiveVector(&watchAngles);
|
||||
arc.ArchiveSafePointer(&watchEnt);
|
||||
arc.ArchiveBoolean(&watchNodes);
|
||||
arc.ArchiveBoolean(&watchPath);
|
||||
}
|
||||
|
||||
class CameraState : public Class
|
||||
{
|
||||
public:
|
||||
CameraMoveState move;
|
||||
CameraWatchState watch;
|
||||
float fov;
|
||||
class CameraState : public Class
|
||||
{
|
||||
public:
|
||||
CameraMoveState move;
|
||||
CameraWatchState watch;
|
||||
float fov;
|
||||
|
||||
void Evaluate( Camera * camera );
|
||||
void Initialize( Camera * camera );
|
||||
void Archive( Archiver &arc ) override;
|
||||
};
|
||||
void Evaluate(Camera *camera);
|
||||
void Initialize(Camera *camera);
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline void CameraState::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
{
|
||||
move.Archive( arc );
|
||||
watch.Archive( arc );
|
||||
arc.ArchiveFloat( &fov );
|
||||
}
|
||||
inline void CameraState::Archive(Archiver& arc)
|
||||
{
|
||||
move.Archive(arc);
|
||||
watch.Archive(arc);
|
||||
arc.ArchiveFloat(&fov);
|
||||
}
|
||||
|
||||
class Camera : public Entity
|
||||
{
|
||||
private:
|
||||
friend class CameraState;
|
||||
friend class CameraWatchState;
|
||||
friend class CameraMoveState;
|
||||
//
|
||||
// follow parameters
|
||||
//
|
||||
float follow_yaw;
|
||||
qboolean follow_yaw_fixed;
|
||||
float follow_dist;
|
||||
int follow_mask;
|
||||
|
||||
// camera speed
|
||||
float camera_speed;
|
||||
// current camera fov
|
||||
float camera_fov;
|
||||
// orbit height
|
||||
float orbit_height;
|
||||
// orbit_dotrace
|
||||
qboolean orbit_dotrace;
|
||||
// whether or not auto calculate fov, a non-zero value means yes
|
||||
float auto_fov;
|
||||
|
||||
// automatic variables
|
||||
float automatic_startTime;
|
||||
float automatic_stopTime;
|
||||
float automatic_radius;
|
||||
float automatic_maxFOV;
|
||||
qboolean automatic_active;
|
||||
Container<str> automatic_states;
|
||||
|
||||
// Miscellaneous
|
||||
Vector m_vPosOffset;
|
||||
|
||||
protected:
|
||||
CameraState currentstate;
|
||||
CameraState newstate;
|
||||
|
||||
float watchTime; // if non-zero, camera view is transitioning
|
||||
float followTime; // if non-zero, camera position is tranisitioning
|
||||
float fovTime; // if non-zero, fov is being lerped
|
||||
|
||||
float fadeTime; // time to transition over
|
||||
float fovFadeTime; // time for fov transition
|
||||
float followFadeTime; // time for fov transition
|
||||
float watchFadeTime; // time for fov transition
|
||||
|
||||
bool m_bShowquakes;
|
||||
|
||||
str nextCamera;
|
||||
|
||||
qboolean showcamera;
|
||||
|
||||
void SetupCamera( Event *ev );
|
||||
void CameraThink( Event *ev );
|
||||
void CreateOrbit( Vector pos, float radius, Vector &forward, Vector &left );
|
||||
void CreatePath( SplinePath *path, splinetype_t type );
|
||||
void UpdateStates( void );
|
||||
Vector CalculatePosition( void );
|
||||
Vector CalculateOrientation( void );
|
||||
float CalculateFov( void );
|
||||
virtual void bind( Entity *master, qboolean use_my_angles = false );
|
||||
void unbind( void ) override;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( Camera );
|
||||
|
||||
Camera();
|
||||
void Stop( void );
|
||||
void FollowPath( SplinePath *path, qboolean loop, Entity *watch );
|
||||
void Orbit( Entity *ent, float dist, Entity *watch, float yaw_offset = 0, qboolean dotrace = qtrue );
|
||||
void FollowEntity( Entity *ent, float dist, int mask, Entity *watch = NULL );
|
||||
void Watch( str watch, float time );
|
||||
void Watch( Entity *ent, float time );
|
||||
void SetFOV( float fov, float time );
|
||||
|
||||
void StartMoving( Event *ev );
|
||||
void StopMoving( Event *ev );
|
||||
void Pause( Event *ev );
|
||||
void Continue( Event *ev );
|
||||
void SetAnglesEvent( Event *ev );
|
||||
void SetSpeed( Event *ev );
|
||||
void SetFollowDistance( Event *ev );
|
||||
void SetOrbitHeight( float height );
|
||||
void SetOrbitHeight( Event *ev );
|
||||
void SetFollowYaw( Event *ev );
|
||||
void AbsoluteYaw( Event *ev );
|
||||
void RelativeYaw( Event *ev );
|
||||
void SetFOV( Event *ev );
|
||||
void OrbitEvent( Event *ev );
|
||||
void FollowEvent( Event *ev );
|
||||
void WatchEvent( Event *ev );
|
||||
void WatchStringEvent( Event *ev );
|
||||
void WatchPathEvent( Event *ev );
|
||||
void WatchNodesEvent( Event *ev );
|
||||
void NoWatchEvent(Event* ev);
|
||||
void EventShowQuakes(Event* ev);
|
||||
void LookAt( Event *ev );
|
||||
void MoveToEntity( Event *ev );
|
||||
void MoveToPos( Event *ev );
|
||||
void Cut( Event *ev );
|
||||
void FadeTime( Event *ev );
|
||||
void TurnTo( Event *ev );
|
||||
void SetNextCamera( Event *ev );
|
||||
float CalculateScore( Entity * player, str state );
|
||||
float AutomaticStart( Entity * player );
|
||||
float AutomaticStop( Entity * player );
|
||||
qboolean IsAutomatic( void );
|
||||
qboolean IsLevelExit( void );
|
||||
void SetAutoStateEvent( Event * ev );
|
||||
void SetAutoRadiusEvent( Event * ev );
|
||||
void SetAutoStartTimeEvent( Event * ev );
|
||||
void SetAutoStopTimeEvent( Event * ev );
|
||||
void SetMaximumAutoFOVEvent( Event * ev );
|
||||
void SetAutoActiveEvent( Event * ev );
|
||||
|
||||
str& NextCamera( void );
|
||||
float Fov( void );
|
||||
|
||||
void Reset( Vector org, Vector ang );
|
||||
|
||||
Vector GetPositionOffset( void );
|
||||
void SetPositionOffset( Vector vNewOfs );
|
||||
|
||||
void Archive( Archiver &arc ) override;
|
||||
};
|
||||
|
||||
inline Vector Camera::GetPositionOffset
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return m_vPosOffset;
|
||||
private:
|
||||
friend class CameraState;
|
||||
friend class CameraWatchState;
|
||||
friend class CameraMoveState;
|
||||
//
|
||||
// follow parameters
|
||||
//
|
||||
float follow_yaw;
|
||||
qboolean follow_yaw_fixed;
|
||||
float follow_dist;
|
||||
int follow_mask;
|
||||
|
||||
// camera speed
|
||||
float camera_speed;
|
||||
// current camera fov
|
||||
float camera_fov;
|
||||
// orbit height
|
||||
float orbit_height;
|
||||
// orbit_dotrace
|
||||
qboolean orbit_dotrace;
|
||||
// whether or not auto calculate fov, a non-zero value means yes
|
||||
float auto_fov;
|
||||
|
||||
// automatic variables
|
||||
float automatic_startTime;
|
||||
float automatic_stopTime;
|
||||
float automatic_radius;
|
||||
float automatic_maxFOV;
|
||||
qboolean automatic_active;
|
||||
Container<str> automatic_states;
|
||||
|
||||
// Miscellaneous
|
||||
Vector m_vPosOffset;
|
||||
|
||||
protected:
|
||||
CameraState currentstate;
|
||||
CameraState newstate;
|
||||
|
||||
float watchTime; // if non-zero, camera view is transitioning
|
||||
float followTime; // if non-zero, camera position is tranisitioning
|
||||
float fovTime; // if non-zero, fov is being lerped
|
||||
|
||||
float fadeTime; // time to transition over
|
||||
float fovFadeTime; // time for fov transition
|
||||
float followFadeTime; // time for fov transition
|
||||
float watchFadeTime; // time for fov transition
|
||||
|
||||
bool m_bShowquakes;
|
||||
|
||||
str nextCamera;
|
||||
|
||||
qboolean showcamera;
|
||||
|
||||
void SetupCamera(Event *ev);
|
||||
void CameraThink(Event *ev);
|
||||
void CreateOrbit(Vector pos, float radius, Vector &forward, Vector &left);
|
||||
void CreatePath(SplinePath *path, splinetype_t type);
|
||||
void UpdateStates(void);
|
||||
Vector CalculatePosition(void);
|
||||
Vector CalculateOrientation(void);
|
||||
float CalculateFov(void);
|
||||
virtual void bind(Entity *master, qboolean use_my_angles = false);
|
||||
void unbind(void) override;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(Camera);
|
||||
|
||||
Camera();
|
||||
void Stop(void);
|
||||
void FollowPath(SplinePath *path, qboolean loop, Entity *watch);
|
||||
void Orbit(Entity *ent, float dist, Entity *watch, float yaw_offset = 0, qboolean dotrace = qtrue);
|
||||
void FollowEntity(Entity *ent, float dist, int mask, Entity *watch = NULL);
|
||||
void Watch(str watch, float time);
|
||||
void Watch(Entity *ent, float time);
|
||||
void SetFOV(float fov, float time);
|
||||
|
||||
void StartMoving(Event *ev);
|
||||
void StopMoving(Event *ev);
|
||||
void Pause(Event *ev);
|
||||
void Continue(Event *ev);
|
||||
void SetAnglesEvent(Event *ev);
|
||||
void SetSpeed(Event *ev);
|
||||
void SetFollowDistance(Event *ev);
|
||||
void SetOrbitHeight(float height);
|
||||
void SetOrbitHeight(Event *ev);
|
||||
void SetFollowYaw(Event *ev);
|
||||
void AbsoluteYaw(Event *ev);
|
||||
void RelativeYaw(Event *ev);
|
||||
void SetFOV(Event *ev);
|
||||
void OrbitEvent(Event *ev);
|
||||
void FollowEvent(Event *ev);
|
||||
void WatchEvent(Event *ev);
|
||||
void WatchStringEvent(Event *ev);
|
||||
void WatchPathEvent(Event *ev);
|
||||
void WatchNodesEvent(Event *ev);
|
||||
void NoWatchEvent(Event *ev);
|
||||
void EventShowQuakes(Event *ev);
|
||||
void LookAt(Event *ev);
|
||||
void MoveToEntity(Event *ev);
|
||||
void MoveToPos(Event *ev);
|
||||
void Cut(Event *ev);
|
||||
void FadeTime(Event *ev);
|
||||
void TurnTo(Event *ev);
|
||||
void SetNextCamera(Event *ev);
|
||||
float CalculateScore(Entity *player, str state);
|
||||
float AutomaticStart(Entity *player);
|
||||
float AutomaticStop(Entity *player);
|
||||
qboolean IsAutomatic(void);
|
||||
qboolean IsLevelExit(void);
|
||||
void SetAutoStateEvent(Event *ev);
|
||||
void SetAutoRadiusEvent(Event *ev);
|
||||
void SetAutoStartTimeEvent(Event *ev);
|
||||
void SetAutoStopTimeEvent(Event *ev);
|
||||
void SetMaximumAutoFOVEvent(Event *ev);
|
||||
void SetAutoActiveEvent(Event *ev);
|
||||
|
||||
str & NextCamera(void);
|
||||
float Fov(void);
|
||||
|
||||
void Reset(Vector org, Vector ang);
|
||||
|
||||
bool ShowQuakes(void) const;
|
||||
Vector GetPositionOffset(void);
|
||||
void SetPositionOffset(Vector vNewOfs);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline bool Camera::ShowQuakes(void) const
|
||||
{
|
||||
return m_bShowquakes;
|
||||
}
|
||||
|
||||
inline void Camera::SetPositionOffset
|
||||
(
|
||||
Vector vNewOfs
|
||||
)
|
||||
inline Vector Camera::GetPositionOffset(void)
|
||||
{
|
||||
m_vPosOffset = vNewOfs;
|
||||
return m_vPosOffset;
|
||||
}
|
||||
|
||||
inline void Camera::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
{
|
||||
Entity::Archive( arc );
|
||||
inline void Camera::SetPositionOffset(Vector vNewOfs)
|
||||
{
|
||||
m_vPosOffset = vNewOfs;
|
||||
}
|
||||
|
||||
arc.ArchiveFloat( &follow_yaw );
|
||||
arc.ArchiveBoolean( &follow_yaw_fixed );
|
||||
arc.ArchiveFloat( &follow_dist );
|
||||
arc.ArchiveInteger( &follow_mask );
|
||||
inline void Camera::Archive(Archiver& arc)
|
||||
{
|
||||
Entity::Archive(arc);
|
||||
|
||||
arc.ArchiveFloat( &camera_speed );
|
||||
arc.ArchiveFloat( &camera_fov );
|
||||
arc.ArchiveFloat( &orbit_height );
|
||||
arc.ArchiveBoolean( &orbit_dotrace );
|
||||
arc.ArchiveFloat( &auto_fov );
|
||||
arc.ArchiveFloat(&follow_yaw);
|
||||
arc.ArchiveBoolean(&follow_yaw_fixed);
|
||||
arc.ArchiveFloat(&follow_dist);
|
||||
arc.ArchiveInteger(&follow_mask);
|
||||
|
||||
arc.ArchiveFloat( &automatic_startTime );
|
||||
arc.ArchiveFloat( &automatic_stopTime );
|
||||
arc.ArchiveFloat( &automatic_radius );
|
||||
arc.ArchiveFloat( &automatic_maxFOV );
|
||||
arc.ArchiveBoolean( &automatic_active );
|
||||
arc.ArchiveFloat(&camera_speed);
|
||||
arc.ArchiveFloat(&camera_fov);
|
||||
arc.ArchiveFloat(&orbit_height);
|
||||
arc.ArchiveBoolean(&orbit_dotrace);
|
||||
arc.ArchiveFloat(&auto_fov);
|
||||
|
||||
automatic_states.Archive( arc );
|
||||
arc.ArchiveFloat(&automatic_startTime);
|
||||
arc.ArchiveFloat(&automatic_stopTime);
|
||||
arc.ArchiveFloat(&automatic_radius);
|
||||
arc.ArchiveFloat(&automatic_maxFOV);
|
||||
arc.ArchiveBoolean(&automatic_active);
|
||||
|
||||
// currentstate
|
||||
currentstate.Archive( arc );
|
||||
// newstate
|
||||
newstate.Archive( arc );
|
||||
automatic_states.Archive(arc);
|
||||
|
||||
arc.ArchiveFloat( &watchTime );
|
||||
arc.ArchiveFloat( &followTime );
|
||||
arc.ArchiveFloat( &fovTime );
|
||||
arc.ArchiveFloat( &fadeTime );
|
||||
arc.ArchiveFloat( &fovFadeTime );
|
||||
arc.ArchiveFloat( &followFadeTime );
|
||||
arc.ArchiveFloat( &watchFadeTime );
|
||||
// currentstate
|
||||
currentstate.Archive(arc);
|
||||
// newstate
|
||||
newstate.Archive(arc);
|
||||
|
||||
arc.ArchiveString( &nextCamera );
|
||||
arc.ArchiveFloat(&watchTime);
|
||||
arc.ArchiveFloat(&followTime);
|
||||
arc.ArchiveFloat(&fovTime);
|
||||
arc.ArchiveFloat(&fadeTime);
|
||||
arc.ArchiveFloat(&fovFadeTime);
|
||||
arc.ArchiveFloat(&followFadeTime);
|
||||
arc.ArchiveFloat(&watchFadeTime);
|
||||
|
||||
arc.ArchiveBoolean( &showcamera );
|
||||
arc.ArchiveString(&nextCamera);
|
||||
|
||||
if ( arc.Loading() )
|
||||
{
|
||||
if ( spawnflags & AUTOMATIC )
|
||||
{
|
||||
level.AddAutomaticCamera( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
arc.ArchiveBoolean(&showcamera);
|
||||
|
||||
void SetCamera( Entity *ent, float switchTime );
|
||||
Entity * GetWatchEntity( str watch );
|
||||
if (arc.Loading()) {
|
||||
if (spawnflags & AUTOMATIC) {
|
||||
level.AddAutomaticCamera(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetCamera(Entity *ent, float switchTime);
|
||||
Entity *GetWatchEntity(str watch);
|
||||
|
||||
typedef SafePtr<Camera> CameraPtr;
|
||||
|
||||
class CameraManager : public Listener
|
||||
{
|
||||
protected:
|
||||
Container<str> pathList;
|
||||
BSpline cameraPath;
|
||||
SplinePathPtr path;
|
||||
SplinePathPtr current;
|
||||
float speed;
|
||||
int watch;
|
||||
str pathName;
|
||||
CameraPtr cam;
|
||||
qboolean cameraPath_dirty;
|
||||
{
|
||||
protected:
|
||||
Container<str> pathList;
|
||||
BSpline cameraPath;
|
||||
SplinePathPtr path;
|
||||
SplinePathPtr current;
|
||||
float speed;
|
||||
int watch;
|
||||
str pathName;
|
||||
CameraPtr cam;
|
||||
qboolean cameraPath_dirty;
|
||||
|
||||
void NewPath( Event *ev );
|
||||
void SetPath( Event *ev );
|
||||
void SetTargetName( Event *ev );
|
||||
void SetTarget( Event *ev );
|
||||
void AddPoint( Event *ev );
|
||||
void ReplacePoint( Event *ev );
|
||||
void DeletePoint( Event *ev );
|
||||
void MovePlayer( Event *ev );
|
||||
void NextPoint( Event *ev );
|
||||
void PreviousPoint( Event *ev );
|
||||
void ShowingPath( Event *ev );
|
||||
void ShowPath( Event *ev );
|
||||
void HidePath( Event *ev );
|
||||
void StopPlayback( Event *ev );
|
||||
void PlayPath( Event *ev );
|
||||
void LoopPath( Event *ev );
|
||||
void Watch( Event *ev );
|
||||
void NoWatch( Event *ev );
|
||||
void Fov( Event *ev );
|
||||
void FadeTime( Event *ev );
|
||||
void Speed( Event *ev );
|
||||
void Save( Event *ev );
|
||||
void Load( Event *ev );
|
||||
void SaveMap( Event *ev );
|
||||
void UpdateEvent( Event *ev );
|
||||
void NextPath( Event *ev );
|
||||
void PreviousPath( Event *ev );
|
||||
void RenamePath( Event *ev );
|
||||
void NewPath(Event *ev);
|
||||
void SetPath(Event *ev);
|
||||
void SetTargetName(Event *ev);
|
||||
void SetTarget(Event *ev);
|
||||
void AddPoint(Event *ev);
|
||||
void ReplacePoint(Event *ev);
|
||||
void DeletePoint(Event *ev);
|
||||
void MovePlayer(Event *ev);
|
||||
void NextPoint(Event *ev);
|
||||
void PreviousPoint(Event *ev);
|
||||
void ShowingPath(Event *ev);
|
||||
void ShowPath(Event *ev);
|
||||
void HidePath(Event *ev);
|
||||
void StopPlayback(Event *ev);
|
||||
void PlayPath(Event *ev);
|
||||
void LoopPath(Event *ev);
|
||||
void Watch(Event *ev);
|
||||
void NoWatch(Event *ev);
|
||||
void Fov(Event *ev);
|
||||
void FadeTime(Event *ev);
|
||||
void Speed(Event *ev);
|
||||
void Save(Event *ev);
|
||||
void Load(Event *ev);
|
||||
void SaveMap(Event *ev);
|
||||
void UpdateEvent(Event *ev);
|
||||
void NextPath(Event *ev);
|
||||
void PreviousPath(Event *ev);
|
||||
void RenamePath(Event *ev);
|
||||
|
||||
void ShowPath( void );
|
||||
void UpdateUI( void );
|
||||
void SetPathName( str name );
|
||||
void SavePath( str pathName );
|
||||
void ShowPath(void);
|
||||
void UpdateUI(void);
|
||||
void SetPathName(str name);
|
||||
void SavePath(str pathName);
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( CameraManager );
|
||||
public:
|
||||
CLASS_PROTOTYPE(CameraManager);
|
||||
|
||||
CameraManager();
|
||||
void SetPath( str pathName );
|
||||
void Archive( Archiver &arc ) override;
|
||||
};
|
||||
CameraManager();
|
||||
void SetPath(str pathName);
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline void CameraManager::Archive
|
||||
(
|
||||
Archiver &arc
|
||||
)
|
||||
inline void CameraManager::Archive(Archiver& arc)
|
||||
|
||||
{
|
||||
Listener::Archive( arc );
|
||||
{
|
||||
Listener::Archive(arc);
|
||||
|
||||
pathList.Archive( arc );
|
||||
pathList.Archive(arc);
|
||||
|
||||
// no need to archive the cameraPath
|
||||
arc.ArchiveSafePointer( &path );
|
||||
arc.ArchiveSafePointer( ¤t );
|
||||
arc.ArchiveFloat( &speed );
|
||||
arc.ArchiveInteger( &watch );
|
||||
arc.ArchiveString( &pathName );
|
||||
arc.ArchiveSafePointer( &cam );
|
||||
// no need to archive the cameraPath
|
||||
arc.ArchiveSafePointer(&path);
|
||||
arc.ArchiveSafePointer(¤t);
|
||||
arc.ArchiveFloat(&speed);
|
||||
arc.ArchiveInteger(&watch);
|
||||
arc.ArchiveString(&pathName);
|
||||
arc.ArchiveSafePointer(&cam);
|
||||
|
||||
// make sure the cameraPath gets rebuilt
|
||||
cameraPath_dirty = qtrue;
|
||||
}
|
||||
// make sure the cameraPath gets rebuilt
|
||||
cameraPath_dirty = qtrue;
|
||||
}
|
||||
|
||||
extern CameraManager CameraMan;
|
||||
|
||||
#endif /* camera.h */
|
||||
+297
-374
@@ -45,491 +45,414 @@ NOTSTACKED prevents the crate from causing crates above it to fall. Great for cr
|
||||
|
||||
Event EV_Crate_Think
|
||||
(
|
||||
"_crate_think",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"think function for a crate."
|
||||
"_crate_think",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"think function for a crate."
|
||||
);
|
||||
|
||||
Event EV_Crate_Falling
|
||||
(
|
||||
"_crate_falling",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"crate's falling."
|
||||
"_crate_falling",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"crate's falling."
|
||||
);
|
||||
|
||||
Event EV_Crate_Setup
|
||||
(
|
||||
"_cratesetup",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Does the post spawn setup of the crate"
|
||||
"_cratesetup",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Does the post spawn setup of the crate"
|
||||
);
|
||||
|
||||
Event EV_Crate_Start_Falling
|
||||
(
|
||||
"_cratestartfalling",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Makes a crate start falling"
|
||||
"_cratestartfalling",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Makes a crate start falling"
|
||||
);
|
||||
|
||||
Event EV_Crate_SetDebris
|
||||
(
|
||||
"debristype",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"type",
|
||||
"Sets the debris type of the crate"
|
||||
"debristype",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"type",
|
||||
"Sets the debris type of the crate"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION( Entity, CrateObject, "func_crate" )
|
||||
{
|
||||
{ &EV_Crate_Setup, &CrateObject::CrateSetup },
|
||||
{ &EV_Crate_Falling, &CrateObject::CrateFalling },
|
||||
{ &EV_Damage, &CrateObject::CrateDamaged },
|
||||
{ &EV_Killed, &CrateObject::CrateKilled },
|
||||
{ &EV_Crate_Start_Falling, &CrateObject::StartFalling },
|
||||
{ &EV_Crate_Think, &CrateObject::CrateThink },
|
||||
{ &EV_Crate_SetDebris, &CrateObject::CrateDebrisType },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(Entity, CrateObject, "func_crate") {
|
||||
{&EV_Crate_Setup, &CrateObject::CrateSetup },
|
||||
{&EV_Crate_Falling, &CrateObject::CrateFalling },
|
||||
{&EV_Damage, &CrateObject::CrateDamaged },
|
||||
{&EV_Killed, &CrateObject::CrateKilled },
|
||||
{&EV_Crate_Start_Falling, &CrateObject::StartFalling },
|
||||
{&EV_Crate_Think, &CrateObject::CrateThink },
|
||||
{&EV_Crate_SetDebris, &CrateObject::CrateDebrisType},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
CrateObject::CrateObject()
|
||||
{
|
||||
entflags |= EF_CRATEOBJECT;
|
||||
entflags |= ECF_CRATEOBJECT;
|
||||
|
||||
AddWaitTill(STRING_DEATH);
|
||||
AddWaitTill(STRING_DEATH);
|
||||
|
||||
if( LoadingSavegame )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (LoadingSavegame) {
|
||||
return;
|
||||
}
|
||||
|
||||
edict->s.eType = ET_GENERAL;
|
||||
edict->s.eType = ET_GENERAL;
|
||||
|
||||
m_fMoveTime = 0.0f;
|
||||
m_fMoveTime = 0.0f;
|
||||
|
||||
health = 100.0f;
|
||||
max_health = 100.0f;
|
||||
deadflag = 0;
|
||||
takedamage = DAMAGE_YES;
|
||||
health = 100.0f;
|
||||
max_health = 100.0f;
|
||||
deadflag = 0;
|
||||
takedamage = DAMAGE_YES;
|
||||
|
||||
mass = 1200;
|
||||
mass = 1200;
|
||||
|
||||
m_iDebrisType = 0;
|
||||
m_iDebrisType = 0;
|
||||
|
||||
PostEvent( EV_Crate_Setup, EV_POSTSPAWN );
|
||||
PostEvent(EV_Crate_Setup, EV_POSTSPAWN);
|
||||
}
|
||||
|
||||
|
||||
void CrateObject::TellNeighborsToFall
|
||||
(
|
||||
void
|
||||
)
|
||||
void CrateObject::TellNeighborsToFall(void)
|
||||
{
|
||||
Entity *pEnt;
|
||||
Entity *pNext;
|
||||
Vector vMins;
|
||||
Vector vMaxs;
|
||||
Entity *pEnt;
|
||||
Entity *pNext;
|
||||
Vector vMins;
|
||||
Vector vMaxs;
|
||||
|
||||
vMins[ 0 ] = mins[ 0 ] + origin[ 0 ] + 6.0f;
|
||||
vMins[ 1 ] = mins[ 1 ] + origin[ 1 ] + 6.0f;
|
||||
vMins[ 2 ] = mins[ 2 ] + origin[ 2 ] + 6.0f;
|
||||
vMins[0] = mins[0] + origin[0] + 6.0f;
|
||||
vMins[1] = mins[1] + origin[1] + 6.0f;
|
||||
vMins[2] = mins[2] + origin[2] + 6.0f;
|
||||
|
||||
vMaxs[ 0 ] = maxs[ 0 ] + origin[ 0 ] - 6.0f;
|
||||
vMaxs[ 1 ] = maxs[ 1 ] + origin[ 1 ] - 6.0f;
|
||||
vMaxs[ 2 ] = maxs[ 2 ] + origin[ 2 ] + 12.0f;
|
||||
vMaxs[0] = maxs[0] + origin[0] - 6.0f;
|
||||
vMaxs[1] = maxs[1] + origin[1] - 6.0f;
|
||||
vMaxs[2] = maxs[2] + origin[2] + 12.0f;
|
||||
|
||||
for( pEnt = G_NextEntity( NULL ); pEnt != NULL; pEnt = pNext )
|
||||
{
|
||||
pNext = G_NextEntity( pEnt );
|
||||
for (pEnt = G_NextEntity(NULL); pEnt != NULL; pEnt = pNext) {
|
||||
pNext = G_NextEntity(pEnt);
|
||||
|
||||
for( pEnt = G_NextEntity( NULL ); pEnt != NULL; pEnt = pNext )
|
||||
{
|
||||
pNext = G_NextEntity( pEnt );
|
||||
for (pEnt = G_NextEntity(NULL); pEnt != NULL; pEnt = pNext) {
|
||||
pNext = G_NextEntity(pEnt);
|
||||
|
||||
if( pEnt != this && pEnt->IsSubclassOfCrateObject() )
|
||||
{
|
||||
if( vMins[ 0 ] <= absmax[ 0 ] &&
|
||||
vMins[ 1 ] <= absmax[ 1 ] &&
|
||||
vMins[ 2 ] <= absmax[ 2 ] &&
|
||||
absmin[ 0 ] <= vMaxs[ 0 ] &&
|
||||
absmin[ 1 ] <= vMaxs[ 1 ] &&
|
||||
absmin[ 2 ] <= vMaxs[ 2 ] )
|
||||
{
|
||||
if( !pEnt->EventPending( EV_Crate_Start_Falling ) )
|
||||
{
|
||||
float time = level.frametime + level.frametime;
|
||||
pEnt->PostEvent( EV_Crate_Start_Falling, time );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pEnt != this && pEnt->IsSubclassOfCrateObject()) {
|
||||
if (vMins[0] <= absmax[0] && vMins[1] <= absmax[1] && vMins[2] <= absmax[2] && absmin[0] <= vMaxs[0]
|
||||
&& absmin[1] <= vMaxs[1] && absmin[2] <= vMaxs[2]) {
|
||||
if (!pEnt->EventPending(EV_Crate_Start_Falling)) {
|
||||
float time = level.frametime + level.frametime;
|
||||
pEnt->PostEvent(EV_Crate_Start_Falling, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CrateObject::TellNeighborsToJitter
|
||||
(
|
||||
Vector vJitterAdd
|
||||
)
|
||||
void CrateObject::TellNeighborsToJitter(Vector vJitterAdd)
|
||||
{
|
||||
Entity *pEnt;
|
||||
Entity *pNext;
|
||||
Vector vMins;
|
||||
Vector vMaxs;
|
||||
|
||||
Entity *pEnt;
|
||||
Entity *pNext;
|
||||
Vector vMins;
|
||||
Vector vMaxs;
|
||||
vMins[0] = mins[0] + origin[0] + 6.0f;
|
||||
vMins[1] = mins[1] + origin[1] + 6.0f;
|
||||
vMins[2] = mins[2] + origin[2] + 6.0f;
|
||||
|
||||
vMins[ 0 ] = mins[ 0 ] + origin[ 0 ] + 6.0f;
|
||||
vMins[ 1 ] = mins[ 1 ] + origin[ 1 ] + 6.0f;
|
||||
vMins[ 2 ] = mins[ 2 ] + origin[ 2 ] + 6.0f;
|
||||
vMaxs[0] = maxs[0] + origin[0] - 6.0f;
|
||||
vMaxs[1] = maxs[1] + origin[1] - 6.0f;
|
||||
vMaxs[2] = maxs[2] + origin[2] + 12.0f;
|
||||
|
||||
vMaxs[ 0 ] = maxs[ 0 ] + origin[ 0 ] - 6.0f;
|
||||
vMaxs[ 1 ] = maxs[ 1 ] + origin[ 1 ] - 6.0f;
|
||||
vMaxs[ 2 ] = maxs[ 2 ] + origin[ 2 ] + 12.0f;
|
||||
for (pEnt = G_NextEntity(NULL); pEnt != NULL; pEnt = pNext) {
|
||||
CrateObject *crate = (CrateObject *)pEnt;
|
||||
|
||||
for( pEnt = G_NextEntity( NULL ); pEnt != NULL; pEnt = pNext )
|
||||
{
|
||||
CrateObject *crate = ( CrateObject * )pEnt;
|
||||
pNext = G_NextEntity(pEnt);
|
||||
|
||||
pNext = G_NextEntity( pEnt );
|
||||
if (pEnt == this) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( pEnt == this )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!pEnt->IsSubclassOfCrateObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !pEnt->IsSubclassOfCrateObject() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (vMins[0] > absmax[0] || vMins[1] > absmax[1] || vMins[2] > absmax[2] || absmin[0] > vMaxs[0]
|
||||
|| absmin[1] > vMaxs[1] || absmin[2] > vMaxs[2]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( vMins[ 0 ] > absmax[ 0 ] ||
|
||||
vMins[ 1 ] > absmax[ 1 ] ||
|
||||
vMins[ 2 ] > absmax[ 2 ] ||
|
||||
absmin[ 0 ] > vMaxs[ 0 ] ||
|
||||
absmin[ 1 ] > vMaxs[ 1 ] ||
|
||||
absmin[ 2 ] > vMaxs[ 2 ] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
crate->m_vJitterAngles[0] = m_vJitterAngles[0] + vJitterAdd[0];
|
||||
|
||||
crate->m_vJitterAngles[ 0 ] = m_vJitterAngles[ 0 ] + vJitterAdd[ 0 ];
|
||||
if (crate->m_vJitterAngles[0] > m_fJitterScale * 1.25f
|
||||
|| -(m_fJitterScale * 1.25f) <= crate->m_vJitterAngles[0]) {
|
||||
crate->m_vJitterAngles[0] = m_fJitterScale * 1.25f;
|
||||
}
|
||||
|
||||
if( crate->m_vJitterAngles[ 0 ] > m_fJitterScale * 1.25f ||
|
||||
-( m_fJitterScale * 1.25f ) <= crate->m_vJitterAngles[ 0 ] )
|
||||
{
|
||||
crate->m_vJitterAngles[ 0 ] = m_fJitterScale * 1.25f;
|
||||
}
|
||||
crate->m_vJitterAngles[2] += vJitterAdd[2];
|
||||
|
||||
crate->m_vJitterAngles[ 2 ] += vJitterAdd[ 2 ];
|
||||
if (crate->m_vJitterAngles[2] > m_fJitterScale * 1.25f) {
|
||||
break;
|
||||
}
|
||||
|
||||
if( crate->m_vJitterAngles[ 2 ] > m_fJitterScale * 1.25f ) {
|
||||
break;
|
||||
}
|
||||
if (-(m_fJitterScale * 1.25f) <= crate->m_vJitterAngles[2]) {
|
||||
m_vJitterAngles[2] = -(m_fJitterScale * 1.25f);
|
||||
}
|
||||
|
||||
if( -( m_fJitterScale * 1.25f ) <= crate->m_vJitterAngles[ 2 ] )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] = -( m_fJitterScale * 1.25f );
|
||||
}
|
||||
|
||||
if( !crate->EventPending( EV_Crate_Think ) )
|
||||
{
|
||||
crate->ProcessEvent( EV_Crate_Think );
|
||||
}
|
||||
}
|
||||
if (!crate->EventPending(EV_Crate_Think)) {
|
||||
crate->ProcessEvent(EV_Crate_Think);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CrateObject::CrateSetup
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void CrateObject::CrateSetup(Event *ev)
|
||||
{
|
||||
Vector vMins;
|
||||
Vector vMaxs;
|
||||
Entity *pEnt;
|
||||
Entity *pNext;
|
||||
Vector vMins;
|
||||
Vector vMaxs;
|
||||
Entity *pEnt;
|
||||
Entity *pNext;
|
||||
|
||||
mass = 20 * ( size[ 0 ] * 0.625f * size[ 1 ] * 0.625f * size[ 2 ] * 0.625f );
|
||||
mass = 20 * ((size[0] / 16) * (size[1] / 16) * (size[2] / 16));
|
||||
|
||||
m_vStartAngles = angles;
|
||||
m_fJitterScale = 64.0f / size[ 2 ];
|
||||
m_vStartAngles = angles;
|
||||
m_fJitterScale = 64.0f / size[2];
|
||||
|
||||
setMoveType( MOVETYPE_PUSH );
|
||||
setSolidType( SOLID_BSP );
|
||||
setMoveType(MOVETYPE_PUSH);
|
||||
setSolidType(SOLID_BSP);
|
||||
|
||||
vMins[ 0 ] = mins[ 0 ] + origin[ 0 ] + 12.0f;
|
||||
vMins[ 1 ] = mins[ 1 ] + origin[ 1 ] + 12.0f;
|
||||
vMins[ 2 ] = mins[ 2 ] + origin[ 2 ] + 18.0f;
|
||||
vMins = origin + mins + Vector(12, 12, 18);
|
||||
vMaxs = origin + maxs - Vector(12, 12, 18);
|
||||
|
||||
vMaxs[ 0 ] = maxs[ 0 ] + origin[ 0 ] - 12.0f;
|
||||
vMaxs[ 1 ] = maxs[ 1 ] + origin[ 1 ] - 12.0f;
|
||||
vMaxs[ 2 ] = maxs[ 2 ] + origin[ 2 ] - 18.0f;
|
||||
for (pEnt = G_NextEntity(NULL); pEnt != NULL; pEnt = pNext) {
|
||||
pNext = G_NextEntity(pEnt);
|
||||
|
||||
for( pEnt = G_NextEntity( NULL ); pEnt != NULL; pEnt = pNext )
|
||||
{
|
||||
pNext = G_NextEntity( pEnt );
|
||||
if (pEnt->entnum <= entnum) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( pEnt->entnum > entnum && pEnt->IsSubclassOfCrateObject() )
|
||||
{
|
||||
if( vMins[ 0 ] <= absmax[ 0 ] &&
|
||||
vMins[ 1 ] <= absmax[ 1 ] &&
|
||||
vMins[ 2 ] <= absmax[ 2 ] &&
|
||||
absmin[ 0 ] <= vMaxs[ 0 ] &&
|
||||
absmin[ 1 ] <= vMaxs[ 1 ] &&
|
||||
absmin[ 2 ] <= vMaxs[ 2 ] )
|
||||
{
|
||||
Com_Printf( "^~^~^ WARNING: func_crate entities %i and %i have overlapping volumes near (%g %g %g) to (%g %g %g)\n",
|
||||
entnum, pEnt->entnum, vMins[ 0 ], vMins[ 1 ], vMins[ 2 ], vMaxs[ 0 ], vMaxs[ 1 ], vMaxs[ 2 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pEnt->IsSubclassOfCrateObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vMins[0] <= pEnt->absmax[0]
|
||||
&& vMins[1] <= pEnt->absmax[1]
|
||||
&& vMins[2] <= pEnt->absmax[2]
|
||||
&& vMaxs[0] >= pEnt->absmin[0]
|
||||
&& vMaxs[1] >= pEnt->absmin[1]
|
||||
&& vMaxs[2] >= pEnt->absmin[2]) {
|
||||
Com_Printf(
|
||||
"^~^~^ WARNING: func_crate entities %i and %i have overlapping volumes near (%g %g %g) to (%g %g %g)\n",
|
||||
entnum,
|
||||
pEnt->entnum,
|
||||
vMins[0],
|
||||
vMins[1],
|
||||
vMins[2],
|
||||
vMaxs[0],
|
||||
vMaxs[1],
|
||||
vMaxs[2]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CrateObject::CrateDebrisType
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void CrateObject::CrateDebrisType(Event *ev)
|
||||
{
|
||||
m_iDebrisType = ev->GetInteger( 1 );
|
||||
m_iDebrisType = ev->GetInteger(1);
|
||||
|
||||
if( m_iDebrisType >= 0 )
|
||||
{
|
||||
CacheResource( va( "models/fx/crates/debris_%i.tik", m_iDebrisType ) );
|
||||
}
|
||||
if (m_iDebrisType >= 0) {
|
||||
CacheResource(va("models/fx/crates/debris_%i.tik", m_iDebrisType));
|
||||
}
|
||||
}
|
||||
|
||||
void CrateObject::StartFalling
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void CrateObject::StartFalling(Event *ev)
|
||||
{
|
||||
setMoveType( MOVETYPE_FLY );
|
||||
m_fMoveTime = 0;
|
||||
setMoveType(MOVETYPE_FLY);
|
||||
m_fMoveTime = 0;
|
||||
|
||||
PostEvent( EV_Crate_Think, level.frametime );
|
||||
PostEvent(EV_Crate_Think, level.frametime);
|
||||
|
||||
if( !( spawnflags & CRATE_NOTSTACKEDON ) )
|
||||
{
|
||||
TellNeighborsToFall();
|
||||
}
|
||||
if (!(spawnflags & CRATE_NOTSTACKEDON)) {
|
||||
TellNeighborsToFall();
|
||||
}
|
||||
}
|
||||
|
||||
void CrateObject::CrateFalling
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void CrateObject::CrateFalling(Event *ev)
|
||||
{
|
||||
if( velocity != vec_zero || !groundentity || edict->solid != SOLID_BSP )
|
||||
{
|
||||
m_fMoveTime = level.time + 2.0f;
|
||||
}
|
||||
if (velocity != vec_zero || !groundentity || edict->solid != SOLID_BSP) {
|
||||
m_fMoveTime = level.time + 2.0f;
|
||||
}
|
||||
|
||||
if( level.time <= m_fMoveTime )
|
||||
{
|
||||
PostEvent( EV_Crate_Think, level.frametime );
|
||||
}
|
||||
else
|
||||
{
|
||||
setMoveType( MOVETYPE_PUSH );
|
||||
setSolidType( SOLID_BSP );
|
||||
}
|
||||
if (level.time <= m_fMoveTime) {
|
||||
PostEvent(EV_Crate_Think, level.frametime);
|
||||
} else {
|
||||
setMoveType(MOVETYPE_PUSH);
|
||||
setSolidType(SOLID_BSP);
|
||||
}
|
||||
}
|
||||
|
||||
void CrateObject::CrateDamaged
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void CrateObject::CrateDamaged(Event *ev)
|
||||
{
|
||||
Vector vDir;
|
||||
Vector vForward;
|
||||
Vector vRight;
|
||||
Vector vJitterAdd;
|
||||
int iDamage;
|
||||
int iMeansOfDeath;
|
||||
Vector vHitPos;
|
||||
Vector vHitDirection;
|
||||
Vector vHitNormal;
|
||||
Vector vDir;
|
||||
Vector vForward;
|
||||
Vector vRight;
|
||||
Vector vJitterAdd;
|
||||
int iDamage;
|
||||
int iMeansOfDeath;
|
||||
Vector vHitPos;
|
||||
Vector vHitDirection;
|
||||
Vector vHitNormal;
|
||||
|
||||
if( !takedamage )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!takedamage) {
|
||||
return;
|
||||
}
|
||||
|
||||
iDamage = ev->GetInteger( 2 );
|
||||
iMeansOfDeath = ev->GetInteger( 9 );
|
||||
vHitPos = ev->GetVector( 4 );
|
||||
vHitDirection = ev->GetVector( 5 );
|
||||
vHitNormal = ev->GetVector( 6 );
|
||||
iDamage = ev->GetInteger(2);
|
||||
iMeansOfDeath = ev->GetInteger(9);
|
||||
vHitPos = ev->GetVector(4);
|
||||
vHitDirection = ev->GetVector(5);
|
||||
vHitNormal = ev->GetVector(6);
|
||||
|
||||
vDir = ( vHitDirection - vHitNormal ) * 0.5f;
|
||||
AngleVectors( angles, vForward, vRight, NULL );
|
||||
vDir = (vHitDirection - vHitNormal) * 0.5f;
|
||||
AngleVectors(angles, vForward, vRight, NULL);
|
||||
|
||||
vJitterAdd[ 0 ] = DotProduct( vDir, vForward ) * m_fJitterScale * 0.025f * ( float )iDamage;
|
||||
vJitterAdd[ 2 ] = DotProduct( vDir, vRight ) * m_fJitterScale * 0.025f * ( float )iDamage;
|
||||
vJitterAdd[0] = DotProduct(vDir, vForward) * m_fJitterScale * 0.025f * (float)iDamage;
|
||||
vJitterAdd[2] = DotProduct(vDir, vRight) * m_fJitterScale * 0.025f * (float)iDamage;
|
||||
|
||||
m_vJitterAngles += Vector( vJitterAdd[ 0 ], 0, vJitterAdd[ 2 ] );
|
||||
m_vJitterAngles += Vector(vJitterAdd[0], 0, vJitterAdd[2]);
|
||||
|
||||
if( m_vJitterAngles[ 0 ] > m_fJitterScale * 1.25f ||
|
||||
-( m_fJitterScale * 1.25f ) > m_vJitterAngles[ 0 ] )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] = m_fJitterScale * 1.25f;
|
||||
}
|
||||
if (m_vJitterAngles[0] > m_fJitterScale * 1.25f || -(m_fJitterScale * 1.25f) > m_vJitterAngles[0]) {
|
||||
m_vJitterAngles[0] = m_fJitterScale * 1.25f;
|
||||
}
|
||||
|
||||
if( m_vJitterAngles[ 2 ] > m_fJitterScale * 1.25f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] = m_fJitterScale * 1.25f;
|
||||
}
|
||||
else if( m_vJitterAngles[ 2 ] >= -( m_fJitterScale * 1.25f ) )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] = -( m_fJitterScale * 1.25f );
|
||||
}
|
||||
if (m_vJitterAngles[2] > m_fJitterScale * 1.25f) {
|
||||
m_vJitterAngles[2] = m_fJitterScale * 1.25f;
|
||||
} else if (m_vJitterAngles[2] >= -(m_fJitterScale * 1.25f)) {
|
||||
m_vJitterAngles[2] = -(m_fJitterScale * 1.25f);
|
||||
}
|
||||
|
||||
vJitterAdd[ 1 ] = 0.0f;
|
||||
vJitterAdd *= -0.5f;
|
||||
|
||||
TellNeighborsToJitter( vJitterAdd );
|
||||
|
||||
if( !EventPending( EV_Crate_Think ) )
|
||||
{
|
||||
ProcessEvent( EV_Crate_Think );
|
||||
}
|
||||
|
||||
if( spawnflags & CRATE_INDESTRUCTABLE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( iMeansOfDeath >= MOD_VEHICLE )
|
||||
{
|
||||
if( iMeansOfDeath == MOD_BASH )
|
||||
{
|
||||
iDamage *= 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iDamage /= 2;
|
||||
}
|
||||
|
||||
health -= iDamage;
|
||||
|
||||
if( health <= 0.0f )
|
||||
{
|
||||
Event *event = new Event( EV_Killed );
|
||||
event->AddEntity( ev->GetEntity( 1 ) );
|
||||
event->AddInteger( iDamage );
|
||||
ev->AddEntity( ev->GetEntity( 3 ) );
|
||||
|
||||
ProcessEvent( event );
|
||||
}
|
||||
vJitterAdd[1] = 0.0f;
|
||||
vJitterAdd *= -0.5f;
|
||||
|
||||
TellNeighborsToJitter(vJitterAdd);
|
||||
|
||||
if (!EventPending(EV_Crate_Think)) {
|
||||
ProcessEvent(EV_Crate_Think);
|
||||
}
|
||||
|
||||
if (spawnflags & CRATE_INDESTRUCTABLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (iMeansOfDeath >= MOD_VEHICLE) {
|
||||
if (iMeansOfDeath == MOD_BASH) {
|
||||
iDamage *= 2;
|
||||
}
|
||||
} else {
|
||||
iDamage /= 2;
|
||||
}
|
||||
|
||||
health -= iDamage;
|
||||
|
||||
if (health <= 0.0f) {
|
||||
Event *event = new Event(EV_Killed);
|
||||
event->AddEntity(ev->GetEntity(1));
|
||||
event->AddInteger(iDamage);
|
||||
ev->AddEntity(ev->GetEntity(3));
|
||||
|
||||
ProcessEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void CrateObject::CrateKilled
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void CrateObject::CrateKilled(Event *ev)
|
||||
{
|
||||
Vector vCenter;
|
||||
Entity *attacker = ev->GetEntity( 1 );
|
||||
Vector vCenter;
|
||||
Entity *attacker = ev->GetEntity(1);
|
||||
|
||||
if( attacker->IsSubclassOfPlayer() )
|
||||
{
|
||||
Player *p = ( Player * )attacker;
|
||||
p->m_iNumObjectsDestroyed++;
|
||||
}
|
||||
if (attacker->IsSubclassOfPlayer()) {
|
||||
Player *p = (Player *)attacker;
|
||||
p->m_iNumObjectsDestroyed++;
|
||||
}
|
||||
|
||||
setSolidType( SOLID_NOT );
|
||||
hideModel();
|
||||
setSolidType(SOLID_NOT);
|
||||
hideModel();
|
||||
|
||||
takedamage = DAMAGE_NO;
|
||||
takedamage = DAMAGE_NO;
|
||||
|
||||
if( !( spawnflags & CRATE_NOTSTACKEDON ) )
|
||||
{
|
||||
TellNeighborsToFall();
|
||||
}
|
||||
if (!(spawnflags & CRATE_NOTSTACKEDON)) {
|
||||
TellNeighborsToFall();
|
||||
}
|
||||
|
||||
vCenter = origin + ( maxs + mins ) * 0.5f;
|
||||
vCenter = origin + (maxs + mins) * 0.5f;
|
||||
|
||||
// Tell clients around that a crate is destroyed
|
||||
gi.SetBroadcastVisible( origin, origin );
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_CRATE_DEBRIS));
|
||||
gi.MSG_WriteCoord( vCenter[ 0 ] );
|
||||
gi.MSG_WriteCoord( vCenter[ 1 ] );
|
||||
gi.MSG_WriteCoord( vCenter[ 2 ] );
|
||||
gi.MSG_WriteByte( m_iDebrisType );
|
||||
gi.MSG_EndCGM();
|
||||
// Tell clients around that a crate is destroyed
|
||||
gi.SetBroadcastVisible(origin, origin);
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_CRATE_DEBRIS));
|
||||
gi.MSG_WriteCoord(vCenter[0]);
|
||||
gi.MSG_WriteCoord(vCenter[1]);
|
||||
gi.MSG_WriteCoord(vCenter[2]);
|
||||
gi.MSG_WriteByte(m_iDebrisType);
|
||||
gi.MSG_EndCGM();
|
||||
|
||||
health = 0;
|
||||
deadflag = DEAD_DEAD;
|
||||
health = 0;
|
||||
deadflag = DEAD_DEAD;
|
||||
|
||||
PostEvent( EV_Remove, 0 );
|
||||
PostEvent(EV_Remove, 0);
|
||||
|
||||
// Notify scripts
|
||||
Unregister( STRING_DEATH );
|
||||
// Notify scripts
|
||||
Unregister(STRING_DEATH);
|
||||
}
|
||||
|
||||
void CrateObject::CrateThink
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void CrateObject::CrateThink(Event *ev)
|
||||
{
|
||||
// Shake the create if it's on fire
|
||||
// Shake the create if it's on fire
|
||||
|
||||
if( m_vJitterAngles[ 0 ] || m_vJitterAngles[ 2 ] )
|
||||
{
|
||||
setAngles( Vector( m_vStartAngles[ 0 ] * 2.0f, m_vStartAngles[ 1 ], m_vStartAngles[ 2 ] * 2.0f ) );
|
||||
if (m_vJitterAngles[0] || m_vJitterAngles[2]) {
|
||||
setAngles(Vector(m_vStartAngles[0] * 2.0f, m_vStartAngles[1], m_vStartAngles[2] * 2.0f));
|
||||
|
||||
if( m_vJitterAngles[ 0 ] > 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] -= 1 / 3 * m_fJitterScale;
|
||||
if (m_vJitterAngles[0] > 0.0f) {
|
||||
m_vJitterAngles[0] -= 1 / 3 * m_fJitterScale;
|
||||
|
||||
if( m_vJitterAngles[ 0 ] > 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] = 0.0f;
|
||||
}
|
||||
}
|
||||
else if( m_vJitterAngles[ 0 ] < 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] += 1 / 3 * m_fJitterScale;
|
||||
if (m_vJitterAngles[0] > 0.0f) {
|
||||
m_vJitterAngles[0] = 0.0f;
|
||||
}
|
||||
} else if (m_vJitterAngles[0] < 0.0f) {
|
||||
m_vJitterAngles[0] += 1 / 3 * m_fJitterScale;
|
||||
|
||||
if( m_vJitterAngles[ 0 ] < 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] = 0.0f;
|
||||
}
|
||||
}
|
||||
if (m_vJitterAngles[0] < 0.0f) {
|
||||
m_vJitterAngles[0] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
m_vJitterAngles[ 0 ] = -m_vJitterAngles[ 0 ];
|
||||
m_vJitterAngles[0] = -m_vJitterAngles[0];
|
||||
|
||||
if( m_vJitterAngles[ 2 ] > 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] -= 1 / 3 * m_fJitterScale;
|
||||
if (m_vJitterAngles[2] > 0.0f) {
|
||||
m_vJitterAngles[2] -= 1 / 3 * m_fJitterScale;
|
||||
|
||||
if( m_vJitterAngles[ 2 ] > 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] = 0.0f;
|
||||
}
|
||||
}
|
||||
else if( m_vJitterAngles[ 2 ] < 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] += 1 / 3 * m_fJitterScale;
|
||||
if (m_vJitterAngles[2] > 0.0f) {
|
||||
m_vJitterAngles[2] = 0.0f;
|
||||
}
|
||||
} else if (m_vJitterAngles[2] < 0.0f) {
|
||||
m_vJitterAngles[2] += 1 / 3 * m_fJitterScale;
|
||||
|
||||
if( m_vJitterAngles[ 2 ] < 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] = 0.0f;
|
||||
}
|
||||
}
|
||||
if (m_vJitterAngles[2] < 0.0f) {
|
||||
m_vJitterAngles[2] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
m_vJitterAngles[ 2 ] = -m_vJitterAngles[ 2 ];
|
||||
m_vJitterAngles[2] = -m_vJitterAngles[2];
|
||||
|
||||
PostEvent( EV_Crate_Think, 0.05f );
|
||||
}
|
||||
else if( !VectorCompare( angles, m_vStartAngles ) )
|
||||
{
|
||||
setAngles( m_vStartAngles );
|
||||
}
|
||||
PostEvent(EV_Crate_Think, 0.05f);
|
||||
} else if (!VectorCompare(angles, m_vStartAngles)) {
|
||||
setAngles(m_vStartAngles);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 434 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user