mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-25 12:00:31 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
586da44c30 | ||
|
|
3956e03557 | ||
|
|
8d0b7b77c6 | ||
|
|
23ad991743 | ||
|
|
4493b2c42e | ||
|
|
8b6b1597d7 | ||
|
|
dddedba721 | ||
|
|
be34870a18 | ||
|
|
4d4b9288c6 | ||
|
|
fc9be91124 | ||
|
|
0d24c620fb | ||
|
|
89140f775e | ||
|
|
de6718b511 | ||
|
|
5c094f9c8a | ||
|
|
e2f4d8cd6b | ||
|
|
04da76167c | ||
|
|
90639cee36 | ||
|
|
ecfdcca4d5 | ||
|
|
3790f057e1 | ||
|
|
44d8adcfb0 | ||
|
|
64f877ae80 | ||
|
|
2ce8450a7e | ||
|
|
7e7b3ab280 | ||
|
|
48c2d026e6 | ||
|
|
ad825f5114 | ||
|
|
120a486aea | ||
|
|
864cdf1fc6 | ||
|
|
f1c12e0649 | ||
|
|
58d8a73269 | ||
|
|
c788d57c52 | ||
|
|
50eda4156a | ||
|
|
1e609a4b2f | ||
|
|
a0e2162dd7 | ||
|
|
01dfbcdbfe | ||
|
|
862af012cb | ||
|
|
d83374d38c | ||
|
|
05e14f6364 | ||
|
|
6bc621462c | ||
|
|
acb08b89f7 | ||
|
|
2107523eda | ||
|
|
2662174eba | ||
|
|
59d03ff6f0 | ||
|
|
05d304dfc3 | ||
|
|
614ed6e632 | ||
|
|
eb938c872d | ||
|
|
46e1aa979b | ||
|
|
ec5acb4d98 | ||
|
|
b237222761 | ||
|
|
652df1a5af | ||
|
|
69621335db | ||
|
|
7b58fbec8a | ||
|
|
aeb8aa8e55 | ||
|
|
e74e113199 | ||
|
|
953091cdc8 | ||
|
|
5819145af8 | ||
|
|
154464cda1 | ||
|
|
2342f08a79 | ||
|
|
16711a33ef | ||
|
|
cea0d95fee | ||
|
|
989ec9574c | ||
|
|
b0b82f0252 | ||
|
|
80ddba1013 | ||
|
|
23f776d3c7 | ||
|
|
880acf9120 | ||
|
|
598110477e | ||
|
|
ffdfbc3c7d | ||
|
|
a7dc8b3493 | ||
|
|
67d8cad64d | ||
|
|
b007842fb4 | ||
|
|
2c4b5fc9ba | ||
|
|
e96a3f4f59 | ||
|
|
8eded28efc | ||
|
|
b68bb4cee7 | ||
|
|
824cfd789c | ||
|
|
a0b80a9096 | ||
|
|
857d25825b | ||
|
|
735832829d | ||
|
|
5703161166 | ||
|
|
d85455e9ec | ||
|
|
f6c9de4286 | ||
|
|
a598cbf0dc | ||
|
|
67b285924c | ||
|
|
0c206beb45 | ||
|
|
9a6472210c | ||
|
|
7576d1241d | ||
|
|
fb2f3bddaa | ||
|
|
96ca9c20e4 | ||
|
|
d01fa33e46 | ||
|
|
ab84a6ea58 | ||
|
|
b0a683c188 | ||
|
|
e5ef61c5d2 | ||
|
|
02af9a763d | ||
|
|
132903a843 | ||
|
|
fe862badf6 | ||
|
|
1ad5964c2f | ||
|
|
851a16e18c | ||
|
|
763a79cb74 | ||
|
|
c9ccb0efaf | ||
|
|
9e060d11b6 | ||
|
|
50fdbaf152 | ||
|
|
ccca958ec5 | ||
|
|
dd37ba2741 | ||
|
|
81b49236a5 | ||
|
|
894e1d7d66 | ||
|
|
9d83d58756 | ||
|
|
54b9a0c340 | ||
|
|
2cf380c15d | ||
|
|
d400d8927d | ||
|
|
fef30ff3d5 | ||
|
|
4023c9d863 | ||
|
|
7bcb91bbb5 | ||
|
|
5edee7d12e | ||
|
|
51c7e27bc1 | ||
|
|
f400190531 | ||
|
|
8732e368b6 | ||
|
|
7e4da514f6 | ||
|
|
9a55939b42 | ||
|
|
cd89d2c0b4 | ||
|
|
661b08a7fa | ||
|
|
d27f928e2d | ||
|
|
079555e43a | ||
|
|
fcc4e94655 | ||
|
|
c5721f8a2c | ||
|
|
e5acee55ea | ||
|
|
d3f3b9b51c | ||
|
|
48e9db8966 | ||
|
|
67486f1e49 | ||
|
|
923a6de394 | ||
|
|
de0e4954f8 | ||
|
|
1ef1bad9ae | ||
|
|
23a035e2ca | ||
|
|
ec73268f94 | ||
|
|
2b06cc690e | ||
|
|
7afc2427ac | ||
|
|
f3bbcba4f0 | ||
|
|
0dca08a66a | ||
|
|
f646151ce2 | ||
|
|
2e0e5db260 | ||
|
|
f34aad03cd | ||
|
|
332d209f62 | ||
|
|
888e35466b | ||
|
|
1f69fce10e | ||
|
|
ac3eb58671 | ||
|
|
14f3e2faf9 | ||
|
|
a528e916c2 | ||
|
|
e6f83bc1d6 | ||
|
|
841a8d2b4a | ||
|
|
a51c250a31 | ||
|
|
c2291e92c4 | ||
|
|
b8cc3313b1 | ||
|
|
d1fca3e499 | ||
|
|
66b882346f | ||
|
|
b38fedb18c | ||
|
|
e6559c6ae6 | ||
|
|
772aad79d7 | ||
|
|
3e84dbe6ac | ||
|
|
381f2b02f5 | ||
|
|
f347102ecb | ||
|
|
f5d2fdbcad | ||
|
|
ab037f1890 | ||
|
|
a933c78d93 | ||
|
|
d08f539e6d | ||
|
|
caea6e6bba | ||
|
|
6970e2d00c | ||
|
|
af084542c4 | ||
|
|
9f728580b6 | ||
|
|
c25d0b668a | ||
|
|
1e29fd7d2b | ||
|
|
67f822d492 | ||
|
|
effbbd6c62 | ||
|
|
db802d1a4c | ||
|
|
fba40370af | ||
|
|
fc0ca18632 | ||
|
|
059b0ba34f | ||
|
|
e833b08a8e | ||
|
|
afc431c413 | ||
|
|
81e407a924 | ||
|
|
1f232efdf3 | ||
|
|
94e1830895 | ||
|
|
406f804ef8 | ||
|
|
437f20dfb9 | ||
|
|
ff4438bce9 | ||
|
|
5cb343730b | ||
|
|
dacaaa2cef | ||
|
|
2e6e20cf09 | ||
|
|
2da379bade | ||
|
|
cf8f755f6c | ||
|
|
8114003c84 | ||
|
|
bb47ba468c | ||
|
|
b97c47ab32 | ||
|
|
9042ea320c | ||
|
|
98e725ef7b | ||
|
|
05b2d3529e | ||
|
|
00dbc74269 | ||
|
|
8addeedf5e | ||
|
|
bc834b021c | ||
|
|
6bac4bd57a | ||
|
|
51324aa8e9 | ||
|
|
7d1d92980a | ||
|
|
3d42197f50 | ||
|
|
8a774c02dc | ||
|
|
a644e8a09c | ||
|
|
6f51427c7c | ||
|
|
62bcf58d83 | ||
|
|
f40f206161 | ||
|
|
1235f42143 | ||
|
|
1016bfa1ad | ||
|
|
f9ce111784 | ||
|
|
4c057faf73 | ||
|
|
4f16179c09 | ||
|
|
6991c9f9f7 | ||
|
|
6e6dac0b74 | ||
|
|
23f9c1a1e6 | ||
|
|
e4b2c863d8 | ||
|
|
ae16994289 | ||
|
|
b8b17bb0c9 | ||
|
|
3098fc98d3 | ||
|
|
f3ecfd04da | ||
|
|
0796fab24b | ||
|
|
0fda31b430 | ||
|
|
84a2b4be76 | ||
|
|
5269fbb1fa | ||
|
|
f23dfa091e | ||
|
|
32c3964474 | ||
|
|
6ff92f0a7e | ||
|
|
c795b2390e | ||
|
|
ce7005103c | ||
|
|
1a18878f26 | ||
|
|
1e036a7689 | ||
|
|
858b27b809 | ||
|
|
b4841a878b | ||
|
|
4565b6a9a8 | ||
|
|
9ffb407d11 | ||
|
|
0f3ffa267a | ||
|
|
74c8aa95f5 | ||
|
|
4853235d86 | ||
|
|
0d01ea939d | ||
|
|
5ba6c006c2 | ||
|
|
22e7d1e2e4 | ||
|
|
c650af7b55 | ||
|
|
2ce5e498ab | ||
|
|
d3212c55a0 | ||
|
|
becf9f5d8c | ||
|
|
9cd8133068 | ||
|
|
48fa5c0ce6 | ||
|
|
6fc7199719 | ||
|
|
9e04f94625 | ||
|
|
c9b844b9ea | ||
|
|
497058d7f4 | ||
|
|
a509dd4692 | ||
|
|
8fdfffab36 | ||
|
|
aa118bceb3 | ||
|
|
4da50a78d5 | ||
|
|
4d27a6daa3 | ||
|
|
b6f8997a01 | ||
|
|
568efd4742 | ||
|
|
bf68808eae | ||
|
|
5cbd2dd988 | ||
|
|
92b4ae2702 | ||
|
|
a8cdf0b5ad | ||
|
|
e8dfa0206b | ||
|
|
afe1ba47cf | ||
|
|
2afa9adceb | ||
|
|
ef32200c8d | ||
|
|
dae7795478 | ||
|
|
7c96b68623 | ||
|
|
558e69dba8 | ||
|
|
da7cd03f09 | ||
|
|
6934e5cff8 | ||
|
|
c7cdde7bc2 | ||
|
|
940ac789b9 | ||
|
|
3d46bae1d0 | ||
|
|
16bedf7e86 | ||
|
|
2ee531511b | ||
|
|
0ad5222946 | ||
|
|
2b4aef4ea6 | ||
|
|
679cf4b7ec | ||
|
|
a993b8d352 | ||
|
|
b7403347bb | ||
|
|
bf978256e9 | ||
|
|
9bd25e9734 | ||
|
|
e7499cca04 | ||
|
|
e2d6156b5a | ||
|
|
31cb6216c9 | ||
|
|
e75f5bbbfc | ||
|
|
69cc87212a | ||
|
|
3c1500002b | ||
|
|
b2287f3d83 | ||
|
|
005a278210 | ||
|
|
976e2ae022 | ||
|
|
8fe87e1067 | ||
|
|
d142ded9ad | ||
|
|
090f362bb6 | ||
|
|
ff3c25cc07 | ||
|
|
ed22a51a72 | ||
|
|
9e0c11a970 | ||
|
|
edb52a8448 | ||
|
|
afb08e0ea9 | ||
|
|
8758ba6cb1 | ||
|
|
e6a9968d23 | ||
|
|
fcd2d2e668 | ||
|
|
991c8869d1 | ||
|
|
aef9dc1704 | ||
|
|
848cf7ac01 | ||
|
|
de1d3b6ef4 | ||
|
|
29f8ff8d71 | ||
|
|
b641a1040c | ||
|
|
83acdeb16e | ||
|
|
aa2d73a1c8 | ||
|
|
b7a643aa59 | ||
|
|
3d454c90cb | ||
|
|
590b3f5cbb | ||
|
|
f87e6d5938 | ||
|
|
901e81cdf5 | ||
|
|
d2ed2f5e95 | ||
|
|
c580ccdee1 | ||
|
|
8ecbe1dd79 | ||
|
|
64696c7645 | ||
|
|
ff0dcbd786 | ||
|
|
a3e5d62c96 | ||
|
|
267e2f4b15 | ||
|
|
d52bf52e6a | ||
|
|
f5391bbfa0 | ||
|
|
a218106c8b | ||
|
|
8f54f4b806 | ||
|
|
78b2637c66 | ||
|
|
4b25e24a13 | ||
|
|
aa0c704655 | ||
|
|
4da099d15c | ||
|
|
0bb11d76bd | ||
|
|
c146452570 | ||
|
|
ed05983a57 | ||
|
|
909dc96c2f | ||
|
|
863a6293e7 | ||
|
|
7a49f6fc8b | ||
|
|
c1433a6d9e | ||
|
|
374b8b9ae7 | ||
|
|
e2f5c80afc | ||
|
|
29911380d1 | ||
|
|
405a4bfe28 | ||
|
|
87e41f0c21 | ||
|
|
dce2bcca7c | ||
|
|
00421a7666 | ||
|
|
fd426926e9 | ||
|
|
d83634f8a2 | ||
|
|
6efac1c0f7 | ||
|
|
3a68ca7f4b | ||
|
|
8898919fd3 | ||
|
|
40834380cf | ||
|
|
18abf3854d | ||
|
|
6d0b4f8cb7 | ||
|
|
fc1f795e83 | ||
|
|
ef09f136d4 | ||
|
|
6136bbd019 | ||
|
|
5136aa4886 | ||
|
|
1a3122bef3 | ||
|
|
23d7db814c | ||
|
|
3174ca5da9 | ||
|
|
6a107419e3 | ||
|
|
6d69a8033f | ||
|
|
bb9ccdd3b9 | ||
|
|
5b3ce85695 | ||
|
|
84c5bfa777 | ||
|
|
d9166478e5 | ||
|
|
373fe45b50 | ||
|
|
cd83091101 | ||
|
|
631abd2b0f | ||
|
|
02df233205 | ||
|
|
11e9d0f9ba | ||
|
|
35fea91268 | ||
|
|
6f3d79ae1b | ||
|
|
32da07ea80 | ||
|
|
e9a76f933b | ||
|
|
6b6adf1147 | ||
|
|
6413e770e1 | ||
|
|
7d1067108b | ||
|
|
e00ebda641 | ||
|
|
2b6fc0602a | ||
|
|
53c09b5342 | ||
|
|
d78d8abb9f | ||
|
|
f6b459b408 | ||
|
|
581585a47c | ||
|
|
ddbdcc91dd | ||
|
|
8f8b75e0aa | ||
|
|
2e673a6bc9 | ||
|
|
8c2b92d151 | ||
|
|
032fb9b5ba | ||
|
|
b1c5d6c62a | ||
|
|
037af5d728 | ||
|
|
61a2b6a837 | ||
|
|
13698a9590 | ||
|
|
4f2907ef77 | ||
|
|
8667d11c52 | ||
|
|
24309095ff | ||
|
|
d5a90ded17 | ||
|
|
9d744367ac | ||
|
|
46a46a9536 | ||
|
|
224c1df553 | ||
|
|
bcea5af30f | ||
|
|
211ce09c0b | ||
|
|
1e41a2595d | ||
|
|
36a080b3a9 | ||
|
|
a3050f6c64 | ||
|
|
be5deddc1d | ||
|
|
36f9bdb88c | ||
|
|
1a33e9a15b | ||
|
|
4157a49c7e | ||
|
|
f27be7314e | ||
|
|
a425038fa6 | ||
|
|
0b07858bfc | ||
|
|
7dbf1d7bf5 | ||
|
|
34c44ab2cf | ||
|
|
5ec106642d | ||
|
|
dcd9ce91a8 | ||
|
|
a05fbfe69b | ||
|
|
feb76f4fb4 | ||
|
|
d467b68187 | ||
|
|
de18fa2860 | ||
|
|
58f6c719a9 | ||
|
|
b2fa21a111 | ||
|
|
f94099e350 | ||
|
|
e2f11879d5 | ||
|
|
aa15b3ea7f | ||
|
|
1624d10a01 | ||
|
|
0d53adf9bd | ||
|
|
295c267c31 | ||
|
|
d4b3f7378e | ||
|
|
a503e18966 | ||
|
|
b1f7d641fc | ||
|
|
5019d1e4f9 | ||
|
|
2aa0205872 | ||
|
|
a7befa8882 | ||
|
|
a5058c7bab | ||
|
|
f5558d106e | ||
|
|
d19328230c | ||
|
|
b77464386c | ||
|
|
9119319429 | ||
|
|
d3d85fded0 | ||
|
|
9b9642df8f | ||
|
|
e564a97b05 | ||
|
|
a150cb5c6e | ||
|
|
afd7943b62 | ||
|
|
09eb130b6d | ||
|
|
5869ba06bc | ||
|
|
b6c2638c1b | ||
|
|
16b0f0d625 | ||
|
|
9293930628 | ||
|
|
46935b165c | ||
|
|
c0dd08f6e0 | ||
|
|
1fde1647e8 | ||
|
|
7ef006ccca | ||
|
|
fd69d6b42c | ||
|
|
627f66fb5b | ||
|
|
8451c11916 | ||
|
|
6bbbbcfb05 | ||
|
|
63465278a5 | ||
|
|
2980771deb | ||
|
|
1169b84c2f | ||
|
|
355491a950 | ||
|
|
7caa0adbab | ||
|
|
8acc51c489 | ||
|
|
732fd98593 | ||
|
|
21a610d22c | ||
|
|
a379e6efbf | ||
|
|
b1e1b6cc68 | ||
|
|
da86e0ce34 | ||
|
|
6ca12eb0de | ||
|
|
a25442368b | ||
|
|
e7e95d47a5 | ||
|
|
292fe8eab4 | ||
|
|
272a401189 | ||
|
|
592e3f47e9 | ||
|
|
cabf1a9043 | ||
|
|
e623541861 | ||
|
|
b74b6f8c1d | ||
|
|
11abdd451f | ||
|
|
1c3596b1f9 | ||
|
|
1e73333fbe | ||
|
|
6eb49f567a | ||
|
|
0120e7e4a5 | ||
|
|
10e4d3db11 | ||
|
|
0b34d2dbb8 | ||
|
|
be1ef1de0e | ||
|
|
ef45c988c6 | ||
|
|
3ecdee1b89 | ||
|
|
c7561b1f6d | ||
|
|
50a3df8dff | ||
|
|
dfde4a58de | ||
|
|
090ba308d8 | ||
|
|
e01e989c22 | ||
|
|
a9b4af98fc | ||
|
|
30f5442728 | ||
|
|
123ca2812a | ||
|
|
95435ea512 | ||
|
|
db625baadd | ||
|
|
200a80aa02 | ||
|
|
0472a93c3f | ||
|
|
9b70e646dc | ||
|
|
388ab210a7 | ||
|
|
15e8a71249 | ||
|
|
dfd04f0d41 | ||
|
|
88ac49c0c9 | ||
|
|
7d6ff3e6a4 | ||
|
|
c68fbfacb9 | ||
|
|
8e51c7ca3b | ||
|
|
33064f8392 | ||
|
|
40141465b5 | ||
|
|
13d855c2e7 | ||
|
|
2f8b6a2009 | ||
|
|
23e56e767f | ||
|
|
ce5b954c4d | ||
|
|
a0c20663a0 | ||
|
|
56f850b59d | ||
|
|
253d4e2c4d | ||
|
|
6fef42d6e0 | ||
|
|
d6a00a5984 | ||
|
|
26a1e24e3a | ||
|
|
6103efa8cc | ||
|
|
9a7ba0786c | ||
|
|
935efaeb3a | ||
|
|
020a6d8b66 | ||
|
|
9dea8fc41e | ||
|
|
3a7e249edf | ||
|
|
c406aaf74f | ||
|
|
83938471ca | ||
|
|
db6ff8901b | ||
|
|
737ee3af64 | ||
|
|
9ea40f31e4 | ||
|
|
27bd6f4b1c | ||
|
|
b9e9137f90 | ||
|
|
bee0bbbe90 | ||
|
|
277ca0c951 | ||
|
|
8aa059dd21 | ||
|
|
c39bdd246a | ||
|
|
9823af9159 | ||
|
|
9ee0e0a3c9 | ||
|
|
bf184fb719 | ||
|
|
94f308c50f | ||
|
|
bfa0ef64ec | ||
|
|
98fc0a8cb9 | ||
|
|
facabc09f5 | ||
|
|
51afcd7b96 | ||
|
|
340f1bb287 | ||
|
|
40c8479448 | ||
|
|
27e2063bf9 | ||
|
|
e43f0a9285 | ||
|
|
a977cbdd26 | ||
|
|
dbc536c6c2 | ||
|
|
97c9075503 | ||
|
|
290e45062d | ||
|
|
fc6bffe683 | ||
|
|
1fb8327ca9 | ||
|
|
36208de902 | ||
|
|
5403577642 | ||
|
|
c76dda1523 | ||
|
|
b5034e5b12 | ||
|
|
b039333922 | ||
|
|
b504e0d109 | ||
|
|
0692b9dcdb | ||
|
|
085b72154f | ||
|
|
4f99c0fa98 | ||
|
|
b38b71eb44 | ||
|
|
639da1a4b8 | ||
|
|
f2d27aae3f | ||
|
|
931876ac77 | ||
|
|
e5f62a9188 | ||
|
|
3fb699979c | ||
|
|
85f15a1f28 | ||
|
|
758017b638 | ||
|
|
724d1db9b8 | ||
|
|
00421fbee6 | ||
|
|
2510bab41f | ||
|
|
c6675f2013 | ||
|
|
1fd6c2bd52 | ||
|
|
8f355fe188 | ||
|
|
dbd10a281b | ||
|
|
d57ea3695b | ||
|
|
8dd74b7789 | ||
|
|
36c00f146d | ||
|
|
aba9f25744 | ||
|
|
dacfa6ae55 | ||
|
|
f53fba082a | ||
|
|
764b95f617 | ||
|
|
3237b3564e | ||
|
|
985731f543 | ||
|
|
7c28efe9cd | ||
|
|
5b567f4cba | ||
|
|
78918eb59d | ||
|
|
1848506f09 | ||
|
|
ce0004a296 | ||
|
|
e85d3f2a19 | ||
|
|
4e5a0a30bf | ||
|
|
9ab37e54b4 | ||
|
|
0bd15172b1 | ||
|
|
fe0e5c1d9c | ||
|
|
5128d88722 | ||
|
|
173ca3e58e | ||
|
|
2a13fca737 | ||
|
|
b3a9f4423b | ||
|
|
62c24826e6 | ||
|
|
a3d2c2c044 | ||
|
|
72409622ef | ||
|
|
c8a2de8235 | ||
|
|
6b91846b0c | ||
|
|
92190220aa | ||
|
|
705d30d125 | ||
|
|
c316dc7b00 | ||
|
|
529dc29d08 | ||
|
|
91e760bf5f | ||
|
|
61e24499bf | ||
|
|
75621651e5 | ||
|
|
3973b95746 | ||
|
|
f9d264058b | ||
|
|
a69d9d4483 | ||
|
|
8b19d00086 | ||
|
|
1156d4f881 | ||
|
|
08c5186426 | ||
|
|
61b4a817f3 | ||
|
|
13710904ba | ||
|
|
015ebb650e | ||
|
|
17d623bf85 | ||
|
|
0049348de5 | ||
|
|
20d11f5f97 | ||
|
|
047a7bb949 | ||
|
|
52c79f7f77 | ||
|
|
c97bc2e977 | ||
|
|
78d564cc04 | ||
|
|
e27c0716c4 | ||
|
|
35d037daff | ||
|
|
f055162ac0 | ||
|
|
f2e32c737b | ||
|
|
205709271b | ||
|
|
3e70a9fab8 | ||
|
|
733c6c96f0 | ||
|
|
a010e648ee | ||
|
|
1c7b561aa9 | ||
|
|
75a71d35ec | ||
|
|
7c0f0672bd | ||
|
|
8fc6b6e3c3 | ||
|
|
6c2c8ca2b7 | ||
|
|
1b6bdd07e7 | ||
|
|
539688dd3d | ||
|
|
08e09c3b4c | ||
|
|
4259053c7e | ||
|
|
c221cfd493 | ||
|
|
41298b53d4 | ||
|
|
ddcd05adc6 | ||
|
|
a28cd64c7a | ||
|
|
38e62fef18 | ||
|
|
3f139f463b | ||
|
|
0597191319 | ||
|
|
f4c8b0c21f | ||
|
|
bba7031f3d | ||
|
|
4785913e02 | ||
|
|
a6808d1f6a | ||
|
|
7188e9832a | ||
|
|
0cce0c81fb | ||
|
|
a60baa03e0 | ||
|
|
b0c8dafb33 | ||
|
|
b672fc8b29 | ||
|
|
eac69f659f | ||
|
|
d9ab65154c | ||
|
|
c120aed8bb | ||
|
|
ecdbe3d959 | ||
|
|
96d10fb8b0 | ||
|
|
2ab826268d | ||
|
|
c3e3f368e0 | ||
|
|
f35582489d | ||
|
|
9acea3484d | ||
|
|
a72da9b73e | ||
|
|
df53d35967 | ||
|
|
e5e7421d3c | ||
|
|
6ff25d00fc | ||
|
|
4a5b0b3105 | ||
|
|
d05d964432 | ||
|
|
daa4a67b49 | ||
|
|
9c0224911c | ||
|
|
ef5759cff5 | ||
|
|
77292fb9ab | ||
|
|
6fb9ab078e | ||
|
|
844a72e0f3 | ||
|
|
46e9046629 | ||
|
|
e5af60787e | ||
|
|
4b0696a187 | ||
|
|
a6377fedab | ||
|
|
2f884e6d55 | ||
|
|
28f8c65771 | ||
|
|
b509ef5ab4 | ||
|
|
9f48dabaec | ||
|
|
5b0224ae3c | ||
|
|
c3ef267d6d | ||
|
|
fe9b298705 | ||
|
|
0b106cf47e | ||
|
|
9b417c9b26 | ||
|
|
37d5458c4c | ||
|
|
77d48cb104 | ||
|
|
a25200741a | ||
|
|
d04a32920a | ||
|
|
792b676c11 | ||
|
|
690a7a7557 | ||
|
|
e128c93ad9 | ||
|
|
39add5ccec | ||
|
|
a1a89cba34 | ||
|
|
2d696cf500 | ||
|
|
45fe0bc8b7 | ||
|
|
9fc4c67187 | ||
|
|
34aeab5f77 | ||
|
|
b510452260 | ||
|
|
89b8d5a67b | ||
|
|
500e3a3b2c | ||
|
|
47e575ed9a | ||
|
|
10b30d74e7 | ||
|
|
1ba4c6b7ad | ||
|
|
eb899be95e | ||
|
|
6d993af419 | ||
|
|
a136cccbe1 | ||
|
|
2b43ebfca4 | ||
|
|
06f4980ee1 | ||
|
|
6cdf5b7b7e | ||
|
|
117b9a5579 | ||
|
|
9475be8f6f | ||
|
|
41ca1797f9 | ||
|
|
e56ae3d266 | ||
|
|
735ffaf80b | ||
|
|
ed52d1c648 | ||
|
|
78fa90c59b | ||
|
|
548a3efe5a | ||
|
|
18a12eeba3 | ||
|
|
83d486ceeb | ||
|
|
d898c0f995 | ||
|
|
02faf6f8c1 | ||
|
|
3478bbddf2 | ||
|
|
fd1ee31e1e | ||
|
|
4a565f0985 | ||
|
|
c68f23cdaf | ||
|
|
e386eb00ef | ||
|
|
662d048bf4 | ||
|
|
d9e3cc2188 | ||
|
|
a586f13af8 | ||
|
|
37820c1673 | ||
|
|
8a2e4ca470 | ||
|
|
3a5da64c6f | ||
|
|
9c018a2330 | ||
|
|
0840cdd83a | ||
|
|
e972747969 | ||
|
|
e151c6eb15 | ||
|
|
603444a69f | ||
|
|
999e0fd721 | ||
|
|
47131dec44 | ||
|
|
6adad053d9 | ||
|
|
725561b655 | ||
|
|
b84fbf452e | ||
|
|
eb7af2bce9 | ||
|
|
7c57c4b131 | ||
|
|
4460466cb3 | ||
|
|
eea19d733d | ||
|
|
abc97dcab3 | ||
|
|
065c791a10 | ||
|
|
6b902e7f5d | ||
|
|
df0cb87b35 | ||
|
|
0b9687fea4 | ||
|
|
99fbe092bc | ||
|
|
7a7849ae83 | ||
|
|
47830bb330 | ||
|
|
0dfb1a3a2a | ||
|
|
e2e1ab0275 | ||
|
|
4249cacf2f | ||
|
|
4e3ec52673 | ||
|
|
98991a4a7a | ||
|
|
bca6d656b6 | ||
|
|
ffc3580d43 | ||
|
|
c18cdc78ea | ||
|
|
77ecc73631 | ||
|
|
3834f51d74 | ||
|
|
86ddec3f76 | ||
|
|
4d12bcb184 | ||
|
|
7d93723382 | ||
|
|
8e1a52bbb7 | ||
|
|
cd9b1a741f | ||
|
|
cefe331e0c | ||
|
|
14d1fae54a | ||
|
|
a1601be7a6 | ||
|
|
a2ebeb11e3 | ||
|
|
b7f0f32878 | ||
|
|
58e39add5b | ||
|
|
61725c95df | ||
|
|
71a1df661a | ||
|
|
9eed0eab5f | ||
|
|
e42b6fe0a9 | ||
|
|
b1e640ad1d | ||
|
|
2fc091fdf7 | ||
|
|
47ba241e7d | ||
|
|
c0d37c504a | ||
|
|
1e0195f6e3 | ||
|
|
e806c1ddf1 | ||
|
|
78f0072c59 | ||
|
|
1022ce531a | ||
|
|
7f08a7bca8 | ||
|
|
4123bef60d | ||
|
|
c6464efa07 |
No files matched your search
@@ -0,0 +1,17 @@
|
||||
name: Build branch
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-all:
|
||||
uses: ./.github/workflows/shared-build.yml
|
||||
with:
|
||||
environment: "testing"
|
||||
@@ -1,256 +0,0 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: RelWithDebInfo
|
||||
|
||||
jobs:
|
||||
build-platform-linux:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'amd64', triple: 'x86_64-linux-gnu'},
|
||||
{name: 'i686', triple: 'i686-linux-gnu'},
|
||||
{name: 'arm64', triple: 'aarch64-linux-gnu'},
|
||||
{name: 'armhf', triple: 'arm-linux-gnueabihf'},
|
||||
{name: 'powerpc', triple: 'powerpc-linux-gnu'},
|
||||
{name: 'ppc64', triple: 'powerpc64-linux-gnu'},
|
||||
{name: 'ppc64el', triple: 'powerpc64le-linux-gnu'}
|
||||
]
|
||||
|
||||
name: "Building for platform linux-${{matrix.architecture.name}}"
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$(($(nproc) * 16))" >> $GITHUB_ENV
|
||||
# echo "CMAKE_GENERATOR=Ninja" >> $GITHUB_ENV
|
||||
|
||||
- name: Install required packages
|
||||
run: |
|
||||
sudo apt update && sudo apt install -y flex bison \
|
||||
libpulse-dev portaudio19-dev libasound2-dev libjack-dev libpipewire-0.3-dev qtbase5-dev libdbus-1-dev
|
||||
|
||||
- name: Install required cross-platform packages (${{ matrix.architecture.triple }})
|
||||
if: matrix.architecture.name != 'amd64'
|
||||
run: sudo apt install -y gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: sdl2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: "-DCMAKE_C_COMPILER=clang
|
||||
-DCMAKE_CXX_COMPILER=clang++
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }}
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }}"
|
||||
|
||||
# soft-oal setup
|
||||
# Use GCC instead of Clang because of missing SSE intrinsics
|
||||
# It also doesn't enable altivec support on PowerPC by default
|
||||
- name: Checkout soft-oal
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: '1.23.1'
|
||||
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' \
|
||||
-DCMAKE_C_COMPILER=${{ matrix.architecture.triple }}-gcc-12 \
|
||||
-DCMAKE_CXX_COMPILER=${{ matrix.architecture.triple }}-g++-12
|
||||
cmake --build ./build --config ${{env.BUILD_TYPE}}
|
||||
cmake --install ./build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM=--log-level=VERBOSE \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' \
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
# Create hard-link and copy symbolic links
|
||||
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.so.0 '${{github.workspace}}/install/'
|
||||
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.so.1 '${{github.workspace}}/install/'
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-linux-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path:
|
||||
${{github.workspace}}/install
|
||||
|
||||
build-platform-windows:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'x64', config: 'x64' },
|
||||
{name: 'x86', config: 'Win32' },
|
||||
{name: 'arm64', config: 'ARM64' }
|
||||
]
|
||||
|
||||
name: "Building for platform windows-${{matrix.architecture.name}}"
|
||||
runs-on: windows-2022
|
||||
|
||||
steps:
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: sdl2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: "-A ${{ matrix.architecture.config }}"
|
||||
|
||||
- name: Install Flex/Bison
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
mkdir thirdparties && cd thirdparties
|
||||
git clone --depth 1 --single-branch --branch v2.5.25 https://github.com/lexxmark/winflexbison.git
|
||||
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
|
||||
cmake --build winflexbison-build --config Release --parallel
|
||||
cmake --install winflexbison-build
|
||||
|
||||
# soft-oal setup
|
||||
- name: Checkout soft-oal
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: '1.23.1'
|
||||
|
||||
# soft-oal build
|
||||
# Statically link the CRT runtime into OAL as a workaround to prevent crashes
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build -A ${{ matrix.architecture.config }} `
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' `
|
||||
-DALSOFT_BUILD_ROUTER=OFF `
|
||||
-DALSOFT_REQUIRE_WINMM=ON `
|
||||
-DALSOFT_REQUIRE_DSOUND=ON `
|
||||
-DALSOFT_REQUIRE_WASAPI=ON `
|
||||
-DCMAKE_C_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
|
||||
-DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
|
||||
-DCMAKE_C_FLAGS_MINSIZEREL="/MT /O2 /Ob2 /DNDEBUG" `
|
||||
-DCMAKE_CXX_FLAGS_MINSIZEREL="/MT /O1 /Ob1 /DNDEBUG" `
|
||||
-DCMAKE_C_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG" `
|
||||
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG"
|
||||
cmake --build ./build --config ${{env.BUILD_TYPE}}
|
||||
cmake --install ./build --config ${{env.BUILD_TYPE}}
|
||||
# Unfortunately soft-oal produces a binary called OpenAL32 even in 64-bit
|
||||
if (("x64", "ARM64") -icontains "${{ matrix.architecture.config }}") { Rename-Item -Path '.\install\bin\OpenAL32.dll' -NewName 'OpenAL64.dll' }
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM=-A ${{ matrix.architecture.config }} `
|
||||
--log-level=VERBOSE `
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
|
||||
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' `
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' `
|
||||
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
|
||||
Copy-Item '${{github.workspace}}/thirdparties/soft-oal/install/bin/*.dll' -Destination '${{github.workspace}}/install'
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{github.workspace}}/install
|
||||
!${{github.workspace}}/install/**/*.pdb
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}-pdb
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{github.workspace}}/install
|
||||
@@ -20,6 +20,10 @@ on:
|
||||
schedule:
|
||||
- cron: '42 8 * * 1'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
@@ -0,0 +1,477 @@
|
||||
name: Shared build workflow
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
environment:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: RelWithDebInfo
|
||||
RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
|
||||
|
||||
jobs:
|
||||
##########################
|
||||
#
|
||||
# Linux
|
||||
# Ubuntu 22.04
|
||||
#
|
||||
# Using this version instead of 24.04 to use a lower GLIBC version (2.34)
|
||||
##########################
|
||||
build-platform-linux:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'amd64', triple: 'x86_64-linux-gnu'},
|
||||
{name: 'i686', triple: 'i686-linux-gnu'},
|
||||
{name: 'arm64', triple: 'aarch64-linux-gnu'},
|
||||
{name: 'armhf', triple: 'arm-linux-gnueabihf'},
|
||||
{name: 'powerpc', triple: 'powerpc-linux-gnu'},
|
||||
{name: 'ppc64', triple: 'powerpc64-linux-gnu'},
|
||||
{name: 'ppc64el', triple: 'powerpc64le-linux-gnu'}
|
||||
]
|
||||
|
||||
name: "Building for platform linux-${{matrix.architecture.name}}"
|
||||
runs-on: "ubuntu-22.04"
|
||||
environment: ${{ inputs.environment }}
|
||||
|
||||
steps:
|
||||
###
|
||||
# Packages
|
||||
###
|
||||
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
name: Install required packages
|
||||
with:
|
||||
packages: flex bison ninja-build cmake clang libpulse-dev portaudio19-dev libasound2-dev libjack-dev libpipewire-0.3-dev qtbase5-dev libdbus-1-dev
|
||||
version: "0.1"
|
||||
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
name: Install required cross-platform packages (${{ matrix.architecture.triple }})
|
||||
if: matrix.architecture.name != 'amd64'
|
||||
with:
|
||||
packages: gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
|
||||
version: "0.1"
|
||||
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $GITHUB_ENV
|
||||
echo "CC=clang" >> $GITHUB_ENV
|
||||
echo "CXX=clang++" >> $GITHUB_ENV
|
||||
echo "CFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
|
||||
echo "CXXFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
|
||||
# Temporary workaround for PowerPC as the 1.24.0 version doesn't check for altivec
|
||||
# Will use older versions until a new tag is created with this issue resolved
|
||||
if [ ${{ matrix.architecture.name }} != 'powerpc' ] && [ ${{ matrix.architecture.name }} != 'ppc64' ] && [ ${{ matrix.architecture.name }} != 'ppc64el' ]; then
|
||||
echo "OPENAL_REF=1.24.0" >> $GITHUB_ENV
|
||||
else
|
||||
echo "OPENAL_REF=1.23.1" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
###
|
||||
# SDL
|
||||
###
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: 2-latest
|
||||
build-type: Release
|
||||
# Workaround for when changing the runner OS version
|
||||
cmake-arguments: "-DCACHE_OS_VERSION=Ubuntu_22.04"
|
||||
|
||||
###
|
||||
# OpenAL
|
||||
###
|
||||
|
||||
# soft-oal setup
|
||||
- name: Checkout soft-oal
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: ${{ env.OPENAL_REF }}
|
||||
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install'
|
||||
cmake --build ./build --config Release --parallel
|
||||
cmake --install ./build --config Release
|
||||
|
||||
###
|
||||
# Project
|
||||
###
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM=--log-level=VERBOSE \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' \
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
|
||||
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
# Copy libraries
|
||||
mkdir ${{github.workspace}}/package
|
||||
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.so.0 '${{github.workspace}}/package/'
|
||||
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.so.1 '${{github.workspace}}/package/'
|
||||
if [ -d ${{github.workspace}}/install/bin ]; then cp -r ${{github.workspace}}/install/bin/openmohaa/. '${{github.workspace}}/package'; fi
|
||||
if [ -d ${{github.workspace}}/install/lib ]; then cp -r ${{github.workspace}}/install/lib/openmohaa/. '${{github.workspace}}/package'; fi
|
||||
|
||||
###
|
||||
# Artifacts
|
||||
###
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-linux-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path:
|
||||
${{github.workspace}}/package
|
||||
|
||||
##########################
|
||||
#
|
||||
# Microsoft Windows
|
||||
# Windows Server 2022
|
||||
#
|
||||
##########################
|
||||
build-platform-windows:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'x64', config: 'x64', toolset: 'x64' },
|
||||
{name: 'x86', config: 'Win32', toolset: 'x64_x86' },
|
||||
{name: 'arm64', config: 'ARM64', toolset: 'x64_arm64' }
|
||||
]
|
||||
|
||||
name: "Building for platform windows-${{matrix.architecture.name}}"
|
||||
runs-on: "windows-2022"
|
||||
environment: ${{ inputs.environment }}
|
||||
|
||||
steps:
|
||||
###
|
||||
# Packages
|
||||
###
|
||||
|
||||
#
|
||||
# Commented out for now, chocolatey servers started complaining about too many requests
|
||||
#
|
||||
#- name: Install required packages
|
||||
# run: |
|
||||
# choco install -y ninja
|
||||
|
||||
- name: Install required packages
|
||||
run: |
|
||||
$DownloadPath="$($env:USERPROFILE)\Downloads"
|
||||
Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-win.zip" -OutFile "$DownloadPath\ninja-win.zip"
|
||||
Expand-Archive -Path "$DownloadPath\ninja-win.zip" -DestinationPath "$($env:PROGRAMFILES)\ninja"
|
||||
echo "$($env:PROGRAMFILES)\ninja" >> $GITHUB_PATH
|
||||
|
||||
- name: Install Flex/Bison
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
mkdir thirdparties && cd thirdparties
|
||||
git clone --depth 1 --single-branch --branch v2.5.25 https://github.com/lexxmark/winflexbison.git
|
||||
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
|
||||
cmake --build winflexbison-build --config Release --parallel
|
||||
cmake --install winflexbison-build --config Release
|
||||
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $env:GITHUB_ENV
|
||||
echo "CC=cl.exe" >> $env:GITHUB_ENV
|
||||
echo "CXX=cl.exe" >> $env:GITHUB_ENV
|
||||
pushd "$($env:PROGRAMFILES)\Microsoft Visual Studio\*\*\VC\Auxiliary\Build"
|
||||
cmd /c "vcvarsall.bat ${{ matrix.architecture.toolset }} & set" | ForEach-Object {
|
||||
if ($_ -match "=") {
|
||||
# Split into key=value
|
||||
$var = $_.split("=", 2);
|
||||
echo "$($var[0])=$($var[1])" >> $env:GITHUB_ENV
|
||||
}
|
||||
}
|
||||
popd
|
||||
|
||||
###
|
||||
# SDL
|
||||
###
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: 2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: ""
|
||||
|
||||
###
|
||||
# OpenAL
|
||||
###
|
||||
|
||||
# soft-oal setup
|
||||
- name: Checkout soft-oal
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: '1.24.0'
|
||||
|
||||
# soft-oal build
|
||||
# Statically link the CRT runtime into OAL as a workaround to prevent crashes
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build `
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' `
|
||||
-DALSOFT_BUILD_ROUTER=OFF `
|
||||
-DALSOFT_REQUIRE_WINMM=ON `
|
||||
-DALSOFT_REQUIRE_DSOUND=ON `
|
||||
-DALSOFT_REQUIRE_WASAPI=ON `
|
||||
-DCMAKE_C_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
|
||||
-DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
|
||||
-DCMAKE_C_FLAGS_MINSIZEREL="/MT /O2 /Ob2 /DNDEBUG" `
|
||||
-DCMAKE_CXX_FLAGS_MINSIZEREL="/MT /O1 /Ob1 /DNDEBUG" `
|
||||
-DCMAKE_C_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG" `
|
||||
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG"
|
||||
cmake --build ./build --config Release --parallel
|
||||
cmake --install ./build --config Release
|
||||
# Unfortunately soft-oal produces a binary called OpenAL32 even in 64-bit
|
||||
if (("x64", "ARM64") -icontains "${{ matrix.architecture.config }}") { Rename-Item -Path '.\install\bin\OpenAL32.dll' -NewName 'OpenAL64.dll' }
|
||||
|
||||
###
|
||||
# Project
|
||||
###
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM= `
|
||||
--log-level=VERBOSE `
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
|
||||
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' `
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' `
|
||||
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe' `
|
||||
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
New-Item -ItemType Directory '${{github.workspace}}/package'
|
||||
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/package'
|
||||
Copy-Item '${{github.workspace}}/thirdparties/soft-oal/install/bin/*.dll' -Destination '${{github.workspace}}/package'
|
||||
if (Test-Path ${{github.workspace}}/install/bin) { Copy-Item '${{github.workspace}}/install/bin/*' -Include '*.dll','*.exe','*.pdb' -Destination '${{github.workspace}}/package' }
|
||||
if (Test-Path ${{github.workspace}}/install/lib) { Copy-Item '${{github.workspace}}/install/lib/*' -Include '*.dll','*.exe','*.pdb' -Destination '${{github.workspace}}/package' }
|
||||
|
||||
###
|
||||
# Artifact
|
||||
###
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{github.workspace}}/package
|
||||
!${{github.workspace}}/package/**/*.pdb
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-windows-${{matrix.architecture.name}}-pdb
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{github.workspace}}/package
|
||||
|
||||
##########################
|
||||
#
|
||||
# Apple macOS
|
||||
# macOS 14
|
||||
#
|
||||
# This version is used as the OS, as older versions are slower.
|
||||
##########################
|
||||
build-platform-macos:
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [
|
||||
{name: 'x86_64', triple: 'x86_64-apple-macos10.8'},
|
||||
{name: 'arm64', triple: 'arm64-apple-macos11'}
|
||||
]
|
||||
|
||||
name: "Building for platform macos-${{matrix.architecture.name}}"
|
||||
runs-on: "macos-14"
|
||||
environment: ${{inputs.environment}}
|
||||
|
||||
steps:
|
||||
###
|
||||
# Packages
|
||||
###
|
||||
|
||||
# Install required packages
|
||||
# Paths on x86_64 and ARM64 are different for homebrew
|
||||
- name: Install required packages
|
||||
run: |
|
||||
brew update && brew install git flex bison ninja cmake llvm ninja
|
||||
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $GITHUB_ENV
|
||||
echo "CC=clang" >> $GITHUB_ENV
|
||||
echo "CXX=clang++" >> $GITHUB_ENV
|
||||
echo "MACOSX_DEPLOYMENT_TARGET=10.15" >> $GITHUB_ENV
|
||||
|
||||
###
|
||||
# SDL
|
||||
###
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: 2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: "-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }}
|
||||
-DCMAKE_VERBOSE_MAKEFILE=on"
|
||||
###
|
||||
# OpenAL
|
||||
###
|
||||
|
||||
# soft-oal setup
|
||||
# Use GCC instead of Clang because of missing SSE intrinsics
|
||||
# It also doesn't enable altivec support on PowerPC by default
|
||||
- name: Checkout soft-oal
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'kcat/openal-soft'
|
||||
path: 'thirdparties/soft-oal'
|
||||
ref: '1.24.0'
|
||||
|
||||
- name: Configure and install soft-oal
|
||||
working-directory: ${{github.workspace}}/thirdparties/soft-oal
|
||||
run: |
|
||||
cmake -B ./build \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' \
|
||||
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }} \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=on
|
||||
cmake --build ./build --config Release --parallel
|
||||
cmake --install ./build --config Release
|
||||
|
||||
###
|
||||
# Project
|
||||
###
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'source'
|
||||
|
||||
- name: CMake Settings
|
||||
run: |
|
||||
echo "CMAKE_PARAM=--log-level=VERBOSE \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=on \
|
||||
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }} \
|
||||
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal/install' \
|
||||
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/install/include/AL' \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
|
||||
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: |
|
||||
cd "${{github.workspace}}/build"
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{github.workspace}}
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
# Create hard-link and copy symbolic links
|
||||
mkdir ${{github.workspace}}/package
|
||||
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.0.dylib '${{github.workspace}}/package/'
|
||||
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.1.dylib '${{github.workspace}}/package/'
|
||||
if [ -d ${{github.workspace}}/install/bin ]; then cp -r ${{github.workspace}}/install/bin/openmohaa/. '${{github.workspace}}/package'; fi
|
||||
if [ -d ${{github.workspace}}/install/lib ]; then cp -r ${{github.workspace}}/install/lib/openmohaa/. '${{github.workspace}}/package'; fi
|
||||
|
||||
###
|
||||
# Artifacts
|
||||
###
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: out-macos-${{matrix.architecture.name}}
|
||||
if-no-files-found: error
|
||||
path:
|
||||
${{github.workspace}}/package
|
||||
@@ -6,7 +6,7 @@ on:
|
||||
- "v*.*.*"
|
||||
|
||||
env:
|
||||
RELEASE_TYPE: ${{ vars.RELEASE_TYPE || 'test' }}
|
||||
RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
|
||||
RELEASE_IS_PRERELEASE: ${{ vars.RELEASE_IS_PRELEASE }}
|
||||
|
||||
permissions:
|
||||
@@ -14,7 +14,9 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build-all:
|
||||
uses: ./.github/workflows/build-cmake.yml
|
||||
uses: ./.github/workflows/shared-build.yml
|
||||
with:
|
||||
environment: "release"
|
||||
|
||||
deploy_all:
|
||||
strategy:
|
||||
@@ -31,15 +33,17 @@ jobs:
|
||||
'linux-ppc64',
|
||||
'linux-ppc64el',
|
||||
'windows-x64',
|
||||
'windows-x86',
|
||||
'windows-x64-pdb',
|
||||
'windows-x86',
|
||||
'windows-x86-pdb',
|
||||
'windows-arm64',
|
||||
'windows-arm64-pdb'
|
||||
'windows-arm64-pdb',
|
||||
'macos-x86_64',
|
||||
'macos-arm64'
|
||||
]
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
environment: release
|
||||
runs-on: ubuntu-24.04
|
||||
environment: "release"
|
||||
needs: [build-all]
|
||||
|
||||
env:
|
||||
@@ -58,6 +62,6 @@ jobs:
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: '${{github.ref_name}}-${{env.RELEASE_TYPE}}'
|
||||
name: '${{github.ref_name}}-${{env.RELEASE_STAGE}}'
|
||||
prerelease: ${{env.RELEASE_IS_PRERELEASE}}
|
||||
files: ${{github.workspace}}/${{ env.RELEASE_NAME }}.zip
|
||||
+142
-17
@@ -5,6 +5,14 @@ include(TargetArch.cmake)
|
||||
|
||||
target_architecture(TARGET_ARCH)
|
||||
|
||||
set(USE_INTERNAL_LIBS ON)
|
||||
if(USE_SYSTEM_LIBS)
|
||||
set(USE_INTERNAL_LIBS OFF)
|
||||
endif()
|
||||
|
||||
option(USE_INTERNAL_JPEG "If set, use bundled libjpeg." ${USE_INTERNAL_LIBS})
|
||||
option(USE_INTERNAL_MAD "If set, use bundled libmad." ${USE_INTERNAL_LIBS})
|
||||
option(USE_INTERNAL_ZLIB "If set, use bundled zlib." ${USE_INTERNAL_LIBS})
|
||||
|
||||
if(TARGET_GAME_TYPE)
|
||||
message(SEND_ERROR "TARGET_GAME_TYPE is now unsupported, it is now done at runtime.")
|
||||
@@ -14,23 +22,35 @@ endif()
|
||||
set(TARGET_BASE_GAME "./")
|
||||
set(CMAKE_DEBUG_POSTFIX "-dbg")
|
||||
|
||||
#
|
||||
# Microsoft compiler specific parameters
|
||||
#
|
||||
if(MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
# Treat no return type as error
|
||||
add_compile_options(/we4715)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
#
|
||||
# Clang and GCC specific parameters
|
||||
#
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
add_compile_options(-Wno-comment)
|
||||
# Treat no return type as error
|
||||
add_compile_options(-Werror=return-type)
|
||||
endif()
|
||||
|
||||
#
|
||||
# Clang specific parameters
|
||||
#
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Ignore warnings for code like 'assert("Assert string")'
|
||||
add_compile_options(-Wno-pointer-bool-conversion)
|
||||
endif()
|
||||
|
||||
#
|
||||
# GCC specific parameters
|
||||
#
|
||||
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
|
||||
@@ -48,6 +68,8 @@ ELSE()
|
||||
set(TARGET_ARCH_SUFFIX ${TARGET_ARCH})
|
||||
ENDIF()
|
||||
|
||||
set(TARGET_BIN_SUFFIX ".${TARGET_ARCH}")
|
||||
|
||||
message(STATUS "Architecture detected: ${TARGET_ARCH}, suffix set to ${TARGET_ARCH_SUFFIX}.")
|
||||
|
||||
IF(WIN32)
|
||||
@@ -61,7 +83,7 @@ ELSE()
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
add_definitions(-D_DEBUG)
|
||||
add_compile_definitions(_DEBUG)
|
||||
|
||||
# NOTE: The following may mess up function importation
|
||||
#if(UNIX)
|
||||
@@ -69,18 +91,60 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
# set(CMAKE_ENABLE_EXPORTS ON)
|
||||
# message(STATUS "Enabling exports on Unix for backtrace")
|
||||
#endif()
|
||||
ELSE()
|
||||
# Non-debug builds
|
||||
add_compile_definitions(NDEBUG)
|
||||
ENDIF()
|
||||
|
||||
# Common stuff
|
||||
if(APPLE)
|
||||
# macOS doesn't search the executable path by default
|
||||
# so, locate libraries like SDL in the executable path
|
||||
set(CMAKE_INSTALL_RPATH "@executable_path")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
# Set the visibility to hidden on macOS to prevent shared libraries from
|
||||
# using functions in the executable
|
||||
# it's ok to hide them because the backtrace on macOS will still print the name of the functions
|
||||
add_compile_options(-fvisibility=hidden)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Setup the installation directory
|
||||
#
|
||||
if(WIN32)
|
||||
# By default, both DLLs and EXEs are in the same directory
|
||||
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR bin)
|
||||
set(BIN_INSTALL_SUBDIR ".")
|
||||
set(LIB_INSTALL_SUBDIR ".")
|
||||
else()
|
||||
# Unix
|
||||
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR lib)
|
||||
set(BIN_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
|
||||
set(LIB_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
|
||||
endif()
|
||||
|
||||
# By default, put both binaries and shared libraries in the same directory
|
||||
# the game uses internal shared libraries that must be in the same folder as the binaries
|
||||
set(CMAKE_INSTALL_BINDIR ${CMAKE_DEFAULT_INSTALL_RUNTIME_DIR} CACHE PATH "Binary dir")
|
||||
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Library dir")
|
||||
include(GNUInstallDirs)
|
||||
|
||||
#
|
||||
# Common stuff
|
||||
#
|
||||
add_subdirectory("code/qcommon")
|
||||
add_subdirectory("code/gamespy")
|
||||
|
||||
#
|
||||
# Application
|
||||
|
||||
#
|
||||
add_subdirectory("code/sys")
|
||||
|
||||
##
|
||||
## Server app
|
||||
##
|
||||
add_subdirectory("code/server")
|
||||
|
||||
add_executable(omohaaded "code/null/null_client.c" "code/null/null_input.c" "code/null/null_snddma.c")
|
||||
@@ -91,21 +155,23 @@ target_link_libraries(omohaaded PRIVATE omohserver)
|
||||
target_link_libraries(omohaaded PRIVATE syslib)
|
||||
target_link_libraries(omohaaded PRIVATE qcommon qcommon_standalone)
|
||||
|
||||
# Gamespy dependency
|
||||
# Add the 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}")
|
||||
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BIN_SUFFIX}")
|
||||
set_target_properties(omohaaded PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
|
||||
INSTALL(TARGETS omohaaded DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
|
||||
|
||||
if (MSVC)
|
||||
target_link_options(omohaaded PRIVATE "/MANIFEST:NO")
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:omohaaded> DESTINATION "./" OPTIONAL)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:omohaaded> DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR} OPTIONAL)
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS omohaaded DESTINATION "./")
|
||||
|
||||
if (NOT BUILD_NO_CLIENT)
|
||||
##
|
||||
## Client app
|
||||
|
||||
##
|
||||
|
||||
add_subdirectory("code/client")
|
||||
add_subdirectory("code/renderer")
|
||||
add_subdirectory("code/sdl")
|
||||
@@ -121,18 +187,77 @@ if (NOT BUILD_NO_CLIENT)
|
||||
target_link_libraries(openmohaa PRIVATE omohclient)
|
||||
target_link_libraries(openmohaa PRIVATE omohrenderer omohsdl)
|
||||
target_link_libraries(openmohaa PRIVATE qcommon qcommon_standalone)
|
||||
|
||||
### Gamespy dependency
|
||||
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib" "code/jpeg-8c")
|
||||
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
|
||||
|
||||
# Add the gamespy dependency
|
||||
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib")
|
||||
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BIN_SUFFIX}")
|
||||
set_target_properties(openmohaa PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
|
||||
target_link_libraries(openmohaa PRIVATE jpeg8)
|
||||
if(USE_INTERNAL_JPEG)
|
||||
target_include_directories(openmohaa PUBLIC "code/jpeg-8c")
|
||||
target_link_libraries(openmohaa PRIVATE jpeg8)
|
||||
else()
|
||||
find_package(JPEG REQUIRED)
|
||||
target_include_directories(openmohaa PUBLIC ${JPEG_INCLUDE_DIRS})
|
||||
target_link_libraries(openmohaa PRIVATE ${JPEG_LIBRARIES})
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS openmohaa DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
|
||||
|
||||
if (MSVC)
|
||||
target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:openmohaa> DESTINATION "./" OPTIONAL)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:openmohaa> DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR} OPTIONAL)
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS openmohaa DESTINATION "./")
|
||||
if(UNIX AND NOT APPLE)
|
||||
#
|
||||
# Desktop entries installation on Unix
|
||||
#
|
||||
set(TARGET_ARCH ${TARGET_BIN_SUFFIX})
|
||||
|
||||
# Configure the .desktop entries with the arch suffix
|
||||
configure_file(
|
||||
misc/linux/org.openmoh.openmohaa.desktop.in
|
||||
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaa.desktop
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
misc/linux/org.openmoh.openmohaab.desktop.in
|
||||
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaab.desktop
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
misc/linux/org.openmoh.openmohaas.desktop.in
|
||||
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaas.desktop
|
||||
@ONLY
|
||||
)
|
||||
|
||||
# Install .desktop entries
|
||||
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaa.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaab.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaas.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||
|
||||
install(FILES misc/linux/org.openmoh.openmohaa.metainfo.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo)
|
||||
|
||||
install(FILES misc/openmohaa.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/symbolic/apps/ RENAME org.openmoh.openmohaa.svg)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Launcher
|
||||
#
|
||||
add_subdirectory(code/Launcher)
|
||||
|
||||
#
|
||||
# uninstall target
|
||||
#
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
|
||||
@@ -1,34 +1,28 @@
|
||||
# OpenMoHAA
|
||||
|
||||
 [](https://github.com/openmoh/openmohaa/releases) [](https://github.com/openmoh/openmohaa/releases)
|
||||
[](https://github.com/openmoh/openmohaa/actions/workflows/branches-build.yml) [](https://github.com/openmoh/openmohaa/releases) [](https://github.com/openmoh/openmohaa/releases)
|
||||
|
||||
 
|
||||
|
||||

|
||||
|
||||
|
||||
```
|
||||
/ _ \ _ __ ___ _ __ | \/ |/ _ \| | | | / \ / \
|
||||
| | | | '_ \ / _ \ '_ \| |\/| | | | | |_| | / _ \ / _ \
|
||||
| |_| | |_) | __/ | | | | | | |_| | _ |/ ___ \ / ___ \
|
||||
\___/| .__/ \___|_| |_|_| |_|\___/|_| |_/_/ \_\/_/ \_\
|
||||
|_|
|
||||
```
|
||||

|
||||
|
||||
## 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).
|
||||
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault** on all platforms/architectures by providing new patches/features. Thanks to the ioquake3 project and the F.A.K.K SDK, OpenMoHAA has already reached more than half of its goal: 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).
|
||||
|
||||
## Getting started
|
||||
|
||||
- [Installing OpenMoHAA](docs/getting_started_installation.md)
|
||||
- [Downloading and installing OpenMoHAA](docs/getting_started_installation.md)
|
||||
- [Running OpenMoHAA and using expansion assets](docs/getting_started_running.md)
|
||||
- [Dedicated server configuration](docs/configuration/server.md)
|
||||
|
||||
## Current state
|
||||
|
||||
### Single-player
|
||||
|
||||
The entire single-player campaign can be played from start to end. There may be occasional bugs though; if you encounter any, please create a new [GitHub issue](https://github.com/openmoh/openmohaa/issues) describing them.
|
||||
The entire single-player campaign should work (Allied Assault, Spearhead and Breakthrough). If you encounter any bug, please create a new [GitHub issue](https://github.com/openmoh/openmohaa/issues) describing them.
|
||||
|
||||
### Multiplayer
|
||||
|
||||
@@ -40,8 +34,7 @@ All game modes including `Tug-of-War` from Medal of Honor: Spearhead, and `Liber
|
||||
|
||||
## Features
|
||||
|
||||
- [What's working](docs/features_implementation.md)
|
||||
- [New features](docs/features.md)
|
||||
- [List of new features](docs/features.md)
|
||||
- [Scripting commands](https://htmlpreview.github.io/?https://github.com/openmoh/openmohaa/blob/main/docs/features_g_allclasses.html)
|
||||
|
||||
## Compiling
|
||||
|
||||
+10
-4
@@ -71,12 +71,14 @@ function(target_architecture output_var)
|
||||
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
|
||||
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
|
||||
set(osx_arch_ppc TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
|
||||
set(osx_arch_ppc64 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "i386")
|
||||
set(osx_arch_i386 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "x86_64")
|
||||
set(osx_arch_x86_64 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
|
||||
set(osx_arch_ppc64 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "arm64")
|
||||
set(osx_arch_arm64 TRUE)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
|
||||
endif()
|
||||
@@ -87,6 +89,10 @@ function(target_architecture output_var)
|
||||
list(APPEND ARCH ppc)
|
||||
endif()
|
||||
|
||||
if(osx_arch_ppc64)
|
||||
list(APPEND ARCH ppc64)
|
||||
endif()
|
||||
|
||||
if(osx_arch_i386)
|
||||
list(APPEND ARCH i386)
|
||||
endif()
|
||||
@@ -95,8 +101,8 @@ function(target_architecture output_var)
|
||||
list(APPEND ARCH x86_64)
|
||||
endif()
|
||||
|
||||
if(osx_arch_ppc64)
|
||||
list(APPEND ARCH ppc64)
|
||||
if(osx_arch_arm64)
|
||||
list(APPEND ARCH arm64)
|
||||
endif()
|
||||
else()
|
||||
# figure out extension for the source file
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
endif()
|
||||
|
||||
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
execute_process(
|
||||
COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RESULT_VARIABLE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif()
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -0,0 +1,36 @@
|
||||
project(Launcher)
|
||||
|
||||
set(LAUNCHER_SOURCES "${CMAKE_SOURCE_DIR}/code/Launcher/launch_main.cpp")
|
||||
|
||||
if (WIN32)
|
||||
set(LAUNCHER_SOURCES ${LAUNCHER_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/code/Launcher/launch_win32.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/code/sys/win_resource.rc")
|
||||
else()
|
||||
set(LAUNCHER_SOURCES ${LAUNCHER_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/code/Launcher/launch_linux.cpp")
|
||||
endif()
|
||||
|
||||
function (create_launcher name type)
|
||||
if (NOT BUILD_NO_CLIENT)
|
||||
add_executable(openmohaa_launcher_${name} ${LAUNCHER_SOURCES})
|
||||
target_include_directories(openmohaa_launcher_${name} PUBLIC "../qcommon")
|
||||
target_compile_definitions(openmohaa_launcher_${name} PRIVATE NO_RC_MANIFEST=1 TARGET_GAME=${type})
|
||||
target_compile_features(openmohaa_launcher_${name} PRIVATE cxx_std_17)
|
||||
set_target_properties(openmohaa_launcher_${name} PROPERTIES OUTPUT_NAME "launch_openmohaa_${name}${TARGET_BIN_SUFFIX}")
|
||||
|
||||
INSTALL(TARGETS openmohaa_launcher_${name} DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
|
||||
endif()
|
||||
|
||||
#add_executable(omohaaded_launcher_${name} ${LAUNCHER_SOURCES})
|
||||
#target_include_directories(omohaaded_launcher_${name} PUBLIC "../qcommon")
|
||||
#target_compile_definitions(omohaaded_launcher_${name} PRIVATE NO_RC_MANIFEST=1 TARGET_GAME=${type} DEDICATED=1)
|
||||
#target_compile_features(omohaaded_launcher_${name} PRIVATE cxx_std_17)
|
||||
#set_target_properties(omohaaded_launcher_${name} PROPERTIES OUTPUT_NAME "launch_omohaaded_${name}${TARGET_BIN_SUFFIX}")
|
||||
#
|
||||
#INSTALL(TARGETS omohaaded_launcher_${name} DESTINATION ${CMAKE_INSTALL_BINDIR}/${PROJECT_INSTALL_SUBDIR})
|
||||
endfunction()
|
||||
|
||||
create_launcher(base 0)
|
||||
create_launcher(spearhead 1)
|
||||
create_launcher(breakthrough 2)
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// launch.h: Base interface for starting programs
|
||||
|
||||
#include "q_platform.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
std::filesystem::path GetProgramLocation();
|
||||
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList);
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// main.cpp: Windows implementation of the launcher
|
||||
|
||||
#include "launch.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <spawn.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
extern "C" char** environ;
|
||||
|
||||
std::filesystem::path GetProgramLocation()
|
||||
{
|
||||
char path[FILENAME_MAX];
|
||||
ssize_t count = readlink("/proc/self/exe", path, FILENAME_MAX);
|
||||
|
||||
return std::filesystem::path(std::string(path, (count > 0) ? count : 0)).parent_path();
|
||||
}
|
||||
|
||||
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList)
|
||||
{
|
||||
pid_t pid;
|
||||
std::string pathString = path.string();
|
||||
size_t argCount = argumentList.size();
|
||||
char** argv;
|
||||
int status;
|
||||
|
||||
argv = new char*[argCount + 2];
|
||||
argv[0] = (char*)pathString.c_str();
|
||||
|
||||
for (size_t i = 0; i < argCount; i++) {
|
||||
argv[i + 1] = (char*)argumentList[i].c_str();
|
||||
}
|
||||
argv[argCount + 1] = NULL;
|
||||
|
||||
//status = posix_spawn(&pid, pathString.c_str(), NULL, NULL, argv, environ);
|
||||
//delete[] argv;
|
||||
//if (status != 0) {
|
||||
// std::cout << "posix_spawn returned error: " << status << std::endl;
|
||||
// return;
|
||||
//}
|
||||
|
||||
//
|
||||
// Using execve rather than posix_spawn
|
||||
// This replaces the current process that is not needed anyway
|
||||
//
|
||||
status = execve(pathString.c_str(), argv, environ);
|
||||
delete[] argv;
|
||||
if (status == -1) {
|
||||
std::cout << "posix_spawn returned error: " << errno << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
waitpid(pid, NULL, 0);
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// main.cpp: The launcher
|
||||
|
||||
#include "launch.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
const char* targetGameList[] =
|
||||
{
|
||||
"Base",
|
||||
"Spearhead",
|
||||
"Breakthrough"
|
||||
};
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
std::vector<std::string> argumentList;
|
||||
#if !defined(DEDICATED) || !DEDICATED
|
||||
const char* programName = "openmohaa" "." ARCH_STRING DLL_SUFFIX EXE_EXT;
|
||||
#else
|
||||
const char* programName = "omohaaded" "." ARCH_STRING DLL_SUFFIX EXE_EXT;
|
||||
#endif
|
||||
|
||||
argumentList.push_back("+set");
|
||||
argumentList.push_back("com_target_game");
|
||||
argumentList.push_back(std::to_string(TARGET_GAME));
|
||||
|
||||
for (size_t i = 1; i < argc; i++) {
|
||||
argumentList.push_back(argv[i]);
|
||||
}
|
||||
|
||||
std::cout << "Using the target game: " << targetGameList[TARGET_GAME] << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Expected program name: " << programName << std::endl;
|
||||
|
||||
const std::filesystem::path programLocation = GetProgramLocation();
|
||||
const std::filesystem::path programPath = programLocation / programName;
|
||||
|
||||
std::cout << "Program location: " << programLocation << std::endl;
|
||||
std::cout << "Expected path: " << programPath << std::endl;
|
||||
|
||||
LaunchProgram(programPath, argumentList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// main.cpp: Windows implementation of the launcher
|
||||
|
||||
#include "launch.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
std::filesystem::path GetProgramLocation()
|
||||
{
|
||||
wchar_t path[FILENAME_MAX] = { 0 };
|
||||
GetModuleFileNameW(nullptr, path, FILENAME_MAX);
|
||||
|
||||
return std::filesystem::path(path).parent_path();
|
||||
}
|
||||
|
||||
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList)
|
||||
{
|
||||
PROCESS_INFORMATION processInfo;
|
||||
STARTUPINFOW startupInfo;
|
||||
BOOL returnValue;
|
||||
std::wstring osCommandLine;
|
||||
std::wstring commandLine;
|
||||
size_t argCount = argumentList.size();
|
||||
|
||||
memset(&processInfo, 0, sizeof(processInfo));
|
||||
memset(&startupInfo, 0, sizeof(startupInfo));
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
|
||||
for (size_t i = 0; i < argCount; i++) {
|
||||
commandLine += L"\"";
|
||||
commandLine += std::wstring(argumentList[i].begin(), argumentList[i].end());
|
||||
commandLine += L"\"";
|
||||
if (i != argCount - 1) {
|
||||
commandLine += L" ";
|
||||
}
|
||||
}
|
||||
|
||||
osCommandLine = path.wstring();
|
||||
osCommandLine += L" ";
|
||||
osCommandLine += commandLine;
|
||||
|
||||
returnValue = CreateProcessW(
|
||||
path.wstring().c_str(),
|
||||
(LPWSTR)osCommandLine.c_str(),
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
std::filesystem::current_path().wstring().c_str(),
|
||||
&startupInfo,
|
||||
&processInfo
|
||||
);
|
||||
|
||||
if (!returnValue) {
|
||||
std::cout << "Error in CreateProcess: " << GetLastError() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
WaitForSingleObject(processInfo.hProcess, INFINITE);
|
||||
|
||||
CloseHandle(processInfo.hProcess);
|
||||
CloseHandle(processInfo.hThread);
|
||||
}
|
||||
@@ -27,16 +27,11 @@ target_compile_features(cgame PUBLIC cxx_nullptr)
|
||||
target_compile_features(cgame PUBLIC c_variadic_macros)
|
||||
target_link_libraries(cgame PUBLIC qcommon)
|
||||
|
||||
set_target_properties(cgame PROPERTIES PREFIX "${TARGET_PLATFORM_PREFIX}")
|
||||
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(cgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
|
||||
set_target_properties(cgame PROPERTIES PREFIX "")
|
||||
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_BIN_SUFFIX}")
|
||||
|
||||
INSTALL(
|
||||
TARGETS cgame
|
||||
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
|
||||
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
|
||||
)
|
||||
INSTALL(TARGETS cgame DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR})
|
||||
|
||||
if(MSVC)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION "${TARGET_BASE_GAME}" OPTIONAL)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR} OPTIONAL)
|
||||
endif()
|
||||
+181
-53
@@ -564,7 +564,16 @@ Event EV_Client_LoopSound
|
||||
EV_DEFAULT,
|
||||
"sFFf",
|
||||
"soundName volume min_distance pitch",
|
||||
"Play the specifed sound as a looping sound"
|
||||
"Play the specified sound as a looping sound"
|
||||
);
|
||||
// Added in 2.0
|
||||
Event EV_Client_StopLoopSound
|
||||
(
|
||||
"stoploopsound",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Stop the looping sound"
|
||||
);
|
||||
Event EV_Client_Cache
|
||||
(
|
||||
@@ -985,7 +994,7 @@ Event EV_Client_BounceDecal(
|
||||
"maxamount temporary",
|
||||
"Put a mark when the tempmodel bounces and hits a surface\n"
|
||||
"maxamount = Max amount of decals to make when bouncing\n"
|
||||
"temporary = specify 1 for a temporary mark that only appears for a short time, 0 for a decal that stays aroung "
|
||||
"temporary = specify 1 for a temporary mark that only appears for a short time, 0 for a decal that stays around "
|
||||
"longer (default is 0)\n"
|
||||
);
|
||||
Event EV_Client_SetDecalRadius
|
||||
@@ -1085,6 +1094,15 @@ Event EV_Client_Print
|
||||
"string",
|
||||
"Prints a string."
|
||||
);
|
||||
// Added in 2.0
|
||||
Event EV_Client_PrintDeathMsg
|
||||
(
|
||||
"printdeathmsg",
|
||||
EV_DEFAULT,
|
||||
"sssss",
|
||||
"msg1, msg2, killer, victim, deathType",
|
||||
"Prints a death message string. Used to allow death messages to appear in their correct language on client machines.."
|
||||
);
|
||||
Event EV_Client_SetVolumetric
|
||||
(
|
||||
"volumetric",
|
||||
@@ -1122,7 +1140,7 @@ Event EV_Client_SetAlignStretch(
|
||||
EV_DEFAULT,
|
||||
"F",
|
||||
"scaleMultiplier",
|
||||
"Aligns the temp model to the direction of travel, and stretches it betwen the last and current positions.\n"
|
||||
"Aligns the temp model to the direction of travel, and stretches it between the last and current positions.\n"
|
||||
);
|
||||
Event EV_Client_SetClampVelocity
|
||||
(
|
||||
@@ -1195,6 +1213,14 @@ Event EV_Client_SFXStartDelayed
|
||||
"fDelay sCommand arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8",
|
||||
"Used for adding commands to a special effect with a time delay"
|
||||
);
|
||||
Event EV_Client_PlayForceFeedback
|
||||
(
|
||||
"playforcefeedback",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"effectname",
|
||||
"Starts a force feedback effect."
|
||||
);
|
||||
|
||||
EffectsEventQueueNode EffectsEventQueue;
|
||||
|
||||
@@ -1261,6 +1287,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
|
||||
{&EV_Client_StopSound, &ClientGameCommandManager::StopSound },
|
||||
{&EV_Client_StopAliasChannel, &ClientGameCommandManager::StopAliasChannel },
|
||||
{&EV_Client_LoopSound, &ClientGameCommandManager::LoopSound },
|
||||
{&EV_Client_StopLoopSound, &ClientGameCommandManager::StopLoopSound },
|
||||
{&EV_Client_Cache, &ClientGameCommandManager::Cache },
|
||||
{&EV_Client_CacheImage, &ClientGameCommandManager::CacheImage },
|
||||
{&EV_Client_CacheFont, &ClientGameCommandManager::CacheFont },
|
||||
@@ -1323,6 +1350,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
|
||||
{&EV_Client_SetClampVelocity, &ClientGameCommandManager::SetClampVel },
|
||||
{&EV_Client_SetClampVelocityAxis, &ClientGameCommandManager::SetClampVelAxis },
|
||||
{&EV_Client_Print, &ClientGameCommandManager::Print },
|
||||
{&EV_Client_PrintDeathMsg, &ClientGameCommandManager::PrintDeathMsg },
|
||||
{&EV_Client_EyeLimits, &ClientGameCommandManager::SetEyeLimits },
|
||||
{&EV_Client_EyeMovement, &ClientGameCommandManager::SetEyeMovement },
|
||||
{&EV_Client_SFXStart, &ClientGameCommandManager::StartSFX },
|
||||
@@ -1394,9 +1422,11 @@ qboolean ClientGameCommandManager::PostEventForEntity(Event *ev, float fWait)
|
||||
EffectsEventQueueNode *node;
|
||||
int inttime;
|
||||
|
||||
if (!m_fEventWait || current_entity_number < 0) {
|
||||
if (!str::icmp(ev->getName(), ")")) {
|
||||
m_fEventWait = 0.0;
|
||||
if (m_fEventWait < 0 || current_entity_number < 0) {
|
||||
if (m_fEventWait != 0.0) {
|
||||
if (!str::icmp(ev->getName(), ")")) {
|
||||
m_fEventWait = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
delete ev;
|
||||
@@ -1413,7 +1443,7 @@ qboolean ClientGameCommandManager::PostEventForEntity(Event *ev, float fWait)
|
||||
event = EffectsEventQueue.next;
|
||||
inttime = EVENT_msec + (fWait * 1000.0f + 0.5f);
|
||||
|
||||
while (event != &EffectsEventQueue && inttime > event->inttime) {
|
||||
while (event != &EffectsEventQueue && inttime >= event->inttime) {
|
||||
event = event->next;
|
||||
}
|
||||
|
||||
@@ -1449,8 +1479,8 @@ void ClientGameCommandManager::SetBaseAndAmplitude(Event *ev, Vector& base, Vect
|
||||
base[j] = ev->GetFloat(i++);
|
||||
amplitude[j] = ev->GetFloat(i++);
|
||||
} else {
|
||||
base[j] = 0.0;
|
||||
amplitude[j] = atof(org.c_str());
|
||||
base[j] = atof(org.c_str());
|
||||
amplitude[j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1473,6 +1503,13 @@ void ClientGameCommandManager::Print(Event *ev)
|
||||
}
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::PrintDeathMsg(Event* ev)
|
||||
{
|
||||
if (current_entity) {
|
||||
cgi.DPrintf("%d:%s\n", current_entity->entityNumber, ev->GetString(1).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
qboolean ClientGameCommandManager::IsBlockCommand(const str& name)
|
||||
{
|
||||
if (!str::icmp(name, "originspawn")) {
|
||||
@@ -1552,7 +1589,6 @@ void ClientGameCommandManager::CommandDelay(Event *ev)
|
||||
ev1->AddValue(ev->GetValue(i));
|
||||
}
|
||||
|
||||
delay = ev->GetFloat(1) * 1000;
|
||||
if (current_entity_number != -1) {
|
||||
PostEventForEntity(ev1, fWait);
|
||||
} else {
|
||||
@@ -1562,6 +1598,16 @@ void ClientGameCommandManager::CommandDelay(Event *ev)
|
||||
current_tiki->name
|
||||
);
|
||||
}
|
||||
|
||||
if (IsBlockCommand(eventName)) {
|
||||
m_fEventWait = fWait;
|
||||
} else {
|
||||
m_fEventWait = 0;
|
||||
}
|
||||
|
||||
if (current_entity_number == -1 && m_fEventWait > 0) {
|
||||
m_fEventWait = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::StartSFX(Event *ev)
|
||||
@@ -2599,7 +2645,9 @@ void ClientGameCommandManager::SetColorRange(Event *ev)
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: unused stub??
|
||||
//
|
||||
// Unused
|
||||
//
|
||||
}
|
||||
|
||||
//=============
|
||||
@@ -2825,7 +2873,9 @@ void ClientGameCommandManager::SetAccel(Event *ev)
|
||||
m_spawnthing->cgd.accel[1] = ev->GetFloat(2);
|
||||
m_spawnthing->cgd.accel[2] = ev->GetFloat(3);
|
||||
|
||||
m_spawnthing->cgd.flags2 |= T2_ACCEL;
|
||||
if (!(m_spawnthing->cgd.flags & T_SWARM)) {
|
||||
m_spawnthing->cgd.flags2 |= T2_ACCEL;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::SetFriction(Event *ev)
|
||||
@@ -3054,7 +3104,7 @@ spawnthing_t *ClientGameCommandManager::InitializeSpawnthing(spawnthing_t *sp)
|
||||
sp->cgd.parent = -1;
|
||||
sp->cgd.tiki = nullptr;
|
||||
sp->cgd.lightstyle = -1;
|
||||
sp->cgd.physicsRate = 10;
|
||||
sp->cgd.physicsRate = cg_effect_physicsrate->integer;
|
||||
sp->cgd.shadername = "beamshader";
|
||||
sp->cgd.decal_orientation = 0;
|
||||
sp->cgd.decal_radius = 10;
|
||||
@@ -3873,7 +3923,7 @@ void ClientGameCommandManager::PlaySound(
|
||||
} else {
|
||||
if (debugSound->integer) {
|
||||
Com_Printf(
|
||||
"\nWARNING: OVERRIDE OVERRIDE OVERRIDESound %s had all its parm overriden by code.\n\n",
|
||||
"\nWARNING: OVERRIDE OVERRIDE OVERRIDESound %s had all its parm overridden by code.\n\n",
|
||||
sound_name.c_str()
|
||||
);
|
||||
}
|
||||
@@ -3987,6 +4037,9 @@ void ClientGameCommandManager::StopSound(Event *ev)
|
||||
cgi.S_StopSound(current_entity_number, channel);
|
||||
}
|
||||
|
||||
//===============
|
||||
// StopAliasChannel
|
||||
//===============
|
||||
void ClientGameCommandManager::StopAliasChannel(Event *ev)
|
||||
{
|
||||
str sound_name;
|
||||
@@ -4082,6 +4135,54 @@ void ClientGameCommandManager::LoopSound(Event *ev)
|
||||
current_centity->tikiLoopSoundFlags = 0;
|
||||
}
|
||||
|
||||
//===============
|
||||
// StopLoopSound
|
||||
//===============
|
||||
void ClientGameCommandManager::StopLoopSound(Event* ev)
|
||||
{
|
||||
if (!current_centity) {
|
||||
cgi.DPrintf("CCM::StopLoopSound : StopLoopSound in %s without current_centity\n", cgi.TIKI_Name(current_tiki));
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf("\n\nClientGameCommandManager::StopLoopSound\n\n");
|
||||
current_centity->tikiLoopSound = NULL;
|
||||
}
|
||||
|
||||
//===============
|
||||
// CacheImageResource
|
||||
//===============
|
||||
void CacheImageResource(const char* stuff) {
|
||||
str real_stuff;
|
||||
char filename[1024];
|
||||
|
||||
if (cgi.fsDebug->integer == 2) {
|
||||
Com_Printf("client cacheimage: %s\n", stuff);
|
||||
}
|
||||
|
||||
Q_strncpyz(filename, stuff, sizeof(filename));
|
||||
cgi.FS_CanonicalFilename(filename);
|
||||
|
||||
cgi.R_RegisterShaderNoMip(filename);
|
||||
}
|
||||
|
||||
//===============
|
||||
// CacheFontResource
|
||||
//===============
|
||||
void CacheFontResource(const char* stuff) {
|
||||
str real_stuff;
|
||||
char filename[1024];
|
||||
|
||||
if (cgi.fsDebug->integer == 2) {
|
||||
Com_Printf("client cacheimage: %s\n", stuff);
|
||||
}
|
||||
|
||||
Q_strncpyz(filename, stuff, sizeof(filename));
|
||||
cgi.FS_CanonicalFilename(filename);
|
||||
|
||||
cgi.R_LoadFont(filename);
|
||||
}
|
||||
|
||||
//===============
|
||||
// CacheResource
|
||||
//===============
|
||||
@@ -4121,12 +4222,12 @@ void ClientGameCommandManager::Cache(Event *ev)
|
||||
|
||||
void ClientGameCommandManager::CacheImage(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
CacheImageResource(ev->GetString(1).c_str());
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::CacheFont(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
CacheFontResource(ev->GetString(1).c_str());
|
||||
}
|
||||
|
||||
//===============
|
||||
@@ -4134,15 +4235,16 @@ void ClientGameCommandManager::CacheFont(Event *ev)
|
||||
//===============
|
||||
void AliasResource(dtiki_t *pmdl, const char *alias, const char *realname, const char *parameters)
|
||||
{
|
||||
if (pmdl) {
|
||||
if (!pmdl->a->alias_list) {
|
||||
pmdl->a->alias_list = cgi.AliasList_New(pmdl->a->name);
|
||||
}
|
||||
|
||||
cgi.Alias_ListAdd((AliasList_t *)pmdl->a->alias_list, alias, realname, parameters);
|
||||
} else {
|
||||
if (!pmdl) {
|
||||
cgi.Alias_Add(alias, realname, parameters);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pmdl->a->alias_list) {
|
||||
pmdl->a->alias_list = cgi.AliasList_New(pmdl->a->name);
|
||||
}
|
||||
|
||||
cgi.Alias_ListAdd((AliasList_t*)pmdl->a->alias_list, alias, realname, parameters);
|
||||
}
|
||||
|
||||
qboolean bLoadForMap(const char *psMapsBuffer, const char *name)
|
||||
@@ -4203,19 +4305,32 @@ void ClientGameCommandManager::AliasCache(Event *ev)
|
||||
psMapsBuffer = NULL;
|
||||
|
||||
for (i = 3; i <= ev->NumArgs(); i++) {
|
||||
if (!strcmp(ev->GetToken(i).c_str(), "maps")) {
|
||||
str s = ev->GetString(i);
|
||||
|
||||
if (!s.icmp("maps")) {
|
||||
i++;
|
||||
psMapsBuffer = ev->GetToken(i);
|
||||
} else if (!strcmp(ev->GetToken(i).c_str(), "always")) {
|
||||
bAlwaysLoaded = true;
|
||||
} else {
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
strcat(parmbuffer, " ");
|
||||
psMapsBuffer = (char *)ev->GetToken(i).c_str();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!s.icmp("always")) {
|
||||
bAlwaysLoaded = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
strcat(parmbuffer, s);
|
||||
strcat(parmbuffer, " ");
|
||||
}
|
||||
|
||||
if (bAlwaysLoaded || bLoadForMap(psMapsBuffer, ev->GetString(1))) {
|
||||
if (bAlwaysLoaded) {
|
||||
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
|
||||
}
|
||||
|
||||
if (bLoadForMap(psMapsBuffer, ev->GetString(1))) {
|
||||
if (!bAlwaysLoaded) {
|
||||
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
|
||||
}
|
||||
|
||||
CacheResource(ev->GetString(2));
|
||||
}
|
||||
}
|
||||
@@ -4245,28 +4360,33 @@ void ClientGameCommandManager::Alias(Event *ev)
|
||||
psMapsBuffer = NULL;
|
||||
|
||||
for (i = 3; i <= ev->NumArgs(); i++) {
|
||||
if (!strcmp(ev->GetToken(i).c_str(), "maps")) {
|
||||
str s = ev->GetString(i);
|
||||
|
||||
if (!s.icmp("maps")) {
|
||||
i++;
|
||||
psMapsBuffer = ev->GetToken(i);
|
||||
} else if (!strcmp(ev->GetToken(i).c_str(), "always")) {
|
||||
psMapsBuffer = (char *)ev->GetToken(i).c_str();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!s.icmp("always")) {
|
||||
bAlwaysLoaded = true;
|
||||
} else if (subtitle) {
|
||||
strcat(parmbuffer, "\"");
|
||||
strcat(parmbuffer, s);
|
||||
strcat(parmbuffer, "\" ");
|
||||
|
||||
subtitle = 0;
|
||||
} else {
|
||||
subtitle = s.icmp("subtitle") == 0;
|
||||
|
||||
if (!subtitle) {
|
||||
if (!Q_stricmp(ev->GetToken(i), "subtitle") || !Q_stricmp(ev->GetToken(i), "forcesubtitle")) {
|
||||
subtitle = qtrue;
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
} else {
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
}
|
||||
} else {
|
||||
strcat(parmbuffer, "\"");
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
strcat(parmbuffer, "\"");
|
||||
subtitle = qfalse;
|
||||
subtitle = s.icmp("forcesubtitle") == 0;
|
||||
}
|
||||
|
||||
strcat(parmbuffer, " ");
|
||||
strcat(parmbuffer, s);
|
||||
}
|
||||
|
||||
strcat(parmbuffer, " ");
|
||||
}
|
||||
|
||||
if (bAlwaysLoaded || bLoadForMap(psMapsBuffer, ev->GetString(1))) {
|
||||
@@ -4998,7 +5118,15 @@ bool ClientGameCommandManager::GetTagPositionAndOrientation(str tagname, orienta
|
||||
//===============
|
||||
void ClientGameCommandManager::RestartAllEmitters(void)
|
||||
{
|
||||
// FIXME: stub??
|
||||
ctempmodel_t *p;
|
||||
|
||||
//
|
||||
// FIXME: not sure if it's the right thing
|
||||
//
|
||||
|
||||
for (p = m_active_tempmodels.prev; p != &m_active_tempmodels; p = p->next) {
|
||||
p->cgd.createTime = cg.time;
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
@@ -5209,7 +5337,7 @@ void CG_ClientCommandDebugMessage(centity_t *cent, const char *fmt, ...)
|
||||
char msg[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(msg, fmt, argptr);
|
||||
Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
if ((!cg_debugAnimWatch->integer) || ((cg_debugAnimWatch->integer - 1) == cent->currentState.number)) {
|
||||
@@ -5364,7 +5492,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
|
||||
current_tiki = NULL;
|
||||
|
||||
// Update the loading screen
|
||||
sprintf(tempName, "m%s", filename);
|
||||
Com_sprintf(tempName, sizeof(tempName), "m%s", filename);
|
||||
cgi.LoadResource(tempName);
|
||||
|
||||
bufstart = buffer;
|
||||
@@ -5373,7 +5501,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
|
||||
Event *ev;
|
||||
|
||||
// grab each line as we go
|
||||
strcpy(com_token, COM_ParseExt(&buffer, qtrue));
|
||||
Q_strncpyz(com_token, COM_ParseExt(&buffer, qtrue), sizeof(com_token));
|
||||
if (!com_token[0]) {
|
||||
break;
|
||||
}
|
||||
@@ -5381,7 +5509,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
|
||||
if (!Q_stricmp(com_token, "end") || !Q_stricmp(com_token, "server")) {
|
||||
// skip the line
|
||||
while (1) {
|
||||
strcpy(com_token, COM_ParseExt(&buffer, qfalse));
|
||||
Q_strncpyz(com_token, COM_ParseExt(&buffer, qfalse), sizeof(com_token));
|
||||
if (!com_token[0]) {
|
||||
break;
|
||||
}
|
||||
@@ -5394,7 +5522,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
|
||||
|
||||
// get the rest of the line
|
||||
while (1) {
|
||||
strcpy(com_token, COM_ParseExt(&buffer, qfalse));
|
||||
Q_strncpyz(com_token, COM_ParseExt(&buffer, qfalse), sizeof(com_token));
|
||||
if (!com_token[0]) {
|
||||
break;
|
||||
}
|
||||
@@ -5406,7 +5534,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
|
||||
cgi.FS_FreeFile((void *)bufstart);
|
||||
|
||||
// Update the loading screen
|
||||
sprintf(tempName, "o%s", filename);
|
||||
Com_sprintf(tempName, sizeof(tempName), "o%s", filename);
|
||||
cgi.LoadResource(tempName);
|
||||
|
||||
return qtrue;
|
||||
|
||||
@@ -764,6 +764,7 @@ private:
|
||||
void SpawnVSSSource(int count, int timealive);
|
||||
void EventViewKick(Event *ev);
|
||||
void Print(Event *ev);
|
||||
void PrintDeathMsg(Event *ev); // Added in 2.0
|
||||
void StartBlock(Event *ev);
|
||||
void EndBlock(Event *ev);
|
||||
void UpdateSpawnThing(spawnthing_t *ep);
|
||||
@@ -851,6 +852,7 @@ private:
|
||||
void StopSound(Event *ev);
|
||||
void StopAliasChannel(Event *ev);
|
||||
void LoopSound(Event *ev);
|
||||
void StopLoopSound(Event *ev); // Added in 2.0
|
||||
void Cache(Event *ev);
|
||||
void CacheImage(Event *ev);
|
||||
void CacheFont(Event *ev);
|
||||
|
||||
+205
-65
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2008-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -160,17 +160,157 @@ baseshader_t *CG_GetShaderUnderCrosshair(qboolean bVerbose, trace_t *pRetTrace)
|
||||
|
||||
static void CG_PrintContentTypes(int iContentFlags)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
if (iContentFlags & CONTENTS_SOLID) {
|
||||
cgi.Printf(" solid");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_LAVA) {
|
||||
cgi.Printf(" lava");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_SLIME) {
|
||||
cgi.Printf(" slime");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_WATER) {
|
||||
cgi.Printf(" water");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_FOG) {
|
||||
cgi.Printf(" fog");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_FENCE) {
|
||||
cgi.Printf(" fence");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_AREAPORTAL) {
|
||||
cgi.Printf(" areaportal");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_PLAYERCLIP) {
|
||||
cgi.Printf(" playerclip");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_VEHICLECLIP) {
|
||||
cgi.Printf(" vehicleclip");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_MONSTERCLIP) {
|
||||
cgi.Printf(" monsterclip");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_WEAPONCLIP) {
|
||||
cgi.Printf(" weaponclip");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_SHOOTONLY) {
|
||||
cgi.Printf(" shootableonly");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_ORIGIN) {
|
||||
cgi.Printf(" origin");
|
||||
}
|
||||
if (iContentFlags & CONTENTS_TRANSLUCENT) {
|
||||
cgi.Printf(" trans");
|
||||
}
|
||||
}
|
||||
|
||||
static void CG_PrintSurfaceProperties(int iSurfaceFlags)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
if (iSurfaceFlags & SURF_NODAMAGE) {
|
||||
cgi.Printf(" nodamage");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_SLICK) {
|
||||
cgi.Printf(" slick");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_SKY) {
|
||||
cgi.Printf(" sky");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_LADDER) {
|
||||
cgi.Printf(" ladder");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NOIMPACT) {
|
||||
cgi.Printf(" noimpact");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NOMARKS) {
|
||||
cgi.Printf(" nomarks");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_CASTSHADOW) {
|
||||
cgi.Printf(" castshadow");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NODRAW) {
|
||||
cgi.Printf(" nodraw");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NOLIGHTMAP) {
|
||||
cgi.Printf(" nolightmap");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_ALPHASHADOW) {
|
||||
cgi.Printf(" alphashadow");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NOSTEPS) {
|
||||
cgi.Printf(" nofootsteps");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NONSOLID) {
|
||||
cgi.Printf(" nonsolid");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_OVERBRIGHT) {
|
||||
cgi.Printf(" overbright");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_BACKSIDE) {
|
||||
cgi.Printf(" backside");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_NODLIGHT) {
|
||||
cgi.Printf(" nodlight");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_HINT) {
|
||||
cgi.Printf(" hint");
|
||||
}
|
||||
if (iSurfaceFlags & SURF_PATCH) {
|
||||
cgi.Printf(" patch");
|
||||
}
|
||||
}
|
||||
|
||||
static void CG_PrintSurfaceType(int iSurfType)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
switch (iSurfType & MASK_SURF_TYPE) {
|
||||
case SURF_FOLIAGE:
|
||||
cgi.Printf("foliage");
|
||||
break;
|
||||
case SURF_SNOW:
|
||||
cgi.Printf("snow");
|
||||
break;
|
||||
case SURF_CARPET:
|
||||
cgi.Printf("carpet");
|
||||
break;
|
||||
case SURF_SAND:
|
||||
cgi.Printf("sand");
|
||||
break;
|
||||
case SURF_PUDDLE:
|
||||
cgi.Printf("puddle");
|
||||
break;
|
||||
case SURF_GLASS:
|
||||
cgi.Printf("glass");
|
||||
break;
|
||||
case SURF_GRAVEL:
|
||||
cgi.Printf("gravel");
|
||||
break;
|
||||
case SURF_MUD:
|
||||
cgi.Printf("mud");
|
||||
break;
|
||||
case SURF_DIRT:
|
||||
cgi.Printf("dirt");
|
||||
break;
|
||||
case SURF_GRILL:
|
||||
cgi.Printf("metal grill");
|
||||
break;
|
||||
case SURF_GRASS:
|
||||
cgi.Printf("grass");
|
||||
break;
|
||||
case SURF_ROCK:
|
||||
cgi.Printf("rock");
|
||||
break;
|
||||
case SURF_PAPER:
|
||||
cgi.Printf("paper");
|
||||
break;
|
||||
case SURF_WOOD:
|
||||
cgi.Printf("wood");
|
||||
break;
|
||||
case SURF_METAL:
|
||||
cgi.Printf("metal");
|
||||
break;
|
||||
default:
|
||||
cgi.Printf("!!*none specified*!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CG_GetCHShader(void)
|
||||
@@ -216,9 +356,9 @@ void CG_EditCHShader(void)
|
||||
|
||||
pShader = CG_GetShaderUnderCrosshair(qfalse, NULL);
|
||||
if (pShader) {
|
||||
strcpy(name, "editspecificshader ");
|
||||
strcat(name, pShader->shader);
|
||||
strcat(name, "\n");
|
||||
Q_strncpyz(name, "editspecificshader ", sizeof(name));
|
||||
Q_strcat(name, sizeof(name), pShader->shader);
|
||||
Q_strcat(name, sizeof(name), "\n");
|
||||
cgi.AddCommand(name);
|
||||
} else {
|
||||
cgi.Printf("No surface selected\n");
|
||||
@@ -340,65 +480,65 @@ typedef struct {
|
||||
} consoleCommand_t;
|
||||
|
||||
static consoleCommand_t commands[] = {
|
||||
{"useweaponclass", &CG_UseWeaponClass_f },
|
||||
{"weapnext", &CG_NextWeapon_f },
|
||||
{"weapprev", &CG_PrevWeapon_f },
|
||||
{"uselast", &CG_UseLastWeapon_f },
|
||||
{"holster", &CG_HolsterWeapon_f },
|
||||
{"weapdrop", &CG_DropWeapon_f },
|
||||
{"toggleitem", &CG_ToggleItem_f },
|
||||
{"+scores", &CG_ScoresDown_f },
|
||||
{"-scores", &CG_ScoresUp_f },
|
||||
{"viewpos", &CG_Viewpos_f },
|
||||
{"sizeup", &CG_SizeUp_f },
|
||||
{"sizedown", &CG_SizeDown_f },
|
||||
{"cg_eventlist", &CG_EventList_f },
|
||||
{"cg_eventhelp", &CG_EventHelp_f },
|
||||
{"cg_dumpevents", &CG_DumpEventHelp_f },
|
||||
{"cg_pendingevents", &CG_PendingEvents_f },
|
||||
{"cg_classlist", &CG_ClassList_f },
|
||||
{"cg_classtree", &CG_ClassTree_f },
|
||||
{"cg_classevents", &CG_ClassEvents_f },
|
||||
{"cg_dumpclassevents", &CG_DumpClassEvents_f },
|
||||
{"cg_dumpallclasses", &CG_DumpAllClasses_f },
|
||||
{"testemitter", &CG_TestEmitter_f },
|
||||
{"triggertestemitter", &CG_TriggerTestEmitter_f },
|
||||
{"prevemittercommand", &CG_PrevEmitterCommand_f },
|
||||
{"nextemittercommand", &CG_NextEmitterCommand_f },
|
||||
{"newemittercommand", &CG_NewEmitterCommand_f },
|
||||
{"deleteemittercommand", &CG_DeleteEmitterCommand_f },
|
||||
{"dumpemitter", &CG_DumpEmitter_f },
|
||||
{"loademitter", &CG_LoadEmitter_f },
|
||||
{"resetvss", &CG_ResetVSSSources },
|
||||
{"getchshader", &CG_GetCHShader },
|
||||
{"editchshader", &CG_EditCHShader },
|
||||
{"messagemode", &CG_MessageMode_f },
|
||||
{"messagemode_all", &CG_MessageMode_All_f },
|
||||
{"messagemode_team", &CG_MessageMode_Team_f },
|
||||
{"messagemode_private", &CG_MessageMode_Private_f },
|
||||
{"say", &CG_MessageSingleAll_f },
|
||||
{"sayteam", &CG_MessageSingleTeam_f },
|
||||
{"teamsay", &CG_MessageSingleTeam_f },
|
||||
{"sayprivate", &CG_MessageSingleClient_f },
|
||||
{"sayone", &CG_MessageSingleClient_f },
|
||||
{"wisper", &CG_MessageSingleClient_f },
|
||||
{"instamsg_main", &CG_InstaMessageMain_f },
|
||||
{"instamsg_group_a", &CG_InstaMessageGroupA_f },
|
||||
{"instamsg_group_b", &CG_InstaMessageGroupB_f },
|
||||
{"instamsg_group_c", &CG_InstaMessageGroupC_f },
|
||||
{"instamsg_group_d", &CG_InstaMessageGroupD_f },
|
||||
{"instamsg_group_e", &CG_InstaMessageGroupE_f },
|
||||
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
|
||||
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f },
|
||||
{"useweaponclass", &CG_UseWeaponClass_f },
|
||||
{"weapnext", &CG_NextWeapon_f },
|
||||
{"weapprev", &CG_PrevWeapon_f },
|
||||
{"uselast", &CG_UseLastWeapon_f },
|
||||
{"holster", &CG_HolsterWeapon_f },
|
||||
{"weapdrop", &CG_DropWeapon_f },
|
||||
{"toggleitem", &CG_ToggleItem_f },
|
||||
{"+scores", &CG_ScoresDown_f },
|
||||
{"-scores", &CG_ScoresUp_f },
|
||||
{"viewpos", &CG_Viewpos_f },
|
||||
{"sizeup", &CG_SizeUp_f },
|
||||
{"sizedown", &CG_SizeDown_f },
|
||||
{"cg_eventlist", &CG_EventList_f },
|
||||
{"cg_eventhelp", &CG_EventHelp_f },
|
||||
{"cg_dumpevents", &CG_DumpEventHelp_f },
|
||||
{"cg_pendingevents", &CG_PendingEvents_f },
|
||||
{"cg_classlist", &CG_ClassList_f },
|
||||
{"cg_classtree", &CG_ClassTree_f },
|
||||
{"cg_classevents", &CG_ClassEvents_f },
|
||||
{"cg_dumpclassevents", &CG_DumpClassEvents_f },
|
||||
{"cg_dumpallclasses", &CG_DumpAllClasses_f },
|
||||
{"testemitter", &CG_TestEmitter_f },
|
||||
{"triggertestemitter", &CG_TriggerTestEmitter_f },
|
||||
{"prevemittercommand", &CG_PrevEmitterCommand_f },
|
||||
{"nextemittercommand", &CG_NextEmitterCommand_f },
|
||||
{"newemittercommand", &CG_NewEmitterCommand_f },
|
||||
{"deleteemittercommand", &CG_DeleteEmitterCommand_f },
|
||||
{"dumpemitter", &CG_DumpEmitter_f },
|
||||
{"loademitter", &CG_LoadEmitter_f },
|
||||
{"resetvss", &CG_ResetVSSSources },
|
||||
{"getchshader", &CG_GetCHShader },
|
||||
{"editchshader", &CG_EditCHShader },
|
||||
{"messagemode", &CG_MessageMode_f },
|
||||
{"messagemode_all", &CG_MessageMode_All_f },
|
||||
{"messagemode_team", &CG_MessageMode_Team_f },
|
||||
{"messagemode_private", &CG_MessageMode_Private_f },
|
||||
{"say", &CG_MessageSingleAll_f },
|
||||
{"sayteam", &CG_MessageSingleTeam_f },
|
||||
{"teamsay", &CG_MessageSingleTeam_f },
|
||||
{"sayprivate", &CG_MessageSingleClient_f },
|
||||
{"sayone", &CG_MessageSingleClient_f },
|
||||
{"wisper", &CG_MessageSingleClient_f },
|
||||
{"instamsg_main", &CG_InstaMessageMain_f },
|
||||
{"instamsg_group_a", &CG_InstaMessageGroupA_f },
|
||||
{"instamsg_group_b", &CG_InstaMessageGroupB_f },
|
||||
{"instamsg_group_c", &CG_InstaMessageGroupC_f },
|
||||
{"instamsg_group_d", &CG_InstaMessageGroupD_f },
|
||||
{"instamsg_group_e", &CG_InstaMessageGroupE_f },
|
||||
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
|
||||
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f },
|
||||
// Added in 2.0
|
||||
{"pushcallvote", &CG_PushCallVote_f },
|
||||
{"pushcallvotesublist", &CG_PushCallVoteSubList_f },
|
||||
{"pushcallvotesubtext", &CG_PushCallVoteSubText_f },
|
||||
{"pushcallvotesubinteger",&CG_PushCallVoteSubInteger_f },
|
||||
{"pushcallvotesubfloat", &CG_PushCallVoteSubFloat_f },
|
||||
{"pushcallvotesubclient", &CG_PushCallVoteSubClient_f },
|
||||
{"pushvote", &CG_PushVote_f },
|
||||
{"callentryvote", &CG_CallEntryVote_f },
|
||||
{"pushcallvote", &CG_PushCallVote_f },
|
||||
{"pushcallvotesublist", &CG_PushCallVoteSubList_f },
|
||||
{"pushcallvotesubtext", &CG_PushCallVoteSubText_f },
|
||||
{"pushcallvotesubinteger", &CG_PushCallVoteSubInteger_f},
|
||||
{"pushcallvotesubfloat", &CG_PushCallVoteSubFloat_f },
|
||||
{"pushcallvotesubclient", &CG_PushCallVoteSubClient_f },
|
||||
{"pushvote", &CG_PushVote_f },
|
||||
{"callentryvote", &CG_CallEntryVote_f },
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+70
-36
@@ -675,14 +675,17 @@ void CG_DrawObjectives()
|
||||
{
|
||||
float vColor[4];
|
||||
float fX, fY;
|
||||
int iNumObjectives;
|
||||
float fObjectivesTop;
|
||||
static float fWidth;
|
||||
float fHeight;
|
||||
int iNumLines[20];
|
||||
int iTotalNumLines;
|
||||
int i;
|
||||
int ii;
|
||||
int iCurrentObjective;
|
||||
float fTimeDelta;
|
||||
const char *pszLocalizedText;
|
||||
const char *pszLine;
|
||||
|
||||
iTotalNumLines = 0;
|
||||
for (i = CS_OBJECTIVES; i < CS_OBJECTIVES + MAX_OBJECTIVES; ++i) {
|
||||
@@ -702,26 +705,30 @@ void CG_DrawObjectives()
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_OBJECTIVES; i++) {
|
||||
if ((cg.Objectives[i].flags & 0xFFFFFFFE)) {
|
||||
iNumLines[i] = 0;
|
||||
// Added in 2.0
|
||||
// Get the minimum Y value, it should be below the compass
|
||||
fObjectivesTop = cgi.UI_GetObjectivesTop();
|
||||
iNumObjectives = 0;
|
||||
|
||||
for (ii = 0; ii < MAX_STRING_CHARS; ii++) {
|
||||
if (cg.Objectives[i].text[ii] == '\n') {
|
||||
iTotalNumLines++;
|
||||
iNumLines[i]++;
|
||||
} else if (!cg.Objectives[i].text[ii]) {
|
||||
iTotalNumLines++;
|
||||
iNumLines[i]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_OBJECTIVES; i++) {
|
||||
if ((cg.Objectives[i].flags == OBJ_FLAG_NONE) || (cg.Objectives[i].flags & OBJ_FLAG_HIDDEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iNumObjectives++;
|
||||
iNumLines[i] = 0;
|
||||
pszLocalizedText = cgi.LV_ConvertString(cg.Objectives[i].text);
|
||||
|
||||
for (pszLine = strchr(pszLocalizedText, '\n'); pszLine; pszLine = strchr(pszLine + 1, '\n')) {
|
||||
iNumLines[i]++;
|
||||
}
|
||||
|
||||
iTotalNumLines += iNumLines[i];
|
||||
}
|
||||
|
||||
fX = 25.0;
|
||||
fY = 125.0;
|
||||
fWidth = (float)(25 * iTotalNumLines + 155) + 5.0 - 130.0;
|
||||
fY = fObjectivesTop + 5;
|
||||
fWidth = (float)(iTotalNumLines * 12 + fObjectivesTop + iNumObjectives * 25 + 32) - fY;
|
||||
vColor[2] = 0.2f;
|
||||
vColor[1] = 0.2f;
|
||||
vColor[0] = 0.2f;
|
||||
@@ -730,7 +737,7 @@ void CG_DrawObjectives()
|
||||
cgi.R_DrawStretchPic(fX, fY, 450.0, fWidth, 0.0, 0.0, 1.0, 1.0, cgs.media.objectivesBackShader);
|
||||
|
||||
fX = 30.0;
|
||||
fY = 130.0;
|
||||
fY = fObjectivesTop + 10;
|
||||
vColor[0] = 1.0;
|
||||
vColor[1] = 1.0;
|
||||
vColor[2] = 1.0;
|
||||
@@ -740,12 +747,12 @@ void CG_DrawObjectives()
|
||||
fY = fY + 5.0;
|
||||
|
||||
cgi.R_DrawString(cgs.media.objectiveFont, "_______________________________________________________", fX, fY, -1, 0);
|
||||
fHeight = 155.0;
|
||||
fHeight = fObjectivesTop + 35;
|
||||
|
||||
for (i = 0; i < MAX_OBJECTIVES; ++i) {
|
||||
qhandle_t hBoxShader;
|
||||
|
||||
if ((cg.Objectives[i].flags & OBJ_FLAG_HIDDEN) || !cg.Objectives[i].flags) {
|
||||
|
||||
if ((cg.Objectives[i].flags == OBJ_FLAG_NONE) || (cg.Objectives[i].flags & OBJ_FLAG_HIDDEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -789,7 +796,7 @@ void CG_DrawObjectives()
|
||||
cgi.R_SetColor(vColor);
|
||||
cgi.R_DrawStretchPic(fX, fY, 16.0, 16.0, 0.0, 0.0, 1.0, 1.0, hBoxShader);
|
||||
|
||||
fHeight += 25 * iNumLines[i];
|
||||
fHeight += iNumLines[i] * 12 + 25;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -927,6 +934,8 @@ void CG_UpdateAttackerDisplay()
|
||||
|
||||
void CG_UpdateCountdown()
|
||||
{
|
||||
const char* message = "";
|
||||
|
||||
if (!cg.snap) {
|
||||
return;
|
||||
}
|
||||
@@ -937,16 +946,24 @@ void CG_UpdateCountdown()
|
||||
iSecondsLeft = (cgs.matchEndTime - cg.time) / 1000;
|
||||
if (iSecondsLeft >= 0) {
|
||||
iMinutesLeft = iSecondsLeft / 60;
|
||||
cgi.Cvar_Set(
|
||||
"ui_timemessage", va("%s %2i:%02i", cgi.LV_ConvertString("Time Left:"), iMinutesLeft, iSecondsLeft % 60)
|
||||
);
|
||||
message = va("%s %2i:%02i", cgi.LV_ConvertString("Time Left:"), iMinutesLeft, iSecondsLeft % 60);
|
||||
} else if (!cgs.matchEndTime) {
|
||||
cgi.Cvar_Set("ui_timemessage", "");
|
||||
message = "";
|
||||
}
|
||||
} else {
|
||||
// The match has not started yet
|
||||
cgi.Cvar_Set("ui_timemessage", "Waiting For Players");
|
||||
message = "Waiting For Players";
|
||||
}
|
||||
|
||||
if (strcmp(ui_timemessage->string, message)) {
|
||||
cgi.Cvar_Set("ui_timemessage", message);
|
||||
}
|
||||
}
|
||||
|
||||
static void CG_RemoveStopwatch() {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse\n");
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse_wet\n");
|
||||
}
|
||||
|
||||
void CG_DrawStopwatch()
|
||||
@@ -954,38 +971,55 @@ void CG_DrawStopwatch()
|
||||
int iFraction;
|
||||
|
||||
if (!cg_hud->integer) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cgi.stopWatch->iStartTime) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgi.stopWatch->iStartTime >= cgi.stopWatch->iEndTime) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgi.stopWatch->iEndTime <= cg.time) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cg.ObjectivesCurrentAlpha >= 0.02) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cg.snap && cg.snap->ps.stats[STAT_HEALTH] <= 0) {
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
|
||||
CG_RemoveStopwatch();
|
||||
return;
|
||||
}
|
||||
if (cgi.stopWatch->eType >= SWT_FUSE_WET) {
|
||||
iFraction = cgi.stopWatch->iEndTime - cgi.stopWatch->iStartTime;
|
||||
} else {
|
||||
iFraction = cgi.stopWatch->iEndTime - cg.time;
|
||||
}
|
||||
|
||||
iFraction = cgi.stopWatch->iEndTime - cg.time;
|
||||
cgi.Cvar_Set("ui_stopwatch", va("%i", iFraction));
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_stopwatch\n");
|
||||
|
||||
switch (cgi.stopWatch->eType) {
|
||||
case SWT_NORMAL:
|
||||
default:
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_stopwatch\n");
|
||||
break;
|
||||
case SWT_FUSE:
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_fuse\n");
|
||||
break;
|
||||
case SWT_FUSE_WET:
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse\n");
|
||||
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_fuse_wet\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CG_DrawInstantMessageMenu()
|
||||
@@ -1085,7 +1119,7 @@ void CG_DrawSpectatorView_ver_15()
|
||||
char buf[128];
|
||||
|
||||
iClientNum = cg.snap->ps.stats[STAT_INFOCLIENT];
|
||||
sprintf(buf, "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]);
|
||||
Com_sprintf(buf, sizeof(buf), "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]);
|
||||
|
||||
hShader = 0;
|
||||
color[0] = 0.5;
|
||||
@@ -1190,7 +1224,7 @@ void CG_DrawCrosshair()
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cg.snap->ps.pm_flags & PMF_NO_LEAN) || (cg.snap->ps.pm_flags & PMF_INTERMISSION)) {
|
||||
if ((cg.snap->ps.pm_flags & PMF_NO_HUD) || (cg.snap->ps.pm_flags & PMF_INTERMISSION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -503,6 +503,7 @@ extern "C" {
|
||||
extern cvar_t *voiceChat;
|
||||
extern cvar_t *cg_shadowscount;
|
||||
extern cvar_t *cg_shadowdebug;
|
||||
extern cvar_t *ui_timemessage;
|
||||
|
||||
//
|
||||
// cg_main.c
|
||||
@@ -729,8 +730,8 @@ extern "C" {
|
||||
void CG_InitTestTreadMark();
|
||||
void CG_AddTreadMarks();
|
||||
int CG_PermanentMark(
|
||||
const vec3_t origin,
|
||||
const vec3_t dir,
|
||||
vec3_t origin,
|
||||
vec3_t dir,
|
||||
float orientation,
|
||||
float fSScale,
|
||||
float fTScale,
|
||||
@@ -923,7 +924,8 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
|
||||
void CG_InstaMessageGroupD_f(void);
|
||||
void CG_InstaMessageGroupE_f(void);
|
||||
void CG_HudPrint_f(void);
|
||||
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time);
|
||||
|
||||
qboolean CG_CheckCaptureKey(int key, qboolean down, unsigned int time);
|
||||
|
||||
//
|
||||
// cg_vehicle.cpp
|
||||
|
||||
+71
-36
@@ -110,6 +110,7 @@ cvar_t *vm_lean_lower;
|
||||
cvar_t *voiceChat;
|
||||
cvar_t *cg_shadowscount;
|
||||
cvar_t *cg_shadowdebug;
|
||||
cvar_t *ui_timemessage;
|
||||
|
||||
/*
|
||||
=================
|
||||
@@ -197,53 +198,87 @@ void CG_RegisterCvars(void)
|
||||
vm_lean_lower = cgi.Cvar_Get("vm_lean_lower", "0.1", 0);
|
||||
voiceChat = cgi.Cvar_Get("cg_voicechat", "1", 0);
|
||||
|
||||
ui_timemessage = cgi.Cvar_Get("ui_timemessage", "", 0);
|
||||
|
||||
// see if we are also running the server on this machine
|
||||
temp = cgi.Cvar_Get("sv_running", "0", 0);
|
||||
cgs.localServer = temp->integer;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_RegisterSoundsForFile
|
||||
|
||||
Register the specified ubersound source file
|
||||
================
|
||||
*/
|
||||
void CG_RegisterSoundsForFile(const char *name)
|
||||
{
|
||||
int startTime;
|
||||
int endTime;
|
||||
|
||||
Com_Printf("\n\n-----------PARSING '%s'------------\n", name);
|
||||
Com_Printf(
|
||||
"Any SetCurrentTiki errors means that tiki wasn't prefetched and tiki-specific sounds for it won't work. To "
|
||||
"fix prefetch the tiki. Ignore if you don't use that tiki on this level.\n"
|
||||
);
|
||||
|
||||
startTime = cgi.Milliseconds();
|
||||
CG_Command_ProcessFile(name, qfalse, NULL);
|
||||
endTime = cgi.Milliseconds();
|
||||
|
||||
Com_Printf("Parse/Load time: %f seconds.\n", (float)(endTime - startTime) / 1000.0);
|
||||
Com_Printf("-------------PARSING '%s' DONE---------------\n\n", name);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
qsort_compare_strings
|
||||
|
||||
perform case-insensitive sorting
|
||||
=================
|
||||
*/
|
||||
int qsort_compare_strings(const void *s1, const void *s2)
|
||||
{
|
||||
return Q_stricmp(*(const char **)s1, *(const char **)s2);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_RegisterSounds
|
||||
|
||||
called during a precache command
|
||||
Called during a precache command
|
||||
=================
|
||||
*/
|
||||
void CG_RegisterSounds(void)
|
||||
{
|
||||
int startTime;
|
||||
int endTime;
|
||||
char filename[MAX_QPATH];
|
||||
char **fileList;
|
||||
int numFiles;
|
||||
int i;
|
||||
|
||||
Com_Printf("\n\n-----------PARSING UBERSOUND------------\n");
|
||||
Com_Printf(
|
||||
"Any SetCurrentTiki errors means that tiki wasn't prefetched and "
|
||||
"tiki-specific sounds for it won't work. To fix prefe"
|
||||
"tch the tiki. Ignore if you don't use that tiki on this level.\n"
|
||||
);
|
||||
Com_sprintf(filename, sizeof(filename), "ubersound/ubersound.scr");
|
||||
fileList = cgi.FS_ListFilteredFiles("ubersound/", "scr", "*.scr", qfalse, &numFiles, qtrue);
|
||||
if (cg_target_game >= TG_MOHTA) {
|
||||
// Fixed in 2.0
|
||||
// The behavior has changed, all aliases get cleared
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
cgi.Alias_Clear();
|
||||
}
|
||||
} else {
|
||||
if (!cgs.localServer) {
|
||||
cgi.Alias_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
qsort(fileList, numFiles, sizeof(char *), &qsort_compare_strings);
|
||||
|
||||
startTime = cgi.Milliseconds();
|
||||
CG_Command_ProcessFile(filename, 0, 0);
|
||||
endTime = cgi.Milliseconds();
|
||||
for (i = 0; i < numFiles; i++) {
|
||||
// Added in 2.0
|
||||
// Since 2.0, all files in the ubersound folder
|
||||
// are parsed
|
||||
CG_RegisterSoundsForFile(va("ubersound/%s", fileList[i]));
|
||||
}
|
||||
|
||||
Com_Printf("Parse/Load time: %f seconds.\n", (endTime - startTime) / 1000.0f);
|
||||
|
||||
Com_Printf("-------------UBERSOUND DONE---------------\n\n");
|
||||
Com_Printf("\n\n-----------PARSING UBERDIALOG------------\n");
|
||||
Com_Printf(
|
||||
"Any SetCurrentTiki errors means that tiki wasn't prefetched and "
|
||||
"tiki-specific sounds for it won't work. To fix prefe"
|
||||
"tch the tiki. Ignore if you don't use that tiki on this level.\n"
|
||||
);
|
||||
Com_sprintf(filename, sizeof(filename), "ubersound/uberdialog.scr");
|
||||
|
||||
startTime = cgi.Milliseconds();
|
||||
CG_Command_ProcessFile(filename, 0, 0);
|
||||
endTime = cgi.Milliseconds() - startTime;
|
||||
|
||||
Com_Printf("Parse/Load time: %f seconds.\n", endTime / 1000.0f);
|
||||
Com_Printf("-------------UBERDIALOG DONE---------------\n\n");
|
||||
cgi.FS_FreeFileList(fileList);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -338,7 +373,7 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
|
||||
if (cg.rain.numshaders) {
|
||||
// Fixed in OPM
|
||||
// not sure why some maps set a digit at the end...
|
||||
int len = strlen(cg.rain.currentShader);
|
||||
size_t len = strlen(cg.rain.currentShader);
|
||||
if (isdigit(cg.rain.currentShader[len - 1])) {
|
||||
cg.rain.currentShader[len - 1] = 0;
|
||||
}
|
||||
@@ -366,7 +401,7 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
|
||||
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"));
|
||||
Q_strncpyz(objective->text, Info_ValueForKey(str, "text"), sizeof(objective->text));
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
@@ -421,7 +456,7 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
|
||||
if (len) {
|
||||
qboolean streamed;
|
||||
char buf[1024];
|
||||
strcpy(buf, str);
|
||||
Q_strncpyz(buf, str, sizeof(buf));
|
||||
|
||||
streamed = buf[len - 1] != '0';
|
||||
buf[len - 1] = 0;
|
||||
@@ -823,7 +858,7 @@ void Com_Error(int level, const char *error, ...)
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, error);
|
||||
vsprintf(text, error, argptr);
|
||||
Q_vsnprintf(text, sizeof(text), error, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
cgi.Error(level, "%s", text);
|
||||
@@ -835,7 +870,7 @@ void Com_Printf(const char *msg, ...)
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, msg);
|
||||
vsprintf(text, msg, argptr);
|
||||
Q_vsnprintf(text, sizeof(text), msg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
cgi.Printf("%s", text);
|
||||
|
||||
+1165
-276
File diff suppressed because it is too large.
Load diff
+116
-105
@@ -180,6 +180,117 @@ void CG_PlayerTeamIcon(refEntity_t *pModel, entityState_t *pPlayerState)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_InterpolateAnimParms
|
||||
|
||||
Interpolate between current and next entity
|
||||
===============
|
||||
*/
|
||||
void CG_InterpolateAnimParms(entityState_t* state, entityState_t* sNext, refEntity_t* model)
|
||||
{
|
||||
static cvar_t *vmEntity = NULL;
|
||||
int i;
|
||||
float t;
|
||||
float animLength;
|
||||
float t1, t2;
|
||||
|
||||
if (!vmEntity) {
|
||||
vmEntity = cgi.Cvar_Get("viewmodelanim", "1", 0);
|
||||
}
|
||||
|
||||
if (sNext && sNext->usageIndex == state->usageIndex) {
|
||||
t1 = cg.time - cg.snap->serverTime;
|
||||
t2 = cg.nextSnap->serverTime - cg.snap->serverTime;
|
||||
t = t1 / t2;
|
||||
|
||||
model->actionWeight = (sNext->actionWeight - state->actionWeight) * t + state->actionWeight;
|
||||
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
if (sNext->frameInfo[i].weight) {
|
||||
model->frameInfo[i].index = sNext->frameInfo[i].index;
|
||||
if (sNext->frameInfo[i].index == state->frameInfo[i].index && state->frameInfo[i].weight) {
|
||||
model->frameInfo[i].weight =
|
||||
(sNext->frameInfo[i].weight - state->frameInfo[i].weight) * t + state->frameInfo[i].weight;
|
||||
|
||||
if (sNext->frameInfo[i].time >= state->frameInfo[i].time) {
|
||||
model->frameInfo[i].time = (sNext->frameInfo[i].time - state->frameInfo[i].time) * t + state->frameInfo[i].time;
|
||||
} else {
|
||||
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = (animLength + sNext->frameInfo[i].time - state->frameInfo[i].time) * t
|
||||
+ state->frameInfo[i].time;
|
||||
}
|
||||
|
||||
t2 = t1;
|
||||
while (t2 > animLength) {
|
||||
t2 -= animLength;
|
||||
|
||||
if (t2 == t1) {
|
||||
t2 = 1.0;
|
||||
break;
|
||||
}
|
||||
|
||||
t1 = t2;
|
||||
}
|
||||
|
||||
model->frameInfo[i].time = t2;
|
||||
}
|
||||
} else {
|
||||
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = sNext->frameInfo[i].time - (cg.nextSnap->serverTime - cg.time) / 1000.0;
|
||||
}
|
||||
|
||||
model->frameInfo[i].time = Q_max(0, t1);
|
||||
model->frameInfo[i].weight = sNext->frameInfo[i].weight;
|
||||
}
|
||||
} else if (sNext->frameInfo[i].index == state->frameInfo[i].index) {
|
||||
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = (cg.time - cg.snap->serverTime) / 1000.0 + state->frameInfo[i].time;
|
||||
}
|
||||
|
||||
model->frameInfo[i].index = Q_clamp_int(state->frameInfo[i].index, 0, model->tiki->a->num_anims - 1);
|
||||
model->frameInfo[i].time = Q_min(animLength, t1);
|
||||
model->frameInfo[i].weight = (1.0 - t) * state->frameInfo[i].weight;
|
||||
} else {
|
||||
model->frameInfo[i].index = -1;
|
||||
model->frameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no next state, don't blend anims
|
||||
|
||||
model->actionWeight = state->actionWeight;
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
if (state->frameInfo[i].weight) {
|
||||
model->frameInfo[i].index = Q_clamp_int(state->frameInfo[i].index, 0, model->tiki->a->num_anims - 1);
|
||||
model->frameInfo[i].time = state->frameInfo[i].time;
|
||||
model->frameInfo[i].weight = state->frameInfo[i].weight;
|
||||
} else {
|
||||
model->frameInfo[i].index = -1;
|
||||
model->frameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vmEntity->integer == state->number) {
|
||||
static cvar_t *curanim;
|
||||
if (!curanim) {
|
||||
curanim = cgi.Cvar_Get("viewmodelanimslot", "1", 0);
|
||||
}
|
||||
|
||||
cgi.Cvar_Set("viewmodelanimclienttime", va("%0.2f", model->frameInfo[curanim->integer].time));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CastFootShadow
|
||||
@@ -550,7 +661,7 @@ void CG_AnimationDebugMessage(int number, const char *fmt, ...)
|
||||
char msg[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(msg, fmt, argptr);
|
||||
Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
if ((!cg_debugAnimWatch->integer) || ((cg_debugAnimWatch->integer - 1) == number)) {
|
||||
@@ -654,8 +765,8 @@ void CG_UpdateForceModels()
|
||||
pszAlliesPartial = dm_playermodel->string;
|
||||
pszAxisPartial = dm_playergermanmodel->string;
|
||||
|
||||
sprintf(szAlliesModel, "models/player/%s.tik", pszAlliesPartial);
|
||||
sprintf(szAxisModel, "models/player/%s.tik", pszAxisPartial);
|
||||
Com_sprintf(szAlliesModel, sizeof(szAlliesModel), "models/player/%s.tik", pszAlliesPartial);
|
||||
Com_sprintf(szAxisModel, sizeof(szAxisModel), "models/player/%s.tik", pszAxisPartial);
|
||||
hModel = cgi.R_RegisterModel(szAlliesModel);
|
||||
if (!hModel) hModel = cgi.R_RegisterModel("models/player/american_army.tik");
|
||||
|
||||
@@ -697,7 +808,6 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
int i;
|
||||
vec3_t vMins, vMaxs, vTmp;
|
||||
const char *szTagName;
|
||||
static cvar_t *vmEntity = NULL;
|
||||
int iAnimFlags;
|
||||
|
||||
s1 = ¢->currentState;
|
||||
@@ -709,10 +819,6 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
|
||||
memset(&model, 0, sizeof(model));
|
||||
|
||||
if (!vmEntity) {
|
||||
vmEntity = cgi.Cvar_Get("viewmodelanim", "1", 0);
|
||||
}
|
||||
|
||||
if (cent->interpolate) {
|
||||
sNext = ¢->nextState;
|
||||
}
|
||||
@@ -880,103 +986,7 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
model.renderfx |= s1->renderfx;
|
||||
cgi.TIKI_SetEyeTargetPos(model.tiki, model.entityNumber, s1->eyeVector);
|
||||
|
||||
if (sNext && sNext->usageIndex == s1->usageIndex) {
|
||||
float t;
|
||||
float animLength;
|
||||
float t1, t2;
|
||||
|
||||
t1 = cg.time - cg.snap->serverTime;
|
||||
t2 = cg.nextSnap->serverTime - cg.snap->serverTime;
|
||||
t = t1 / t2;
|
||||
model.actionWeight = (sNext->actionWeight - s1->actionWeight) * t + s1->actionWeight;
|
||||
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
if (sNext->frameInfo[i].weight) {
|
||||
model.frameInfo[i].index = sNext->frameInfo[i].index;
|
||||
if (sNext->frameInfo[i].index == s1->frameInfo[i].index && s1->frameInfo[i].weight) {
|
||||
model.frameInfo[i].weight =
|
||||
(sNext->frameInfo[i].weight - s1->frameInfo[i].weight) * t + s1->frameInfo[i].weight;
|
||||
|
||||
if (sNext->frameInfo[i].time >= s1->frameInfo[i].time) {
|
||||
model.frameInfo[i].time =
|
||||
(sNext->frameInfo[i].time - s1->frameInfo[i].time) * t + s1->frameInfo[i].time;
|
||||
} else {
|
||||
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = (animLength + sNext->frameInfo[i].time - s1->frameInfo[i].time) * t
|
||||
+ s1->frameInfo[i].time;
|
||||
}
|
||||
|
||||
t2 = t1;
|
||||
while (t2 > animLength) {
|
||||
t2 -= animLength;
|
||||
}
|
||||
|
||||
model.frameInfo[i].time = t2;
|
||||
}
|
||||
} else {
|
||||
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = sNext->frameInfo[i].time - (cg.nextSnap->serverTime - cg.time) / 1000.0;
|
||||
}
|
||||
|
||||
t2 = t1;
|
||||
if (t2 < 0.0) {
|
||||
t2 = 0.0;
|
||||
}
|
||||
|
||||
model.frameInfo[i].time = t2;
|
||||
model.frameInfo[i].weight = sNext->frameInfo[i].weight;
|
||||
}
|
||||
} else if (sNext->frameInfo[i].index == s1->frameInfo[i].index) {
|
||||
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
|
||||
if (!animLength) {
|
||||
t1 = 0.0;
|
||||
} else {
|
||||
t1 = (cg.time - cg.snap->serverTime) / 1000.0 + s1->frameInfo[i].time;
|
||||
}
|
||||
|
||||
t2 = t1;
|
||||
if (t2 < animLength) {
|
||||
t2 = animLength;
|
||||
}
|
||||
|
||||
model.frameInfo[i].index = s1->frameInfo[i].index;
|
||||
model.frameInfo[i].time = t2;
|
||||
model.frameInfo[i].weight = (1.0 - t) * s1->frameInfo[i].weight;
|
||||
} else {
|
||||
model.frameInfo[i].index = -1;
|
||||
model.frameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no next state, don't blend anims
|
||||
|
||||
model.actionWeight = s1->actionWeight;
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
if (s1->frameInfo[i].weight) {
|
||||
model.frameInfo[i].index = s1->frameInfo[i].index;
|
||||
model.frameInfo[i].time = s1->frameInfo[i].time;
|
||||
model.frameInfo[i].weight = s1->frameInfo[i].weight;
|
||||
} else {
|
||||
model.frameInfo[i].index = -1;
|
||||
model.frameInfo[i].weight = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vmEntity->integer == s1->number) {
|
||||
static cvar_t *curanim;
|
||||
if (!curanim) {
|
||||
curanim = cgi.Cvar_Get("viewmodelanimslot", "1", 0);
|
||||
}
|
||||
|
||||
cgi.Cvar_Set("viewmodelanimclienttime", va("%0.2f", model.frameInfo[curanim->integer].time));
|
||||
}
|
||||
CG_InterpolateAnimParms(s1, sNext, &model);
|
||||
|
||||
if (cent->currentState.parent != ENTITYNUM_NONE) {
|
||||
int iTagNum;
|
||||
@@ -1227,6 +1237,7 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
|
||||
memset(model.surfaces, 0, sizeof(model.surfaces));
|
||||
|
||||
CG_ViewModelAnimation(&model);
|
||||
model.renderfx |= RF_FRAMELERP;
|
||||
cgi.ForceUpdatePose(&model);
|
||||
|
||||
if ((cent->currentState.eFlags & EF_UNARMED) || cg_drawviewmodel->integer <= 1
|
||||
|
||||
@@ -51,7 +51,7 @@ void RainTouch(ctempmodel_t *ct, trace_t *trace)
|
||||
|
||||
void ClientGameCommandManager::RainTouch(Event *ev)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::InitializeRainCvars()
|
||||
@@ -60,7 +60,7 @@ void ClientGameCommandManager::InitializeRainCvars()
|
||||
|
||||
cg_rain = cgi.Cvar_Get("cg_rain", "1", CVAR_ARCHIVE);
|
||||
cg_rain_drawcoverage =
|
||||
cgi.Cvar_Get("cg_rain_drawcoverage", "0", CVAR_SAVEGAME | CVAR_SERVER_CREATED | CVAR_SYSTEMINFO);
|
||||
cgi.Cvar_Get("cg_rain_drawcoverage", "0", CVAR_SAVEGAME | CVAR_RESETSTRING | CVAR_SYSTEMINFO);
|
||||
|
||||
cg.rain.density = 0.0;
|
||||
cg.rain.speed = 2048.0f;
|
||||
|
||||
+96
-37
@@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "cg_local.h"
|
||||
#include "cg_parsemsg.h"
|
||||
#include "cg_specialfx.h"
|
||||
#include "cg_radar.h"
|
||||
|
||||
#include "str.h"
|
||||
|
||||
@@ -426,7 +427,7 @@ static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd, in
|
||||
0,
|
||||
1,
|
||||
1.0,
|
||||
1.0,
|
||||
scale,
|
||||
BEAM_INVERTED,
|
||||
1000.0,
|
||||
iLife,
|
||||
@@ -735,8 +736,14 @@ static void CG_MakeBulletTracerInternal(
|
||||
}
|
||||
|
||||
commandManager.PlaySound("snd_b_zing", vZingPosA, -1, fVolume, -1.0f, fPitch, 1);
|
||||
commandManager.PlaySound("snd_b_zing", vZingPosB, -1, fVolume, -1.0f, fPitch, 1);
|
||||
commandManager.PlaySound("snd_b_zing", vZingPosC, -1, fVolume, -1.0f, fPitch, 1);
|
||||
|
||||
if (fZingDistB != 9999) {
|
||||
commandManager.PlaySound("snd_b_zing", vZingPosB, -1, fVolume, -1.0f, fPitch, 1);
|
||||
|
||||
if (fZingDistC != 9999) {
|
||||
commandManager.PlaySound("snd_b_zing", vZingPosC, -1, fVolume, -1.0f, fPitch, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,7 +873,8 @@ void CG_AddBulletImpacts()
|
||||
fVolume = 0.75f;
|
||||
}
|
||||
|
||||
if (wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_HARD) {
|
||||
if (wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_LITE
|
||||
|| wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_HARD) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
@@ -897,7 +905,8 @@ void CG_AddBulletImpacts()
|
||||
fVolume = 0.75f;
|
||||
}
|
||||
|
||||
if (wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_HARD) {
|
||||
if (wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_LITE
|
||||
|| wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_HARD) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
@@ -952,7 +961,8 @@ void CG_AddBulletImpacts()
|
||||
fVolume = 0.75f;
|
||||
}
|
||||
|
||||
if (wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_HARD) {
|
||||
if (wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_LITE
|
||||
|| wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_HARD) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
@@ -1482,7 +1492,7 @@ void CG_ParseCGMessage_ver_15()
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
cgi.MSG_ReadDir(vEnd);
|
||||
|
||||
sfxManager.MakeEffect_Normal(SFX_EXP_GREN_PUDDLE + iType, vStart, vEnd);
|
||||
sfxManager.MakeEffect_Normal((iType - CGM_MAKE_EFFECT_1) + SFX_OIL_LEAK_BIG, vStart, vEnd);
|
||||
break;
|
||||
|
||||
case CGM_MAKE_CRATE_DEBRIS:
|
||||
@@ -1566,7 +1576,11 @@ void CG_ParseCGMessage_ver_15()
|
||||
|
||||
case CGM_HUDDRAW_SHADER:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].shaderName, cgi.MSG_ReadString());
|
||||
Q_strncpyz(
|
||||
cgi.HudDrawElements[iInfo].shaderName,
|
||||
cgi.MSG_ReadString(),
|
||||
sizeof(cgi.HudDrawElements[iInfo].shaderName)
|
||||
);
|
||||
cgi.HudDrawElements[iInfo].string[0] = 0;
|
||||
cgi.HudDrawElements[iInfo].pFont = NULL;
|
||||
cgi.HudDrawElements[iInfo].fontName[0] = 0;
|
||||
@@ -1608,12 +1622,16 @@ void CG_ParseCGMessage_ver_15()
|
||||
case CGM_HUDDRAW_STRING:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
strcpy(cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString());
|
||||
Q_strncpyz(
|
||||
cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString(), sizeof(cgi.HudDrawElements[iInfo].string)
|
||||
);
|
||||
break;
|
||||
|
||||
case CGM_HUDDRAW_FONT:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString());
|
||||
Q_strncpyz(
|
||||
cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString(), sizeof(cgi.HudDrawElements[iInfo].fontName)
|
||||
);
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
cgi.HudDrawElements[iInfo].shaderName[0] = 0;
|
||||
// load the font
|
||||
@@ -1622,16 +1640,19 @@ void CG_ParseCGMessage_ver_15()
|
||||
|
||||
case CGM_NOTIFY_KILL:
|
||||
case CGM_NOTIFY_HIT:
|
||||
{
|
||||
int iOldEnt;
|
||||
if (cg.snap) {
|
||||
const char *soundName;
|
||||
int iOldEnt;
|
||||
|
||||
iOldEnt = current_entity_number;
|
||||
|
||||
iOldEnt = current_entity_number;
|
||||
current_entity_number = cg.snap->ps.clientNum;
|
||||
if (iType == CGM_NOTIFY_HIT) {
|
||||
commandManager.PlaySound("dm_kill_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
|
||||
soundName = "dm_kill_notify";
|
||||
} else {
|
||||
commandManager.PlaySound("dm_hit_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
|
||||
soundName = "dm_hit_notify";
|
||||
}
|
||||
commandManager.PlaySound(soundName, NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
|
||||
|
||||
current_entity_number = iOldEnt;
|
||||
}
|
||||
@@ -1653,29 +1674,58 @@ void CG_ParseCGMessage_ver_15()
|
||||
if (iLarge) {
|
||||
current_entity_number = iInfo;
|
||||
|
||||
commandManager.PlaySound(szTmp, vStart, CHAN_LOCAL, -1, -1, -1, 0);
|
||||
} else {
|
||||
commandManager.PlaySound(szTmp, vStart, CHAN_AUTO, -1, -1, -1, 0);
|
||||
} else if (cg.snap) {
|
||||
current_entity_number = cg.snap->ps.clientNum;
|
||||
|
||||
commandManager.PlaySound(szTmp, vStart, CHAN_AUTO, -1, -1, -1, 1);
|
||||
commandManager.PlaySound(szTmp, vStart, CHAN_LOCAL, -1, -1, -1, 1);
|
||||
}
|
||||
|
||||
CG_RadarClientSpeaks(iInfo);
|
||||
current_entity_number = iOldEnt;
|
||||
}
|
||||
break;
|
||||
case CGM_FENCEPOST:
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
vEnd[0] = cgi.MSG_ReadCoord();
|
||||
vEnd[1] = cgi.MSG_ReadCoord();
|
||||
vEnd[2] = cgi.MSG_ReadCoord();
|
||||
cgi.MSG_ReadByte();
|
||||
cgi.MSG_ReadByte();
|
||||
VectorSubtract(vEnd, vStart, vTmp);
|
||||
{
|
||||
int iHalf;
|
||||
vec3_t vForward, vRight, vUp;
|
||||
float fLength;
|
||||
|
||||
// FIXME: unimplemented
|
||||
// ?? can't figure out what is this
|
||||
vStart[0] = cgi.MSG_ReadCoord();
|
||||
vStart[1] = cgi.MSG_ReadCoord();
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
vEnd[0] = cgi.MSG_ReadCoord();
|
||||
vEnd[1] = cgi.MSG_ReadCoord();
|
||||
vEnd[2] = cgi.MSG_ReadCoord();
|
||||
iHalf = cgi.MSG_ReadByte();
|
||||
cgi.MSG_ReadByte();
|
||||
|
||||
VectorSubtract(vEnd, vStart, vForward);
|
||||
fLength = VectorNormalize(vForward);
|
||||
iCount = fLength / 2.0;
|
||||
|
||||
MakeNormalVectors(vForward, vRight, vUp);
|
||||
|
||||
for (i = 0; i < iCount; i++) {
|
||||
vec3_t vOrg;
|
||||
vec3_t vNormal;
|
||||
|
||||
VectorCopy(vStart, vOrg);
|
||||
|
||||
VectorMA(vOrg, random(), vForward, vOrg);
|
||||
VectorMA(vOrg, crandom() * iHalf, vRight, vOrg);
|
||||
VectorMA(vOrg, crandom() * iHalf, vUp, vOrg);
|
||||
|
||||
//
|
||||
// Spawn the fence wood effect
|
||||
//
|
||||
|
||||
VectorSubtract(vStart, vOrg, vNormal);
|
||||
VectorNormalize(vNormal);
|
||||
|
||||
sfxManager.MakeEffect_Normal(SFX_FENCE_WOOD, vOrg, vNormal);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cgi.Error(ERR_DROP, "CG_ParseCGMessage: Unknown CGM message type");
|
||||
@@ -1853,7 +1903,7 @@ void CG_ParseCGMessage_ver_6()
|
||||
vStart[2] = cgi.MSG_ReadCoord();
|
||||
cgi.MSG_ReadDir(vEnd);
|
||||
|
||||
sfxManager.MakeEffect_Normal(SFX_EXP_GREN_PUDDLE + iType, vStart, vEnd);
|
||||
sfxManager.MakeEffect_Normal((iType - CGM6_MAKE_EFFECT_1) + SFX_OIL_LEAK_BIG, vStart, vEnd);
|
||||
break;
|
||||
|
||||
case CGM6_MAKE_CRATE_DEBRIS:
|
||||
@@ -1917,7 +1967,11 @@ void CG_ParseCGMessage_ver_6()
|
||||
|
||||
case CGM6_HUDDRAW_SHADER:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].shaderName, cgi.MSG_ReadString());
|
||||
Q_strncpyz(
|
||||
cgi.HudDrawElements[iInfo].shaderName,
|
||||
cgi.MSG_ReadString(),
|
||||
sizeof(cgi.HudDrawElements[iInfo].shaderName)
|
||||
);
|
||||
cgi.HudDrawElements[iInfo].string[0] = 0;
|
||||
cgi.HudDrawElements[iInfo].pFont = NULL;
|
||||
cgi.HudDrawElements[iInfo].fontName[0] = 0;
|
||||
@@ -1959,12 +2013,16 @@ void CG_ParseCGMessage_ver_6()
|
||||
case CGM6_HUDDRAW_STRING:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
strcpy(cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString());
|
||||
Q_strncpyz(
|
||||
cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString(), sizeof(cgi.HudDrawElements[iInfo].string)
|
||||
);
|
||||
break;
|
||||
|
||||
case CGM6_HUDDRAW_FONT:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
strcpy(cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString());
|
||||
Q_strncpyz(
|
||||
cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString(), sizeof(cgi.HudDrawElements[iInfo].fontName)
|
||||
);
|
||||
cgi.HudDrawElements[iInfo].hShader = 0;
|
||||
cgi.HudDrawElements[iInfo].shaderName[0] = 0;
|
||||
// load the font
|
||||
@@ -1973,10 +2031,11 @@ void CG_ParseCGMessage_ver_6()
|
||||
|
||||
case CGM6_NOTIFY_KILL:
|
||||
case CGM6_NOTIFY_HIT:
|
||||
{
|
||||
if (cg.snap) {
|
||||
int iOldEnt;
|
||||
|
||||
iOldEnt = current_entity_number;
|
||||
iOldEnt = current_entity_number;
|
||||
|
||||
current_entity_number = cg.snap->ps.clientNum;
|
||||
if (iType == CGM6_NOTIFY_HIT) {
|
||||
commandManager.PlaySound("dm_kill_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
|
||||
@@ -2005,10 +2064,10 @@ void CG_ParseCGMessage_ver_6()
|
||||
current_entity_number = iInfo;
|
||||
|
||||
commandManager.PlaySound(szTmp, vStart, CHAN_LOCAL, -1, -1, -1, 0);
|
||||
} else {
|
||||
} else if (cg.snap) {
|
||||
current_entity_number = cg.snap->ps.clientNum;
|
||||
|
||||
commandManager.PlaySound(szTmp, vStart, CHAN_AUTO, -1, -1, -1, 1);
|
||||
commandManager.PlaySound(szTmp, vStart, CHAN_LOCAL, -1, -1, -1, 1);
|
||||
}
|
||||
|
||||
current_entity_number = iOldEnt;
|
||||
|
||||
+20
-3
@@ -190,8 +190,9 @@ void CG_ShowTrace(trace_t *trace, int passent, const char *reason)
|
||||
assert(reason);
|
||||
assert(trace);
|
||||
|
||||
sprintf(
|
||||
Com_sprintf(
|
||||
text,
|
||||
sizeof(text),
|
||||
"%0.2f : Pass (%d) Frac %f Hit (%d): '%s'\n",
|
||||
(float)cg.time / 1000.0f,
|
||||
passent,
|
||||
@@ -349,6 +350,13 @@ static void CG_InterpolatePlayerStateCamera(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// Added in 2.0
|
||||
if (cg.predicted_player_state.camera_flags & CF_CAMERA_ANGLES_TURRETMODE) {
|
||||
VectorCopy(cg.nextSnap->ps.camera_origin, cg.camera_origin);
|
||||
VectorCopy(cg.nextSnap->ps.camera_angles, cg.camera_angles);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
cg.camera_origin[i] = prev->ps.camera_origin[i] + f * (next->ps.camera_origin[i] - prev->ps.camera_origin[i]);
|
||||
cg.camera_angles[i] = LerpAngle(prev->ps.camera_angles[i], next->ps.camera_angles[i], f);
|
||||
@@ -493,8 +501,13 @@ void CG_PredictPlayerState(void)
|
||||
cg_pmove.leanSpeed = 2.f;
|
||||
} else {
|
||||
cg_pmove.alwaysAllowLean = qtrue;
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
cg_pmove.leanMax = 40.f;
|
||||
} else {
|
||||
// Don't allow lean in single-player, like in the original game
|
||||
cg_pmove.leanMax = 0;
|
||||
}
|
||||
|
||||
cg_pmove.leanMax = 40.f;
|
||||
cg_pmove.leanAdd = 10.f;
|
||||
cg_pmove.leanRecoverSpeed = 15.f;
|
||||
cg_pmove.leanSpeed = 4.f;
|
||||
@@ -515,7 +528,11 @@ void CG_PredictPlayerState(void)
|
||||
// the server time is beyond our current cg.time,
|
||||
// because predicted player positions are going to
|
||||
// be ahead of everything else anyway
|
||||
if (cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport) {
|
||||
// Added in OPM: prediction check
|
||||
// Don't use the next snapshot if the prediction is about to be disabled
|
||||
// this prevent "blinking" issues like when entering a vehicle turret gun
|
||||
// where arms would be seen shortly
|
||||
if (cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport && !(cg.nextSnap->ps.pm_flags & PMF_NO_PREDICTION)) {
|
||||
cg.predicted_player_state = cg.nextSnap->ps;
|
||||
cg.physicsTime = cg.nextSnap->serverTime;
|
||||
} else {
|
||||
|
||||
@@ -120,6 +120,7 @@ functions exported to the main executable
|
||||
|
||||
// console variable interaction
|
||||
cvar_t *(*Cvar_Get)(const char *var_name, const char *value, int flags);
|
||||
cvar_t *(*Cvar_Find)(const char *var_name);
|
||||
void (*Cvar_Set)(const char *var_name, const char *value);
|
||||
|
||||
// ClientCommand and ConsoleCommand parameter access
|
||||
@@ -360,6 +361,8 @@ functions exported to the main executable
|
||||
void (*UI_ShowMenu)(const char *name, qboolean bForce);
|
||||
void (*UI_HideMenu)(const char *name, qboolean bForce);
|
||||
int (*UI_FontStringWidth)(fontheader_t *font, const char *string, int maxLen);
|
||||
// Added in 2.0
|
||||
float (*UI_GetObjectivesTop)(void);
|
||||
|
||||
int (*Key_StringToKeynum)(const char *str);
|
||||
const char *(*Key_KeynumToBindString)(int keyNum);
|
||||
@@ -465,8 +468,8 @@ functions exported to the main executable
|
||||
int (*CG_GetParent)(int entNum);
|
||||
float (*CG_GetObjectiveAlpha)();
|
||||
int (*CG_PermanentMark)(
|
||||
const vec3_t origin,
|
||||
const vec3_t dir,
|
||||
vec3_t origin,
|
||||
vec3_t dir,
|
||||
float orientation,
|
||||
float sScale,
|
||||
float tScale,
|
||||
|
||||
@@ -58,19 +58,19 @@ void CG_PrepScoreBoardInfo()
|
||||
{
|
||||
switch (cgs.gametype) {
|
||||
case GT_TEAM_ROUNDS:
|
||||
strcpy(cg.scoresMenuName, "DM_Round_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "DM_Round_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
case GT_OBJECTIVE:
|
||||
strcpy(cg.scoresMenuName, "Obj_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "Obj_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
case GT_TOW:
|
||||
strcpy(cg.scoresMenuName, "Tow_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "Tow_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
case GT_LIBERATION:
|
||||
strcpy(cg.scoresMenuName, "Lib_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "Lib_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
default:
|
||||
strcpy(cg.scoresMenuName, "DM_Scoreboard");
|
||||
Q_strncpyz(cg.scoresMenuName, "DM_Scoreboard", sizeof(cg.scoresMenuName));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -296,14 +296,15 @@ void CG_ParseScores_ver_15()
|
||||
|
||||
switch (iClientTeam) {
|
||||
case 1:
|
||||
strcpy(szString3, cgi.LV_ConvertString("Spectators"));
|
||||
Q_strncpyz(szString3, cgi.LV_ConvertString("Spectators"), sizeof(szString3));
|
||||
break;
|
||||
case 2:
|
||||
strcpy(szString3, cgi.LV_ConvertString("Free-For-Allers"));
|
||||
Q_strncpyz(szString3, cgi.LV_ConvertString("Free-For-Allers"), sizeof(szString3));
|
||||
break;
|
||||
case 3:
|
||||
sprintf(
|
||||
Com_sprintf(
|
||||
szString3,
|
||||
sizeof(szString3),
|
||||
"%s - %d %s",
|
||||
cgi.LV_ConvertString("Allies"),
|
||||
atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)),
|
||||
@@ -312,8 +313,9 @@ void CG_ParseScores_ver_15()
|
||||
iCurrentEntry++;
|
||||
break;
|
||||
case 4:
|
||||
sprintf(
|
||||
Com_sprintf(
|
||||
szString3,
|
||||
sizeof(szString3),
|
||||
"%s - %d %s",
|
||||
cgi.LV_ConvertString("Axis"),
|
||||
atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)),
|
||||
@@ -322,7 +324,7 @@ void CG_ParseScores_ver_15()
|
||||
iCurrentEntry++;
|
||||
break;
|
||||
default:
|
||||
strcpy(szString3, cgi.LV_ConvertString("No Team"));
|
||||
Q_strncpyz(szString3, cgi.LV_ConvertString("No Team"), sizeof(szString3));
|
||||
break;
|
||||
}
|
||||
} else if (iClientNum == -2) {
|
||||
@@ -330,14 +332,14 @@ void CG_ParseScores_ver_15()
|
||||
szString2[0] = 0;
|
||||
szString3[0] = 0;
|
||||
} else {
|
||||
strcpy(szString2, va("%i", iClientNum));
|
||||
strcpy(szString3, cg.clientinfo[iClientNum].name);
|
||||
Q_strncpyz(szString2, va("%i", iClientNum), sizeof(szString2));
|
||||
Q_strncpyz(szString3, cg.clientinfo[iClientNum].name, sizeof(szString3));
|
||||
}
|
||||
|
||||
strcpy(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString7, cgi.Argv(5 + iCurrentEntry + iDatumCount * i));
|
||||
Q_strncpyz(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
|
||||
Q_strncpyz(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
|
||||
Q_strncpyz(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
|
||||
Q_strncpyz(szString7, cgi.Argv(5 + iCurrentEntry + iDatumCount * i), sizeof(szString7));
|
||||
|
||||
if (cgs.gametype >= GT_TEAM_ROUNDS && iClientNum == -1
|
||||
&& (iClientTeam == TEAM_ALLIES || iClientTeam == TEAM_AXIS)) {
|
||||
@@ -370,19 +372,19 @@ void CG_ParseScores_ver_15()
|
||||
} else {
|
||||
iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i));
|
||||
if (iClientNum >= 0) {
|
||||
strcpy(szString2, va("%i", iClientNum));
|
||||
strcpy(szString3, cg.clientinfo[iClientNum].name);
|
||||
strcpy(szString4, cgi.Argv(1 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString5, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString6, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString7, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
|
||||
Q_strncpyz(szString2, va("%i", iClientNum), sizeof(szString2));
|
||||
Q_strncpyz(szString3, cg.clientinfo[iClientNum].name, sizeof(szString3));
|
||||
Q_strncpyz(szString4, cgi.Argv(1 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
|
||||
Q_strncpyz(szString5, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
|
||||
Q_strncpyz(szString6, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
|
||||
Q_strncpyz(szString7, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString7));
|
||||
} else {
|
||||
szString2[0] = 0;
|
||||
if (iClientNum == -3) {
|
||||
strcpy(szString2, cgi.LV_ConvertString("Players"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Players"), sizeof(szString2));
|
||||
bIsHeader = qtrue;
|
||||
} else if (iClientNum == -2) {
|
||||
strcpy(szString2, cgi.LV_ConvertString("Spectators"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
|
||||
bIsHeader = qtrue;
|
||||
} else {
|
||||
// unknown
|
||||
@@ -535,32 +537,32 @@ void CG_ParseScores_ver_6()
|
||||
|
||||
switch (iClientTeam) {
|
||||
case 1:
|
||||
strcpy(szString2, cgi.LV_ConvertString("Spectators"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
|
||||
break;
|
||||
case 2:
|
||||
strcpy(szString2, cgi.LV_ConvertString("Free-For-Allers"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Free-For-Allers"), sizeof(szString2));
|
||||
break;
|
||||
case 3:
|
||||
strcpy(szString2, cgi.LV_ConvertString("Allies"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Allies"), sizeof(szString2));
|
||||
break;
|
||||
case 4:
|
||||
strcpy(szString2, cgi.LV_ConvertString("Axis"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Axis"), sizeof(szString2));
|
||||
break;
|
||||
default:
|
||||
strcpy(szString2, cgi.LV_ConvertString("No Team"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("No Team"), sizeof(szString2));
|
||||
break;
|
||||
}
|
||||
} else if (iClientNum == -2) {
|
||||
// spectating
|
||||
szString2[0] = 0;
|
||||
} else {
|
||||
strcpy(szString2, cg.clientinfo[iClientNum].name);
|
||||
Q_strncpyz(szString2, cg.clientinfo[iClientNum].name, sizeof(szString2));
|
||||
}
|
||||
|
||||
strcpy(szString3, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString4, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString5, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString6, cgi.Argv(5 + iCurrentEntry + iDatumCount * i));
|
||||
Q_strncpyz(szString3, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString3));
|
||||
Q_strncpyz(szString4, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
|
||||
Q_strncpyz(szString5, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
|
||||
Q_strncpyz(szString6, cgi.Argv(5 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
|
||||
|
||||
if (iClientNum == cg.snap->ps.clientNum) {
|
||||
pItemTextColor = vThisClientTextColor;
|
||||
@@ -587,17 +589,17 @@ void CG_ParseScores_ver_6()
|
||||
} else {
|
||||
iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i));
|
||||
if (iClientNum >= 0) {
|
||||
strcpy(szString2, cg.clientinfo[iClientNum].name);
|
||||
strcpy(szString3, cgi.Argv(1 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
|
||||
strcpy(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
|
||||
Q_strncpyz(szString2, cg.clientinfo[iClientNum].name, sizeof(szString2));
|
||||
Q_strncpyz(szString3, cgi.Argv(1 + iCurrentEntry + iDatumCount * i), sizeof(szString3));
|
||||
Q_strncpyz(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
|
||||
Q_strncpyz(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
|
||||
Q_strncpyz(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
|
||||
} else {
|
||||
if (iClientNum == -3) {
|
||||
strcpy(szString2, cgi.LV_ConvertString("Players"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Players"), sizeof(szString2));
|
||||
bIsHeader = qtrue;
|
||||
} else if (iClientNum == -2) {
|
||||
strcpy(szString2, cgi.LV_ConvertString("Spectators"));
|
||||
Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
|
||||
bIsHeader = qtrue;
|
||||
} else {
|
||||
// unknown
|
||||
|
||||
+263
-8
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2008-2024 the OpenMoHAA team
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -26,11 +27,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "cg_local.h"
|
||||
#include "../fgame/bg_voteoptions.h"
|
||||
|
||||
static qboolean CG_IsStatementFiltered(char *cmd);
|
||||
|
||||
/*
|
||||
================
|
||||
IsWeaponAllowed
|
||||
|
||||
Returns true if the weapon is allowed
|
||||
================
|
||||
*/
|
||||
static const char *IsWeaponAllowed(int dmFlags, int flags)
|
||||
{
|
||||
return (dmFlags & flags) ? "0" : "1";
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
QueryLandminesAllowed2
|
||||
|
||||
Returns true if landmines is allowed by the map or by a dm flag
|
||||
================
|
||||
*/
|
||||
static qboolean QueryLandminesAllowed2(const char *mapname, int dmflags)
|
||||
{
|
||||
if (dmflags & DF_WEAPON_NO_LANDMINE) {
|
||||
@@ -134,6 +151,7 @@ void CG_ParseServerinfo(void)
|
||||
cgi.Cvar_Set("cg_fraglimit", Info_ValueForKey(info, "fraglimit"));
|
||||
cgi.Cvar_Set("cg_timelimit", Info_ValueForKey(info, "timelimit"));
|
||||
cgi.Cvar_Set("cg_maxclients", Info_ValueForKey(info, "sv_gametype"));
|
||||
cgi.Cvar_Set("cg_allowvote", Info_ValueForKey(info, "g_allowvote"));
|
||||
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"));
|
||||
@@ -148,10 +166,10 @@ void CG_ParseServerinfo(void)
|
||||
cgi.Cvar_Set("cg_scoreboardpicover", Info_ValueForKey(info, "g_scoreboardpicover"));
|
||||
mapChecksumStr = Info_ValueForKey(info, "sv_mapChecksum");
|
||||
if (mapChecksumStr && mapChecksumStr[0]) {
|
||||
cgs.mapChecksum = atoi(mapChecksumStr);
|
||||
cgs.mapChecksum = atoi(mapChecksumStr);
|
||||
cgs.useMapChecksum = qtrue;
|
||||
} else {
|
||||
cgs.mapChecksum = 0;
|
||||
cgs.mapChecksum = 0;
|
||||
cgs.useMapChecksum = qfalse;
|
||||
}
|
||||
|
||||
@@ -169,7 +187,7 @@ void CG_ParseServerinfo(void)
|
||||
if (spawnpos) {
|
||||
Q_strncpyz(map, mapname, spawnpos - mapname + 1);
|
||||
} else {
|
||||
strcpy(map, mapname);
|
||||
Q_strncpyz(map, mapname, sizeof(map));
|
||||
}
|
||||
|
||||
Com_sprintf(cgs.mapname, sizeof(cgs.mapname), "maps/%s.bsp", map);
|
||||
@@ -311,12 +329,12 @@ static void CG_ServerCommand(qboolean modelOnly)
|
||||
}
|
||||
return;
|
||||
} else if (!strcmp(cmd, "printdeathmsg")) {
|
||||
const char *s1, *s2, * attackerName, * victimName, *type;
|
||||
const char *s1, *s2, *attackerName, *victimName, *type;
|
||||
const char *result1, *result2;
|
||||
int hudColor;
|
||||
|
||||
result1 = NULL;
|
||||
result2 = NULL;
|
||||
result1 = NULL;
|
||||
result2 = NULL;
|
||||
s1 = cgi.Argv(1);
|
||||
s2 = cgi.Argv(2);
|
||||
attackerName = cgi.Argv(3);
|
||||
@@ -352,7 +370,14 @@ static void CG_ServerCommand(qboolean modelOnly)
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "stufftext")) {
|
||||
cgi.Cmd_Stuff(cgi.Argv(1));
|
||||
char *cmd = cgi.Argv(1);
|
||||
if (CG_IsStatementFiltered(cmd)) {
|
||||
// Added in OPM
|
||||
// Don't execute filtered commands
|
||||
return;
|
||||
}
|
||||
|
||||
cgi.Cmd_Stuff(cmd);
|
||||
cgi.Cmd_Stuff("\n");
|
||||
return;
|
||||
}
|
||||
@@ -429,3 +454,233 @@ void CG_ExecuteNewServerCommands(int latestSequence, qboolean differentServer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// List of client variables allowed to be changed by the server
|
||||
//
|
||||
static const char *whiteListedVariables[] = {
|
||||
"r_fastsky", // some mods set this variable to make the sky uniform
|
||||
"ui_hud",
|
||||
};
|
||||
|
||||
//
|
||||
// List of client variables allowed to be changed by the server
|
||||
//
|
||||
static const char *whiteListedLocalServerVariables[] = {"ui_hidemouse", "ui_showmouse", "cg_marks_add"};
|
||||
|
||||
//
|
||||
// List of commands allowed to be executed by the server
|
||||
//
|
||||
static const char *whiteListedCommands[] = {
|
||||
"primarydmweapon",
|
||||
"pushmenu",
|
||||
"pushmenu_teamselect",
|
||||
"pushmenu_weaponselect",
|
||||
"popmenu",
|
||||
"wait",
|
||||
"globalwidgetcommand", // used for mods adding custom HUDs
|
||||
"ui_addhud",
|
||||
"ui_removehud",
|
||||
"tmstart",
|
||||
"tmstartloop",
|
||||
"tmstop",
|
||||
"tmvolume",
|
||||
"`stufftext",
|
||||
"+moveup", // workaround for mods that want to prevent inactivity when handling the spectate
|
||||
"-moveup",
|
||||
"screenshot",
|
||||
"screenshotJPEG",
|
||||
"levelshot"
|
||||
};
|
||||
|
||||
//
|
||||
// List of commands allowed to be executed by the server
|
||||
//
|
||||
static const char *whiteListedLocalServerCommands[] = {
|
||||
"spmap", // Used by briefings
|
||||
"map",
|
||||
"disconnect",
|
||||
"cinematic",
|
||||
"showmenu",
|
||||
"hidemenu"
|
||||
};
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_IsVariableFiltered
|
||||
|
||||
Returns whether or not the variable should be filtered
|
||||
====================
|
||||
*/
|
||||
static qboolean CG_IsVariableFiltered(const char *name)
|
||||
{
|
||||
cvar_t *var;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(whiteListedVariables); i++) {
|
||||
if (!Q_stricmp(name, whiteListedVariables[i])) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
if (cgs.localServer) {
|
||||
for (i = 0; i < ARRAY_LEN(whiteListedLocalServerVariables); i++) {
|
||||
if (!Q_stricmp(name, whiteListedLocalServerVariables[i])) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filtered
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_IsSetVariableFiltered
|
||||
|
||||
Returns whether or not the variable should be filtered
|
||||
====================
|
||||
*/
|
||||
static qboolean CG_IsSetVariableFiltered(const char *name, char type)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
if (!CG_IsVariableFiltered(name)) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (type != 'u' && type != 's') {
|
||||
// Don't allow custom info variables to avoid flooding
|
||||
// the client with many serverinfo and userinfo variables
|
||||
|
||||
var = cgi.Cvar_Find(name);
|
||||
if (!var) {
|
||||
// Allow as it doesn't exist
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (var->flags & CVAR_USER_CREATED) {
|
||||
// Allow, it's user-created, wouldn't cause issues
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
// Filtered
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_IsCommandFiltered
|
||||
|
||||
Returns whether or not the variable should be filtered
|
||||
====================
|
||||
*/
|
||||
static qboolean CG_IsCommandFiltered(const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(whiteListedCommands); i++) {
|
||||
if (!Q_stricmp(name, whiteListedCommands[i])) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
if (cgs.localServer) {
|
||||
// Allow more commands when the client is hosting the server
|
||||
// Mostly used on single-player mode, like when briefings switch to the next map
|
||||
for (i = 0; i < ARRAY_LEN(whiteListedLocalServerCommands); i++) {
|
||||
if (!Q_stricmp(name, whiteListedLocalServerCommands[i])) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Test variables
|
||||
//
|
||||
return CG_IsVariableFiltered(name);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
RemoveEndToken
|
||||
====================
|
||||
*/
|
||||
static qboolean RemoveEndToken(char* com_token) {
|
||||
char* p;
|
||||
|
||||
for (p = com_token; p[0]; p++) {
|
||||
if (*p == ';') {
|
||||
*p = 0;
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_IsStatementFiltered
|
||||
|
||||
Returns whether or not the statement is filtered
|
||||
====================
|
||||
*/
|
||||
static qboolean CG_IsStatementFiltered(char *cmd)
|
||||
{
|
||||
char* parsed;
|
||||
char* p;
|
||||
char com_token[256];
|
||||
qboolean bNextStatement = qfalse;
|
||||
|
||||
parsed = cmd;
|
||||
|
||||
for (Q_strncpyz(com_token, COM_ParseExt(&parsed, qtrue), sizeof(com_token)); com_token[0]; Q_strncpyz(com_token, COM_ParseExt(&parsed, qtrue), sizeof(com_token))) {
|
||||
bNextStatement = RemoveEndToken(com_token);
|
||||
|
||||
if (com_token[0] == ';') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(com_token, "set") || !Q_stricmp(com_token, "setu") || !Q_stricmp(com_token, "seta")
|
||||
|| !Q_stricmp(com_token, "sets")) {
|
||||
char type = com_token[3];
|
||||
|
||||
//
|
||||
// variable
|
||||
//
|
||||
Q_strncpyz(com_token, COM_ParseExt(&parsed, qfalse), sizeof(com_token));
|
||||
bNextStatement |= RemoveEndToken(com_token);
|
||||
if (com_token[0] == ';') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CG_IsSetVariableFiltered(com_token, type)) {
|
||||
return qtrue;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// normal command
|
||||
//
|
||||
if (CG_IsCommandFiltered(com_token)) {
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bNextStatement) {
|
||||
// Skip up to the next statement
|
||||
while (parsed && parsed[0]) {
|
||||
char c = parsed[0];
|
||||
|
||||
parsed++;
|
||||
if (c == '\n' || c == ';') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
@@ -73,10 +73,10 @@ static void CG_ResetEntity(centity_t *cent)
|
||||
CG_RemoveClientEntity(cent->currentState.number, tiki, cent);
|
||||
|
||||
// reset the animation for the entities
|
||||
if (tiki && tiki->a->bIsCharacter) {
|
||||
if (tiki) {
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
cent->animLast[i] = cent->currentState.frameInfo[i].index;
|
||||
cent->animLastTimes[i] = cent->currentState.frameInfo[i].time;
|
||||
cent->animLast[i] = -1;
|
||||
cent->animLastTimes[i] = -1;
|
||||
if (cent->currentState.frameInfo[i].weight) {
|
||||
cent->animLastWeight |= 1 << i;
|
||||
} else {
|
||||
@@ -87,7 +87,8 @@ static void CG_ResetEntity(centity_t *cent)
|
||||
} else {
|
||||
// clear all the last animations
|
||||
for (i = 0; i < MAX_FRAMEINFOS; i++) {
|
||||
cent->animLast[i] = -1;
|
||||
cent->animLast[i] = -1;
|
||||
cent->animLastTimes[i] = 0.0;
|
||||
}
|
||||
|
||||
cent->animLastWeight = 0;
|
||||
@@ -346,8 +347,10 @@ static snapshot_t *CG_ReadNextSnapshot(void)
|
||||
snapshot_t *dest;
|
||||
|
||||
if (cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000) {
|
||||
cgi.Error(
|
||||
ERR_DROP, "CG_ReadNextSnapshot: way out of range, %i > %i", cg.latestSnapshotNum, cgs.processedSnapshotNum
|
||||
cgi.Printf(
|
||||
"WARNING: CG_ReadNextSnapshot: way out of range, %i > %i\n",
|
||||
cg.latestSnapshotNum,
|
||||
cgs.processedSnapshotNum
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ void ClientSpecialEffectsManager::LoadEffects()
|
||||
cgi.DPrintf("Loading Special Effects...\n");
|
||||
AxisClear(axis);
|
||||
|
||||
for (i = 0; i < MAX_SPECIAL_EFFECTS; i++) {
|
||||
for (i = 0; i < SFX_COUNT; i++) {
|
||||
switch (i) {
|
||||
case SFX_BHIT_PAPER_LITE:
|
||||
szEffectModel = "models/fx/bh_paper_lite.tik";
|
||||
@@ -512,7 +512,7 @@ void ClientSpecialEffectsManager::ExecuteEffect(
|
||||
current_tiki = NULL;
|
||||
|
||||
pCommand->emitter->cgd.origin = vPos;
|
||||
if (pCommand->emitter->cgd.flags & T_ANGLES) {
|
||||
if (!(pCommand->emitter->cgd.flags & T_ANGLES)) {
|
||||
pCommand->emitter->cgd.angles = vAngles;
|
||||
}
|
||||
|
||||
@@ -1194,5 +1194,5 @@ qboolean ClientSpecialEffectsManager::EffectsPending()
|
||||
|
||||
specialeffect_t *ClientSpecialEffectsManager::GetTestEffectPointer()
|
||||
{
|
||||
return &m_effects[SPECIAL_EFFECT_TEST];
|
||||
return &m_effects[SFX_TEST_EFFECT];
|
||||
}
|
||||
@@ -170,12 +170,9 @@ public:
|
||||
specialeffectcommand_t *AddNewCommand();
|
||||
};
|
||||
|
||||
#define MAX_SPECIAL_EFFECTS 99
|
||||
#define SPECIAL_EFFECT_TEST MAX_SPECIAL_EFFECTS - 1
|
||||
|
||||
class ClientSpecialEffectsManager : public Listener
|
||||
{
|
||||
specialeffect_t m_effects[99];
|
||||
specialeffect_t m_effects[SFX_COUNT];
|
||||
qboolean m_bEffectsLoaded;
|
||||
int m_iNumPendingEvents;
|
||||
|
||||
|
||||
@@ -79,6 +79,11 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
|
||||
|
||||
RemoveClientEntity(p->number, p->cgd.tiki, NULL, p);
|
||||
|
||||
if (m_active_tempmodels.next == p) {
|
||||
// use the next active temp model
|
||||
m_active_tempmodels.next = p->next;
|
||||
}
|
||||
|
||||
// remove from the doubly linked active list
|
||||
p->prev->next = p->next;
|
||||
p->next->prev = p->prev;
|
||||
@@ -86,6 +91,22 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
|
||||
// the free list is only singly linked
|
||||
p->next = m_free_tempmodels;
|
||||
m_free_tempmodels = p;
|
||||
|
||||
if (p->m_spawnthing) {
|
||||
p->m_spawnthing->numtempmodels--;
|
||||
// delete unused spawnthings
|
||||
if (!p->m_spawnthing->numtempmodels) {
|
||||
m_emitters.RemoveObject(p->m_spawnthing);
|
||||
|
||||
if (p->m_spawnthing == m_spawnthing) {
|
||||
m_spawnthing = NULL;
|
||||
}
|
||||
|
||||
delete p->m_spawnthing;
|
||||
}
|
||||
|
||||
p->m_spawnthing = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
@@ -418,9 +439,11 @@ qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, flo
|
||||
|
||||
p->ent.shaderRGBA[0] = (int)((float)tempColor[0] * vLighting[0]);
|
||||
p->ent.shaderRGBA[1] = (int)((float)tempColor[1] * vLighting[1]);
|
||||
p->ent.shaderRGBA[2] = (int)((float)tempColor[2] * vLighting[2]);
|
||||
} else {
|
||||
p->ent.shaderRGBA[0] = tempColor[0];
|
||||
p->ent.shaderRGBA[1] = tempColor[1];
|
||||
p->ent.shaderRGBA[2] = tempColor[2];
|
||||
}
|
||||
|
||||
if (p->cgd.flags & T_FADEIN && (fadein < 1)) // Do the fadein effect
|
||||
@@ -518,6 +541,7 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
Vector tempangles;
|
||||
trace_t trace;
|
||||
float dot;
|
||||
int i;
|
||||
|
||||
VectorCopy(p->ent.origin, p->lastEnt.origin);
|
||||
AxisCopy(p->ent.axis, p->lastEnt.axis);
|
||||
@@ -633,9 +657,7 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
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) {
|
||||
} else if (p->cgd.flags2 & T2_CLAMP_VEL_AXIS) {
|
||||
Vector localVelocity;
|
||||
localVelocity.x = DotProduct(p->cgd.velocity, p->ent.axis[0]);
|
||||
localVelocity.y = DotProduct(p->cgd.velocity, p->ent.axis[1]);
|
||||
@@ -650,8 +672,48 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
p->cgd.velocity.z = DotProduct(localVelocity, p->ent.axis[2]);
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T_ALIGN) {
|
||||
// FIXME: vss wind
|
||||
if (p->cgd.flags2 & T2_WIND_AFFECT) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
float fWind;
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
fWind = vss_wind_x->value;
|
||||
break;
|
||||
case 1:
|
||||
fWind = vss_wind_y->value;
|
||||
break;
|
||||
case 2:
|
||||
fWind = vss_wind_z->value;
|
||||
break;
|
||||
}
|
||||
|
||||
if (fWind < 0) {
|
||||
if (p->cgd.velocity[i] > fWind) {
|
||||
p->cgd.velocity[i] -= ftime * vss_wind_strength->value;
|
||||
if (p->cgd.velocity[i] > fWind) {
|
||||
p->cgd.velocity[i] = fWind;
|
||||
}
|
||||
} else if (p->cgd.velocity[i] < fWind) {
|
||||
p->cgd.velocity[i] += ftime * vss_movement_dampen->value;
|
||||
if (p->cgd.velocity[i] < fWind) {
|
||||
p->cgd.velocity[i] = fWind;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (p->cgd.velocity[i] < fWind) {
|
||||
p->cgd.velocity[i] += ftime * vss_wind_strength->value;
|
||||
if (p->cgd.velocity[i] > fWind) {
|
||||
p->cgd.velocity[i] = fWind;
|
||||
}
|
||||
} else if (p->cgd.velocity[i] > fWind) {
|
||||
p->cgd.velocity[i] -= ftime * vss_wind_strength->value;
|
||||
if (p->cgd.velocity[i] < fWind) {
|
||||
p->cgd.velocity[i] = fWind;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Vector normal;
|
||||
@@ -913,7 +975,12 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
// time of this tempmodel
|
||||
lerpfrac = (float)(cg.time - p->lastPhysicsTime) / (float)physics_rate;
|
||||
// Clamp
|
||||
lerpfrac = Q_clamp_float(lerpfrac, 0, 1);
|
||||
if (lerpfrac > 1 || (p->cgd.flags2 & T2_PHYSICS_EVERYFRAME)) {
|
||||
lerpfrac = 1;
|
||||
}
|
||||
if (lerpfrac < 0) {
|
||||
lerpfrac = 0;
|
||||
}
|
||||
|
||||
// Increment the time this tempmodel has been alive
|
||||
p->aliveTime += frameTime;
|
||||
@@ -1137,7 +1204,13 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
{
|
||||
Vector dst;
|
||||
// Create a circular shaped burst around the up vector
|
||||
float angle = ((float)count / (float)m_spawnthing->count) * 360; // * M_PI * 2;
|
||||
float angle;
|
||||
|
||||
if (mcount == 1) {
|
||||
angle = random() * 360;
|
||||
} else {
|
||||
angle = ((float)count / (float)m_spawnthing->count) * 360; // * M_PI * 2;
|
||||
}
|
||||
|
||||
Vector end = Vector(vLeft) * m_spawnthing->sphereRadius * current_entity_scale;
|
||||
RotatePointAroundVector(dst, Vector(vForward), end, angle);
|
||||
@@ -1390,7 +1463,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
p->cgd.avelocity[i] = m_spawnthing->avelocity_amplitude[i] * random() + m_spawnthing->avelocity_base[i];
|
||||
|
||||
// Randomize angles or set absolute
|
||||
p->cgd.angles[i] += random() * m_spawnthing->angles_amplitude[i];
|
||||
p->cgd.angles[i] = m_spawnthing->angles_amplitude[i] * random() + m_spawnthing->cgd.angles[i];
|
||||
}
|
||||
|
||||
// If forward velocity is set, just use that otherwise use random
|
||||
@@ -1424,18 +1497,15 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate one tick of velocity based on time alive ( passed in )
|
||||
p->cgd.origin = p->cgd.origin + (p->cgd.velocity * ((float)p->aliveTime / 1000.0f) * current_entity_scale);
|
||||
|
||||
if (p->cgd.flags2 & T2_ACCEL) {
|
||||
if (m_spawnthing->cgd.flags2 & T2_RADIALVELOCITY) {
|
||||
float fLength;
|
||||
|
||||
p->cgd.velocity = p->cgd.origin - start;
|
||||
|
||||
fLength = p->cgd.velocity.length();
|
||||
if (fLength) {
|
||||
float fVel = m_spawnthing->cgd.velocity.x
|
||||
+ (m_spawnthing->cgd.velocity.y + m_spawnthing->cgd.velocity.z * crandom()) / fLength;
|
||||
float fVel = m_spawnthing->cgd.velocity[0]
|
||||
+ (m_spawnthing->cgd.velocity[1] + m_spawnthing->cgd.velocity[2] * random()) / fLength;
|
||||
|
||||
p->cgd.velocity *= fVel;
|
||||
}
|
||||
@@ -1446,20 +1516,22 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
(m_spawnthing->randvel_base[i] + m_spawnthing->randvel_amplitude[i] * random()) * current_entity_scale;
|
||||
|
||||
if (m_spawnthing->cgd.flags & T_RANDVELAXIS) {
|
||||
p->cgd.velocity += fVel * Vector(m_spawnthing->tag_axis[i]);
|
||||
if (p->cgd.flags2 & T2_NOTAGAXIS) {
|
||||
p->cgd.velocity += fVel * Vector(m_spawnthing->axis[i]);
|
||||
} else {
|
||||
p->cgd.velocity += fVel * Vector(m_spawnthing->tag_axis[i]);
|
||||
}
|
||||
} else {
|
||||
p->cgd.velocity[i] += fVel;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->cgd.flags & (T_ALIGN | T_DETAIL)) {
|
||||
if (p->cgd.velocity.x && p->cgd.velocity.y) {
|
||||
p->cgd.angles = p->cgd.velocity.toAngles();
|
||||
}
|
||||
|
||||
p->cgd.origin += p->cgd.velocity * (p->aliveTime / 1000.0) * current_entity_scale;
|
||||
p->cgd.angles = p->cgd.velocity.toAngles();
|
||||
}
|
||||
|
||||
p->cgd.origin += p->cgd.velocity * (p->aliveTime / 1000.0) * current_entity_scale;
|
||||
|
||||
if (p->cgd.flags & T_AUTOCALCLIFE) {
|
||||
Vector end, delta;
|
||||
float length, speed;
|
||||
|
||||
+1647
-37
File diff suppressed because it is too large.
Load diff
+34
-5
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "str.h"
|
||||
#include "../client/keycodes.h"
|
||||
|
||||
void CG_MessageMode_f(void)
|
||||
{
|
||||
@@ -61,8 +62,8 @@ void CG_MessageMode_Private_f(void)
|
||||
return;
|
||||
}
|
||||
|
||||
clientNum = atoi(cgi.Argv(1)) - 1;
|
||||
if (clientNum < 0 || clientNum >= MAX_CLIENTS) {
|
||||
clientNum = atoi(cgi.Argv(1));
|
||||
if (clientNum < 1 || clientNum >= MAX_CLIENTS) {
|
||||
cgi.Printf(HUD_MESSAGE_CHAT_WHITE "Message Error: %s is a bad client number\n", cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
@@ -192,8 +193,36 @@ void CG_HudPrint_f(void)
|
||||
cgi.Printf("\x1%s", cgi.Argv(1));
|
||||
}
|
||||
|
||||
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time)
|
||||
qboolean CG_CheckCaptureKey(int key, qboolean down, unsigned int time)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
char minKey = '1', maxKey = '9';
|
||||
|
||||
if (!cg.iInstaMessageMenu || !down) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
maxKey = '8';
|
||||
}
|
||||
|
||||
if (key < minKey || key > maxKey) {
|
||||
if (key == K_ESCAPE || key == '0') {
|
||||
cg.iInstaMessageMenu = 0;
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (cg.iInstaMessageMenu == -1) {
|
||||
if (key > '6') {
|
||||
cg.iInstaMessageMenu = 0;
|
||||
} else {
|
||||
cg.iInstaMessageMenu = key - '0';
|
||||
}
|
||||
} else if (cg.iInstaMessageMenu > 0) {
|
||||
cgi.SendClientCommand(va("dmmessage 0 *%i%i\n", cg.iInstaMessageMenu, key - '0'));
|
||||
cg.iInstaMessageMenu = 0;
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
+51
-11
@@ -242,6 +242,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
|
||||
float mat[3][3];
|
||||
vec3_t vOldOrigin;
|
||||
vec3_t vStart, vEnd, vMins, vMaxs;
|
||||
vec3_t vVelocity;
|
||||
trace_t trace;
|
||||
|
||||
VectorSet(vMins, -6, -6, -6);
|
||||
@@ -297,6 +298,15 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
|
||||
|
||||
VectorCopy(origin, vOldOrigin);
|
||||
|
||||
if (!cg.predicted_player_state.walking || !(cg.predicted_player_state.pm_flags & PMF_FROZEN)) {
|
||||
VectorCopy(cg.predicted_player_state.velocity, vVelocity);
|
||||
} else {
|
||||
//
|
||||
// Added in OPM
|
||||
// When frozen, there must be no movement at all
|
||||
VectorClear(vVelocity);
|
||||
}
|
||||
|
||||
if (bUseWorldPosition) {
|
||||
iMask = MASK_VIEWSOLID;
|
||||
} else {
|
||||
@@ -367,7 +377,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
|
||||
}
|
||||
|
||||
if (cg.predicted_player_state.walking) {
|
||||
fVel = VectorLength(cg.predicted_player_state.velocity);
|
||||
fVel = VectorLength(vVelocity);
|
||||
fPhase = fVel * 0.0015 + 0.9;
|
||||
cg.fCurrentViewBobPhase += (cg.frametime / 1000.0 + cg.frametime / 1000.0) * M_PI * fPhase;
|
||||
|
||||
@@ -446,7 +456,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
|
||||
AngleVectorsLeft(vDelta, mat[0], mat[1], mat[2]);
|
||||
|
||||
CG_CalcViewModelMovement(
|
||||
cg.fCurrentViewBobPhase, cg.fCurrentViewBobAmp, cg.predicted_player_state.velocity, vDelta
|
||||
cg.fCurrentViewBobPhase, cg.fCurrentViewBobAmp, vVelocity, vDelta
|
||||
);
|
||||
|
||||
VectorMA(pREnt->origin, vDelta[0], mat[0], pREnt->origin);
|
||||
@@ -712,7 +722,37 @@ float CG_SensitivityScale()
|
||||
|
||||
void CG_AddLightShow()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
int i;
|
||||
float fSlopeY, fSlopeZ;
|
||||
float x, y, z;
|
||||
vec3_t vOrg;
|
||||
float r, g, b;
|
||||
float fMax;
|
||||
|
||||
fSlopeY = tan(cg.refdef.fov_x * 0.5);
|
||||
fSlopeZ = tan(cg.refdef.fov_y * 0.5);
|
||||
|
||||
for (i = 0; i < cg_acidtrip->integer; i++) {
|
||||
x = pow(random(), 1.0 / 3.0) * 2048.0;
|
||||
y = crandom() * x * fSlopeY;
|
||||
z = crandom() * x * fSlopeZ;
|
||||
|
||||
VectorCopy(cg.refdef.vieworg, vOrg);
|
||||
VectorMA(vOrg, x, cg.refdef.viewaxis[0], vOrg);
|
||||
VectorMA(vOrg, y, cg.refdef.viewaxis[1], vOrg);
|
||||
VectorMA(vOrg, z, cg.refdef.viewaxis[2], vOrg);
|
||||
|
||||
r = random();
|
||||
g = random();
|
||||
b = random();
|
||||
|
||||
fMax = Q_max(r, Q_max(g, b));
|
||||
r /= fMax;
|
||||
g /= fMax;
|
||||
b /= fMax;
|
||||
|
||||
cgi.R_AddLightToScene(vOrg, (rand() & 0x1FF) + 0x80, r, g, b, 0);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean CG_FrustumCullSphere(const vec3_t vPos, float fRadius) {
|
||||
@@ -871,13 +911,13 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_HideMenu("mission_success_1", CVAR_ARCHIVE);
|
||||
cgi.UI_HideMenu("mission_success_1", qtrue);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_HideMenu("mission_success_2", CVAR_ARCHIVE);
|
||||
cgi.UI_HideMenu("mission_success_2", qtrue);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_HideMenu("mission_success_3", CVAR_ARCHIVE);
|
||||
cgi.UI_HideMenu("mission_success_3", qtrue);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -885,21 +925,21 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_HideMenu("mission_failed_1", CVAR_ARCHIVE);
|
||||
cgi.UI_HideMenu("mission_failed_1", qtrue);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_HideMenu("mission_failed_2", CVAR_ARCHIVE);
|
||||
cgi.UI_HideMenu("mission_failed_2", qtrue);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_HideMenu("mission_failed_3", CVAR_ARCHIVE);
|
||||
cgi.UI_HideMenu("mission_failed_3", qtrue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_HideMenu("StatsScreen_Success", qfalse);
|
||||
cgi.UI_HideMenu("StatsScreen_Success", qtrue);
|
||||
} else {
|
||||
cgi.UI_HideMenu("StatsScreen_Failed", qfalse);
|
||||
cgi.UI_HideMenu("StatsScreen_Failed", qtrue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
|
||||
} else {
|
||||
iAnimPrefixIndex = CG_GetVMAnimPrefixIndex();
|
||||
cgi.anim->g_iLastEquippedWeaponStat = cg.snap->ps.stats[STAT_EQUIPPED_WEAPON];
|
||||
strcpy(cgi.anim->g_szLastActiveItem, CG_ConfigString(CS_WEAPONS + cg.snap->ps.activeItems[1]));
|
||||
Q_strncpyz(cgi.anim->g_szLastActiveItem, CG_ConfigString(CS_WEAPONS + cg.snap->ps.activeItems[1]), sizeof(cgi.anim->g_szLastActiveItem));
|
||||
cgi.anim->g_iLastAnimPrefixIndex = iAnimPrefixIndex;
|
||||
|
||||
bAnimChanged = qtrue;
|
||||
@@ -359,7 +359,7 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
|
||||
}
|
||||
|
||||
if (cgi.anim->g_iLastVMAnim == -1) {
|
||||
sprintf(szAnimName, "%s_idle", AnimPrefixList[iAnimPrefixIndex]);
|
||||
Com_sprintf(szAnimName, sizeof(szAnimName), "%s_idle", AnimPrefixList[iAnimPrefixIndex]);
|
||||
cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index = cgi.Anim_NumForName(pTiki, szAnimName);
|
||||
|
||||
if (cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index == -1) {
|
||||
@@ -428,7 +428,7 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(szAnimName, "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix);
|
||||
Com_sprintf(szAnimName, sizeof(szAnimName), "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix);
|
||||
if (!bWeaponChanged) {
|
||||
fCrossblendTime =
|
||||
cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
|
||||
|
||||
@@ -209,7 +209,7 @@ void ClientGameCommandManager::ResetVSSSources()
|
||||
|
||||
void ClientGameCommandManager::ResetVSSSources(Event *ev)
|
||||
{
|
||||
// FIXME: stub??
|
||||
ResetVSSSources();
|
||||
}
|
||||
|
||||
void CG_ResetVSSSources()
|
||||
@@ -289,13 +289,13 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
|
||||
|
||||
fWind = 0.0;
|
||||
|
||||
if ((pSource->flags2 & 5) != 0) {
|
||||
if ((pSource->flags2 & (T2_ACCEL | T2_MOVE)) != 0) {
|
||||
VectorMA(pSource->velocity, ftime, pSource->repulsion, pSource->velocity);
|
||||
}
|
||||
|
||||
pSource->lastOrigin = pSource->newOrigin;
|
||||
|
||||
if (pSource->flags & 0x800) {
|
||||
if (pSource->flags & T_COLLISION) {
|
||||
trace.allsolid = qfalse;
|
||||
CG_ClipMoveToEntities(
|
||||
pSource->newOrigin, vec3_origin, vec3_origin, pSource->newOrigin, -1, MASK_VOLUMETRIC_SMOKE, &trace, qfalse
|
||||
@@ -315,11 +315,11 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
|
||||
}
|
||||
}
|
||||
|
||||
if (pSource->flags2 & 5) {
|
||||
if (pSource->flags2 & (T2_ACCEL | T2_MOVE)) {
|
||||
VectorMA(pSource->newOrigin, ftime, pSource->velocity, pSource->newOrigin);
|
||||
}
|
||||
|
||||
if (pSource->flags & 0x800) {
|
||||
if (pSource->flags & T_COLLISION) {
|
||||
CG_Trace(
|
||||
&trace,
|
||||
pSource->lastOrigin,
|
||||
@@ -363,7 +363,7 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
|
||||
}
|
||||
|
||||
iSmokeType = abs(pSource->smokeType);
|
||||
if (pSource->flags2 & 5) {
|
||||
if (pSource->flags2 & (T2_ACCEL | T2_MOVE)) {
|
||||
VectorCopy(pSource->velocity, vVel);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -624,7 +624,7 @@ qboolean VSS_LerpSource(cvssource_t *pCurrent, cvssourcestate_t *pState, float f
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pCurrent->flags & 0xA0000) {
|
||||
if (pCurrent->flags & (T_HARDLINK | T_PARENTLINK)) {
|
||||
Vector parentOrigin;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -643,7 +643,7 @@ qboolean VSS_LerpSource(cvssource_t *pCurrent, cvssourcestate_t *pState, float f
|
||||
|
||||
parentOrigin = e->origin;
|
||||
VectorAdd(pState->origin, parentOrigin, pState->origin);
|
||||
} else if (pCurrent->flags2 & 5) {
|
||||
} else if (pCurrent->flags2 & (T2_ACCEL | T2_MOVE)) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
pState->origin[i] =
|
||||
(pCurrent->newOrigin[i] - pCurrent->lastOrigin[i]) * fLerpFrac + pCurrent->lastOrigin[i];
|
||||
@@ -746,9 +746,8 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
|
||||
pSource->startAlpha = (random() * 0.15 + 0.85) * fDensity;
|
||||
pSource->newDensity = 0.0;
|
||||
if (m_spawnthing->cgd.flags & 1) {
|
||||
if (m_spawnthing->cgd.flags & T_RANDSCALE) {
|
||||
pSource->newRadius = RandomizeRange(m_spawnthing->cgd.scalemin, m_spawnthing->cgd.scalemax);
|
||||
;
|
||||
if (pSource->newRadius > 32.0) {
|
||||
pSource->newRadius = 32.0;
|
||||
}
|
||||
@@ -777,16 +776,16 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
pSource->roll = anglemod(fAngle);
|
||||
|
||||
if (random() < 0.5) {
|
||||
pSource->flags |= 0x40000;
|
||||
pSource->flags |= T_RANDOMROLL;
|
||||
}
|
||||
|
||||
VectorCopy(m_spawnthing->axis[0], vNewForward);
|
||||
if (m_spawnthing->cgd.flags & 4) {
|
||||
if (m_spawnthing->cgd.flags & T_SPHERE) {
|
||||
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
|
||||
do {
|
||||
vNewForward = Vector(crandom(), crandom(), crandom());
|
||||
} while (Vector::Dot(vNewForward, vNewForward) < 1.0);
|
||||
} else if (m_spawnthing->cgd.flags & 0x10) {
|
||||
} else if (m_spawnthing->cgd.flags & T_CIRCLE) {
|
||||
if (m_spawnthing->sphereRadius != 0.0) {
|
||||
Vector dst, end;
|
||||
|
||||
@@ -799,7 +798,7 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
|
||||
fAngle += fAngleStep;
|
||||
}
|
||||
} else if (m_spawnthing->cgd.flags & 8) {
|
||||
} else if (m_spawnthing->cgd.flags & T_INWARDSPHERE) {
|
||||
Vector dir, end;
|
||||
do {
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
@@ -808,7 +807,7 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius;
|
||||
VectorCopy(end, pSource->newOrigin);
|
||||
vNewForward = dir * -1.0;
|
||||
} else if (m_spawnthing->cgd.flags2 & 0x20000) {
|
||||
} else if (m_spawnthing->cgd.flags2 & T2_CONE) {
|
||||
float fHeight, fRadius;
|
||||
float fAngle;
|
||||
float sina, cosa;
|
||||
@@ -830,8 +829,6 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
VectorMA(m_spawnthing->cgd.origin, fRadius * cosa, m_spawnthing->axis[1], pSource->newOrigin);
|
||||
VectorMA(m_spawnthing->cgd.origin, fRadius * sina, m_spawnthing->axis[2], pSource->newOrigin);
|
||||
} else if (m_spawnthing->sphereRadius) {
|
||||
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
|
||||
} else {
|
||||
Vector dir, end;
|
||||
do {
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
@@ -841,6 +838,8 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius;
|
||||
VectorCopy(end, pSource->newOrigin);
|
||||
vNewForward = dir;
|
||||
} else {
|
||||
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -874,15 +873,14 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
|
||||
for (i = 0; i < 3; ++i) {
|
||||
float fDist = m_spawnthing->axis_offset_base[i] + random() * m_spawnthing->axis_offset_amplitude[i];
|
||||
|
||||
if (pSource->flags2 & 0x80) {
|
||||
if (pSource->flags2 & T2_PARALLEL) {
|
||||
pSource->newOrigin += Vector(m_spawnthing->axis[i]) * fDist;
|
||||
} else {
|
||||
pSource->newOrigin += Vector(m_spawnthing->tag_axis[i]) * fDist;
|
||||
}
|
||||
}
|
||||
|
||||
pSource->velocity *= pSource->lifeTime / 1000.0;
|
||||
pSource->newOrigin += pSource->velocity;
|
||||
pSource->newOrigin += pSource->velocity * (pSource->lifeTime / 1000.0);
|
||||
if (vss_lighting_fps->integer) {
|
||||
cgi.R_GetLightingForSmoke(pSource->newLighting, pSource->newOrigin);
|
||||
}
|
||||
@@ -1225,13 +1223,13 @@ void ClientGameCommandManager::AddVSSSources()
|
||||
pComp = pCurrent->prev;
|
||||
|
||||
newEnt.renderfx = 0;
|
||||
if (pCurrent->flags < 0 && !cg_detail->integer) {
|
||||
if ((pCurrent->flags & T_DETAIL) && !cg_detail->integer) {
|
||||
FreeVSSSource(pCurrent);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((pCurrent->flags2 & 0x4000) != 0) {
|
||||
newEnt.renderfx = 0x4000000;
|
||||
if ((pCurrent->flags2 & T2_ALWAYSDRAW) != 0) {
|
||||
newEnt.renderfx = RF_ALWAYSDRAW;
|
||||
}
|
||||
|
||||
if (pCurrent->lastPhysicsTime) {
|
||||
@@ -1240,8 +1238,8 @@ void ClientGameCommandManager::AddVSSSources()
|
||||
mstime = physics_rate;
|
||||
}
|
||||
|
||||
if (mstime >= physics_rate || (pCurrent->flags2 & 0x10) != 0) {
|
||||
if (!VSS_SourcePhysics(pCurrent, (float)mstime * 0.001)) {
|
||||
if (mstime >= physics_rate || (pCurrent->flags2 & T2_PHYSICS_EVERYFRAME) != 0) {
|
||||
if (!VSS_SourcePhysics(pCurrent, (float)mstime / 1000.0)) {
|
||||
FreeVSSSource(pCurrent);
|
||||
continue;
|
||||
}
|
||||
@@ -1265,26 +1263,18 @@ void ClientGameCommandManager::AddVSSSources()
|
||||
}
|
||||
}
|
||||
|
||||
fLerpFrac = (cg.time - pCurrent->lastPhysicsTime) / physics_rate;
|
||||
if (fLerpFrac > 1.0) {
|
||||
fLerpFrac = 1.0;
|
||||
} else if (fLerpFrac < 0.0) {
|
||||
fLerpFrac = 0.0;
|
||||
}
|
||||
fLerpFrac = (float)(cg.time - pCurrent->lastPhysicsTime) / (float)physics_rate;
|
||||
fLerpFrac = Q_clamp_float(fLerpFrac, 0, 1);
|
||||
|
||||
fLightingFrac = (cg.time - pCurrent->lastLightingTime) / lighting_rate;
|
||||
if (fLightingFrac > 1.0) {
|
||||
fLightingFrac = 1.0;
|
||||
} else if (fLightingFrac < 0.0) {
|
||||
fLightingFrac = 0.0;
|
||||
}
|
||||
fLightingFrac = (float)(cg.time - pCurrent->lastLightingTime) / (float)lighting_rate;
|
||||
fLightingFrac = Q_clamp_float(fLightingFrac, 0, 1);
|
||||
|
||||
if (lastVSSFrameTime) {
|
||||
pCurrent->lifeTime += frameTime;
|
||||
}
|
||||
|
||||
if (!pCurrent->lastValid) {
|
||||
if (!VSS_SourcePhysics(pCurrent, (float)physics_rate * 0.001)) {
|
||||
if (!VSS_SourcePhysics(pCurrent, (float)physics_rate / 1000)) {
|
||||
ClientGameCommandManager::FreeVSSSource(pCurrent);
|
||||
continue;
|
||||
}
|
||||
@@ -1338,12 +1328,12 @@ void ClientGameCommandManager::AddVSSSources()
|
||||
pCurrent->roll -= j;
|
||||
}
|
||||
|
||||
if ((pCurrent->flags & 0x40000) != 0) {
|
||||
if ((pCurrent->flags & T_RANDOMROLL) != 0) {
|
||||
newEnt.hModel = hModel;
|
||||
} else {
|
||||
newEnt.hModel = hModel2;
|
||||
}
|
||||
} else if ((pCurrent->flags & 0x40000) != 0) {
|
||||
} else if ((pCurrent->flags & T_RANDOMROLL) != 0) {
|
||||
newEnt.hModel = hModel;
|
||||
} else {
|
||||
newEnt.hModel = hModel2;
|
||||
|
||||
+17
-11
@@ -52,18 +52,24 @@ endif()
|
||||
|
||||
set(OLD_VALUE ${BUILD_SHARED_LIBS})
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory("../libmad" "./libmad" EXCLUDE_FROM_ALL)
|
||||
target_link_libraries(omohclient INTERFACE mad)
|
||||
set(BUILD_SHARED_LIBS ${OLD_VALUE} CACHE BOOL "" FORCE)
|
||||
|
||||
if (USE_OPENAL)
|
||||
# Try to use OpenAL
|
||||
find_package(OpenAL)
|
||||
if (OPENAL_FOUND)
|
||||
target_compile_definitions(omohclient INTERFACE USE_OPENAL=1)
|
||||
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
|
||||
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
|
||||
endif()
|
||||
if(USE_INTERNAL_MAD)
|
||||
add_subdirectory("../libmad" "./libmad" EXCLUDE_FROM_ALL)
|
||||
target_link_libraries(omohclient INTERFACE mad)
|
||||
else()
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_path(LIBMAD_INCLUDE_DIRS mad.h)
|
||||
find_library(LIBMAD_LIBRARIES mad)
|
||||
find_package_handle_standard_args(
|
||||
LibMad
|
||||
DEFAULT_MSG
|
||||
LIBMAD_LIBRARIES
|
||||
LIBMAD_INCLUDE_DIRS
|
||||
)
|
||||
target_include_directories(omohclient INTERFACE ${LIBMAD_INCLUDE_DIRS})
|
||||
target_link_libraries(omohclient INTERFACE ${LIBMAD_LIBRARIES})
|
||||
endif()
|
||||
|
||||
set(BUILD_SHARED_LIBS ${OLD_VALUE} CACHE BOOL "" FORCE)
|
||||
|
||||
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
|
||||
+60
-15
@@ -248,21 +248,23 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
|
||||
if (snapshot->numEntities != count) {
|
||||
Com_DPrintf("CL_GetSnapshot: Not all children could find their parents.\n");
|
||||
|
||||
for (i = count; i < snapshot->numEntities; i++)
|
||||
for (i = snapshot->numEntities; i < count; i++)
|
||||
{
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
|
||||
if (parents[s1->number] >= 0) {
|
||||
Com_DPrintf(
|
||||
"CL_GetSnapshot: entity %d with parent %d and model '%s' at %.2f %.2f %.2f, could not find parent.\n",
|
||||
s1->number,
|
||||
s1->parent,
|
||||
CL_ConfigString(CS_MODELS + s1->modelindex),
|
||||
s1->origin[0],
|
||||
s1->origin[1],
|
||||
s1->origin[2]
|
||||
);
|
||||
for (pnum = 0; pnum < count; pnum++) {
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + pnum) & (MAX_PARSE_ENTITIES - 1)];
|
||||
if (parents[s1->number] >= 0) {
|
||||
Com_DPrintf(
|
||||
"CL_GetSnapshot: entity %d with parent %d and model '%s' at %.2f %.2f %.2f, could not find parent.\n",
|
||||
s1->number,
|
||||
s1->parent,
|
||||
CL_ConfigString(CS_MODELS + s1->modelindex),
|
||||
s1->origin[0],
|
||||
s1->origin[1],
|
||||
s1->origin[2]
|
||||
);
|
||||
|
||||
parents[s1->number] = -2;
|
||||
parents[s1->number] = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -625,6 +627,7 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->LV_ConvertString = Sys_LV_CL_ConvertString;
|
||||
|
||||
cgi->Cvar_Get = Cvar_Get;
|
||||
cgi->Cvar_Find = Cvar_FindVar;
|
||||
cgi->Cvar_Set = Cvar_Set;
|
||||
|
||||
cgi->Argc = Cmd_Argc;
|
||||
@@ -769,7 +772,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
|
||||
cgi->UI_ShowMenu = UI_ShowMenu;
|
||||
cgi->UI_HideMenu = UI_HideMenu;
|
||||
cgi->UI_FontStringWidth = uie.FontStringWidth;
|
||||
cgi->UI_FontStringWidth = CL_FontStringWidth;
|
||||
cgi->UI_GetObjectivesTop = UI_GetObjectivesTop;
|
||||
cgi->Key_StringToKeynum = Key_StringToKeynum;
|
||||
cgi->Key_KeynumToBindString = Key_KeynumToBindString;
|
||||
cgi->Key_GetKeysForCommand = Key_GetKeysForCommand;
|
||||
@@ -1111,6 +1115,42 @@ void CL_FirstSnapshot( void ) {
|
||||
Cbuf_AddText( cl_activeAction->string );
|
||||
Cvar_Set( "activeAction", "" );
|
||||
}
|
||||
|
||||
#ifdef USE_MUMBLE
|
||||
if ((cl_useMumble->integer) && !mumble_islinked()) {
|
||||
int ret = mumble_link(CLIENT_WINDOW_TITLE);
|
||||
Com_Printf("Mumble: Linking to Mumble application %s\n", ret==0?"ok":"failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_VOIP
|
||||
if (!clc.voipCodecInitialized) {
|
||||
int i;
|
||||
int error;
|
||||
|
||||
clc.opusEncoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, &error);
|
||||
|
||||
if ( error ) {
|
||||
Com_DPrintf("VoIP: Error opus_encoder_create %d\n", error);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
clc.opusDecoder[i] = opus_decoder_create(48000, 1, &error);
|
||||
if ( error ) {
|
||||
Com_DPrintf("VoIP: Error opus_decoder_create(%d) %d\n", i, error);
|
||||
return;
|
||||
}
|
||||
clc.voipIgnore[i] = qfalse;
|
||||
clc.voipGain[i] = 1.0f;
|
||||
}
|
||||
clc.voipCodecInitialized = qtrue;
|
||||
clc.voipMuteAll = qfalse;
|
||||
Cmd_AddCommand ("voip", CL_Voip_f);
|
||||
Cvar_Set("cl_voipSendTarget", "spatial");
|
||||
Com_Memset(clc.voipTargets, ~0, sizeof(clc.voipTargets));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int lastSnapFlags;
|
||||
@@ -1161,7 +1201,12 @@ void CL_SetCGameTime( void ) {
|
||||
// allow pause in single player
|
||||
if ( paused->integer && com_sv_running->integer ) {
|
||||
// paused
|
||||
CL_AdjustTimeDelta();
|
||||
//CL_AdjustTimeDelta();
|
||||
// Fixed in OPM
|
||||
// Keep in sync with the server time.
|
||||
// In OG, the game could lag for a short time
|
||||
// when pausing and unpausing frequently
|
||||
cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+159
-51
@@ -35,6 +35,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "../uilib/ui_public.h"
|
||||
#include "snd_local.h"
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
#define MAXSIZE 8
|
||||
#define MINSIZE 4
|
||||
|
||||
@@ -55,6 +57,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
static void RoQ_init( void );
|
||||
static void CL_FinishedCinematic();
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
@@ -126,6 +129,10 @@ typedef struct {
|
||||
int playonwalls;
|
||||
byte* buf;
|
||||
long drawX, drawY;
|
||||
|
||||
long realTime;
|
||||
long currTime;
|
||||
long soundTime;
|
||||
} cin_cache;
|
||||
|
||||
static cinematics_t cin;
|
||||
@@ -133,6 +140,10 @@ static cin_cache cinTable[MAX_VIDEO_HANDLES];
|
||||
static int currentHandle = -1;
|
||||
static int CL_handle = -1;
|
||||
|
||||
static connstate_t oldClientState;
|
||||
|
||||
static int audioStartTime = 0;
|
||||
|
||||
extern "C" int s_soundtime; // sample PAIRS
|
||||
|
||||
|
||||
@@ -160,7 +171,7 @@ static int CIN_HandleForVideo(void) {
|
||||
}
|
||||
|
||||
|
||||
extern "C" int CL_ScaledMilliseconds(void);
|
||||
extern "C" int Com_Milliseconds(void);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RllSetupTable
|
||||
@@ -1091,8 +1102,6 @@ static void RoQReset( void ) {
|
||||
|
||||
static void RoQInterrupt(void)
|
||||
{
|
||||
// Removed in OPM
|
||||
#if 0
|
||||
byte *framedata;
|
||||
short sbuf[32768];
|
||||
int ssize;
|
||||
@@ -1144,24 +1153,20 @@ redump:
|
||||
case ZA_SOUND_MONO:
|
||||
if (!cinTable[currentHandle].silent) {
|
||||
ssize = RllDecodeMonoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
|
||||
S_RawSamples(0, ssize, 22050, 2, 1, (byte *)sbuf, 1.0f, -1);
|
||||
// S_RawSamples(0, ssize, 22050, 2, 1, (byte *)sbuf, 1.0f, -1);
|
||||
}
|
||||
break;
|
||||
case ZA_SOUND_STEREO:
|
||||
if (!cinTable[currentHandle].silent) {
|
||||
if (cinTable[currentHandle].numQuads == -1) {
|
||||
S_Update();
|
||||
s_rawend[0] = s_soundtime;
|
||||
}
|
||||
ssize = RllDecodeStereoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
|
||||
S_RawSamples(0, ssize, 22050, 2, 2, (byte *)sbuf, 1.0f, -1);
|
||||
// S_RawSamples(0, ssize, 22050, 2, 2, (byte *)sbuf, 1.0f, -1);
|
||||
}
|
||||
break;
|
||||
case ROQ_QUAD_INFO:
|
||||
if (cinTable[currentHandle].numQuads == -1) {
|
||||
readQuadInfo( framedata );
|
||||
setupQuad( 0, 0 );
|
||||
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds();
|
||||
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Com_Milliseconds();
|
||||
}
|
||||
if (cinTable[currentHandle].numQuads != 1) cinTable[currentHandle].numQuads = 0;
|
||||
break;
|
||||
@@ -1216,7 +1221,6 @@ redump:
|
||||
// assert(cinTable[currentHandle].RoQFrameSize <= 65536);
|
||||
// r = FS_Read( cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile );
|
||||
cinTable[currentHandle].RoQPlayed += cinTable[currentHandle].RoQFrameSize+8;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -1229,7 +1233,10 @@ redump:
|
||||
|
||||
static void RoQ_init( void )
|
||||
{
|
||||
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds();
|
||||
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Com_Milliseconds();
|
||||
cinTable[currentHandle].realTime = Com_Milliseconds();
|
||||
cinTable[currentHandle].currTime = 0;
|
||||
cinTable[currentHandle].soundTime = 0;
|
||||
|
||||
cinTable[currentHandle].RoQPlayed = 24;
|
||||
|
||||
@@ -1276,8 +1283,10 @@ static void RoQShutdown( void ) {
|
||||
cinTable[currentHandle].iFile = 0;
|
||||
}
|
||||
|
||||
S_StopMovieAudio();
|
||||
|
||||
if (cinTable[currentHandle].alterGameState) {
|
||||
clc.state = CA_DISCONNECTED;
|
||||
clc.state = oldClientState;
|
||||
// we can't just do a vstr nextmap, because
|
||||
// if we are aborting the intro cinematic with
|
||||
// a devmap command, nextmap would be valid by
|
||||
@@ -1289,8 +1298,29 @@ static void RoQShutdown( void ) {
|
||||
}
|
||||
CL_handle = -1;
|
||||
}
|
||||
|
||||
cinTable[currentHandle].fileName[0] = 0;
|
||||
currentHandle = -1;
|
||||
|
||||
CL_FinishedCinematic();
|
||||
}
|
||||
|
||||
static void CL_FinishedCinematic()
|
||||
{
|
||||
const char* s;
|
||||
|
||||
if (!CL_FinishedIntro())
|
||||
{
|
||||
CL_FinishedStartStage();
|
||||
return;
|
||||
}
|
||||
|
||||
s = Cvar_VariableString("nextmap");
|
||||
if (*s)
|
||||
{
|
||||
Cbuf_ExecuteText(EXEC_APPEND, va("%s\n", s));
|
||||
Cvar_Set("nextmap", "");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1331,8 +1361,11 @@ Fetch and decompress the pending frame
|
||||
|
||||
e_status CIN_RunCinematic (int handle)
|
||||
{
|
||||
int start = 0;
|
||||
int thisTime = 0;
|
||||
int deltaTime;
|
||||
int frameTime;
|
||||
int soundTime;
|
||||
int newTime;
|
||||
long tfps;
|
||||
|
||||
if (handle < 0 || handle>= MAX_VIDEO_HANDLES || cinTable[handle].status == FMV_EOF) return FMV_EOF;
|
||||
|
||||
@@ -1360,24 +1393,46 @@ e_status CIN_RunCinematic (int handle)
|
||||
return cinTable[currentHandle].status;
|
||||
}
|
||||
|
||||
thisTime = CL_ScaledMilliseconds();
|
||||
if (cinTable[currentHandle].shader && (abs(thisTime - cinTable[currentHandle].lastTime))>100) {
|
||||
cinTable[currentHandle].startTime += thisTime - cinTable[currentHandle].lastTime;
|
||||
frameTime = Com_Milliseconds();
|
||||
deltaTime = frameTime - cinTable[currentHandle].realTime;
|
||||
if (deltaTime > 100) {
|
||||
deltaTime = 100;
|
||||
}
|
||||
cinTable[currentHandle].tfps = (((CL_ScaledMilliseconds() - cinTable[currentHandle].startTime)*3)/100);
|
||||
|
||||
start = cinTable[currentHandle].startTime;
|
||||
while( (cinTable[currentHandle].tfps != cinTable[currentHandle].numQuads)
|
||||
newTime = cinTable[currentHandle].currTime + deltaTime;
|
||||
if (cl_movieaudio->integer) {
|
||||
soundTime = S_CurrentMoviePosition();
|
||||
if (soundTime > cinTable[currentHandle].currTime || soundTime > cinTable[currentHandle].soundTime) {
|
||||
cinTable[currentHandle].currTime = newTime + (deltaTime * (soundTime - newTime)) / 100;
|
||||
}
|
||||
else {
|
||||
cinTable[currentHandle].currTime = newTime;
|
||||
}
|
||||
|
||||
cinTable[currentHandle].soundTime = soundTime;
|
||||
} else {
|
||||
//
|
||||
// Fixed in OPM
|
||||
//
|
||||
cinTable[currentHandle].currTime = newTime;
|
||||
}
|
||||
|
||||
cinTable[currentHandle].realTime = frameTime;
|
||||
|
||||
tfps = (cinTable[currentHandle].currTime * 3) / 100;
|
||||
|
||||
while( (tfps != cinTable[currentHandle].numQuads)
|
||||
&& (cinTable[currentHandle].status == FMV_PLAY) )
|
||||
{
|
||||
RoQInterrupt();
|
||||
if (start != cinTable[currentHandle].startTime) {
|
||||
cinTable[currentHandle].tfps = (((CL_ScaledMilliseconds() - cinTable[currentHandle].startTime)*3)/100);
|
||||
start = cinTable[currentHandle].startTime;
|
||||
|
||||
cinTable[currentHandle].realTime = Com_Milliseconds();
|
||||
if (cinTable[currentHandle].realTime > frameTime + 66) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cinTable[currentHandle].lastTime = thisTime;
|
||||
cinTable[currentHandle].lastTime = frameTime;
|
||||
|
||||
if (cinTable[currentHandle].status == FMV_LOOPED) {
|
||||
cinTable[currentHandle].status = FMV_PLAY;
|
||||
@@ -1400,9 +1455,6 @@ CIN_PlayCinematic
|
||||
==================
|
||||
*/
|
||||
int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBits ) {
|
||||
return 0;
|
||||
// Removed in OPM
|
||||
#if 0
|
||||
unsigned short RoQID;
|
||||
char name[MAX_OSPATH];
|
||||
int i;
|
||||
@@ -1428,7 +1480,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
|
||||
|
||||
cin.currentHandle = currentHandle;
|
||||
|
||||
strcpy(cinTable[currentHandle].fileName, name);
|
||||
Q_strncpyz(cinTable[currentHandle].fileName, name, sizeof(cinTable[currentHandle].fileName));
|
||||
|
||||
cinTable[currentHandle].ROQSize = 0;
|
||||
cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue, qtrue);
|
||||
@@ -1474,17 +1526,12 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
|
||||
clc.state = CA_CINEMATIC;
|
||||
}
|
||||
|
||||
if (!cinTable[currentHandle].silent) {
|
||||
s_rawend[0] = s_soundtime;
|
||||
}
|
||||
|
||||
return currentHandle;
|
||||
}
|
||||
Com_DPrintf("trFMV::play(), invalid RoQ ID\n");
|
||||
|
||||
RoQShutdown();
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CIN_SetExtents (int handle, int x, int y, int w, int h) {
|
||||
@@ -1600,33 +1647,96 @@ void CIN_DrawCinematic (int handle) {
|
||||
cinTable[handle].dirty = qfalse;
|
||||
}
|
||||
|
||||
static unsigned short CL_PlayRoQ(const char* name, const char* arg, const char* s) {
|
||||
unsigned short RoQID;
|
||||
|
||||
Com_Memset(&cin, 0, sizeof(cinematics_t) );
|
||||
currentHandle = CIN_HandleForVideo();
|
||||
|
||||
cin.currentHandle = currentHandle;
|
||||
|
||||
Q_strncpyz(cinTable[currentHandle].fileName, name, sizeof(cinTable[currentHandle].fileName));
|
||||
|
||||
cinTable[currentHandle].ROQSize = 0;
|
||||
cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue, qtrue);
|
||||
|
||||
if (cinTable[currentHandle].ROQSize<=0) {
|
||||
Com_DPrintf("Can not find RoQ cinematic '%s'\n", name);
|
||||
CL_FinishedCinematic();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((s && s[0] == '1') || Q_stricmp(arg,"demoend.roq")==0 || Q_stricmp(arg,"end.roq")==0) {
|
||||
cinTable[currentHandle].holdAtEnd = qtrue;
|
||||
}
|
||||
|
||||
CIN_SetExtents(currentHandle, 0, 0, 640, 480);
|
||||
cinTable[currentHandle].alterGameState = qtrue;
|
||||
|
||||
initRoQ();
|
||||
|
||||
FS_Read (cin.file, 16, cinTable[currentHandle].iFile);
|
||||
|
||||
RoQID = (unsigned short)(cin.file[0]) + (unsigned short)(cin.file[1])*256;
|
||||
if (RoQID == 0x1084)
|
||||
{
|
||||
RoQ_init();
|
||||
// FS_Read (cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile);
|
||||
|
||||
cinTable[currentHandle].status = FMV_PLAY;
|
||||
Com_DPrintf("trFMV::play(), playing %s\n", arg);
|
||||
|
||||
if (cl_movieaudio->integer) {
|
||||
audioStartTime = Com_Milliseconds();
|
||||
S_SetupMovieAudio(name);
|
||||
}
|
||||
|
||||
oldClientState = clc.state;
|
||||
clc.state = CA_CINEMATIC;
|
||||
|
||||
if (cls.glconfig.maxTextureSize <= 256 || s && *s == '2') {
|
||||
//cinTable[currentHandle].interlaced = qtrue;
|
||||
}
|
||||
|
||||
CL_handle = currentHandle;
|
||||
|
||||
do {
|
||||
SCR_RunCinematic();
|
||||
} while (!cinTable[currentHandle].buf && cinTable[currentHandle].status == FMV_PLAY);
|
||||
|
||||
UI_CloseConsole();
|
||||
|
||||
return currentHandle;
|
||||
}
|
||||
Com_DPrintf("trFMV::play(), invalid RoQ ID\n");
|
||||
|
||||
RoQShutdown();
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CL_PlayCinematic_f(void) {
|
||||
char *arg, *s;
|
||||
int bits = CIN_system;
|
||||
char name[256];
|
||||
|
||||
Com_DPrintf("CL_PlayCinematic_f\n");
|
||||
if (clc.state == CA_CINEMATIC) {
|
||||
SCR_StopCinematic();
|
||||
}
|
||||
|
||||
arg = Cmd_Argv( 1 );
|
||||
Com_DPrintf("CL_PlayCinematic( %s )\n", arg);
|
||||
s = Cmd_Argv(2);
|
||||
|
||||
if ((s && s[0] == '1') || Q_stricmp(arg,"demoend.roq")==0 || Q_stricmp(arg,"end.roq")==0) {
|
||||
bits |= CIN_hold;
|
||||
}
|
||||
if (s && s[0] == '2') {
|
||||
bits |= CIN_loop;
|
||||
CL_StartHunkUsers(qfalse);
|
||||
S_StopAllSounds2(qtrue);
|
||||
|
||||
Com_sprintf(name, sizeof(name), "video/%s", arg);
|
||||
|
||||
if (Q_stricmp(&name[strlen(name) - 4], ".roq")) {
|
||||
Com_Printf("Bad or missing cinematic extension.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
S_StopAllSounds2( qtrue );
|
||||
|
||||
CL_handle = CIN_PlayCinematic( arg, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, bits );
|
||||
if (CL_handle >= 0) {
|
||||
do {
|
||||
SCR_RunCinematic();
|
||||
} while (cinTable[currentHandle].buf == NULL && cinTable[currentHandle].status == FMV_PLAY); // wait for first frame (load codebook and sound)
|
||||
}
|
||||
CL_PlayRoQ(name, arg, s);
|
||||
}
|
||||
|
||||
|
||||
@@ -1646,7 +1756,5 @@ void SCR_RunCinematic (void)
|
||||
void SCR_StopCinematic(void) {
|
||||
if (CL_handle >= 0 && CL_handle < MAX_VIDEO_HANDLES) {
|
||||
CIN_StopCinematic(CL_handle);
|
||||
S_StopAllSounds2( qtrue );
|
||||
CL_handle = -1;
|
||||
}
|
||||
}
|
||||
+178
-17
@@ -56,6 +56,10 @@ qboolean in_guimouse;
|
||||
|
||||
kbutton_t in_up, in_down;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
kbutton_t in_voiprecord;
|
||||
#endif
|
||||
|
||||
kbutton_t in_buttons[16];
|
||||
|
||||
qboolean in_mlooking;
|
||||
@@ -258,6 +262,20 @@ void IN_SpeedUp(void) {IN_KeyUp(&in_speed);}
|
||||
void IN_StrafeDown(void) {IN_KeyDown(&in_strafe);}
|
||||
void IN_StrafeUp(void) {IN_KeyUp(&in_strafe);}
|
||||
|
||||
#ifdef USE_VOIP
|
||||
void IN_VoipRecordDown(void)
|
||||
{
|
||||
IN_KeyDown(&in_voiprecord);
|
||||
Cvar_Set("cl_voipSend", "1");
|
||||
}
|
||||
|
||||
void IN_VoipRecordUp(void)
|
||||
{
|
||||
IN_KeyUp(&in_voiprecord);
|
||||
Cvar_Set("cl_voipSend", "0");
|
||||
}
|
||||
#endif
|
||||
|
||||
void IN_Button0Down(void) {IN_KeyDown(&in_buttons[0]);}
|
||||
void IN_Button0Up(void) {IN_KeyUp(&in_buttons[0]);}
|
||||
void IN_Button1Down(void) {IN_KeyDown(&in_buttons[1]);}
|
||||
@@ -461,6 +479,16 @@ CL_JoystickMove
|
||||
void CL_JoystickMove( usercmd_t *cmd ) {
|
||||
float anglespeed;
|
||||
|
||||
float yaw = j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
|
||||
float right = j_side->value * cl.joystickAxis[j_side_axis->integer];
|
||||
float forward = j_forward->value * cl.joystickAxis[j_forward_axis->integer];
|
||||
float pitch = j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
|
||||
float up = j_up->value * cl.joystickAxis[j_up_axis->integer];
|
||||
|
||||
if ( in_speed.active ^ cl_run->integer ) {
|
||||
cmd->buttons |= BUTTON_RUN;
|
||||
}
|
||||
|
||||
if ( in_speed.active ) {
|
||||
anglespeed = 0.001 * cls.frametime * cl_anglespeedkey->value;
|
||||
} else {
|
||||
@@ -468,18 +496,22 @@ void CL_JoystickMove( usercmd_t *cmd ) {
|
||||
}
|
||||
|
||||
if ( !in_strafe.active ) {
|
||||
cl.viewangles[YAW] += anglespeed * cl_yawspeed->value * cl.joystickAxis[AXIS_SIDE];
|
||||
cl.viewangles[YAW] += anglespeed * yaw;
|
||||
cmd->rightmove = ClampChar( cmd->rightmove + (int)right );
|
||||
} else {
|
||||
cmd->rightmove = ClampChar( cmd->rightmove + cl.joystickAxis[AXIS_SIDE] );
|
||||
cl.viewangles[YAW] += anglespeed * right;
|
||||
cmd->rightmove = ClampChar( cmd->rightmove + (int)yaw );
|
||||
}
|
||||
|
||||
if ( in_mlooking ) {
|
||||
cl.viewangles[PITCH] += anglespeed * cl_pitchspeed->value * cl.joystickAxis[AXIS_FORWARD];
|
||||
cl.viewangles[PITCH] += anglespeed * forward;
|
||||
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)pitch );
|
||||
} else {
|
||||
cmd->forwardmove = ClampChar( cmd->forwardmove + cl.joystickAxis[AXIS_FORWARD] );
|
||||
cl.viewangles[PITCH] += anglespeed * pitch;
|
||||
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)forward );
|
||||
}
|
||||
|
||||
cmd->upmove = ClampChar( cmd->upmove + cl.joystickAxis[AXIS_UP] );
|
||||
cmd->upmove = ClampChar( cmd->upmove + (int)up );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -565,6 +597,8 @@ void CL_MouseMove( usercmd_t *cmd ) {
|
||||
mx *= cgameSensitivity;
|
||||
my *= cgameSensitivity;
|
||||
|
||||
cmd->buttons |= BUTTON_ANY;
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if(in_strafe.active)
|
||||
cmd->rightmove = ClampChar(cmd->rightmove + m_side->value * mx);
|
||||
@@ -617,8 +651,8 @@ void CL_CmdButtons( usercmd_t *cmd ) {
|
||||
if (UI_MenuActive() || UI_ConsoleIsOpen()) {
|
||||
cmd->buttons |= BUTTON_TALK;
|
||||
}
|
||||
|
||||
if (in_speed.active == !cl_run->integer) {
|
||||
|
||||
if ( in_speed.active ^ cl_run->integer ) {
|
||||
cmd->buttons |= BUTTON_RUN;
|
||||
}
|
||||
|
||||
@@ -726,6 +760,12 @@ void CL_CreateNewCommands( void ) {
|
||||
|
||||
frame_msec = com_frameTime - old_com_frameTime;
|
||||
|
||||
// if running over 1000fps, act as if each frame is 1ms
|
||||
// prevents divisions by zero
|
||||
if ( frame_msec < 1 ) {
|
||||
frame_msec = 1;
|
||||
}
|
||||
|
||||
// if running less than 5fps, truncate the extra time to prevent
|
||||
// unexpected moves after a hitch
|
||||
if ( frame_msec > 200 ) {
|
||||
@@ -917,6 +957,58 @@ void CL_WritePacket( void ) {
|
||||
count = MAX_PACKET_USERCMDS;
|
||||
Com_Printf("MAX_PACKET_USERCMDS\n");
|
||||
}
|
||||
|
||||
#ifdef USE_VOIP
|
||||
if (clc.voipOutgoingDataSize > 0)
|
||||
{
|
||||
if((clc.voipFlags & VOIP_SPATIAL) || Com_IsVoipTarget(clc.voipTargets, sizeof(clc.voipTargets), -1))
|
||||
{
|
||||
MSG_WriteByte (&buf, clc_voipOpus);
|
||||
MSG_WriteByte (&buf, clc.voipOutgoingGeneration);
|
||||
MSG_WriteLong (&buf, clc.voipOutgoingSequence);
|
||||
MSG_WriteByte (&buf, clc.voipOutgoingDataFrames);
|
||||
MSG_WriteData (&buf, clc.voipTargets, sizeof(clc.voipTargets));
|
||||
MSG_WriteByte(&buf, clc.voipFlags);
|
||||
MSG_WriteShort (&buf, clc.voipOutgoingDataSize);
|
||||
MSG_WriteData (&buf, clc.voipOutgoingData, clc.voipOutgoingDataSize);
|
||||
|
||||
// If we're recording a demo, we have to fake a server packet with
|
||||
// this VoIP data so it gets to disk; the server doesn't send it
|
||||
// back to us, and we might as well eliminate concerns about dropped
|
||||
// and misordered packets here.
|
||||
if(clc.demorecording && !clc.demowaiting)
|
||||
{
|
||||
const int voipSize = clc.voipOutgoingDataSize;
|
||||
msg_t fakemsg;
|
||||
byte fakedata[MAX_MSGLEN];
|
||||
MSG_Init (&fakemsg, fakedata, sizeof (fakedata));
|
||||
MSG_Bitstream (&fakemsg);
|
||||
MSG_WriteLong (&fakemsg, clc.reliableAcknowledge);
|
||||
MSG_WriteByte (&fakemsg, svc_voipOpus);
|
||||
MSG_WriteShort (&fakemsg, clc.clientNum);
|
||||
MSG_WriteByte (&fakemsg, clc.voipOutgoingGeneration);
|
||||
MSG_WriteLong (&fakemsg, clc.voipOutgoingSequence);
|
||||
MSG_WriteByte (&fakemsg, clc.voipOutgoingDataFrames);
|
||||
MSG_WriteShort (&fakemsg, clc.voipOutgoingDataSize );
|
||||
MSG_WriteBits (&fakemsg, clc.voipFlags, VOIP_FLAGCNT);
|
||||
MSG_WriteData (&fakemsg, clc.voipOutgoingData, voipSize);
|
||||
MSG_WriteByte (&fakemsg, svc_EOF);
|
||||
CL_WriteDemoMessage (&fakemsg, 0);
|
||||
}
|
||||
|
||||
clc.voipOutgoingSequence += clc.voipOutgoingDataFrames;
|
||||
clc.voipOutgoingDataSize = 0;
|
||||
clc.voipOutgoingDataFrames = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have data, but no targets. Silently discard all data
|
||||
clc.voipOutgoingDataSize = 0;
|
||||
clc.voipOutgoingDataFrames = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( count >= 1 ) {
|
||||
if ( cl_showSend->integer ) {
|
||||
Com_Printf( "(%i)", count );
|
||||
@@ -973,16 +1065,6 @@ void CL_WritePacket( void ) {
|
||||
}
|
||||
|
||||
CL_Netchan_Transmit (&clc.netchan, &buf);
|
||||
|
||||
// clients never really should have messages large enough
|
||||
// to fragment, but in case they do, fire them all off
|
||||
// at once
|
||||
// TTimo: this causes a packet burst, which is bad karma for winsock
|
||||
// added a WARNING message, we'll see if there are legit situations where this happens
|
||||
while ( clc.netchan.unsentFragments ) {
|
||||
Com_DPrintf( "WARNING: #462 unsent fragments (not supposed to happen!)\n" );
|
||||
CL_Netchan_TransmitNextFragment( &clc.netchan );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1094,6 +1176,85 @@ void CL_InitInput( void ) {
|
||||
Cmd_AddCommand("+mlook", IN_MLookDown);
|
||||
Cmd_AddCommand("-mlook", IN_MLookUp);
|
||||
|
||||
#ifdef USE_VOIP
|
||||
Cmd_AddCommand ("+voiprecord", IN_VoipRecordDown);
|
||||
Cmd_AddCommand ("-voiprecord", IN_VoipRecordUp);
|
||||
#endif
|
||||
|
||||
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0);
|
||||
cl_debugMove = Cvar_Get ("cl_debugMove", "0", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_ShutdownInput
|
||||
============
|
||||
*/
|
||||
void CL_ShutdownInput(void)
|
||||
{
|
||||
Cmd_RemoveCommand("centerview");
|
||||
|
||||
Cmd_RemoveCommand("+moveup");
|
||||
Cmd_RemoveCommand("-moveup");
|
||||
Cmd_RemoveCommand("+movedown");
|
||||
Cmd_RemoveCommand("-movedown");
|
||||
Cmd_RemoveCommand("+left");
|
||||
Cmd_RemoveCommand("-left");
|
||||
Cmd_RemoveCommand("+right");
|
||||
Cmd_RemoveCommand("-right");
|
||||
Cmd_RemoveCommand("+forward");
|
||||
Cmd_RemoveCommand("-forward");
|
||||
Cmd_RemoveCommand("+back");
|
||||
Cmd_RemoveCommand("-back");
|
||||
Cmd_RemoveCommand("+lookup");
|
||||
Cmd_RemoveCommand("-lookup");
|
||||
Cmd_RemoveCommand("+lookdown");
|
||||
Cmd_RemoveCommand("-lookdown");
|
||||
Cmd_RemoveCommand("+strafe");
|
||||
Cmd_RemoveCommand("-strafe");
|
||||
Cmd_RemoveCommand("+moveleft");
|
||||
Cmd_RemoveCommand("-moveleft");
|
||||
Cmd_RemoveCommand("+moveright");
|
||||
Cmd_RemoveCommand("-moveright");
|
||||
Cmd_RemoveCommand("+speed");
|
||||
Cmd_RemoveCommand("-speed");
|
||||
Cmd_RemoveCommand("+attack");
|
||||
Cmd_RemoveCommand("-attack");
|
||||
Cmd_RemoveCommand("+button0");
|
||||
Cmd_RemoveCommand("-button0");
|
||||
Cmd_RemoveCommand("+button1");
|
||||
Cmd_RemoveCommand("-button1");
|
||||
Cmd_RemoveCommand("+button2");
|
||||
Cmd_RemoveCommand("-button2");
|
||||
Cmd_RemoveCommand("+button3");
|
||||
Cmd_RemoveCommand("-button3");
|
||||
Cmd_RemoveCommand("+button4");
|
||||
Cmd_RemoveCommand("-button4");
|
||||
Cmd_RemoveCommand("+button5");
|
||||
Cmd_RemoveCommand("-button5");
|
||||
Cmd_RemoveCommand("+button6");
|
||||
Cmd_RemoveCommand("-button6");
|
||||
Cmd_RemoveCommand("+button7");
|
||||
Cmd_RemoveCommand("-button7");
|
||||
Cmd_RemoveCommand("+button8");
|
||||
Cmd_RemoveCommand("-button8");
|
||||
Cmd_RemoveCommand("+button9");
|
||||
Cmd_RemoveCommand("-button9");
|
||||
Cmd_RemoveCommand("+button10");
|
||||
Cmd_RemoveCommand("-button10");
|
||||
Cmd_RemoveCommand("+button11");
|
||||
Cmd_RemoveCommand("-button11");
|
||||
Cmd_RemoveCommand("+button12");
|
||||
Cmd_RemoveCommand("-button12");
|
||||
Cmd_RemoveCommand("+button13");
|
||||
Cmd_RemoveCommand("-button13");
|
||||
Cmd_RemoveCommand("+button14");
|
||||
Cmd_RemoveCommand("-button14");
|
||||
Cmd_RemoveCommand("+mlook");
|
||||
Cmd_RemoveCommand("-mlook");
|
||||
|
||||
#ifdef USE_VOIP
|
||||
Cmd_RemoveCommand("+voiprecord");
|
||||
Cmd_RemoveCommand("-voiprecord");
|
||||
#endif
|
||||
}
|
||||
@@ -148,7 +148,7 @@ void CL_Draw3DModel(
|
||||
|
||||
hModel[iCurrNum] = model;
|
||||
iIndex[iCurrNum] = -1;
|
||||
strcpy(szAnimName[iCurrNum], anim);
|
||||
Q_strncpyz(szAnimName[iCurrNum], anim, sizeof(szAnimName[iCurrNum]));
|
||||
} else {
|
||||
iCurrNum = i;
|
||||
|
||||
@@ -164,7 +164,7 @@ void CL_Draw3DModel(
|
||||
}
|
||||
} else {
|
||||
iIndex[iCurrNum] = -1;
|
||||
strcpy(szAnimName[iCurrNum], anim);
|
||||
Q_strncpyz(szAnimName[iCurrNum], anim, sizeof(szAnimName[iCurrNum]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -984,6 +984,8 @@ CL_InitKeyCommands
|
||||
*/
|
||||
void CL_InitKeyCommands(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// register our functions
|
||||
Cmd_AddCommand("bind", Key_Bind_f);
|
||||
Cmd_AddCommand("unbind", Key_Unbind_f);
|
||||
@@ -997,6 +999,10 @@ void CL_InitKeyCommands(void)
|
||||
Cmd_AddCommand("ctrlbindlist", Key_AltBindlist_f);
|
||||
|
||||
memset(menubound, 0, sizeof(menubound));
|
||||
|
||||
for (i = K_F1; i <= K_F15; i++) {
|
||||
menubound[i] = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1089,7 +1095,7 @@ void CL_KeyEvent(int key, qboolean down, unsigned time)
|
||||
|
||||
if (clc.state > CA_DISCONNECTED && cge && !Key_GetCatcher() && cge->CG_CheckCaptureKey(key, down, time)
|
||||
&& key != K_ESCAPE) {
|
||||
if (key == K_CONSOLE || (keys[K_SHIFT].down && key == K_ESCAPE)) {
|
||||
if (key != K_CONSOLE && (!keys[K_SHIFT].down || key != K_ESCAPE)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1134,9 +1140,9 @@ void CL_KeyEvent(int key, qboolean down, unsigned time)
|
||||
|
||||
if (key >= K_MOUSE1 && key <= K_MOUSE5) {
|
||||
if (down) {
|
||||
cl.mouseButtons |= (1 << (key + (256 - K_MOUSE1)));
|
||||
cl.mouseButtons |= (1 << (key - K_MOUSE1));
|
||||
} else {
|
||||
cl.mouseButtons &= ~(1 << (key + (256 - K_MOUSE1)));
|
||||
cl.mouseButtons &= ~(1 << (key - K_MOUSE1));
|
||||
}
|
||||
|
||||
if (in_guimouse) {
|
||||
@@ -1346,5 +1352,5 @@ Key_SetCatcher
|
||||
*/
|
||||
void Key_SetCatcher(int catcher)
|
||||
{
|
||||
keyCatchers = catcher;
|
||||
cls.keyCatchers = catcher;
|
||||
}
|
||||
+180
-204
@@ -56,6 +56,8 @@ cvar_t *cl_showTimeDelta;
|
||||
cvar_t *cl_freezeDemo;
|
||||
|
||||
cvar_t *cl_shownet;
|
||||
cvar_t *cl_netprofile;
|
||||
cvar_t *cl_netprofileoverlay;
|
||||
cvar_t *cl_showSend;
|
||||
cvar_t *cl_timedemo;
|
||||
cvar_t *cl_timedemoLog;
|
||||
@@ -118,6 +120,7 @@ cvar_t *cl_r_fullscreen;
|
||||
|
||||
cvar_t *cl_consoleKeys;
|
||||
cvar_t *name;
|
||||
cvar_t *cl_rate;
|
||||
|
||||
clientActive_t cl;
|
||||
clientConnection_t clc;
|
||||
@@ -167,8 +170,6 @@ void CL_ShowIP_f(void);
|
||||
void CL_ServerStatus_f(void);
|
||||
void CL_ServerStatusResponse( netadr_t from, msg_t *msg );
|
||||
|
||||
void CL_GamespyServers_f( void );
|
||||
|
||||
static qboolean cl_bCLSystemStarted = qfalse;
|
||||
|
||||
/*
|
||||
@@ -706,7 +707,7 @@ void CL_PlayDemo_f( void ) {
|
||||
|
||||
clc.state = CA_CONNECTED;
|
||||
clc.demoplaying = qtrue;
|
||||
Q_strncpyz( cls.servername, Cmd_Argv(1), sizeof( cls.servername ) );
|
||||
Q_strncpyz( clc.servername, Cmd_Argv(1), sizeof( clc.servername ) );
|
||||
|
||||
// read demo messages until connected
|
||||
while ( clc.state >= CA_CONNECTED && clc.state < CA_PRIMED ) {
|
||||
@@ -832,7 +833,7 @@ void CL_MapLoading( qboolean flush, const char *pszMapName ) {
|
||||
|
||||
if (pszMapName) {
|
||||
// if we are already connected to the local host, stay connected
|
||||
if (clc.state >= CA_CONNECTED && !Q_stricmp(cls.servername, "localhost")) {
|
||||
if (clc.state >= CA_CONNECTED && !Q_stricmp(clc.servername, "localhost")) {
|
||||
clc.state = CA_CONNECTED; // so the connect screen is drawn
|
||||
Com_Memset(cls.updateInfoString, 0, sizeof(cls.updateInfoString));
|
||||
Com_Memset(clc.serverMessage, 0, sizeof(clc.serverMessage));
|
||||
@@ -843,11 +844,11 @@ void CL_MapLoading( qboolean flush, const char *pszMapName ) {
|
||||
// clear nextmap so the cinematic shutdown doesn't execute it
|
||||
Cvar_Set("nextmap", "");
|
||||
CL_Disconnect();
|
||||
Q_strncpyz(cls.servername, "localhost", sizeof(cls.servername));
|
||||
Q_strncpyz(clc.servername, "localhost", sizeof(clc.servername));
|
||||
clc.state = CA_CHALLENGING; // so the connect screen is drawn
|
||||
clc.connectStartTime = cls.realtime;
|
||||
clc.connectTime = -RETRANSMIT_TIMEOUT;
|
||||
NET_StringToAdr(cls.servername, &clc.serverAddress, NA_UNSPEC);
|
||||
NET_StringToAdr(clc.servername, &clc.serverAddress, NA_UNSPEC);
|
||||
// we don't need a challenge on the localhost
|
||||
|
||||
CL_CheckForResend();
|
||||
@@ -912,6 +913,8 @@ This is also called on Com_Error and Com_Quit, so it shouldn't cause any errors
|
||||
=====================
|
||||
*/
|
||||
void CL_Disconnect() {
|
||||
int mouseX, mouseY;
|
||||
|
||||
if ( !com_cl_running || !com_cl_running->integer ) {
|
||||
return;
|
||||
}
|
||||
@@ -947,8 +950,16 @@ void CL_Disconnect() {
|
||||
CL_WritePacket();
|
||||
}
|
||||
|
||||
// Fixed in OPM
|
||||
// Don't reset the mouse every time the client disconnects
|
||||
mouseX = cl.mousex;
|
||||
mouseY = cl.mousey;
|
||||
|
||||
CL_ClearState ();
|
||||
|
||||
cl.mousex = mouseX;
|
||||
cl.mousey = mouseY;
|
||||
|
||||
// wipe the client connection
|
||||
Com_Memset( &clc, 0, sizeof( clientConnection_t ) );
|
||||
|
||||
@@ -1049,7 +1060,7 @@ void CL_RequestMotd( void ) {
|
||||
Info_SetValueForKey( info, "renderer", cls.glconfig.renderer_string );
|
||||
Info_SetValueForKey( info, "version", com_version->string );
|
||||
|
||||
NET_OutOfBandPrint( NS_CLIENT, cls.updateServer, "getmotd \"%s\"\n", info );
|
||||
CL_NET_OutOfBandPrint( cls.updateServer, "getmotd \"%s\"\n", info );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1132,7 +1143,7 @@ void CL_RequestAuthorization( void ) {
|
||||
|
||||
fs = Cvar_Get ("cl_anonymous", "0", CVAR_INIT|CVAR_SYSTEMINFO );
|
||||
|
||||
NET_OutOfBandPrint(NS_CLIENT, cls.authorizeServer, "getKeyAuthorize %i %s", fs->integer, nums );
|
||||
CL_NET_OutOfBandPrint(cls.authorizeServer, "getKeyAuthorize %i %s", fs->integer, nums );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1174,12 +1185,12 @@ void CL_Setenv_f( void ) {
|
||||
char buffer[1024];
|
||||
int i;
|
||||
|
||||
strcpy( buffer, Cmd_Argv(1) );
|
||||
strcat( buffer, "=" );
|
||||
Q_strncpyz( buffer, Cmd_Argv(1), sizeof( buffer ) );
|
||||
Q_strcat( buffer, sizeof( buffer ), "=" );
|
||||
|
||||
for ( i = 2; i < argc; i++ ) {
|
||||
strcat( buffer, Cmd_Argv( i ) );
|
||||
strcat( buffer, " " );
|
||||
Q_strcat( buffer, sizeof( buffer ), Cmd_Argv( i ) );
|
||||
Q_strcat( buffer, sizeof( buffer ), " " );
|
||||
}
|
||||
|
||||
putenv( buffer );
|
||||
@@ -1201,28 +1212,32 @@ CL_Disconnect_f
|
||||
==================
|
||||
*/
|
||||
void CL_Disconnect_f( void ) {
|
||||
if ( clc.state != CA_DISCONNECTED ) {
|
||||
qboolean bConsoleState = UI_ConsoleIsOpen();
|
||||
qboolean bConsoleState;
|
||||
|
||||
Com_Printf("\nDisconnected from server\n");
|
||||
SV_Shutdown("Disconnected from server\n");
|
||||
if ( clc.state == CA_DISCONNECTED ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (com_cl_running && com_cl_running->integer)
|
||||
{
|
||||
CL_AbnormalDisconnect();
|
||||
CL_FlushMemory();
|
||||
CL_StartHunkUsers(qfalse);
|
||||
S_StopAllSounds2(1);
|
||||
S_TriggeredMusic_PlayIntroMusic();
|
||||
}
|
||||
bConsoleState = UI_ConsoleIsOpen();
|
||||
|
||||
UI_FocusMenuIfExists();
|
||||
Com_Printf("\nDisconnected from server\n");
|
||||
SV_Shutdown("Disconnected from server\n");
|
||||
|
||||
if (bConsoleState) {
|
||||
UI_OpenConsole();
|
||||
} else {
|
||||
UI_CloseConsole();
|
||||
}
|
||||
if (com_cl_running && com_cl_running->integer)
|
||||
{
|
||||
CL_AbnormalDisconnect();
|
||||
CL_FlushMemory();
|
||||
CL_StartHunkUsers(qfalse);
|
||||
S_StopAllSounds2(1);
|
||||
S_TriggeredMusic_PlayIntroMusic();
|
||||
}
|
||||
|
||||
UI_FocusMenuIfExists();
|
||||
|
||||
if (bConsoleState) {
|
||||
UI_OpenConsole();
|
||||
} else {
|
||||
UI_CloseConsole();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1234,12 +1249,12 @@ CL_Reconnect_f
|
||||
================
|
||||
*/
|
||||
void CL_Reconnect_f( void ) {
|
||||
if ( !strlen( cls.servername ) || !strcmp( cls.servername, "localhost" ) ) {
|
||||
if ( !strlen( clc.servername ) || !strcmp( clc.servername, "localhost" ) ) {
|
||||
Com_Printf( "Can't reconnect to localhost.\n" );
|
||||
return;
|
||||
}
|
||||
Cvar_Set("ui_singlePlayerActive", "0");
|
||||
Cbuf_AddText( va("connect %s\n", cls.servername ) );
|
||||
Cbuf_AddText( va("connect %s\n", clc.servername ) );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1275,9 +1290,9 @@ void CL_Connect( const char *server, netadrtype_t family ) {
|
||||
CL_FlushMemory( );
|
||||
*/
|
||||
|
||||
Q_strncpyz( cls.servername, server, sizeof( cls.servername ) );
|
||||
Q_strncpyz( clc.servername, server, sizeof( clc.servername ) );
|
||||
|
||||
if( !NET_StringToAdr( cls.servername, &clc.serverAddress, family ) ) {
|
||||
if( !NET_StringToAdr( clc.servername, &clc.serverAddress, family ) ) {
|
||||
Com_Printf( "Bad server address\n" );
|
||||
clc.state = CA_DISCONNECTED;
|
||||
UI_PushMenu("badserveraddy");
|
||||
@@ -1288,7 +1303,7 @@ void CL_Connect( const char *server, netadrtype_t family ) {
|
||||
}
|
||||
serverString = NET_AdrToStringwPort(clc.serverAddress);
|
||||
|
||||
Com_Printf( "%s resolved to %s\n", cls.servername, serverString );
|
||||
Com_Printf( "%s resolved to %s\n", clc.servername, serverString );
|
||||
|
||||
if (cl_guidServerUniq->integer)
|
||||
CL_UpdateGUID(serverString, strlen(serverString));
|
||||
@@ -1464,7 +1479,11 @@ void CL_Rcon_f( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
NET_SendPacket (NS_CLIENT, strlen(message)+1, message, to);
|
||||
NET_SendPacket (NS_CLIENT, strlen(message) + 1, message, to);
|
||||
|
||||
if (cl_netprofile->integer) {
|
||||
NetProfileAddPacket(&cls.netprofile.inPackets, strlen(message) + 1, NETPROF_PACKET_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1483,7 +1502,6 @@ void CL_SendPureChecksums( void ) {
|
||||
// "cp"
|
||||
// "Yf"
|
||||
Com_sprintf(cMsg, sizeof(cMsg), "Yf ");
|
||||
Q_strcat(cMsg, sizeof(cMsg), va("%d ", cl.serverId) );
|
||||
Q_strcat(cMsg, sizeof(cMsg), pChecksums);
|
||||
for (i = 0; i < 2; i++) {
|
||||
cMsg[i] += '\n';
|
||||
@@ -1707,7 +1725,7 @@ CL_Clientinfo_f
|
||||
void CL_Clientinfo_f( void ) {
|
||||
Com_Printf( "--------- Client Information ---------\n" );
|
||||
Com_Printf( "state: %i\n", clc.state );
|
||||
Com_Printf( "Server: %s\n", cls.servername );
|
||||
Com_Printf( "Server: %s\n", clc.servername );
|
||||
Com_Printf ("User info settings:\n");
|
||||
Info_Print( Cvar_InfoString( CVAR_USERINFO ) );
|
||||
Com_Printf( "--------------------------------------\n" );
|
||||
@@ -1908,7 +1926,7 @@ void CL_InitDownloads(void) {
|
||||
if (FS_ComparePaks( missingfiles, sizeof( missingfiles ), qfalse ) )
|
||||
{
|
||||
// NOTE TTimo I would rather have that printed as a modal message box
|
||||
// but at this point while joining the game we don't know wether we will successfully join or not
|
||||
// but at this point while joining the game we don't know whether we will successfully join or not
|
||||
Com_Printf( "\nWARNING: You are missing some files referenced by the server:\n%s"
|
||||
"You might not be able to join the game\n"
|
||||
"Go to the setting menu to turn on autodownload, or get the file elsewhere\n\n", missingfiles );
|
||||
@@ -1967,12 +1985,12 @@ void CL_CheckForResend( void ) {
|
||||
// if ( !Sys_IsLANAddress( clc.serverAddress ) ) {
|
||||
// CL_RequestAuthorization();
|
||||
// }
|
||||
NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "getchallenge");
|
||||
CL_NET_OutOfBandPrint(clc.serverAddress, "getchallenge");
|
||||
break;
|
||||
case CA_AUTHORIZING:
|
||||
// resend the cd key authorization
|
||||
gcd_compute_response(cl_cdkey, Cmd_Argv(1), cls.gcdResponse, CDResponseMethod_REAUTH);
|
||||
NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "authorizeThis %s", cls.gcdResponse);
|
||||
CL_NET_OutOfBandPrint(clc.serverAddress, "authorizeThis %s", cls.gcdResponse);
|
||||
break;
|
||||
case CA_CHALLENGING:
|
||||
/*
|
||||
@@ -1996,13 +2014,13 @@ wombat: sending conect here: an example connect string from MOHAA looks like thi
|
||||
Info_SetValueForKey(info, "protocol", va("%i", com_protocol->integer));
|
||||
Info_SetValueForKey( info, "qport", va("%i", port ) );
|
||||
Info_SetValueForKey(info, "challenge", va("%i", clc.challenge));
|
||||
Info_SetValueForKey(info, "version", com_shortversion->string);
|
||||
Info_SetValueForKey(info, "version", com_target_version->string);
|
||||
if (com_target_game->integer == target_game_e::TG_MOHTT) {
|
||||
// only send if maintt is loaded
|
||||
Info_SetValueForKey(info, "clientType", "Breakthrough");
|
||||
}
|
||||
|
||||
strcpy(data, "connect ");
|
||||
Q_strncpyz(data, "connect ", sizeof(data));
|
||||
// TTimo adding " " around the userinfo string to avoid truncated userinfo on the server
|
||||
// (Com_TokenizeString tokenizes around spaces)
|
||||
data[8] = '"';
|
||||
@@ -2235,6 +2253,10 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
||||
char *s;
|
||||
char *c;
|
||||
const char *reason;
|
||||
|
||||
if (cl_netprofile->integer) {
|
||||
NetProfileAddPacket(&cls.netprofile.inPackets, msg->cursize, NETPROF_PACKET_MESSAGE);
|
||||
}
|
||||
|
||||
MSG_BeginReadingOOB( msg );
|
||||
MSG_ReadLong( msg ); // skip the -1
|
||||
@@ -2319,7 +2341,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
||||
|
||||
// echo request from server
|
||||
if ( !Q_stricmp(c, "echo") ) {
|
||||
NET_OutOfBandPrint( NS_CLIENT, from, "%s", Cmd_Argv(1) );
|
||||
CL_NET_OutOfBandPrint(from, "%s", Cmd_Argv(1) );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2327,7 +2349,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
||||
if ( !Q_stricmp(c, "getKey") ) {
|
||||
clc.state = CA_AUTHORIZING;
|
||||
gcd_compute_response(cl_cdkey, Cmd_Argv(1), cls.gcdResponse, CDResponseMethod_NEWAUTH);
|
||||
NET_OutOfBandPrint(NS_CLIENT, from, "authorizeThis %s", cls.gcdResponse);
|
||||
CL_NET_OutOfBandPrint(from, "authorizeThis %s", cls.gcdResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2575,12 +2597,17 @@ void CL_Frame ( int msec ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( clc.state == CA_DISCONNECTED && !UI_MenuActive()
|
||||
&& !com_sv_running->integer ) {
|
||||
// if disconnected, bring up the menu
|
||||
S_StopAllSounds2( qtrue );
|
||||
S_TriggeredMusic_PlayIntroMusic();
|
||||
UI_MenuEscape( "main" );
|
||||
if (CL_FinishedIntro()) {
|
||||
if (clc.state == CA_DISCONNECTED) {
|
||||
if (!UI_MenuActive() && !com_sv_running->integer) {
|
||||
// if disconnected, bring up the menu
|
||||
S_StopAllSounds2(qtrue);
|
||||
S_TriggeredMusic_PlayIntroMusic();
|
||||
UI_MenuEscape("main");
|
||||
}
|
||||
} else if (clc.state == CA_CINEMATIC) {
|
||||
UI_ForceMenuOff(qtrue);
|
||||
}
|
||||
}
|
||||
|
||||
// if recording an avi, lock to a fixed fps
|
||||
@@ -2615,7 +2642,7 @@ void CL_Frame ( int msec ) {
|
||||
now.tm_min,
|
||||
now.tm_sec );
|
||||
|
||||
Q_strncpyz( serverName, cls.servername, MAX_OSPATH );
|
||||
Q_strncpyz( serverName, clc.servername, MAX_OSPATH );
|
||||
// Replace the ":" in the address as it is not a valid
|
||||
// file name character
|
||||
p = strstr( serverName, ":" );
|
||||
@@ -2649,6 +2676,31 @@ void CL_Frame ( int msec ) {
|
||||
|
||||
cls.timeScaled = com_timescale->integer != 1;
|
||||
|
||||
//
|
||||
// Added in 2.0: network profiling
|
||||
//
|
||||
if (cl_netprofile->integer) {
|
||||
if (!cls.netprofile.initialized) {
|
||||
memset(&cls.netprofile, 0, sizeof(cls.netprofile));
|
||||
cls.netprofile.initialized = qtrue;
|
||||
}
|
||||
|
||||
if (cls.netprofile.rate != cl_rate->integer) {
|
||||
cls.netprofile.rate = cl_rate->integer;
|
||||
|
||||
if (cls.netprofile.rate < 1000) {
|
||||
cls.netprofile.rate = 1000;
|
||||
} else if (cls.netprofile.rate > 90000) {
|
||||
cls.netprofile.rate = 90000;
|
||||
}
|
||||
}
|
||||
|
||||
cls.netprofile.outPackets.updateTime = Com_Milliseconds();
|
||||
cls.netprofile.inPackets.updateTime = cls.netprofile.outPackets.updateTime;
|
||||
} else {
|
||||
cls.netprofile.initialized = qfalse;
|
||||
}
|
||||
|
||||
// see if we need to update any userinfo
|
||||
CL_CheckUserinfo();
|
||||
|
||||
@@ -2859,7 +2911,7 @@ void CL_RefStaticClear( void ) {
|
||||
CL_CG_PermanentMark
|
||||
============
|
||||
*/
|
||||
int CL_CG_PermanentMark(const vec3_t origin, const vec3_t dir, float orientation,
|
||||
int CL_CG_PermanentMark(vec3_t origin, vec3_t dir, float orientation,
|
||||
float fSScale, float fTScale, float red, float green, float blue, float alpha,
|
||||
qboolean dolighting, float fSCenter, float fTCenter,
|
||||
markFragment_t *pMarkFragments, void *pPolyVerts )
|
||||
@@ -3123,7 +3175,7 @@ void CL_VidMode_f( void ) {
|
||||
mode = atoi( Cmd_Argv( 1 ) );
|
||||
|
||||
if( CL_SetVidMode( mode ) ) {
|
||||
sprintf( text, "%d", mode );
|
||||
Com_sprintf( text, sizeof( text ), "%d", mode );
|
||||
Cvar_Set( "r_mode", text );
|
||||
}
|
||||
}
|
||||
@@ -3142,10 +3194,10 @@ void CL_TikiInfoCommand_f( void ) {
|
||||
name = Cmd_Argv( 1 );
|
||||
|
||||
if( strchr( name, '/' ) ) {
|
||||
strcpy( modelname, name );
|
||||
Q_strncpyz( modelname, name, sizeof( modelname ) );
|
||||
} else {
|
||||
strcpy( modelname, "models/" );
|
||||
strcat( modelname, name );
|
||||
Q_strncpyz( modelname, "models/", sizeof( modelname ) );
|
||||
Q_strcat( modelname, sizeof( modelname ), name );
|
||||
}
|
||||
|
||||
COM_DefaultExtension( modelname, sizeof( modelname ), ".tik" );
|
||||
@@ -3237,8 +3289,6 @@ it by filling it with 2048 bytes of random data.
|
||||
*/
|
||||
static void CL_GenerateQKey(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
/*
|
||||
int len = 0;
|
||||
unsigned char buff[ QKEY_SIZE ];
|
||||
fileHandle_t f;
|
||||
@@ -3268,7 +3318,6 @@ static void CL_GenerateQKey(void)
|
||||
FS_FCloseFile( f );
|
||||
Com_Printf( "QKEY generated\n" );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3316,6 +3365,8 @@ void CL_Init( void ) {
|
||||
cl_master = Cvar_Get ("cl_master", MASTER_SERVER_NAME, CVAR_ARCHIVE);
|
||||
cl_timeNudge = Cvar_Get ("cl_timeNudge", "0", CVAR_TEMP );
|
||||
cl_shownet = Cvar_Get ("cl_shownet", "0", CVAR_TEMP );
|
||||
cl_netprofile = Cvar_Get("cl_netprofile", "0", CVAR_TEMP);
|
||||
cl_netprofileoverlay = Cvar_Get("cl_netprofileoverlay", "0", CVAR_TEMP);
|
||||
cl_showSend = Cvar_Get ("cl_showSend", "0", CVAR_TEMP );
|
||||
cl_showTimeDelta = Cvar_Get ("cl_showTimeDelta", "0", CVAR_TEMP );
|
||||
cl_freezeDemo = Cvar_Get ("cl_freezeDemo", "0", CVAR_TEMP );
|
||||
@@ -3431,7 +3482,7 @@ void CL_Init( void ) {
|
||||
|
||||
// userinfo
|
||||
name = Cvar_Get ("name", "UnnamedSoldier", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("rate", "5000", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
cl_rate = Cvar_Get ("rate", "5000", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("snaps", "20", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
Cvar_Get ("password", "", CVAR_USERINFO);
|
||||
Cvar_Get ("dm_playermodel", "american_army", CVAR_USERINFO | CVAR_ARCHIVE );
|
||||
@@ -3463,7 +3514,6 @@ void CL_Init( void ) {
|
||||
Cmd_AddCommand ("reconnect", CL_Reconnect_f);
|
||||
Cmd_AddCommand ("localservers", CL_LocalServers_f);
|
||||
Cmd_AddCommand ("globalservers", CL_GlobalServers_f);
|
||||
Cmd_AddCommand ("refreshserverlist", CL_GamespyServers_f); // wombat: gamespy query
|
||||
Cmd_AddCommand ("rcon", CL_Rcon_f);
|
||||
Cmd_AddCommand ("setenv", CL_Setenv_f );
|
||||
Cmd_AddCommand ("ping", CL_Ping_f );
|
||||
@@ -3498,7 +3548,6 @@ void CL_Init( void ) {
|
||||
S_Init(qtrue);
|
||||
#endif
|
||||
|
||||
// fixme: should we leave it?
|
||||
CL_GenerateQKey();
|
||||
Cvar_Get( "cl_guid", "", CVAR_USERINFO | CVAR_ROM );
|
||||
CL_UpdateGUID( NULL, 0 );
|
||||
@@ -3569,6 +3618,8 @@ void CL_Shutdown(const char* finalmsg, qboolean disconnect, qboolean quit) {
|
||||
Cmd_RemoveCommand ("video");
|
||||
Cmd_RemoveCommand ("stopvideo");
|
||||
|
||||
CL_ShutdownInput();
|
||||
|
||||
Cvar_Set( "cl_running", "0" );
|
||||
|
||||
recursive = qfalse;
|
||||
@@ -3588,6 +3639,7 @@ static void CL_SetServerInfo(serverInfo_t *server, const char *info, int ping) {
|
||||
server->maxClients = atoi(Info_ValueForKey(info, "sv_maxclients"));
|
||||
Q_strncpyz(server->game,Info_ValueForKey(info, "game"), MAX_NAME_LENGTH);
|
||||
server->gameType = atoi(Info_ValueForKey(info, "gametype"));
|
||||
Q_strncpyz(server->gameTypeString, Info_ValueForKey(info, "gametypestring"), sizeof(server->gameTypeString));
|
||||
server->netType = atoi(Info_ValueForKey(info, "nettype"));
|
||||
server->minPing = atoi(Info_ValueForKey(info, "minping"));
|
||||
server->maxPing = atoi(Info_ValueForKey(info, "maxping"));
|
||||
@@ -3636,6 +3688,8 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
||||
char *infoString;
|
||||
int prot;
|
||||
char *gamename;
|
||||
char *pszVersion;
|
||||
char *pszServerType;
|
||||
qboolean gameMismatch;
|
||||
|
||||
infoString = MSG_ReadString( msg );
|
||||
@@ -3664,12 +3718,42 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
&& prot != com_legacyprotocol->integer
|
||||
#endif
|
||||
&& (com_target_demo->integer || prot != protocol_version_demo)
|
||||
)
|
||||
{
|
||||
Com_DPrintf( "Different protocol info packet: %s\n", infoString );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!com_target_demo->integer && protocol_version_demo != protocol_version_full && prot == protocol_version_demo) {
|
||||
Com_DPrintf("Full version found compatible demo protocol version. %s\n", infoString);
|
||||
}
|
||||
|
||||
pszVersion = Info_ValueForKey(infoString, "gamever");
|
||||
pszServerType = Info_ValueForKey(infoString, "serverType");
|
||||
|
||||
if (*pszVersion) {
|
||||
if (*pszVersion == 'd') {
|
||||
pszVersion++;
|
||||
}
|
||||
|
||||
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
|
||||
if (atoi(pszServerType) == target_game_e::TG_MOHTT) {
|
||||
if (fabs(atof(pszVersion)) < 2.3f) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (fabs(atof(pszVersion)) < 2.1f) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (fabs(atof(pszVersion) - com_target_version->value) > 0.1f) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate servers waiting for ping response
|
||||
for (i=0; i<MAX_PINGREQUESTS; i++)
|
||||
{
|
||||
@@ -3815,7 +3899,7 @@ int CL_ServerStatus( const char *serverAddress, char *serverStatusString, int ma
|
||||
serverStatus->retrieved = qfalse;
|
||||
serverStatus->time = 0;
|
||||
serverStatus->startTime = Com_Milliseconds();
|
||||
NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" );
|
||||
CL_NET_OutOfBandPrint(to, "getstatus" );
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
@@ -3827,7 +3911,7 @@ int CL_ServerStatus( const char *serverAddress, char *serverStatusString, int ma
|
||||
serverStatus->retrieved = qfalse;
|
||||
serverStatus->startTime = Com_Milliseconds();
|
||||
serverStatus->time = 0;
|
||||
NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" );
|
||||
CL_NET_OutOfBandPrint(to, "getstatus" );
|
||||
return qfalse;
|
||||
}
|
||||
return qfalse;
|
||||
@@ -3839,10 +3923,10 @@ CL_ServerStatusResponse
|
||||
===================
|
||||
*/
|
||||
void CL_ServerStatusResponse( netadr_t from, msg_t *msg ) {
|
||||
char *s;
|
||||
char info[MAX_INFO_STRING];
|
||||
int i, l, score, ping;
|
||||
int len;
|
||||
const char *s;
|
||||
char info[MAX_INFO_STRING];
|
||||
int i, l, score, ping;
|
||||
int len;
|
||||
serverStatus_t *serverStatus;
|
||||
|
||||
serverStatus = NULL;
|
||||
@@ -3966,133 +4050,22 @@ void CL_LocalServers_f( void ) {
|
||||
|
||||
to.type = NA_BROADCAST;
|
||||
NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
|
||||
|
||||
if (cl_netprofile->integer) {
|
||||
NetProfileAddPacket(&cls.netprofile.inPackets, strlen( message ), NETPROF_PACKET_MESSAGE);
|
||||
}
|
||||
|
||||
// Added in OPM (from ioquake3)
|
||||
to.type = NA_MULTICAST6;
|
||||
NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
|
||||
|
||||
if (cl_netprofile->integer) {
|
||||
NetProfileAddPacket(&cls.netprofile.inPackets, strlen(message), NETPROF_PACKET_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_GamespyServers_f
|
||||
==================
|
||||
*/
|
||||
// currently about 1000 mohaa servers at a time. when set higher, buffer must be increased!
|
||||
#define MAX_GAMESPYSERVERS 16
|
||||
|
||||
void CL_GamespyServers_f( void ) {
|
||||
// FIXME: unimplemented
|
||||
#if 0
|
||||
char buffer[10240];
|
||||
int bytesRead;
|
||||
|
||||
int i, count, max, total;
|
||||
serverAddress_t addresses[MAX_GAMESPYSERVERS];
|
||||
int numservers;
|
||||
byte* buffptr;
|
||||
byte* buffend;
|
||||
|
||||
// if ( Cmd_Argc() < 1) {
|
||||
// Com_Printf( "usage: gamespyservers [keywords]\n");
|
||||
// return;
|
||||
// }
|
||||
|
||||
Com_Printf( "Requesting servers from the GameSpy master...\n" );
|
||||
Cvar_Set( "dm_serverstatus", "Getting List.");
|
||||
|
||||
|
||||
if (!NETGS_CreateMasterSocket()) {
|
||||
Com_Printf( "CL_GamespyServers_f: could not create socket.\n" );
|
||||
return;
|
||||
}
|
||||
if (!NETGS_SendMasterRequest()) {
|
||||
Com_Printf( "CL_GamespyServers_f: could not send master request.\n" );
|
||||
return;
|
||||
}
|
||||
bytesRead = NETGS_ReceiveMasterResponse( buffer, sizeof(buffer) );
|
||||
if (!bytesRead) {
|
||||
Com_Printf( "CL_GamespyServers_f: Error in Response.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// parse through server response string
|
||||
numservers = 0;
|
||||
buffptr = ( byte * )buffer;
|
||||
buffend = buffptr + bytesRead;
|
||||
|
||||
while (buffptr+1 < buffend) {
|
||||
if ( buffptr >= buffend - 6 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// parse out ip
|
||||
addresses[numservers].ip[0] = *buffptr++;
|
||||
addresses[numservers].ip[1] = *buffptr++;
|
||||
addresses[numservers].ip[2] = *buffptr++;
|
||||
addresses[numservers].ip[3] = *buffptr++;
|
||||
|
||||
// parse out port
|
||||
addresses[numservers].port = *buffptr++;
|
||||
addresses[numservers].port += (*buffptr++) << 8;
|
||||
|
||||
Com_DPrintf( "server: %d ip: %d.%d.%d.%d:%d\n",numservers,
|
||||
addresses[numservers].ip[0],
|
||||
addresses[numservers].ip[1],
|
||||
addresses[numservers].ip[2],
|
||||
addresses[numservers].ip[3],
|
||||
BigShort(addresses[numservers].port) );
|
||||
|
||||
numservers++;
|
||||
if (numservers >= MAX_GAMESPYSERVERS) {
|
||||
break;
|
||||
}
|
||||
|
||||
// parse out "\\final\\"
|
||||
if (buffptr[0] == '\\' && buffptr[1] == 'f' && buffptr[2] == 'i' && buffptr[3] == 'n' && buffptr[4] == 'a' && buffptr[6] == 'l' && buffptr[6] == '\\') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cls.numglobalservers = 0;
|
||||
cls.numGlobalServerAddresses = 0;
|
||||
|
||||
count = cls.numglobalservers;
|
||||
max = MAX_GLOBAL_SERVERS;
|
||||
for (i = 0; i < numservers && count < max; i++) {
|
||||
// build net address
|
||||
serverInfo_t *server = &cls.globalServers[count];
|
||||
|
||||
CL_InitServerInfo( server, &addresses[i] );
|
||||
// advance to next slot
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
if ( cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS ) {
|
||||
// if we couldn't store the servers in the main list anymore
|
||||
for (; i < numservers && count >= max; i++) {
|
||||
serverAddress_t *addr;
|
||||
// just store the addresses in an additional list
|
||||
addr = &cls.globalServerAddresses[cls.numGlobalServerAddresses++];
|
||||
addr->ip[0] = addresses[i].ip[0];
|
||||
addr->ip[1] = addresses[i].ip[1];
|
||||
addr->ip[2] = addresses[i].ip[2];
|
||||
addr->ip[3] = addresses[i].ip[3];
|
||||
addr->port = addresses[i].port;
|
||||
}
|
||||
}
|
||||
|
||||
cls.numglobalservers = count;
|
||||
total = count + cls.numGlobalServerAddresses;
|
||||
|
||||
Com_Printf("%d servers parsed (total %d)\n", numservers, total);
|
||||
Cvar_Set( "dm_serverstatus", "Server List Received.");
|
||||
Cvar_SetValue( "dm_servercount", total );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_GlobalServers_f
|
||||
@@ -4118,7 +4091,7 @@ void CL_GlobalServers_f( void ) {
|
||||
int numAddress = 0;
|
||||
|
||||
for ( i = 1; i <= MAX_MASTER_SERVERS; i++ ) {
|
||||
sprintf(command, "sv_master%d", i);
|
||||
Com_sprintf(command, sizeof(command), "sv_master%d", i);
|
||||
masteraddress = Cvar_VariableString(command);
|
||||
|
||||
if(!*masteraddress)
|
||||
@@ -4136,7 +4109,7 @@ void CL_GlobalServers_f( void ) {
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(command, "sv_master%d", masterNum);
|
||||
Com_sprintf(command, sizeof(command), "sv_master%d", masterNum);
|
||||
masteraddress = Cvar_VariableString(command);
|
||||
|
||||
if(!*masteraddress)
|
||||
@@ -4192,7 +4165,7 @@ void CL_GlobalServers_f( void ) {
|
||||
Q_strcat(command, sizeof(command), Cmd_Argv(i));
|
||||
}
|
||||
|
||||
NET_OutOfBandPrint( NS_SERVER, to, "%s", command );
|
||||
CL_NET_OutOfBandPrint( to, "%s", command );
|
||||
}
|
||||
|
||||
|
||||
@@ -4412,7 +4385,7 @@ void CL_Ping_f( void ) {
|
||||
|
||||
CL_SetServerInfoByAddress(pingptr->adr, NULL, 0);
|
||||
|
||||
NET_OutOfBandPrint( NS_CLIENT, to, "\x02getinfo xxx" );
|
||||
CL_NET_OutOfBandPrint( to, "\x02getinfo xxx" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4465,10 +4438,10 @@ void CL_Dialog_f( void ) {
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy( title, Cmd_Argv( 1 ) );
|
||||
strcpy( cvar, Cmd_Argv( 2 ) );
|
||||
strcpy( command, Cmd_Argv( 3 ) );
|
||||
strcpy( cancelCommand, Cmd_Argv( 4 ) );
|
||||
Q_strncpyz( title, Cmd_Argv( 1 ), sizeof( title ) );
|
||||
Q_strncpyz( cvar, Cmd_Argv( 2 ), sizeof( cvar ) );
|
||||
Q_strncpyz( command, Cmd_Argv( 3 ), sizeof( command ) );
|
||||
Q_strncpyz( cancelCommand, Cmd_Argv( 4 ), sizeof( cancelCommand ) );
|
||||
|
||||
if( Cmd_Argc() > 5 ) {
|
||||
width = atoi( Cmd_Argv( 5 ) );
|
||||
@@ -4482,17 +4455,17 @@ void CL_Dialog_f( void ) {
|
||||
}
|
||||
|
||||
if( Cmd_Argc() > 7 ) {
|
||||
strcpy( shader, Cmd_Argv( 7 ) );
|
||||
Q_strncpyz( shader, Cmd_Argv( 7 ), sizeof( shader ) );
|
||||
} else {
|
||||
shader[ 0 ] = 0;
|
||||
}
|
||||
if( Cmd_Argc() > 8 ) {
|
||||
strcpy( okshader, Cmd_Argv( 8 ) );
|
||||
Q_strncpyz( okshader, Cmd_Argv( 8 ), sizeof(okshader) );
|
||||
} else {
|
||||
okshader[ 0 ] = 0;
|
||||
}
|
||||
if( Cmd_Argc() > 9 ) {
|
||||
strcpy( cancelshader, Cmd_Argv( 9 ) );
|
||||
Q_strncpyz( cancelshader, Cmd_Argv( 9 ), sizeof(cancelshader) );
|
||||
} else {
|
||||
cancelshader[ 0 ] = 0;
|
||||
}
|
||||
@@ -4506,7 +4479,10 @@ CL_ServerRestarted
|
||||
==================
|
||||
*/
|
||||
void CL_ServerRestarted( void ) {
|
||||
S_StopAllSounds2( qfalse );
|
||||
//S_StopAllSounds2( qfalse );
|
||||
// Fixed in OPM
|
||||
// Also stop the music
|
||||
S_StopAllSounds2( qtrue );
|
||||
|
||||
UI_ServerLoaded();
|
||||
UI_ClearState();
|
||||
@@ -4579,7 +4555,7 @@ qboolean CL_UpdateVisiblePings_f(int source) {
|
||||
memcpy(&cl_pinglist[j].adr, &server[i].adr, sizeof(netadr_t));
|
||||
cl_pinglist[j].start = Sys_Milliseconds();
|
||||
cl_pinglist[j].time = 0;
|
||||
NET_OutOfBandPrint( NS_CLIENT, cl_pinglist[j].adr, "getinfo xxx" );
|
||||
CL_NET_OutOfBandPrint( cl_pinglist[j].adr, "getinfo xxx" );
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
@@ -4667,7 +4643,7 @@ void CL_ServerStatus_f(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
NET_OutOfBandPrint( NS_CLIENT, *toptr, "getstatus" );
|
||||
CL_NET_OutOfBandPrint( *toptr, "getstatus" );
|
||||
|
||||
serverStatus = CL_GetServerStatus( *toptr );
|
||||
serverStatus->address = *toptr;
|
||||
@@ -4736,7 +4712,7 @@ qboolean CL_CDKeyValidate( const char *key, const char *checksum ) {
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(chs, "%02x", sum);
|
||||
Com_sprintf(chs, sizeof(chs), "%02x", sum);
|
||||
|
||||
if (checksum && !Q_stricmp(chs, checksum)) {
|
||||
return qtrue;
|
||||
|
||||
@@ -132,7 +132,7 @@ CL_Netchan_TransmitNextFragment
|
||||
=================
|
||||
*/
|
||||
void CL_Netchan_TransmitNextFragment( netchan_t *chan ) {
|
||||
Netchan_TransmitNextFragment( chan );
|
||||
Netchan_TransmitNextFragment( chan, cl_netprofile->integer ? &cls.netprofile.inPackets : NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -144,7 +144,7 @@ void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg ) {
|
||||
MSG_WriteByte( msg, clc_EOF );
|
||||
|
||||
CL_Netchan_Encode( msg );
|
||||
Netchan_Transmit( chan, msg->cursize, msg->data );
|
||||
Netchan_Transmit( chan, msg->cursize, msg->data, cl_netprofile->integer ? &cls.netprofile.inPackets : NULL );
|
||||
}
|
||||
|
||||
extern int oldsize;
|
||||
@@ -158,10 +158,30 @@ CL_Netchan_Process
|
||||
qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
||||
int ret;
|
||||
|
||||
ret = Netchan_Process( chan, msg );
|
||||
ret = Netchan_Process( chan, msg, cl_netprofile->integer ? &cls.netprofile.outPackets : NULL );
|
||||
if (!ret)
|
||||
return qfalse;
|
||||
CL_Netchan_Decode( msg );
|
||||
newsize += msg->cursize;
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_NET_OutOfBandPrint
|
||||
=================
|
||||
*/
|
||||
void CL_NET_OutOfBandPrint(netadr_t adr, const char* format, ...) {
|
||||
va_list argptr;
|
||||
char string[MAX_MSGLEN];
|
||||
|
||||
va_start(argptr, format);
|
||||
Q_vsnprintf(string, sizeof(string), format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
NET_OutOfBandPrint(NS_CLIENT, adr, "%s", string);
|
||||
|
||||
if (cl_netprofile->integer) {
|
||||
NetProfileAddPacket(&cls.netprofile.inPackets, strlen(string), NETPROF_PACKET_MESSAGE);
|
||||
}
|
||||
}
|
||||
+199
-7
@@ -223,13 +223,13 @@ qboolean CL_UnpackNonPVSClient(int* packed, radarUnpacked_t* unpacked) {
|
||||
range = 0;
|
||||
}
|
||||
|
||||
unpacked->x = x * range / 63.f;
|
||||
unpacked->y = y * range / 63.f;
|
||||
unpacked->x = x * range / (MAX_CLIENTS - 1);
|
||||
unpacked->y = y * range / (MAX_CLIENTS - 1);
|
||||
|
||||
if (!bValid)
|
||||
{
|
||||
unpacked->x = x * range / 63.f * 1024;
|
||||
unpacked->y = y * range / 63.f * 1024;
|
||||
unpacked->x = x * range / (MAX_CLIENTS - 1) * 1024.0;
|
||||
unpacked->y = y * range / (MAX_CLIENTS - 1) * 1024.0;
|
||||
}
|
||||
|
||||
unpacked->yaw = yaw * 11.25f;
|
||||
@@ -429,12 +429,24 @@ void CL_SystemInfoChanged( void ) {
|
||||
// in some cases, outdated cp commands might get sent with this news serverId
|
||||
cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) );
|
||||
|
||||
#ifdef USE_VOIP
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(clc.compat)
|
||||
clc.voipEnabled = qfalse;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
s = Info_ValueForKey( systemInfo, "sv_voipProtocol" );
|
||||
clc.voipEnabled = !Q_stricmp(s, "opus");
|
||||
}
|
||||
#endif
|
||||
|
||||
// don't set any vars when playing a demo
|
||||
if ( clc.demoplaying ) {
|
||||
return;
|
||||
}
|
||||
|
||||
s = Info_ValueForKey( systemInfo, "sv_cheats" );
|
||||
s = Info_ValueForKey( systemInfo, "cheats" );
|
||||
cl_connectedToCheatServer = atoi( s );
|
||||
if ( !cl_connectedToCheatServer ) {
|
||||
Cvar_SetCheatState();
|
||||
@@ -784,6 +796,178 @@ void CL_ParseDownload ( msg_t *msg ) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_VOIP
|
||||
static
|
||||
qboolean CL_ShouldIgnoreVoipSender(int sender)
|
||||
{
|
||||
if (!cl_voip->integer)
|
||||
return qtrue; // VoIP is disabled.
|
||||
else if ((sender == clc.clientNum) && (!clc.demoplaying))
|
||||
return qtrue; // ignore own voice (unless playing back a demo).
|
||||
else if (clc.voipMuteAll)
|
||||
return qtrue; // all channels are muted with extreme prejudice.
|
||||
else if (clc.voipIgnore[sender])
|
||||
return qtrue; // just ignoring this guy.
|
||||
else if (clc.voipGain[sender] == 0.0f)
|
||||
return qtrue; // too quiet to play.
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_PlayVoip
|
||||
|
||||
Play raw data
|
||||
=====================
|
||||
*/
|
||||
|
||||
static void CL_PlayVoip(int sender, int samplecnt, const byte *data, int flags)
|
||||
{
|
||||
if(flags & VOIP_DIRECT)
|
||||
{
|
||||
S_RawSamples(sender + 1, samplecnt, 48000, 2, 1,
|
||||
data, clc.voipGain[sender], -1);
|
||||
}
|
||||
|
||||
if(flags & VOIP_SPATIAL)
|
||||
{
|
||||
S_RawSamples(sender + MAX_CLIENTS + 1, samplecnt, 48000, 2, 1,
|
||||
data, 1.0f, sender);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ParseVoip
|
||||
|
||||
A VoIP message has been received from the server
|
||||
=====================
|
||||
*/
|
||||
static
|
||||
void CL_ParseVoip ( msg_t *msg, qboolean ignoreData ) {
|
||||
static short decoded[VOIP_MAX_PACKET_SAMPLES*4]; // !!! FIXME: don't hard code
|
||||
|
||||
const int sender = MSG_ReadShort(msg);
|
||||
const int generation = MSG_ReadByte(msg);
|
||||
const int sequence = MSG_ReadLong(msg);
|
||||
const int frames = MSG_ReadByte(msg);
|
||||
const int packetsize = MSG_ReadShort(msg);
|
||||
const int flags = MSG_ReadBits(msg, VOIP_FLAGCNT);
|
||||
unsigned char encoded[4000];
|
||||
int numSamples;
|
||||
int seqdiff;
|
||||
int written = 0;
|
||||
int i;
|
||||
|
||||
Com_DPrintf("VoIP: %d-byte packet from client %d\n", packetsize, sender);
|
||||
|
||||
if (sender < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
else if (generation < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
else if (sequence < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
else if (frames < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
else if (packetsize < 0)
|
||||
return; // short/invalid packet, bail.
|
||||
|
||||
if (packetsize > sizeof (encoded)) { // overlarge packet?
|
||||
int bytesleft = packetsize;
|
||||
while (bytesleft) {
|
||||
int br = bytesleft;
|
||||
if (br > sizeof (encoded))
|
||||
br = sizeof (encoded);
|
||||
MSG_ReadData(msg, encoded, br);
|
||||
bytesleft -= br;
|
||||
}
|
||||
return; // overlarge packet, bail.
|
||||
}
|
||||
|
||||
MSG_ReadData(msg, encoded, packetsize);
|
||||
|
||||
if (ignoreData) {
|
||||
return; // just ignore legacy speex voip data
|
||||
} else if (!clc.voipCodecInitialized) {
|
||||
return; // can't handle VoIP without libopus!
|
||||
} else if (sender >= MAX_CLIENTS) {
|
||||
return; // bogus sender.
|
||||
} else if (CL_ShouldIgnoreVoipSender(sender)) {
|
||||
return; // Channel is muted, bail.
|
||||
}
|
||||
|
||||
// !!! FIXME: make sure data is narrowband? Does decoder handle this?
|
||||
|
||||
Com_DPrintf("VoIP: packet accepted!\n");
|
||||
|
||||
seqdiff = sequence - clc.voipIncomingSequence[sender];
|
||||
|
||||
// This is a new "generation" ... a new recording started, reset the bits.
|
||||
if (generation != clc.voipIncomingGeneration[sender]) {
|
||||
Com_DPrintf("VoIP: new generation %d!\n", generation);
|
||||
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
|
||||
clc.voipIncomingGeneration[sender] = generation;
|
||||
seqdiff = 0;
|
||||
} else if (seqdiff < 0) { // we're ahead of the sequence?!
|
||||
// This shouldn't happen unless the packet is corrupted or something.
|
||||
Com_DPrintf("VoIP: misordered sequence! %d < %d!\n",
|
||||
sequence, clc.voipIncomingSequence[sender]);
|
||||
// reset the decoder just in case.
|
||||
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
|
||||
seqdiff = 0;
|
||||
} else if (seqdiff * VOIP_MAX_PACKET_SAMPLES*2 >= sizeof (decoded)) { // dropped more than we can handle?
|
||||
// just start over.
|
||||
Com_DPrintf("VoIP: Dropped way too many (%d) frames from client #%d\n",
|
||||
seqdiff, sender);
|
||||
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
|
||||
seqdiff = 0;
|
||||
}
|
||||
|
||||
if (seqdiff != 0) {
|
||||
Com_DPrintf("VoIP: Dropped %d frames from client #%d\n",
|
||||
seqdiff, sender);
|
||||
// tell opus that we're missing frames...
|
||||
for (i = 0; i < seqdiff; i++) {
|
||||
assert((written + VOIP_MAX_PACKET_SAMPLES) * 2 < sizeof (decoded));
|
||||
numSamples = opus_decode(clc.opusDecoder[sender], NULL, 0, decoded + written, VOIP_MAX_PACKET_SAMPLES, 0);
|
||||
if ( numSamples <= 0 ) {
|
||||
Com_DPrintf("VoIP: Error decoding frame %d from client #%d\n", i, sender);
|
||||
continue;
|
||||
}
|
||||
written += numSamples;
|
||||
}
|
||||
}
|
||||
|
||||
numSamples = opus_decode(clc.opusDecoder[sender], encoded, packetsize, decoded + written, ARRAY_LEN(decoded) - written, 0);
|
||||
|
||||
if ( numSamples <= 0 ) {
|
||||
Com_DPrintf("VoIP: Error decoding voip data from client #%d\n", sender);
|
||||
numSamples = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static FILE *encio = NULL;
|
||||
if (encio == NULL) encio = fopen("voip-incoming-encoded.bin", "wb");
|
||||
if (encio != NULL) { fwrite(encoded, packetsize, 1, encio); fflush(encio); }
|
||||
static FILE *decio = NULL;
|
||||
if (decio == NULL) decio = fopen("voip-incoming-decoded.bin", "wb");
|
||||
if (decio != NULL) { fwrite(decoded+written, numSamples*2, 1, decio); fflush(decio); }
|
||||
#endif
|
||||
|
||||
written += numSamples;
|
||||
|
||||
Com_DPrintf("VoIP: playback %d bytes, %d samples, %d frames\n",
|
||||
written * 2, written, frames);
|
||||
|
||||
if(written > 0)
|
||||
CL_PlayVoip(sender, written, (const byte *) decoded, flags);
|
||||
|
||||
clc.voipIncomingSequence[sender] = sequence + frames;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ParseCommandString
|
||||
@@ -932,8 +1116,16 @@ void CL_ParseServerMessage( msg_t *msg ) {
|
||||
}
|
||||
CL_ParseCGMessage( msg );
|
||||
break;
|
||||
case svc_voipSpeex:
|
||||
#ifdef USE_VOIP
|
||||
CL_ParseVoip( msg, qtrue );
|
||||
#endif
|
||||
break;
|
||||
case svc_voipOpus:
|
||||
#ifdef USE_VOIP
|
||||
CL_ParseVoip( msg, !clc.voipEnabled );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -343,7 +343,7 @@ void SCR_DrawDemoRecording( void ) {
|
||||
}
|
||||
|
||||
pos = FS_FTell( clc.demofile );
|
||||
sprintf( string, "RECORDING %s: %ik", clc.demoName, pos / 1024 );
|
||||
Com_sprintf( string, sizeof( string ), "RECORDING %s: %ik", clc.demoName, pos / 1024 );
|
||||
|
||||
SCR_DrawStringExt( 320 - strlen( string ) * 4, 20, 8, string, g_color_table[7], qtrue, qfalse );
|
||||
}
|
||||
@@ -520,16 +520,18 @@ text to the screen.
|
||||
==================
|
||||
*/
|
||||
void SCR_UpdateScreen( void ) {
|
||||
static int recursive;
|
||||
static qboolean screen_recursive;
|
||||
|
||||
if ( !scr_initialized ) {
|
||||
return; // not initialized yet
|
||||
}
|
||||
|
||||
if ( ++recursive > 2 ) {
|
||||
Com_Error( ERR_FATAL, "SCR_UpdateScreen: recursively called" );
|
||||
if (screen_recursive) {
|
||||
// already called
|
||||
return;
|
||||
}
|
||||
recursive = 1;
|
||||
|
||||
screen_recursive = qtrue;
|
||||
|
||||
CL_StartHunkUsers(qfalse);
|
||||
SCR_SimpleUpdateScreen();
|
||||
@@ -553,6 +555,6 @@ void SCR_UpdateScreen( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
recursive = 0;
|
||||
screen_recursive = qfalse;
|
||||
}
|
||||
|
||||
+225
-164
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -136,7 +136,8 @@ static unsigned int startCountHigh;
|
||||
static unsigned int loadCountLow;
|
||||
static unsigned int loadCountHigh;
|
||||
static unsigned int loadCount;
|
||||
static unsigned int lastTime;
|
||||
static unsigned int lastTime = 0;
|
||||
static unsigned int updateTime = 0;
|
||||
static unsigned int loadNumber;
|
||||
static unsigned int totalLoadTime;
|
||||
static unsigned int currentLoadTime;
|
||||
@@ -265,7 +266,7 @@ static void GetClientState(uiClientState_t *state)
|
||||
{
|
||||
state->connectPacketCount = clc.connectPacketCount;
|
||||
state->connState = clc.state;
|
||||
Q_strncpyz(state->servername, cls.servername, sizeof(state->servername));
|
||||
Q_strncpyz(state->servername, clc.servername, sizeof(state->servername));
|
||||
Q_strncpyz(state->updateInfoString, cls.updateInfoString, sizeof(state->updateInfoString));
|
||||
Q_strncpyz(state->messageString, clc.serverMessage, sizeof(state->messageString));
|
||||
state->clientNum = cl.snap.ps.clientNum;
|
||||
@@ -1001,10 +1002,14 @@ static UIRect2D getQuickMessageDMConsoleRectangle(void)
|
||||
rect.size.width = f[2] + 50.0;
|
||||
rect.size.height = f[3] + 50.0;
|
||||
} else {
|
||||
rect.pos.x = 0;
|
||||
rect.pos.y = cls.glconfig.vidHeight * 0.65;
|
||||
rect.size.width = cls.glconfig.vidWidth;
|
||||
rect.size.height = 38.0;
|
||||
rect.pos.x = 0;
|
||||
rect.pos.y = cls.glconfig.vidHeight * 0.66;
|
||||
rect.size.width = cls.glconfig.vidWidth;
|
||||
// Fixed in 2.0
|
||||
// Was 38.0 in 1.11 and below
|
||||
// This prevents characters to be seen from the DM console
|
||||
// in the quick message console
|
||||
rect.size.height = 36.0;
|
||||
}
|
||||
|
||||
return rect;
|
||||
@@ -1017,7 +1022,7 @@ UI_DMMessageModesMatch
|
||||
*/
|
||||
static qboolean UI_DMMessageModesMatch(int iMode)
|
||||
{
|
||||
qboolean bQuickMessage;
|
||||
qboolean bQuickMessage = qfalse;
|
||||
|
||||
if (iMode && (iMode != 300 || dm_console->GetQuickMessageMode())) {
|
||||
if (iMode < 0) {
|
||||
@@ -1048,13 +1053,15 @@ static void UI_SetDMConsoleMode(int iMode)
|
||||
return;
|
||||
}
|
||||
|
||||
bQuickMessage = qfalse;
|
||||
|
||||
if (iMode < 0) {
|
||||
bQuickMessage = qtrue;
|
||||
iMode = -iMode;
|
||||
}
|
||||
|
||||
if (iMode == 300) {
|
||||
bQuickMessage = dm_console->GetMessageMode();
|
||||
iMode = dm_console->GetMessageMode();
|
||||
}
|
||||
|
||||
if (dm_console->GetQuickMessageMode()) {
|
||||
@@ -1064,8 +1071,8 @@ static void UI_SetDMConsoleMode(int iMode)
|
||||
}
|
||||
} else {
|
||||
if (bQuickMessage) {
|
||||
dm_console->setFrame(getDefaultDMConsoleRectangle());
|
||||
dm_console->SetQuickMessageMode(qfalse);
|
||||
dm_console->setFrame(getQuickMessageDMConsoleRectangle());
|
||||
dm_console->SetQuickMessageMode(bQuickMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1086,7 +1093,7 @@ static void UI_SetDMConsoleMode(int iMode)
|
||||
dm_console->setTitle(Sys_LV_CL_ConvertString(
|
||||
"Chat Window (Enter to send/close) (all|team|private to change mode) : Messaging to All"
|
||||
));
|
||||
} else if (iMode == 100) {
|
||||
} else if (iMode == 200) {
|
||||
dm_console->setTitle(Sys_LV_CL_ConvertString(
|
||||
"Chat Window (Enter to send/close) (all|team|private to change mode) : Messaging to Team"
|
||||
));
|
||||
@@ -1204,6 +1211,16 @@ static UIRect2D getDefaultDMBoxRectangle(void)
|
||||
return UIRect2D(width, 0, cls.glconfig.vidWidth - (width + 192.0f), 120.0f);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
UI_GetObjectivesTop
|
||||
====================
|
||||
*/
|
||||
float UI_GetObjectivesTop(void)
|
||||
{
|
||||
return getDefaultGMBoxRectangle().pos.y;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
UI_ShowHudList
|
||||
@@ -1460,7 +1477,7 @@ void UI_FocusMenuIfExists(void)
|
||||
currentMenu->ActivateMenu();
|
||||
|
||||
if (ui_newvidmode->integer == -1) {
|
||||
Cvar_Get("ui_newvidmode", va("%d", r_mode), CVAR_SERVER_CREATED);
|
||||
Cvar_Get("ui_newvidmode", va("%d", r_mode), CVAR_RESETSTRING);
|
||||
Cvar_SetValue("ui_newvidmode", r_mode);
|
||||
}
|
||||
} else {
|
||||
@@ -1664,7 +1681,7 @@ UI_ClearBackground
|
||||
void UI_ClearBackground(void)
|
||||
{
|
||||
re.Set2DWindow(
|
||||
0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, -1, -1
|
||||
0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, -1, 1
|
||||
);
|
||||
re.Scissor(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight);
|
||||
re.SetColor(g_color_table[0]);
|
||||
@@ -1702,7 +1719,36 @@ void UI_DrawIntro(void)
|
||||
view3d->setShow(false);
|
||||
UI_ClearBackground();
|
||||
|
||||
// FIXME: draw intro
|
||||
if (cls.startStage < 3 || cls.startStage >= 12) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (intro_stage.material->GetMaterial()) {
|
||||
float swidth;
|
||||
float sheight;
|
||||
vec4_t color;
|
||||
|
||||
VectorSet4(color, 1, 1, 1, 1);
|
||||
if (intro_stage.fadetime) {
|
||||
float frac;
|
||||
|
||||
frac = Q_clamp_float((cls.realtime - intro_stage.starttime) / intro_stage.fadetime, 0, 1);
|
||||
color[0] = color[1] = color[2] =
|
||||
intro_stage.alpha_start + frac * (intro_stage.alpha_end - intro_stage.alpha_start);
|
||||
}
|
||||
|
||||
swidth = view3d->getFrame().getMaxX();
|
||||
sheight = view3d->getFrame().getMaxY();
|
||||
|
||||
re.SetColor(color);
|
||||
|
||||
re.DrawStretchPic(0.0, 0.0, swidth, sheight, 0.0, 0.0, 1.0, 1.0, intro_stage.material->GetMaterial());
|
||||
re.SetColor(NULL);
|
||||
}
|
||||
|
||||
if (cls.realtime >= intro_stage.endtime) {
|
||||
CL_FinishedStartStage();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1809,17 +1855,9 @@ void UI_Update(void)
|
||||
}
|
||||
|
||||
// don't care about the intro
|
||||
/*
|
||||
if( CL_FinishedIntro() )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
UI_DrawIntro();
|
||||
}
|
||||
*/
|
||||
|
||||
if (!server_loading && (clc.state == CA_CONNECTING || clc.state == CA_CHALLENGING) && ui_pConnectingMenu) {
|
||||
if (!CL_FinishedIntro()) {
|
||||
UI_DrawIntro();
|
||||
} else if (!server_loading && (clc.state == CA_CONNECTING || clc.state == CA_CHALLENGING) && ui_pConnectingMenu) {
|
||||
view3d->setShow(false);
|
||||
UI_ClearBackground();
|
||||
|
||||
@@ -1857,7 +1895,7 @@ void UI_Update(void)
|
||||
if (clc.state <= CA_PRIMED) {
|
||||
view3d->setShow(false);
|
||||
UI_ClearBackground();
|
||||
} else if (clc.state == CA_PRIMED || clc.state == CA_ACTIVE) {
|
||||
} else if (clc.state == CA_ACTIVE || clc.state == CA_CINEMATIC) {
|
||||
Com_FakeUnpause();
|
||||
view3d->setShow(true);
|
||||
} else {
|
||||
@@ -2638,7 +2676,7 @@ void UI_PushMenuSP_f(void)
|
||||
}
|
||||
|
||||
if ((!com_cl_running || !com_cl_running->integer || clc.state == CA_DISCONNECTED || !cg_gametype->integer)
|
||||
&& (!com_sv_running || !com_sv_running->integer || !g_gametype->integer)) {
|
||||
&& (!com_sv_running || !com_sv_running->integer || g_gametype->integer == GT_SINGLE_PLAYER)) {
|
||||
UI_PushMenu(Cmd_Argv(1));
|
||||
}
|
||||
}
|
||||
@@ -2659,7 +2697,7 @@ void UI_PushMenuMP_f(void)
|
||||
}
|
||||
|
||||
if (com_cl_running && com_cl_running->integer && clc.state != CA_DISCONNECTED && cg_gametype->integer
|
||||
&& com_sv_running && com_sv_running->integer && g_gametype->integer) {
|
||||
&& com_sv_running && com_sv_running->integer && g_gametype->integer != GT_SINGLE_PLAYER) {
|
||||
cmd = Cmd_Argv(1);
|
||||
|
||||
//
|
||||
@@ -3013,14 +3051,14 @@ void CL_PingServers_f(void)
|
||||
if (!noudp->integer) {
|
||||
adr.type = NA_BROADCAST;
|
||||
adr.port = BigShort(12203);
|
||||
NET_OutOfBandPrint(NS_SERVER, adr, "info %i", 8);
|
||||
CL_NET_OutOfBandPrint(adr, "info %i", 8);
|
||||
}
|
||||
|
||||
noipx = Cvar_Get("noipx", "0", CVAR_INIT);
|
||||
if (!noipx->integer) {
|
||||
adr.type = NA_BROADCAST_IPX;
|
||||
adr.port = BigShort(12203);
|
||||
NET_OutOfBandPrint(NS_SERVER, adr, "info %i", 8);
|
||||
CL_NET_OutOfBandPrint(adr, "info %i", 8);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
@@ -3035,7 +3073,7 @@ void CL_PingServers_f(void)
|
||||
adr.port = BigShort(12203);
|
||||
}
|
||||
|
||||
NET_OutOfBandPrint(NS_SERVER, adr, "info %i", 8);
|
||||
CL_NET_OutOfBandPrint(adr, "info %i", 8);
|
||||
} else {
|
||||
Com_Printf("Bad address: %s\n", adrstring);
|
||||
}
|
||||
@@ -3549,7 +3587,7 @@ UI_WantsKeyboard
|
||||
*/
|
||||
void UI_WantsKeyboard()
|
||||
{
|
||||
cls.keyCatchers |= KEYCATCH_UI;
|
||||
Key_SetCatcher(Key_GetCatcher() | KEYCATCH_UI);
|
||||
}
|
||||
|
||||
struct widgettrans_s {
|
||||
@@ -3712,102 +3750,6 @@ void CL_FillUIImports(void)
|
||||
|
||||
uii.GetConfigstring = CL_ConfigString;
|
||||
uii.UI_CloseDMConsole = UI_CloseDMConsole;
|
||||
|
||||
#if 0
|
||||
uii.TIKI_RegisterModel = TIKI_RegisterTiki;
|
||||
|
||||
uii.Cvar_Get = Cvar_Get;
|
||||
uii.Argc = Cmd_Argc;
|
||||
uii.Argv = Cmd_Argv;
|
||||
uii.Cmd_ExecuteText = Cbuf_ExecuteText;
|
||||
uii.FS_FOpenFile = FS_FOpenFileByMode;
|
||||
uii.FS_Read = FS_Read;
|
||||
uii.FS_Write = FS_Write;
|
||||
uii.FS_FCloseFile = FS_FCloseFile;
|
||||
uii.FS_GetFileList = FS_GetFileList;
|
||||
uii.FS_Seek = FS_Seek;
|
||||
uii.R_RegisterModel = re.RegisterModel;
|
||||
uii.R_RegisterSkin = re.RegisterShader;
|
||||
uii.R_RegisterShader = re.RegisterShader;
|
||||
uii.R_RegisterShaderNoMip = re.RegisterShaderNoMip;
|
||||
uii.R_ClearScene = re.ClearScene;
|
||||
uii.R_AddRefEntityToScene = re.AddRefEntityToScene;
|
||||
uii.R_AddPolyToScene = re.AddPolyToScene;
|
||||
uii.R_AddLightToScene = re.AddLightToScene;
|
||||
uii.R_RenderScene = re.RenderScene;
|
||||
uii.R_SetColor = re.SetColor;
|
||||
uii.R_DrawStretchPic = re.DrawStretchPic;
|
||||
uii.UpdateScreen = SCR_UpdateScreen;
|
||||
uii.S_StartLocalSound = S_StartLocalSound;
|
||||
uii.S_RegisterSound = S_RegisterSound;
|
||||
uii.Key_KeynumToStringBuf = Key_KeynumToStringBuf;
|
||||
uii.Key_KeynumToString = Key_KeynumToString;
|
||||
uii.Key_GetBindingBuf = Key_GetBindingBuf;
|
||||
uii.Key_IsDown = Key_IsDown;
|
||||
uii.Key_GetOverstrikeMode = Key_GetOverstrikeMode;
|
||||
uii.Key_SetOverstrikeMode = Key_SetOverstrikeMode;
|
||||
uii.Key_ClearStates = Key_ClearStates;
|
||||
uii.Key_GetCatcher = Key_GetCatcher;
|
||||
uii.Key_SetCatcher = Key_SetCatcher;
|
||||
uii.GetClipboardData = CL_GetClipboardData;
|
||||
uii.GetClientState = GetClientState;
|
||||
uii.GetGlconfig = CL_GetGlconfig;
|
||||
uii.GetConfigString = GetConfigString;
|
||||
uii.LAN_GetServerCount = LAN_GetServerCount;
|
||||
uii.LAN_GetServerAddressString = LAN_GetServerAddressString;
|
||||
uii.LAN_GetServerInfo = LAN_GetServerInfo;
|
||||
uii.LAN_GetPingQueueCount = LAN_GetPingQueueCount;
|
||||
uii.LAN_ServerStatus = LAN_GetServerStatus;
|
||||
uii.LAN_ClearPing = LAN_ClearPing;
|
||||
uii.LAN_GetPing = LAN_GetPing;
|
||||
uii.LAN_GetPingInfo = LAN_GetPingInfo;
|
||||
uii.LAN_GetServerPing = LAN_GetServerPing;
|
||||
uii.LAN_MarkServerVisible = LAN_MarkServerVisible;
|
||||
uii.LAN_UpdateVisiblePings = LAN_UpdateVisiblePings;
|
||||
uii.GetCDKey = CLUI_GetCDKey;
|
||||
uii.SetCDKey = CLUI_SetCDKey;
|
||||
uii.R_RegisterFont = re.RegisterFont;
|
||||
uii.R_Text_Width = re.Text_Width;
|
||||
uii.R_Text_Height = re.Text_Height;
|
||||
uii.R_Text_Paint = re.Text_Paint;
|
||||
uii.R_Text_PaintChar = re.Text_PaintChar;
|
||||
uii.R_GetShaderName = re.GetShaderName;
|
||||
|
||||
uii.Cmd_Stuff = Cbuf_AddText;
|
||||
uii.Cvar_GetString = CvarGetForUI;
|
||||
uii.Cvar_Reset = Cvar_Reset;
|
||||
uii.Cvar_Find = Cvar_FindVar;
|
||||
uii.Cvar_Set = UI_Cvar_Set;
|
||||
uii.File_PickFile = PickFile;
|
||||
uii.File_FreeFile = FS_FreeFile;
|
||||
uii.File_ListFiles = ListFilesForUI;
|
||||
uii.File_OpenFile = FS_ReadFile;
|
||||
uii.File_WriteFile = FS_WriteTextFile;
|
||||
uii.Rend_SetColor = re.SetColor;
|
||||
uii.Snd_PlaySound = UI_StartLocalSound;
|
||||
uii.Snd_RegisterSound = UI_RegisterSound;
|
||||
uii.Alias_Add = Alias_Add;
|
||||
uii.Alias_FindRandom = Alias_FindRandom;
|
||||
uii.Sys_Error = Com_Error;
|
||||
uii.Sys_IsKeyDown = IsKeyDown;
|
||||
uii.Sys_Milliseconds = Sys_Milliseconds;
|
||||
uii.Sys_Printf = Com_Printf;
|
||||
uii.Sys_DPrintf = Com_DPrintf;
|
||||
uii.Sys_GetClipboard = Sys_GetWholeClipboard;
|
||||
uii.Sys_SetClipboard = Sys_SetClipboard;
|
||||
uii.Cmd_CompleteCommandByNumber = Cmd_CompleteCommandByNumber;
|
||||
uii.Cvar_CompleteCvarByNumber = Cvar_CompleteVariableByNumber;
|
||||
uii.UI_WantsKeyboard = UI_WantsKeyboard;
|
||||
uii.Client_TranslateWidgetName = TranslateWidgetName;
|
||||
uii.Connect = CL_Connect;
|
||||
uii.Key_GetKeynameForCommand = Key_GetKeynameForCommand;
|
||||
uii.Key_GetCommandForKey = Key_GetBinding;
|
||||
uii.Key_SetBinding = Key_SetBinding;
|
||||
uii.Key_GetKeysForCommand = Key_GetKeysForCommand;
|
||||
uii.Key_KeynumToString = Key_KeynumToBindString;
|
||||
uii.GetConfigstring = CL_ConfigString;
|
||||
uii.UI_CloseDMConsole = UI_CloseDMConsole;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3890,7 +3832,13 @@ void UI_ResolutionChange(void)
|
||||
{
|
||||
UIRect2D frame;
|
||||
|
||||
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.75", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
if (com_target_game->integer >= TG_MOHTA) {
|
||||
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.75", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
} else {
|
||||
// Older version doesn't have an adjustable compass, so assume 0.5 by default
|
||||
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.5", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
}
|
||||
|
||||
CL_FillUIImports();
|
||||
CL_FillUIDef();
|
||||
|
||||
@@ -3978,10 +3926,10 @@ void S_ServerLoaded(void)
|
||||
|
||||
S_TriggeredMusic_Stop();
|
||||
s_bSoundPaused = qtrue;
|
||||
S_ReLoad( &svs.soundSystem );
|
||||
S_ReLoad(&svs.soundSystem);
|
||||
|
||||
if( svs.tm_filename[ 0 ] ) {
|
||||
S_TriggeredMusic_SetupHandle( svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0 );
|
||||
if (svs.tm_filename[0]) {
|
||||
S_TriggeredMusic_SetupHandle(svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4027,6 +3975,11 @@ void UI_ServerLoaded(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ui_sCurrentLoadingMenu == "loading_default") {
|
||||
UI_FinishLoadingScreen_f();
|
||||
return;
|
||||
}
|
||||
|
||||
server_loading_waiting = qtrue;
|
||||
|
||||
event = new Event(EV_Widget_Enable);
|
||||
@@ -4322,7 +4275,7 @@ public:
|
||||
void UpdateStats(Event *ev);
|
||||
};
|
||||
|
||||
Event EV_StatsUpdater_UpdateStats;
|
||||
Event EV_StatsUpdater_UpdateStats("updatestats", EV_DEFAULT, NULL, NULL, "Update the stats on the missionLog");
|
||||
|
||||
CLASS_DECLARATION(Listener, StatsUpdater, NULL) {
|
||||
{NULL, NULL}
|
||||
@@ -4733,7 +4686,7 @@ CL_FinishedIntro
|
||||
*/
|
||||
qboolean CL_FinishedIntro(void)
|
||||
{
|
||||
return !cls.startStage;
|
||||
return cls.startStage == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4743,7 +4696,87 @@ CL_FinishedStartStage
|
||||
*/
|
||||
void CL_FinishedStartStage(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
int wait;
|
||||
|
||||
switch (cls.startStage++) {
|
||||
case 1:
|
||||
Cbuf_ExecuteText(EXEC_NOW, "cinematic EAlogo.RoQ\n");
|
||||
break;
|
||||
case 2:
|
||||
intro_stage.alpha_start = 0.0;
|
||||
intro_stage.alpha_end = 1.0;
|
||||
|
||||
wait = ui_titlescreen_fadein->value * 1000.0;
|
||||
intro_stage.fadetime = wait;
|
||||
intro_stage.starttime = cls.realtime;
|
||||
intro_stage.endtime = cls.realtime + wait;
|
||||
|
||||
intro_stage.material = uWinMan.RegisterShader("mohaa_title");
|
||||
break;
|
||||
case 3:
|
||||
intro_stage.alpha_start = 1.0;
|
||||
intro_stage.alpha_end = 1.0;
|
||||
|
||||
wait = ui_legalscreen_stay->value * 1000.0;
|
||||
intro_stage.fadetime = 0.0;
|
||||
intro_stage.starttime = cls.realtime;
|
||||
intro_stage.endtime = cls.realtime + wait;
|
||||
break;
|
||||
case 4:
|
||||
intro_stage.alpha_start = 1.0;
|
||||
intro_stage.alpha_end = 0.0;
|
||||
|
||||
wait = ui_titlescreen_fadeout->value * 1000.0;
|
||||
intro_stage.fadetime = wait;
|
||||
intro_stage.starttime = cls.realtime;
|
||||
intro_stage.endtime = cls.realtime + wait;
|
||||
break;
|
||||
case 5:
|
||||
intro_stage.alpha_start = 0.0;
|
||||
intro_stage.alpha_end = 1.0;
|
||||
|
||||
wait = ui_legalscreen_fadein->value * 1000.0;
|
||||
intro_stage.fadetime = wait;
|
||||
intro_stage.starttime = cls.realtime;
|
||||
intro_stage.endtime = cls.realtime + wait;
|
||||
|
||||
intro_stage.material = uWinMan.RegisterShader("legal");
|
||||
break;
|
||||
case 6:
|
||||
intro_stage.alpha_start = 1.0;
|
||||
intro_stage.alpha_end = 1.0;
|
||||
|
||||
wait = ui_legalscreen_stay->value * 1000.0;
|
||||
intro_stage.fadetime = 0.0;
|
||||
intro_stage.starttime = cls.realtime;
|
||||
intro_stage.endtime = cls.realtime + wait;
|
||||
break;
|
||||
case 7:
|
||||
intro_stage.alpha_start = 1.0;
|
||||
intro_stage.alpha_end = 0.0;
|
||||
|
||||
wait = ui_legalscreen_fadeout->value * 1000.0;
|
||||
intro_stage.fadetime = wait;
|
||||
intro_stage.starttime = cls.realtime;
|
||||
intro_stage.endtime = cls.realtime + wait;
|
||||
break;
|
||||
case 8:
|
||||
if (com_target_game->integer >= target_game_e::TG_MOHTA) {
|
||||
cls.startStage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
Cbuf_ExecuteText(EXEC_NOW, "cinematic 2015intro.RoQ\n");
|
||||
break;
|
||||
case 9:
|
||||
Cbuf_ExecuteText(EXEC_NOW, "cinematic intro.RoQ\n");
|
||||
break;
|
||||
case 10:
|
||||
cls.startStage = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4759,9 +4792,6 @@ void UI_StartStageKeyEvent(void)
|
||||
SCR_StopCinematic();
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
SCR_StopCinematic();
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
@@ -4780,11 +4810,9 @@ void UI_StartStageKeyEvent(void)
|
||||
break;
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
if (ui_skip_legalscreen->integer) {
|
||||
cls.startStage = 11;
|
||||
CL_FinishedStartStage();
|
||||
}
|
||||
SCR_StopCinematic();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -4812,8 +4840,8 @@ void CL_TryStartIntro(void)
|
||||
UI_ToggleConsole();
|
||||
} else {
|
||||
// FIXME: no intro from now
|
||||
//Cvar_Set( cl_playintro->name, "0" );
|
||||
//UI_StartIntro_f();
|
||||
Cvar_Set(cl_playintro->name, "0");
|
||||
UI_StartIntro_f();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4974,6 +5002,20 @@ void UI_HideStatistics_f()
|
||||
statsUpdater.CancelEventsOfType(EV_StatsUpdater_UpdateStats);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
UI_SalesScreen_f
|
||||
====================
|
||||
*/
|
||||
void UI_SalesScreen_f()
|
||||
{
|
||||
if (random() > 0.5) {
|
||||
Cbuf_AddText("pushmenu sales_splash1\n");
|
||||
} else {
|
||||
Cbuf_AddText("pushmenu sales_splash2\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_ShutdownUI
|
||||
@@ -5169,7 +5211,7 @@ void CL_InitializeUI(void)
|
||||
ui_success = Cvar_Get("ui_success", "0", 0);
|
||||
ui_failed = Cvar_Get("ui_failed", "0", 0);
|
||||
ui_returnmenu = Cvar_Get("ui_returnmenu", "0", 0);
|
||||
ui_skip_eamovie = Cvar_Get("ui_skip_eamovie", "0", 0);
|
||||
ui_skip_eamovie = Cvar_Get("ui_skip_eamovie", "1", 0);
|
||||
ui_skip_titlescreen = Cvar_Get("ui_skip_titlescreen", "1", 0);
|
||||
ui_skip_legalscreen = Cvar_Get("ui_skip_legalscreen", "1", 0);
|
||||
ui_titlescreen_fadein = Cvar_Get("ui_titlescreen_fadein", "1", 0);
|
||||
@@ -5244,6 +5286,7 @@ void CL_InitializeUI(void)
|
||||
Cmd_AddCommand("-statistics", UI_HideStatistics_f);
|
||||
Cmd_AddCommand("setreturnmenu", UI_SetReturnMenuToCurrent);
|
||||
Cmd_AddCommand("gotoreturnmenu", UI_PushReturnMenu_f);
|
||||
Cmd_AddCommand("salesscreen", UI_SalesScreen_f);
|
||||
|
||||
if (developer->integer) {
|
||||
UColor bgColor;
|
||||
@@ -5365,6 +5408,10 @@ void CL_InitializeUI(void)
|
||||
CL_ClearButtons();
|
||||
|
||||
cls.uiStarted = qtrue;
|
||||
|
||||
if (!com_dedicated->integer) {
|
||||
CL_TryStartIntro();
|
||||
}
|
||||
}
|
||||
|
||||
static char **loadStrings;
|
||||
@@ -5402,7 +5449,16 @@ void UI_BeginLoadResource(void)
|
||||
UI_EndLoadResource
|
||||
====================
|
||||
*/
|
||||
void UI_EndLoadResource(void) {}
|
||||
void UI_EndLoadResource(void)
|
||||
{
|
||||
clock_t time;
|
||||
|
||||
time = clock() - (((clock_t)startCountHigh << 32) | startCountLow) + (((clock_t)loadCountHigh << 32) | loadCountLow);
|
||||
|
||||
loadCountHigh = time >> 32;
|
||||
loadCountLow = time;
|
||||
loadCount = time >> 25;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
@@ -5468,19 +5524,17 @@ void UI_RegisterLoadResource(const char *name)
|
||||
high = loadNumber - 1;
|
||||
|
||||
while (low <= high) {
|
||||
i = (high + low) / 2;
|
||||
i = (low + high) / 2;
|
||||
j = strcmp(name, loadStrings[i]);
|
||||
|
||||
if (j >= 0) {
|
||||
if (j <= 0) {
|
||||
currentLoadTime += loadTimes[i];
|
||||
loadTimes[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (j < 0) {
|
||||
high = i - 1;
|
||||
} else if (j > 0) {
|
||||
low = i + 1;
|
||||
} else {
|
||||
high = i - 1;
|
||||
currentLoadTime += loadTimes[i];
|
||||
loadTimes[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5493,12 +5547,19 @@ UI_TestUpdateScreen
|
||||
void UI_TestUpdateScreen(unsigned int timeout)
|
||||
{
|
||||
unsigned int newTime = Sys_Milliseconds();
|
||||
unsigned int startRenderTime, endRenderTime;
|
||||
|
||||
if (newTime - lastTime >= timeout) {
|
||||
lastTime = newTime;
|
||||
Sys_PumpMessageLoop();
|
||||
SCR_UpdateScreen();
|
||||
if (timeout > 0 && (newTime - lastTime) < (timeout + updateTime)) {
|
||||
return;
|
||||
}
|
||||
|
||||
startRenderTime = Sys_Milliseconds();
|
||||
Sys_PumpMessageLoop();
|
||||
SCR_UpdateScreen();
|
||||
endRenderTime = Sys_Milliseconds();
|
||||
|
||||
updateTime = Q_min(endRenderTime - startRenderTime, 1000);
|
||||
lastTime = endRenderTime;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5536,7 +5597,7 @@ void UI_LoadResource(const char *name)
|
||||
Cvar_SetValue("loadingbar", (float)currentLoadTime / (float)totalLoadTime);
|
||||
}
|
||||
|
||||
UI_TestUpdateScreen(333u);
|
||||
UI_TestUpdateScreen(33);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5812,12 +5873,12 @@ void UI_EndLoad(void)
|
||||
}
|
||||
|
||||
file = FS_FOpenFileWrite(loadName);
|
||||
sprintf(buf, "%d\n%d %d\n", 3, loadNumber, size);
|
||||
Com_sprintf(buf, sizeof(buf), "%d\n%d %d\n", 3, loadNumber, size);
|
||||
|
||||
FS_Write(buf, strlen(buf), file);
|
||||
|
||||
for (i = 0; i < loadNumber; i++) {
|
||||
sprintf(buf, "%s\n%d\n", base[i]->name, base[i]->loadCount);
|
||||
Com_sprintf(buf, sizeof(buf), "%s\n%d\n", base[i]->name, base[i]->loadCount);
|
||||
FS_Write(buf, strlen(buf), file);
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2023-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef struct {
|
||||
extern cvar_t *ui_health_start;
|
||||
extern cvar_t *ui_health_end;
|
||||
extern cvar_t *sound_overlay;
|
||||
extern cvar_t *cl_movieaudio;
|
||||
|
||||
//
|
||||
// initialization
|
||||
@@ -55,6 +56,7 @@ const char *CvarGetForUI(const char *name, const char *defval);
|
||||
void UI_ClearState(void);
|
||||
void CL_BeginRegistration(void);
|
||||
void CL_EndRegistration(void);
|
||||
float UI_GetObjectivesTop(void);
|
||||
|
||||
//
|
||||
// menu
|
||||
@@ -111,6 +113,7 @@ void UI_DeleteScoreBoardItems(int iMaxIndex);
|
||||
void UI_BeginLoad(const char *pszMapName);
|
||||
void UI_EndLoad(void);
|
||||
void UI_AbortLoad(void);
|
||||
int CL_FontStringWidth(fontheader_t* pFont, const char* pszString, int iMaxLen);
|
||||
void UI_BeginLoadResource(void);
|
||||
void UI_EndLoadResource(void);
|
||||
void UI_EndLoadResource(const char *name);
|
||||
|
||||
@@ -61,6 +61,7 @@ UIDMBox::UIDMBox()
|
||||
m_iBeginDecay = 0;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
|
||||
}
|
||||
|
||||
void UIDMBox::VerifyBoxOut( void )
|
||||
@@ -278,6 +279,28 @@ float UIDMBox::PrintWrap( UIFont *font, float x, float y, str text )
|
||||
|
||||
float UIDMBox::DrawItem( item_t *in, float x, float y, float alpha )
|
||||
{
|
||||
if (m_drawoutline) {
|
||||
//
|
||||
// Draw an outline
|
||||
//
|
||||
|
||||
in->font->setColor(UBlack);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
PrintWrap(in->font, x + 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 2, y, in->string);
|
||||
PrintWrap(in->font, x - 2, y, in->string);
|
||||
PrintWrap(in->font, x, y + 2, in->string);
|
||||
PrintWrap(in->font, x, y - 2, in->string);
|
||||
}
|
||||
|
||||
in->font->setColor(in->color);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
@@ -316,7 +339,11 @@ void UIDMBox::Print( const char *text )
|
||||
}
|
||||
else if (*text == MESSAGE_CHAT_GREEN)
|
||||
{
|
||||
m_items[m_numitems].color = UGreen;
|
||||
if (com_target_game->integer >= TG_MOHTA) {
|
||||
m_items[m_numitems].color = ULightGreen;
|
||||
} else {
|
||||
m_items[m_numitems].color = UGreen;
|
||||
}
|
||||
m_items[m_numitems].font = m_fontbold;
|
||||
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2015-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIDMBOX_H__
|
||||
#define __CL_UIDMBOX_H__
|
||||
#pragma once
|
||||
|
||||
static constexpr unsigned int DMBOX_ITEM_FLAG_BOLD = 2u;
|
||||
static constexpr unsigned int DMBOX_ITEM_FLAG_DEATH = 4u;
|
||||
@@ -47,6 +46,8 @@ protected:
|
||||
int m_movespeed;
|
||||
int m_iBeginDecay;
|
||||
int m_iEndDecay;
|
||||
// Added in OPM
|
||||
bool m_drawoutline;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIDMBox );
|
||||
@@ -75,5 +76,3 @@ public:
|
||||
void setRealShow( bool b );
|
||||
void Clear( void );
|
||||
};
|
||||
|
||||
#endif /* __CL_UIDMBOX_H__ */
|
||||
@@ -104,8 +104,10 @@ void FilePickerClass::Initialize(
|
||||
currentDirectory += "/";
|
||||
}
|
||||
|
||||
extension = ext;
|
||||
ignoredFiles = ignore_files;
|
||||
extension = ext;
|
||||
if (ignore_files) {
|
||||
ignoredFiles = ignore_files;
|
||||
}
|
||||
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ UIGMBox::UIGMBox()
|
||||
m_iBeginDecay = 0;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
|
||||
}
|
||||
|
||||
void UIGMBox::VerifyBoxOut( void )
|
||||
@@ -272,6 +273,28 @@ float UIGMBox::PrintWrap( UIFont *font, float x, float y, str text )
|
||||
|
||||
float UIGMBox::DrawItem( item_t *in, float x, float y, float alpha )
|
||||
{
|
||||
if (m_drawoutline) {
|
||||
//
|
||||
// Draw an outline
|
||||
//
|
||||
|
||||
in->font->setColor(UBlack);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
PrintWrap(in->font, x + 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y + 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y + 1, in->string);
|
||||
PrintWrap(in->font, x - 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x - 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 1, y - 2, in->string);
|
||||
PrintWrap(in->font, x + 2, y - 1, in->string);
|
||||
PrintWrap(in->font, x + 2, y, in->string);
|
||||
PrintWrap(in->font, x - 2, y, in->string);
|
||||
PrintWrap(in->font, x, y + 2, in->string);
|
||||
PrintWrap(in->font, x, y - 2, in->string);
|
||||
}
|
||||
|
||||
in->font->setColor(in->color);
|
||||
in->font->setAlpha(alpha);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2015-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIGMBOX_H__
|
||||
#define __CL_UIGMBOX_H__
|
||||
#pragma once
|
||||
|
||||
static constexpr unsigned int GMBOX_ITEM_FLAG_BOLD = 1u;
|
||||
|
||||
@@ -44,6 +43,8 @@ protected:
|
||||
int m_movespeed;
|
||||
int m_iBeginDecay;
|
||||
int m_iEndDecay;
|
||||
// Added in OPM
|
||||
bool m_drawoutline;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIGMBox );
|
||||
@@ -72,5 +73,3 @@ public:
|
||||
void setRealShow( bool b );
|
||||
void Clear( void );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2023-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -25,12 +25,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
class LANGameItem : public UIListCtrlItem
|
||||
{
|
||||
str strings[5];
|
||||
str strings[6];
|
||||
|
||||
public:
|
||||
LANGameItem();
|
||||
LANGameItem(
|
||||
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
|
||||
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping, const str& ipAddress
|
||||
);
|
||||
|
||||
int getListItemValue(int which) const override;
|
||||
@@ -65,6 +65,11 @@ UILANGameClass::UILANGameClass()
|
||||
|
||||
m_iLastUpdateTime = 0;
|
||||
m_noservers_mat = uWinMan.RegisterShader("textures/menu/noservers");
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
//
|
||||
m_bVirtual = false;
|
||||
}
|
||||
|
||||
void UILANGameClass::Draw(void)
|
||||
@@ -102,11 +107,12 @@ void UILANGameClass::UpdateUIElement(void)
|
||||
|
||||
width = getClientFrame().size.width - 16.f;
|
||||
|
||||
AddColumn(Sys_LV_CL_ConvertString("Server Name"), 0, width * 0.4f, false, false);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Map"), 1, width * 0.15f, false, false);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Players"), 2, width * 0.165f, true, true);
|
||||
AddColumn(Sys_LV_CL_ConvertString("GameType"), 3, width * 0.22f, false, false);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Ping"), 4, width * 0.065f, true, false);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Server Name"), 0, width * 0.27f, false, false); // was 0.4
|
||||
AddColumn(Sys_LV_CL_ConvertString("Map"), 1, width * 0.12f, false, false); // was 0.15
|
||||
AddColumn(Sys_LV_CL_ConvertString("Players"), 2, width * 0.08f, true, true); // was 0.165
|
||||
AddColumn(Sys_LV_CL_ConvertString("GameType"), 3, width * 0.118f, false, false); // was 0.22
|
||||
AddColumn(Sys_LV_CL_ConvertString("Ping"), 4, width * 0.052f, true, false); // was 0.065
|
||||
AddColumn(Sys_LV_CL_ConvertString("IP"), 5, width * 0.36f, false, false); // Added in OPM
|
||||
|
||||
uWinMan.ActivateControl(this);
|
||||
|
||||
@@ -134,7 +140,9 @@ void UILANGameClass::SetupServers(void)
|
||||
pServerInfo->mapName,
|
||||
va("%02i/%02i", pServerInfo->clients, pServerInfo->maxClients),
|
||||
pServerInfo->gameTypeString,
|
||||
str(pServerInfo->ping)
|
||||
str(pServerInfo->ping),
|
||||
// Added in OPM
|
||||
NET_AdrToStringwPort(pServerInfo->adr)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -167,7 +175,7 @@ void UILANGameClass::JoinServer(Event *ev)
|
||||
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
|
||||
|
||||
UI_SetReturnMenuToCurrent();
|
||||
CL_Connect(NET_AdrToString(serverInfo.adr), netadrtype_t::NA_UNSPEC);
|
||||
CL_Connect(NET_AdrToStringwPort(serverInfo.adr), netadrtype_t::NA_UNSPEC);
|
||||
}
|
||||
|
||||
qboolean UILANGameClass::KeyEvent(int key, unsigned int time)
|
||||
@@ -197,7 +205,7 @@ qboolean UILANGameClass::KeyEvent(int key, unsigned int time)
|
||||
LANGameItem::LANGameItem() {}
|
||||
|
||||
LANGameItem::LANGameItem(
|
||||
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
|
||||
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping, const str& ipAddress
|
||||
)
|
||||
{
|
||||
strings[0] = hostName;
|
||||
@@ -205,6 +213,12 @@ LANGameItem::LANGameItem(
|
||||
strings[2] = players;
|
||||
strings[3] = gameTypeString;
|
||||
strings[4] = ping;
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
//
|
||||
|
||||
strings[5] = ipAddress;
|
||||
}
|
||||
|
||||
int LANGameItem::getListItemValue(int which) const
|
||||
|
||||
@@ -95,7 +95,7 @@ UIFAKKLoadGameClass::UIFAKKLoadGameClass()
|
||||
{
|
||||
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
AllowActivate(false);
|
||||
AllowActivate(true);
|
||||
m_bRemovePending = false;
|
||||
|
||||
setHeaderFont("facfont-20");
|
||||
@@ -287,7 +287,7 @@ qboolean UIFAKKLoadGameClass::KeyEvent(int key, unsigned int time)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return UIListBase::KeyEvent(key, time);
|
||||
return UIListCtrl::KeyEvent(key, time);
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
|
||||
@@ -76,7 +76,7 @@ void UIMapRotationListBox::PopulateRotationList()
|
||||
maplistVar = Cvar_Get("ui_maplist_ffa", "", 0);
|
||||
}
|
||||
|
||||
strcpy(mapBuffer, maplistVar->string);
|
||||
Q_strncpyz(mapBuffer, maplistVar->string, sizeof(mapBuffer));
|
||||
|
||||
for (token = strtok(mapBuffer, " /"); token; token = strtok(NULL, " /")) {
|
||||
if (!Q_stricmp(token, "dm")) {
|
||||
@@ -143,7 +143,7 @@ void UIMapListBox::PopulateMapList()
|
||||
bool bHasTOW = false;
|
||||
bool bHasLib = false;
|
||||
|
||||
strcpy(mapName, filename);
|
||||
Q_strncpyz(mapName, filename, sizeof(mapName));
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
|
||||
if (!COM_IsMapValid(mapName)) {
|
||||
@@ -151,7 +151,7 @@ void UIMapListBox::PopulateMapList()
|
||||
}
|
||||
|
||||
if (bTugOfWar || bLiberation) {
|
||||
strcpy(tokenized, mapName);
|
||||
Q_strncpyz(tokenized, mapName, sizeof(tokenized));
|
||||
|
||||
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (bLiberation) {
|
||||
@@ -181,7 +181,7 @@ void UIMapListBox::PopulateMapList()
|
||||
}
|
||||
}
|
||||
} else if (bObjective) {
|
||||
strcpy(tokenized, mapName);
|
||||
Q_strncpyz(tokenized, mapName, sizeof(tokenized));
|
||||
|
||||
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (!Q_stricmp(token, "obj")) {
|
||||
@@ -209,9 +209,9 @@ void UIMapListBox::PopulateMapList()
|
||||
char mapName[256];
|
||||
char tokenized[256];
|
||||
|
||||
strcpy(mapName, filename);
|
||||
Q_strncpyz(mapName, filename, sizeof(mapName));
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
strcpy(tokenized, mapName);
|
||||
Q_strncpyz(tokenized, mapName, sizeof(tokenized));
|
||||
|
||||
token = strtok(tokenized, "_");
|
||||
if (!Q_stricmp(token, "obj") || !Q_stricmp(mapName, "mp_ship_lib")) {
|
||||
@@ -237,7 +237,7 @@ void UIMapListBox::PopulateMapList()
|
||||
const char *filename = filenames[i];
|
||||
char mapName[256];
|
||||
|
||||
strcpy(mapName, filename);
|
||||
Q_strncpyz(mapName, filename, sizeof(mapName));
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
|
||||
if (!COM_IsMapValid(mapName)) {
|
||||
@@ -277,20 +277,27 @@ void UIAddToRotationButton::Released(Event *ev)
|
||||
|
||||
if (mapList && rotationList) {
|
||||
size_t mapLength = 0;
|
||||
int item = mapList->getCurrentItem();
|
||||
int item = mapList->getCurrentItem();
|
||||
str currentItemText;
|
||||
|
||||
if (item) {
|
||||
currentItemText = mapList->getItemText(item);
|
||||
}
|
||||
|
||||
for (i = 1; i <= rotationList->getNumItems(); i++) {
|
||||
str text = rotationList->getItemText(i);
|
||||
if (text == currentItemText) {
|
||||
// Added in OPM
|
||||
// Prevent adding duplicates
|
||||
item = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
mapLength += text.length();
|
||||
}
|
||||
|
||||
if (item) {
|
||||
str text = mapList->getItemText(item);
|
||||
|
||||
if (prefixLength + mapLength + text.length() < 256) {
|
||||
rotationList->AddItem(text, NULL);
|
||||
}
|
||||
if (item && prefixLength + mapLength + currentItemText.length() < 256) {
|
||||
rotationList->AddItem(currentItemText, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +363,7 @@ void UIRotationApplyButton::Released(Event *ev)
|
||||
char map[256];
|
||||
bool bHasTOW = false, bHasObj = false, bHasLib = false, bHasShip = false;
|
||||
|
||||
strcpy(map, text);
|
||||
Q_strncpyz(map, text, sizeof(map));
|
||||
for (token = strtok(map, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (!Q_stricmp(token, "TOW")) {
|
||||
bHasTOW = true;
|
||||
@@ -387,11 +394,12 @@ void UIRotationApplyButton::Released(Event *ev)
|
||||
}
|
||||
|
||||
maplistStr += text;
|
||||
maplistStr += " ";
|
||||
|
||||
if (i == 1) {
|
||||
Cvar_Set("ui_dmmap", maplistStr);
|
||||
}
|
||||
|
||||
maplistStr += " ";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,10 +421,10 @@ void UIRotationMoveItemUpButton::Released(Event *ev)
|
||||
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
item = list->getCurrentItem();
|
||||
|
||||
if (item < list->getNumItems() && list->getNumItems() > 1) {
|
||||
str text = list->getItemText(item + 1);
|
||||
if (item > 1 && list->getNumItems() > 1) {
|
||||
str text = list->getItemText(item - 1);
|
||||
|
||||
list->DeleteItem(list->getCurrentItem() - 1);
|
||||
list->DeleteItem(item - 1);
|
||||
list->InsertItem(text, item);
|
||||
list->setCurrentItem(item - 1);
|
||||
}
|
||||
@@ -440,7 +448,7 @@ void UIRotationMoveItemDownButton::Released(Event *ev)
|
||||
if (item < list->getNumItems() && list->getNumItems() > 1) {
|
||||
str text = list->getItemText(item + 1);
|
||||
|
||||
list->DeleteItem(list->getCurrentItem() + 1);
|
||||
list->DeleteItem(item + 1);
|
||||
list->InsertItem(text, item);
|
||||
list->setCurrentItem(item + 1);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ void PickFile(const char *name, Listener *obj, Event& event)
|
||||
if (name && *name && strchr(name, '/')) {
|
||||
currentpath = name;
|
||||
|
||||
for (i = currentpath.length(); i > 0; i--) {
|
||||
for (i = currentpath.length() - 1; i > 0; i--) {
|
||||
if (currentpath[i] == '/') {
|
||||
break;
|
||||
}
|
||||
|
||||
+14
-11
@@ -58,7 +58,7 @@ void UIRadar::Draw(void)
|
||||
float inv;
|
||||
float iconSize;
|
||||
int blinkTime, speakTime;
|
||||
float origin[2], axis[2];
|
||||
vec2_t origin, axis;
|
||||
float halfScale;
|
||||
int i;
|
||||
|
||||
@@ -105,17 +105,17 @@ void UIRadar::Draw(void)
|
||||
halfScale = iconSize * 0.5f;
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
float delta[2];
|
||||
float newOrg[2];
|
||||
float screenOrg[2];
|
||||
float length;
|
||||
vec2_t delta;
|
||||
vec2_t newOrg;
|
||||
vec2_t screenOrg;
|
||||
float length;
|
||||
|
||||
radar = &g_radarClients[i];
|
||||
if (i == g_radarClientNum) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!g_radarClients[i].time) {
|
||||
if (!radar->time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -128,10 +128,13 @@ void UIRadar::Draw(void)
|
||||
// make the icon blink
|
||||
if (delta >= 0 && delta < speakTime && ((delta / blinkTime) % 2) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (delta < 0 || delta >= speakTime) {
|
||||
radar->lastSpeakTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
radar->lastSpeakTime = 0;
|
||||
delta[0] = radar->origin[0] - origin[0];
|
||||
delta[1] = radar->origin[1] - origin[1];
|
||||
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv;
|
||||
@@ -140,12 +143,12 @@ void UIRadar::Draw(void)
|
||||
|
||||
if (length > 1)
|
||||
{
|
||||
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv * (1.f / length);
|
||||
newOrg[1] = (delta[0] * axis[1] + delta[1] * -axis[0]) * inv * (1.f / length);
|
||||
newOrg[0] *= 1.f / length;
|
||||
newOrg[1] *= 1.f / length;
|
||||
}
|
||||
|
||||
screenOrg[0] = -((halfScale * (1.141f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width));
|
||||
screenOrg[1] = -((halfScale * (1.141f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height));
|
||||
screenOrg[0] = -((halfScale * (1.414f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width));
|
||||
screenOrg[1] = -((halfScale * (1.414f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height));
|
||||
|
||||
uii.Rend_DrawPicStretched2(
|
||||
screenOrg[0],
|
||||
|
||||
@@ -651,6 +651,9 @@ static void AddFilter(char* filter, const char* value) {
|
||||
void UIFAKKServerList::CancelRefresh( Event *ev )
|
||||
{
|
||||
ServerListHalt(m_serverList[0]);
|
||||
if (m_serverList[1]) {
|
||||
ServerListHalt(m_serverList[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void UIFAKKServerList::NewServerList( void )
|
||||
@@ -1037,6 +1040,7 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
{
|
||||
const char* pszHostName;
|
||||
bool bDiffVersion;
|
||||
bool bIsDemo;
|
||||
str sServerName;
|
||||
str sPlayers;
|
||||
const char* pszGameVer;
|
||||
@@ -1044,12 +1048,14 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
|
||||
pszHostName = ServerGetStringValue(server, "hostname", "(NONE)");
|
||||
bDiffVersion = false;
|
||||
bIsDemo = false;
|
||||
pszGameVer = ServerGetStringValue(server, "gamever", "1.00");
|
||||
pszGameVerNumber = pszGameVer;
|
||||
|
||||
if (pszGameVerNumber[0] == 'd') {
|
||||
// demo server
|
||||
pszGameVerNumber++;
|
||||
bIsDemo = true;
|
||||
}
|
||||
|
||||
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
|
||||
@@ -1074,7 +1080,11 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
|
||||
}
|
||||
}
|
||||
// always show the version
|
||||
sServerName = va(" (%s) %s", pszGameVer, pszHostName);
|
||||
if (!bIsDemo) {
|
||||
sServerName = va(" (%s) %s", pszGameVerNumber, pszHostName);
|
||||
} else {
|
||||
sServerName = va(" (d%s) %s", pszGameVerNumber, pszHostName);
|
||||
}
|
||||
|
||||
iRealIP = inet_addr(ServerGetAddress(server));
|
||||
iPort = ServerGetIntValue(server, "hostport", PORT_SERVER);
|
||||
|
||||
@@ -439,8 +439,10 @@ void UIFakkLabel::LayoutRenderModelAnim(Event *ev)
|
||||
|
||||
void UIFakkLabel::DrawStatbar(float frac)
|
||||
{
|
||||
vec4_t col;
|
||||
float alpha;
|
||||
vec4_t col;
|
||||
float alpha;
|
||||
qhandle_t hMat;
|
||||
float w, h;
|
||||
|
||||
col[0] = col[1] = col[2] = col[3] = 1.0;
|
||||
|
||||
@@ -475,11 +477,7 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
m_lastfrac = frac;
|
||||
|
||||
alpha = 1.0 - ((float)uid.time - m_flashtime) / 1500.0;
|
||||
if (alpha < 0.0) {
|
||||
alpha = 0.0;
|
||||
} else if (alpha > 1.0) {
|
||||
alpha = 1.0;
|
||||
}
|
||||
alpha = Q_clamp_float(alpha, 0, 1);
|
||||
|
||||
col[3] = alpha;
|
||||
|
||||
@@ -496,6 +494,24 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
re.SetColor(col);
|
||||
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
|
||||
if (m_statbar_material_marker) {
|
||||
hMat = m_statbar_material_marker->GetMaterial();
|
||||
w = re.GetShaderWidth(hMat);
|
||||
h = re.GetShaderHeight(hMat);
|
||||
|
||||
re.DrawStretchPic(
|
||||
m_frame.size.width * frac - w * 0.5,
|
||||
m_frame.size.height * 0.5 - h * 0.5,
|
||||
w,
|
||||
h,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
hMat
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case L_STATBAR_VERTICAL:
|
||||
@@ -513,6 +529,24 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial()
|
||||
);
|
||||
}
|
||||
|
||||
if (m_statbar_material_marker) {
|
||||
hMat = m_statbar_material_marker->GetMaterial();
|
||||
w = re.GetShaderWidth(hMat);
|
||||
h = re.GetShaderHeight(hMat);
|
||||
|
||||
re.DrawStretchPic(
|
||||
m_frame.size.width * frac - w * 0.5,
|
||||
m_frame.size.height * 0.5 - h * 0.5,
|
||||
w,
|
||||
h,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
hMat
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -542,6 +576,24 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
m_statbar_material_flash->GetMaterial()
|
||||
);
|
||||
}
|
||||
|
||||
if (m_statbar_material_marker) {
|
||||
hMat = m_statbar_material_marker->GetMaterial();
|
||||
w = re.GetShaderWidth(hMat);
|
||||
h = re.GetShaderHeight(hMat);
|
||||
|
||||
re.DrawStretchPic(
|
||||
m_frame.size.width * frac - w * 0.5,
|
||||
m_frame.size.height * 0.5 - h * 0.5,
|
||||
w,
|
||||
h,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
hMat
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case L_STATBAR_VERTICAL:
|
||||
@@ -569,6 +621,24 @@ void UIFakkLabel::DrawStatbar(float frac)
|
||||
m_statbar_material_flash->GetMaterial()
|
||||
);
|
||||
}
|
||||
|
||||
if (m_statbar_material_marker) {
|
||||
hMat = m_statbar_material_marker->GetMaterial();
|
||||
w = re.GetShaderWidth(hMat);
|
||||
h = re.GetShaderHeight(hMat);
|
||||
|
||||
re.DrawStretchPic(
|
||||
m_frame.size.width * frac - w * 0.5,
|
||||
m_frame.size.height * 0.5 - h * 0.5,
|
||||
w,
|
||||
h,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
hMat
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case L_STATBAR_VERTICAL_REVERSE:
|
||||
@@ -1393,6 +1463,12 @@ void UIFakkLabel::Draw(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (cl.snap.ps.activeItems[m_itemindex] < 0 || cl.snap.ps.activeItems[m_itemindex] >= MAX_WEAPONS) {
|
||||
// Fixed in OPM
|
||||
// Make sure to not overflow configstrings
|
||||
return;
|
||||
}
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
|
||||
if (m_bOutlinedText) {
|
||||
|
||||
+589
-307
File diff suppressed because it is too large.
Load diff
@@ -51,6 +51,9 @@ protected:
|
||||
void OnDeactivate(Event *ev);
|
||||
void DrawSubtitleOverlay(void);
|
||||
|
||||
// Added in 2.0
|
||||
void DrawNetProfile(void);
|
||||
|
||||
public:
|
||||
View3D();
|
||||
|
||||
|
||||
+72
-7
@@ -36,6 +36,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "cl_curl.h"
|
||||
#endif /* USE_CURL */
|
||||
|
||||
#ifdef USE_VOIP
|
||||
#include <opus.h>
|
||||
#endif
|
||||
|
||||
// file full of random crap that gets used to create cl_guid
|
||||
#define QKEY_FILE "qkey"
|
||||
#define QKEY_SIZE 2048
|
||||
@@ -174,6 +178,7 @@ typedef struct {
|
||||
int lastPacketSentTime; // for retransmits during connection
|
||||
int lastPacketTime; // for timeouts
|
||||
|
||||
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
|
||||
netadr_t serverAddress;
|
||||
int connectTime; // for connection retransmits
|
||||
int connectStartTime;
|
||||
@@ -239,15 +244,42 @@ typedef struct {
|
||||
int timeDemoMaxDuration; // maximum frame duration
|
||||
unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations
|
||||
|
||||
float aviVideoFrameRemainder;
|
||||
float aviSoundFrameRemainder;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
qboolean voipEnabled;
|
||||
qboolean voipCodecInitialized;
|
||||
|
||||
// incoming data...
|
||||
// !!! FIXME: convert from parallel arrays to array of a struct.
|
||||
OpusDecoder *opusDecoder[MAX_CLIENTS];
|
||||
byte voipIncomingGeneration[MAX_CLIENTS];
|
||||
int voipIncomingSequence[MAX_CLIENTS];
|
||||
float voipGain[MAX_CLIENTS];
|
||||
qboolean voipIgnore[MAX_CLIENTS];
|
||||
qboolean voipMuteAll;
|
||||
|
||||
// outgoing data...
|
||||
// if voipTargets[i / 8] & (1 << (i % 8)),
|
||||
// then we are sending to clientnum i.
|
||||
uint8_t voipTargets[(MAX_CLIENTS + 7) / 8];
|
||||
uint8_t voipFlags;
|
||||
OpusEncoder *opusEncoder;
|
||||
int voipOutgoingDataSize;
|
||||
int voipOutgoingDataFrames;
|
||||
int voipOutgoingSequence;
|
||||
byte voipOutgoingGeneration;
|
||||
byte voipOutgoingData[1024];
|
||||
float voipPower;
|
||||
#endif
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
qboolean compat;
|
||||
#endif
|
||||
|
||||
// big stuff at end of structure so most offsets are 15 bits or less
|
||||
netchan_t netchan;
|
||||
|
||||
float aviVideoFrameRemainder;
|
||||
float aviSoundFrameRemainder;
|
||||
} clientConnection_t;
|
||||
|
||||
extern clientConnection_t clc;
|
||||
@@ -297,8 +329,6 @@ typedef struct {
|
||||
qboolean cddialog; // bring up the cd needed dialog next frame
|
||||
qboolean no_menus;
|
||||
|
||||
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
|
||||
|
||||
// when the server clears the hunk, all of these must be restarted
|
||||
qboolean rendererRegistered;
|
||||
qboolean cgameStarted;
|
||||
@@ -353,8 +383,8 @@ typedef struct {
|
||||
void* savedCgameState;
|
||||
size_t savedCgameStateSize;
|
||||
char gcdResponse[73];
|
||||
int unknown3_0;
|
||||
int currentRate;
|
||||
// Added in 2.0
|
||||
netprofclient_t netprofile;
|
||||
qhandle_t charSetShader;
|
||||
qhandle_t whiteShader;
|
||||
qhandle_t consoleShader;
|
||||
@@ -385,6 +415,8 @@ extern cvar_t *cl_connect_timeout;
|
||||
extern cvar_t *cl_maxpackets;
|
||||
extern cvar_t *cl_packetdup;
|
||||
extern cvar_t *cl_shownet;
|
||||
extern cvar_t *cl_netprofile;
|
||||
extern cvar_t *cl_netprofileoverlay;
|
||||
extern cvar_t *cl_showSend;
|
||||
extern cvar_t *cl_timeNudge;
|
||||
extern cvar_t *cl_showTimeDelta;
|
||||
@@ -445,6 +477,32 @@ extern cvar_t *cl_r_fullscreen;
|
||||
|
||||
extern cvar_t *cl_consoleKeys;
|
||||
|
||||
#ifdef USE_MUMBLE
|
||||
extern cvar_t *cl_useMumble;
|
||||
extern cvar_t *cl_mumbleScale;
|
||||
#endif
|
||||
|
||||
#ifdef USE_VOIP
|
||||
// cl_voipSendTarget is a string: "all" to broadcast to everyone, "none" to
|
||||
// send to no one, or a comma-separated list of client numbers:
|
||||
// "0,7,2,23" ... an empty string is treated like "all".
|
||||
extern cvar_t *cl_voipUseVAD;
|
||||
extern cvar_t *cl_voipVADThreshold;
|
||||
extern cvar_t *cl_voipSend;
|
||||
extern cvar_t *cl_voipSendTarget;
|
||||
extern cvar_t *cl_voipGainDuringCapture;
|
||||
extern cvar_t *cl_voipCaptureMult;
|
||||
extern cvar_t *cl_voipShowMeter;
|
||||
extern cvar_t *cl_voip;
|
||||
|
||||
// 20ms at 48k
|
||||
#define VOIP_MAX_FRAME_SAMPLES ( 20 * 48 )
|
||||
|
||||
// 3 frame is 60ms of audio, the max opus will encode at once
|
||||
#define VOIP_MAX_PACKET_FRAMES 3
|
||||
#define VOIP_MAX_PACKET_SAMPLES ( VOIP_MAX_FRAME_SAMPLES * VOIP_MAX_PACKET_FRAMES )
|
||||
#endif
|
||||
|
||||
extern cvar_t *cg_gametype;
|
||||
|
||||
extern cvar_t* j_pitch;
|
||||
@@ -520,6 +578,7 @@ void IN_MouseOn( void );
|
||||
void IN_MouseOff( void );
|
||||
|
||||
void CL_InitInput (void);
|
||||
void CL_ShutdownInput(void);
|
||||
void CL_SendCmd (void);
|
||||
void CL_ClearState (void);
|
||||
void CL_ReadPackets (void);
|
||||
@@ -545,6 +604,10 @@ extern int cl_connectedToPureServer;
|
||||
extern int cl_connectedToCheatServer;
|
||||
extern msg_t *cl_currentMSG;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
void CL_Voip_f( void );
|
||||
#endif
|
||||
|
||||
void CL_SystemInfoChanged( void );
|
||||
void CL_ParseServerMessage( msg_t *msg );
|
||||
|
||||
@@ -583,6 +646,7 @@ void Con_DrawCharacter (int cx, int line, int num);
|
||||
|
||||
void Con_CheckResize (void);
|
||||
void Con_Init (void);
|
||||
void Con_Shutdown (void);
|
||||
void Con_Clear_f (void);
|
||||
void Con_ToggleConsole_f (void);
|
||||
void Con_DrawNotify (void);
|
||||
@@ -670,6 +734,7 @@ void LAN_SaveServersToCache( void );
|
||||
void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg); //int length, const byte *data );
|
||||
void CL_Netchan_TransmitNextFragment( netchan_t *chan );
|
||||
qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg );
|
||||
void CL_NET_OutOfBandPrint( netadr_t adr, const char* format, ... );
|
||||
|
||||
//
|
||||
// cl_avi.c
|
||||
|
||||
@@ -592,4 +592,29 @@ void S_ReLoad(soundsystemsavegame_t* pSave) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_StopMovieAudio
|
||||
==============
|
||||
*/
|
||||
void S_StopMovieAudio() {
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_CurrentMoviePosition
|
||||
==============
|
||||
*/
|
||||
int S_CurrentMoviePosition() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_SetupMovieAudio
|
||||
==============
|
||||
*/
|
||||
void S_SetupMovieAudio(const char* pszMovieName) {
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -86,6 +86,10 @@ const char* S_GetMusicFilename();
|
||||
int S_GetMusicLoopCount();
|
||||
unsigned int S_GetMusicOffset();
|
||||
|
||||
void S_StopMovieAudio();
|
||||
int S_CurrentMoviePosition();
|
||||
void S_SetupMovieAudio(const char* pszMovieName);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -161,12 +161,12 @@ void S_Base_SoundList( void ) {
|
||||
char type[4][16];
|
||||
char mem[2][16];
|
||||
|
||||
strcpy(type[0], "16bit");
|
||||
strcpy(type[1], "adpcm");
|
||||
strcpy(type[2], "daub4");
|
||||
strcpy(type[3], "mulaw");
|
||||
strcpy(mem[0], "paged out");
|
||||
strcpy(mem[1], "resident ");
|
||||
Q_strncpyz(type[0], "16bit", sizeof(type[0]));
|
||||
Q_strncpyz(type[1], "adpcm", sizeof(type[1]));
|
||||
Q_strncpyz(type[2], "daub4", sizeof(type[2]));
|
||||
Q_strncpyz(type[3], "mulaw", sizeof(type[3]));
|
||||
Q_strncpyz(mem[0], "paged out", sizeof(mem[0]));
|
||||
Q_strncpyz(mem[1], "resident ", sizeof(mem[1]));
|
||||
total = 0;
|
||||
for (sfx=s_knownSfx, i=0 ; i<s_numSfx ; i++, sfx++) {
|
||||
size = sfx->soundLength;
|
||||
@@ -303,7 +303,7 @@ static sfx_t *S_FindName( const char *name ) {
|
||||
|
||||
sfx = &s_knownSfx[i];
|
||||
Com_Memset (sfx, 0, sizeof(*sfx));
|
||||
strcpy (sfx->soundName, name);
|
||||
Q_strncpyz (sfx->soundName, name, sizeof(sfx->soundName));
|
||||
|
||||
sfx->next = sfxHash[hash];
|
||||
sfxHash[hash] = sfx;
|
||||
|
||||
@@ -280,15 +280,25 @@ S_BeginRegistration
|
||||
*/
|
||||
void S_BeginRegistration()
|
||||
{
|
||||
int i;
|
||||
|
||||
Com_Printf("------- Sound Begin Registration -------\n");
|
||||
|
||||
S_StopAllSounds(true);
|
||||
|
||||
++s_registrationSequence;
|
||||
s_registrationSequence++;
|
||||
s_inRegistration = true;
|
||||
s_knownSfx[0].registration_sequence = s_registrationSequence;
|
||||
|
||||
Com_Printf("------- Sound Begin Registration Complete -------\n");
|
||||
|
||||
// Added in OPM
|
||||
// Reset all sound entities
|
||||
// OG doesn't do this but this makes sure
|
||||
// entities don't leak info from previous sessions
|
||||
for (i = 0; i < ARRAY_LEN(s_entity); i++) {
|
||||
s_entity[i] = s_entity_t{};
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -34,7 +34,7 @@ void load_sfx_info()
|
||||
sfx_infos[0].max_factor = -1.0;
|
||||
sfx_infos[0].loop_start = -1;
|
||||
sfx_infos[0].loop_end = -1;
|
||||
sfx_infos[0].max_number_playing = 5;
|
||||
sfx_infos[0].max_number_playing = DEFAULT_SFX_NUMBER_PLAYING;
|
||||
number_of_sfx_infos = 1;
|
||||
|
||||
for (current_sound_file = 0; current_sound_file < 10; current_sound_file++) {
|
||||
@@ -62,7 +62,7 @@ void load_sfx_info()
|
||||
sfx_infos[number_of_sfx_infos].max_factor = -1.f;
|
||||
sfx_infos[number_of_sfx_infos].loop_start = -1;
|
||||
sfx_infos[number_of_sfx_infos].loop_end = -1;
|
||||
sfx_infos[number_of_sfx_infos].max_number_playing = 5;
|
||||
sfx_infos[number_of_sfx_infos].max_number_playing = DEFAULT_SFX_NUMBER_PLAYING;
|
||||
number_of_sfx_infos++;
|
||||
}
|
||||
} else if (!Q_stricmp(token, "loopstart")) {
|
||||
|
||||
@@ -36,6 +36,22 @@ extern cvar_t *s_separation;
|
||||
extern cvar_t *s_musicVolume;
|
||||
extern cvar_t *s_ambientVolume;
|
||||
|
||||
#define MAX_SOUNDSYSTEM_CHANNELS_3D 32
|
||||
#define MAX_SOUNDSYSTEM_CHANNELS_2D 32
|
||||
#define MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM 32
|
||||
#define MAX_SOUNDSYSTEM_POSITION_CHANNELS (MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D + MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM)
|
||||
#define MAX_SOUNDSYSTEM_SONGS 2
|
||||
#define MAX_SOUNDSYSTEM_MISC_CHANNELS 3
|
||||
#define MAX_SOUNDSYSTEM_CHANNELS \
|
||||
(MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D + MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM + MAX_SOUNDSYSTEM_SONGS \
|
||||
+ MAX_SOUNDSYSTEM_MISC_CHANNELS)
|
||||
#define MAX_SOUNDSYSTEM_LOOP_SOUNDS 64
|
||||
|
||||
#define SOUNDSYSTEM_CHANNEL_MP3_ID \
|
||||
(MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D + MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM + MAX_SOUNDSYSTEM_SONGS)
|
||||
#define SOUNDSYSTEM_CHANNEL_TRIGGER_MUSIC_ID (SOUNDSYSTEM_CHANNEL_MP3_ID + 1)
|
||||
#define SOUNDSYSTEM_CHANNEL_MOVIE_ID (SOUNDSYSTEM_CHANNEL_TRIGGER_MUSIC_ID + 1)
|
||||
|
||||
typedef struct {
|
||||
int format;
|
||||
float rate;
|
||||
@@ -134,7 +150,7 @@ typedef struct {
|
||||
} channelbasesavegame_t;
|
||||
|
||||
typedef struct {
|
||||
channelbasesavegame_t Channels[96];
|
||||
channelbasesavegame_t Channels[MAX_SOUNDSYSTEM_CHANNELS];
|
||||
} soundsystemsavegame_t;
|
||||
|
||||
enum channel_flags_t {
|
||||
@@ -162,6 +178,7 @@ enum loopsound_flags_t {
|
||||
#define MAX_SFX 1400
|
||||
#define MAX_SFX_INFOS 1000
|
||||
#define MAX_LOOP_SOUNDS 64
|
||||
#define DEFAULT_SFX_NUMBER_PLAYING 10 //5
|
||||
|
||||
extern qboolean s_bLastInitSound;
|
||||
extern qboolean s_bSoundStarted;
|
||||
|
||||
@@ -203,7 +203,7 @@ void DumpChunks()
|
||||
|
||||
iff_chunk_len = GetLittleLong();
|
||||
|
||||
Com_Printf("0x%x : %s (%d)\n", data_p - 4, str, iff_chunk_len);
|
||||
Com_Printf("0x%p : %s (%d)\n", data_p - 4, str, iff_chunk_len);
|
||||
|
||||
data_p += (iff_chunk_len + 1) & ~1;
|
||||
} while (data_p < (byte *)iff_end);
|
||||
@@ -404,6 +404,8 @@ qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, by
|
||||
datap += width;
|
||||
}
|
||||
|
||||
assert(iff_end - data_p == 0);
|
||||
|
||||
return newdatasize;
|
||||
}
|
||||
|
||||
@@ -414,10 +416,7 @@ DownSampleWav_MILES
|
||||
*/
|
||||
int DownSampleWav_MILES(wavinfo_t *info, byte *wav, int wavlength, int newkhz, byte **newdata)
|
||||
{
|
||||
//STUB_DESC("sound stuff");
|
||||
//return 0;
|
||||
// FIXME: unimplemented
|
||||
// Fallback to software downsampling
|
||||
// Fallback to software downsampling
|
||||
return DownSampleWav(info, wav, wavlength, newkhz, newdata);
|
||||
}
|
||||
|
||||
@@ -440,9 +439,6 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
||||
}
|
||||
|
||||
if (streamed) {
|
||||
//
|
||||
// Added in 2.0
|
||||
// Will be loaded next time
|
||||
sfx->length = 5000;
|
||||
sfx->width = 1;
|
||||
sfx->iFlags |= SFX_FLAG_STREAMED;
|
||||
@@ -513,6 +509,7 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
||||
if (newdatasize) {
|
||||
Z_Free(sfx->data);
|
||||
sfx->data = newdata;
|
||||
sfx->info.datasize = newdatasize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,7 +522,7 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
||||
sfx->data = NULL;
|
||||
}
|
||||
|
||||
sprintf(tempName, "k%s", fileName);
|
||||
Com_sprintf(tempName, sizeof(tempName), "k%s", fileName);
|
||||
UI_LoadResource(tempName);
|
||||
|
||||
if (strstr(fileName, "sound/null.wav")) {
|
||||
|
||||
@@ -233,7 +233,7 @@ static sfxHandle_t S_AL_BufferFind(const char *filename)
|
||||
ptr = &knownSfx[sfx];
|
||||
memset(ptr, 0, sizeof(*ptr));
|
||||
ptr->masterLoopSrc = -1;
|
||||
strcpy(ptr->filename, filename);
|
||||
Q_strncpyz(ptr->filename, filename, sizeof(ptr->filename));
|
||||
}
|
||||
|
||||
// Return the handle
|
||||
|
||||
+210
-186
File diff suppressed because it is too large.
Load diff
@@ -29,22 +29,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
typedef int S32;
|
||||
typedef unsigned int U32;
|
||||
|
||||
#define MAX_OPENAL_CHANNELS_3D 32
|
||||
#define MAX_OPENAL_CHANNELS_2D 32
|
||||
#define MAX_OPENAL_CHANNELS_2D_STREAM 32
|
||||
#define MAX_OPENAL_POSITION_CHANNELS (MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM)
|
||||
#define MAX_OPENAL_SONGS 2
|
||||
#define MAX_OPENAL_MISC_CHANNELS 3
|
||||
#define MAX_OPENAL_CHANNELS \
|
||||
(MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM + MAX_OPENAL_SONGS \
|
||||
+ MAX_OPENAL_MISC_CHANNELS)
|
||||
#define MAX_OPENAL_LOOP_SOUNDS 64
|
||||
|
||||
#define OPENAL_CHANNEL_MP3_ID \
|
||||
(MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM + MAX_OPENAL_SONGS)
|
||||
#define OPENAL_CHANNEL_TRIGGER_MUSIC_ID (OPENAL_CHANNEL_MP3_ID + 1)
|
||||
#define OPENAL_CHANNEL_MOVIE_ID (OPENAL_CHANNEL_TRIGGER_MUSIC_ID + 1)
|
||||
|
||||
#define MAX_STREAM_BUFFERS 16
|
||||
#define MAX_BUFFER_SAMPLES 16384
|
||||
|
||||
@@ -184,19 +168,23 @@ private:
|
||||
unsigned int getBytesPerSample() const;
|
||||
};
|
||||
|
||||
struct openal_movie_channel : public openal_channel {
|
||||
|
||||
};
|
||||
|
||||
struct openal_internal_t {
|
||||
openal_channel chan_3D[MAX_OPENAL_CHANNELS_3D];
|
||||
openal_channel chan_2D[MAX_OPENAL_CHANNELS_2D];
|
||||
openal_channel_two_d_stream chan_2D_stream[MAX_OPENAL_CHANNELS_2D_STREAM];
|
||||
openal_channel_two_d_stream chan_song[MAX_OPENAL_SONGS];
|
||||
openal_channel chan_3D[MAX_SOUNDSYSTEM_CHANNELS_3D];
|
||||
openal_channel chan_2D[MAX_SOUNDSYSTEM_CHANNELS_2D];
|
||||
openal_channel_two_d_stream chan_2D_stream[MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM];
|
||||
openal_channel_two_d_stream chan_song[MAX_SOUNDSYSTEM_SONGS];
|
||||
openal_channel_two_d_stream chan_mp3;
|
||||
openal_channel_two_d_stream chan_trig_music;
|
||||
openal_channel_two_d_stream chan_movie;
|
||||
|
||||
// Pointers to channels
|
||||
openal_channel *channel[MAX_OPENAL_CHANNELS];
|
||||
openal_channel *channel[MAX_SOUNDSYSTEM_CHANNELS];
|
||||
|
||||
openal_loop_sound_t loop_sounds[MAX_OPENAL_LOOP_SOUNDS];
|
||||
openal_loop_sound_t loop_sounds[MAX_SOUNDSYSTEM_LOOP_SOUNDS];
|
||||
|
||||
openal_channel movieChannel;
|
||||
sfx_t movieSFX;
|
||||
|
||||
@@ -150,6 +150,7 @@ void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffs
|
||||
void S_TriggeredMusic_Start();
|
||||
void S_TriggeredMusic_StartLoop();
|
||||
void S_TriggeredMusic_Stop();
|
||||
void S_TriggeredMusic_Volume();
|
||||
void S_TriggeredMusic_Pause();
|
||||
void S_TriggeredMusic_Unpause();
|
||||
void S_TriggeredMusic_PlayIntroMusic();
|
||||
@@ -166,3 +167,20 @@ unsigned int S_GetMusicOffset();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef USE_VOIP
|
||||
void S_StartCapture( void );
|
||||
int S_AvailableCaptureSamples( void );
|
||||
void S_Capture( int samples, byte *data );
|
||||
void S_StopCapture( void );
|
||||
void S_MasterGain( float gain );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+22
-11
@@ -27,8 +27,24 @@ file(
|
||||
|
||||
add_library(fgame SHARED ${SOURCES_GAME})
|
||||
|
||||
find_package(BISON)
|
||||
find_package(FLEX)
|
||||
#
|
||||
# Workaround to get a recent version Flex and Bison executables in MacOS
|
||||
# as Bison 2.3 shipped with MacOS doesn't work
|
||||
#
|
||||
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
|
||||
execute_process(COMMAND brew --prefix bison RESULT_VARIABLE APP_RESULT OUTPUT_VARIABLE APP_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (APP_RESULT EQUAL 0 AND EXISTS "${APP_PREFIX}")
|
||||
set(BISON_EXECUTABLE "${APP_PREFIX}/bin/bison")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND brew --prefix flex RESULT_VARIABLE APP_RESULT OUTPUT_VARIABLE APP_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (APP_RESULT EQUAL 0 AND EXISTS "${APP_PREFIX}")
|
||||
set(FLEX_EXECUTABLE "${APP_PREFIX}/bin/flex")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(BISON 3 REQUIRED)
|
||||
find_package(FLEX REQUIRED)
|
||||
|
||||
if (FLEX_FOUND)
|
||||
flex_target(fgame-lexer ${CMAKE_SOURCE_DIR}/code/parser/lex_source.txt ${CMAKE_SOURCE_DIR}/code/parser/generated/yyLexer.cpp DEFINES_FILE ${CMAKE_SOURCE_DIR}/code/parser/generated/yyLexer.h COMPILE_FLAGS "-Cem --nounistd")
|
||||
@@ -50,16 +66,11 @@ target_compile_features(fgame PUBLIC cxx_nullptr)
|
||||
target_compile_features(fgame PUBLIC c_variadic_macros)
|
||||
target_link_libraries(fgame PUBLIC qcommon)
|
||||
|
||||
set_target_properties(fgame PROPERTIES PREFIX "${TARGET_PLATFORM_PREFIX}")
|
||||
set_target_properties(fgame PROPERTIES OUTPUT_NAME "game${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(fgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
|
||||
set_target_properties(fgame PROPERTIES PREFIX "")
|
||||
set_target_properties(fgame PROPERTIES OUTPUT_NAME "game${TARGET_BIN_SUFFIX}")
|
||||
|
||||
INSTALL(
|
||||
TARGETS fgame
|
||||
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
|
||||
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
|
||||
)
|
||||
INSTALL(TARGETS fgame DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR})
|
||||
|
||||
if(MSVC)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:fgame> DESTINATION "${TARGET_BASE_GAME}" OPTIONAL)
|
||||
INSTALL(FILES $<TARGET_PDB_FILE:fgame> DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR} OPTIONAL)
|
||||
endif()
|
||||
+76
-34
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -327,7 +327,7 @@ void ClearProjectileTargets()
|
||||
|
||||
ProjectileTarget::ProjectileTarget()
|
||||
{
|
||||
m_iTarget = -1;
|
||||
m_iID = -1;
|
||||
setMoveType(MOVETYPE_NONE);
|
||||
setSolidType(SOLID_NOT);
|
||||
hideModel();
|
||||
@@ -337,12 +337,19 @@ ProjectileTarget::ProjectileTarget()
|
||||
|
||||
void ProjectileTarget::EventSetId(Event *ev)
|
||||
{
|
||||
m_iTarget = ev->GetInteger(1);
|
||||
m_iID = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
int ProjectileTarget::GetTarget() const
|
||||
int ProjectileTarget::GetId() const
|
||||
{
|
||||
return m_iTarget;
|
||||
return m_iID;
|
||||
}
|
||||
|
||||
void ProjectileTarget::Archive(Archiver& arc)
|
||||
{
|
||||
Entity::Archive(arc);
|
||||
|
||||
arc.ArchiveInteger(&m_iID);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(Animate, ProjectileGenerator, "ProjectileGenerator") {
|
||||
@@ -583,7 +590,7 @@ void ProjectileGenerator::GetLocalTargets()
|
||||
m_projectileTargets.ClearObjectList();
|
||||
for (i = 1; i <= g_projectileTargets.NumObjects(); i++) {
|
||||
ProjectileTarget *target = g_projectileTargets.ObjectAt(i);
|
||||
if (m_iId == target->GetTarget()) {
|
||||
if (m_iId == target->GetId()) {
|
||||
m_projectileTargets.AddObject(target);
|
||||
}
|
||||
}
|
||||
@@ -1635,7 +1642,7 @@ ThrobbingBox_Explosive::ThrobbingBox_Explosive()
|
||||
|
||||
setModel("items\\\\pulse_explosive.tik");
|
||||
m_sUsedModel = "items/explosive.tik";
|
||||
m_sSound = "explose_flak88";
|
||||
m_sSound = "explode_flak88";
|
||||
m_sActivateSound = "plantbomb";
|
||||
m_sTickSound = "bombtick";
|
||||
|
||||
@@ -1809,6 +1816,7 @@ void ThrobbingBox_Explosive::OnBlowUp(Event *ev)
|
||||
|
||||
ent = veh->QueryDriverSlotEntity(0);
|
||||
if (ent) {
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->Damage(this, this, ent->health * 2.f, vec_zero, vec_zero, vec_zero, 50, 0, MOD_VEHICLE);
|
||||
}
|
||||
}
|
||||
@@ -1842,7 +1850,7 @@ void ThrobbingBox_Explosive::OnUse(Event *ev)
|
||||
|
||||
if (m_fStopwatchDuration > 0) {
|
||||
Player *player = static_cast<Player *>(G_FindTarget(this, "player"));
|
||||
player->SetStopwatch(m_fStopwatchDuration, SWT_FUSE);
|
||||
player->SetStopwatch(m_fStopwatchDuration, SWT_NORMAL);
|
||||
LoopSound(m_sTickSound);
|
||||
}
|
||||
|
||||
@@ -1899,6 +1907,13 @@ CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_ExplodePlayerFlak88, "Thr
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
ThrobbingBox_ExplodePlayerFlak88::ThrobbingBox_ExplodePlayerFlak88()
|
||||
{
|
||||
spawnflags |= TBE_SPAWNFLAG_DESTROYED_MODEL;
|
||||
m_sDestroyedModel = "statweapons/flak88_d.tik";
|
||||
m_sEffect = "fx/demodamage_flak88.tik";
|
||||
}
|
||||
|
||||
/*QUAKED ThrobbingBox_ExplodeFlak88 (1.0 0.0 1.0) (-12 -12 -12) (12 12 12)
|
||||
|
||||
Explosive throbbing box. Connect to the object you want to make explode.
|
||||
@@ -1921,6 +1936,12 @@ CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_ExplodeFlak88, "Throbbing
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
ThrobbingBox_ExplodeFlak88::ThrobbingBox_ExplodeFlak88()
|
||||
{
|
||||
m_sDestroyedModel = "statweapons/flak88_d.tik";
|
||||
m_sEffect = "fx/demodamage_flak88.tik";
|
||||
}
|
||||
|
||||
/*QUAKED ThrobbingBox_ExplodeNebelwerfer (1.0 0.0 1.0) (-12 -12 -12) (12 12 12) ReplaceModel
|
||||
|
||||
Explosive throbbing box. Connect to the object you want to make explode.
|
||||
@@ -1943,6 +1964,11 @@ CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_ExplodeNebelwerfer, "Thro
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
ThrobbingBox_ExplodeNebelwerfer::ThrobbingBox_ExplodeNebelwerfer()
|
||||
{
|
||||
m_sDestroyedModel = "statweapons/nebelwerfer_d.tik";
|
||||
}
|
||||
|
||||
/*QUAKED ThrobbingBox_ExplodePlayerNebelwerfer (1.0 0.0 1.0) (-12 -12 -12) (12 12 12) ReplaceModel
|
||||
|
||||
Explosive throbbing box. Connect to the object you want to make explode.
|
||||
@@ -1961,10 +1987,16 @@ CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_ExplodeNebelwerfer, "Thro
|
||||
---------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_ExplodePlayerNebelwerfer, "ThrobbingBox_ExplodeNebelwerfer") {
|
||||
CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_ExplodePlayerNebelwerfer, "ThrobbingBox_ExplodePlayerNebelwerfer") {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
ThrobbingBox_ExplodePlayerNebelwerfer::ThrobbingBox_ExplodePlayerNebelwerfer()
|
||||
{
|
||||
spawnflags |= TBE_SPAWNFLAG_DESTROYED_MODEL;
|
||||
m_sDestroyedModel = "statweapons/nebelwerfer_d.tik";
|
||||
}
|
||||
|
||||
/*QUAKED ThrobbingBox_Stickybomb (1.0 0.0 1.0) (-12 -12 -12) (12 12 12) ReplaceModel WetFuse
|
||||
|
||||
Stickybomb throbbing box. Connect to the object you want to make explode.
|
||||
@@ -1984,7 +2016,7 @@ CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_ExplodePlayerNebelwerfer,
|
||||
|
||||
Event EV_StickyBombWet("stickybombwet", EV_DEFAULT, NULL, NULL, NULL);
|
||||
|
||||
CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_Stickybomb, "ThrobbingBox_ExplodeNebelwerfer") {
|
||||
CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_Stickybomb, "ThrobbingBox_Stickybomb") {
|
||||
{&EV_Damage, &ThrobbingBox_Stickybomb::OnBlowUp },
|
||||
{&EV_Use, &ThrobbingBox_Stickybomb::OnStickyBombUse},
|
||||
{&EV_StickyBombWet, &ThrobbingBox_Stickybomb::OnStickyBombWet},
|
||||
@@ -2022,7 +2054,7 @@ void ThrobbingBox_Stickybomb::OnStickyBombWet(Event *ev)
|
||||
|
||||
player = static_cast<Player *>(G_FindTarget(this, "player"));
|
||||
player->SetStopwatch(0, SWT_NORMAL);
|
||||
player->SetStopwatch(m_fStopwatchDuration - (level.svsFloatTime - m_fStopwatchStartTime), SWT_FUSE);
|
||||
player->SetStopwatch(m_fStopwatchDuration - (level.svsFloatTime - m_fStopwatchStartTime), SWT_FUSE_WET);
|
||||
}
|
||||
|
||||
void ThrobbingBox_Stickybomb::OnStickyBombUse(Event *ev)
|
||||
@@ -2462,31 +2494,38 @@ CLASS_DECLARATION(SimpleArchivedEntity, AISpawnPoint, "info_aispawnpoint") {
|
||||
|
||||
AISpawnPoint::AISpawnPoint()
|
||||
{
|
||||
m_iHealth = 100;
|
||||
m_iAccuracy = 20;
|
||||
m_iAmmoGrenade = 0;
|
||||
m_iBalconyHeight = 128;
|
||||
m_iDisguiseLevel = 1;
|
||||
m_fDisguisePeriod = 30000;
|
||||
m_fDisguiseRange = 256;
|
||||
m_fEnemyShareRange = 0;
|
||||
m_fFixedLeash = 0.0;
|
||||
m_iHealth = 100;
|
||||
|
||||
m_iAccuracy = 20;
|
||||
m_iAmmoGrenade = 0;
|
||||
m_iBalconyHeight = 128;
|
||||
|
||||
m_iDisguiseLevel = 1;
|
||||
m_fDisguisePeriod = 30000;
|
||||
m_fDisguiseRange = 256;
|
||||
|
||||
m_fEnemyShareRange = 0;
|
||||
m_fFixedLeash = 0.0;
|
||||
|
||||
m_fGrenadeAwareness = 20.0;
|
||||
m_fMaxNoticeTimeScale = 1;
|
||||
m_fSoundAwareness = 100;
|
||||
m_bPatrolWaitTrigger = 0;
|
||||
m_fHearing = 2048;
|
||||
m_fSight = world->m_fAIVisionDistance;
|
||||
m_fFov = 90;
|
||||
m_fLeash = 512;
|
||||
m_fMinDist = 128.0;
|
||||
m_fMaxDist = 1024;
|
||||
m_fInterval = 128.0;
|
||||
m_bDontDropWeapons = 0;
|
||||
m_bDontDropHealth = 0;
|
||||
m_bNoSurprise = 0;
|
||||
m_bForceDropWeapon = 0;
|
||||
m_bForceDropHealth = 0;
|
||||
|
||||
m_bPatrolWaitTrigger = false;
|
||||
|
||||
m_fHearing = 2048;
|
||||
m_fSight = world->m_fAIVisionDistance;
|
||||
m_fFov = 90;
|
||||
m_fLeash = 512;
|
||||
m_fMinDist = 128.0;
|
||||
m_fMaxDist = 1024;
|
||||
m_fInterval = 128.0;
|
||||
|
||||
m_bDontDropWeapons = false;
|
||||
m_bDontDropHealth = false;
|
||||
m_bNoSurprise = false;
|
||||
m_bForceDropWeapon = false;
|
||||
m_bForceDropHealth = false;
|
||||
}
|
||||
|
||||
void AISpawnPoint::GetForceDropHealth(Event *ev)
|
||||
@@ -2496,7 +2535,10 @@ void AISpawnPoint::GetForceDropHealth(Event *ev)
|
||||
|
||||
void AISpawnPoint::SetForceDropHealth(Event *ev)
|
||||
{
|
||||
// This is a bug on original mohaab (2.30 and 2.40), it should be m_bForceDropHealth
|
||||
// Fixed in OPM
|
||||
// This does look like a mistake on original mohaab (2.30 and 2.40)
|
||||
// it should be m_bForceDropHealth.
|
||||
// That's the reason why AI often don't drop weapons
|
||||
//m_bForceDropWeapon = ev->GetBoolean(1);
|
||||
m_bForceDropHealth = ev->GetBoolean(1);
|
||||
}
|
||||
|
||||
+17
-3
@@ -26,8 +26,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "animate.h"
|
||||
|
||||
typedef enum {
|
||||
CONTROLLER_ALLIES,
|
||||
CONTROLLER_AXIS,
|
||||
CONTROLLER_ALLIES,
|
||||
CONTROLLER_DRAW
|
||||
} eController;
|
||||
|
||||
@@ -45,7 +45,7 @@ void ClearProjectileTargets();
|
||||
class ProjectileTarget : public Entity
|
||||
{
|
||||
private:
|
||||
int m_iTarget;
|
||||
int m_iID;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileTarget);
|
||||
@@ -53,7 +53,9 @@ public:
|
||||
ProjectileTarget();
|
||||
|
||||
void EventSetId(Event *ev);
|
||||
int GetTarget() const;
|
||||
int GetId() const;
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
#define MAX_PROJECTILE_GENERATOR_TARGETS 16
|
||||
@@ -275,24 +277,36 @@ class ThrobbingBox_ExplodePlayerFlak88 : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodePlayerFlak88);
|
||||
|
||||
public:
|
||||
ThrobbingBox_ExplodePlayerFlak88();
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodeFlak88 : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodeFlak88);
|
||||
|
||||
public:
|
||||
ThrobbingBox_ExplodeFlak88();
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodeNebelwerfer : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodeNebelwerfer);
|
||||
|
||||
public:
|
||||
ThrobbingBox_ExplodeNebelwerfer();
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodePlayerNebelwerfer : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodePlayerNebelwerfer);
|
||||
|
||||
public:
|
||||
ThrobbingBox_ExplodePlayerNebelwerfer();
|
||||
};
|
||||
|
||||
#define TBE_SPAWNFLAG_DESTROYED_MODEL 1
|
||||
|
||||
@@ -269,13 +269,13 @@ void TOWObjective::TakeOver(Event *ev)
|
||||
|
||||
switch (controller) {
|
||||
case CONTROLLER_ALLIES:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "1");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "0");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "1");
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "1");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -308,13 +308,13 @@ void TOWObjective::OnInitialize(Event *ev)
|
||||
|
||||
switch (m_eController) {
|
||||
case CONTROLLER_ALLIES:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "1");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "0");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "1");
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "1");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
|
||||
break;
|
||||
case CONTROLLER_DRAW:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "0");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
|
||||
|
||||
@@ -59,8 +59,8 @@ class TOWObjectiveMan
|
||||
{
|
||||
private:
|
||||
Container<TOWObjective *> m_towObjectives;
|
||||
int m_iNumAxisObjectives;
|
||||
int m_iNumAlliesObjectives;
|
||||
int m_iNumAxisObjectives;
|
||||
|
||||
public:
|
||||
TOWObjectiveMan();
|
||||
|
||||
+199
-19
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2018 the OpenMoHAA team
|
||||
Copyright (C) 2018-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,42 +22,222 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "vehicle.h"
|
||||
#include "player.h"
|
||||
#include "g_phys.h"
|
||||
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleHalfTrack, "VehicleHalfTrack")
|
||||
{
|
||||
{ &EV_Damage, &VehicleHalfTrack::EventDamage },
|
||||
{ &EV_Killed, &VehicleHalfTrack::Killed },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleHalfTrack, "VehicleHalfTrack") {
|
||||
{&EV_Damage, &VehicleHalfTrack::EventDamage},
|
||||
{&EV_Killed, &VehicleHalfTrack::Killed },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
VehicleHalfTrack::VehicleHalfTrack()
|
||||
{
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
void VehicleHalfTrack::Think()
|
||||
{
|
||||
vmove_t vm;
|
||||
flags |= FL_POSTTHINK;
|
||||
vmove_t vm;
|
||||
flags |= FL_POSTTHINK;
|
||||
|
||||
prev_velocity = velocity;
|
||||
prev_velocity = velocity;
|
||||
|
||||
SetSlotsNonSolid();
|
||||
SetSlotsNonSolid();
|
||||
|
||||
SetMoveInfo(&vm);
|
||||
VmoveSingle(&vm);
|
||||
GetMoveInfo(&vm);
|
||||
SetMoveInfo(&vm);
|
||||
VmoveSingle(&vm);
|
||||
GetMoveInfo(&vm);
|
||||
|
||||
SetSlotsSolid();
|
||||
SetSlotsSolid();
|
||||
}
|
||||
|
||||
void VehicleHalfTrack::Postthink()
|
||||
{
|
||||
// FIXME: STUB
|
||||
float turn;
|
||||
Vector i, j, k;
|
||||
int index;
|
||||
trace_t trace;
|
||||
Vector normalsum;
|
||||
int numnormals;
|
||||
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;
|
||||
|
||||
primal_angles = angles;
|
||||
|
||||
if (drivable) {
|
||||
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;
|
||||
|
||||
temp = angles;
|
||||
temp.AngleVectorsLeft(&i, &j, &k);
|
||||
|
||||
j = vec_zero - j;
|
||||
|
||||
numnormals = 0;
|
||||
for (index = 0; index < MAX_CORNERS; index++) {
|
||||
Vector start, end;
|
||||
Vector boxoffset;
|
||||
Vector t_mins(-8, -8, -8), t_maxs(8, 8, 8);
|
||||
|
||||
boxoffset = Corners[index];
|
||||
start = origin + i * boxoffset[0] + j * boxoffset[1] + k * boxoffset[2];
|
||||
end = start + Vector(0, 0, -400);
|
||||
|
||||
trace = G_Trace(start, t_mins, t_maxs, end, this, MASK_VEHICLE_TIRES, false, "Vehicle::PostThink Corners");
|
||||
|
||||
if (trace.fraction != 1.0 || trace.startsolid) {
|
||||
normalsum += trace.plane.normal;
|
||||
}
|
||||
}
|
||||
|
||||
angles[2] = 0;
|
||||
|
||||
if (m_iNumNormals > 1) {
|
||||
temp = normalsum / numnormals;
|
||||
temp.normalize();
|
||||
i = temp.CrossProduct(temp, j);
|
||||
|
||||
pitch = i;
|
||||
angles[0] = -pitch.toPitch();
|
||||
}
|
||||
|
||||
turn = turnangle / 200.0;
|
||||
if (groundentity) {
|
||||
Vector newvel;
|
||||
Vector flatvel;
|
||||
|
||||
velocity[0] *= 0.925f;
|
||||
velocity[1] *= 0.925f;
|
||||
|
||||
flatvel = orientation[0];
|
||||
velocity += flatvel * currentspeed;
|
||||
flatvel[2] = 0;
|
||||
|
||||
drivespeed = Q_clamp_float(velocity * flatvel, -speed, speed);
|
||||
|
||||
newvel = flatvel * drivespeed;
|
||||
velocity[0] = newvel[0];
|
||||
velocity[1] = newvel[1];
|
||||
velocity[2] += drivespeed * jumpimpulse;
|
||||
|
||||
avelocity *= 0.05f;
|
||||
|
||||
if (steerinplace) {
|
||||
if (drivespeed < 350) {
|
||||
drivespeed = 350;
|
||||
}
|
||||
}
|
||||
|
||||
avelocity.y += turn * drivespeed;
|
||||
} else {
|
||||
avelocity *= 0.1f;
|
||||
}
|
||||
|
||||
angles += avelocity * level.frametime;
|
||||
setAngles(angles);
|
||||
}
|
||||
|
||||
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_backward";
|
||||
} else {
|
||||
sound_name = "snd_idle";
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
n_angles = (angles - primal_angles) * level.frametime;
|
||||
if (n_angles.x > 180 || n_angles.x < -180) {
|
||||
n_angles.x = 0;
|
||||
}
|
||||
if (n_angles.y > 180 || n_angles.y < -180) {
|
||||
n_angles.y = 0;
|
||||
}
|
||||
if (n_angles.z > 180 || n_angles.z < -180) {
|
||||
n_angles.z = 0;
|
||||
}
|
||||
|
||||
if (n_angles.x > -1 || n_angles.x < 1) {
|
||||
n_angles.x = 0;
|
||||
}
|
||||
if (n_angles.y > -1 || n_angles.y < 1) {
|
||||
n_angles.y = 0;
|
||||
}
|
||||
if (n_angles.z > -1 || n_angles.z < 1) {
|
||||
n_angles.z = 0;
|
||||
}
|
||||
|
||||
avelocity = n_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();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleHalfTrack::Killed(Event* ev)
|
||||
void VehicleHalfTrack::Killed(Event *ev)
|
||||
{
|
||||
deadflag = DEAD_DEAD;
|
||||
deadflag = DEAD_DEAD;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -31,6 +31,8 @@ cVehicleSlot::cVehicleSlot()
|
||||
prev_takedamage = (damage_t)-1;
|
||||
prev_solid = (solid_t)-1;
|
||||
prev_contents = -1;
|
||||
|
||||
prev_num_children = 0;
|
||||
}
|
||||
|
||||
void cVehicleSlot::NotSolid(void)
|
||||
@@ -51,11 +53,20 @@ void cVehicleSlot::NotSolid(void)
|
||||
prev_contents = ent->edict->r.contents;
|
||||
|
||||
ent->takedamage = DAMAGE_NO;
|
||||
ent->setSolidType(SOLID_NOT);
|
||||
|
||||
prev_num_children = 0;
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
// Fixed in OPM
|
||||
// Check for solidity
|
||||
if (sub && !sub->IsSubclassOfWeapon() && sub->getSolidType() != SOLID_NOT) {
|
||||
// Fixed in OPM
|
||||
// Save children solidity so it can properly be restored later
|
||||
prev_children_ent[prev_num_children] = sub;
|
||||
prev_children_solid[prev_num_children] = (solid_t)sub->getSolidType();
|
||||
prev_num_children++;
|
||||
|
||||
sub->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
@@ -67,7 +78,7 @@ void cVehicleSlot::NotSolid(void)
|
||||
|
||||
void cVehicleSlot::Solid(void)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (!(flags & FL_SWIM)) {
|
||||
return;
|
||||
@@ -87,12 +98,24 @@ void cVehicleSlot::Solid(void)
|
||||
prev_solid = (solid_t)-1;
|
||||
prev_contents = -1;
|
||||
|
||||
//
|
||||
// Fixed in OPM
|
||||
// Restore children solidity
|
||||
//
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_BBOX);
|
||||
for (j = 0; j < prev_num_children; j++) {
|
||||
if (prev_children_ent[j] == sub) {
|
||||
sub->setSolidType(prev_children_solid[j]);
|
||||
}
|
||||
}
|
||||
|
||||
//sub->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
|
||||
prev_num_children = 0;
|
||||
}
|
||||
|
||||
cTurretSlot::cTurretSlot()
|
||||
@@ -136,9 +159,19 @@ void cTurretSlot::NotSolid(void)
|
||||
}
|
||||
}
|
||||
|
||||
prev_num_children = 0;
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
// Fixed in OPM
|
||||
// Check for solidity
|
||||
if (sub && !sub->IsSubclassOfWeapon() && sub->getSolidType() != SOLID_NOT) {
|
||||
// Fixed in OPM
|
||||
// Save children solidity so it can properly be restored later
|
||||
prev_children_ent[prev_num_children] = sub;
|
||||
prev_children_solid[prev_num_children] = (solid_t)sub->getSolidType();
|
||||
prev_num_children++;
|
||||
|
||||
sub->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
@@ -146,7 +179,7 @@ void cTurretSlot::NotSolid(void)
|
||||
|
||||
void cTurretSlot::Solid(void)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (!(flags & FL_SWIM)) {
|
||||
return;
|
||||
@@ -177,10 +210,22 @@ void cTurretSlot::Solid(void)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Fixed in OPM
|
||||
// Restore children solidity
|
||||
//
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_BBOX);
|
||||
for (j = 0; j < prev_num_children; j++) {
|
||||
if (prev_children_ent[j] == sub) {
|
||||
sub->setSolidType(prev_children_solid[j]);
|
||||
}
|
||||
}
|
||||
|
||||
//sub->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
|
||||
prev_num_children = 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -46,12 +46,19 @@ protected:
|
||||
solid_t prev_solid;
|
||||
int prev_contents;
|
||||
|
||||
//
|
||||
// Added in OPM
|
||||
// Used for properly saving and restoring children solidity
|
||||
Entity *prev_children_ent[MAX_MODEL_CHILDREN];
|
||||
solid_t prev_children_solid[MAX_MODEL_CHILDREN];
|
||||
int prev_num_children;
|
||||
|
||||
public:
|
||||
cVehicleSlot();
|
||||
|
||||
virtual void NotSolid(void);
|
||||
virtual void Solid(void);
|
||||
void Archive(Archiver &arc) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline void cVehicleSlot::Archive(Archiver& arc)
|
||||
|
||||
@@ -334,7 +334,10 @@ void VehicleTank::Postthink()
|
||||
// the tank was non-solid with a player driver,
|
||||
// instead of the driver being non-solid.
|
||||
//setSolidType(SOLID_NOT);
|
||||
driver.ent->setSolidType(SOLID_NOT);
|
||||
|
||||
// Fixed in OPM
|
||||
// Driver is made non-solid in Vehicle::MoveThink
|
||||
//driver.ent->setSolidType(SOLID_NOT);
|
||||
} else {
|
||||
driver.ent->takedamage = DAMAGE_NO;
|
||||
driver.ent->setSolidType(SOLID_NOT);
|
||||
@@ -503,7 +506,7 @@ void VehicleTank::UpdateSound()
|
||||
// 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
|
||||
// So the other native method is overridden instead
|
||||
/*
|
||||
void VehicleTank::AttachDriverSlot(Event *ev)
|
||||
{
|
||||
|
||||
+92
-93
@@ -558,7 +558,7 @@ Event EV_Actor_DamagePuff
|
||||
EV_DEFAULT,
|
||||
"vv",
|
||||
"position direction",
|
||||
"Spawns a puff of 'blood' smoke at the speficied location in the specified direction.",
|
||||
"Spawns a puff of 'blood' smoke at the specified location in the specified direction.",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_Actor_SetAngleYawSpeed
|
||||
@@ -2628,7 +2628,7 @@ CLASS_DECLARATION(SimpleActor, Actor, "Actor") {
|
||||
//{&EV_Actor_SetBreathSteam2, &Actor::EventSetBreathSteam },
|
||||
//====
|
||||
{&EV_Actor_CalcGrenadeToss, &Actor::EventCalcGrenadeToss },
|
||||
{&EV_Actor_CalcGrenadeToss2, &Actor::EventCalcGrenadeToss },
|
||||
{&EV_Actor_CalcGrenadeToss2, &Actor::EventCalcGrenadeToss2 },
|
||||
{&EV_Actor_GetNoSurprise, &Actor::EventGetNoSurprise },
|
||||
{&EV_Actor_SetNoSurprise, &Actor::EventSetNoSurprise },
|
||||
{&EV_Actor_SetNoSurprise2, &Actor::EventSetNoSurprise },
|
||||
@@ -3212,7 +3212,7 @@ void Actor::GetMoveInfo(mmove_t *mm)
|
||||
m_Dest - Vector(0, 0, 16384),
|
||||
(Entity *)NULL,
|
||||
MASK_MOVEINFO,
|
||||
qfalse,
|
||||
false,
|
||||
"Actor::GetMoveInfo"
|
||||
);
|
||||
|
||||
@@ -3744,7 +3744,7 @@ void Actor::DoMove(void)
|
||||
case ANIM_MODE_SCRIPTED:
|
||||
setAngles(angles + Vector(0, angular_delta, 0));
|
||||
trace = G_Trace(
|
||||
origin, mins, maxs, origin + frame_delta, this, edict->clipmask & ~MASK_SCRIPT_SLAVE, qtrue, "Actor"
|
||||
origin, mins, maxs, origin + frame_delta, this, edict->clipmask & ~MASK_SCRIPT_SLAVE, true, "Actor"
|
||||
);
|
||||
SafeSetOrigin(trace.endpos);
|
||||
velocity = frame_delta / level.frametime;
|
||||
@@ -3956,7 +3956,7 @@ bool Actor::CanShoot(Entity *ent)
|
||||
Vector vGunPos;
|
||||
|
||||
if (FriendlyInLineOfFire(ent)) {
|
||||
// Added in 2.0
|
||||
// Added in 2.0
|
||||
// Check if a friend is in sight
|
||||
bCanShoot = false;
|
||||
} else if (ent->IsSubclassOfSentient()) {
|
||||
@@ -3974,7 +3974,7 @@ bool Actor::CanShoot(Entity *ent)
|
||||
this,
|
||||
sen,
|
||||
MASK_CANSEE,
|
||||
qfalse,
|
||||
false,
|
||||
"Actor::CanShoot centroid"
|
||||
)) {
|
||||
bCanShoot = true;
|
||||
@@ -3986,7 +3986,7 @@ bool Actor::CanShoot(Entity *ent)
|
||||
this,
|
||||
sen,
|
||||
MASK_CANSEE,
|
||||
qfalse,
|
||||
false,
|
||||
"Actor::CanShoot eyes"
|
||||
)) {
|
||||
bCanShoot = true;
|
||||
@@ -4027,7 +4027,7 @@ bool Actor::CanSeeFrom(vec3_t pos, Entity *ent)
|
||||
return false;
|
||||
}
|
||||
|
||||
return G_SightTrace(pos, vec_zero, vec_zero, ent->centroid, this, ent, MASK_CANSEE, qfalse, "Actor::CanSeeFrom");
|
||||
return G_SightTrace(pos, vec_zero, vec_zero, ent->centroid, this, ent, MASK_CANSEE, false, "Actor::CanSeeFrom");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4300,14 +4300,14 @@ void Actor::ShowInfo(float fDot, float fDist)
|
||||
|
||||
G_DebugLine(centroid, a, 0.0, 1.0, 0.0, 1.0);
|
||||
|
||||
G_DebugCircle(a, m_fLeash, 0.0, 1.0, 0.0, 1.0, qtrue);
|
||||
G_DebugCircle(a, m_fLeash, 0.0, 1.0, 0.0, 1.0, true);
|
||||
|
||||
G_DebugCircle(centroid, m_fMinDistance, 1.0, 0.0, 0.0, 1.0, qtrue);
|
||||
G_DebugCircle(centroid, m_fMinDistance, 1.0, 0.0, 0.0, 1.0, true);
|
||||
|
||||
G_DebugCircle(centroid, m_fMaxDistance, 0.0, 0.0, 1.0, 1.0, qtrue);
|
||||
G_DebugCircle(centroid, m_fMaxDistance, 0.0, 0.0, 1.0, 1.0, true);
|
||||
} else if (g_entinfo->integer == 2) {
|
||||
G_DebugCircle(centroid, m_fHearing, 1.0, 0.0, 0.0, 1.0, qtrue);
|
||||
G_DebugCircle(centroid, m_fSight, 0.0, 0.0, 1.0, 1.0, qtrue);
|
||||
G_DebugCircle(centroid, m_fHearing, 1.0, 0.0, 0.0, 1.0, true);
|
||||
G_DebugCircle(centroid, m_fSight, 0.0, 0.0, 1.0, 1.0, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5057,7 +5057,7 @@ void Actor::HandlePain(Event *ev)
|
||||
//FIXME: macro
|
||||
SetCuriousAnimHint(7);
|
||||
|
||||
// Added in 2.30 the m_bIsCurous check
|
||||
// Added in 2.30 the m_bIsCurous check
|
||||
if (m_bEnableEnemy && m_ThinkStates[THINKLEVEL_IDLE] == THINKSTATE_IDLE && m_bIsCurious) {
|
||||
SetEnemyPos(attacker->origin);
|
||||
m_pszDebugState = "from_pain";
|
||||
@@ -5394,7 +5394,8 @@ void Actor::MovePath(float fMoveSpeed)
|
||||
if (m_WallDir) {
|
||||
if (level.inttime >= m_iWallDodgeTimeout) {
|
||||
m_WallDir = 0;
|
||||
} else if (DotProduct2D(mm.desired_dir, m_PrevObstacleNormal) > 0 && CrossProduct2D(mm.desired_dir, m_PrevObstacleNormal) < 0) {
|
||||
} else if (DotProduct2D(mm.desired_dir, m_PrevObstacleNormal) > 0
|
||||
&& CrossProduct2D(mm.desired_dir, m_PrevObstacleNormal) < 0) {
|
||||
m_iWallDodgeTimeout = level.inttime + 1000;
|
||||
m_WallDir = -m_WallDir;
|
||||
}
|
||||
@@ -5646,13 +5647,20 @@ void Actor::EventSetMood(Event *ev)
|
||||
===============
|
||||
Actor::EventDamagePuff
|
||||
|
||||
Spawns a puff of 'blood' smoke at the speficied location in the specified direction.
|
||||
Spawns a puff of 'blood' smoke at the specified location in the specified direction.
|
||||
===============
|
||||
*/
|
||||
void Actor::EventDamagePuff(Event *ev)
|
||||
{
|
||||
Vector pos = ev->GetVector(1);
|
||||
Vector dir = ev->GetVector(2);
|
||||
int bulletbits;
|
||||
|
||||
// Fixed in OPM
|
||||
// Large bullet flag normally take 2 bits since 2.0.
|
||||
// However, in OG Spearhead and Breakthrough, EventDamagePuff
|
||||
// mistakenly uses 1 bit which causes a parse message error
|
||||
bulletbits = (g_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) ? 2 : 1;
|
||||
|
||||
gi.SetBroadcastVisible(pos, NULL);
|
||||
|
||||
@@ -5662,7 +5670,7 @@ void Actor::EventDamagePuff(Event *ev)
|
||||
gi.MSG_WriteCoord(pos.z);
|
||||
|
||||
gi.MSG_WriteDir(dir);
|
||||
gi.MSG_WriteBits(0, 1);
|
||||
gi.MSG_WriteBits(0, bulletbits);
|
||||
gi.MSG_EndCGM();
|
||||
}
|
||||
|
||||
@@ -6206,7 +6214,7 @@ bool Actor::MoveToPatrolCurrentNode(void)
|
||||
IdleLook();
|
||||
Anim_Idle();
|
||||
// tell scripts the move has failed
|
||||
parm.movefail = qtrue;
|
||||
parm.movefail = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6596,15 +6604,7 @@ void Actor::DetectSmokeGrenades(void)
|
||||
|
||||
if (fDistSquared > Square(256) || InFOV(sprite->origin)) {
|
||||
if (G_SightTrace(
|
||||
eyePos,
|
||||
vec_zero,
|
||||
vec_zero,
|
||||
sprite->origin,
|
||||
this,
|
||||
NULL,
|
||||
MASK_CANSEE,
|
||||
qfalse,
|
||||
"Actor::DetectSmokeGrenades"
|
||||
eyePos, vec_zero, vec_zero, sprite->origin, this, NULL, MASK_CANSEE, false, "Actor::DetectSmokeGrenades"
|
||||
)) {
|
||||
m_PotentialEnemies.ConfirmEnemy(this, sprite->owner);
|
||||
}
|
||||
@@ -6696,12 +6696,12 @@ void Actor::EventSetAnim(Event *ev)
|
||||
int slot = 0;
|
||||
int anim;
|
||||
const_str flagVal;
|
||||
qboolean flagged = qfalse;
|
||||
qboolean flagged = false;
|
||||
|
||||
switch (ev->NumArgs()) {
|
||||
case 4:
|
||||
flagVal = ev->GetConstString(4);
|
||||
flagged = qtrue;
|
||||
flagged = true;
|
||||
if (flagVal != STRING_FLAGGED) {
|
||||
ScriptError("unknown keyword '%s', expected 'flagged'", Director.GetString(flagVal).c_str());
|
||||
}
|
||||
@@ -6732,11 +6732,11 @@ void Actor::EventSetAnim(Event *ev)
|
||||
}
|
||||
|
||||
if (!slot) {
|
||||
flagged = qtrue;
|
||||
flagged = true;
|
||||
}
|
||||
|
||||
if (flagged) {
|
||||
parm.motionfail = qtrue;
|
||||
parm.motionfail = true;
|
||||
}
|
||||
|
||||
if (!m_bLevelMotionAnim) {
|
||||
@@ -6750,7 +6750,7 @@ void Actor::EventSetAnim(Event *ev)
|
||||
StartMotionAnimSlot(slot, anim, weight);
|
||||
if (flagged) {
|
||||
m_iMotionSlot = GetMotionSlot(slot);
|
||||
parm.motionfail = qfalse;
|
||||
parm.motionfail = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6764,10 +6764,10 @@ End action animation.
|
||||
*/
|
||||
void Actor::EventEndActionAnim(Event *ev)
|
||||
{
|
||||
parm.upperfail = qtrue;
|
||||
parm.upperfail = true;
|
||||
if (!m_bLevelActionAnim) {
|
||||
ChangeActionAnim();
|
||||
parm.upperfail = qfalse;
|
||||
parm.upperfail = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6794,7 +6794,7 @@ void Actor::EventSetMotionAnim(Event *ev)
|
||||
UnknownAnim(Director.GetString(name), edict->tiki);
|
||||
}
|
||||
|
||||
parm.motionfail = qtrue;
|
||||
parm.motionfail = true;
|
||||
|
||||
if (!m_bLevelMotionAnim) {
|
||||
ChangeMotionAnim();
|
||||
@@ -6805,7 +6805,7 @@ void Actor::EventSetMotionAnim(Event *ev)
|
||||
// set the slot
|
||||
m_iMotionSlot = GetMotionSlot(0);
|
||||
|
||||
parm.motionfail = qfalse;
|
||||
parm.motionfail = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6843,7 +6843,7 @@ void Actor::EventSetAimMotionAnim(Event *ev)
|
||||
UnknownAnim(Director.GetString(name), edict->tiki);
|
||||
}
|
||||
|
||||
parm.motionfail = qtrue;
|
||||
parm.motionfail = true;
|
||||
|
||||
if (!m_bLevelMotionAnim) {
|
||||
ChangeMotionAnim();
|
||||
@@ -6856,7 +6856,7 @@ void Actor::EventSetAimMotionAnim(Event *ev)
|
||||
StartAimMotionAnimSlot(2, anim_high);
|
||||
|
||||
m_iMotionSlot = GetMotionSlot(1);
|
||||
parm.motionfail = qfalse;
|
||||
parm.motionfail = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6907,7 +6907,7 @@ void Actor::EventSetActionAnim(Event *ev)
|
||||
UnknownAnim(derivedName, edict->tiki);
|
||||
}
|
||||
|
||||
parm.upperfail = qtrue;
|
||||
parm.upperfail = true;
|
||||
if (!m_bLevelActionAnim) {
|
||||
ChangeActionAnim();
|
||||
m_bAimAnimSet = true;
|
||||
@@ -6918,7 +6918,7 @@ void Actor::EventSetActionAnim(Event *ev)
|
||||
StartAimAnimSlot(1, anim_forward);
|
||||
StartAimAnimSlot(2, anim_down);
|
||||
m_iActionSlot = GetActionSlot(0);
|
||||
parm.upperfail = qfalse;
|
||||
parm.upperfail = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6973,13 +6973,16 @@ void Actor::EventSetUpperAnim(Event *ev)
|
||||
UnknownAnim(Director.GetString(name), edict->tiki);
|
||||
}
|
||||
|
||||
parm.upperfail = qtrue;
|
||||
parm.upperfail = true;
|
||||
|
||||
if (!m_bLevelActionAnim) {
|
||||
ChangeActionAnim();
|
||||
m_bActionAnimSet = true;
|
||||
|
||||
StartActionAnimSlot(anim);
|
||||
m_iActionSlot = SimpleActor::GetActionSlot(0);
|
||||
parm.upperfail = qfalse;
|
||||
m_iActionSlot = GetActionSlot(0);
|
||||
|
||||
parm.upperfail = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7007,7 +7010,7 @@ bool Actor::SoundSayAnim(const_str name, byte bLevelSayAnim)
|
||||
edict->tiki->a->name
|
||||
);
|
||||
|
||||
Sound(Director.GetString(name), CHAN_AUTO, 0, 0, 0, NULL, 0, 1, 1, -1);
|
||||
Sound(Director.GetString(name), CHAN_AUTO, 0, 0, NULL, 0, 0, 1, 1, -1);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -7091,7 +7094,7 @@ void Actor::EventSetSayAnim(Event *ev)
|
||||
}
|
||||
|
||||
name = ev->GetConstString(1);
|
||||
parm.sayfail = qtrue;
|
||||
parm.sayfail = true;
|
||||
anim = gi.Anim_NumForName(edict->tiki, Director.GetString(name));
|
||||
|
||||
if (anim == -1) {
|
||||
@@ -7147,7 +7150,7 @@ void Actor::EventSetSayAnim(Event *ev)
|
||||
m_iSaySlot = GetSaySlot();
|
||||
}
|
||||
|
||||
parm.sayfail = qfalse;
|
||||
parm.sayfail = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -7313,6 +7316,8 @@ void Actor::UpdateUpperAnim(void)
|
||||
if (!m_bActionAnimSet) {
|
||||
Unregister(STRING_UPPERANIMDONE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gi.Anim_FlagsSkel(edict->tiki, anim);
|
||||
@@ -7699,10 +7704,7 @@ void Actor::SetThinkState(eThinkState state, eThinkLevel level)
|
||||
m_csIdleMood = STRING_NERVOUS;
|
||||
map = m_ThinkMap[THINKSTATE_ATTACK];
|
||||
|
||||
if (map != THINK_ALARM
|
||||
&& map != THINK_WEAPONLESS
|
||||
&& map != THINK_DOG_ATTACK
|
||||
&& !GetWeapon(WEAPON_MAIN)) {
|
||||
if (map != THINK_ALARM && map != THINK_WEAPONLESS && map != THINK_DOG_ATTACK && !GetWeapon(WEAPON_MAIN)) {
|
||||
Com_Printf(
|
||||
"^~^~^ LD ERROR: (entnum %i, radnum %i, targetname '%s'): forcing weaponless attack state.\n"
|
||||
"^~^~^ Level designers should specify 'type_attack weaponless' for this guy.\n",
|
||||
@@ -8135,8 +8137,8 @@ void Actor::EndState(int level)
|
||||
{
|
||||
GlobalFuncs_t *think;
|
||||
|
||||
think = &GlobalFuncs[m_Think[level]];
|
||||
m_Think[level] = THINK_VOID;
|
||||
think = &GlobalFuncs[m_Think[level]];
|
||||
m_Think[level] = THINK_VOID;
|
||||
|
||||
if (think->EndState) {
|
||||
(this->*think->EndState)();
|
||||
@@ -8264,8 +8266,8 @@ void Actor::FixAIParameters(void)
|
||||
if (m_pTetherEnt) {
|
||||
fMinLeash = 64;
|
||||
if (m_pTetherEnt->IsSubclassOfEntity()) {
|
||||
Entity* pEnt = static_cast<Entity*>(m_pTetherEnt.Pointer());
|
||||
fMinLeash = pEnt->maxs[0] - pEnt->mins[1] + pEnt->maxs[1] - pEnt->mins[1];
|
||||
Entity *pEnt = static_cast<Entity *>(m_pTetherEnt.Pointer());
|
||||
fMinLeash = pEnt->maxs[0] - pEnt->mins[1] + pEnt->maxs[1] - pEnt->mins[1];
|
||||
}
|
||||
|
||||
if (m_fLeash < fMinLeash) {
|
||||
@@ -8597,7 +8599,7 @@ bool Actor::PassesTransitionConditions_Disguise(void)
|
||||
this,
|
||||
player,
|
||||
MASK_TRANSITION,
|
||||
qfalse,
|
||||
false,
|
||||
"Actor::PassesTransitionConditions_Disguise"
|
||||
);
|
||||
}
|
||||
@@ -9151,7 +9153,7 @@ void Actor::CuriousSound(int iType, vec3_t sound_origin, float fDistSquared, flo
|
||||
}
|
||||
}
|
||||
|
||||
if ((fRangeFactor * m_fSoundAwareness) < (rand() / (0x7fffffff / 100.0))) {
|
||||
if ((fRangeFactor * m_fSoundAwareness) < random()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9231,8 +9233,7 @@ void Actor::WeaponSound(int iType, vec3_t sound_origin, float fDistSquared, floa
|
||||
pEnemy = pOwner->m_Enemy;
|
||||
}
|
||||
|
||||
if (pOwner->m_Team == m_Team && !pEnemy && pOwner->IsSubclassOfActor()
|
||||
&& originator->IsSubclassOfWeapon()) {
|
||||
if (pOwner->m_Team == m_Team && !pEnemy && pOwner->IsSubclassOfActor() && originator->IsSubclassOfWeapon()) {
|
||||
Actor *pActor = static_cast<Actor *>(pOwner);
|
||||
Weapon *pWeapon = static_cast<Weapon *>(originator);
|
||||
|
||||
@@ -9455,7 +9456,7 @@ void Actor::NotifySquadmateKilled(Sentient *pSquadMate, Sentient *pAttacker)
|
||||
this,
|
||||
pSquadMate,
|
||||
MASK_AI_CANSEE,
|
||||
qfalse,
|
||||
false,
|
||||
"Actor::NotifySquadmateKilled"
|
||||
);
|
||||
}
|
||||
@@ -9638,7 +9639,7 @@ bool Actor::ValidGrenadePath(const Vector& vFrom, const Vector& vTo, Vector& vVe
|
||||
G_DebugLine(vFrom, vPoint1, 1.0, 0.5, 0.5, 1.0);
|
||||
}
|
||||
|
||||
if (!G_SightTrace(vFrom, mins, maxs, vPoint1, this, NULL, MASK_GRENADEPATH, qfalse, "Actor::ValidGrenadePath 1")) {
|
||||
if (!G_SightTrace(vFrom, mins, maxs, vPoint1, this, NULL, MASK_GRENADEPATH, false, "Actor::ValidGrenadePath 1")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -9651,9 +9652,7 @@ bool Actor::ValidGrenadePath(const Vector& vFrom, const Vector& vTo, Vector& vVe
|
||||
G_DebugLine(vPoint1, vPoint2, 1.0, 0.5, 0.5, 1.0);
|
||||
}
|
||||
|
||||
if (!G_SightTrace(
|
||||
vPoint1, mins, maxs, vPoint2, this, NULL, MASK_GRENADEPATH, qfalse, "Actor::ValidGrenadePath 2"
|
||||
)) {
|
||||
if (!G_SightTrace(vPoint1, mins, maxs, vPoint2, this, NULL, MASK_GRENADEPATH, false, "Actor::ValidGrenadePath 2")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -9673,16 +9672,14 @@ bool Actor::ValidGrenadePath(const Vector& vFrom, const Vector& vTo, Vector& vVe
|
||||
if (ai_debug_grenades->integer) {
|
||||
G_DebugLine(vPoint2, vPoint3, 1.0, 0.5, 0.5, 1.0);
|
||||
}
|
||||
if (!G_SightTrace(
|
||||
vPoint2, mins, maxs, vPoint3, this, NULL, MASK_GRENADEPATH, qfalse, "Actor::ValidGrenadePath 3"
|
||||
)) {
|
||||
if (!G_SightTrace(vPoint2, mins, maxs, vPoint3, this, NULL, MASK_GRENADEPATH, false, "Actor::ValidGrenadePath 3")) {
|
||||
return false;
|
||||
}
|
||||
if (ai_debug_grenades->integer) {
|
||||
G_DebugLine(vPoint3, vTo, 1.0, 0.5, 0.5, 1.0);
|
||||
}
|
||||
|
||||
trace = G_Trace(vPoint3, mins, maxs, vTo, this, MASK_GRENADEPATH, qfalse, "Actor::ValidGrenadePath 4");
|
||||
trace = G_Trace(vPoint3, mins, maxs, vTo, this, MASK_GRENADEPATH, false, "Actor::ValidGrenadePath 4");
|
||||
if (!trace.allsolid) {
|
||||
if (!trace.ent) {
|
||||
return true;
|
||||
@@ -9715,7 +9712,7 @@ Vector Actor::CalcThrowVelocity(const Vector& vFrom, const Vector& vTo)
|
||||
|
||||
vDelta = vTo - vFrom;
|
||||
fHorzDistSquared = vDelta.lengthXYSquared();
|
||||
fDistance = sqrt(fHorzDistSquared + vDelta.z * vDelta.z);
|
||||
fDistance = sqrt(fHorzDistSquared + Square(vDelta.z));
|
||||
|
||||
// original irl equation: v10 = sqrt(fGravity * 0.5 * fHorzDistSquared / (fDistance * trigMult ))
|
||||
// trigMult = (cos(th)/ tan(al) - sin(th)/tanSquared(al))
|
||||
@@ -10490,8 +10487,7 @@ bool Actor::CanMovePathWithLeash(void) const
|
||||
}
|
||||
|
||||
VectorSub2D(origin, m_vHome, delta);
|
||||
if (VectorLength2DSquared(delta) >= m_fLeashSquared
|
||||
&& DotProduct2D(m_Path.CurrentDelta(), delta) >= 0) {
|
||||
if (VectorLength2DSquared(delta) >= m_fLeashSquared && DotProduct2D(m_Path.CurrentDelta(), delta) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10530,7 +10526,7 @@ Vector Actor::GunTarget(bool bNoCollision, const vec3_t position, const vec3_t f
|
||||
static cvar_t *aiScatterWide = gi.Cvar_Get("g_aiScatterWide", "16.0", 0);
|
||||
static cvar_t *aiScatterHeight = gi.Cvar_Get("g_aiScatterHeight", "45.0", 0);
|
||||
static cvar_t *aiRanges[4];
|
||||
static qboolean doInit = qtrue;
|
||||
static qboolean doInit = true;
|
||||
float fAccuracy, fCoverFactor;
|
||||
Vector aimDir;
|
||||
|
||||
@@ -10566,7 +10562,7 @@ Vector Actor::GunTarget(bool bNoCollision, const vec3_t position, const vec3_t f
|
||||
dir.normalize();
|
||||
|
||||
if (g_target_game > target_game_e::TG_MOH) {
|
||||
if (DotProduct2D(forward, dir) < aiMaxDeviation->value) {
|
||||
if (DotProduct(forward, dir) < aiMaxDeviation->value) {
|
||||
Vector vOut;
|
||||
|
||||
VectorMA(position, 2048, forward, vOut);
|
||||
@@ -10614,7 +10610,7 @@ Vector Actor::GunTarget(bool bNoCollision, const vec3_t position, const vec3_t f
|
||||
vPos = player->centroid;
|
||||
|
||||
if (!G_SightTrace(
|
||||
GunPosition(), vec_zero, vec_zero, vPos, m_Enemy, this, MASK_CANSEE, qfalse, "Actor::GunTarget 1"
|
||||
GunPosition(), vec_zero, vec_zero, vPos, m_Enemy, this, MASK_CANSEE, false, "Actor::GunTarget 1"
|
||||
)) {
|
||||
fCoverFactor *= aifCoverFactor->value;
|
||||
vPos = m_Enemy->EyePosition();
|
||||
@@ -11148,9 +11144,9 @@ Actor::EventSound
|
||||
void Actor::EventSound(Event *ev)
|
||||
{
|
||||
if (g_gametype->integer == GT_SINGLE_PLAYER || m_Team == TEAM_AMERICAN) {
|
||||
ProcessSoundEvent(ev, qtrue);
|
||||
ProcessSoundEvent(ev, true);
|
||||
} else {
|
||||
ProcessSoundEvent(ev, qfalse);
|
||||
ProcessSoundEvent(ev, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11387,7 +11383,7 @@ void Actor::StrafeToAttack(float fDist, vec3_t vDir)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!G_SightTrace(origin, mins, maxs, vSpot, this, NULL, MASK_TARGETPATH, qtrue, "Actor::StrafeToAttack 1")) {
|
||||
if (!G_SightTrace(origin, mins, maxs, vSpot, this, NULL, MASK_TARGETPATH, true, "Actor::StrafeToAttack 1")) {
|
||||
ClearPath();
|
||||
return;
|
||||
}
|
||||
@@ -11403,7 +11399,7 @@ void Actor::StrafeToAttack(float fDist, vec3_t vDir)
|
||||
this,
|
||||
m_Enemy,
|
||||
MASK_CANSEE,
|
||||
qfalse,
|
||||
false,
|
||||
"Actor::StrafeToAttack 1"
|
||||
)) {
|
||||
ClearPath();
|
||||
@@ -11588,8 +11584,8 @@ void Actor::DontFaceWall(void)
|
||||
|
||||
VectorSub2D(m_vDfwPos, origin, vDelta);
|
||||
|
||||
if (Square(fErrorLerp * -14.0 + 16.0) > VectorLength2DSquared(vDelta) &&
|
||||
(fabs(AngleNormalize180(m_fDfwRequestedYaw - m_DesiredYaw)) <= fErrorLerp * -29.0 + 30.0
|
||||
if (Square(fErrorLerp * -14.0 + 16.0) > VectorLength2DSquared(vDelta)
|
||||
&& (fabs(AngleNormalize180(m_fDfwRequestedYaw - m_DesiredYaw)) <= fErrorLerp * -29.0 + 30.0
|
||||
|| fabs(AngleNormalize180(m_fDfwDerivedYaw - m_DesiredYaw)) <= fErrorLerp * -29.0 + 30.0)) {
|
||||
if (AvoidingFacingWall()) {
|
||||
SetDesiredYaw(m_fDfwDerivedYaw);
|
||||
@@ -11610,12 +11606,12 @@ void Actor::DontFaceWall(void)
|
||||
start.y -= origin.y;
|
||||
fEyeRadius = VectorLength2D(start);
|
||||
start.x = origin.x + fEyeRadius * fCosAngle;
|
||||
start.y = origin.x + fEyeRadius * fSinAngle;
|
||||
start.y = origin.y + fEyeRadius * fSinAngle;
|
||||
end.x = start.x + fCosAngle * 64;
|
||||
end.y = start.y + fSinAngle * 64;
|
||||
end.z = start.z;
|
||||
|
||||
trace = G_Trace(start, vec_zero, vec_zero, end, this, MASK_CANSEE, qfalse, "Actor::DontFaceWall");
|
||||
trace = G_Trace(start, vec_zero, vec_zero, end, this, MASK_CANSEE, false, "Actor::DontFaceWall");
|
||||
|
||||
if (trace.entityNum == ENTITYNUM_NONE || trace.fraction > 0.999f || trace.startsolid) {
|
||||
m_eDontFaceWallMode = 3;
|
||||
@@ -11623,7 +11619,7 @@ void Actor::DontFaceWall(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (trace.entityNum != ENTITYNUM_WORLD && trace.ent->entity->AIDontFace()) {
|
||||
if (trace.entityNum != ENTITYNUM_WORLD && !trace.ent->entity->AIDontFace()) {
|
||||
m_eDontFaceWallMode = 4;
|
||||
m_fDfwDerivedYaw = m_fDfwRequestedYaw;
|
||||
return;
|
||||
@@ -11916,8 +11912,10 @@ void Actor::EventCalcGrenadeToss2(Event *ev)
|
||||
}
|
||||
|
||||
if (fDistSquared < Square(1024)) {
|
||||
// See if it can roll
|
||||
vPoint = GrenadeThrowPoint(vFrom, vDelta, STRING_ANIM_GRENADETOSS_SCR);
|
||||
vVel = CanRollGrenade(vPoint, vTargetPos);
|
||||
|
||||
if (vVel != vPointTarget) {
|
||||
m_vGrenadeVel = vVel;
|
||||
m_eGrenadeMode = AI_GREN_TOSS_ROLL;
|
||||
@@ -11930,6 +11928,7 @@ void Actor::EventCalcGrenadeToss2(Event *ev)
|
||||
if (!speed) {
|
||||
vPoint = GrenadeThrowPoint(vFrom, vDelta, STRING_ANIM_GRENADETHROW_SCR);
|
||||
vVel = CanThrowGrenade(vPoint, vTargetPos);
|
||||
|
||||
if (vVel != vec_zero) {
|
||||
m_vGrenadeVel = vVel;
|
||||
m_eGrenadeMode = AI_GREN_TOSS_THROW;
|
||||
@@ -11946,7 +11945,9 @@ void Actor::EventCalcGrenadeToss2(Event *ev)
|
||||
vVel = vTargetPos - vPoint;
|
||||
vVel.normalize();
|
||||
vVel *= speed;
|
||||
m_vGrenadeVel = vVel;
|
||||
|
||||
m_vGrenadeVel = vVel;
|
||||
m_eGrenadeMode = AI_GREN_TOSS_THROW;
|
||||
|
||||
ev->AddConstString(STRING_ANIM_GRENADETOSS_SCR);
|
||||
SetDesiredYawDir(m_vGrenadeVel);
|
||||
@@ -12121,9 +12122,7 @@ void Actor::SetPathToNotBlockSentient(Sentient *pOther)
|
||||
|
||||
vDest = origin + vPerp * 48;
|
||||
|
||||
if (G_SightTrace(
|
||||
vDest, mins, maxs, vDest, this, pOther, MASK_SOLID, qfalse, "Actor::SetPathToNotBlockSentient 1"
|
||||
)) {
|
||||
if (G_SightTrace(vDest, mins, maxs, vDest, this, pOther, MASK_SOLID, false, "Actor::SetPathToNotBlockSentient 1")) {
|
||||
SetPathWithinDistance(vDest, NULL, 96, 0);
|
||||
}
|
||||
|
||||
@@ -12133,9 +12132,7 @@ void Actor::SetPathToNotBlockSentient(Sentient *pOther)
|
||||
|
||||
vDest = origin - vPerp * 48;
|
||||
|
||||
if (G_SightTrace(
|
||||
vDest, mins, maxs, vDest, this, pOther, MASK_SOLID, qfalse, "Actor::SetPathToNotBlockSentient 2"
|
||||
)) {
|
||||
if (G_SightTrace(vDest, mins, maxs, vDest, this, pOther, MASK_SOLID, false, "Actor::SetPathToNotBlockSentient 2")) {
|
||||
SetPathWithinDistance(vDest, NULL, 96, 0);
|
||||
}
|
||||
|
||||
@@ -12172,7 +12169,7 @@ void Actor::LookAround(float fFovAdd)
|
||||
|
||||
VectorMA(vEyePos, 1024, vDest, vDest);
|
||||
|
||||
trace = G_Trace(EyePosition(), vec_zero, vec_zero, vDest, this, MASK_LOOK, qfalse, "Actor::LookAround");
|
||||
trace = G_Trace(EyePosition(), vec_zero, vec_zero, vDest, this, MASK_LOOK, false, "Actor::LookAround");
|
||||
if (trace.fraction > 0.125) {
|
||||
m_bHasDesiredLookDest = true;
|
||||
VectorCopy(trace.endpos, m_vDesiredLookDest);
|
||||
@@ -12282,8 +12279,9 @@ const char *Actor::DumpCallTrace(const char *pszFmt, ...) const
|
||||
vPlayer = p->origin;
|
||||
}
|
||||
|
||||
i1 = sprintf(
|
||||
i1 = Com_sprintf(
|
||||
szTemp,
|
||||
sizeof(szTemp),
|
||||
"map = %s\n"
|
||||
"time = %i (%i:%02i)\n"
|
||||
"entnum = %i, targetname = '%s'\n"
|
||||
@@ -12318,7 +12316,7 @@ const char *Actor::DumpCallTrace(const char *pszFmt, ...) const
|
||||
if (pszFmt) {
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
i2 = i1 + vsprintf(&szTemp[i1], pszFmt, args);
|
||||
i2 = i1 + Q_vsnprintf(szTemp + i1, sizeof(szTemp) - i1, pszFmt, args);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
@@ -12329,8 +12327,9 @@ const char *Actor::DumpCallTrace(const char *pszFmt, ...) const
|
||||
|
||||
t = time(0);
|
||||
ptm = localtime(&t);
|
||||
sprintf(
|
||||
Com_sprintf(
|
||||
szFile,
|
||||
sizeof(szFile),
|
||||
"main\\ai_trace_%s_%i_%i_%02i%02i.log",
|
||||
sv_mapname->string,
|
||||
ptm->tm_mon + 1,
|
||||
|
||||
@@ -120,7 +120,7 @@ void Actor::Think_DisguiseOfficer(void)
|
||||
{
|
||||
Com_Printf("Actor::Think_DisguiseOfficer: invalid think state %i\n", m_State);
|
||||
char assertStr[16317] = {0};
|
||||
strcpy(assertStr, "\"invalid think state\"\n\tMessage: ");
|
||||
Q_strncpyz(assertStr, "\"invalid think state\"\n\tMessage: ", sizeof(assertStr));
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("thinkstate = %i", m_State));
|
||||
assert(!assertStr);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ void Actor::Think_DisguiseRover(void)
|
||||
{
|
||||
Com_Printf("Actor::Think_DisguiseOfficer: invalid think state %i\n", m_State);
|
||||
char assertStr[16317] = {0};
|
||||
strcpy(assertStr, "\"invalid think state\"\n\tMessage: ");
|
||||
Q_strncpyz(assertStr, "\"invalid think state\"\n\tMessage: ", sizeof(assertStr));
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("thinkstate = %i", m_State));
|
||||
assert(!assertStr);
|
||||
}
|
||||
|
||||
@@ -474,7 +474,7 @@ void Actor::FinishedAnimation_Grenade(void)
|
||||
break;
|
||||
default:
|
||||
char assertStr[16317] = {0};
|
||||
strcpy(assertStr, "\"invalid grenade state in FinishedAnimation()\"\n\tMessage: ");
|
||||
Q_strncpyz(assertStr, "\"invalid grenade state in FinishedAnimation()\"\n\tMessage: ", sizeof(assertStr));
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("state = %i", m_eGrenadeState));
|
||||
assert(!assertStr);
|
||||
break;
|
||||
|
||||
@@ -145,31 +145,31 @@ void Actor::ThinkHoldGun_TurretGun(void)
|
||||
if (m_State == ACTOR_STATE_MACHINE_GUNNER_RELOADING) {
|
||||
m_fCrouchWeight = 0;
|
||||
|
||||
temp = (origin[2] + 71.6f - m_pTurret->origin[2]) / 39.f;
|
||||
temp = (origin[2] + 71.6f - m_pTurret->origin[2]) / 39.0f;
|
||||
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;
|
||||
if (m_fCrouchWeight < -1.0f) {
|
||||
m_fCrouchWeight = -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
VectorScale2D(orientation[0], -(m_fCrouchWeight * -9.3f + 23.4f), offset);
|
||||
VectorScale2D(orientation[0], -(23.4 - m_fCrouchWeight * 9.3), offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
VectorScale2D(orientation[1], m_fCrouchWeight * 2.6f + 10.3f, offset);
|
||||
VectorScale2D(orientation[1], 10.3 + m_fCrouchWeight * 2.6, offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
} else {
|
||||
m_fCrouchWeight = machine_gunner_hands_up_stand / (heightDiff - 38.7f);
|
||||
m_fCrouchWeight = machine_gunner_hands_up_stand / (heightDiff - 38.7);
|
||||
if (m_fCrouchWeight > 1.0) {
|
||||
m_fCrouchWeight = 1.0;
|
||||
}
|
||||
|
||||
VectorScale2D(orientation[0], -(m_fCrouchWeight * -3.f + 23.4f), offset);
|
||||
VectorScale2D(orientation[0], -(23.4 - m_fCrouchWeight * 3.0), offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
VectorScale2D(orientation[1], m_fCrouchWeight * -1.6f + 10.3f, offset);
|
||||
VectorScale2D(orientation[1], 10.3 - m_fCrouchWeight * 1.6, offset);
|
||||
VectorAdd2D(newOrigin, offset, newOrigin);
|
||||
}
|
||||
|
||||
@@ -182,11 +182,11 @@ void Actor::ThinkHoldGun_TurretGun(void)
|
||||
UpdateAimMotion();
|
||||
UpdateAnim();
|
||||
|
||||
newOrigin[2] += 18;
|
||||
newOrigin[2] = origin[2] + 18.0;
|
||||
|
||||
end[0] = newOrigin[0];
|
||||
end[1] = newOrigin[1];
|
||||
end[2] = newOrigin[2] - 94;
|
||||
end[2] = origin[2] - 94.0;
|
||||
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) {
|
||||
|
||||
@@ -121,7 +121,7 @@ void Actor::Think_Weaponless(void)
|
||||
} else {
|
||||
Com_Printf("Think_Weaponless: invalid think state %i\n", m_State);
|
||||
char assertStr[16317] = {0};
|
||||
strcpy(assertStr, "\"invalid think state\"\n\tMessage: ");
|
||||
Q_strncpyz(assertStr, "\"invalid think state\"\n\tMessage: ", sizeof(assertStr));
|
||||
Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("thinkstate = %i", m_State));
|
||||
assert(!assertStr);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -142,7 +142,8 @@ int ActorEnemy::UpdateThreat(Actor *pSelf)
|
||||
Square(305),
|
||||
Square(254),
|
||||
Square(200),
|
||||
Square(137)};
|
||||
Square(137)
|
||||
};
|
||||
static int iWeaponThreat[7][5] = {
|
||||
{5, 3, 1, 1, 1},
|
||||
{8, 6, 4, 2, 1},
|
||||
@@ -165,7 +166,7 @@ int ActorEnemy::UpdateThreat(Actor *pSelf)
|
||||
}
|
||||
|
||||
m_iThreat = 10000;
|
||||
if (m_bVisible == true) {
|
||||
if (m_bVisible) {
|
||||
m_iThreat = 10500;
|
||||
}
|
||||
|
||||
@@ -321,7 +322,7 @@ void ActorEnemySet::FlagBadEnemy(Sentient *pEnemy)
|
||||
|
||||
// Added in 2.0.
|
||||
// Set the reaction time
|
||||
pActorEnemy->m_iNextEnemyTime = level.inttime + 5000;
|
||||
pActorEnemy->m_iNextEnemyTime = level.inttime + 5000;
|
||||
|
||||
pActorEnemy->m_fLastLookTime = level.time;
|
||||
pActorEnemy->m_fVisibility = 0.0;
|
||||
|
||||
+16
-18
@@ -105,8 +105,8 @@ public:
|
||||
|
||||
inline void ActorPath::Archive(Archiver& arc)
|
||||
{
|
||||
int pos;
|
||||
int startpathpos;
|
||||
int index;
|
||||
int i;
|
||||
|
||||
arc.ArchiveInteger(&m_pathlen);
|
||||
|
||||
@@ -115,42 +115,40 @@ inline void ActorPath::Archive(Archiver& arc)
|
||||
m_path = new PathInfo[m_pathlen];
|
||||
}
|
||||
|
||||
if (m_pathlen > 0) {
|
||||
for (int i = 0; i < m_pathlen; i++) {
|
||||
m_path->Archive(arc);
|
||||
}
|
||||
for (i = 0; i < m_pathlen; i++) {
|
||||
m_path[i].Archive(arc);
|
||||
}
|
||||
|
||||
if (!arc.Saving()) {
|
||||
arc.ArchiveInteger(&pos);
|
||||
if (pos == -1) {
|
||||
arc.ArchiveInteger(&index);
|
||||
if (index == -1) {
|
||||
m_pathpos = NULL;
|
||||
} else {
|
||||
m_pathpos = &m_path[pos];
|
||||
m_pathpos = &m_path[index];
|
||||
}
|
||||
|
||||
arc.ArchiveInteger(&startpathpos);
|
||||
if (startpathpos == -1) {
|
||||
arc.ArchiveInteger(&index);
|
||||
if (index == -1) {
|
||||
m_startpathpos = NULL;
|
||||
} else {
|
||||
m_startpathpos = &m_path[pos];
|
||||
m_startpathpos = &m_path[index];
|
||||
}
|
||||
} else {
|
||||
if (m_pathpos) {
|
||||
pos = m_pathpos - m_path;
|
||||
index = m_pathpos - m_path;
|
||||
} else {
|
||||
pos = -1;
|
||||
index = -1;
|
||||
}
|
||||
|
||||
arc.ArchiveInteger(&pos);
|
||||
arc.ArchiveInteger(&index);
|
||||
|
||||
if (m_startpathpos) {
|
||||
pos = m_startpathpos - m_path;
|
||||
index = m_startpathpos - m_path;
|
||||
} else {
|
||||
pos = -1;
|
||||
index = -1;
|
||||
}
|
||||
|
||||
arc.ArchiveInteger(&pos);
|
||||
arc.ArchiveInteger(&index);
|
||||
}
|
||||
} else if (arc.Loading()) {
|
||||
m_pathpos = 0;
|
||||
|
||||
@@ -315,8 +315,8 @@ void Animate::NewAnim(int animnum, int slot, float weight)
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
int eventNum;
|
||||
|
||||
strcpy(cmdName, "_client_");
|
||||
strcpy(cmdName + 8, single_cmd.args[0]);
|
||||
Q_strncpyz(cmdName, "_client_", longest + 8 + 1);
|
||||
Q_strncpyz(cmdName + 8, single_cmd.args[0], longest + 1);
|
||||
|
||||
eventNum = Event::FindEventNum(cmdName);
|
||||
|
||||
@@ -386,8 +386,8 @@ void Animate::NewAnim(int animnum, int slot, float weight)
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
int eventNum;
|
||||
|
||||
strcpy(cmdName, "_client_");
|
||||
strcpy(cmdName + 8, single_cmd.args[0]);
|
||||
Q_strncpyz(cmdName, "_client_", longestAllFrames + 8 + 1);
|
||||
Q_strncpyz(cmdName + 8, single_cmd.args[0], longestAllFrames + 1);
|
||||
|
||||
eventNum = Event::FindEventNum(cmdName);
|
||||
|
||||
@@ -554,8 +554,8 @@ void Animate::DoExitCommands(int slot)
|
||||
const tiki_singlecmd_t& single_cmd = cmds.cmds[ii];
|
||||
int eventNum;
|
||||
|
||||
strcpy(cmdName, "_client_");
|
||||
strcpy(cmdName + 8, single_cmd.args[0]);
|
||||
Q_strncpyz(cmdName, "_client_", longest + 8 + 1);
|
||||
Q_strncpyz(cmdName + 8, single_cmd.args[0], longest + 1);
|
||||
|
||||
eventNum = Event::FindEventNum(cmdName);
|
||||
|
||||
@@ -596,7 +596,7 @@ int Animate::NumAnims(void)
|
||||
|
||||
const char *Animate::AnimName(int slot)
|
||||
{
|
||||
return gi.Anim_NameForNum(edict->tiki, edict->s.frameInfo[slot].index);
|
||||
return gi.Anim_NameForNum(edict->tiki, CurrentAnim(slot));
|
||||
}
|
||||
|
||||
void Animate::AnimFinished(int slot)
|
||||
|
||||
+9
-10
@@ -109,6 +109,11 @@ const char *ArchiveFile::Filename(void)
|
||||
|
||||
qboolean ArchiveFile::Compress()
|
||||
{
|
||||
#ifdef Q3_BIG_ENDIAN
|
||||
// FIXME: Decompressing crashes on big-endian architectures
|
||||
return false;
|
||||
#endif
|
||||
|
||||
byte *tempbuf;
|
||||
size_t out_len;
|
||||
size_t tempbuf_len;
|
||||
@@ -310,7 +315,7 @@ void Archiver::FileError(const char *fmt, ...)
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(text, fmt, argptr);
|
||||
Q_vsnprintf(text, sizeof(text), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
fileerror = true;
|
||||
@@ -517,7 +522,6 @@ void ArchiveSwapValue<Quat>(Quat* value) {
|
||||
#define ARCHIVE(func, type) \
|
||||
void Archiver::Archive##func(type *v) \
|
||||
{ \
|
||||
int i; \
|
||||
if (archivemode == ARCHIVE_WRITE) { \
|
||||
type nv = *v; \
|
||||
ArchiveSwapValue(&nv); \
|
||||
@@ -559,7 +563,6 @@ void Archiver::ArchiveSvsTime(int *time)
|
||||
|
||||
void Archiver::ArchiveVec2(vec2_t vec)
|
||||
{
|
||||
int i;
|
||||
if (archivemode == ARCHIVE_WRITE) {
|
||||
vec2_t nv = { vec[0], vec[1] };
|
||||
ArchiveSwapValue(nv, 2);
|
||||
@@ -572,7 +575,6 @@ void Archiver::ArchiveVec2(vec2_t vec)
|
||||
|
||||
void Archiver::ArchiveVec3(vec3_t vec)
|
||||
{
|
||||
int i;
|
||||
if (archivemode == ARCHIVE_WRITE) {
|
||||
vec3_t nv = { vec[0], vec[1], vec[2]};
|
||||
ArchiveSwapValue(nv, 3);
|
||||
@@ -585,7 +587,6 @@ void Archiver::ArchiveVec3(vec3_t vec)
|
||||
|
||||
void Archiver::ArchiveVec4(vec4_t vec)
|
||||
{
|
||||
int i;
|
||||
if (archivemode == ARCHIVE_WRITE) {
|
||||
vec4_t nv = { vec[0], vec[1], vec[2], vec[3] };
|
||||
ArchiveSwapValue(nv, 4);
|
||||
@@ -784,8 +785,6 @@ void Archiver::ArchiveString(str *string)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fileSize_t s;
|
||||
|
||||
#ifndef NDEBUG
|
||||
CheckWrite();
|
||||
#endif
|
||||
@@ -1124,7 +1123,8 @@ int Archiver::ReadType(void)
|
||||
|
||||
void Archiver::WriteType(int type)
|
||||
{
|
||||
archivefile.Write(&type, sizeof(type));
|
||||
int nt = LittleLong(type);
|
||||
archivefile.Write(&nt, sizeof(nt));
|
||||
}
|
||||
|
||||
void Archiver::CheckType(int type)
|
||||
@@ -1147,8 +1147,7 @@ void Archiver::CheckType(int type)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int nt = LittleLong(type);
|
||||
archivefile.Write(&nt, sizeof(nt));
|
||||
WriteType(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,8 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
// archive.h: OpenMoHAA Archiver
|
||||
|
||||
#ifndef __ARCHIVE_H__
|
||||
#define __ARCHIVE_H__
|
||||
#pragma once
|
||||
|
||||
#include "g_local.h"
|
||||
#include "class.h"
|
||||
@@ -343,5 +342,3 @@ void con_map<key, value>::Archive(Archiver& arc)
|
||||
arc.ArchiveInteger(&tempInt); \
|
||||
(thing) = (type)tempInt; \
|
||||
}
|
||||
|
||||
#endif // __ARCHIVE_H__
|
||||
+2
-5
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,8 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
// armor.h: Standard armor that prevents a percentage of damage per hit.
|
||||
|
||||
#ifndef __ARMOR_H__
|
||||
#define __ARMOR_H__
|
||||
#pragma once
|
||||
|
||||
#include "weapon.h"
|
||||
|
||||
@@ -40,5 +39,3 @@ class Armor : public Item
|
||||
|
||||
qboolean Pickupable( Entity *other ) override;
|
||||
};
|
||||
|
||||
#endif /* armor.h */
|
||||
+325
-443
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -30,7 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
/*****************************************************************************
|
||||
/*QUAKED func_barrel (0 0.25 0.5) ? INDESTRUCTABLE
|
||||
Brush model barrel object
|
||||
Bashing only makes thunk or gong sounds (depending on wether it's full or not)
|
||||
Bashing only makes thunk or gong sounds (depending on whether it's full or not)
|
||||
Bullets and explosions effects are dependant apon the type of barrel.
|
||||
"barreltype" sets the type of barrel that it is. Valid settings are:
|
||||
- "water" makes the barrel be filled with water.
|
||||
@@ -45,562 +45,444 @@ Does nothing special at all. It's just a poor empty barrel. aww :(
|
||||
******************************************************************************/
|
||||
|
||||
Event EV_Barrel_Think
|
||||
(
|
||||
(
|
||||
"_barrel_think",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"think function for a barrel."
|
||||
);
|
||||
);
|
||||
|
||||
Event EV_Barrel_Setup
|
||||
(
|
||||
(
|
||||
"_barrel_setup",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Does the post spawn setup of the barrel"
|
||||
);
|
||||
);
|
||||
|
||||
Event EV_Barrel_SetType
|
||||
(
|
||||
(
|
||||
"barreltype",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"type",
|
||||
"Sets the barrel's type"
|
||||
);
|
||||
);
|
||||
|
||||
CLASS_DECLARATION( Entity, BarrelObject, "func_barrel" )
|
||||
{
|
||||
{ &EV_Barrel_Setup, &BarrelObject::BarrelSetup },
|
||||
{ &EV_Barrel_Think, &BarrelObject::BarrelThink },
|
||||
{ &EV_Barrel_SetType, &BarrelObject::BarrelSetType },
|
||||
{ &EV_Damage, &BarrelObject::BarrelDamaged },
|
||||
{ &EV_Killed, &BarrelObject::BarrelKilled },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(Entity, BarrelObject, "func_barrel") {
|
||||
{&EV_Barrel_Setup, &BarrelObject::BarrelSetup },
|
||||
{&EV_Barrel_Think, &BarrelObject::BarrelThink },
|
||||
{&EV_Barrel_SetType, &BarrelObject::BarrelSetType},
|
||||
{&EV_Damage, &BarrelObject::BarrelDamaged},
|
||||
{&EV_Killed, &BarrelObject::BarrelKilled },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
BarrelObject::BarrelObject()
|
||||
{
|
||||
AddWaitTill(STRING_DEATH);
|
||||
|
||||
AddWaitTill(STRING_DEATH);
|
||||
if (LoadingSavegame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (LoadingSavegame)
|
||||
{
|
||||
return;
|
||||
}
|
||||
edict->s.eType = ET_GENERAL;
|
||||
|
||||
edict->s.eType = ET_GENERAL;
|
||||
m_iBarrelType = 0;
|
||||
m_fFluidAmount = 0;
|
||||
m_fHeightFluid = 0;
|
||||
|
||||
m_iBarrelType = 0;
|
||||
m_fFluidAmount = 0;
|
||||
m_fHeightFluid = 0;
|
||||
for (int i = 0; i < MAX_BARREL_LEAKS; i++) {
|
||||
m_bLeaksActive[i] = 0;
|
||||
}
|
||||
|
||||
for( int i = 0; i < MAX_BARREL_LEAKS; i++ )
|
||||
{
|
||||
m_bLeaksActive[ i ] = 0;
|
||||
}
|
||||
m_fDamageSoundTime = 0;
|
||||
mass = 500;
|
||||
max_health = 75;
|
||||
health = 75;
|
||||
deadflag = DEAD_NO;
|
||||
takedamage = DAMAGE_YES;
|
||||
m_vJitterAngles = vec_zero;
|
||||
|
||||
m_fDamageSoundTime = 0;
|
||||
mass = 500;
|
||||
max_health = 75;
|
||||
health = 75;
|
||||
deadflag = DEAD_NO;
|
||||
takedamage = DAMAGE_YES;
|
||||
m_vJitterAngles = vec_zero;
|
||||
|
||||
PostEvent( EV_Barrel_Setup, EV_POSTSPAWN );
|
||||
PostEvent(EV_Barrel_Setup, EV_POSTSPAWN);
|
||||
}
|
||||
|
||||
int BarrelObject::PickBarrelLeak
|
||||
(
|
||||
void
|
||||
)
|
||||
int BarrelObject::PickBarrelLeak(void)
|
||||
{
|
||||
int iHighest;
|
||||
float fHighestHeight;
|
||||
int iHighest;
|
||||
float fHighestHeight;
|
||||
|
||||
for( int i = 0; i < MAX_BARREL_LEAKS; i++ )
|
||||
{
|
||||
if( !m_bLeaksActive[ i ] ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < MAX_BARREL_LEAKS; i++) {
|
||||
if (!m_bLeaksActive[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
fHighestHeight = m_vLeaks[ 0 ][ 2 ];
|
||||
iHighest = 0;
|
||||
fHighestHeight = m_vLeaks[0][2];
|
||||
iHighest = 0;
|
||||
|
||||
for( int i = 1; i < MAX_BARREL_LEAKS; i++ )
|
||||
{
|
||||
if( m_vLeaks[ 0 ][ 2 ] > fHighestHeight )
|
||||
{
|
||||
fHighestHeight = m_vLeaks[ 0 ][ 2 ];
|
||||
iHighest = i;
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < MAX_BARREL_LEAKS; i++) {
|
||||
if (m_vLeaks[0][2] > fHighestHeight) {
|
||||
fHighestHeight = m_vLeaks[0][2];
|
||||
iHighest = i;
|
||||
}
|
||||
}
|
||||
|
||||
return iHighest;
|
||||
return iHighest;
|
||||
}
|
||||
|
||||
void BarrelObject::BarrelSetup
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void BarrelObject::BarrelSetup(Event *ev)
|
||||
{
|
||||
setMoveType( MOVETYPE_PUSH );
|
||||
setSolidType( SOLID_BSP );
|
||||
setMoveType(MOVETYPE_PUSH);
|
||||
setSolidType(SOLID_BSP);
|
||||
|
||||
m_vStartAngles = angles;
|
||||
m_fJitterScale = 64.0f / size[ 2 ];
|
||||
m_vStartAngles = angles;
|
||||
m_fJitterScale = 64.0f / size[2];
|
||||
|
||||
m_fFluidAmount = size[ 0 ] * size[ 1 ] * size[ 2 ] / 150.0f;
|
||||
m_fHeightFluid = m_fFluidAmount / size[ 2 ];
|
||||
m_fFluidAmount = size[0] * size[1] * size[2] / 150.0f;
|
||||
m_fHeightFluid = m_fFluidAmount / size[2];
|
||||
|
||||
// Position the barrel correctly
|
||||
CheckGround();
|
||||
// Position the barrel correctly
|
||||
CheckGround();
|
||||
}
|
||||
|
||||
void BarrelObject::BarrelSetType
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void BarrelObject::BarrelSetType(Event *ev)
|
||||
{
|
||||
str sType = ev->GetString( 1 );
|
||||
str sType = ev->GetString(1);
|
||||
|
||||
if( !sType.icmp( "oil" ) )
|
||||
{
|
||||
health = 75;
|
||||
m_iBarrelType = BARREL_OIL;
|
||||
if (!sType.icmp("oil")) {
|
||||
health = 75;
|
||||
m_iBarrelType = BARREL_OIL;
|
||||
|
||||
CacheResource( "models/fx/barrel_empty_destroyed.tik" );
|
||||
CacheResource( "models/fx/barrel_oil_destroyed.tik" );
|
||||
}
|
||||
else if( !sType.icmp( "water" ) )
|
||||
{
|
||||
health = 75;
|
||||
m_iBarrelType = BARREL_WATER;
|
||||
CacheResource("models/fx/barrel_empty_destroyed.tik");
|
||||
CacheResource("models/fx/barrel_oil_destroyed.tik");
|
||||
} else if (!sType.icmp("water")) {
|
||||
health = 75;
|
||||
m_iBarrelType = BARREL_WATER;
|
||||
|
||||
CacheResource( "models/fx/barrel_empty_destroyed.tik" );
|
||||
CacheResource( "models/fx/barrel_water_destroyed.tik" );
|
||||
}
|
||||
else if( !sType.icmp( "gas" ) )
|
||||
{
|
||||
spawnflags &= ~BARREL_INDESTRUCTABLE;
|
||||
health = 75;
|
||||
m_iBarrelType = BARREL_GAS;
|
||||
CacheResource("models/fx/barrel_empty_destroyed.tik");
|
||||
CacheResource("models/fx/barrel_water_destroyed.tik");
|
||||
} else if (!sType.icmp("gas")) {
|
||||
spawnflags &= ~BARREL_INDESTRUCTABLE;
|
||||
health = 75;
|
||||
m_iBarrelType = BARREL_GAS;
|
||||
|
||||
CacheResource( "models/fx/barrel_gas_destroyed.tik" );
|
||||
}
|
||||
else
|
||||
{
|
||||
health = 75;
|
||||
m_iBarrelType = BARREL_EMPTY;
|
||||
CacheResource("models/fx/barrel_gas_destroyed.tik");
|
||||
} else {
|
||||
health = 75;
|
||||
m_iBarrelType = BARREL_EMPTY;
|
||||
|
||||
CacheResource( "models/fx/barrel_empty_destroyed.tik" );
|
||||
}
|
||||
CacheResource("models/fx/barrel_empty_destroyed.tik");
|
||||
}
|
||||
|
||||
max_health = health;
|
||||
max_health = health;
|
||||
}
|
||||
|
||||
void BarrelObject::BarrelThink
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void BarrelObject::BarrelThink(Event *ev)
|
||||
{
|
||||
int i;
|
||||
int iBiggestLeak;
|
||||
float fFluidTop;
|
||||
int i;
|
||||
int iBiggestLeak;
|
||||
float fFluidTop;
|
||||
|
||||
iBiggestLeak = 0;
|
||||
iBiggestLeak = 0;
|
||||
|
||||
fFluidTop = m_fFluidAmount / m_fHeightFluid + ( mins[ 2 ] + origin[ 2 ] );
|
||||
for( i = 0; i < MAX_BARREL_LEAKS; i++ )
|
||||
{
|
||||
if( !m_bLeaksActive[ i ] ) {
|
||||
continue;
|
||||
}
|
||||
fFluidTop = m_fFluidAmount / m_fHeightFluid + (mins[2] + origin[2]);
|
||||
for (i = 0; i < MAX_BARREL_LEAKS; i++) {
|
||||
if (!m_bLeaksActive[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Send infos to clients
|
||||
if( m_vLeaks[ i ][ 2 ] <= fFluidTop )
|
||||
{
|
||||
gi.SetBroadcastVisible( m_vLeaks[ i ], m_vLeaks[ i ] );
|
||||
// Send infos to clients
|
||||
if (m_vLeaks[i][2] > fFluidTop) {
|
||||
gi.SetBroadcastVisible(m_vLeaks[i], m_vLeaks[i]);
|
||||
|
||||
if( m_vLeaks[ i ][ 2 ] <= fFluidTop - 1.3f )
|
||||
{
|
||||
if( m_vLeaks[ i ][ 2 ] <= fFluidTop - 3.0f )
|
||||
{
|
||||
// big leak
|
||||
if (m_iBarrelType == BARREL_OIL) {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_3));
|
||||
} else {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_7));
|
||||
}
|
||||
|
||||
if( m_iBarrelType == BARREL_OIL )
|
||||
{
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_1));
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_5));
|
||||
}
|
||||
gi.MSG_WriteCoord(m_vLeaks[i][0]);
|
||||
gi.MSG_WriteCoord(m_vLeaks[i][1]);
|
||||
gi.MSG_WriteCoord(m_vLeaks[i][2]);
|
||||
gi.MSG_WriteDir(m_vLeakNorms[i]);
|
||||
gi.MSG_EndCGM();
|
||||
|
||||
m_fFluidAmount -= 1.0f;
|
||||
iBiggestLeak |= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// medium leak
|
||||
m_bLeaksActive[i] = qfalse;
|
||||
} else {
|
||||
gi.SetBroadcastVisible(m_vLeaks[i], m_vLeaks[i]);
|
||||
|
||||
if( m_iBarrelType == BARREL_OIL )
|
||||
{
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_2));
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_6));
|
||||
}
|
||||
if (m_vLeaks[i][2] > fFluidTop - 1.3f) {
|
||||
// small leak
|
||||
|
||||
m_fFluidAmount -= 0.75f;
|
||||
iBiggestLeak |= 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// small leak
|
||||
if (m_iBarrelType == BARREL_OIL) {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_3));
|
||||
} else {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_7));
|
||||
}
|
||||
|
||||
if( m_iBarrelType == BARREL_OIL )
|
||||
{
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_3));
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_7));
|
||||
}
|
||||
m_fFluidAmount -= 0.5f;
|
||||
iBiggestLeak |= 1;
|
||||
} else if (m_vLeaks[i][2] > fFluidTop - 3.0f) {
|
||||
// medium leak
|
||||
|
||||
m_fFluidAmount -= 0.5f;
|
||||
iBiggestLeak |= 1;
|
||||
}
|
||||
if (m_iBarrelType == BARREL_OIL) {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_2));
|
||||
} else {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_6));
|
||||
}
|
||||
|
||||
gi.MSG_WriteCoord( m_vLeaks[ i ][ 0 ] );
|
||||
gi.MSG_WriteCoord( m_vLeaks[ i ][ 1 ] );
|
||||
gi.MSG_WriteCoord( m_vLeaks[ i ][ 2 ] );
|
||||
gi.MSG_WriteDir( m_vLeakNorms[ i ] );
|
||||
gi.MSG_EndCGM();
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.SetBroadcastVisible( m_vLeaks[ i ], m_vLeaks[ i ] );
|
||||
m_fFluidAmount -= 0.75f;
|
||||
iBiggestLeak |= 2;
|
||||
} else {
|
||||
// big leak
|
||||
|
||||
if( m_iBarrelType == BARREL_OIL )
|
||||
{
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_3));
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_7));
|
||||
}
|
||||
if (m_iBarrelType == BARREL_OIL) {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_1));
|
||||
} else {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_5));
|
||||
}
|
||||
|
||||
gi.MSG_WriteCoord( m_vLeaks[ i ][ 0 ] );
|
||||
gi.MSG_WriteCoord( m_vLeaks[ i ][ 1 ] );
|
||||
gi.MSG_WriteCoord( m_vLeaks[ i ][ 2 ] );
|
||||
gi.MSG_WriteDir( m_vLeakNorms[ i ] );
|
||||
gi.MSG_EndCGM();
|
||||
m_fFluidAmount -= 1.0f;
|
||||
iBiggestLeak |= 4;
|
||||
}
|
||||
|
||||
m_bLeaksActive[ i ] = qfalse;
|
||||
}
|
||||
}
|
||||
gi.MSG_WriteCoord(m_vLeaks[i][0]);
|
||||
gi.MSG_WriteCoord(m_vLeaks[i][1]);
|
||||
gi.MSG_WriteCoord(m_vLeaks[i][2]);
|
||||
gi.MSG_WriteDir(m_vLeakNorms[i]);
|
||||
gi.MSG_EndCGM();
|
||||
}
|
||||
}
|
||||
|
||||
if( m_vJitterAngles[ 0 ] == 0.0f && m_vJitterAngles[ 2 ] == 0.0f )
|
||||
{
|
||||
if( !VectorCompare( angles, m_vStartAngles ) )
|
||||
{
|
||||
setAngles( m_vStartAngles );
|
||||
}
|
||||
}
|
||||
if (m_vJitterAngles[0] == 0.0f && m_vJitterAngles[2] == 0.0f) {
|
||||
if (!VectorCompare(angles, m_vStartAngles)) {
|
||||
setAngles(m_vStartAngles);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Vector ang;
|
||||
|
||||
setAngles( Vector( m_vStartAngles[ 0 ] + m_vJitterAngles[ 0 ], m_vStartAngles[ 1 ], m_vStartAngles[ 2 ] + m_vJitterAngles[ 2 ] ) );
|
||||
ang = m_vStartAngles;
|
||||
ang[0] += m_vJitterAngles[0];
|
||||
ang[2] += m_vJitterAngles[2];
|
||||
setAngles(ang);
|
||||
|
||||
if( m_vJitterAngles[ 0 ] > 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] -= 1.f / 3.f * m_fJitterScale;
|
||||
if (m_vJitterAngles[0] < 0) {
|
||||
m_vJitterAngles[0] += 1.f / 3.f * m_fJitterScale;
|
||||
|
||||
if( m_vJitterAngles[ 0 ] > 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] = 0.0f;
|
||||
}
|
||||
}
|
||||
else if( m_vJitterAngles[ 0 ] < 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] += 1.f / 3.f * m_fJitterScale;
|
||||
if (m_vJitterAngles[0] > 0) {
|
||||
m_vJitterAngles[0] = 0;
|
||||
}
|
||||
} else if (m_vJitterAngles[0] > 0) {
|
||||
m_vJitterAngles[0] -= 1.f / 3.f * m_fJitterScale;
|
||||
|
||||
if( m_vJitterAngles[ 0 ] < 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] = 0.0f;
|
||||
}
|
||||
}
|
||||
if (m_vJitterAngles[0] < 0) {
|
||||
m_vJitterAngles[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_vJitterAngles[ 0 ] = -m_vJitterAngles[ 0 ];
|
||||
m_vJitterAngles[0] = -m_vJitterAngles[0];
|
||||
|
||||
if( m_vJitterAngles[ 2 ] > 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] -= 1.f / 3.f * m_fJitterScale;
|
||||
if (m_vJitterAngles[2] < 0) {
|
||||
m_vJitterAngles[2] += 1.f / 3.f * m_fJitterScale;
|
||||
|
||||
if( m_vJitterAngles[ 2 ] > 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] = 0.0f;
|
||||
}
|
||||
}
|
||||
else if( m_vJitterAngles[ 2 ] < 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] += 1.f / 3.f * m_fJitterScale;
|
||||
if (m_vJitterAngles[2] > 0) {
|
||||
m_vJitterAngles[2] = 0;
|
||||
}
|
||||
} else if (m_vJitterAngles[2] > 0) {
|
||||
m_vJitterAngles[2] -= 1.f / 3.f * m_fJitterScale;
|
||||
|
||||
if( m_vJitterAngles[ 2 ] < 0.0f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] = 0.0f;
|
||||
}
|
||||
}
|
||||
if (m_vJitterAngles[2] < 0) {
|
||||
m_vJitterAngles[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_vJitterAngles[ 2 ] = -m_vJitterAngles[ 2 ];
|
||||
m_vJitterAngles[2] = -m_vJitterAngles[2];
|
||||
}
|
||||
|
||||
// Check for at least one active leak to play a sound
|
||||
for( i = 0; i < MAX_BARREL_LEAKS; i++ )
|
||||
{
|
||||
if( m_bLeaksActive[ i ] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check for at least one active leak to play a sound
|
||||
for (i = 0; i < MAX_BARREL_LEAKS; i++) {
|
||||
if (m_bLeaksActive[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Play a leak sound
|
||||
if( i != MAX_BARREL_LEAKS && iBiggestLeak )
|
||||
{
|
||||
if( !( iBiggestLeak & 4 ) )
|
||||
{
|
||||
if( iBiggestLeak & 2 )
|
||||
{
|
||||
// medium leak
|
||||
LoopSound( "liquid_leak", 0.60f, -1.0f, -1.0f, 0.90f );
|
||||
}
|
||||
else
|
||||
{
|
||||
// small leak
|
||||
LoopSound( "liquid_leak", 0.30f, -1.0f, -1.0f, 0.80f );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// big leak
|
||||
LoopSound( "liquid_leak", 1.0f, -1.0f, -1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
// Play a leak sound
|
||||
if (i != MAX_BARREL_LEAKS && iBiggestLeak) {
|
||||
if (iBiggestLeak & 4) {
|
||||
// big leak
|
||||
LoopSound("liquid_leak", 1, -1, -1, 1);
|
||||
} else if (iBiggestLeak & 2) {
|
||||
// medium leak
|
||||
LoopSound("liquid_leak", 0.6, -1, -1, 0.9);
|
||||
} else {
|
||||
// small leak
|
||||
LoopSound("liquid_leak", 0.3, -1, -1, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
if( i == MAX_BARREL_LEAKS ) {
|
||||
StopLoopSound();
|
||||
}
|
||||
if (i == MAX_BARREL_LEAKS) {
|
||||
StopLoopSound();
|
||||
}
|
||||
|
||||
if( m_vJitterAngles[ 0 ] || m_vJitterAngles[ 2 ] || i < MAX_BARREL_LEAKS )
|
||||
{
|
||||
m_fLastEffectTime += 0.075f;
|
||||
if (m_vJitterAngles[0] || m_vJitterAngles[2] || i < MAX_BARREL_LEAKS) {
|
||||
m_fLastEffectTime += 0.075f;
|
||||
|
||||
if( level.time >= m_fLastEffectTime )
|
||||
{
|
||||
m_fLastEffectTime = level.time + 0.075f;
|
||||
}
|
||||
if (m_fLastEffectTime <= level.time) {
|
||||
m_fLastEffectTime = level.time + 0.075f;
|
||||
}
|
||||
|
||||
PostEvent( EV_Barrel_Think, m_fLastEffectTime - level.time );
|
||||
}
|
||||
PostEvent(EV_Barrel_Think, m_fLastEffectTime - level.time);
|
||||
}
|
||||
}
|
||||
|
||||
void BarrelObject::BarrelDamaged
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void BarrelObject::BarrelDamaged(Event *ev)
|
||||
{
|
||||
Vector vDir;
|
||||
Vector vForward;
|
||||
Vector vRight;
|
||||
int iDamage;
|
||||
int iMeansOfDeath;
|
||||
Vector vHitPos;
|
||||
Vector vHitDirection;
|
||||
Vector vHitNormal;
|
||||
Vector vDir;
|
||||
Vector vForward;
|
||||
Vector vRight;
|
||||
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);
|
||||
|
||||
m_vJitterAngles[ 0 ] += DotProduct( vDir, vForward ) * m_fJitterScale * 0.0275f * ( float )iDamage;
|
||||
m_vJitterAngles[ 2 ] += DotProduct( vDir, vRight ) * m_fJitterScale * 0.0275f * ( float )iDamage;
|
||||
m_vJitterAngles[0] += DotProduct(vDir, vForward) * m_fJitterScale * 0.0275f * (float)iDamage;
|
||||
m_vJitterAngles[2] += DotProduct(vDir, vRight) * m_fJitterScale * 0.0275f * (float)iDamage;
|
||||
|
||||
if( m_vJitterAngles[ 0 ] > m_fJitterScale * 1.5f )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] = m_fJitterScale * 1.5f;
|
||||
}
|
||||
else if( m_vJitterAngles[ 0 ] < -( m_fJitterScale * 1.5f ) )
|
||||
{
|
||||
m_vJitterAngles[ 0 ] = -( m_fJitterScale * 1.5f );
|
||||
}
|
||||
if (m_vJitterAngles[0] > m_fJitterScale * 1.5f) {
|
||||
m_vJitterAngles[0] = m_fJitterScale * 1.5f;
|
||||
} else if (m_vJitterAngles[0] < -(m_fJitterScale * 1.5f)) {
|
||||
m_vJitterAngles[0] = -(m_fJitterScale * 1.5f);
|
||||
}
|
||||
|
||||
if( m_vJitterAngles[ 2 ] > m_fJitterScale * 1.5f )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] = m_fJitterScale * 1.5f;
|
||||
}
|
||||
else if( m_vJitterAngles[ 2 ] < -( m_fJitterScale * 1.5f ) )
|
||||
{
|
||||
m_vJitterAngles[ 2 ] = -( m_fJitterScale * 1.5f );
|
||||
}
|
||||
if (m_vJitterAngles[2] > m_fJitterScale * 1.5f) {
|
||||
m_vJitterAngles[2] = m_fJitterScale * 1.5f;
|
||||
} else if (m_vJitterAngles[2] < -(m_fJitterScale * 1.5f)) {
|
||||
m_vJitterAngles[2] = -(m_fJitterScale * 1.5f);
|
||||
}
|
||||
|
||||
if( !( spawnflags & BARREL_INDESTRUCTABLE ) )
|
||||
{
|
||||
if( ( iMeansOfDeath == MOD_VEHICLE || iMeansOfDeath == MOD_ROCKET ||
|
||||
iMeansOfDeath == MOD_GRENADE || iMeansOfDeath == MOD_EXPLODEWALL ||
|
||||
iMeansOfDeath == MOD_EXPLOSION || m_iBarrelType == BARREL_GAS ) &&
|
||||
iMeansOfDeath != MOD_BASH
|
||||
)
|
||||
{
|
||||
if( iDamage >= health )
|
||||
{
|
||||
PostEvent( EV_Killed, 0.01f );
|
||||
takedamage = DAMAGE_NO;
|
||||
return;
|
||||
}
|
||||
if (!(spawnflags & BARREL_INDESTRUCTABLE)) {
|
||||
if ((iMeansOfDeath == MOD_VEHICLE || iMeansOfDeath == MOD_ROCKET || iMeansOfDeath == MOD_GRENADE
|
||||
|| iMeansOfDeath == MOD_EXPLODEWALL || iMeansOfDeath == MOD_EXPLOSION || m_iBarrelType == BARREL_GAS)
|
||||
&& iMeansOfDeath != MOD_BASH) {
|
||||
if (iDamage >= health) {
|
||||
PostEvent(EV_Killed, 0.01f);
|
||||
takedamage = DAMAGE_NO;
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_iBarrelType == BARREL_GAS )
|
||||
{
|
||||
iDamage /= 2;
|
||||
if (m_iBarrelType == BARREL_GAS) {
|
||||
iDamage /= 2;
|
||||
|
||||
health -= iDamage;
|
||||
if( health < 1.0f )
|
||||
health = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
health -= iDamage;
|
||||
if (health < 1.0f) {
|
||||
health = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !EventPending( EV_Barrel_Think ) )
|
||||
{
|
||||
m_fLastEffectTime = level.time - 0.075f;
|
||||
ProcessEvent( EV_Barrel_Think );
|
||||
}
|
||||
if (!EventPending(EV_Barrel_Think)) {
|
||||
m_fLastEffectTime = level.time - 0.075f;
|
||||
ProcessEvent(EV_Barrel_Think);
|
||||
}
|
||||
|
||||
if( m_iBarrelType <= BARREL_WATER )
|
||||
{
|
||||
int index = PickBarrelLeak();
|
||||
if (m_iBarrelType <= BARREL_WATER) {
|
||||
int index = PickBarrelLeak();
|
||||
|
||||
if( vHitPos[ 2 ] <= m_fFluidAmount / m_fHeightFluid + origin[ 2 ] + mins[ 2 ] )
|
||||
{
|
||||
m_bLeaksActive[ index ] = qtrue;
|
||||
m_vLeaks[ index ] = vHitPos;
|
||||
m_vLeakNorms[ index ] = vHitNormal;
|
||||
if (vHitPos[2] <= m_fFluidAmount / m_fHeightFluid + origin[2] + mins[2]) {
|
||||
m_bLeaksActive[index] = qtrue;
|
||||
m_vLeaks[index] = vHitPos;
|
||||
m_vLeakNorms[index] = vHitNormal;
|
||||
|
||||
gi.SetBroadcastVisible( vHitPos, vHitPos );
|
||||
gi.SetBroadcastVisible(vHitPos, vHitPos);
|
||||
|
||||
if( m_iBarrelType == BARREL_OIL )
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_4));
|
||||
else
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_8));
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.SetBroadcastVisible( vHitPos, vHitPos );
|
||||
if (m_iBarrelType == BARREL_OIL) {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_4));
|
||||
} else {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_8));
|
||||
}
|
||||
} else {
|
||||
gi.SetBroadcastVisible(vHitPos, vHitPos);
|
||||
|
||||
if( m_iBarrelType == BARREL_OIL )
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_3));
|
||||
else
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_7));
|
||||
}
|
||||
if (m_iBarrelType == BARREL_OIL) {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_3));
|
||||
} else {
|
||||
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_EFFECT_7));
|
||||
}
|
||||
}
|
||||
|
||||
gi.MSG_WriteCoord( vHitPos[ 0 ] );
|
||||
gi.MSG_WriteCoord( vHitPos[ 1 ] );
|
||||
gi.MSG_WriteCoord( vHitPos[ 2 ] );
|
||||
gi.MSG_WriteDir( vHitNormal );
|
||||
gi.MSG_EndCGM();
|
||||
}
|
||||
gi.MSG_WriteCoord(vHitPos[0]);
|
||||
gi.MSG_WriteCoord(vHitPos[1]);
|
||||
gi.MSG_WriteCoord(vHitPos[2]);
|
||||
gi.MSG_WriteDir(vHitNormal);
|
||||
gi.MSG_EndCGM();
|
||||
}
|
||||
}
|
||||
|
||||
void BarrelObject::BarrelKilled
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
void BarrelObject::BarrelKilled(Event *ev)
|
||||
{
|
||||
float fFluidTop;
|
||||
Vector vPos;
|
||||
str sModel;
|
||||
float fFluidTop;
|
||||
Vector vPos;
|
||||
str sModel;
|
||||
|
||||
setSolidType( SOLID_NOT );
|
||||
PostEvent( EV_Remove, 0.05f );
|
||||
setSolidType(SOLID_NOT);
|
||||
PostEvent(EV_Remove, 0.05f);
|
||||
|
||||
vPos[ 2 ] = ( mins[ 2 ] + origin[ 2 ] );
|
||||
fFluidTop = m_fFluidAmount / m_fHeightFluid + vPos[ 2 ];
|
||||
vPos[2] = (mins[2] + origin[2]);
|
||||
fFluidTop = m_fFluidAmount / m_fHeightFluid + vPos[2];
|
||||
|
||||
if( m_iBarrelType == BARREL_GAS )
|
||||
{
|
||||
RadiusDamage(
|
||||
centroid,
|
||||
this,
|
||||
this,
|
||||
200,
|
||||
this,
|
||||
MOD_EXPLOSION,
|
||||
350,
|
||||
24 );
|
||||
if (m_iBarrelType == BARREL_GAS) {
|
||||
RadiusDamage(centroid, this, this, 200, this, MOD_EXPLOSION, 350, 24);
|
||||
|
||||
sModel = "models/fx/barrel_gas_destroyed.tik";
|
||||
}
|
||||
else if( m_iBarrelType == BARREL_WATER )
|
||||
{
|
||||
if( vPos[ 2 ] + 0.25f * maxs[ 2 ] <= fFluidTop )
|
||||
{
|
||||
sModel = "models/fx/barrel_water_destroyed.tik";
|
||||
}
|
||||
else
|
||||
{
|
||||
sModel = "models/fx/barrel_empty_destroyed.tik";
|
||||
}
|
||||
}
|
||||
else if( m_iBarrelType == BARREL_OIL )
|
||||
{
|
||||
if( vPos[ 2 ] + 0.25f * maxs[ 2 ] > fFluidTop )
|
||||
{
|
||||
sModel = "models/fx/barrel_empty_destroyed.tik";
|
||||
}
|
||||
else
|
||||
{
|
||||
RadiusDamage(
|
||||
centroid,
|
||||
this,
|
||||
this,
|
||||
200,
|
||||
this,
|
||||
MOD_EXPLOSION,
|
||||
350,
|
||||
24 );
|
||||
sModel = "models/fx/barrel_gas_destroyed.tik";
|
||||
} else if (m_iBarrelType == BARREL_WATER) {
|
||||
if (vPos[2] + 0.25f * maxs[2] <= fFluidTop) {
|
||||
sModel = "models/fx/barrel_water_destroyed.tik";
|
||||
} else {
|
||||
sModel = "models/fx/barrel_empty_destroyed.tik";
|
||||
}
|
||||
} else if (m_iBarrelType == BARREL_OIL) {
|
||||
if (vPos[2] + 0.25f * maxs[2] > fFluidTop) {
|
||||
sModel = "models/fx/barrel_empty_destroyed.tik";
|
||||
} else {
|
||||
RadiusDamage(centroid, this, this, 200, this, MOD_EXPLOSION, 350, 24);
|
||||
|
||||
sModel = "models/fx/barrel_oil_destroyed.tik";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sModel = "models/fx/barrel_empty_destroyed.tik";
|
||||
}
|
||||
sModel = "models/fx/barrel_oil_destroyed.tik";
|
||||
}
|
||||
} else {
|
||||
sModel = "models/fx/barrel_empty_destroyed.tik";
|
||||
}
|
||||
|
||||
Animate *exp = new Animate;
|
||||
Animate *exp = new Animate;
|
||||
|
||||
// Spawn an explosion effect
|
||||
exp->edict->s.renderfx |= RF_DONTDRAW;
|
||||
exp->setModel( sModel );
|
||||
// Spawn an explosion effect
|
||||
exp->edict->s.renderfx |= RF_DONTDRAW;
|
||||
exp->setModel(sModel);
|
||||
|
||||
vPos = origin + ( maxs + mins ) * 0.5f;
|
||||
vPos = origin + (maxs + mins) * 0.5f;
|
||||
|
||||
exp->setAngles( Vector( -90, 0, 0 ) );
|
||||
exp->setOrigin( vPos );
|
||||
exp->NewAnim( "idle" );
|
||||
exp->setAngles(Vector(-90, 0, 0));
|
||||
exp->setOrigin(vPos);
|
||||
exp->NewAnim("idle");
|
||||
|
||||
exp->PostEvent( EV_Remove, 0.1f );
|
||||
exp->Unregister( STRING_DEATH );
|
||||
exp->PostEvent(EV_Remove, 0.1f);
|
||||
exp->Unregister(STRING_DEATH);
|
||||
}
|
||||
+46
-53
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,73 +22,66 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
// barrels.h : Barrels
|
||||
|
||||
#ifndef __BARRELOBJECT_H__
|
||||
#define __BARRELOBJECT_H__
|
||||
#pragma once
|
||||
|
||||
#include "entity.h"
|
||||
|
||||
#define BARREL_INDESTRUCTABLE 1
|
||||
#define MAX_BARREL_LEAKS 4
|
||||
#define BARREL_INDESTRUCTABLE 1
|
||||
#define MAX_BARREL_LEAKS 4
|
||||
|
||||
enum
|
||||
{
|
||||
BARREL_EMPTY,
|
||||
BARREL_OIL,
|
||||
BARREL_WATER,
|
||||
BARREL_GAS
|
||||
enum {
|
||||
BARREL_EMPTY,
|
||||
BARREL_OIL,
|
||||
BARREL_WATER,
|
||||
BARREL_GAS
|
||||
};
|
||||
|
||||
class BarrelObject : public Entity {
|
||||
int m_iBarrelType;
|
||||
float m_fFluidAmount;
|
||||
float m_fHeightFluid;
|
||||
qboolean m_bLeaksActive[ MAX_BARREL_LEAKS ];
|
||||
Vector m_vLeaks[ MAX_BARREL_LEAKS ];
|
||||
Vector m_vLeakNorms[ MAX_BARREL_LEAKS ];
|
||||
Vector m_vJitterAngles;
|
||||
Vector m_vStartAngles;
|
||||
float m_fJitterScale;
|
||||
float m_fLastEffectTime;
|
||||
float m_fDamageSoundTime;
|
||||
class BarrelObject : public Entity
|
||||
{
|
||||
int m_iBarrelType;
|
||||
float m_fFluidAmount;
|
||||
float m_fHeightFluid;
|
||||
qboolean m_bLeaksActive[MAX_BARREL_LEAKS];
|
||||
Vector m_vLeaks[MAX_BARREL_LEAKS];
|
||||
Vector m_vLeakNorms[MAX_BARREL_LEAKS];
|
||||
Vector m_vJitterAngles;
|
||||
Vector m_vStartAngles;
|
||||
float m_fJitterScale;
|
||||
float m_fLastEffectTime;
|
||||
float m_fDamageSoundTime;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( BarrelObject );
|
||||
CLASS_PROTOTYPE(BarrelObject);
|
||||
|
||||
BarrelObject();
|
||||
BarrelObject();
|
||||
|
||||
int PickBarrelLeak( void );
|
||||
int PickBarrelLeak(void);
|
||||
|
||||
void BarrelSetup( Event *ev );
|
||||
void BarrelSetType( Event *ev );
|
||||
void BarrelThink( Event *ev );
|
||||
void BarrelDamaged( Event *ev );
|
||||
void BarrelKilled( Event *ev );
|
||||
void BarrelSetup(Event *ev);
|
||||
void BarrelSetType(Event *ev);
|
||||
void BarrelThink(Event *ev);
|
||||
void BarrelDamaged(Event *ev);
|
||||
void BarrelKilled(Event *ev);
|
||||
|
||||
void Archive( Archiver& arc ) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline void BarrelObject::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline void BarrelObject::Archive(Archiver& arc)
|
||||
{
|
||||
Entity::Archive( arc );
|
||||
Entity::Archive(arc);
|
||||
|
||||
arc.ArchiveInteger( &m_iBarrelType );
|
||||
arc.ArchiveFloat( &m_fFluidAmount );
|
||||
arc.ArchiveFloat( &m_fHeightFluid );
|
||||
arc.ArchiveVector( &m_vJitterAngles );
|
||||
arc.ArchiveVector( &m_vStartAngles );
|
||||
arc.ArchiveFloat( &m_fJitterScale );
|
||||
arc.ArchiveFloat( &m_fLastEffectTime );
|
||||
arc.ArchiveFloat( &m_fDamageSoundTime );
|
||||
arc.ArchiveInteger(&m_iBarrelType);
|
||||
arc.ArchiveFloat(&m_fFluidAmount);
|
||||
arc.ArchiveFloat(&m_fHeightFluid);
|
||||
arc.ArchiveVector(&m_vJitterAngles);
|
||||
arc.ArchiveVector(&m_vStartAngles);
|
||||
arc.ArchiveFloat(&m_fJitterScale);
|
||||
arc.ArchiveFloat(&m_fLastEffectTime);
|
||||
arc.ArchiveFloat(&m_fDamageSoundTime);
|
||||
|
||||
for( int i = MAX_BARREL_LEAKS - 1; i >= 0; i-- )
|
||||
{
|
||||
arc.ArchiveBoolean( &m_bLeaksActive[ i ] );
|
||||
arc.ArchiveVector( &m_vLeaks[ i ] );
|
||||
arc.ArchiveVector( &m_vLeakNorms[ i ] );
|
||||
}
|
||||
for (int i = MAX_BARREL_LEAKS - 1; i >= 0; i--) {
|
||||
arc.ArchiveBoolean(&m_bLeaksActive[i]);
|
||||
arc.ArchiveVector(&m_vLeaks[i]);
|
||||
arc.ArchiveVector(&m_vLeakNorms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __BARRELOBJECT_H__
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __BASEIMP_H__
|
||||
#define __BASEIMP_H__
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -86,5 +85,3 @@ void CacheResource( const char *name );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loaded 100 of 453 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user