mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-29 04:00:28 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08d97e0277 | ||
|
|
21d0675035 | ||
|
|
1dfb81917c | ||
|
|
af8c92f090 | ||
|
|
04e0242422 | ||
|
|
110ffc3a01 | ||
|
|
6b4a8bd627 | ||
|
|
0d851fdb68 | ||
|
|
5064f2c16d | ||
|
|
ac46d0eef0 | ||
|
|
70c71b69ee | ||
|
|
4487113c58 | ||
|
|
983f5b9ca4 | ||
|
|
13612d3de9 | ||
|
|
6317ca7183 | ||
|
|
2b96aac1c8 | ||
|
|
a6b75aefa4 | ||
|
|
7dc72b435e | ||
|
|
5a586f4700 | ||
|
|
ef50a5f2cd | ||
|
|
c2c3f6aa1b | ||
|
|
9c8ca98e68 | ||
|
|
3a18c9f327 | ||
|
|
9438f6497d | ||
|
|
5c3c3f8e70 | ||
|
|
3d3c99cd22 | ||
|
|
b3464e620e | ||
|
|
72a38b0b68 | ||
|
|
46e7f29820 | ||
|
|
cb36015a38 | ||
|
|
66cb10a3bf | ||
|
|
bfdd99a028 | ||
|
|
63ef75222e | ||
|
|
072ba0a38f | ||
|
|
576869bda0 | ||
|
|
0d556b1b40 | ||
|
|
0cd217b484 | ||
|
|
907255837e | ||
|
|
ebf33349a3 | ||
|
|
ea6920b711 | ||
|
|
53a47d470a | ||
|
|
7fe7b6ce79 | ||
|
|
0110704abd | ||
|
|
aca23fc62f | ||
|
|
c0a284927e | ||
|
|
2d911c37a4 | ||
|
|
1e7af27227 | ||
|
|
06678a8b0a | ||
|
|
e1706610c4 | ||
|
|
7bb940d819 | ||
|
|
b4e0120428 | ||
|
|
db1013d926 | ||
|
|
759dacd345 | ||
|
|
903fd28953 | ||
|
|
6c520babf0 | ||
|
|
9bb2fda6df | ||
|
|
d48b37ece1 | ||
|
|
f4164e84e1 | ||
|
|
33aabadaf5 | ||
|
|
e815fda908 | ||
|
|
fe04adee1d | ||
|
|
115647a8c0 | ||
|
|
ddd70eadf6 | ||
|
|
319e00214e | ||
|
|
6bdcfc2b6f | ||
|
|
ae0a2238da | ||
|
|
a69f9fe88b | ||
|
|
696b57f990 | ||
|
|
998c1b78c7 | ||
|
|
8c207f094d | ||
|
|
09c9c0ef51 | ||
|
|
8cd571c96c | ||
|
|
979af2925d | ||
|
|
f092eab842 | ||
|
|
3d4832ca85 | ||
|
|
b120fc6f2f | ||
|
|
c299ad92aa | ||
|
|
956cd59385 | ||
|
|
acbd802790 | ||
|
|
c4bcecf5e0 | ||
|
|
09949251ac | ||
|
|
43218f1685 | ||
|
|
eb7d01b3e7 | ||
|
|
c58e6d58b4 | ||
|
|
3a892e1a47 | ||
|
|
5bb487e1fa | ||
|
|
4ae091be4b | ||
|
|
7654ab6be6 | ||
|
|
193cc9dc10 | ||
|
|
a6d268e1a1 | ||
|
|
7822e94e61 | ||
|
|
eb663fdbc1 | ||
|
|
c738a40c05 | ||
|
|
2ca3443b7f | ||
|
|
06be4c03fa | ||
|
|
32d77f4a7d | ||
|
|
d217b1d561 | ||
|
|
0167f0a3a4 | ||
|
|
4304ad0faa | ||
|
|
3be17376e4 | ||
|
|
0b4fd4c17e | ||
|
|
66c4499b2e | ||
|
|
cde13177a4 | ||
|
|
9fce2575ab | ||
|
|
8f8e92c8c3 | ||
|
|
8683d317fe | ||
|
|
1178c619bc | ||
|
|
2fa568eb01 | ||
|
|
d62242d653 | ||
|
|
991bf2f1f5 | ||
|
|
2f241343ff | ||
|
|
035de09c15 | ||
|
|
d3a4407391 | ||
|
|
395c16ce24 | ||
|
|
f7accc01ad | ||
|
|
3733154e63 | ||
|
|
2ef95ddba9 | ||
|
|
043f8cba22 | ||
|
|
09ab172630 | ||
|
|
c23a182bec | ||
|
|
c321470382 | ||
|
|
932bdd402c | ||
|
|
3692671f49 | ||
|
|
1cd4c35a79 | ||
|
|
c0f7a48649 | ||
|
|
c1258f160b | ||
|
|
bdb9feb7c5 | ||
|
|
830cbe7af2 | ||
|
|
4eb83c0766 | ||
|
|
210f2fef77 | ||
|
|
d19a6160d2 | ||
|
|
cd773cf73f | ||
|
|
f3b9a10f7a | ||
|
|
709283ff33 | ||
|
|
fae261d7da | ||
|
|
6b5e527b6b | ||
|
|
b7005a310e | ||
|
|
edd25b9264 | ||
|
|
65a8b03ee4 | ||
|
|
0044ec0ac0 | ||
|
|
73111d854d | ||
|
|
065ab98175 | ||
|
|
cbeaeba828 | ||
|
|
7af2a9444e | ||
|
|
f476f3690a | ||
|
|
fae02da4b1 | ||
|
|
b0e4e29ce3 | ||
|
|
11f7728b9d | ||
|
|
7510b05d25 | ||
|
|
e467f91262 | ||
|
|
b03afb899d | ||
|
|
ec71ff3c3c | ||
|
|
02ce50ace2 | ||
|
|
4a4a552a05 | ||
|
|
5b3615d262 | ||
|
|
2821488c93 | ||
|
|
9814887b10 | ||
|
|
3f86381541 | ||
|
|
7736966dc1 | ||
|
|
60faa9dd9b | ||
|
|
75f8f86f86 | ||
|
|
0ee1307e75 | ||
|
|
f0c38305b5 | ||
|
|
e07dda6991 | ||
|
|
b10ce9a426 | ||
|
|
2ac2800ecb | ||
|
|
e59200a7de | ||
|
|
a7902a8837 | ||
|
|
615726cc75 | ||
|
|
839abf6076 | ||
|
|
c7c8d4580d | ||
|
|
2cc47e10f9 | ||
|
|
8fc5dacebf | ||
|
|
cb23f3bb70 | ||
|
|
d7350d8629 | ||
|
|
ac6b5ef1f7 | ||
|
|
7fdd26c59e | ||
|
|
fad555308b | ||
|
|
969255c48e | ||
|
|
433305617c | ||
|
|
5418d84c7e | ||
|
|
cca37e3dfe | ||
|
|
0e9d83ee14 | ||
|
|
ecbf7f6caa | ||
|
|
5a3638fa68 | ||
|
|
111088b540 | ||
|
|
ba1703ebf0 | ||
|
|
825df20a72 | ||
|
|
0a42fd79d2 | ||
|
|
e50a041c12 | ||
|
|
ce0e9fe77e | ||
|
|
5105dcce04 | ||
|
|
58b4a9a676 | ||
|
|
1146c834fb | ||
|
|
9068264132 | ||
|
|
59ac8ea437 | ||
|
|
afafacaeec | ||
|
|
baf451d2a2 | ||
|
|
d588012168 | ||
|
|
a3ed25cb2e | ||
|
|
c399f45841 | ||
|
|
6a6eeae4ee | ||
|
|
65f36505d1 | ||
|
|
b852980842 | ||
|
|
d351ced78b | ||
|
|
4cd45c63c4 | ||
|
|
de16a72aed | ||
|
|
4b29c63fc9 | ||
|
|
770e832592 | ||
|
|
14f9acdb57 | ||
|
|
573a6f5bd5 | ||
|
|
8c64b7aa89 | ||
|
|
8d49f8935c | ||
|
|
ff8ec63e95 | ||
|
|
771ee1b5a9 | ||
|
|
096692fec8 | ||
|
|
d29454b44d | ||
|
|
30a1ccb2e2 | ||
|
|
ea1b411cc0 | ||
|
|
7794ee8aea | ||
|
|
99a9022b53 | ||
|
|
1255964e6b | ||
|
|
37de859bee | ||
|
|
990aa5cdb2 | ||
|
|
befcedcf58 | ||
|
|
eeb697570d | ||
|
|
6410567e9a | ||
|
|
bde7242cc7 | ||
|
|
e8aad97975 | ||
|
|
0662359776 | ||
|
|
5568d160ab | ||
|
|
defa297a56 | ||
|
|
782c37c4fe | ||
|
|
6f03c88ad5 | ||
|
|
3ec980c8ec | ||
|
|
c0a50eb2ff | ||
|
|
f73e4b6f22 | ||
|
|
096972827e | ||
|
|
08c040d4ea | ||
|
|
6d8b6b5f29 | ||
|
|
410f1c0ed8 | ||
|
|
cb73cfd57b | ||
|
|
8cb8a7f370 | ||
|
|
8c893acfff | ||
|
|
e453d1fa17 | ||
|
|
a7301ed7b6 | ||
|
|
42ebfd5394 | ||
|
|
cdf2f84b14 | ||
|
|
2592aeab8b | ||
|
|
34d4225ea0 | ||
|
|
17dcb4b00e | ||
|
|
eb1d096539 | ||
|
|
05c74655be | ||
|
|
3e0e0ba3b1 | ||
|
|
f90b6cd18c | ||
|
|
f0ecfcb708 | ||
|
|
177702d027 | ||
|
|
64429232f8 | ||
|
|
d6b7fecb69 | ||
|
|
51a0ee56aa | ||
|
|
2ed369568c | ||
|
|
e5b7e16d1a | ||
|
|
4a9f676d5d | ||
|
|
0e0da3d767 | ||
|
|
343ce4a6a7 | ||
|
|
df8b854cb7 | ||
|
|
831dc770d8 | ||
|
|
8a9285c64f | ||
|
|
7e4e06b09d | ||
|
|
96748b3fbc | ||
|
|
f1325048e9 | ||
|
|
deee21eb68 | ||
|
|
2f43e5c5ea | ||
|
|
4766067edb | ||
|
|
bc54f22639 | ||
|
|
20c8c87e79 | ||
|
|
3a5dcd6a3c | ||
|
|
a5ba02c2bb | ||
|
|
e1554efc08 | ||
|
|
9d652dd41b | ||
|
|
22eadf2c08 | ||
|
|
d3f1b62208 | ||
|
|
affc28ab79 | ||
|
|
41be7f44ab | ||
|
|
646c1f0f16 | ||
|
|
3cea097b48 | ||
|
|
786d72575e | ||
|
|
6d9a794aaf | ||
|
|
9e69df1e94 | ||
|
|
72d4bb0206 | ||
|
|
f68e06a949 | ||
|
|
f4da539d95 | ||
|
|
17af75a9bb | ||
|
|
dcbb39d640 | ||
|
|
d0ba1df4e0 | ||
|
|
2b92869683 | ||
|
|
379a4b0ce4 | ||
|
|
d4c7d4a7e1 | ||
|
|
dcac24c9e2 | ||
|
|
753589d840 | ||
|
|
382903c9e1 | ||
|
|
f29fec0b31 | ||
|
|
f9dc37d60a | ||
|
|
c5e48c67bb | ||
|
|
cc62ebcffc | ||
|
|
0f36504959 | ||
|
|
1fb8e25209 | ||
|
|
260876b1a2 | ||
|
|
e4fc074f09 | ||
|
|
7899e5161e | ||
|
|
95603b1142 | ||
|
|
bf8e0eb812 | ||
|
|
0c04ffc1e8 | ||
|
|
bd86acf118 | ||
|
|
6caa16444e | ||
|
|
94d4cbeb82 | ||
|
|
b31f4bc00c | ||
|
|
cf0808e119 | ||
|
|
92333909fd | ||
|
|
9c68af92be | ||
|
|
bc5d7f5e93 | ||
|
|
f2ba9a88be | ||
|
|
81b711364e | ||
|
|
554e0c7fac | ||
|
|
bd2c1c387b | ||
|
|
f19edac9ca | ||
|
|
1698f6d1bf | ||
|
|
2c3180813a | ||
|
|
a262fe5d9d | ||
|
|
a69249ee22 | ||
|
|
393c2a81d1 | ||
|
|
3a6be342ce | ||
|
|
6616bfe53e | ||
|
|
bafe60f48f | ||
|
|
e306c415f0 | ||
|
|
56a8c8d48d | ||
|
|
421f1d39a4 | ||
|
|
7c655944a5 | ||
|
|
0a27f37dc0 | ||
|
|
4695932ea1 | ||
|
|
7fe7a12167 | ||
|
|
f9487b0ba3 | ||
|
|
7c5c34741c | ||
|
|
d09459f4bf | ||
|
|
c0c6598151 | ||
|
|
f52fcc6f0e | ||
|
|
2e9ef64bd2 | ||
|
|
ff3ee39830 | ||
|
|
abd757f3bc | ||
|
|
c741591a36 | ||
|
|
78c481d725 | ||
|
|
b2ece37819 | ||
|
|
a557b29ecf | ||
|
|
1184843318 | ||
|
|
dd1f8bd92a | ||
|
|
220c82954c | ||
|
|
8879bacb1d | ||
|
|
5824022745 | ||
|
|
3ecb5bd06a | ||
|
|
7de31a776b | ||
|
|
503320d13f | ||
|
|
bd263c5d22 | ||
|
|
b0201aef5d | ||
|
|
31014808c8 | ||
|
|
0906124867 | ||
|
|
43bb5ce653 | ||
|
|
7e66483b1a | ||
|
|
f96b606a1a | ||
|
|
30d26c3e44 | ||
|
|
57e450a745 | ||
|
|
24297bf396 | ||
|
|
481cd760a9 | ||
|
|
6d6043775e | ||
|
|
bb97ec8933 | ||
|
|
dc028b87e4 | ||
|
|
0d1b7a9c8a | ||
|
|
a6e602af1d | ||
|
|
04a6012e5d | ||
|
|
0f7691c722 | ||
|
|
f01a0a17c1 | ||
|
|
b291ab92b6 | ||
|
|
fb4bf4fcaa | ||
|
|
98816156d7 | ||
|
|
92bfb4c426 | ||
|
|
cac883c4a0 | ||
|
|
5a4fb90c96 | ||
|
|
c4f9eb65ae | ||
|
|
9f5557b33c | ||
|
|
4d876fdf5d | ||
|
|
978666c946 | ||
|
|
9b9fa696e8 | ||
|
|
088b22073c | ||
|
|
4f9831faa4 | ||
|
|
3373caa939 | ||
|
|
dc1be17b2a | ||
|
|
64a3b04181 | ||
|
|
57e1920b9c | ||
|
|
ddb6236eb9 | ||
|
|
4e4af590e5 | ||
|
|
a249f6b29b | ||
|
|
7787729b24 | ||
|
|
45c8c704af | ||
|
|
31fde1ad94 | ||
|
|
bfb0fbd656 | ||
|
|
8afb7457c2 | ||
|
|
0ae1c8f771 | ||
|
|
6ff046ae29 | ||
|
|
6f9f845bb2 | ||
|
|
00033c3a70 | ||
|
|
acf71610df | ||
|
|
86e9ae343a | ||
|
|
9bbd546d4c | ||
|
|
31f2573b28 | ||
|
|
4d7fcb77c2 | ||
|
|
da02a8c73a | ||
|
|
dd0b4505a6 | ||
|
|
eaff26216a | ||
|
|
e850dd1963 | ||
|
|
cf61ae0332 | ||
|
|
5cffe3fb05 | ||
|
|
b996918d3b | ||
|
|
4a9f9a45c2 | ||
|
|
3a75772005 | ||
|
|
c196e31c6c | ||
|
|
60ceff5ae0 | ||
|
|
34a4a0c892 | ||
|
|
2a3c42d47b | ||
|
|
0b1f796e0a | ||
|
|
766d4d23bf | ||
|
|
6860a1e992 | ||
|
|
70c628d759 | ||
|
|
6eff8bc273 | ||
|
|
0b1e8cdbf3 | ||
|
|
6f58b34f87 | ||
|
|
adf081ba3c | ||
|
|
6d4a9fde3f | ||
|
|
5a5cc4ea17 | ||
|
|
69df583508 | ||
|
|
18506d9932 | ||
|
|
f076e7609e | ||
|
|
0b0d053044 | ||
|
|
ce7dfdd986 | ||
|
|
50e589f27c | ||
|
|
e904dafa38 | ||
|
|
6a210fa212 | ||
|
|
ae33155ed3 | ||
|
|
d3d44001ef | ||
|
|
c2aec1ff57 | ||
|
|
d5f08fe950 | ||
|
|
bdf4df9fd0 | ||
|
|
7481b0939e | ||
|
|
346e59f18a | ||
|
|
4725aad3e9 | ||
|
|
59fd1bfdb2 | ||
|
|
7546d91580 | ||
|
|
c81df27470 | ||
|
|
bd6232d913 | ||
|
|
7f6b73e60f | ||
|
|
e3562f9e56 | ||
|
|
40141c55de | ||
|
|
a6f6cbd9b5 | ||
|
|
e9ffb4b9b5 | ||
|
|
1f0418a9cd | ||
|
|
e76837b42c | ||
|
|
87be7068c9 | ||
|
|
49cb5af265 | ||
|
|
f0fe93429f | ||
|
|
c2461f1219 | ||
|
|
f82b6b75ff | ||
|
|
3486b590eb | ||
|
|
5730af672c | ||
|
|
4daff05142 | ||
|
|
e930768c67 | ||
|
|
6f03e388bf | ||
|
|
9b340e03c5 | ||
|
|
d5b61fe5cc | ||
|
|
5b46e48a17 | ||
|
|
585221f7cc | ||
|
|
77eb7a5259 | ||
|
|
77bfc4b599 | ||
|
|
95bbfba1b8 | ||
|
|
844a50dfd8 | ||
|
|
cd2fea5262 | ||
|
|
79d8b4bb0b | ||
|
|
531825545d | ||
|
|
daab5b9238 | ||
|
|
ce59e5e6a7 | ||
|
|
ea0c4b5060 | ||
|
|
9b9908b660 | ||
|
|
101894be37 | ||
|
|
3e314251f2 | ||
|
|
1995c75006 | ||
|
|
ff85986c44 | ||
|
|
9131297d43 | ||
|
|
301f3091d1 | ||
|
|
b59bd449d4 | ||
|
|
5e510ef0e2 | ||
|
|
c7c3fcd0e0 | ||
|
|
a5532ad67b | ||
|
|
290cd5501c | ||
|
|
8d1b1410cd | ||
|
|
df9aead324 | ||
|
|
851fd240d3 | ||
|
|
2da03c89d1 | ||
|
|
89cd12d2c1 | ||
|
|
e21d2a0adb | ||
|
|
2fad64b08a | ||
|
|
97fd147fbe | ||
|
|
0f01f6af11 | ||
|
|
a9892c88be | ||
|
|
f1d76a042d | ||
|
|
77d4e5d051 | ||
|
|
7041acfd51 | ||
|
|
b27bfbe189 | ||
|
|
1c10e7a63d | ||
|
|
0a7c324d48 | ||
|
|
c81d247fbb | ||
|
|
82294b7b2e | ||
|
|
d80f55d5bf | ||
|
|
7930cda277 | ||
|
|
7870db7202 | ||
|
|
407538fd85 | ||
|
|
1a293420c0 | ||
|
|
1e94cdd8ca | ||
|
|
7a2311d6e6 | ||
|
|
e686937ae9 | ||
|
|
8dca8988fe | ||
|
|
c890ac5944 | ||
|
|
56e52fda80 | ||
|
|
e7786b3192 | ||
|
|
4cc3a84e98 | ||
|
|
6e0b048ae7 | ||
|
|
115786798d | ||
|
|
376db9e9e6 | ||
|
|
8abdb80e85 | ||
|
|
656f212608 | ||
|
|
60e07cc4ff | ||
|
|
e132c0a015 | ||
|
|
8e63526f2a | ||
|
|
a5b7c774c1 | ||
|
|
130a5bb8c4 | ||
|
|
3802dd9984 | ||
|
|
7d37397222 | ||
|
|
932454d7b2 | ||
|
|
5d2e6c46aa | ||
|
|
38089195be | ||
|
|
85a6c1d145 | ||
|
|
85d034b7fb | ||
|
|
82b5468fb4 | ||
|
|
89759c44af | ||
|
|
6f66a1d1c3 | ||
|
|
d4bac185f6 | ||
|
|
658bba576e | ||
|
|
31f3c25b18 | ||
|
|
4a1f149051 | ||
|
|
c55a78b8b4 | ||
|
|
3dbf957304 | ||
|
|
8f98f49f1b | ||
|
|
0a8322960b | ||
|
|
63d73c6f86 | ||
|
|
f8cbbe78a2 | ||
|
|
2bb09503c6 | ||
|
|
ba313decd1 | ||
|
|
0d6847c76c | ||
|
|
7b721c7849 | ||
|
|
1fb073fd6a | ||
|
|
484272aed4 | ||
|
|
57422ce793 | ||
|
|
ba855cd064 | ||
|
|
39ac9f7de6 | ||
|
|
4368035da4 | ||
|
|
4391912ee3 | ||
|
|
fc17536f55 | ||
|
|
3bae4338c3 | ||
|
|
f59bdd6b9f | ||
|
|
03f3676b00 | ||
|
|
e0d7079745 | ||
|
|
b7f421481f | ||
|
|
3506cb3f94 | ||
|
|
7280acee42 | ||
|
|
d757fa6306 | ||
|
|
475fc92629 | ||
|
|
f24303dd78 | ||
|
|
180a20f561 | ||
|
|
2e5ca5b9dc | ||
|
|
decee20fd8 | ||
|
|
3d9a60c415 | ||
|
|
a4a7002867 | ||
|
|
96c9a014e6 | ||
|
|
11b4471be9 | ||
|
|
17aea205f7 | ||
|
|
739f54ed87 | ||
|
|
01be5bee72 | ||
|
|
dfcf0da710 | ||
|
|
f47fb87d1b | ||
|
|
bd639ba936 | ||
|
|
e784e62a4e | ||
|
|
e4425dcbf8 | ||
|
|
0dcffe8771 | ||
|
|
2b27f6c452 | ||
|
|
3ba3c728bc | ||
|
|
7193198af2 | ||
|
|
6691afd160 | ||
|
|
59fb220197 | ||
|
|
ff7651d4c8 | ||
|
|
b02abb1f18 | ||
|
|
9f42da4686 | ||
|
|
58e3056374 | ||
|
|
3142865fef | ||
|
|
06e3497a57 | ||
|
|
e49833737d | ||
|
|
7eedc5fef8 | ||
|
|
c442942022 | ||
|
|
2c2652ed1d | ||
|
|
97bcc07aab | ||
|
|
001704b22e | ||
|
|
f1d9cd93ce | ||
|
|
49aa2aa858 | ||
|
|
6274d9a1e9 | ||
|
|
5fa9d91401 | ||
|
|
9acb803ffe | ||
|
|
105924bca3 | ||
|
|
5f12be2037 | ||
|
|
13931c40cb | ||
|
|
ada5d614c5 | ||
|
|
7323d51219 | ||
|
|
f5071f2667 | ||
|
|
0ca0a81644 | ||
|
|
e1bd69b467 | ||
|
|
b17494519e | ||
|
|
13555f505c | ||
|
|
2a65f53084 | ||
|
|
71fe83083e | ||
|
|
0ddb5c859f | ||
|
|
f7b12d5108 | ||
|
|
baa8f4334b | ||
|
|
24a211b190 | ||
|
|
6e82f254b7 | ||
|
|
fbfedcf8d6 | ||
|
|
5b06a0c2a4 | ||
|
|
f3204b0845 | ||
|
|
334314a137 | ||
|
|
8ecc8122b8 | ||
|
|
eb9a119dfe | ||
|
|
313ece62f7 | ||
|
|
5799bcceb2 | ||
|
|
61e7571388 | ||
|
|
6cfd99e40a | ||
|
|
b3bdd9d563 | ||
|
|
5bec3d8471 | ||
|
|
711e46ecfb | ||
|
|
ddd127352f | ||
|
|
784fd825bb | ||
|
|
673a42242d | ||
|
|
3317345d92 | ||
|
|
7958ba38d8 | ||
|
|
2dd7e0c03f | ||
|
|
b94f021567 | ||
|
|
cf50c5b535 | ||
|
|
1b71169565 | ||
|
|
30f2b9d5ed | ||
|
|
999d6a449b | ||
|
|
a65aa2a0d0 | ||
|
|
36fc0b6e8a | ||
|
|
f97362cdb1 | ||
|
|
6398484459 | ||
|
|
07e8c6feaa | ||
|
|
faf351a496 | ||
|
|
cd9315852e | ||
|
|
8c8487231a | ||
|
|
65ebdf0862 | ||
|
|
9704362501 | ||
|
|
f0e87cd85a | ||
|
|
f6e6bf1d6b | ||
|
|
4b4e8f806b | ||
|
|
4141cee13f | ||
|
|
b2ee346f68 | ||
|
|
2220f1ff05 | ||
|
|
7ba48dd666 | ||
|
|
2a48e2fd27 | ||
|
|
63a24c4448 | ||
|
|
787df3362b | ||
|
|
5ad0f60ee3 | ||
|
|
d42f92361a | ||
|
|
0693db3ef5 | ||
|
|
fafb0e2793 | ||
|
|
0a4819d172 | ||
|
|
ee03f32a3e | ||
|
|
f4e01917a2 | ||
|
|
eed9b36c9f | ||
|
|
055192c2a8 | ||
|
|
cca39108dc | ||
|
|
b1bbd5e366 | ||
|
|
afb718f01f | ||
|
|
653b4e0ab7 | ||
|
|
c3d228a9f5 | ||
|
|
15e10caca0 | ||
|
|
46efa85441 | ||
|
|
bb42456653 | ||
|
|
38bf80aa52 | ||
|
|
c5c2aa5348 | ||
|
|
1e67aeb667 | ||
|
|
9ac7bccba5 | ||
|
|
610b82cfb7 | ||
|
|
c8144539d0 | ||
|
|
60f83597ee | ||
|
|
46c0c6085d | ||
|
|
36d4c4af61 | ||
|
|
7406c3dc23 | ||
|
|
24bb15ce29 | ||
|
|
f3ad05dc85 | ||
|
|
bbae3223cb | ||
|
|
8cedb24d31 | ||
|
|
528414dfef | ||
|
|
6e1c58e343 | ||
|
|
002e935193 | ||
|
|
e26d7d346a | ||
|
|
5d917f2578 | ||
|
|
8aecff1879 | ||
|
|
718672119e | ||
|
|
6ec7482662 | ||
|
|
5f3ea7c634 | ||
|
|
1c813a59d0 | ||
|
|
a66236fc3d | ||
|
|
ef9b7022df | ||
|
|
ad7efce855 | ||
|
|
78a9990c3a | ||
|
|
422b9eb6c0 | ||
|
|
703eb271f9 | ||
|
|
2aca32c44a | ||
|
|
56c30bddb1 | ||
|
|
1179b50ad1 | ||
|
|
6ad44441a6 | ||
|
|
2455c09475 | ||
|
|
7a1e07e72a | ||
|
|
aa8e95885a | ||
|
|
54bae94ad9 | ||
|
|
98b7e01069 | ||
|
|
12c7707bc3 | ||
|
|
a8a2c7e345 | ||
|
|
6c7542ec0c | ||
|
|
5ec56cbe77 | ||
|
|
6b79770783 | ||
|
|
e125a83625 | ||
|
|
d05b47e996 | ||
|
|
e1093d0c0c | ||
|
|
25690648d6 | ||
|
|
5c3c4f6288 | ||
|
|
9dec5e9e54 | ||
|
|
ae1fa808da | ||
|
|
ed6839dc99 | ||
|
|
e95d71da0d | ||
|
|
128c8f3c06 | ||
|
|
04f61a1af7 | ||
|
|
974e86b698 | ||
|
|
12c03384b2 | ||
|
|
99ba912d7b | ||
|
|
7607932216 | ||
|
|
acc9c241a3 | ||
|
|
5f5055f4fc | ||
|
|
fc3749e008 | ||
|
|
155734370c | ||
|
|
1095e3d509 | ||
|
|
f7bfa47f2e | ||
|
|
9f6ef14ea1 | ||
|
|
15de08556e | ||
|
|
e7dfa8fcfe | ||
|
|
7a67dc5dfd | ||
|
|
7eb8ef42b7 | ||
|
|
c9c7a4beed | ||
|
|
bcf3aad1b2 | ||
|
|
ad75363028 | ||
|
|
f4ec3939a5 | ||
|
|
aead97d29d | ||
|
|
f468305a2c | ||
|
|
a962f469eb | ||
|
|
63e025cc02 | ||
|
|
b2d332f152 | ||
|
|
e160cf240c | ||
|
|
19a4f70c44 | ||
|
|
dcca3901d5 | ||
|
|
0ee4ffbfbc | ||
|
|
776bc781cd | ||
|
|
b1bb79e19f | ||
|
|
76c69b7bd1 | ||
|
|
15a25a412f | ||
|
|
b511d89dcc | ||
|
|
9512ae7aeb | ||
|
|
5db086e470 | ||
|
|
d63f668291 | ||
|
|
35c72a9570 | ||
|
|
b29f62ddd4 | ||
|
|
525dc17573 | ||
|
|
4d8ed24833 | ||
|
|
aa15d996e0 | ||
|
|
0ec846945d | ||
|
|
03ff158e76 | ||
|
|
b3371b2d63 | ||
|
|
ed64d03bf5 | ||
|
|
3d936dede1 | ||
|
|
33e9c5b1ea | ||
|
|
078c90bbc9 | ||
|
|
2caf2cad5a | ||
|
|
5dec21dd43 | ||
|
|
36aa9bd802 | ||
|
|
bed2f15a72 | ||
|
|
f949f1e88d | ||
|
|
8af202bd5f | ||
|
|
67556a88f1 | ||
|
|
4f8573784d | ||
|
|
c5a46be23e | ||
|
|
47a3c0bf55 | ||
|
|
e8d2a2a461 | ||
|
|
7b72a3fba4 | ||
|
|
dda79e7f27 | ||
|
|
9a104566ba | ||
|
|
b4d8982341 | ||
|
|
5ea3fc28f7 | ||
|
|
0bbf39660e | ||
|
|
791f38762b | ||
|
|
c296b909c7 | ||
|
|
9c7a54f8fc | ||
|
|
4289eab72b | ||
|
|
7b0dbc7445 | ||
|
|
02db904336 | ||
|
|
55140fee3a | ||
|
|
96d881a1f1 | ||
|
|
260a95c05e | ||
|
|
99d633587f | ||
|
|
cf2f0256a2 | ||
|
|
dae8e8dfbd | ||
|
|
6d2d35e82d | ||
|
|
5e23a6b640 | ||
|
|
f2ec502dc2 | ||
|
|
be04f31256 | ||
|
|
85dd881c97 | ||
|
|
0ef2dccd90 | ||
|
|
000ec39c81 | ||
|
|
3160c6ee0b | ||
|
|
9da403e534 | ||
|
|
f19c3408e1 | ||
|
|
38c0e09e8a | ||
|
|
2be4f7cdaf | ||
|
|
cd48272fbb | ||
|
|
a5a146bb02 | ||
|
|
c901bcf321 | ||
|
|
8f3142e532 | ||
|
|
88438d6db4 | ||
|
|
7348734070 | ||
|
|
a99a4a3a2b | ||
|
|
7bc8c3ab5b | ||
|
|
2a58fbdd22 | ||
|
|
d102f5a88a | ||
|
|
8227f7125b | ||
|
|
673535dc08 | ||
|
|
9750489d07 | ||
|
|
53c6224ed0 | ||
|
|
f84794acbe | ||
|
|
9e535e509a | ||
|
|
489210424f | ||
|
|
394abbdb6f | ||
|
|
5fdeb92429 | ||
|
|
11cc39e41b | ||
|
|
b3d5851fdc | ||
|
|
5c25839bab | ||
|
|
fbd314b447 | ||
|
|
86888a32d4 | ||
|
|
37c2d22b10 | ||
|
|
19758ef75d | ||
|
|
519ccc90f7 | ||
|
|
b592d15d1f | ||
|
|
78d70a892c | ||
|
|
dbcf4c1800 | ||
|
|
cbd4630b3c | ||
|
|
92fdfe3f35 | ||
|
|
8b563e5232 | ||
|
|
aeb4875fa5 | ||
|
|
5ebb9c61f9 | ||
|
|
c0e5b8fe15 | ||
|
|
f852efea7d | ||
|
|
664ae905bb | ||
|
|
243b0fd109 | ||
|
|
43b0944403 | ||
|
|
ecc3c9f7b4 | ||
|
|
296249b203 | ||
|
|
8c1145bb9f | ||
|
|
7ad18a68f8 | ||
|
|
99ba396c24 | ||
|
|
f88e9960f2 | ||
|
|
b53466ea0d | ||
|
|
2afda6a470 | ||
|
|
acc8081ef2 | ||
|
|
7433677ead | ||
|
|
4132f7efe6 | ||
|
|
56e0f5797e | ||
|
|
54c142ce78 | ||
|
|
c106aeef2b | ||
|
|
66bde85807 | ||
|
|
08363511a7 | ||
|
|
d6b93b712c | ||
|
|
a85d6d0f4c | ||
|
|
2c1f341099 | ||
|
|
52bb709ca5 | ||
|
|
24ea958748 | ||
|
|
b6143ce54c | ||
|
|
463ea7d34b | ||
|
|
1015302a7f | ||
|
|
c73f5917f8 | ||
|
|
9315cfa488 | ||
|
|
0f58b5780a | ||
|
|
edd5f07d48 | ||
|
|
a7f258f2b1 | ||
|
|
65dcb72cba | ||
|
|
4885c536c8 | ||
|
|
b6204dab78 | ||
|
|
5b5951483a | ||
|
|
194d53569f | ||
|
|
5e8b54be7e | ||
|
|
8dc91e413e | ||
|
|
57cf513b39 | ||
|
|
bb1326860b | ||
|
|
136838e40b | ||
|
|
30d9483504 | ||
|
|
05d3c50866 | ||
|
|
d5e93d863a | ||
|
|
d3f93aae15 | ||
|
|
963e4aa7ec | ||
|
|
5a250ea247 | ||
|
|
bc8d8aafc0 | ||
|
|
f67ab4ec7f | ||
|
|
cf9af20fbd | ||
|
|
3be2a3eb79 | ||
|
|
7dfd18f4fb | ||
|
|
05fc960338 | ||
|
|
21d41ce14b | ||
|
|
1562ba3f97 | ||
|
|
2798e73707 | ||
|
|
89aeee4269 | ||
|
|
d50302fa41 | ||
|
|
8efae54450 | ||
|
|
2785a72789 | ||
|
|
ac55a44761 | ||
|
|
42f1a286a8 | ||
|
|
241fa5d485 | ||
|
|
e87f9c5710 | ||
|
|
c95a6ee3fd | ||
|
|
10b954cb1a | ||
|
|
cf7914b6f8 | ||
|
|
e58e048f00 | ||
|
|
b92cd8a64f | ||
|
|
317aead26d | ||
|
|
e93780c66c | ||
|
|
af8990acf0 | ||
|
|
e41dcf03ad | ||
|
|
0209e8f782 | ||
|
|
50d935171e | ||
|
|
86ee9089e9 | ||
|
|
ba6fe112bb | ||
|
|
15860a7795 | ||
|
|
78b3ad8075 | ||
|
|
f61bda330e | ||
|
|
5c9fceea2c | ||
|
|
32cceebc47 | ||
|
|
9d921df733 | ||
|
|
428f8c183d | ||
|
|
45aae54b32 | ||
|
|
d9ca73bc4c | ||
|
|
c2e24da9bd | ||
|
|
c6ae5ed551 | ||
|
|
0f86a5ee8a | ||
|
|
803e53869b | ||
|
|
a4fc25cca8 | ||
|
|
28fbcf5628 | ||
|
|
3ea73febe4 | ||
|
|
9eb3b3e1c3 | ||
|
|
48e1c39320 | ||
|
|
fe38c7650f | ||
|
|
5e2f5010f8 | ||
|
|
efce4703ca | ||
|
|
94ab4a5ac5 | ||
|
|
58321be1ce | ||
|
|
20282ffa56 | ||
|
|
ff4987cc81 | ||
|
|
80a22ca2ed | ||
|
|
51ca0a06a7 | ||
|
|
010794418c | ||
|
|
51b5b2571a | ||
|
|
182a677337 | ||
|
|
17f6c25bc7 | ||
|
|
31d19cb0f6 | ||
|
|
6c65bba279 | ||
|
|
8ae15be0de | ||
|
|
11fb5ee2af | ||
|
|
b68992e55e | ||
|
|
007a7681eb | ||
|
|
7d4cdac52c | ||
|
|
916f38e1b2 | ||
|
|
39ae88a2ab | ||
|
|
24f82e8e36 | ||
|
|
247d09a09d | ||
|
|
030b291af1 | ||
|
|
9d0a5faed3 | ||
|
|
261b15851f | ||
|
|
2929bd82a5 | ||
|
|
4939927975 | ||
|
|
f9ef6733b9 | ||
|
|
de08fe7ca3 | ||
|
|
482536ff1c | ||
|
|
3089cc8bc3 | ||
|
|
a307450e17 | ||
|
|
50cfc7e5ad | ||
|
|
5b82cc4f11 | ||
|
|
a83a76da95 | ||
|
|
2e4759ab1f | ||
|
|
af056d7646 | ||
|
|
46e57f0a1f | ||
|
|
fe5473bc85 | ||
|
|
1a03288144 | ||
|
|
0c2326480b | ||
|
|
24f3b3bc93 | ||
|
|
459aa89ca2 | ||
|
|
ec8eaacc69 | ||
|
|
84f55f627e | ||
|
|
a30f78e834 | ||
|
|
d22cda594f | ||
|
|
8cfa909b73 | ||
|
|
86a6dd020f | ||
|
|
556133fa11 | ||
|
|
4001de1dde | ||
|
|
7a57a25c58 | ||
|
|
d95cdcc142 | ||
|
|
d2a967e577 | ||
|
|
84adaa07e0 | ||
|
|
2efeb7e972 | ||
|
|
b9655e3f19 | ||
|
|
dce004ef13 | ||
|
|
b9f1530eec | ||
|
|
9b15b27f28 | ||
|
|
ff2e64a742 | ||
|
|
4e38b803fb | ||
|
|
9825e1e6f2 | ||
|
|
b278f2eafa | ||
|
|
25912079db | ||
|
|
b1753df1ed | ||
|
|
03143d1341 | ||
|
|
843b49d56b | ||
|
|
00644e7605 | ||
|
|
93814bd05b | ||
|
|
438ed2c0ea | ||
|
|
0310475957 | ||
|
|
435bfe1271 | ||
|
|
7ca532f0e4 | ||
|
|
8c3997f13b | ||
|
|
d8ae1ce6b9 | ||
|
|
5cb1e5de84 | ||
|
|
7fd2aff17b | ||
|
|
b9f3ee867b | ||
|
|
f16b992a97 | ||
|
|
9ba5710412 | ||
|
|
7e6854f96b | ||
|
|
aa25ef6c68 | ||
|
|
9db1076603 | ||
|
|
7b39218af5 | ||
|
|
ba5b2adf94 | ||
|
|
ded7d941ea | ||
|
|
09ed4e4a1d | ||
|
|
9b3aaa0f87 | ||
|
|
a274325f43 | ||
|
|
b0da0b8321 | ||
|
|
a241ea20fa | ||
|
|
f8d5a5ecd2 | ||
|
|
f20b47ebc0 | ||
|
|
de10ab8df3 | ||
|
|
47c7c5a5e3 | ||
|
|
80ada3225d | ||
|
|
a1745829b2 | ||
|
|
b2853465ed | ||
|
|
c89091b4cd | ||
|
|
e5beb0d9b9 | ||
|
|
80ab513d76 | ||
|
|
854136d85b | ||
|
|
25c417187b | ||
|
|
e3e9328ba3 | ||
|
|
3cc0c41b7b | ||
|
|
697013bbbf | ||
|
|
0080d4b9a8 | ||
|
|
8c391ef880 | ||
|
|
e6d3ca32f4 | ||
|
|
fab78f933e | ||
|
|
5cd7d89e72 | ||
|
|
15e8146306 | ||
|
|
250f1d090e | ||
|
|
03c5864034 | ||
|
|
07b7f10912 | ||
|
|
0e1837db31 | ||
|
|
070fe17473 | ||
|
|
ba607a0aad | ||
|
|
2b38a0f48e | ||
|
|
a1fb3b283c | ||
|
|
12e85aba45 | ||
|
|
44fe18fef1 | ||
|
|
28de2543ec | ||
|
|
4435984b81 | ||
|
|
1435489a43 | ||
|
|
3d20b3a232 | ||
|
|
97543622bf | ||
|
|
a9374f068b | ||
|
|
d80e9d80e7 | ||
|
|
4f757445c4 | ||
|
|
2749ab92b2 | ||
|
|
011bee9f33 | ||
|
|
1b86e60548 | ||
|
|
23e01fc1a7 | ||
|
|
2c9c80d7bc | ||
|
|
5146b1f36b | ||
|
|
bc81fe78b2 | ||
|
|
4de1b7c73b | ||
|
|
3c8c4e9f97 | ||
|
|
c366c10530 | ||
|
|
6f5106803d | ||
|
|
55a6b7956a | ||
|
|
911d1f1706 | ||
|
|
56fba733f3 | ||
|
|
a3c65ef7e4 | ||
|
|
73bc196592 | ||
|
|
8487099264 | ||
|
|
bdcd0dbd56 | ||
|
|
3c2600648c | ||
|
|
f1abfeced6 | ||
|
|
99bce5a11a | ||
|
|
ab5a3604bf | ||
|
|
fab7d8539c | ||
|
|
0347a5ca0b | ||
|
|
42ad1cb41c | ||
|
|
64e3c18fb9 | ||
|
|
7e113359b3 | ||
|
|
467802c466 | ||
|
|
ce1b3aaee9 | ||
|
|
1a53bdd584 | ||
|
|
5521e7654d | ||
|
|
73716dd624 | ||
|
|
840d23dcac | ||
|
|
525a0c7c82 | ||
|
|
46c35057fb | ||
|
|
6d03b9763a | ||
|
|
9eaecb0a2a | ||
|
|
c274af839e | ||
|
|
f9232840e4 | ||
|
|
3ea40fda82 | ||
|
|
c357c2614a | ||
|
|
efed6d0eac | ||
|
|
244220f031 | ||
|
|
7ce87575bc | ||
|
|
401cfeda65 | ||
|
|
a45a8c7742 | ||
|
|
c80b360918 | ||
|
|
8514ef6ef8 | ||
|
|
9b1dc34ea1 | ||
|
|
f5490321e7 | ||
|
|
1f4393e3b2 | ||
|
|
8aa6a16a27 | ||
|
|
286f553a54 | ||
|
|
f0ec50e37b | ||
|
|
c1ee0332e3 | ||
|
|
d2737f2b40 | ||
|
|
0d501ec38a | ||
|
|
d39e6421fe | ||
|
|
c2125947ab | ||
|
|
953a33a6ff | ||
|
|
883e7884c4 | ||
|
|
508903c3b1 | ||
|
|
9116063d3f | ||
|
|
e2a0d2d01e | ||
|
|
5343949254 | ||
|
|
c17454b124 | ||
|
|
4f8dc5dc2a | ||
|
|
0fea47bb69 | ||
|
|
47665fcd70 | ||
|
|
968b073338 | ||
|
|
03582bb59a | ||
|
|
149d3ce2fc | ||
|
|
fe5e151d89 | ||
|
|
06a7341eda | ||
|
|
456ed42e14 | ||
|
|
2337f93df8 | ||
|
|
ad675b05ac | ||
|
|
44f6de9524 | ||
|
|
e25605b898 | ||
|
|
919d14e329 | ||
|
|
8fc64cd1b1 | ||
|
|
028a7d6125 | ||
|
|
60b9a6e2e0 | ||
|
|
9ad515335a | ||
|
|
7593ea53f9 | ||
|
|
07374ba1ed | ||
|
|
2deba01a5f | ||
|
|
3daee90b5b | ||
|
|
c4ba60afbd | ||
|
|
81e9ce10cd | ||
|
|
c4738966fe | ||
|
|
0eedc4e2f8 | ||
|
|
14f9368575 | ||
|
|
394546dee7 | ||
|
|
e86e5c0d80 | ||
|
|
e0b5a62c4f | ||
|
|
7fb42cf655 | ||
|
|
819f6bcf71 | ||
|
|
ad47f8855b | ||
|
|
a50102ef52 | ||
|
|
0b2a0634f5 | ||
|
|
8ea32fee31 | ||
|
|
f0571385d5 | ||
|
|
83318af532 | ||
|
|
860c9b33ef | ||
|
|
ecbd6ae282 | ||
|
|
3ec799d150 | ||
|
|
72715c1a85 | ||
|
|
16d262f6ee | ||
|
|
49850940d6 | ||
|
|
e634fb5022 | ||
|
|
c0726f0634 | ||
|
|
91dc3e5884 | ||
|
|
ba2c3ed5fd | ||
|
|
161f7e3313 | ||
|
|
f2f7afadef | ||
|
|
0898bffb43 | ||
|
|
99dc7bf7f2 | ||
|
|
64acea9018 | ||
|
|
8e05347ba0 | ||
|
|
07e90d37ee | ||
|
|
71bd04e5b2 | ||
|
|
95510279ed | ||
|
|
f1502833b2 | ||
|
|
e6448697d3 | ||
|
|
5a96d6dd96 | ||
|
|
8d6b3d0bd8 | ||
|
|
1fd0cd097f | ||
|
|
421126db38 | ||
|
|
7258a2e972 | ||
|
|
df66ab0339 | ||
|
|
c49d0c7afa | ||
|
|
421b3d6375 | ||
|
|
11ef489225 | ||
|
|
e1da6797c5 | ||
|
|
430c7d1a57 | ||
|
|
d3794c0dd9 | ||
|
|
eef1368083 | ||
|
|
6dfefa04f5 | ||
|
|
8b17d81545 | ||
|
|
ec58ca0f13 | ||
|
|
3fd87f90a2 | ||
|
|
9f268b0f6a | ||
|
|
f857116f75 | ||
|
|
ea78d96bc3 | ||
|
|
0be9e69833 | ||
|
|
8171641e3a | ||
|
|
ee6014a30f | ||
|
|
16c22a3ee5 | ||
|
|
571e48fecf | ||
|
|
973d7c5f34 | ||
|
|
a1c5ca288a | ||
|
|
e330d00565 | ||
|
|
6feeb21e21 | ||
|
|
bb5cf24d5f | ||
|
|
0dda70cca1 | ||
|
|
5e83e03e33 | ||
|
|
d2b3f6c12b | ||
|
|
f5af33b181 | ||
|
|
0da1ed8764 | ||
|
|
8aa6f29c4c | ||
|
|
1b7a4442d3 | ||
|
|
a163df993c | ||
|
|
2787007b9d | ||
|
|
cea2c178b5 | ||
|
|
77a9cd5a9a | ||
|
|
ec3259271e | ||
|
|
ae02abba3b | ||
|
|
bf960f6f32 | ||
|
|
66a1087099 | ||
|
|
c1a431f857 | ||
|
|
dac5279a59 | ||
|
|
a175ea27d7 | ||
|
|
ddac42e21e | ||
|
|
34535ad415 | ||
|
|
c0597e441c | ||
|
|
04b66684dd | ||
|
|
244a2e66f9 | ||
|
|
55b737e730 | ||
|
|
059dacf2a7 | ||
|
|
41f7003747 | ||
|
|
64ba900511 | ||
|
|
e371b4bbd3 | ||
|
|
aa44150525 | ||
|
|
3572be718a | ||
|
|
a56d74814b | ||
|
|
8d41b58635 | ||
|
|
e80f326ee6 | ||
|
|
c5bd64912a | ||
|
|
8a808b616e | ||
|
|
91bb2f2e0b | ||
|
|
aa4e6a0651 | ||
|
|
8e9ff2b289 | ||
|
|
d53ab8540e | ||
|
|
7b133e5b2f | ||
|
|
2b72959935 | ||
|
|
82d0b62631 | ||
|
|
7205e27c8c | ||
|
|
c8d1248d86 | ||
|
|
845e4556ef | ||
|
|
a92bfbde40 | ||
|
|
999b6409b3 | ||
|
|
0ae0be4047 | ||
|
|
fc7029c271 | ||
|
|
307ee117bd | ||
|
|
087d28eb9a | ||
|
|
1deea345bc | ||
|
|
e0fa706f6c | ||
|
|
cf794d2b95 | ||
|
|
391e82bb92 | ||
|
|
83a44b3158 | ||
|
|
8cd0e6c5bf | ||
|
|
619ab00035 | ||
|
|
4ded5c3380 | ||
|
|
85fa2185f8 | ||
|
|
ab39259bbe | ||
|
|
9bf2065d18 | ||
|
|
ceb121d588 | ||
|
|
e7dbc25ca0 | ||
|
|
7386784765 | ||
|
|
9062952539 | ||
|
|
9f0a479c3b | ||
|
|
517b9296dc | ||
|
|
3ca09613e1 | ||
|
|
ba931cbedf | ||
|
|
090b354b23 | ||
|
|
dd30bfde15 | ||
|
|
477735cb3d | ||
|
|
38599f2181 | ||
|
|
bd794fb286 | ||
|
|
ce34b78113 | ||
|
|
b8a87dc6ea | ||
|
|
7bdc30936c | ||
|
|
9e635a7207 | ||
|
|
e5626378ef | ||
|
|
73921c116d | ||
|
|
d4b98ef9dd | ||
|
|
40318f052a | ||
|
|
a130f45c62 | ||
|
|
e687d97660 | ||
|
|
e4a0406fc2 | ||
|
|
ef18c389be | ||
|
|
85099801ab | ||
|
|
3472657f92 | ||
|
|
c197513ff3 | ||
|
|
9dca77c2cf | ||
|
|
f08a7fa21e | ||
|
|
2df56c810d | ||
|
|
8c6098f730 | ||
|
|
1462d4f8d9 | ||
|
|
5bd49304d7 | ||
|
|
f52d648d6f | ||
|
|
987af7eb81 | ||
|
|
f313b6a058 | ||
|
|
99b989bb63 | ||
|
|
7ebbba6ce5 | ||
|
|
c2a6db15a6 | ||
|
|
aa58bcf948 | ||
|
|
fa5b030522 | ||
|
|
3e44049abf | ||
|
|
94c501e71b | ||
|
|
484b2a8900 | ||
|
|
e8ff4fb9a7 | ||
|
|
b89e10fd5c | ||
|
|
d86ea606eb | ||
|
|
2135be12b8 | ||
|
|
ae5d51f2e9 | ||
|
|
6eaf25ff80 | ||
|
|
17c371c15e | ||
|
|
13febc125e | ||
|
|
b0f26acc18 | ||
|
|
8ffa5f15e6 | ||
|
|
f6bcc1ab86 | ||
|
|
a4d6442526 | ||
|
|
b7fac3a5b0 | ||
|
|
64ebf3ed05 | ||
|
|
9933612607 | ||
|
|
22ff072b54 | ||
|
|
73b0a84ad0 | ||
|
|
7b03f953bf | ||
|
|
367d6ff6fc | ||
|
|
ca61fde54b | ||
|
|
f739588c73 | ||
|
|
ce02d782c4 | ||
|
|
a498b11e20 | ||
|
|
ffa5a91cd2 | ||
|
|
ae680ffd5d | ||
|
|
4c17d12fc6 | ||
|
|
0259f1a251 | ||
|
|
04708aeb67 | ||
|
|
a47eb1653e | ||
|
|
10fda39430 | ||
|
|
b2be03cce3 | ||
|
|
84ecf838d4 | ||
|
|
c115796137 | ||
|
|
7e054c8beb | ||
|
|
e8df36998e | ||
|
|
0cc558f757 | ||
|
|
5c9bc074f4 | ||
|
|
d89175ebc8 | ||
|
|
727eb71995 | ||
|
|
3d48c00902 | ||
|
|
963318264c | ||
|
|
d9123799d6 | ||
|
|
6562bcb164 | ||
|
|
4fa8af3b30 | ||
|
|
3f4be4f8ef | ||
|
|
09c7badf4f | ||
|
|
7b9b371cf6 | ||
|
|
25e44e7a45 | ||
|
|
51374729d3 | ||
|
|
5a19f7f574 | ||
|
|
40ac8a1557 | ||
|
|
ca42a3e08e | ||
|
|
3a04357b71 | ||
|
|
078223c1b6 | ||
|
|
3fe7cbf725 | ||
|
|
d6059e42ba | ||
|
|
02c1fbe4fc | ||
|
|
6f8fee47f2 | ||
|
|
6c247b300e | ||
|
|
3627760748 | ||
|
|
f3affb3d4c | ||
|
|
a86ed01ba3 | ||
|
|
d40755eb7c | ||
|
|
ce7599cb02 | ||
|
|
68bf89c522 | ||
|
|
0c5b57ee05 | ||
|
|
69a10da52c | ||
|
|
ab534623c4 | ||
|
|
ae4ea14b35 | ||
|
|
ea3c48af02 | ||
|
|
9df0c023ed | ||
|
|
a5259ebc05 | ||
|
|
add59ad12a | ||
|
|
53eecb4d4c | ||
|
|
77fb47451c | ||
|
|
80ae39c2a7 | ||
|
|
118ce0d550 | ||
|
|
dfd9afceba | ||
|
|
6f7eb93645 | ||
|
|
a5268cbd24 | ||
|
|
c732ed66b2 | ||
|
|
10981f706f | ||
|
|
d61218d7e2 | ||
|
|
615032bc25 | ||
|
|
ea70be07a2 | ||
|
|
1884d3d23c | ||
|
|
3f036cca5e | ||
|
|
3e02fe340b | ||
|
|
50d62f1505 | ||
|
|
60511ace99 |
No files matched your search
@@ -2,6 +2,8 @@ name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
@@ -27,19 +29,6 @@ jobs:
|
||||
name: "Building for platform linux-${{matrix.architecture.name}}"
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
# container:
|
||||
# image: ubuntu:22.04
|
||||
# volumes:
|
||||
# - ${{github.workspace}}:${{github.workspace}}
|
||||
#
|
||||
# steps:
|
||||
# - name: Install required packages
|
||||
# run: apt update && apt install -y clang-15 cmake ninja-build flex bison git
|
||||
#
|
||||
# - name: Install required cross-platform packages (${{ matrix.architecture.triple }})
|
||||
# if: matrix.architecture.name != 'amd64'
|
||||
# run: apt install -y gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
|
||||
|
||||
steps:
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
@@ -54,22 +43,18 @@ jobs:
|
||||
- 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 }}
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo Using triple: ${{ matrix.architecture.triple }}
|
||||
mkdir -p thirdparties && cd thirdparties
|
||||
git clone --depth 1 --single-branch --branch SDL2 https://github.com/libsdl-org/SDL.git
|
||||
cmake -B SDL-build \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/SDL-install' \
|
||||
./SDL
|
||||
cmake --build SDL-build --config Release
|
||||
cmake --install SDL-build
|
||||
|
||||
# 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 }}"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -84,9 +69,7 @@ jobs:
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
|
||||
-DSDL2_DIR='${{github.workspace}}/thirdparties/SDL-install/lib/cmake/SDL2' \
|
||||
-DWITH_CLIENT=1" >> $GITHUB_ENV
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
@@ -111,7 +94,7 @@ jobs:
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
cp '${{github.workspace}}/thirdparties/SDL-install/lib/libSDL2.so' '${{github.workspace}}/install'
|
||||
cp '${{steps.sdl.outputs.prefix}}/lib/libSDL2.so' '${{github.workspace}}/install'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@@ -138,14 +121,19 @@ jobs:
|
||||
run: |
|
||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
|
||||
|
||||
- name: Install required packages
|
||||
# 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 SDL2 https://github.com/libsdl-org/SDL.git
|
||||
cmake -B SDL-build -A ${{ matrix.architecture.config }} -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/SDL-install' ./SDL
|
||||
cmake --build SDL-build --config Release --parallel
|
||||
cmake --install SDL-build
|
||||
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
|
||||
@@ -161,13 +149,9 @@ jobs:
|
||||
--log-level=VERBOSE `
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
|
||||
-DCMAKE_C_COMPILER=clang `
|
||||
-DCMAKE_CXX_COMPILER=clang++ `
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
|
||||
-DSDL2_DIR='${{github.workspace}}/thirdparties/SDL-install/cmake' `
|
||||
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
|
||||
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe' `
|
||||
-DWITH_CLIENT=1".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
|
||||
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
@@ -192,7 +176,7 @@ jobs:
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
Copy-Item "${{github.workspace}}/thirdparties/SDL-install/bin/*.dll" -Destination "${{github.workspace}}/install"
|
||||
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
||||
@@ -43,6 +43,13 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: sdl2-latest
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
|
||||
@@ -18,6 +18,9 @@ jobs:
|
||||
|
||||
deploy_all:
|
||||
strategy:
|
||||
# Set the maximum number of parallel jobs to 1, to avoid a race-condition
|
||||
# while creating a new release
|
||||
max-parallel: 1
|
||||
matrix:
|
||||
target_os: [
|
||||
'linux-amd64',
|
||||
|
||||
+2
-1
@@ -44,5 +44,6 @@ profile
|
||||
*.suo
|
||||
|
||||
.vs
|
||||
out
|
||||
code_unfinished/*
|
||||
thirdparties/
|
||||
code/parser/generated/*
|
||||
+30
-17
@@ -11,16 +11,37 @@ if(TARGET_GAME_TYPE)
|
||||
endif()
|
||||
|
||||
|
||||
set(TARGET_BASE_GAME "main")
|
||||
set(TARGET_BASE_GAME "./")
|
||||
set(CMAKE_DEBUG_POSTFIX "-dbg")
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# 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")
|
||||
add_compile_options(-Wno-comment)
|
||||
# Treat no return type as error
|
||||
add_compile_options(-Werror=return-type)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Ignore warnings for code like 'assert("Assert string")'
|
||||
add_compile_options(-Wno-pointer-bool-conversion)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
# Add this option on gcc to prevent functions from having the STB_GNU_UNIQUE binding
|
||||
# Otherwise, it would prevent libraries from being unloaded
|
||||
# which will cause undefined behavior and crashes due to memory corruption
|
||||
add_compile_options(-fno-gnu-unique)
|
||||
endif()
|
||||
|
||||
if(DEBUG_MEMORY)
|
||||
add_definitions(-D_DEBUG_MEM)
|
||||
endif()
|
||||
|
||||
IF("${TARGET_ARCH}" STREQUAL "i386")
|
||||
set(TARGET_ARCH_SUFFIX "x86")
|
||||
ELSE()
|
||||
@@ -40,16 +61,14 @@ ELSE()
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(TARGET_CONFIG_SUFFIX "-dbg")
|
||||
add_definitions(-D_DEBUG)
|
||||
|
||||
# NOTE: The following may mess up function importation
|
||||
#if(UNIX)
|
||||
# # Enable all exports so all functions name can be seen during executable crash
|
||||
# set(CMAKE_ENABLE_EXPORTS ON)
|
||||
# message(STATUS "Enabling exports on Unix for backtrace")
|
||||
#endif()
|
||||
ELSE()
|
||||
set(TARGET_CONFIG_SUFFIX "")
|
||||
ENDIF()
|
||||
|
||||
# Common stuff
|
||||
@@ -71,9 +90,11 @@ target_compile_features(omohaaded PUBLIC c_variadic_macros)
|
||||
target_link_libraries(omohaaded PRIVATE omohserver)
|
||||
target_link_libraries(omohaaded PRIVATE syslib)
|
||||
target_link_libraries(omohaaded PRIVATE qcommon qcommon_standalone)
|
||||
|
||||
# Gamespy dependency
|
||||
target_include_directories(omohaaded PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server")
|
||||
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
|
||||
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(omohaaded PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
|
||||
if (MSVC)
|
||||
target_link_options(omohaaded PRIVATE "/MANIFEST:NO")
|
||||
@@ -82,7 +103,7 @@ endif()
|
||||
|
||||
INSTALL(TARGETS omohaaded DESTINATION "./")
|
||||
|
||||
if (WITH_CLIENT)
|
||||
if (NOT BUILD_NO_CLIENT)
|
||||
## Client app
|
||||
|
||||
add_subdirectory("code/renderer")
|
||||
@@ -103,18 +124,10 @@ if (WITH_CLIENT)
|
||||
|
||||
### 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}${TARGET_CONFIG_SUFFIX}")
|
||||
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(openmohaa PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
|
||||
target_link_libraries(openmohaa PRIVATE jpeg8)
|
||||
if (USE_OPENAL)
|
||||
# Try to use OpenAL
|
||||
find_package(OpenAL)
|
||||
if (OPENAL_FOUND)
|
||||
target_compile_definitions(openmohaa PRIVATE USE_OPENAL=1)
|
||||
target_include_directories(openmohaa PRIVATE ${OPENAL_INCLUDE_DIR})
|
||||
target_link_libraries(openmohaa PRIVATE ${OPENAL_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
|
||||
|
||||
@@ -15,100 +15,48 @@
|
||||
|_|
|
||||
```
|
||||
|
||||
## Current State
|
||||
## Intro
|
||||
|
||||
OpenMoHAA is still in its early days. The singleplayer part is not working correctly, the current usage is multiplayer.
|
||||
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault**. It has always been a dream in the community to provide patches and security fixes for the game. Thanks to the ioquake3 project, F.A.K.K SDK and other quality tools, OpenMoHAA has already reached more than half of its goal: to create an open-source version of MoH:AA (based on version 2.40) that is fully compatible with the original game (in terms of protocol, assets, and scripts).
|
||||
|
||||
## Running
|
||||
## Getting started
|
||||
|
||||
Backup existing mohaa files, **cgamex86.dll** and **gamex86.dll** (set their extension to **.bak**)
|
||||
- [Installing OpenMoHAA](docs/getting_started_installation.md)
|
||||
- [Running OpenMoHAA and using expansion assets](docs/getting_started_running.md)
|
||||
|
||||
a) extract archive to your MOHAA installation directory.
|
||||
## Current state
|
||||
|
||||
-or-
|
||||
### Multiplayer
|
||||
|
||||
b) Copy all pak*.pk3 files and the sound/ directory from your **MOHAA/main** directory into openmohaa's 'main' directory.
|
||||
The Multiplayer part is almost fully stable.
|
||||
|
||||
If you have problems running the game :
|
||||
Server admins can use OpenMoHAA to [host](docs/getting_started_installation.md#server) a mohaa/mohaas/mohaab server. Bugs must be reported by creating a new [issue](https://github.com/openmoh/openmohaa/issues) on the OpenMoHAA GitHub project. Players can use OpenMoHAA to [play](docs/getting_started_installation.md#client) on a mohaa/mohaas/mohaab server.
|
||||
|
||||
You may need to install Microsoft Visual C++ 2015/2017/2019/2022 Redistributable from
|
||||
All game modes including `Tug-of-War` from Medal of Honor: Spearhead, and `Liberation` from Medal of Honor: Breakthrough are implemented and are working as intended. Mods like `Freeze-Tag` are working as well.
|
||||
|
||||
https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
|
||||
### Single-player
|
||||
|
||||
You can now start a local OpenMOHAA server or play on a server.
|
||||
The `training` map can be played from start to end. The single-player campaign is not fully functional, but at least AI can breathe, talk, run, and shoot.
|
||||
|
||||
To play expansions, append to the executable `+set com_target_game 1` for Spearhead, and `+set com_target_game 2` for Breakthrough. On windows you can make a shortcut.
|
||||
## Features
|
||||
|
||||
## Builds
|
||||
|
||||
### Server
|
||||
|
||||
The server version can successfully be built.
|
||||
Some stuff are not working as intended, such as Actor or Vehicle. These systems are both almost fully implemented, but not really in stable state.
|
||||
|
||||
Overall the server part and the game module are almost fully implemented, but the stability may vary, there may be some minor bugs and crashes.
|
||||
|
||||
### Client
|
||||
|
||||
The client version of OpenMoHAA is partially implemented and not stable currently. The cgame module is partially implemented as well, but is compatible with the original MOH:AA game. Credits to **Heavy Metal: F.A.K.K. 2**'s SDK for the cgame module.
|
||||
|
||||
Here is the current working state for each part of the engine:
|
||||
|
||||
| Part name | Full | Almost | Half | Early | Bad | Not working | Comment |
|
||||
|-------------------------|------|--------|------|-------|-----|-------------|-------------------------------------------------------------------|
|
||||
| Audio | | | | | x | | Very basic implementation from Quake III |
|
||||
| CG Module | | x | | | | | Missing FX, Marks and decals |
|
||||
| Client | | | x | | | | Missing GameSpy, server list, binds, map picker, ... |
|
||||
| Collision | x | | | | | | |
|
||||
| Model/TIKI/Skeletor | x | | | | | | |
|
||||
| Renderer | | | | x | | | Missing ghost, marks, sphere lights, sky portal, sun flare, swipe |
|
||||
| Server | | x | | | | | Probably a few bugs remaining |
|
||||
| Server module (fgame) | | x | | | | | Actor, vehicle, and few gameplay bugs |
|
||||
| UI | | | | x | | | Has core features only (menu, widgets, console, hud, urc loading) |
|
||||
|
||||
**Medal of Honor: Allied Assault Spearhead** and **Medal of Honor: Allied Assault Breakthrough** are supported in OpenMoHAA with the `com_target_game` variable. See the **Running** section for the usage.
|
||||
- [What's working and what's not](docs/features_implementation.md)
|
||||
- [New features](docs/features.md)
|
||||
- [Scripting commands](https://htmlpreview.github.io/?https://github.com/openmoh/openmohaa/blob/main/docs/features_g_allclasses.html)
|
||||
|
||||
## Compiling
|
||||
|
||||
OpenMoHAA supports both x86 and x64 architectures, and although the target platform is Windows, it still can be compiled for other platforms, and even other architectures.
|
||||
|
||||
These are the tools required for all platforms :
|
||||
- CMake >= 3.5
|
||||
- Flex and Bison (currently not used)
|
||||
- A C++11 compiler is required.
|
||||
|
||||
The installation directory can be set to MOHAA directory.
|
||||
|
||||
The client build can be built by adding `-DWITH_CLIENT=1` to the CMake command line. This will compile the cgame module and the full app with rendering, ui and sound suppport, alongside the dedicated server version.
|
||||
|
||||
### Linux
|
||||
|
||||
These are the tools required on Unix :
|
||||
- Clang >= 3.3 or GCC >= 4.8.1
|
||||
|
||||
**clang-3.5** and **gcc-4.8.5** should work (tested on Ubuntu 16.04). Use the latest possible version of those compilers.
|
||||
|
||||
SDL2 library is required (libsdl2-dev).
|
||||
|
||||
1 line install command with latest clang version : `sudo apt-get install -y ninja-build cmake make clang-15 lld-15 flex bison libsdl2-dev`
|
||||
|
||||
Example with **CMake**, **clang-15** and **ninja-build** installed:
|
||||
```sh
|
||||
mkdir .cmake && cd .cmake
|
||||
cmake -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 -DWITH_CLIENT=1 -G Ninja
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
Visual Studio (2019 or 2022) is generally preferred.
|
||||
- See [Compiling OpenMoHAA](docs/compiling.md)
|
||||
|
||||
## Screenshots
|
||||
|
||||
| | |
|
||||
|-------------------------------------------------------------------------------|-----------------------------------------------------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
| | |
|
||||
|-----------------------------------------------------------------------------------|----------------------------------------------------------------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
*More screenshots [here](docs/images)*
|
||||
|
||||
## Third party
|
||||
|
||||
@@ -116,20 +64,14 @@ Visual Studio (2019 or 2022) is generally preferred.
|
||||
|
||||
http://www.libsdl.org/
|
||||
|
||||
download Source code, compile
|
||||
|
||||
### OpenAL
|
||||
|
||||
https://www.openal.org/ download OpenAL soft source
|
||||
|
||||
run cmake on OpenAL, compile
|
||||
https://www.openal.org/
|
||||
|
||||
### LibMAD
|
||||
|
||||
http://www.underbit.com/products/mad/
|
||||
|
||||
download source code, compile
|
||||
|
||||
### cURL
|
||||
|
||||
https://curl.se/
|
||||
|
||||
+24
-16
@@ -1,36 +1,44 @@
|
||||
set(archdetect_c_code "
|
||||
#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||
#error cmake_ARCH x86
|
||||
# error cmake_ARCH x86
|
||||
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
|
||||
#error cmake_ARCH x86_64
|
||||
# error cmake_ARCH x86_64
|
||||
#elif defined(__ppc64__) || defined(__powerpc64__)
|
||||
#error cmake_ARCH ppc64
|
||||
# error cmake_ARCH ppc64
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__)
|
||||
#error cmake_ARCH ppc
|
||||
# error cmake_ARCH ppc
|
||||
#elif defined __s390__
|
||||
#error cmake_ARCH s390
|
||||
# error cmake_ARCH s390
|
||||
#elif defined __s390x__
|
||||
#error cmake_ARCH s390x
|
||||
# error cmake_ARCH s390x
|
||||
#elif defined __ia64__
|
||||
#error cmake_ARCH ia64
|
||||
# error cmake_ARCH ia64
|
||||
#elif defined __e2k__
|
||||
# error cmake_ARCH e2k
|
||||
#elif defined __alpha__
|
||||
#error cmake_ARCH alpha
|
||||
# error cmake_ARCH alpha
|
||||
#elif defined __sparc__
|
||||
#error cmake_ARCH sparc
|
||||
# error cmake_ARCH sparc
|
||||
#elif defined __arm__ || defined (_M_ARM)
|
||||
#error cmake_ARCH arm
|
||||
# error cmake_ARCH arm
|
||||
#elif defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
|
||||
#error cmake_ARCH aarch64
|
||||
# error cmake_ARCH aarch64
|
||||
#elif defined __cris__
|
||||
#error cmake_ARCH cris
|
||||
# error cmake_ARCH cris
|
||||
#elif defined __hppa__
|
||||
#error cmake_ARCH hppa
|
||||
# error cmake_ARCH hppa
|
||||
#elif defined __mips__
|
||||
#error cmake_ARCH mips
|
||||
# error cmake_ARCH mips
|
||||
#elif defined __sh__
|
||||
#error cmake_ARCH sh
|
||||
# error cmake_ARCH sh
|
||||
#elif defined __riscv
|
||||
# if __UINTPTR_MAX__ == __UINT64_MAX__
|
||||
# error cmake_ARCH riscv64
|
||||
# else
|
||||
# error cmake_ARCH riscv
|
||||
# endif
|
||||
#else
|
||||
#error cmake_ARCH unknown
|
||||
# error cmake_ARCH unknown
|
||||
#endif
|
||||
|
||||
")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(fgame)
|
||||
project(cgame)
|
||||
|
||||
# Shared source files for modules
|
||||
set(SOURCES_SHARED
|
||||
@@ -18,7 +18,7 @@ set(SOURCES_SHARED
|
||||
"../script/scriptvariable.cpp"
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SOURCES_BG "../fgame/bg_misc.cpp" "../fgame/bg_pmove.cpp" "../fgame/bg_slidemove.cpp")
|
||||
file(GLOB_RECURSE SOURCES_BG "../fgame/bg_misc.cpp" "../fgame/bg_pmove.cpp" "../fgame/bg_slidemove.cpp" "../fgame/bg_voteoptions.cpp")
|
||||
file(GLOB_RECURSE SOURCES_CGAME "./*.c" "./*.cpp")
|
||||
|
||||
add_library(cgame SHARED ${SOURCES_CGAME} ${SOURCES_BG})
|
||||
@@ -28,13 +28,13 @@ 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}${TARGET_CONFIG_SUFFIX}")
|
||||
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(cgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
|
||||
|
||||
INSTALL(
|
||||
TARGETS cgame
|
||||
DESTINATION "${TARGET_BASE_GAME}"
|
||||
ARCHIVE EXCLUDE_FROM_ALL
|
||||
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
|
||||
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_archive.h"
|
||||
#include "cg_commands.h"
|
||||
#include "memarchiver.h"
|
||||
#include "../qcommon/tiki.h"
|
||||
|
||||
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime)
|
||||
{
|
||||
archiver.SetBaseTime(svsTime);
|
||||
commandManager.ArchiveToMemory(archiver);
|
||||
CG_ArchiveVSSGlobals(archiver);
|
||||
}
|
||||
|
||||
size_t CG_SaveStateToBuffer(void** out, int svsTime)
|
||||
{
|
||||
MemArchiver archiver;
|
||||
size_t size;
|
||||
|
||||
archiver.SetupForWriting(0x200000);
|
||||
CG_ArchiveStuff(archiver, svsTime);
|
||||
size = archiver.BufferSize();
|
||||
if (size && out) {
|
||||
*out = archiver.ConfiscateBuffer();
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
qboolean CG_LoadStateToBuffer(void* state, size_t size, int svsTime)
|
||||
{
|
||||
MemArchiver archiver;
|
||||
|
||||
archiver.SetupForReading((byte*)state, size);
|
||||
CG_ArchiveStuff(archiver, svsTime);
|
||||
|
||||
return archiver.FinishedReading();
|
||||
}
|
||||
|
||||
void CG_ArchiveStringContainer(MemArchiver& archiver, Container<str>* container)
|
||||
{
|
||||
int num;
|
||||
int i;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
str tmp;
|
||||
|
||||
archiver.ArchiveInteger(&num);
|
||||
container->ClearObjectList();
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
container->AddObject(tmp);
|
||||
}
|
||||
} else {
|
||||
num = container->NumObjects();
|
||||
archiver.ArchiveInteger(&num);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
str& tmp = container->ObjectAt(i + 1);
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveTikiPointer(MemArchiver& archiver, dtiki_t** pTiki)
|
||||
{
|
||||
str tmp;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
if (tmp.length()) {
|
||||
*pTiki = cgi.R_Model_GetHandle(cgi.R_RegisterModel(tmp.c_str()));
|
||||
} else {
|
||||
*pTiki = NULL;
|
||||
}
|
||||
} else {
|
||||
if (*pTiki) {
|
||||
tmp = (*pTiki)->name;
|
||||
}
|
||||
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
{
|
||||
str tmp;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
if (tmp.length()) {
|
||||
*handle = cgi.R_RegisterModel(tmp.c_str());
|
||||
} else {
|
||||
*handle = NULL;
|
||||
}
|
||||
} else {
|
||||
if (*handle) {
|
||||
tmp = cgi.R_GetModelName(*handle);
|
||||
} else {
|
||||
tmp = "";
|
||||
}
|
||||
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
{
|
||||
str tmp;
|
||||
|
||||
if (archiver.IsReading()) {
|
||||
archiver.ArchiveString(&tmp);
|
||||
if (tmp.length()) {
|
||||
*handle = cgi.R_RegisterShader(tmp.c_str());
|
||||
} else {
|
||||
*handle = NULL;
|
||||
}
|
||||
} else {
|
||||
if (*handle) {
|
||||
tmp = cgi.R_GetShaderName(*handle);
|
||||
} else {
|
||||
tmp = "";
|
||||
}
|
||||
|
||||
archiver.ArchiveString(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
|
||||
{
|
||||
archiver.ArchiveRaw(&ref->reType, sizeof(ref->reType));
|
||||
archiver.ArchiveInteger(&ref->renderfx);
|
||||
|
||||
CG_ArchiveModelHandle(archiver, &ref->hModel);
|
||||
CG_ArchiveModelHandle(archiver, &ref->hOldModel);
|
||||
|
||||
archiver.ArchiveVec3(ref->lightingOrigin);
|
||||
archiver.ArchiveInteger(&ref->parentEntity);
|
||||
archiver.ArchiveVec3(ref->axis[0]);
|
||||
archiver.ArchiveVec3(ref->axis[1]);
|
||||
archiver.ArchiveVec3(ref->axis[2]);
|
||||
archiver.ArchiveBoolean(&ref->nonNormalizedAxes);
|
||||
archiver.ArchiveVec3(ref->origin);
|
||||
archiver.ArchiveRaw(ref->frameInfo, 192);
|
||||
archiver.ArchiveFloat(&ref->actionWeight);
|
||||
archiver.ArchiveShort(&ref->wasframe);
|
||||
archiver.ArchiveFloat(&ref->scale);
|
||||
archiver.ArchiveVec3(ref->oldorigin);
|
||||
archiver.ArchiveInteger(&ref->skinNum);
|
||||
|
||||
CG_ArchiveShaderHandle(archiver, &ref->customShader);
|
||||
archiver.ArchiveRaw(ref->shaderRGBA, 4);
|
||||
archiver.ArchiveFloat(ref->shaderTexCoord);
|
||||
archiver.ArchiveFloat(&ref->shaderTexCoord[1]);
|
||||
archiver.ArchiveFloat(&ref->shaderTime);
|
||||
|
||||
archiver.ArchiveInteger(&ref->entityNumber);
|
||||
archiver.ArchiveRaw(ref->surfaces, 32);
|
||||
archiver.ArchiveFloat(ref->shader_data);
|
||||
archiver.ArchiveFloat(&ref->shader_data[1]);
|
||||
|
||||
ref->bone_tag = NULL;
|
||||
ref->bone_quat = NULL;
|
||||
ref->of = NULL;
|
||||
ref->nf = NULL;
|
||||
|
||||
CG_ArchiveTikiPointer(archiver, &ref->tiki);
|
||||
|
||||
archiver.ArchiveInteger(&ref->bonestart);
|
||||
archiver.ArchiveInteger(&ref->morphstart);
|
||||
archiver.ArchiveBoolean(&ref->hasMorph);
|
||||
archiver.ArchiveFloat(&ref->radius);
|
||||
archiver.ArchiveFloat(&ref->rotation);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// DESCRIPTION:
|
||||
// Memory archiver
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "../qcommon/container.h"
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
class MemArchiver;
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
size_t CG_SaveStateToBuffer(void** out, int svsTime);
|
||||
qboolean CG_LoadStateToBuffer(void* state, size_t size, int svsTime);
|
||||
|
||||
#ifdef __cplusplus
|
||||
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime);
|
||||
void CG_ArchiveStringContainer(MemArchiver& archiver, Container<str>* container);
|
||||
void CG_ArchiveTikiPointer(MemArchiver& archiver, dtiki_t** pTiki);
|
||||
void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle);
|
||||
void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle);
|
||||
void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+1148
-301
File diff suppressed because it is too large.
Load diff
+95
-19
@@ -116,6 +116,7 @@ TIKI file, similar to ScriptMaster in the server game dll.
|
||||
|
||||
class spawnthing_t;
|
||||
class specialeffect_t;
|
||||
class MemArchiver;
|
||||
|
||||
typedef enum {
|
||||
NOT_RANDOM,
|
||||
@@ -181,6 +182,9 @@ public:
|
||||
float decal_orientation;
|
||||
float decal_radius;
|
||||
float spin_rotation;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline cg_common_data::cg_common_data()
|
||||
@@ -249,6 +253,9 @@ public:
|
||||
spawnthing_t *m_spawnthing;
|
||||
|
||||
void (*touchfcn)(ctempmodel_t *ct, trace_t *trace);
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline ctempmodel_t::ctempmodel_t()
|
||||
@@ -315,8 +322,44 @@ public:
|
||||
int lastPhysicsTime;
|
||||
int lastLightingTime;
|
||||
qboolean lastValid;
|
||||
|
||||
public:
|
||||
cvssource_t();
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline cvssource_t::cvssource_t()
|
||||
: next(NULL)
|
||||
, prev(NULL)
|
||||
, stnext(NULL)
|
||||
, stindex(0)
|
||||
, lastRadius(0)
|
||||
, lastDensity(0)
|
||||
, lastColor {0}
|
||||
, lastLighting {0}
|
||||
, newRadius(0)
|
||||
, newDensity(0)
|
||||
, newColor {0}
|
||||
, newLighting {0}
|
||||
, ooRadius(0)
|
||||
, startAlpha(0)
|
||||
, roll(0)
|
||||
, lifeTime(0)
|
||||
, collisionmask(0)
|
||||
, parent(0)
|
||||
, flags(0)
|
||||
, flags2(0)
|
||||
, smokeType(0)
|
||||
, typeInfo(0)
|
||||
, fadeMult(0)
|
||||
, scaleMult(0)
|
||||
, lastPhysicsTime(0)
|
||||
, lastLightingTime(0)
|
||||
, lastValid(qfalse)
|
||||
{}
|
||||
|
||||
class cvssourcestate_t
|
||||
{
|
||||
public:
|
||||
@@ -387,6 +430,9 @@ public:
|
||||
protected:
|
||||
qboolean usedNumbers[256];
|
||||
virtual void RemoveEntity(int entnum);
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline enttracker_t::enttracker_t()
|
||||
@@ -437,6 +483,9 @@ public:
|
||||
Vector oldorigin;
|
||||
qboolean active;
|
||||
qboolean lerp_emitter;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
// emitterthing_t is used to keep track of the last time and emitter was updated
|
||||
@@ -452,6 +501,9 @@ public:
|
||||
emittertime_t *GetEmitTime(int entnum);
|
||||
virtual void RemoveEntity(int entnum);
|
||||
qboolean startoff;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline void emitterthing_t::RemoveEntity(int entnum)
|
||||
@@ -510,18 +562,23 @@ public:
|
||||
int entity_number;
|
||||
int command_number;
|
||||
int last_command_time;
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
// This class is used for keeping track of the last time an entity executed a
|
||||
// particular command. A command number must be assigned externally by the user
|
||||
class commandthing_t : public enttracker_t
|
||||
{
|
||||
Container<commandtime_t *> m_commandtimes; // A list of entity numbers and the last time they
|
||||
// executed a command
|
||||
Container<commandtime_t> m_commandtimes; // A list of entity numbers and the last time they
|
||||
// executed a command
|
||||
|
||||
public:
|
||||
commandtime_t *GetLastCommandTime(int entnum, int commandnum);
|
||||
virtual void RemoveEntity(int entnum);
|
||||
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline void commandthing_t::RemoveEntity(int entnum)
|
||||
@@ -532,7 +589,7 @@ inline void commandthing_t::RemoveEntity(int entnum)
|
||||
count = m_commandtimes.NumObjects();
|
||||
|
||||
for (num = count; num >= 1; num--) {
|
||||
ct = m_commandtimes.ObjectAt(num);
|
||||
ct = &m_commandtimes.ObjectAt(num);
|
||||
if (ct->entity_number == entnum) {
|
||||
m_commandtimes.RemoveObjectAt(num);
|
||||
}
|
||||
@@ -543,28 +600,27 @@ inline void commandthing_t::RemoveEntity(int entnum)
|
||||
|
||||
inline commandtime_t *commandthing_t::GetLastCommandTime(int entnum, int commandnum)
|
||||
{
|
||||
int num, count;
|
||||
commandtime_t *ct;
|
||||
int num, count;
|
||||
|
||||
// Search for this entity number
|
||||
count = m_commandtimes.NumObjects();
|
||||
|
||||
for (num = 1; num <= count; num++) {
|
||||
ct = m_commandtimes.ObjectAt(num);
|
||||
commandtime_t *ct = &m_commandtimes.ObjectAt(num);
|
||||
if ((ct->entity_number == entnum) && (ct->command_number == commandnum)) {
|
||||
return ct;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new entry if we didn't find it
|
||||
ct = new commandtime_t;
|
||||
ct->entity_number = entnum;
|
||||
ct->command_number = commandnum;
|
||||
ct->last_command_time = 0;
|
||||
commandtime_t ct;
|
||||
ct.entity_number = entnum;
|
||||
ct.command_number = commandnum;
|
||||
ct.last_command_time = 0;
|
||||
|
||||
m_commandtimes.AddObject(ct);
|
||||
|
||||
return ct;
|
||||
return &m_commandtimes.ObjectAt(m_commandtimes.NumObjects());
|
||||
}
|
||||
|
||||
class spawnthing_t : public emitterthing_t
|
||||
@@ -625,6 +681,9 @@ public:
|
||||
void (*touchfcn)(ctempmodel_t *ct, trace_t *trace);
|
||||
str GetModel(void);
|
||||
void SetModel(str model);
|
||||
|
||||
public:
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
inline void spawnthing_t::SetModel(str model)
|
||||
@@ -824,8 +883,8 @@ private:
|
||||
void SetClampVel(Event *ev);
|
||||
void SetClampVelAxis(Event *ev);
|
||||
ctempmodel_t *AllocateTempModel(void);
|
||||
qboolean TempModelPhysics(ctempmodel_t *p, float ftime, float time2, float scale);
|
||||
qboolean TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float time2, float scale);
|
||||
qboolean TempModelPhysics(ctempmodel_t *p, float ftime, float scale);
|
||||
qboolean TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float scale);
|
||||
qboolean LerpTempModel(refEntity_t *newEnt, ctempmodel_t *p, float frac);
|
||||
void SpawnEffect(int count, int timealive);
|
||||
void SpawnTempModel(int count);
|
||||
@@ -871,18 +930,19 @@ public:
|
||||
void UpdateEmitter(dtiki_t *tiki, vec3_t axis[3], int entity_number, int parent_number, Vector entity_origin);
|
||||
void UpdateBeam(dtiki_t *tiki, int entity_number, spawnthing_t *beamthing);
|
||||
void PlaySound(
|
||||
str sound_name,
|
||||
str sound_name,
|
||||
const vec3_t origin = NULL,
|
||||
int channel = CHAN_AUTO,
|
||||
float volume = -1,
|
||||
float min_distance = -1,
|
||||
float pitch = -1,
|
||||
int argstype = 0
|
||||
int channel = CHAN_AUTO,
|
||||
float volume = -1,
|
||||
float min_distance = -1,
|
||||
float pitch = -1,
|
||||
int argstype = 0
|
||||
);
|
||||
|
||||
spawnthing_t *InitializeSpawnthing(spawnthing_t *ep);
|
||||
void SpawnEffect(int count, spawnthing_t *sp);
|
||||
void FreeAllTempModels(void);
|
||||
void FreeSomeTempModels(void);
|
||||
void RestartAllEmitters(void);
|
||||
|
||||
void InitializeTempModels(void);
|
||||
@@ -890,6 +950,7 @@ public:
|
||||
void InitializeEmitters(void);
|
||||
void RemoveClientEntity(int number, dtiki_t *tiki, centity_t *cent, ctempmodel_t *p = NULL);
|
||||
void ClearSwipes(void);
|
||||
void FreeSpawnthing(spawnthing_t *sp);
|
||||
void ResetTempModels(void);
|
||||
void SpawnTempModel(int count, spawnthing_t *sp);
|
||||
|
||||
@@ -920,6 +981,21 @@ public:
|
||||
void ResetTreadMarkSources(Event *ev);
|
||||
void InitializeRainCvars();
|
||||
void InitializeBeams();
|
||||
|
||||
//
|
||||
// archive stuff
|
||||
//
|
||||
int IdForTempModel(const ctempmodel_t *model);
|
||||
ctempmodel_t *TempModelForId(int id);
|
||||
int IdForSpawnThing(const spawnthing_t *sp);
|
||||
spawnthing_t *SpawnThingForId(int id);
|
||||
int IdForVssSource(const cvssource_t *source);
|
||||
cvssource_t *VssSourceForId(int id);
|
||||
|
||||
void ArchiveTempModelPointerToMemory(MemArchiver& archiver, ctempmodel_t **model);
|
||||
void ArchiveSpawnThingPointerToMemory(MemArchiver& archiver, spawnthing_t **sp);
|
||||
void ArchiveVssSourcePointerToMemory(MemArchiver& archiver, cvssource_t **source);
|
||||
void ArchiveToMemory(MemArchiver& archiver);
|
||||
};
|
||||
|
||||
class EmitterLoader : public Listener
|
||||
|
||||
+62
-52
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// text commands typed in at the local console, or executed by a key binding
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "../fgame/bg_voteoptions.h"
|
||||
|
||||
void CG_TargetCommand_f(void);
|
||||
|
||||
@@ -110,8 +111,8 @@ void CG_ScoresDown_f(void)
|
||||
void CG_ScoresUp_f(void)
|
||||
{
|
||||
if (cgs.gametype == GT_SINGLE_PLAYER) {
|
||||
if (!cg.scoresRequestTime) {
|
||||
cg.scoresRequestTime = cg.time;
|
||||
if (cg.scoresRequestTime) {
|
||||
cg.scoresRequestTime = 0;
|
||||
CG_SetDesiredObjectiveAlpha(0.0f);
|
||||
}
|
||||
|
||||
@@ -339,56 +340,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 },
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+180
-16
@@ -323,8 +323,12 @@ static void CG_DrawPauseIcon()
|
||||
}
|
||||
w = cgi.R_GetShaderWidth(handle);
|
||||
h = cgi.R_GetShaderHeight(handle);
|
||||
x = w / 4;
|
||||
y = cgs.glconfig.vidHeight - (1.25f * h);
|
||||
if (cg.snap && cg.snap->ps.blend[3] > 0) {
|
||||
y = cgs.glconfig.vidHeight * 0.45f - h / 2.f;
|
||||
} else {
|
||||
y = cgs.glconfig.vidHeight * 0.75f - h / 2.f;
|
||||
}
|
||||
x = (cgs.glconfig.vidWidth - w) / 2.f;
|
||||
|
||||
cgi.R_SetColor(colorWhite);
|
||||
cgi.R_DrawStretchPic(x, y, w, h, 0, 0, 1, 1, handle);
|
||||
@@ -682,15 +686,16 @@ void CG_DrawObjectives()
|
||||
|
||||
iTotalNumLines = 0;
|
||||
for (i = CS_OBJECTIVES; i < CS_OBJECTIVES + MAX_OBJECTIVES; ++i) {
|
||||
CG_ProcessConfigString(i);
|
||||
CG_ProcessConfigString(i, qfalse);
|
||||
}
|
||||
|
||||
iCurrentObjective = atoi(CG_ConfigString(CS_CURRENT_OBJECTIVE));
|
||||
fTimeDelta = cg.ObjectivesAlphaTime - cg.time;
|
||||
if (fTimeDelta > 0.0) {
|
||||
iCurrentObjective = atoi(CG_ConfigString(CS_CURRENT_OBJECTIVE));
|
||||
fTimeDelta = cg.ObjectivesAlphaTime - cg.time;
|
||||
cg.ObjectivesCurrentAlpha = cg.ObjectivesDesiredAlpha;
|
||||
if (fTimeDelta > 0) {
|
||||
cg.ObjectivesCurrentAlpha =
|
||||
(cg.ObjectivesBaseAlpha - cg.ObjectivesDesiredAlpha) * sin(fTimeDelta * 0.0062831854)
|
||||
+ cg.ObjectivesCurrentAlpha;
|
||||
(cg.ObjectivesBaseAlpha - cg.ObjectivesDesiredAlpha) * sin(fTimeDelta / (M_PI * 50.f + 2.f))
|
||||
+ cg.ObjectivesDesiredAlpha;
|
||||
}
|
||||
|
||||
if (cg.ObjectivesCurrentAlpha < 0.02) {
|
||||
@@ -702,12 +707,12 @@ void CG_DrawObjectives()
|
||||
iNumLines[i] = 0;
|
||||
|
||||
for (ii = 0; ii < MAX_STRING_CHARS; ii++) {
|
||||
if (cg.Objectives[i].text[ii] == 10) {
|
||||
if (cg.Objectives[i].text[ii] == '\n') {
|
||||
iTotalNumLines++;
|
||||
iNumLines[ii]++;
|
||||
iNumLines[i]++;
|
||||
} else if (!cg.Objectives[i].text[ii]) {
|
||||
iTotalNumLines++;
|
||||
iNumLines[ii]++;
|
||||
iNumLines[i]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -740,17 +745,17 @@ void CG_DrawObjectives()
|
||||
for (i = 0; i < MAX_OBJECTIVES; ++i) {
|
||||
qhandle_t hBoxShader;
|
||||
|
||||
if ((cg.Objectives[i].flags & 1) || !cg.Objectives[i].flags) {
|
||||
if ((cg.Objectives[i].flags & OBJ_FLAG_HIDDEN) || !cg.Objectives[i].flags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((cg.Objectives[i].flags & 2) != 0) {
|
||||
if ((cg.Objectives[i].flags & OBJ_FLAG_CURRENT) != 0) {
|
||||
vColor[0] = 1.0;
|
||||
vColor[1] = 1.0;
|
||||
vColor[2] = 1.0;
|
||||
vColor[3] = cg.ObjectivesCurrentAlpha;
|
||||
hBoxShader = cgs.media.uncheckedBoxShader;
|
||||
} else if ((cg.Objectives[i].flags & 4) != 0) {
|
||||
} else if ((cg.Objectives[i].flags & OBJ_FLAG_COMPLETED) != 0) {
|
||||
vColor[0] = 0.75;
|
||||
vColor[1] = 0.75;
|
||||
vColor[2] = 0.75;
|
||||
@@ -763,7 +768,7 @@ void CG_DrawObjectives()
|
||||
vColor[3] = cg.ObjectivesCurrentAlpha;
|
||||
hBoxShader = cgs.media.uncheckedBoxShader;
|
||||
}
|
||||
if (i == iCurrentObjective && (cg.Objectives[i].flags & 4) == 0) {
|
||||
if (i == iCurrentObjective && !(cg.Objectives[i].flags & OBJ_FLAG_COMPLETED)) {
|
||||
vColor[0] = 1.0;
|
||||
vColor[1] = 1.0;
|
||||
vColor[2] = 0.0;
|
||||
@@ -1082,7 +1087,7 @@ void CG_DrawSpectatorView_ver_15()
|
||||
iClientNum = cg.snap->ps.stats[STAT_INFOCLIENT];
|
||||
sprintf(buf, "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]);
|
||||
|
||||
hShader = 0;
|
||||
hShader = 0;
|
||||
color[0] = 0.5;
|
||||
color[1] = 1.0;
|
||||
color[2] = 0.5;
|
||||
@@ -1164,6 +1169,163 @@ void CG_DrawSpectatorView()
|
||||
}
|
||||
}
|
||||
|
||||
void CG_DrawCrosshair()
|
||||
{
|
||||
centity_t *friendEnt;
|
||||
qhandle_t shader;
|
||||
vec3_t forward;
|
||||
vec3_t end;
|
||||
vec3_t mins, maxs;
|
||||
trace_t trace;
|
||||
float x, y;
|
||||
float width, height;
|
||||
|
||||
shader = NULL;
|
||||
|
||||
if (!cg_hud->integer || !ui_crosshair->integer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cg.snap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cg.snap->ps.pm_flags & PMF_NO_LEAN) || (cg.snap->ps.pm_flags & PMF_INTERMISSION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cg.snap->ps.stats[STAT_CROSSHAIR]
|
||||
&& (!cg.snap->ps.stats[STAT_INZOOM] || cg.snap->ps.stats[STAT_INZOOM] > 30)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgs.gametype != GT_FFA) {
|
||||
AngleVectorsLeft(cg.refdefViewAngles, forward, NULL, NULL);
|
||||
|
||||
VectorMA(cg.refdef.vieworg, 8192, forward, end);
|
||||
VectorClear(mins);
|
||||
VectorClear(maxs);
|
||||
|
||||
CG_Trace(&trace, cg.refdef.vieworg, mins, maxs, end, 9999, MASK_SOLID, qfalse, qtrue, "CG_DrawCrosshair");
|
||||
|
||||
// ENTITYNUM_WORLD check added in OPM
|
||||
if ((trace.entityNum != ENTITYNUM_NONE && trace.entityNum != ENTITYNUM_WORLD)
|
||||
&& trace.entityNum != cg.snap->ps.clientNum) {
|
||||
int myFlags;
|
||||
|
||||
friendEnt = &cg_entities[trace.entityNum];
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
myFlags = cg_entities[cg.snap->ps.clientNum].currentState.eFlags & EF_ANY_TEAM;
|
||||
} else {
|
||||
// the player will always be considered as an allied
|
||||
// in single-player
|
||||
myFlags = EF_ALLIES;
|
||||
}
|
||||
|
||||
if (((myFlags & EF_ALLIES) && (friendEnt->currentState.eFlags & EF_ALLIES))
|
||||
|| ((myFlags & EF_AXIS) && (friendEnt->currentState.eFlags & EF_AXIS))) {
|
||||
// friend
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair_friend->string);
|
||||
}
|
||||
} else {
|
||||
// enemy
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// FFA
|
||||
if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
|
||||
shader = cgi.R_RegisterShader(cg_crosshair->string);
|
||||
}
|
||||
}
|
||||
|
||||
if (shader) {
|
||||
width = cgi.R_GetShaderWidth(shader);
|
||||
height = cgi.R_GetShaderHeight(shader);
|
||||
x = (cgs.glconfig.vidWidth - width) * 0.5f;
|
||||
y = (cgs.glconfig.vidHeight - height) * 0.5f;
|
||||
|
||||
cgi.R_SetColor(NULL);
|
||||
cgi.R_DrawStretchPic(x, y, width, height, 0, 0, 1, 1, shader);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_DrawVote()
|
||||
{
|
||||
const char *text;
|
||||
int seconds;
|
||||
int percentYes;
|
||||
int percentNo;
|
||||
int percentUndecided;
|
||||
float x, y;
|
||||
vec4_t col;
|
||||
|
||||
if (!cgs.voteTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgs.voteRefreshed) {
|
||||
cgs.voteRefreshed = qfalse;
|
||||
}
|
||||
|
||||
seconds = (30000 - (cg.time - cgs.voteTime)) / 1000 + 1;
|
||||
if (seconds < 0) {
|
||||
seconds = 0;
|
||||
}
|
||||
|
||||
percentYes = cgs.numVotesYes * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
|
||||
percentNo = cgs.numVotesNo * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
|
||||
percentUndecided = cgs.numUndecidedVotes * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
|
||||
|
||||
x = 8;
|
||||
y = (cgs.glconfig.vidHeight > 480) ? (cgs.glconfig.vidHeight * 0.725f) : (cgs.glconfig.vidHeight * 0.75f);
|
||||
|
||||
cgi.R_SetColor(NULL);
|
||||
|
||||
text = va("%s: %s", cgi.LV_ConvertString("Vote Running"), cgs.voteString);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
|
||||
y += 12;
|
||||
|
||||
text =
|
||||
va("%s: %isec %s: %i%% %s: %i%% %s: %i%%",
|
||||
cgi.LV_ConvertString("Time"),
|
||||
seconds,
|
||||
cgi.LV_ConvertString("Yes"),
|
||||
percentYes,
|
||||
cgi.LV_ConvertString("No"),
|
||||
percentNo,
|
||||
cgi.LV_ConvertString("Undecided"),
|
||||
percentUndecided);
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
|
||||
if (cg.snap && !cg.snap->ps.voted) {
|
||||
col[0] = 0.5;
|
||||
col[1] = 1.0;
|
||||
col[2] = 0.5;
|
||||
col[3] = 1.0;
|
||||
cgi.R_SetColor(col);
|
||||
|
||||
y += 12;
|
||||
|
||||
text = cgi.LV_ConvertString("Vote now, it's your patriotic duty!");
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
|
||||
y += 12;
|
||||
|
||||
text = cgi.LV_ConvertString("To vote Yes, press F1. To vote No, press F2.");
|
||||
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse);
|
||||
cgi.R_SetColor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
CG_Draw2D
|
||||
@@ -1182,5 +1344,7 @@ void CG_Draw2D(void)
|
||||
CG_DrawPlayerTeam();
|
||||
CG_DrawPlayerEntInfo();
|
||||
CG_UpdateAttackerDisplay();
|
||||
CG_DrawVote();
|
||||
CG_DrawInstantMessageMenu();
|
||||
CG_DrawCrosshair();
|
||||
}
|
||||
@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// cg_ents.c -- present snapshot entities, happens every single frame
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_radar.h"
|
||||
|
||||
/*
|
||||
==========================================================================
|
||||
@@ -551,7 +552,10 @@ void CG_AddCEntity(centity_t *cent)
|
||||
break;
|
||||
case ET_PLAYER:
|
||||
CG_Player(cent);
|
||||
CG_Splash(cent);
|
||||
CG_Splash(cent);
|
||||
CG_ModelAnim(cent, qfalse);
|
||||
CG_UpdateRadarClient(cent);
|
||||
break;
|
||||
case ET_ITEM:
|
||||
CG_ModelAnim(cent, qfalse);
|
||||
break;
|
||||
@@ -666,7 +670,6 @@ void CG_GetOrigin(centity_t *cent, vec3_t origin)
|
||||
parent = cgi.R_GetRenderEntity(cent->currentState.parent);
|
||||
|
||||
if (!parent) {
|
||||
cgi.DPrintf("CG_GetOrigin: Could not find parent entity\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+26
-2
@@ -35,6 +35,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "cg_public.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
class MemArchiver;
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -341,7 +343,9 @@ extern "C" {
|
||||
|
||||
// misc
|
||||
crain_t rain;
|
||||
clientInfo_t clientinfo[MAX_CLIENTS];
|
||||
clientInfo_t clientinfo[MAX_CLIENTS];
|
||||
radarClient_t radars[MAX_CLIENTS];
|
||||
qhandle_t radarShaders[2];
|
||||
} cg_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -392,8 +396,19 @@ extern "C" {
|
||||
int maxclients;
|
||||
int cinematic;
|
||||
int mapChecksum;
|
||||
qboolean useMapChecksum;
|
||||
char mapname[MAX_QPATH];
|
||||
|
||||
//
|
||||
// vote
|
||||
//
|
||||
int voteTime;
|
||||
int numVotesYes;
|
||||
int numVotesNo;
|
||||
int numUndecidedVotes;
|
||||
qboolean voteRefreshed;
|
||||
char voteString[1024];
|
||||
|
||||
//
|
||||
// locally derived information from gamestate
|
||||
//
|
||||
@@ -456,6 +471,9 @@ extern "C" {
|
||||
extern cvar_t *cg_hud;
|
||||
extern cvar_t *cg_huddraw_force;
|
||||
extern cvar_t *cg_drawsvlag;
|
||||
extern cvar_t *cg_crosshair;
|
||||
extern cvar_t *cg_crosshair_friend;
|
||||
extern cvar_t *ui_crosshair;
|
||||
extern cvar_t *vm_offset_max;
|
||||
extern cvar_t *vm_offset_speed;
|
||||
extern cvar_t *vm_sway_front;
|
||||
@@ -486,7 +504,7 @@ extern "C" {
|
||||
//
|
||||
// cg_main.c
|
||||
//
|
||||
void CG_ProcessConfigString(int num);
|
||||
void CG_ProcessConfigString(int num, qboolean modelOnly);
|
||||
const char *CG_ConfigString(int index);
|
||||
void CG_AddToTeamChat(const char *str);
|
||||
void CG_NewClientinfo(int clientNum);
|
||||
@@ -519,6 +537,7 @@ extern "C" {
|
||||
void CG_EndTiki(dtiki_t *tiki);
|
||||
qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *curTiki);
|
||||
void CG_RestartCommandManager();
|
||||
void CG_CleanUpTempModels();
|
||||
qboolean CG_ProcessEntityCommands(int frame, int anim, int entnum, refEntity_t *ent, centity_t *cent);
|
||||
void CG_ClientCommands(refEntity_t *ent, centity_t *cent, int slot);
|
||||
float RandomizeRange(float start, float end);
|
||||
@@ -527,6 +546,8 @@ extern "C" {
|
||||
// cg_tempmodels.cpp
|
||||
//
|
||||
extern cvar_t *cg_showtempmodels;
|
||||
extern cvar_t *cg_max_tempmodels;
|
||||
extern cvar_t *cg_reserve_tempmodels;
|
||||
extern cvar_t *cg_detail;
|
||||
extern cvar_t *cg_effectdetail;
|
||||
extern cvar_t *cg_effect_physicsrate;
|
||||
@@ -908,6 +929,9 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
|
||||
//
|
||||
// cg_volumetricsmoke.cpp
|
||||
void CG_ResetVSSSources(void);
|
||||
#ifdef __cplusplus
|
||||
void CG_ArchiveVSSGlobals(MemArchiver& archiver);
|
||||
#endif
|
||||
void CG_AddVSSSources(void);
|
||||
|
||||
extern cvar_t *vss_draw;
|
||||
|
||||
+205
-122
@@ -25,6 +25,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_parsemsg.h"
|
||||
#include "cg_archive.h"
|
||||
#include "cg_radar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
@@ -78,6 +80,9 @@ cvar_t *cg_acidtrip;
|
||||
cvar_t *cg_hud;
|
||||
cvar_t *cg_huddraw_force;
|
||||
cvar_t *cg_drawsvlag;
|
||||
cvar_t *cg_crosshair;
|
||||
cvar_t *cg_crosshair_friend;
|
||||
cvar_t *ui_crosshair;
|
||||
cvar_t *vm_offset_max;
|
||||
cvar_t *vm_offset_speed;
|
||||
cvar_t *vm_sway_front;
|
||||
@@ -157,6 +162,15 @@ void CG_RegisterCvars(void)
|
||||
cg_hud = cgi.Cvar_Get("cg_hud", "0", 0);
|
||||
cg_huddraw_force = cgi.Cvar_Get("cg_huddraw_force", "0", CVAR_SAVEGAME);
|
||||
cg_drawsvlag = cgi.Cvar_Get("cg_drawsvlag", "1", CVAR_ARCHIVE);
|
||||
cg_crosshair = cgi.Cvar_Get("cg_crosshair", "textures/hud/crosshair", CVAR_ARCHIVE);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cg_crosshair_friend = cgi.Cvar_Get("cg_crosshair_friend", "textures/hud/crosshair_friend", CVAR_ARCHIVE);
|
||||
} else {
|
||||
// on 1.11 and below, fallback to standard crosshair
|
||||
// as it doesn't have crosshair_friend texture
|
||||
cg_crosshair_friend = cgi.Cvar_Get("cg_crosshair_friend", "textures/hud/crosshair", CVAR_ARCHIVE);
|
||||
}
|
||||
ui_crosshair = cgi.Cvar_Get("ui_crosshair", "1", CVAR_ARCHIVE);
|
||||
vm_offset_max = cgi.Cvar_Get("vm_offset_max", "8.0", 0);
|
||||
vm_offset_speed = cgi.Cvar_Get("vm_offset_speed", "8.0", 0);
|
||||
vm_sway_front = cgi.Cvar_Get("vm_sway_front", "0.1", 0);
|
||||
@@ -231,91 +245,48 @@ void CG_RegisterSounds(void)
|
||||
Com_Printf("-------------UBERDIALOG DONE---------------\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_IsHandleUnique
|
||||
|
||||
Check if the model handle is unique
|
||||
================
|
||||
*/
|
||||
static qboolean CG_IsHandleUnique(int num) {
|
||||
qhandle_t handle;
|
||||
int i;
|
||||
int numRef;
|
||||
|
||||
numRef = 0;
|
||||
handle = cgs.model_draw[num];
|
||||
for (i = 0; i < MAX_MODELS; i++) {
|
||||
if (cgs.model_draw[i] == handle) {
|
||||
numRef++;
|
||||
if (numRef >= 2) {
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_ProcessConfigString
|
||||
================
|
||||
*/
|
||||
void CG_ProcessConfigString(int num)
|
||||
void CG_ProcessConfigString(int num, qboolean modelOnly)
|
||||
{
|
||||
const char *str = CG_ConfigString(num);
|
||||
int i;
|
||||
const char* str;
|
||||
int i;
|
||||
|
||||
switch (num) {
|
||||
case CS_RAIN_DENSITY:
|
||||
cg.rain.density = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEED:
|
||||
cg.rain.speed = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEEDVARY:
|
||||
cg.rain.speed_vary = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_SLANT:
|
||||
cg.rain.slant = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_LENGTH:
|
||||
cg.rain.length = atof(str);
|
||||
return;
|
||||
case CS_RAIN_MINDIST:
|
||||
cg.rain.min_dist = atof(str);
|
||||
return;
|
||||
case CS_RAIN_WIDTH:
|
||||
cg.rain.width = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SHADER:
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
}
|
||||
} else {
|
||||
strcpy(cg.rain.shader[0], str);
|
||||
}
|
||||
return;
|
||||
case CS_RAIN_NUMSHADERS:
|
||||
cg.rain.numshaders = atoi(str);
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
|
||||
cobjective_t *objective = &cg.Objectives[num - CS_OBJECTIVES];
|
||||
objective->flags = atoi(Info_ValueForKey(str, "flags"));
|
||||
strcpy(objective->text, Info_ValueForKey(str, "text"));
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
case CS_MUSIC:
|
||||
cgi.MUSIC_NewSoundtrack(str);
|
||||
return;
|
||||
case CS_WARMUP:
|
||||
cg.matchStartTime = atoi(str);
|
||||
return;
|
||||
case CS_FOGINFO:
|
||||
CG_ParseFogInfo(str);
|
||||
return;
|
||||
case CS_SKYINFO:
|
||||
sscanf(str, "%f %d", &cg.sky_alpha, &cg.sky_portal);
|
||||
return;
|
||||
case CS_SERVERINFO:
|
||||
CG_ParseServerinfo();
|
||||
return;
|
||||
case CS_LEVEL_START_TIME:
|
||||
cgs.levelStartTime = atoi(str);
|
||||
return;
|
||||
case CS_MATCHEND:
|
||||
cgs.matchEndTime = atoi(str);
|
||||
return;
|
||||
}
|
||||
str = CG_ConfigString(num);
|
||||
|
||||
if (num >= CS_MODELS && num < CS_MODELS + MAX_MODELS) {
|
||||
qhandle_t hOldModel = cgs.model_draw[num - CS_MODELS];
|
||||
|
||||
if (str && str[0]) {
|
||||
if (str && str[0] && !modelOnly) {
|
||||
qhandle_t hModel = cgi.R_RegisterServerModel(str);
|
||||
dtiki_t *tiki;
|
||||
|
||||
@@ -332,43 +303,142 @@ void CG_ProcessConfigString(int num)
|
||||
}
|
||||
} else {
|
||||
// clear out the model
|
||||
if (hOldModel) {
|
||||
if (hOldModel && CG_IsHandleUnique(hOldModel)) {
|
||||
// Handle uniqueness added in OPM
|
||||
cgi.R_UnregisterServerModel(hOldModel);
|
||||
}
|
||||
cgs.model_draw[num - CS_MODELS] = 0;
|
||||
}
|
||||
} else if (num >= CS_SOUNDS && num < CS_SOUNDS + MAX_SOUNDS) {
|
||||
size_t len = strlen(str);
|
||||
if (len) {
|
||||
qboolean streamed;
|
||||
char buf[1024];
|
||||
strcpy(buf, str);
|
||||
}
|
||||
|
||||
streamed = buf[len - 1] != '0';
|
||||
buf[len - 1] = 0;
|
||||
if (buf[0] != '*') {
|
||||
cgs.sound_precache[num - CS_SOUNDS] = cgi.S_RegisterSound(buf, streamed);
|
||||
if (!modelOnly) {
|
||||
switch (num) {
|
||||
case CS_RAIN_DENSITY:
|
||||
cg.rain.density = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEED:
|
||||
cg.rain.speed = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SPEEDVARY:
|
||||
cg.rain.speed_vary = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_SLANT:
|
||||
cg.rain.slant = atoi(str);
|
||||
return;
|
||||
case CS_RAIN_LENGTH:
|
||||
cg.rain.length = atof(str);
|
||||
return;
|
||||
case CS_RAIN_MINDIST:
|
||||
cg.rain.min_dist = atof(str);
|
||||
return;
|
||||
case CS_RAIN_WIDTH:
|
||||
cg.rain.width = atof(str);
|
||||
return;
|
||||
case CS_RAIN_SHADER:
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
}
|
||||
} else {
|
||||
strcpy(cg.rain.shader[0], str);
|
||||
}
|
||||
}
|
||||
} else if (num >= CS_LIGHTSTYLES && num < CS_LIGHTSTYLES + MAX_LIGHTSTYLES) {
|
||||
CG_SetLightStyle(num - CS_LIGHTSTYLES, str);
|
||||
} else if (num >= CS_PLAYERS && num < CS_PLAYERS + MAX_CLIENTS) {
|
||||
const char *value;
|
||||
|
||||
value = Info_ValueForKey(str, "name");
|
||||
if (value) {
|
||||
strncpy(cg.clientinfo[num - CS_PLAYERS].name, value, sizeof(cg.clientinfo[num - CS_PLAYERS].name));
|
||||
} else {
|
||||
strncpy(
|
||||
cg.clientinfo[num - CS_PLAYERS].name, "UnnamedSoldier", sizeof(cg.clientinfo[num - CS_PLAYERS].name)
|
||||
);
|
||||
return;
|
||||
case CS_RAIN_NUMSHADERS:
|
||||
cg.rain.numshaders = atoi(str);
|
||||
if (cg.rain.numshaders) {
|
||||
for (i = 0; i < cg.rain.numshaders; i++) {
|
||||
sprintf(cg.rain.shader[i], "%s%i", str, i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
value = Info_ValueForKey(str, "team");
|
||||
if (value) {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = atoi(value);
|
||||
} else {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = TEAM_NONE;
|
||||
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
|
||||
cobjective_t *objective = &cg.Objectives[num - CS_OBJECTIVES];
|
||||
objective->flags = atoi(Info_ValueForKey(str, "flags"));
|
||||
strcpy(objective->text, Info_ValueForKey(str, "text"));
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
case CS_MUSIC:
|
||||
cgi.MUSIC_NewSoundtrack(str);
|
||||
return;
|
||||
case CS_WARMUP:
|
||||
cg.matchStartTime = atoi(str);
|
||||
return;
|
||||
case CS_FOGINFO:
|
||||
cg.farclipOverride = 0;
|
||||
cg.farplaneColorOverride[0] = -1;
|
||||
cg.farplaneColorOverride[1] = -1;
|
||||
cg.farplaneColorOverride[2] = -1;
|
||||
CG_ParseFogInfo(str);
|
||||
return;
|
||||
case CS_SKYINFO:
|
||||
sscanf(str, "%f %d", &cg.sky_alpha, &cg.sky_portal);
|
||||
return;
|
||||
case CS_SERVERINFO:
|
||||
CG_ParseServerinfo();
|
||||
return;
|
||||
case CS_LEVEL_START_TIME:
|
||||
cgs.levelStartTime = atoi(str);
|
||||
return;
|
||||
case CS_VOTE_TIME:
|
||||
cgs.voteTime = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_VOTE_STRING:
|
||||
Q_strncpyz(cgs.voteString, str, sizeof(cgs.voteString));
|
||||
break;
|
||||
case CS_VOTE_YES:
|
||||
cgs.numVotesYes = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_VOTE_NO:
|
||||
cgs.numVotesNo = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_VOTE_UNDECIDED:
|
||||
cgs.numUndecidedVotes = atoi(str);
|
||||
cgs.voteRefreshed = qtrue;
|
||||
break;
|
||||
case CS_MATCHEND:
|
||||
cgs.matchEndTime = atoi(str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (num >= CS_SOUNDS && num < CS_SOUNDS + MAX_SOUNDS) {
|
||||
size_t len = strlen(str);
|
||||
if (len) {
|
||||
qboolean streamed;
|
||||
char buf[1024];
|
||||
strcpy(buf, str);
|
||||
|
||||
streamed = buf[len - 1] != '0';
|
||||
buf[len - 1] = 0;
|
||||
if (buf[0] != '*') {
|
||||
cgs.sound_precache[num - CS_SOUNDS] = cgi.S_RegisterSound(buf, streamed);
|
||||
}
|
||||
}
|
||||
} else if (num >= CS_LIGHTSTYLES && num < CS_LIGHTSTYLES + MAX_LIGHTSTYLES) {
|
||||
CG_SetLightStyle(num - CS_LIGHTSTYLES, str);
|
||||
} else if (num >= CS_PLAYERS && num < CS_PLAYERS + MAX_CLIENTS) {
|
||||
const char *value;
|
||||
|
||||
value = Info_ValueForKey(str, "name");
|
||||
if (value) {
|
||||
strncpy(cg.clientinfo[num - CS_PLAYERS].name, value, sizeof(cg.clientinfo[num - CS_PLAYERS].name));
|
||||
} else {
|
||||
strncpy(
|
||||
cg.clientinfo[num - CS_PLAYERS].name, "UnnamedSoldier", sizeof(cg.clientinfo[num - CS_PLAYERS].name)
|
||||
);
|
||||
}
|
||||
|
||||
value = Info_ValueForKey(str, "team");
|
||||
if (value) {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = atoi(value);
|
||||
} else {
|
||||
cg.clientinfo[num - CS_PLAYERS].team = TEAM_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -421,14 +491,14 @@ void CG_PrepRefresh(void)
|
||||
cgs.media.binocularsOverlayShader = cgi.R_RegisterShaderNoMip("textures/hud/binocularsoverlay");
|
||||
cgs.media.hudDrawFont = cgi.R_LoadFont("verdana-14");
|
||||
cgs.media.attackerFont = cgi.R_LoadFont("facfont-20");
|
||||
cgs.media.objectiveFont = cgi.R_LoadFont("courier-16");
|
||||
cgs.media.objectiveFont = cgi.R_LoadFont("facfont-20"); // was courier-16 before 2.0
|
||||
cgs.media.objectivesBackShader = cgi.R_RegisterShaderNoMip("textures/hud/objectives_backdrop");
|
||||
cgs.media.checkedBoxShader = cgi.R_RegisterShaderNoMip("textures/objectives/filledbox");
|
||||
cgs.media.uncheckedBoxShader = cgi.R_RegisterShaderNoMip("textures/objectives/emptybox");
|
||||
|
||||
// go through all the configstrings and process them
|
||||
for (i = CS_SYSTEMINFO + 1; i < MAX_CONFIGSTRINGS; i++) {
|
||||
CG_ProcessConfigString(i);
|
||||
CG_ProcessConfigString(i, qfalse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,6 +537,7 @@ Displays the info screen while loading media
|
||||
void CG_GameStateReceived(void)
|
||||
{
|
||||
const char *s;
|
||||
int checksum;
|
||||
|
||||
// clear everything
|
||||
memset(&cg, 0, sizeof(cg));
|
||||
@@ -493,7 +564,10 @@ void CG_GameStateReceived(void)
|
||||
CG_ParseServerinfo();
|
||||
|
||||
// load the new map
|
||||
cgi.CM_LoadMap(cgs.mapname);
|
||||
cgi.CM_LoadMap(cgs.mapname, &checksum);
|
||||
if (cgs.useMapChecksum && checksum != cgs.mapChecksum && cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
cgi.Error(ERR_DROP, "Client/Server map checksum mismatch: %x/%x", checksum, cgs.mapChecksum);
|
||||
}
|
||||
|
||||
CG_InitMarks();
|
||||
|
||||
@@ -537,16 +611,6 @@ void CG_ServerRestarted(void)
|
||||
CG_InitializeObjectives();
|
||||
}
|
||||
|
||||
void *CG_Malloc(int size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void CG_Free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_Init
|
||||
@@ -557,10 +621,6 @@ Called after every level change or subsystem restart
|
||||
void CG_Init(clientGameImport_t *imported, int serverMessageNum, int serverCommandSequence, int clientNum)
|
||||
{
|
||||
cgi = *imported;
|
||||
#if _DEBUG
|
||||
cgi.Malloc = &CG_Malloc;
|
||||
cgi.Free = &CG_Free;
|
||||
#endif
|
||||
|
||||
cg_protocol = cgi.Cvar_Get("com_protocol", "", 0)->integer;
|
||||
CG_InitCGMessageAPI(&cge);
|
||||
@@ -568,6 +628,11 @@ void CG_Init(clientGameImport_t *imported, int serverMessageNum, int serverComma
|
||||
|
||||
memset(&cg, 0, sizeof(cg));
|
||||
memset(&cgs, 0, sizeof(cgs));
|
||||
// clear fog values
|
||||
cg.farclipOverride = 0;
|
||||
cg.farplaneColorOverride[0] = -1;
|
||||
cg.farplaneColorOverride[1] = -1;
|
||||
cg.farplaneColorOverride[2] = -1;
|
||||
|
||||
cg.clientNum = clientNum;
|
||||
cgs.processedSnapshotNum = serverMessageNum;
|
||||
@@ -624,11 +689,14 @@ Called before every level change or subsystem restart
|
||||
void CG_Shutdown(void)
|
||||
{
|
||||
L_ShutdownEvents();
|
||||
// Shutdown radar
|
||||
cgi.CL_InitRadar(NULL, NULL, -1);
|
||||
|
||||
// some mods may need to do cleanup work here,
|
||||
// like closing files or archiving session data
|
||||
|
||||
// hide the stats screen
|
||||
cgi.UI_HideMenu("StatsScreen", 1);
|
||||
cgi.UI_HideMenu("StatsScreen", qtrue);
|
||||
|
||||
// reset the scoreboard
|
||||
CG_PrepScoreBoardInfo();
|
||||
@@ -677,6 +745,11 @@ clientGameExport_t *GetCGameAPI(void)
|
||||
cge.CG_GetObjectiveAlpha = CG_GetObjectiveAlpha;
|
||||
cge.CG_WeaponCommandButtonBits = CG_WeaponCommandButtonBits;
|
||||
cge.CG_CheckCaptureKey = CG_CheckCaptureKey;
|
||||
cge.CG_ReadNonPVSClient = CG_ReadNonPVSClient;
|
||||
cge.CG_UpdateRadar = CG_UpdateRadar;
|
||||
cge.CG_SaveStateToBuffer = CG_SaveStateToBuffer;
|
||||
cge.CG_LoadStateToBuffer = CG_LoadStateToBuffer;
|
||||
cge.CG_CleanUpTempModels = CG_CleanUpTempModels;
|
||||
|
||||
// FIXME
|
||||
//cge.profStruct = NULL;
|
||||
@@ -781,10 +854,20 @@ void CG_ParseFogInfo_ver_15(const char *str)
|
||||
|
||||
void CG_ParseFogInfo_ver_6(const char *str)
|
||||
{
|
||||
cg.farclipOverride = 0.0;
|
||||
//
|
||||
// clear all unsupported fields in protocol below version 15
|
||||
//
|
||||
|
||||
// don't set the farplane_bias 0, otherwise the renderer will set a minimum value
|
||||
cg.farplane_bias = 0.001f;
|
||||
cg.skyboxFarplane = 0;
|
||||
cg.skyboxSpeed = 0;
|
||||
cg.renderTerrain = qtrue;
|
||||
cg.farclipOverride = -1.0;
|
||||
cg.farplaneColorOverride[0] = -1.0;
|
||||
cg.farplaneColorOverride[1] = -1.0;
|
||||
cg.farplaneColorOverride[2] = -1.0;
|
||||
|
||||
sscanf(
|
||||
str,
|
||||
"%d %f %f %f %f",
|
||||
|
||||
@@ -685,9 +685,9 @@ void CG_ImpactMark(
|
||||
// create the full polygon
|
||||
for (i = 0; i < 3; i++) {
|
||||
originalPoints[0][i] = origin[i] - fSScale2 * info.axis[1][i] - fTScale2 * info.axis[2][i];
|
||||
originalPoints[1][i] = origin[i] + fSScale3 * info.axis[1][i] - fTScale3 * info.axis[2][i];
|
||||
originalPoints[1][i] = origin[i] + fSScale3 * info.axis[1][i] - fTScale2 * info.axis[2][i];
|
||||
originalPoints[2][i] = origin[i] + fSScale3 * info.axis[1][i] + fTScale3 * info.axis[2][i];
|
||||
originalPoints[3][i] = origin[i] - fSScale2 * info.axis[1][i] + fTScale2 * info.axis[2][i];
|
||||
originalPoints[3][i] = origin[i] - fSScale2 * info.axis[1][i] + fTScale3 * info.axis[2][i];
|
||||
}
|
||||
|
||||
// get the fragments
|
||||
|
||||
+286
-20
@@ -180,6 +180,226 @@ void CG_PlayerTeamIcon(refEntity_t *pModel, entityState_t *pPlayerState)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CastFootShadow
|
||||
|
||||
Cast complex foot shadow using lights
|
||||
===============
|
||||
*/
|
||||
void CG_CastFootShadow(const vec_t* vLightPos, vec_t* vLightIntensity, int iTag, refEntity_t* model)
|
||||
{
|
||||
int i;
|
||||
float fAlpha;
|
||||
float fLength;
|
||||
float fWidth;
|
||||
float fAlphaOfs;
|
||||
float fOfs;
|
||||
float fPitchCos;
|
||||
vec3_t vPos;
|
||||
vec3_t vEnd;
|
||||
vec3_t vDelta;
|
||||
vec3_t vLightAngles;
|
||||
trace_t trace;
|
||||
orientation_t oFoot;
|
||||
|
||||
VectorCopy(model->origin, vPos);
|
||||
oFoot = cgi.TIKI_Orientation(model, iTag);
|
||||
VectorMA(oFoot.origin, 2, oFoot.axis[1], vEnd);
|
||||
for (i = 0; i < 3; i++) {
|
||||
VectorMA(vPos, vEnd[i], model->axis[i], vPos);
|
||||
}
|
||||
|
||||
if (cg_shadowdebug->integer)
|
||||
{
|
||||
vec3_t vDir;
|
||||
|
||||
//
|
||||
// show debug lines
|
||||
//
|
||||
memset(vDir, 0, sizeof(vDir));
|
||||
for (i = 0; i < 3; ++i) {
|
||||
VectorMA(vDir, oFoot.axis[0][i], model->axis[i], vDir);
|
||||
}
|
||||
VectorMA(vPos, 32.0, vDir, vEnd);
|
||||
cgi.R_DebugLine(vPos, vEnd, 1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
memset(vDir, 0, sizeof(vDir));
|
||||
for (i = 0; i < 3; ++i) {
|
||||
VectorMA(vDir, oFoot.axis[1][i], model->axis[i], vDir);
|
||||
}
|
||||
VectorMA(vPos, 32.0, vDir, vEnd);
|
||||
cgi.R_DebugLine(vPos, vEnd, 0.0, 1.0, 0.0, 1.0);
|
||||
|
||||
memset(vDir, 0, sizeof(vDir));
|
||||
for (i = 0; i < 3; ++i) {
|
||||
VectorMA(vDir, oFoot.axis[2][i], model->axis[i], vDir);
|
||||
}
|
||||
VectorMA(vPos, 32.0, vDir, vEnd);
|
||||
cgi.R_DebugLine(vPos, vEnd, 0.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
// calculate the direction
|
||||
VectorSubtract(vLightPos, vPos, vDelta);
|
||||
VectorNormalizeFast(vDelta);
|
||||
vectoangles(vDelta, vLightAngles);
|
||||
|
||||
// normalize to 180 degrees
|
||||
if (vLightAngles[0] > 180) {
|
||||
vLightAngles[0] -= 360;
|
||||
}
|
||||
|
||||
if (vLightAngles[0] > -5.7319679) {
|
||||
// FIXME: what is -5.7319679?
|
||||
return;
|
||||
}
|
||||
|
||||
fPitchCos = cos(DEG2RAD(vLightAngles[0]));
|
||||
if (fPitchCos > 0.955) {
|
||||
fAlpha = 1.0 - (fPitchCos - 0.955) * 25;
|
||||
} else {
|
||||
fAlpha = 1.0;
|
||||
}
|
||||
|
||||
fLength = fPitchCos * fPitchCos * 32.0 + fPitchCos * 8.0 + 10.0;
|
||||
fOfs = 0.5 - (-4.1 / tan(DEG2RAD(vLightAngles[0])) + 4.0 - fLength) / fLength * 0.5;
|
||||
VectorMA(vPos, -96.0, vDelta, vEnd);
|
||||
CG_Trace(&trace, vPos, vec3_origin, vec3_origin, vEnd, 0, MASK_FOOTSHADOW, qfalse, qtrue, "CG_CastFootShadow");
|
||||
|
||||
if (cg_shadowdebug->integer)
|
||||
{
|
||||
cgi.R_DebugLine(vPos, vLightPos, 0.75, 0.75, 0.5, 1.0);
|
||||
cgi.R_DebugLine(vPos, vEnd, 1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
if (trace.fraction == 1.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
trace.fraction -= 0.0427f;
|
||||
if (trace.fraction < 0) {
|
||||
trace.fraction = 0;
|
||||
}
|
||||
|
||||
fWidth = 10.f - (1.f - trace.fraction) * 6.f;
|
||||
fAlphaOfs = (1.f - trace.fraction) * fAlpha;
|
||||
|
||||
fAlpha = Q_max(vLightIntensity[0], Q_max(vLightIntensity[1], vLightIntensity[2]));
|
||||
|
||||
if (fAlpha < 0.1) {
|
||||
vLightIntensity[0] *= 0.1 / fAlpha * fAlphaOfs;
|
||||
vLightIntensity[1] *= 0.1 / fAlpha * fAlphaOfs;
|
||||
vLightIntensity[2] *= 0.1 / fAlpha * fAlphaOfs;
|
||||
} else {
|
||||
vLightIntensity[0] *= fAlphaOfs;
|
||||
vLightIntensity[1] *= fAlphaOfs;
|
||||
vLightIntensity[2] *= fAlphaOfs;
|
||||
}
|
||||
|
||||
fAlpha = Q_max(vLightIntensity[0], Q_max(vLightIntensity[1], vLightIntensity[2]));
|
||||
if (fAlpha > 0.6) {
|
||||
vLightIntensity[0] *= 0.6 / fAlpha;
|
||||
vLightIntensity[1] *= 0.6 / fAlpha;
|
||||
vLightIntensity[2] *= 0.6 / fAlpha;
|
||||
}
|
||||
|
||||
if (vLightIntensity[0] <= 0.01 && vLightIntensity[1] <= 0.01 && vLightIntensity[2] <= 0.01) {
|
||||
return;
|
||||
}
|
||||
|
||||
CG_ImpactMark(
|
||||
cgs.media.footShadowMarkShader,
|
||||
trace.endpos,
|
||||
trace.plane.normal,
|
||||
vLightAngles[1],
|
||||
fWidth,
|
||||
fLength,
|
||||
vLightIntensity[0],
|
||||
vLightIntensity[1],
|
||||
vLightIntensity[2],
|
||||
1.0,
|
||||
qfalse,
|
||||
qtrue,
|
||||
qfalse,
|
||||
qfalse,
|
||||
0.5,
|
||||
fOfs
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CastSimpleFeetShadow
|
||||
|
||||
Cast basic feet shadow
|
||||
===============
|
||||
*/
|
||||
void CG_CastSimpleFeetShadow(const trace_t* pTrace, float fWidth, float fAlpha, int iRightTag, int iLeftTag, const dtiki_t* tiki, refEntity_t* model)
|
||||
{
|
||||
int i;
|
||||
float fShadowYaw;
|
||||
float fLength;
|
||||
vec3_t vPos, vRightPos, vLeftPos;
|
||||
vec3_t vDelta;
|
||||
orientation_t oFoot;
|
||||
|
||||
//
|
||||
// right foot
|
||||
//
|
||||
VectorCopy(pTrace->endpos, vRightPos);
|
||||
oFoot = cgi.TIKI_Orientation(model, iRightTag);
|
||||
VectorMA(oFoot.origin, 3, oFoot.axis[1], vPos);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
VectorMA(vRightPos, vPos[i], model->axis[i], vRightPos);
|
||||
}
|
||||
|
||||
VectorMA(vRightPos, -2, oFoot.axis[1], vRightPos);
|
||||
|
||||
//
|
||||
// left foot
|
||||
//
|
||||
VectorCopy(pTrace->endpos, vLeftPos);
|
||||
oFoot = cgi.TIKI_Orientation(model, iLeftTag);
|
||||
VectorMA(oFoot.origin, 3, oFoot.axis[1], vPos);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
VectorMA(vLeftPos, vPos[i], model->axis[i], vLeftPos);
|
||||
}
|
||||
|
||||
VectorAdd(vRightPos, vLeftPos, vPos);
|
||||
VectorScale(vPos, 0.5, vPos);
|
||||
VectorSubtract(vRightPos, vLeftPos, vDelta);
|
||||
VectorMA(vLeftPos, 0.5, vDelta, vPos);
|
||||
|
||||
// get the facing yaw
|
||||
fShadowYaw = vectoyaw(vDelta);
|
||||
fLength = VectorNormalize(vDelta) * 0.5 + 12;
|
||||
if (fLength < fWidth * 0.7) {
|
||||
fLength = fWidth * 0.7;
|
||||
}
|
||||
|
||||
// add the mark
|
||||
CG_ImpactMark(
|
||||
cgs.media.shadowMarkShader,
|
||||
vPos,
|
||||
pTrace->plane.normal,
|
||||
fShadowYaw,
|
||||
fWidth * 0.7,
|
||||
fLength,
|
||||
fAlpha,
|
||||
fAlpha,
|
||||
fAlpha,
|
||||
1.0,
|
||||
qfalse,
|
||||
qtrue,
|
||||
qfalse,
|
||||
qfalse,
|
||||
0.5,
|
||||
0.5
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_EntityShadow
|
||||
@@ -193,9 +413,15 @@ Returns the Z component of the surface being shadowed
|
||||
|
||||
qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
{
|
||||
int iTagL, iTagR;
|
||||
float alpha;
|
||||
float fWidth;
|
||||
vec3_t end;
|
||||
vec3_t vMins, vMaxs;
|
||||
vec3_t vSize;
|
||||
trace_t trace;
|
||||
float alpha, radius;
|
||||
|
||||
iTagR = -1;
|
||||
|
||||
if (cg_shadows->integer == 0) {
|
||||
return qfalse;
|
||||
@@ -206,10 +432,31 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// no shadows when invisible
|
||||
// if ( cent->currentState.powerups & ( 1 << PW_INVIS ) ) {
|
||||
// return qfalse;
|
||||
// }
|
||||
if (cg_shadows->integer == 2 && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
iTagL = cgi.Tag_NumForName(model->tiki, "Bip01 L Foot");
|
||||
if (iTagL != -1) {
|
||||
iTagR = cgi.Tag_NumForName(model->tiki, "Bip01 R Foot");
|
||||
}
|
||||
|
||||
if (iTagR != -1) {
|
||||
int iNumLights, iCurrLight;
|
||||
vec3_t avLightPos[16], avLightIntensity[16];
|
||||
|
||||
iNumLights = Q_clamp(cg_shadowscount->integer, 1, 8);
|
||||
iNumLights = cgi.R_GatherLightSources(model->origin, avLightPos, avLightIntensity, iNumLights);
|
||||
if (iNumLights)
|
||||
{
|
||||
for (iCurrLight = 0; iCurrLight < iNumLights; iCurrLight++)
|
||||
{
|
||||
CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagL, model);
|
||||
CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagR, model);
|
||||
}
|
||||
|
||||
// shadow was casted properly
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send a trace down from the player to the ground
|
||||
VectorCopy(model->origin, end);
|
||||
@@ -222,29 +469,46 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ((cg_shadows->integer == 2) && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
// since 2.0: no shadow if solid
|
||||
if (trace.startsolid || trace.allsolid) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ((cg_shadows->integer == 3) && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
//
|
||||
// get the bounds of the current frame
|
||||
//
|
||||
radius = model->scale * cgi.R_ModelRadius(model->hModel);
|
||||
|
||||
if (radius < 1) {
|
||||
fWidth = model->scale * cgi.R_ModelRadius(model->hModel);
|
||||
if (fWidth < 1) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// fade the shadow out with height
|
||||
alpha = (1.0 - trace.fraction) * 0.8f;
|
||||
alpha = (1.0 - trace.fraction) * 0.65f;
|
||||
|
||||
if ((cg_shadows->integer == 3) && (model->renderfx & RF_SHADOW_PRECISE)) {
|
||||
if (model->shaderRGBA[3] == 255) {
|
||||
model->shaderRGBA[3] = alpha * 255;
|
||||
if (model->renderfx & RF_SHADOW_PRECISE) {
|
||||
iTagL = cgi.Tag_NumForName(model->tiki, "Bip01 L Foot");
|
||||
if (iTagL != -1) {
|
||||
iTagR = cgi.Tag_NumForName(model->tiki, "Bip01 R Foot");
|
||||
}
|
||||
|
||||
if (iTagR != -1) {
|
||||
if (cg_shadows->integer == 2) {
|
||||
alpha *= 0.6f;
|
||||
}
|
||||
|
||||
CG_CastSimpleFeetShadow(&trace, fWidth, alpha, iTagR, iTagL, model->tiki, model);
|
||||
return qtrue;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
cgi.R_ModelBounds(model->hModel, vMins, vMaxs);
|
||||
VectorSubtract(vMaxs, vMins, vSize);
|
||||
VectorScale(vSize, 0.6f, vSize);
|
||||
|
||||
// add the mark as a temporary, so it goes directly to the renderer
|
||||
// without taking a spot in the cg_marks array
|
||||
CG_ImpactMark(
|
||||
@@ -252,15 +516,15 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
|
||||
trace.endpos,
|
||||
trace.plane.normal,
|
||||
cent->lerpAngles[YAW],
|
||||
radius,
|
||||
radius,
|
||||
vSize[1],
|
||||
vSize[0],
|
||||
alpha,
|
||||
alpha,
|
||||
alpha,
|
||||
1,
|
||||
qfalse,
|
||||
qtrue,
|
||||
qtrue,
|
||||
qfalse,
|
||||
qfalse,
|
||||
0.5f,
|
||||
0.5f
|
||||
@@ -316,10 +580,12 @@ void CG_AttachEntity(
|
||||
orientation_t or ;
|
||||
vec3_t tempAxis[3];
|
||||
vec3_t vOrigin;
|
||||
vec3_t vDeltaLightOrg;
|
||||
|
||||
or = cgi.TIKI_Orientation(parent, tagnum);
|
||||
//cgi.Printf( "th = %d %.2f %.2f %.2f\n", tikihandle, or.origin[ 0 ], or.origin[ 1 ], or.origin[ 2 ] );
|
||||
|
||||
VectorSubtract(entity->lightingOrigin, entity->origin, vDeltaLightOrg);
|
||||
VectorCopy(parent->origin, entity->origin);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -337,14 +603,14 @@ void CG_AttachEntity(
|
||||
VectorCopy(entity->origin, entity->oldorigin);
|
||||
|
||||
if (use_angles) {
|
||||
MatrixMultiply(entity->axis, parent->axis, tempAxis);
|
||||
MatrixMultiply(or.axis, tempAxis, entity->axis);
|
||||
MatrixMultiply(entity->axis, or.axis, tempAxis);
|
||||
MatrixMultiply(tempAxis, parent->axis, entity->axis);
|
||||
}
|
||||
|
||||
entity->scale *= parent->scale;
|
||||
entity->renderfx |= (parent->renderfx & ~(RF_FLAGS_NOT_INHERITED | RF_LIGHTING_ORIGIN));
|
||||
|
||||
MatrixTransformVectorRight(entity->axis, entity->lightingOrigin, vOrigin);
|
||||
MatrixTransformVectorRight(entity->axis, vDeltaLightOrg, vOrigin);
|
||||
VectorAdd(entity->origin, vOrigin, entity->lightingOrigin);
|
||||
}
|
||||
|
||||
|
||||
+183
-224
@@ -37,6 +37,7 @@ typedef struct {
|
||||
vec3_t *i_vEnd;
|
||||
int i_iNumBullets;
|
||||
qboolean iLarge;
|
||||
float alpha;
|
||||
int iTracerVisible;
|
||||
qboolean bIgnoreEntities;
|
||||
} bullet_tracer_t;
|
||||
@@ -60,21 +61,22 @@ static vec3_t flesh_impact_pos[MAX_IMPACTS];
|
||||
static vec3_t flesh_impact_norm[MAX_IMPACTS];
|
||||
static int flesh_impact_large[MAX_IMPACTS];
|
||||
|
||||
void CG_MakeBulletHoleSound(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t* pPreTrace) {
|
||||
|
||||
int iSurfType;
|
||||
float fVolume;
|
||||
str sSoundName;
|
||||
vec3_t vFrom, vDest;
|
||||
void CG_MakeBulletHoleSound(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t *pPreTrace)
|
||||
{
|
||||
int iSurfType;
|
||||
float fVolume;
|
||||
str sSoundName;
|
||||
vec3_t vFrom, vDest;
|
||||
trace_t trace;
|
||||
|
||||
if (pPreTrace) {
|
||||
trace = *pPreTrace;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
VectorMA(i_vPos, 2.0f, i_vNorm, vFrom);
|
||||
VectorMA(i_vPos, -4.0f, i_vNorm, vDest);
|
||||
CG_Trace(&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole");
|
||||
CG_Trace(
|
||||
&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole"
|
||||
);
|
||||
}
|
||||
|
||||
iSurfType = trace.surfaceFlags & MASK_SURF_TYPE;
|
||||
@@ -149,9 +151,12 @@ void CG_MakeBulletHoleSound(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarg
|
||||
commandManager.PlaySound(sSoundName, vFrom, -1, fVolume, -1.f, -1.f, 1);
|
||||
}
|
||||
|
||||
static void CG_MakeBulletHoleType(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, int iEffectNum, float fRadius, qboolean bMakeSound) {
|
||||
static void CG_MakeBulletHoleType(
|
||||
const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, int iEffectNum, float fRadius, qboolean bMakeSound
|
||||
)
|
||||
{
|
||||
if (bMakeSound) {
|
||||
str sBulletHole = "snd_bh_";
|
||||
str sBulletHole = "snd_bh_";
|
||||
float fVolume;
|
||||
|
||||
switch (iEffectNum) {
|
||||
@@ -221,14 +226,15 @@ static void CG_MakeBulletHoleType(const vec3_t i_vPos, const vec3_t i_vNorm, int
|
||||
sfxManager.MakeEffect_Normal(iEffectNum, i_vPos, i_vNorm);
|
||||
}
|
||||
|
||||
static void CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t *pPreTrace, qboolean bMakeSound)
|
||||
static void
|
||||
CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t *pPreTrace, qboolean bMakeSound)
|
||||
{
|
||||
int iSurfType;
|
||||
int iEffect;
|
||||
float fRadius;
|
||||
str sEffectModel;
|
||||
str sBulletHole;
|
||||
vec3_t vFrom, vDest;
|
||||
int iSurfType;
|
||||
int iEffect;
|
||||
float fRadius;
|
||||
str sEffectModel;
|
||||
str sBulletHole;
|
||||
vec3_t vFrom, vDest;
|
||||
trace_t trace;
|
||||
|
||||
if (pPreTrace) {
|
||||
@@ -236,7 +242,9 @@ static void CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLa
|
||||
} else {
|
||||
VectorMA(i_vPos, 2.0f, i_vNorm, vFrom);
|
||||
VectorMA(i_vPos, -4.0f, i_vNorm, vDest);
|
||||
CG_Trace(&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole");
|
||||
CG_Trace(
|
||||
&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole"
|
||||
);
|
||||
}
|
||||
|
||||
iSurfType = trace.surfaceFlags & MASK_SURF_TYPE;
|
||||
@@ -249,7 +257,7 @@ static void CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLa
|
||||
}
|
||||
|
||||
VectorAdd(trace.endpos, trace.plane.normal, vFrom);
|
||||
fRadius = 2.0f;
|
||||
fRadius = 2.0f;
|
||||
sBulletHole = "bhole_";
|
||||
|
||||
switch (iSurfType) {
|
||||
@@ -347,36 +355,48 @@ static void CG_MakeBubbleTrail(const vec3_t i_vStart, const vec3_t i_vEnd, int i
|
||||
{
|
||||
vec3_t vDir;
|
||||
vec3_t vPos;
|
||||
float fDist;
|
||||
float fMove;
|
||||
float fDist;
|
||||
float fMove;
|
||||
|
||||
VectorSubtract(i_vEnd, i_vStart, vDir);
|
||||
fDist = VectorNormalize(vDir);
|
||||
VectorCopy(i_vStart, vPos);
|
||||
|
||||
fMove = random() * 8.f;
|
||||
fMove = random() * 8.f * alpha;
|
||||
fDist -= fMove;
|
||||
while (fDist > 0.f) {
|
||||
VectorMA(vPos, fMove, vDir, vPos);
|
||||
sfxManager.MakeEffect_Angles(32, vPos, vec_zero);
|
||||
|
||||
fMove = 16.f + crandom() * 8.f;
|
||||
fMove = 16.f + crandom() * 8.f * alpha;
|
||||
fDist -= fMove;
|
||||
}
|
||||
}
|
||||
|
||||
static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd)
|
||||
static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd, int iLarge, float alpha)
|
||||
{
|
||||
int iLife;
|
||||
int iTracerLength;
|
||||
float fLength, fDist;
|
||||
int iLife;
|
||||
int iTracerLength;
|
||||
float fLength, fDist;
|
||||
vec4_t fTracerColor;
|
||||
vec3_t vDir, vNewStart;
|
||||
float alphaMult;
|
||||
float scale;
|
||||
|
||||
iTracerLength = 450.0f + random() * 150.f;
|
||||
VectorSubtract(i_vEnd, i_vStart, vDir);
|
||||
fLength = VectorNormalize(vDir);
|
||||
|
||||
if (iLarge > 1) {
|
||||
alphaMult = random() * 0.2f + 0.9f;
|
||||
scale = iLarge * 2;
|
||||
} else {
|
||||
alphaMult = 1;
|
||||
scale = 1;
|
||||
}
|
||||
|
||||
fDist = 450.0f + random() * 150.f;
|
||||
|
||||
if (fLength < fDist + 150.f) {
|
||||
float fFrac;
|
||||
|
||||
@@ -384,13 +404,15 @@ static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd)
|
||||
return;
|
||||
}
|
||||
|
||||
fFrac = fLength / (fDist + 150.0);
|
||||
fFrac = fLength / (fDist + 150.0);
|
||||
iTracerLength = (int)((float)iTracerLength * fFrac + 0.5f);
|
||||
fDist *= fFrac;
|
||||
}
|
||||
|
||||
iLife = (int)((fLength - fDist) / 12000.f * 1000.f);
|
||||
if (iLife < 20) iLife = 20;
|
||||
iLife = (int)((fLength - fDist) / 12000.f * 1000.f / (alpha * alphaMult));
|
||||
if (iLife < 20) {
|
||||
iLife = 20;
|
||||
}
|
||||
|
||||
VectorMA(i_vStart, fDist, vDir, vNewStart);
|
||||
fTracerColor[0] = 1.f;
|
||||
@@ -427,53 +449,54 @@ static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd)
|
||||
}
|
||||
|
||||
static void CG_MakeBulletTracerInternal(
|
||||
const vec3_t i_vBarrel,
|
||||
const vec3_t i_vStart,
|
||||
const vec3_t *i_vEnd,
|
||||
int i_iNumBullets,
|
||||
qboolean iLarge,
|
||||
int iTracerVisible,
|
||||
qboolean bIgnoreEntities
|
||||
const vec3_t i_vBarrel,
|
||||
const vec3_t i_vStart,
|
||||
const vec3_t *i_vEnd,
|
||||
int i_iNumBullets,
|
||||
qboolean iLarge,
|
||||
int iTracerVisible,
|
||||
qboolean bIgnoreEntities,
|
||||
float alpha
|
||||
)
|
||||
{
|
||||
vec3_t vPos;
|
||||
int iBullet;
|
||||
int iContinueCount;
|
||||
int iDist;
|
||||
int iHeadDist;
|
||||
int iTravelDist;
|
||||
float fLen, fDist;
|
||||
trace_t trace;
|
||||
qboolean bStartInWater, bInWater;
|
||||
qboolean bBulletDone;
|
||||
qboolean bMadeTracer;
|
||||
vec3_t vDir;
|
||||
vec3_t vTrailStart;
|
||||
vec3_t vTraceStart;
|
||||
vec3_t vTraceEnd;
|
||||
vec3_t vTmp;
|
||||
int iNumImpacts;
|
||||
trace_t tImpacts[128];
|
||||
float fImpSndDistRA;
|
||||
vec3_t vPos;
|
||||
int iBullet;
|
||||
int iContinueCount;
|
||||
int iDist;
|
||||
int iHeadDist;
|
||||
int iTravelDist;
|
||||
float fLen, fDist;
|
||||
trace_t trace;
|
||||
qboolean bStartInWater, bInWater;
|
||||
qboolean bBulletDone;
|
||||
qboolean bMadeTracer;
|
||||
vec3_t vDir;
|
||||
vec3_t vTrailStart;
|
||||
vec3_t vTraceStart;
|
||||
vec3_t vTraceEnd;
|
||||
vec3_t vTmp;
|
||||
int iNumImpacts;
|
||||
trace_t tImpacts[128];
|
||||
float fImpSndDistRA;
|
||||
static float fImpSndDistLA;
|
||||
float fImpSndDistRB;
|
||||
float fImpSndDistLB;
|
||||
int iImpSndIndexRA;
|
||||
int iImpSndIndexRB;
|
||||
int iImpSndIndexLB;
|
||||
float fVolume;
|
||||
float fPitch;
|
||||
float fZingDistA, fZingDistB, fZingDistC;
|
||||
vec3_t vZingPosA, vZingPosB, vZingPosC;
|
||||
float fImpSndDistRB;
|
||||
float fImpSndDistLB;
|
||||
int iImpSndIndexRA;
|
||||
int iImpSndIndexRB;
|
||||
int iImpSndIndexLB;
|
||||
float fVolume;
|
||||
float fPitch;
|
||||
float fZingDistA, fZingDistB, fZingDistC;
|
||||
vec3_t vZingPosA, vZingPosB, vZingPosC;
|
||||
|
||||
fZingDistB = 9999.0;
|
||||
fZingDistA = 9999.0;
|
||||
fZingDistC = 9999.0;
|
||||
fZingDistB = 9999.0;
|
||||
fZingDistA = 9999.0;
|
||||
fZingDistC = 9999.0;
|
||||
iNumImpacts = 0;
|
||||
|
||||
// check to see if it starts in water
|
||||
bStartInWater = (cgi.CM_PointContents(i_vStart, 0) & CONTENTS_FLUID) != 0;
|
||||
|
||||
|
||||
for (iBullet = 0; iBullet < i_iNumBullets; iBullet++) {
|
||||
bInWater = bStartInWater;
|
||||
VectorCopy(i_vBarrel, vTrailStart);
|
||||
@@ -481,8 +504,8 @@ static void CG_MakeBulletTracerInternal(
|
||||
fLen = VectorNormalize(vDir);
|
||||
|
||||
trace.fraction = 0;
|
||||
iDist = (int)fLen + 32;
|
||||
bBulletDone = qfalse;
|
||||
iDist = (int)fLen + 32;
|
||||
bBulletDone = qfalse;
|
||||
iContinueCount = 0;
|
||||
|
||||
if (bStartInWater) {
|
||||
@@ -501,8 +524,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
if (iDist > BULLET_TRAVEL_DIST) {
|
||||
iTravelDist += BULLET_TRAVEL_DIST;
|
||||
iDist -= BULLET_TRAVEL_DIST;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
iTravelDist += iDist;
|
||||
iDist = 0;
|
||||
}
|
||||
@@ -513,16 +535,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
|
||||
while (trace.fraction < 1) {
|
||||
if (bIgnoreEntities) {
|
||||
cgi.CM_BoxTrace(
|
||||
&trace,
|
||||
vTraceStart,
|
||||
vTraceEnd,
|
||||
vec_zero,
|
||||
vec_zero,
|
||||
0,
|
||||
MASK_SHOT,
|
||||
qfalse
|
||||
);
|
||||
cgi.CM_BoxTrace(&trace, vTraceStart, vTraceEnd, vec_zero, vec_zero, 0, MASK_SHOT, qfalse);
|
||||
|
||||
if (trace.fraction == 1.0f) {
|
||||
trace.entityNum = ENTITYNUM_NONE;
|
||||
@@ -533,8 +546,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
if (trace.startsolid) {
|
||||
trace.entityNum = ENTITYNUM_WORLD;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
CG_Trace(
|
||||
&trace,
|
||||
vTraceStart,
|
||||
@@ -556,35 +568,29 @@ static void CG_MakeBulletTracerInternal(
|
||||
VectorNormalizeFast(trace.plane.normal);
|
||||
}
|
||||
|
||||
if (!bInWater && trace.fraction < 1.0f && iNumImpacts <= 127)
|
||||
{
|
||||
if (!bInWater && trace.fraction < 1.0f && iNumImpacts <= 127) {
|
||||
memcpy(&tImpacts[iNumImpacts], &trace, sizeof(trace_t));
|
||||
iNumImpacts++;
|
||||
}
|
||||
|
||||
if (iTracerVisible && !bMadeTracer)
|
||||
{
|
||||
CG_BulletTracerEffect(vTrailStart, trace.endpos);
|
||||
if (iTracerVisible && !bMadeTracer) {
|
||||
CG_BulletTracerEffect(vTrailStart, trace.endpos, iLarge, alpha);
|
||||
bMadeTracer = qtrue;
|
||||
}
|
||||
|
||||
if (trace.fraction < 1.0f) {
|
||||
if (((trace.surfaceFlags & (SURF_HINT | SURF_NODLIGHT | SURF_SNOW | SURF_FOLIAGE | SURF_DIRT)) || (trace.contents & CONTENTS_WATER))
|
||||
&& iContinueCount < 5)
|
||||
{
|
||||
if (bInWater)
|
||||
{
|
||||
if (((trace.surfaceFlags & (SURF_HINT | SURF_NODLIGHT | SURF_SNOW | SURF_FOLIAGE | SURF_DIRT))
|
||||
|| (trace.contents & CONTENTS_WATER))
|
||||
&& iContinueCount < 5) {
|
||||
if (bInWater) {
|
||||
VectorSubtract(trace.endpos, vDir, vTmp);
|
||||
if (!(trace.contents & CONTENTS_FLUID)
|
||||
&& !(trace.surfaceFlags & SURF_PUDDLE)
|
||||
&& !(cgi.CM_PointContents(vTmp, 0) & CONTENTS_FLUID))
|
||||
{
|
||||
CG_MakeBubbleTrail(vTrailStart, trace.endpos, iLarge);
|
||||
if (!(trace.contents & CONTENTS_FLUID) && !(trace.surfaceFlags & SURF_PUDDLE)
|
||||
&& !(cgi.CM_PointContents(vTmp, 0) & CONTENTS_FLUID)) {
|
||||
CG_MakeBubbleTrail(vTrailStart, trace.endpos, iLarge, alpha);
|
||||
VectorCopy(trace.endpos, vTrailStart);
|
||||
bInWater = qfalse;
|
||||
}
|
||||
}
|
||||
else if ((trace.contents & CONTENTS_FLUID) || (trace.surfaceFlags & SURF_PUDDLE)) {
|
||||
} else if ((trace.contents & CONTENTS_FLUID) || (trace.surfaceFlags & SURF_PUDDLE)) {
|
||||
VectorCopy(trace.endpos, vTrailStart);
|
||||
bInWater = qtrue;
|
||||
}
|
||||
@@ -593,11 +599,9 @@ static void CG_MakeBulletTracerInternal(
|
||||
VectorAdd(vTraceStart, vTraceStart, trace.endpos);
|
||||
|
||||
iContinueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
trace.fraction = 1.0f;
|
||||
bBulletDone = qtrue;
|
||||
bBulletDone = qtrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,14 +609,14 @@ static void CG_MakeBulletTracerInternal(
|
||||
}
|
||||
|
||||
if (bInWater) {
|
||||
CG_MakeBubbleTrail(vTraceStart, trace.endpos, iLarge);
|
||||
CG_MakeBubbleTrail(vTraceStart, trace.endpos, iLarge, alpha);
|
||||
}
|
||||
|
||||
if (iTracerVisible) {
|
||||
iTracerVisible--;
|
||||
}
|
||||
|
||||
fLen = ProjectPointOnLine(i_vStart, i_vEnd[iBullet], cg.SoundOrg, vPos);
|
||||
fLen = ProjectPointOnLine(i_vStart, i_vEnd[iBullet], cg.SoundOrg, vPos);
|
||||
iHeadDist = (int)Distance(vPos, cg.SoundOrg);
|
||||
if (iHeadDist > 255) {
|
||||
continue;
|
||||
@@ -629,7 +633,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
|
||||
if (fLen < 0.f) {
|
||||
VectorCopy(i_vStart, vPos);
|
||||
} else if(fDist >= fLen) {
|
||||
} else if (fDist >= fLen) {
|
||||
VectorCopy(i_vEnd[iBullet], vPos);
|
||||
}
|
||||
|
||||
@@ -652,11 +656,11 @@ static void CG_MakeBulletTracerInternal(
|
||||
}
|
||||
|
||||
if (iNumImpacts > 2) {
|
||||
fImpSndDistRA = 9999.0f;
|
||||
fImpSndDistRB = 9999.0f;
|
||||
fImpSndDistRA = 9999.0f;
|
||||
fImpSndDistRB = 9999.0f;
|
||||
iImpSndIndexRA = 0;
|
||||
iImpSndIndexRB = 0;
|
||||
fImpSndDistLB = 9999.0f;
|
||||
fImpSndDistLB = 9999.0f;
|
||||
iImpSndIndexLB = 0;
|
||||
|
||||
for (iBullet = 0; iBullet < iNumImpacts; iBullet++) {
|
||||
@@ -671,27 +675,23 @@ static void CG_MakeBulletTracerInternal(
|
||||
VectorSubtract(tImpacts[iImpSndIndexLB].endpos, cg.SoundOrg, vTmp);
|
||||
iHeadDist = VectorLength(vTmp);
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) <= 0.f)
|
||||
{
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) <= 0.f) {
|
||||
if (iHeadDist < 9999.0f || iHeadDist < fImpSndDistLB) {
|
||||
if (iHeadDist < 9999.0f) {
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistLB = 9999.0;
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistLB = 9999.0;
|
||||
iImpSndIndexRA = iBullet;
|
||||
} else if (iHeadDist < fImpSndDistLB) {
|
||||
fImpSndDistLB = iHeadDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB)
|
||||
{
|
||||
} else {
|
||||
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB) {
|
||||
if (iHeadDist < fImpSndDistRA) {
|
||||
iImpSndIndexRB = iImpSndIndexRA;
|
||||
iImpSndIndexRA = iBullet;
|
||||
} else if (iHeadDist < fImpSndDistRB) {
|
||||
fImpSndDistRB = iHeadDist;
|
||||
fImpSndDistRB = iHeadDist;
|
||||
iImpSndIndexRB = iBullet;
|
||||
}
|
||||
}
|
||||
@@ -720,11 +720,7 @@ static void CG_MakeBulletTracerInternal(
|
||||
} else {
|
||||
for (iBullet = 0; iBullet < iNumImpacts; iBullet++) {
|
||||
CG_MakeBulletHole(
|
||||
tImpacts[iBullet].endpos,
|
||||
tImpacts[iBullet].plane.normal,
|
||||
iNumImpacts,
|
||||
&tImpacts[iBullet],
|
||||
qtrue
|
||||
tImpacts[iBullet].endpos, tImpacts[iBullet].plane.normal, iNumImpacts, &tImpacts[iBullet], qtrue
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -732,10 +728,10 @@ static void CG_MakeBulletTracerInternal(
|
||||
if (fZingDistA < 9999.0f) {
|
||||
if (iLarge) {
|
||||
fVolume = 1.0f;
|
||||
fPitch = 0.8f;
|
||||
fPitch = 0.8f;
|
||||
} else {
|
||||
fVolume = 0.8f;
|
||||
fPitch = 1.0f;
|
||||
fPitch = 1.0f;
|
||||
}
|
||||
|
||||
commandManager.PlaySound("snd_b_zing", vZingPosA, -1, fVolume, -1.0f, fPitch, 1);
|
||||
@@ -774,13 +770,14 @@ static void CG_MakeBulletTracer(
|
||||
bullet_tracer->i_vEnd = &bullet_tracer_bullets[bullet_tracers_count];
|
||||
bullet_tracer->i_iNumBullets = i_iNumBullets;
|
||||
|
||||
for (i = 0; i < i_iNumBullets; ++i) {
|
||||
bullet_tracer_bullets[bullet_tracers_count][0] = (*i_vEnd)[i];
|
||||
bullet_tracer_bullets[bullet_tracers_count][1] = (*i_vEnd)[i + 1];
|
||||
bullet_tracer_bullets[bullet_tracers_count++][2] = (*i_vEnd)[i + 2];
|
||||
for (i = 0; i < i_iNumBullets; i++, bullet_tracers_count++) {
|
||||
bullet_tracer_bullets[bullet_tracers_count][0] = i_vEnd[i][0];
|
||||
bullet_tracer_bullets[bullet_tracers_count][1] = i_vEnd[i][1];
|
||||
bullet_tracer_bullets[bullet_tracers_count][2] = i_vEnd[i][2];
|
||||
}
|
||||
|
||||
bullet_tracer->iLarge = iLarge;
|
||||
bullet_tracer->alpha = alpha;
|
||||
bullet_tracer->iTracerVisible = iTracerVisible;
|
||||
bullet_tracer->bIgnoreEntities = bIgnoreEntities;
|
||||
}
|
||||
@@ -797,7 +794,8 @@ void CG_AddBulletTracers()
|
||||
bullet_tracers[i].i_iNumBullets,
|
||||
bullet_tracers[i].iLarge,
|
||||
bullet_tracers[i].iTracerVisible,
|
||||
bullet_tracers[i].bIgnoreEntities
|
||||
bullet_tracers[i].bIgnoreEntities,
|
||||
bullet_tracers[i].alpha
|
||||
);
|
||||
}
|
||||
|
||||
@@ -807,26 +805,24 @@ void CG_AddBulletTracers()
|
||||
|
||||
void CG_AddBulletImpacts()
|
||||
{
|
||||
int i;
|
||||
int iHeadDist;
|
||||
float fVolume;
|
||||
float fImpSndDistRA;
|
||||
int i;
|
||||
int iHeadDist;
|
||||
float fVolume;
|
||||
float fImpSndDistRA;
|
||||
static float fImpSndDistLA = 9999.f;
|
||||
float fImpSndDistRB;
|
||||
float fImpSndDistLB;
|
||||
int iImpSndIndexRA;
|
||||
int iImpSndIndexRB;
|
||||
int iImpSndIndexLB;
|
||||
vec3_t vTmp;
|
||||
str sSoundName;
|
||||
float fImpSndDistRB;
|
||||
float fImpSndDistLB;
|
||||
int iImpSndIndexRA;
|
||||
int iImpSndIndexRB;
|
||||
int iImpSndIndexLB;
|
||||
vec3_t vTmp;
|
||||
str sSoundName;
|
||||
|
||||
if (wall_impact_count)
|
||||
{
|
||||
if (wall_impact_count > 4)
|
||||
{
|
||||
fImpSndDistRA = fImpSndDistLA;
|
||||
fImpSndDistRB = fImpSndDistLA;
|
||||
fImpSndDistLB = fImpSndDistLA;
|
||||
if (wall_impact_count) {
|
||||
if (wall_impact_count > 4) {
|
||||
fImpSndDistRA = fImpSndDistLA;
|
||||
fImpSndDistRB = fImpSndDistLA;
|
||||
fImpSndDistLB = fImpSndDistLA;
|
||||
iImpSndIndexRA = 0;
|
||||
iImpSndIndexRB = 0;
|
||||
iImpSndIndexLB = 0;
|
||||
@@ -834,33 +830,28 @@ void CG_AddBulletImpacts()
|
||||
for (i = 0; i < wall_impact_count; i++) {
|
||||
VectorSubtract(wall_impact_pos[i], cg.SoundOrg, vTmp);
|
||||
iHeadDist = VectorLength(vTmp);
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f)
|
||||
{
|
||||
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB)
|
||||
{
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f) {
|
||||
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB) {
|
||||
if (iHeadDist < fImpSndDistRA) {
|
||||
fImpSndDistRB = fImpSndDistRA;
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistRB = fImpSndDistRA;
|
||||
fImpSndDistRA = iHeadDist;
|
||||
iImpSndIndexRB = iImpSndIndexRA;
|
||||
iImpSndIndexRA = i;
|
||||
} else if (iHeadDist < fImpSndDistRB) {
|
||||
fImpSndDistRB = iHeadDist;
|
||||
fImpSndDistRB = iHeadDist;
|
||||
iImpSndIndexRB = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iHeadDist < fImpSndDistLA || iHeadDist < fImpSndDistLB)
|
||||
{
|
||||
} else {
|
||||
if (iHeadDist < fImpSndDistLA || iHeadDist < fImpSndDistLB) {
|
||||
if (iHeadDist < fImpSndDistLA) {
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistLB = fImpSndDistLA;
|
||||
fImpSndDistRA = iHeadDist;
|
||||
fImpSndDistLB = fImpSndDistLA;
|
||||
iImpSndIndexLB = 0;
|
||||
iImpSndIndexRA = i;
|
||||
} else if (iHeadDist < fImpSndDistLB) {
|
||||
fImpSndDistLB = iHeadDist;
|
||||
fImpSndDistLB = iHeadDist;
|
||||
iImpSndIndexLB = i;
|
||||
}
|
||||
}
|
||||
@@ -908,8 +899,7 @@ void CG_AddBulletImpacts()
|
||||
|
||||
if (wall_impact_type[iImpSndIndexRB] == 2 || wall_impact_type[iImpSndIndexRB] == 3) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
}
|
||||
|
||||
@@ -942,26 +932,15 @@ void CG_AddBulletImpacts()
|
||||
|
||||
if (wall_impact_type[0] == 2 || wall_impact_type[0] == 3) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
}
|
||||
|
||||
commandManager.PlaySound(sSoundName, wall_impact_pos[0], -1, fVolume, -1, -1, 1);
|
||||
|
||||
sfxManager.MakeEffect_Normal(
|
||||
wall_impact_type[0],
|
||||
wall_impact_pos[0],
|
||||
wall_impact_norm[0]
|
||||
);
|
||||
sfxManager.MakeEffect_Normal(wall_impact_type[0], wall_impact_pos[0], wall_impact_norm[0]);
|
||||
} else {
|
||||
CG_MakeBulletHole(
|
||||
wall_impact_pos[0],
|
||||
wall_impact_norm[0],
|
||||
wall_impact_large[0],
|
||||
NULL,
|
||||
qtrue
|
||||
);
|
||||
CG_MakeBulletHole(wall_impact_pos[0], wall_impact_norm[0], wall_impact_large[0], NULL, qtrue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -969,15 +948,13 @@ void CG_AddBulletImpacts()
|
||||
if (wall_impact_type[iImpSndIndexLB]) {
|
||||
if (wall_impact_large[iImpSndIndexLB]) {
|
||||
fVolume = 1.f;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fVolume = 0.75f;
|
||||
}
|
||||
|
||||
if (wall_impact_type[iImpSndIndexLB] == 2 || wall_impact_type[iImpSndIndexLB] == 3) {
|
||||
sSoundName = "snd_bh_metal";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sSoundName = "snd_bh_wood";
|
||||
}
|
||||
|
||||
@@ -998,45 +975,31 @@ void CG_AddBulletImpacts()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
for (i = 0; i < wall_impact_count; i++) {
|
||||
CG_MakeBulletHole(
|
||||
wall_impact_pos[i],
|
||||
wall_impact_norm[i],
|
||||
wall_impact_large[i],
|
||||
NULL,
|
||||
qtrue
|
||||
);
|
||||
CG_MakeBulletHole(wall_impact_pos[i], wall_impact_norm[i], wall_impact_large[i], NULL, qtrue);
|
||||
}
|
||||
}
|
||||
|
||||
wall_impact_count = 0;
|
||||
}
|
||||
|
||||
if (flesh_impact_count)
|
||||
{
|
||||
if (flesh_impact_count > 1)
|
||||
{
|
||||
fImpSndDistRA = 9999.0;
|
||||
if (flesh_impact_count) {
|
||||
if (flesh_impact_count > 1) {
|
||||
fImpSndDistRA = 9999.0;
|
||||
iImpSndIndexRA = 0;
|
||||
|
||||
for (i = 0; i < flesh_impact_count; i++) {
|
||||
VectorSubtract(wall_impact_pos[i], cg.SoundOrg, vTmp);
|
||||
iHeadDist = VectorLength(vTmp);
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f)
|
||||
{
|
||||
if (iHeadDist < fImpSndDistRA)
|
||||
{
|
||||
fImpSndDistRA = iHeadDist;
|
||||
|
||||
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f) {
|
||||
if (iHeadDist < fImpSndDistRA) {
|
||||
fImpSndDistRA = iHeadDist;
|
||||
iImpSndIndexRA = i;
|
||||
}
|
||||
}
|
||||
else if (iHeadDist < fImpSndDistLA)
|
||||
{
|
||||
fImpSndDistRA = iHeadDist;
|
||||
} else if (iHeadDist < fImpSndDistLA) {
|
||||
fImpSndDistRA = iHeadDist;
|
||||
iImpSndIndexRA = i;
|
||||
}
|
||||
}
|
||||
@@ -1105,8 +1068,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_SNOW:
|
||||
switch (iBaseEffect)
|
||||
{
|
||||
switch (iBaseEffect) {
|
||||
case SFX_EXP_TANK_BASE:
|
||||
iSurfEffect = SFX_EXP_TANK_SNOW;
|
||||
break;
|
||||
@@ -1122,7 +1084,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
iBaseEffect = -1;
|
||||
break;
|
||||
}
|
||||
fRadius = 0;
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_CARPET:
|
||||
iSurfEffect = SFX_EXP_GREN_CARPET;
|
||||
@@ -1147,8 +1109,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_DIRT:
|
||||
switch (iBaseEffect)
|
||||
{
|
||||
switch (iBaseEffect) {
|
||||
case SFX_EXP_TANK_BASE:
|
||||
iSurfEffect = SFX_EXP_TANK_DIRT;
|
||||
break;
|
||||
@@ -1164,15 +1125,14 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
iBaseEffect = -1;
|
||||
break;
|
||||
}
|
||||
fRadius = 0;
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_GRILL:
|
||||
iSurfEffect = SFX_EXP_GREN_GRILL;
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_GRASS:
|
||||
switch (iBaseEffect)
|
||||
{
|
||||
switch (iBaseEffect) {
|
||||
case SFX_EXP_TANK_BASE:
|
||||
iSurfEffect = SFX_EXP_TANK_DIRT;
|
||||
break;
|
||||
@@ -1190,8 +1150,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
|
||||
fRadius = 0;
|
||||
break;
|
||||
case SURF_ROCK:
|
||||
switch (iBaseEffect)
|
||||
{
|
||||
switch (iBaseEffect) {
|
||||
case SFX_EXP_TANK_BASE:
|
||||
iSurfEffect = SFX_EXP_TANK_STONE;
|
||||
break;
|
||||
|
||||
+24
-2
@@ -25,6 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// interpolating between snapshots from the server or locally predicting
|
||||
// ahead the client's movement. It also handles local physics interaction,
|
||||
// like fragments bouncing off walls
|
||||
//
|
||||
// ADDITIONS:
|
||||
// - CG_InterpolatePlayerState() footer: Interpolate the lean angles
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
@@ -405,6 +408,9 @@ static void CG_InterpolatePlayerState(qboolean grabAngles)
|
||||
}
|
||||
out->velocity[i] = prev->ps.velocity[i] + f * (next->ps.velocity[i] - prev->ps.velocity[i]);
|
||||
}
|
||||
|
||||
// interpolate the lean angle
|
||||
out->fLeanAngle = LerpAngle(prev->ps.fLeanAngle, next->ps.fLeanAngle, f);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -477,8 +483,24 @@ void CG_PredictPlayerState(void)
|
||||
}
|
||||
|
||||
cg_pmove.noFootsteps = (cgs.dmflags & DF_NO_FOOTSTEPS) > 0;
|
||||
// Leaning while moving is allowed in mohta and mohtt only with a specific dm flag bit set
|
||||
cg_pmove.alwaysAllowLean = (cg_protocol < PROTOCOL_MOHTA_MIN) || (cgs.dmflags & DF_ALLOW_LEAN_MOVEMENT);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
// Leaning while moving is allowed in mohta and mohtt only with a specific dm flag bit set
|
||||
cg_pmove.alwaysAllowLean = (cgs.dmflags & DF_ALLOW_LEAN_MOVEMENT) ? qtrue : qfalse;
|
||||
|
||||
cg_pmove.leanMax = 45.f;
|
||||
cg_pmove.leanAdd = 6.f;
|
||||
cg_pmove.leanRecoverSpeed = 8.5f;
|
||||
cg_pmove.leanSpeed = 2.f;
|
||||
} else {
|
||||
cg_pmove.alwaysAllowLean = qtrue;
|
||||
|
||||
cg_pmove.leanMax = 40.f;
|
||||
cg_pmove.leanAdd = 10.f;
|
||||
cg_pmove.leanRecoverSpeed = 15.f;
|
||||
cg_pmove.leanSpeed = 4.f;
|
||||
}
|
||||
|
||||
cg_pmove.protocol = cg_protocol;
|
||||
|
||||
// save the state before the pmove so we can detect transitions
|
||||
oldPlayerState = cg.predicted_player_state;
|
||||
|
||||
+21
-7
@@ -23,8 +23,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// DESCRIPTION:
|
||||
// client game public interfaces
|
||||
|
||||
#ifndef __CG_PUBLIC_H__
|
||||
#define __CG_PUBLIC_H__
|
||||
#pragma once
|
||||
|
||||
#include "../renderercommon/tr_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -67,7 +68,7 @@ extern "C" {
|
||||
typedef struct stopWatch_s {
|
||||
int iStartTime;
|
||||
int iEndTime;
|
||||
|
||||
int eType;
|
||||
} stopWatch_t;
|
||||
|
||||
typedef struct AliasList_s AliasList_t;
|
||||
@@ -136,6 +137,8 @@ functions exported to the main executable
|
||||
void (*FS_FreeFile)(void *buf);
|
||||
int (*FS_WriteFile)(const char *qpath, const void *buffer, int size);
|
||||
void (*FS_WriteTextFile)(const char *qpath, const void *buffer, int size);
|
||||
char** (*FS_ListFilteredFiles)(const char* path, const char* extension, const char* filter, qboolean wantSubs, int* numfiles, qboolean allowNonPureFilesOnDisk);
|
||||
void (*FS_FreeFileList)(char **list);
|
||||
// add commands to the local console as if they were typed in
|
||||
// for map changing, etc. The command is not executed immediately,
|
||||
// but will be executed in order the next time console commands
|
||||
@@ -162,7 +165,7 @@ functions exported to the main executable
|
||||
void (*SendClientCommand)(const char *s);
|
||||
|
||||
// CM functions
|
||||
void (*CM_LoadMap)(const char *name);
|
||||
void (*CM_LoadMap)(const char *name, int* checksum);
|
||||
clipHandle_t (*CM_InlineModel)(int index); // 0 = world, 1+ = bmodels
|
||||
int (*CM_NumInlineModels)(void);
|
||||
int (*CM_PointContents)(const vec3_t p, int headnode);
|
||||
@@ -282,10 +285,11 @@ functions exported to the main executable
|
||||
qhandle_t (*R_RegisterModel)(const char *name);
|
||||
qhandle_t (*R_SpawnEffectModel)(const char *name, vec3_t pos, vec3_t axis[3]);
|
||||
qhandle_t (*R_RegisterServerModel)(const char *name);
|
||||
const char * (*R_GetModelName)(qhandle_t hModel);
|
||||
void (*R_UnregisterServerModel)(qhandle_t hModel);
|
||||
qhandle_t (*R_RegisterSkin)(const char *name);
|
||||
qhandle_t (*R_RegisterShader)(const char *name);
|
||||
qhandle_t (*R_RegisterShaderNoMip)(const char *name);
|
||||
const char* (*R_GetShaderName)(qhandle_t hShader);
|
||||
void (*R_AddRefEntityToScene)(const refEntity_t *ent, int parentEntityNumber);
|
||||
void (*R_AddRefSpriteToScene)(const refEntity_t *ent);
|
||||
void (*R_AddLightToScene)(const vec3_t origin, float intensity, float r, float g, float b, int type);
|
||||
@@ -419,9 +423,12 @@ functions exported to the main executable
|
||||
);
|
||||
void (*UI_DeleteScoreBoardItems)(int maxIndex);
|
||||
void (*UI_ToggleDMMessageConsole)(int consoleMode);
|
||||
void (*CL_InitRadar)(radarClient_t* radars, qhandle_t* shaders, int clientNum); // Added in 2.0
|
||||
dtiki_t *(*TIKI_FindTiki)(const char *path);
|
||||
void (*LoadResource)(const char *name);
|
||||
void (*FS_CanonicalFilename)(char *name);
|
||||
void (*CL_RestoreSavedCgameState)();
|
||||
void (*CL_ClearSavedCgameState)();
|
||||
|
||||
cvar_t *fsDebug;
|
||||
hdelement_t *HudDrawElements;
|
||||
@@ -491,6 +498,15 @@ functions exported to the main executable
|
||||
int (*CG_WeaponCommandButtonBits)();
|
||||
int (*CG_CheckCaptureKey)(int key, qboolean down, unsigned int time);
|
||||
|
||||
//
|
||||
// Added in 2.0
|
||||
//
|
||||
void (*CG_ReadNonPVSClient)(radarUnpacked_t* radarUnpacked);
|
||||
void (*CG_UpdateRadar)();
|
||||
size_t (*CG_SaveStateToBuffer)(void** out, int svsTime);
|
||||
qboolean (*CG_LoadStateToBuffer)(void* state, size_t size, int svsTime);
|
||||
void (*CG_CleanUpTempModels)();
|
||||
|
||||
// FIXME
|
||||
//prof_cgame_t* profStruct;
|
||||
|
||||
@@ -510,5 +526,3 @@ functions exported to the main executable
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __CG_PUBLIC_H__
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_radar.h"
|
||||
|
||||
void CG_InitRadar()
|
||||
{
|
||||
int i;
|
||||
|
||||
cg.radarShaders[0] = cgi.R_RegisterShader("textures/hud/radar_allies.tga");
|
||||
cg.radarShaders[1] = cgi.R_RegisterShader("textures/hud/radar_axis.tga");
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
cg.radars[i].time = 0;
|
||||
cg.radars[i].lastSpeakTime = 0;
|
||||
}
|
||||
|
||||
cgi.CL_InitRadar(cg.radars, cg.radarShaders, cg.snap->ps.clientNum);
|
||||
}
|
||||
|
||||
bool CG_InTeamGame(centity_t *ent)
|
||||
{
|
||||
return ent->currentState.solid && cg.clientinfo[ent->currentState.number].team;
|
||||
}
|
||||
|
||||
bool CG_SameTeam(centity_t *ent)
|
||||
{
|
||||
return cg.clientinfo[ent->currentState.number].team == cg.clientinfo[cg.snap->ps.clientNum].team;
|
||||
}
|
||||
|
||||
bool CG_IsTeamGame()
|
||||
{
|
||||
return cgs.gametype >= GT_TEAM;
|
||||
}
|
||||
|
||||
bool CG_ValidRadarClient(centity_t *ent)
|
||||
{
|
||||
if (!cg.snap) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!CG_IsTeamGame()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CG_InTeamGame(&cg_entities[cg.snap->ps.clientNum])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CG_InTeamGame(ent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CG_SameTeam(ent);
|
||||
}
|
||||
|
||||
int CG_RadarIcon()
|
||||
{
|
||||
switch (cg.clientinfo[cg.snap->ps.clientNum].team)
|
||||
{
|
||||
case TEAM_ALLIES:
|
||||
return 0;
|
||||
default:
|
||||
case TEAM_AXIS:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void CG_UpdateRadarClient(centity_t* ent)
|
||||
{
|
||||
radarClient_t* radar;
|
||||
|
||||
radar = &cg.radars[ent->currentState.number];
|
||||
if (!CG_ValidRadarClient(ent)) {
|
||||
radar->time = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
radar->time = cg.time;
|
||||
radar->teamShader = CG_RadarIcon();
|
||||
if (cg.snap->ps.clientNum == ent->currentState.number)
|
||||
{
|
||||
radar->origin[0] = cg.refdef.vieworg[0];
|
||||
radar->origin[1] = cg.refdef.vieworg[1];
|
||||
radar->axis[0] = cg.refdef.viewaxis[0][0];
|
||||
radar->axis[1] = cg.refdef.viewaxis[0][1];
|
||||
VectorNormalize2D(radar->axis);
|
||||
}
|
||||
else
|
||||
{
|
||||
float axis[2];
|
||||
|
||||
radar->origin[0] = ent->currentState.origin[0];
|
||||
radar->origin[1] = ent->currentState.origin[1];
|
||||
YawToAxis(ent->currentState.angles[1], axis);
|
||||
|
||||
radar->axis[0] = axis[0];
|
||||
radar->axis[1] = axis[1];
|
||||
VectorNormalize2D(radar->axis);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ReadNonPVSClient(radarUnpacked_t* radarUnpacked)
|
||||
{
|
||||
radarClient_t* radar;
|
||||
float axis[2];
|
||||
|
||||
if (!CG_ValidRadarClient(&cg_entities[radarUnpacked->clientNum])) {
|
||||
return;
|
||||
}
|
||||
|
||||
radar = &cg.radars[radarUnpacked->clientNum];
|
||||
radar->time = cg.time;
|
||||
radar->teamShader = CG_RadarIcon();
|
||||
// copy origin
|
||||
radar->origin[0] = radarUnpacked->x;
|
||||
radar->origin[1] = radarUnpacked->y;
|
||||
// copy yaw
|
||||
YawToAxis(radarUnpacked->yaw, axis);
|
||||
radar->axis[0] = axis[0];
|
||||
radar->axis[1] = axis[1];
|
||||
VectorNormalize2D(radar->axis);
|
||||
}
|
||||
|
||||
void CG_UpdateRadar()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if (cg.radars[i].time)
|
||||
{
|
||||
if (!CG_ValidRadarClient(&cg_entities[i])) {
|
||||
cg.radars[i].time = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CG_RadarClientSpeaks(int num)
|
||||
{
|
||||
if (!CG_ValidRadarClient(&cg_entities[num])) {
|
||||
return;
|
||||
}
|
||||
|
||||
cg.radars[num].lastSpeakTime = cg.time;
|
||||
}
|
||||
@@ -1,38 +1,42 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
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.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
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 Foobar; if not, write to the Free Software
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
#if !( defined __linux__ || defined __FreeBSD__ )
|
||||
#error You should include this file only on Linux/FreeBSD platforms
|
||||
|
||||
// DESCRIPTION:
|
||||
// Radar client
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __GLW_LINUX_H__
|
||||
#define __GLW_LINUX_H__
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *OpenGLLib; // instance of OpenGL library
|
||||
|
||||
FILE *log_fp;
|
||||
} glwstate_t;
|
||||
|
||||
extern glwstate_t glw_state;
|
||||
void CG_InitRadar();
|
||||
void CG_UpdateRadarClient(centity_t* ent);
|
||||
void CG_ReadNonPVSClient(radarUnpacked_t* radarUnpacked);
|
||||
void CG_UpdateRadar();
|
||||
void CG_RadarClientSpeaks(int num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+80
-27
@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// cg_servercmds.c -- text commands sent by the server
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "../fgame/bg_voteoptions.h"
|
||||
|
||||
static const char *IsWeaponAllowed(int dmFlags, int flags)
|
||||
{
|
||||
@@ -112,6 +113,7 @@ void CG_ParseServerinfo(void)
|
||||
char map[MAX_QPATH];
|
||||
char *spawnpos;
|
||||
const char *version;
|
||||
const char *mapChecksumStr;
|
||||
|
||||
info = CG_ConfigString(CS_SERVERINFO);
|
||||
cgs.gametype = atoi(Info_ValueForKey(info, "g_gametype"));
|
||||
@@ -135,12 +137,23 @@ void CG_ParseServerinfo(void)
|
||||
cgi.Cvar_Set("cg_obj_alliedtext1", Info_ValueForKey(info, "g_obj_alliedtext1"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext2", Info_ValueForKey(info, "g_obj_alliedtext2"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext3", Info_ValueForKey(info, "g_obj_alliedtext3"));
|
||||
cgi.Cvar_Set("cg_obj_axistext1", Info_ValueForKey(info, "cg_obj_axistext1"));
|
||||
cgi.Cvar_Set("cg_obj_axistext2", Info_ValueForKey(info, "cg_obj_axistext2"));
|
||||
cgi.Cvar_Set("cg_obj_axistext3", Info_ValueForKey(info, "cg_obj_axistext3"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext4", Info_ValueForKey(info, "g_obj_alliedtext4"));
|
||||
cgi.Cvar_Set("cg_obj_alliedtext5", Info_ValueForKey(info, "g_obj_alliedtext5"));
|
||||
cgi.Cvar_Set("cg_obj_axistext1", Info_ValueForKey(info, "g_obj_axistext1"));
|
||||
cgi.Cvar_Set("cg_obj_axistext2", Info_ValueForKey(info, "g_obj_axistext2"));
|
||||
cgi.Cvar_Set("cg_obj_axistext3", Info_ValueForKey(info, "g_obj_axistext3"));
|
||||
cgi.Cvar_Set("cg_obj_axistext4", Info_ValueForKey(info, "g_obj_axistext4"));
|
||||
cgi.Cvar_Set("cg_obj_axistext5", Info_ValueForKey(info, "g_obj_axistext5"));
|
||||
cgi.Cvar_Set("cg_scoreboardpic", Info_ValueForKey(info, "g_scoreboardpic"));
|
||||
cgi.Cvar_Set("cg_scoreboardpicover", Info_ValueForKey(info, "g_scoreboardpicover"));
|
||||
cgs.mapChecksum = atoi(Info_ValueForKey(info, "sv_mapChecksum"));
|
||||
mapChecksumStr = Info_ValueForKey(info, "sv_mapChecksum");
|
||||
if (mapChecksumStr && mapChecksumStr[0]) {
|
||||
cgs.mapChecksum = atoi(mapChecksumStr);
|
||||
cgs.useMapChecksum = qtrue;
|
||||
} else {
|
||||
cgs.mapChecksum = 0;
|
||||
cgs.useMapChecksum = qfalse;
|
||||
}
|
||||
|
||||
mapname = Info_ValueForKey(info, "mapname");
|
||||
|
||||
@@ -184,17 +197,13 @@ CG_ConfigStringModified
|
||||
|
||||
================
|
||||
*/
|
||||
static void CG_ConfigStringModified(void)
|
||||
static void CG_ConfigStringModified(int num, qboolean modelOnly)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = atoi(cgi.Argv(1));
|
||||
|
||||
// get the gamestate from the client system, which will have the
|
||||
// new configstring already integrated
|
||||
cgi.GetGameState(&cgs.gameState);
|
||||
|
||||
CG_ProcessConfigString(num);
|
||||
CG_ProcessConfigString(num, modelOnly);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -241,6 +250,13 @@ static void CG_Stopwatch_f()
|
||||
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cgi.stopWatch->iStartTime = atoi(cgi.Argv(1));
|
||||
|
||||
if (cgi.Argc() > 3) {
|
||||
cgi.stopWatch->eType = atoi(cgi.Argv(3));
|
||||
} else {
|
||||
// Normal stop watch
|
||||
cgi.stopWatch->eType = SWT_NORMAL;
|
||||
}
|
||||
} else {
|
||||
// The base game has it wrong
|
||||
cgi.stopWatch->iStartTime = 1000 * atoi(cgi.Argv(1));
|
||||
@@ -268,7 +284,7 @@ The string has been tokenized and can be retrieved with
|
||||
Cmd_Argc() / Cmd_Argv()
|
||||
=================
|
||||
*/
|
||||
static void CG_ServerCommand(void)
|
||||
static void CG_ServerCommand(qboolean modelOnly)
|
||||
{
|
||||
const char *cmd;
|
||||
|
||||
@@ -280,7 +296,11 @@ static void CG_ServerCommand(void)
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "cs")) {
|
||||
CG_ConfigStringModified();
|
||||
CG_ConfigStringModified(atoi(cgi.Argv(1)), modelOnly);
|
||||
return;
|
||||
}
|
||||
|
||||
if (modelOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -291,19 +311,19 @@ static void CG_ServerCommand(void)
|
||||
}
|
||||
return;
|
||||
} else if (!strcmp(cmd, "printdeathmsg")) {
|
||||
const char *s1, *s2, *s3, *s4, *s5;
|
||||
const char *s1, *s2, * attackerName, * victimName, *type;
|
||||
const char *result1, *result2;
|
||||
int hudColor;
|
||||
|
||||
result1 = NULL;
|
||||
result2 = NULL;
|
||||
s1 = cgi.Argv(1);
|
||||
s2 = cgi.Argv(2);
|
||||
s3 = cgi.Argv(3);
|
||||
s4 = cgi.Argv(4);
|
||||
s5 = cgi.Argv(5);
|
||||
s1 = cgi.Argv(1);
|
||||
s2 = cgi.Argv(2);
|
||||
attackerName = cgi.Argv(3);
|
||||
victimName = cgi.Argv(4);
|
||||
type = cgi.Argv(5);
|
||||
|
||||
if (*s5 == tolower(*s5)) {
|
||||
if (*type == tolower(*type)) {
|
||||
hudColor = 4;
|
||||
} else {
|
||||
hudColor = 5;
|
||||
@@ -315,16 +335,16 @@ static void CG_ServerCommand(void)
|
||||
if (*s2 != 'x') {
|
||||
result2 = cgi.LV_ConvertString(s2);
|
||||
}
|
||||
if (tolower(*s5) == 's') {
|
||||
cgi.Printf("%c%s %s\n", hudColor, s4, result1);
|
||||
} else if (tolower(*s5) == 'p') {
|
||||
if (tolower(*type) == 's') {
|
||||
cgi.Printf("%c%s %s\n", hudColor, victimName, result1);
|
||||
} else if (tolower(*type) == 'p') {
|
||||
if (*s2 == 'x') {
|
||||
cgi.Printf("%c%s %s %s\n", hudColor, s4, result1, s3);
|
||||
cgi.Printf("%c%s %s %s\n", hudColor, victimName, result1, attackerName);
|
||||
} else {
|
||||
cgi.Printf("%c%s %s %s%s\n", hudColor, s4, result1, s3, result2);
|
||||
cgi.Printf("%c%s %s %s%s\n", hudColor, victimName, result1, attackerName, result2);
|
||||
}
|
||||
} else if (tolower(*s5) == 'w') {
|
||||
cgi.Printf("%c%s %s\n", hudColor, s4, result1);
|
||||
} else if (tolower(*type) == 'w') {
|
||||
cgi.Printf("%c%s %s\n", hudColor, victimName, result1);
|
||||
} else {
|
||||
cgi.Printf("%s", cgi.Argv(1));
|
||||
}
|
||||
@@ -357,6 +377,28 @@ static void CG_ServerCommand(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "voteresult")) {
|
||||
cmd = cgi.Argv(1);
|
||||
if (*cmd) {
|
||||
strcmp(cmd, "passed");
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "vo0")) {
|
||||
CG_VoteOptions_StartReadFromServer(cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "vo1")) {
|
||||
CG_VoteOptions_ContinueReadFromServer(cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "vo2")) {
|
||||
CG_VoteOptions_FinishReadFromServer(cgi.Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
cgi.Printf("Unknown client game command: %s\n", cmd);
|
||||
}
|
||||
|
||||
@@ -370,9 +412,20 @@ with this this snapshot.
|
||||
*/
|
||||
void CG_ExecuteNewServerCommands(int latestSequence, qboolean differentServer)
|
||||
{
|
||||
int lastServerCommandSequence;
|
||||
|
||||
lastServerCommandSequence = cgs.serverCommandSequence;
|
||||
|
||||
while (cgs.serverCommandSequence < latestSequence) {
|
||||
if (cgi.GetServerCommand(++cgs.serverCommandSequence, differentServer)) {
|
||||
CG_ServerCommand();
|
||||
CG_ServerCommand(qtrue);
|
||||
}
|
||||
}
|
||||
|
||||
cgs.serverCommandSequence = lastServerCommandSequence;
|
||||
while (cgs.serverCommandSequence < latestSequence) {
|
||||
if (cgi.GetServerCommand(++cgs.serverCommandSequence, differentServer)) {
|
||||
CG_ServerCommand(qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// DESCRIPTION:
|
||||
// things that happen on snapshot transition, not necessarily every
|
||||
// single frame
|
||||
//
|
||||
// ADDITIONS:
|
||||
// - CG_TransitionSnapshot() footer: set ps.walking to true if the ps has a ground entity
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_radar.h"
|
||||
#include "tiki.h"
|
||||
|
||||
/*
|
||||
@@ -161,6 +165,9 @@ void CG_SetInitialSnapshot(snapshot_t *snap)
|
||||
cgi.MUSIC_UpdateMood(snap->ps.current_music_mood, snap->ps.fallback_music_mood);
|
||||
cgi.MUSIC_UpdateVolume(snap->ps.music_volume, snap->ps.music_volume_fade_time);
|
||||
cgi.S_SetReverb(snap->ps.reverb_type, snap->ps.reverb_level);
|
||||
|
||||
CG_InitRadar();
|
||||
cgi.CL_RestoreSavedCgameState();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -203,6 +210,9 @@ static void CG_TransitionSnapshot(qboolean differentServer)
|
||||
cent->teleported = qfalse;
|
||||
}
|
||||
CG_TransitionEntity(cent);
|
||||
|
||||
// remember time of snapshot this entity was last updated in
|
||||
cent->snapShotTime = cg.snap->serverTime;
|
||||
}
|
||||
|
||||
for (i = 0; i < cg.snap->number_of_sounds; i++) {
|
||||
@@ -240,6 +250,15 @@ static void CG_TransitionSnapshot(qboolean differentServer)
|
||||
CG_TransitionPlayerState(ps, ops);
|
||||
}
|
||||
}
|
||||
|
||||
if (differentServer) {
|
||||
cgi.CL_RestoreSavedCgameState();
|
||||
} else {
|
||||
cgi.CL_ClearSavedCgameState();
|
||||
}
|
||||
|
||||
// this allows the view model to still look normal when the player is on ground
|
||||
cg.snap->ps.walking = cg.snap->ps.groundEntityNum != ENTITYNUM_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+221
-118
@@ -28,6 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "tiki.h"
|
||||
|
||||
cvar_t *cg_showtempmodels;
|
||||
cvar_t *cg_max_tempmodels;
|
||||
cvar_t *cg_reserve_tempmodels;
|
||||
cvar_t *cg_detail;
|
||||
cvar_t *cg_effectdetail;
|
||||
cvar_t *cg_effect_physicsrate;
|
||||
@@ -86,6 +88,83 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
|
||||
m_free_tempmodels = p;
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeAllTempModels
|
||||
//===============
|
||||
void ClientGameCommandManager::FreeAllTempModels(void)
|
||||
{
|
||||
ctempmodel_t *p, *next;
|
||||
|
||||
// Go through all the temp models and run the physics if necessary,
|
||||
// then add them to the ref
|
||||
p = m_active_tempmodels.prev;
|
||||
for (; p != &m_active_tempmodels; p = next) {
|
||||
// grab next now, so if the local entity is freed we still have it
|
||||
next = p->prev;
|
||||
FreeTempModel(p);
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeSomeTempModels
|
||||
//===============
|
||||
void ClientGameCommandManager::FreeSomeTempModels(void)
|
||||
{
|
||||
ctempmodel_t* model;
|
||||
int count = 0;
|
||||
unsigned int i;
|
||||
unsigned int numToFree;
|
||||
|
||||
if (!m_free_tempmodels) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (model = m_active_tempmodels.prev; model != &m_active_tempmodels; model = model->prev) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (cg_reserve_tempmodels->integer <= (cg_max_tempmodels->integer - count)) {
|
||||
// nothing to free
|
||||
return;
|
||||
}
|
||||
|
||||
numToFree = cg_reserve_tempmodels->integer - (cg_max_tempmodels->integer - count);
|
||||
|
||||
for (i = 0; i < numToFree; i++) {
|
||||
FreeTempModel(m_active_tempmodels.prev);
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeSpawnthing
|
||||
//===============
|
||||
void ClientGameCommandManager::FreeSpawnthing(spawnthing_t* sp)
|
||||
{
|
||||
ctempmodel_t* model;
|
||||
ctempmodel_t* prev;
|
||||
|
||||
if (sp->numtempmodels) {
|
||||
for (model = m_active_tempmodels.prev; model != &m_active_tempmodels; model = prev) {
|
||||
prev = model->prev;
|
||||
|
||||
if (model->m_spawnthing == sp) {
|
||||
FreeTempModel(model);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_emitters.RemoveObject(sp);
|
||||
|
||||
if (sp == m_spawnthing) {
|
||||
m_spawnthing = NULL;
|
||||
}
|
||||
|
||||
delete sp;
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
// ResetTempModels
|
||||
//===============
|
||||
void ClientGameCommandManager::ResetTempModels(void)
|
||||
{
|
||||
// Go through all the active tempmodels and free them
|
||||
@@ -99,6 +178,7 @@ void ClientGameCommandManager::ResetTempModels(void)
|
||||
}
|
||||
|
||||
static int lastTempModelFrameTime = 0;
|
||||
int next_tempmodel_warning = 0;
|
||||
|
||||
void CG_ResetTempModels(void)
|
||||
{
|
||||
@@ -128,9 +208,23 @@ void ClientGameCommandManager::InitializeTempModels(void)
|
||||
void ClientGameCommandManager::InitializeTempModelCvars(void)
|
||||
{
|
||||
cg_showtempmodels = cgi.Cvar_Get("cg_showtempmodels", "0", 0);
|
||||
cg_detail = cgi.Cvar_Get("detail", "1", 1);
|
||||
cg_effectdetail = cgi.Cvar_Get("cg_effectdetail", "0.2", 1);
|
||||
cg_effect_physicsrate = cgi.Cvar_Get("cg_effect_physicsrate", "10", 1);
|
||||
cg_detail = cgi.Cvar_Get("detail", "1", CVAR_ARCHIVE);
|
||||
cg_effectdetail = cgi.Cvar_Get("cg_effectdetail", "0.2", CVAR_ARCHIVE);
|
||||
cg_effect_physicsrate = cgi.Cvar_Get("cg_effect_physicsrate", "10", CVAR_ARCHIVE);
|
||||
cg_max_tempmodels = cgi.Cvar_Get("cg_max_tempmodels", "1100", CVAR_ARCHIVE);
|
||||
cg_reserve_tempmodels = cgi.Cvar_Get("cg_reserve_tempmodels", "200", CVAR_ARCHIVE);
|
||||
|
||||
if (cg_max_tempmodels->integer > MAX_TEMPMODELS) {
|
||||
// 2.40 sets the integer value directly rather than calling Cvar_Set()
|
||||
//cg_max_tempmodels->integer = MAX_TEMPMODELS
|
||||
cgi.Cvar_Set("cg_max_tempmodels", va("%i", MAX_TEMPMODELS));
|
||||
}
|
||||
|
||||
if (cg_reserve_tempmodels->integer * 5 > cg_max_tempmodels->integer) {
|
||||
// 2.40 sets the integer value directly rather than calling Cvar_Set()
|
||||
//cg_reserve_tempmodels->integer = cg_max_tempmodels->integer / 5;
|
||||
cgi.Cvar_Set("cg_reserve_tempmodels", va("%i", cg_max_tempmodels->integer / 5));
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
@@ -141,6 +235,7 @@ void ClientGameCommandManager::AnimateTempModel(ctempmodel_t *p, Vector origin,
|
||||
int numframes;
|
||||
int deltatime;
|
||||
int frametime;
|
||||
float prev;
|
||||
|
||||
// This code is for animating tempmodels that are spawned from the client
|
||||
// side
|
||||
@@ -165,10 +260,18 @@ void ClientGameCommandManager::AnimateTempModel(ctempmodel_t *p, Vector origin,
|
||||
|
||||
// Go through all the frames, and process any commands associated with the
|
||||
// tempmodel as well
|
||||
prev = deltatime;
|
||||
while (deltatime >= frametime) {
|
||||
deltatime -= frametime;
|
||||
p->lastAnimTime += frametime;
|
||||
p->ent.wasframe = (p->ent.wasframe + 1) % numframes;
|
||||
CG_ProcessEntityCommands(p->ent.wasframe, p->ent.frameInfo[0].index, -1, &p->ent, NULL);
|
||||
|
||||
if (deltatime == prev) {
|
||||
break;
|
||||
}
|
||||
|
||||
prev = deltatime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,9 +311,10 @@ void ClientGameCommandManager::UpdateSwarm(ctempmodel_t *p)
|
||||
}
|
||||
}
|
||||
|
||||
qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float dtime, float scale)
|
||||
qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, float ftime, float scale)
|
||||
{
|
||||
float fade, fadein;
|
||||
float dtime;
|
||||
byte tempColor[4];
|
||||
|
||||
if (p->cgd.flags & (T_FADE | T_SCALEUPDOWN)) {
|
||||
@@ -362,9 +466,19 @@ void ClientGameCommandManager::OtherTempModelEffects(ctempmodel_t *p, Vector ori
|
||||
vec3_t axis[3];
|
||||
|
||||
if (p->number != -1) {
|
||||
refEntity_t *old_entity;
|
||||
dtiki_t *old_tiki;
|
||||
int oldnum;
|
||||
float oldscale;
|
||||
|
||||
// Set the axis
|
||||
AnglesToAxis(p->cgd.angles, axis);
|
||||
|
||||
old_entity = current_entity;
|
||||
old_tiki = current_tiki;
|
||||
oldnum = current_entity_number;
|
||||
oldscale = current_scale;
|
||||
|
||||
current_scale = newEnt->scale;
|
||||
current_entity = newEnt;
|
||||
current_tiki = p->cgd.tiki;
|
||||
@@ -380,14 +494,23 @@ void ClientGameCommandManager::OtherTempModelEffects(ctempmodel_t *p, Vector ori
|
||||
commandManager.ProcessEvent(ev);
|
||||
}
|
||||
|
||||
current_entity_number = -1;
|
||||
current_tiki = NULL;
|
||||
current_entity = NULL;
|
||||
current_scale = -1;
|
||||
current_entity_number = oldnum;
|
||||
current_tiki = old_tiki;
|
||||
current_entity = old_entity;
|
||||
current_scale = oldscale;
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_ALIGNSTRETCH) {
|
||||
Vector vDelta;
|
||||
float fScale;
|
||||
|
||||
vDelta = p->cgd.origin - p->cgd.oldorigin;
|
||||
fScale = vDelta.length() * p->cgd.scale2;
|
||||
VectorScale(newEnt->axis[0], fScale, newEnt->axis[0]);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime, float time2, float scale)
|
||||
qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime, float scale)
|
||||
{
|
||||
int dtime;
|
||||
Vector parentOrigin(0, 0, 0);
|
||||
@@ -406,37 +529,41 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
|
||||
// Update based on swarm
|
||||
if (p->cgd.flags & T_SWARM) {
|
||||
p->cgd.origin += ftime * p->cgd.velocity * scale;
|
||||
p->cgd.origin += p->cgd.velocity * ftime * scale;
|
||||
}
|
||||
|
||||
// Update the orign and the angles based on velocities first
|
||||
if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL)) {
|
||||
p->cgd.origin = p->cgd.origin + (p->cgd.velocity * ftime * scale) + (time2 * p->cgd.accel);
|
||||
else if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL)) {
|
||||
p->cgd.origin += p->cgd.velocity * ftime * scale;
|
||||
}
|
||||
|
||||
// If linked to the parent or hardlinked, get the parent's origin
|
||||
if ((p->cgd.flags & (T_PARENTLINK | T_HARDLINK)) && (p->cgd.parent != ENTITYNUM_NONE)) {
|
||||
centity_t *pc;
|
||||
centity_t* pc;
|
||||
refEntity_t* e;
|
||||
|
||||
pc = &cg_entities[p->cgd.parent];
|
||||
|
||||
if (pc->currentValid) {
|
||||
refEntity_t *e;
|
||||
|
||||
e = cgi.R_GetRenderEntity(p->cgd.parent);
|
||||
|
||||
if (!e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parentOrigin = e->origin;
|
||||
vectoangles(e->axis[0], parentAngles);
|
||||
} else {
|
||||
if (!pc->currentValid) {
|
||||
return false;
|
||||
}
|
||||
} else if (p->cgd.flags & T_SWARM) {
|
||||
|
||||
e = cgi.R_GetRenderEntity(p->cgd.parent);
|
||||
if (!e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parentOrigin = e->origin;
|
||||
vectoangles(e->axis[0], parentAngles);
|
||||
}
|
||||
else if (p->cgd.flags & T_SWARM) {
|
||||
p->cgd.parentOrigin = p->cgd.velocity + p->cgd.accel * ftime * scale;
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_WATERONLY) {
|
||||
if (!(cgi.CM_PointContents(p->cgd.origin, 0) & (CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Align the object along it's traveling vector
|
||||
if (p->cgd.flags & T_ALIGN) {
|
||||
p->cgd.angles = p->cgd.velocity.toAngles();
|
||||
@@ -457,12 +584,12 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
p->cgd.angles[1] = AngleMod(p->cgd.angles[1]);
|
||||
p->cgd.angles[2] = AngleMod(p->cgd.angles[2]);
|
||||
|
||||
// Add in parent angles
|
||||
tempangles = p->cgd.angles + parentAngles;
|
||||
|
||||
// Convert to axis
|
||||
if ((p->cgd.flags & (T_ALIGN | T_RANDOMROLL | T_PARENTLINK | T_HARDLINK | T_ANGLES))
|
||||
|| (p->cgd.flags2 & T2_AMOVE)) {
|
||||
// Add in parent angles
|
||||
tempangles = p->cgd.angles + parentAngles;
|
||||
|
||||
AnglesToAxis(tempangles, p->ent.axis);
|
||||
}
|
||||
|
||||
@@ -503,25 +630,9 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_CLAMP_VEL) {
|
||||
if (p->cgd.velocity.x < p->cgd.minVel.x) {
|
||||
p->cgd.velocity.x = p->cgd.minVel.x;
|
||||
}
|
||||
if (p->cgd.velocity.y < p->cgd.minVel.y) {
|
||||
p->cgd.velocity.y = p->cgd.minVel.y;
|
||||
}
|
||||
if (p->cgd.velocity.z < p->cgd.minVel.z) {
|
||||
p->cgd.velocity.z = p->cgd.minVel.z;
|
||||
}
|
||||
|
||||
if (p->cgd.velocity.x > p->cgd.maxVel.x) {
|
||||
p->cgd.velocity.x = p->cgd.maxVel.x;
|
||||
}
|
||||
if (p->cgd.velocity.y > p->cgd.maxVel.y) {
|
||||
p->cgd.velocity.y = p->cgd.maxVel.y;
|
||||
}
|
||||
if (p->cgd.velocity.z > p->cgd.maxVel.z) {
|
||||
p->cgd.velocity.z = p->cgd.maxVel.z;
|
||||
}
|
||||
p->cgd.velocity.x = Q_clamp_float(p->cgd.velocity.x, p->cgd.minVel.x, p->cgd.maxVel.x);
|
||||
p->cgd.velocity.y = Q_clamp_float(p->cgd.velocity.y, p->cgd.minVel.y, p->cgd.maxVel.y);
|
||||
p->cgd.velocity.z = Q_clamp_float(p->cgd.velocity.z, p->cgd.minVel.z, p->cgd.maxVel.z);
|
||||
}
|
||||
|
||||
if (p->cgd.flags2 & T2_CLAMP_VEL_AXIS) {
|
||||
@@ -530,25 +641,9 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
localVelocity.y = DotProduct(p->cgd.velocity, p->ent.axis[1]);
|
||||
localVelocity.z = DotProduct(p->cgd.velocity, p->ent.axis[2]);
|
||||
|
||||
if (localVelocity.x < p->cgd.minVel.x) {
|
||||
localVelocity.x = p->cgd.minVel.x;
|
||||
}
|
||||
if (localVelocity.y < p->cgd.minVel.y) {
|
||||
localVelocity.y = p->cgd.minVel.y;
|
||||
}
|
||||
if (localVelocity.z < p->cgd.minVel.z) {
|
||||
localVelocity.z = p->cgd.minVel.z;
|
||||
}
|
||||
|
||||
if (localVelocity.x > p->cgd.maxVel.x) {
|
||||
localVelocity.x = p->cgd.maxVel.x;
|
||||
}
|
||||
if (localVelocity.y > p->cgd.maxVel.y) {
|
||||
localVelocity.y = p->cgd.maxVel.y;
|
||||
}
|
||||
if (localVelocity.z > p->cgd.maxVel.z) {
|
||||
localVelocity.z = p->cgd.maxVel.z;
|
||||
}
|
||||
localVelocity.x = Q_clamp_float(localVelocity.x, p->cgd.minVel.x, p->cgd.maxVel.x);
|
||||
localVelocity.y = Q_clamp_float(localVelocity.y, p->cgd.minVel.y, p->cgd.maxVel.y);
|
||||
localVelocity.z = Q_clamp_float(localVelocity.z, p->cgd.minVel.z, p->cgd.maxVel.z);
|
||||
|
||||
p->cgd.velocity.x = DotProduct(localVelocity, p->ent.axis[0]);
|
||||
p->cgd.velocity.y = DotProduct(localVelocity, p->ent.axis[1]);
|
||||
@@ -559,14 +654,6 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
// FIXME: vss wind
|
||||
}
|
||||
} else {
|
||||
if (p->touchfcn) {
|
||||
p->touchfcn(p, &trace);
|
||||
}
|
||||
|
||||
if (p->cgd.flags & T_DIETOUCH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector normal;
|
||||
|
||||
// Set the origin
|
||||
@@ -581,14 +668,14 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
trace.endpos,
|
||||
trace.plane.normal,
|
||||
p->cgd.decal_orientation,
|
||||
p->cgd.decal_radius,
|
||||
p->cgd.color[0],
|
||||
p->cgd.color[1],
|
||||
p->cgd.color[2],
|
||||
p->cgd.alpha,
|
||||
p->cgd.flags & T_FADE,
|
||||
p->cgd.decal_radius,
|
||||
p->cgd.flags2 & T2_TEMPORARY_DECAL,
|
||||
p->cgd.lightstyle,
|
||||
qtrue,
|
||||
p->cgd.flags & T_FADEIN
|
||||
);
|
||||
|
||||
@@ -610,9 +697,10 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
|
||||
dot = p->cgd.velocity * normal;
|
||||
p->cgd.velocity = p->cgd.velocity + ((-2 * dot) * normal);
|
||||
p->cgd.velocity *= p->cgd.bouncefactor;
|
||||
p->cgd.avelocity *= -p->cgd.bouncefactor;
|
||||
|
||||
// check for stop
|
||||
if (trace.plane.normal[2] > 0 && p->cgd.velocity[2] < 40) {
|
||||
if (trace.plane.normal[2] > 0 && p->cgd.velocity[2] < 45) {
|
||||
p->cgd.velocity = Vector(0, 0, 0);
|
||||
p->cgd.avelocity = Vector(0, 0, 0);
|
||||
p->cgd.flags &= ~T_WAVE;
|
||||
@@ -685,7 +773,7 @@ qboolean ClientGameCommandManager::LerpTempModel(refEntity_t *newEnt, ctempmodel
|
||||
// Add the parent ent's origin to the local origin
|
||||
VectorAdd(newEnt->origin, parentOrigin, newEnt->origin);
|
||||
} else {
|
||||
if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL)) {
|
||||
if (p->cgd.flags2 & (T2_MOVE | T2_ACCEL) || (p->cgd.flags & T_SWARM)) {
|
||||
// Lerp the ent's origin
|
||||
for (i = 0; i < 3; i++) {
|
||||
newEnt->origin[i] = p->lastEnt.origin[i] + frac * (p->ent.origin[i] - p->lastEnt.origin[i]);
|
||||
@@ -741,16 +829,17 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
refEntity_t *old_ent;
|
||||
|
||||
// To counteract cg.time going backwards
|
||||
if (lastTempModelFrameTime) {
|
||||
if ((cg.time < lastTempModelFrameTime) || (cg.time - lastTempModelFrameTime > TOO_MUCH_TIME_PASSED)) {
|
||||
p = m_active_tempmodels.prev;
|
||||
for (; p != &m_active_tempmodels; p = next) {
|
||||
next = p->prev;
|
||||
p->lastPhysicsTime = cg.time;
|
||||
}
|
||||
lastTempModelFrameTime = cg.time;
|
||||
return;
|
||||
if (lastTempModelFrameTime && ((cg.time < lastTempModelFrameTime) || (cg.time - lastTempModelFrameTime > TOO_MUCH_TIME_PASSED))) {
|
||||
p = m_active_tempmodels.prev;
|
||||
for (; p != &m_active_tempmodels; p = next) {
|
||||
next = p->prev;
|
||||
p->lastPhysicsTime = cg.time;
|
||||
}
|
||||
lastTempModelFrameTime = cg.time;
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastTempModelFrameTime) {
|
||||
frameTime = cg.time - lastTempModelFrameTime;
|
||||
} else {
|
||||
frameTime = 0;
|
||||
@@ -763,6 +852,7 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
}
|
||||
|
||||
memset(&newEnt, 0, sizeof(newEnt));
|
||||
newEnt.parentEntity = ENTITYNUM_NONE;
|
||||
// Set this frame time for the next one
|
||||
effectTime = (float)frameTime / 1000.0f;
|
||||
effectTime2 = effectTime * effectTime;
|
||||
@@ -793,7 +883,7 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
current_tiki = p->cgd.tiki;
|
||||
current_entity_number = p->number;
|
||||
|
||||
TempModelRealtimeEffects(p, effectTime, effectTime2, scale);
|
||||
TempModelRealtimeEffects(p, effectTime, scale);
|
||||
|
||||
if (p->lastPhysicsTime) {
|
||||
mstime = cg.time - p->lastPhysicsTime;
|
||||
@@ -808,8 +898,7 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
|
||||
if ((mstime >= physics_rate) || (p->cgd.flags2 & T2_PHYSICS_EVERYFRAME)) {
|
||||
ftime = mstime / 1000.0f;
|
||||
time2 = ftime * ftime;
|
||||
ret = TempModelPhysics(p, ftime, time2, scale);
|
||||
ret = TempModelPhysics(p, ftime, scale);
|
||||
|
||||
if (!ret) {
|
||||
FreeTempModel(p);
|
||||
@@ -823,14 +912,8 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
// Calculate the lerp value based on the time passed since last physics
|
||||
// time of this tempmodel
|
||||
lerpfrac = (float)(cg.time - p->lastPhysicsTime) / (float)physics_rate;
|
||||
|
||||
// Clamp
|
||||
if (lerpfrac > 1) {
|
||||
lerpfrac = 1;
|
||||
}
|
||||
if (lerpfrac < 0) {
|
||||
lerpfrac = 0;
|
||||
}
|
||||
lerpfrac = Q_clamp_float(lerpfrac, 0, 1);
|
||||
|
||||
// Increment the time this tempmodel has been alive
|
||||
p->aliveTime += frameTime;
|
||||
@@ -843,11 +926,10 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
|
||||
// Run physics if the lastEnt is not valid to get a valid lerp
|
||||
if (!p->lastEntValid) {
|
||||
float t, t2;
|
||||
float t;
|
||||
t = physics_rate / 1000.0f;
|
||||
t2 = t * t;
|
||||
|
||||
ret = TempModelPhysics(p, t, t2, scale);
|
||||
ret = TempModelPhysics(p, t, scale);
|
||||
if (!ret) {
|
||||
FreeTempModel(p);
|
||||
continue;
|
||||
@@ -872,12 +954,12 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
}
|
||||
|
||||
if (p->cgd.flags & T_WAVE) {
|
||||
Vector origin;
|
||||
vec3_t origin;
|
||||
float axis[3][3];
|
||||
|
||||
origin = Vector(p->m_spawnthing->linked_origin) + Vector(p->m_spawnthing->linked_axis[0]) * newEnt.origin[0]
|
||||
+ Vector(p->m_spawnthing->linked_axis[1]) * newEnt.origin[1]
|
||||
+ Vector(p->m_spawnthing->linked_axis[2]) * newEnt.origin[2];
|
||||
VectorMA(p->m_spawnthing->linked_origin, newEnt.origin[0], p->m_spawnthing->linked_axis[0], origin);
|
||||
VectorMA(origin, newEnt.origin[1], p->m_spawnthing->linked_axis[1], origin);
|
||||
VectorMA(origin, newEnt.origin[2], p->m_spawnthing->linked_axis[2], origin);
|
||||
|
||||
VectorCopy(origin, newEnt.origin);
|
||||
|
||||
@@ -891,7 +973,10 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
newEnt.reType = p->ent.reType;
|
||||
newEnt.shaderTime = p->ent.shaderTime;
|
||||
|
||||
newEnt.frameInfo[0] = p->ent.frameInfo[0];
|
||||
newEnt.frameInfo[0].index = p->ent.frameInfo[0].index;
|
||||
newEnt.frameInfo[0].weight = 1.0;
|
||||
newEnt.frameInfo[0].time = 0.0;
|
||||
|
||||
newEnt.wasframe = p->ent.wasframe;
|
||||
newEnt.actionWeight = 1.0;
|
||||
newEnt.entityNumber = ENTITYNUM_NONE;
|
||||
@@ -901,6 +986,9 @@ void ClientGameCommandManager::AddTempModels(void)
|
||||
|
||||
OtherTempModelEffects(p, newEnt.origin, &newEnt);
|
||||
|
||||
VectorCopy(newEnt.origin, newEnt.lightingOrigin);
|
||||
newEnt.radius = 4.0;
|
||||
|
||||
// Add to the ref
|
||||
if (p->cgd.flags & T_DLIGHT) {
|
||||
// Tempmodel is a Dynamic Light
|
||||
@@ -960,6 +1048,14 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
Vector delta;
|
||||
Vector start;
|
||||
Vector vForward, vLeft, vUp;
|
||||
float fDist;
|
||||
|
||||
delta = m_spawnthing->cgd.origin - cg.refdef.vieworg;
|
||||
fDist = delta * delta * (cg.refdef.fov_x * cg.refdef.fov_x / 6400.0);
|
||||
if (fDist >= m_spawnthing->fMaxRangeSquared || fDist < m_spawnthing->fMinRangeSquared) {
|
||||
// don't draw above the distance
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_entity) {
|
||||
current_entity_scale = current_entity->scale;
|
||||
@@ -1003,7 +1099,11 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
p = AllocateTempModel();
|
||||
|
||||
if (!p) {
|
||||
cgi.DPrintf("Out of tempmodels\n");
|
||||
if (cgi.Milliseconds() >= next_tempmodel_warning) {
|
||||
// make sure to not spam the console with this message
|
||||
cgi.DPrintf("Out of tempmodels\n");
|
||||
next_tempmodel_warning = cgi.Milliseconds() + 1000;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1027,9 +1127,11 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
|
||||
// Set up the origin of the tempmodel
|
||||
if (m_spawnthing->cgd.flags & T_SPHERE) {
|
||||
// Create a random forward vector so the particles burst out in a
|
||||
// sphere
|
||||
newForward = Vector(crandom(), crandom(), crandom());
|
||||
do {
|
||||
// Create a random forward vector so the particles burst out in a
|
||||
// sphere
|
||||
newForward = Vector(crandom(), crandom(), crandom());
|
||||
} while (newForward * newForward > 1.0);
|
||||
} else if (m_spawnthing->cgd.flags & T_CIRCLE) {
|
||||
if (m_spawnthing->sphereRadius != 0) // Offset by the radius
|
||||
{
|
||||
@@ -1049,7 +1151,9 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
// vector pointing back to the origin
|
||||
Vector dir, end;
|
||||
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
do {
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
} while (dir * dir > 1.0);
|
||||
|
||||
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius * current_entity_scale;
|
||||
VectorCopy(end, p->cgd.origin);
|
||||
@@ -1078,10 +1182,9 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
cosa = cos(fAngle);
|
||||
|
||||
p->cgd.origin = start + vForward * fHeight;
|
||||
p->cgd.origin += start + vLeft * (cosa * fRadius);
|
||||
p->cgd.origin += start + vUp * (sina * fRadius);
|
||||
} else if (m_spawnthing->sphereRadius != 0) // Offset in a spherical pattern
|
||||
{
|
||||
p->cgd.origin += vLeft * (cosa * fRadius);
|
||||
p->cgd.origin += vUp * (sina * fRadius);
|
||||
} else if (m_spawnthing->sphereRadius != 0) { // Offset in a spherical pattern
|
||||
Vector dir, end;
|
||||
|
||||
dir = Vector(crandom(), crandom(), crandom());
|
||||
@@ -1092,7 +1195,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
|
||||
VectorCopy(end, p->cgd.origin);
|
||||
newForward = dir;
|
||||
} else {
|
||||
VectorCopy(m_spawnthing->cgd.origin, p->cgd.origin);
|
||||
VectorCopy(start, p->cgd.origin);
|
||||
}
|
||||
|
||||
if (m_spawnthing->cgd.flags & T_SWARM && !(m_spawnthing->cgd.flags & (T_HARDLINK | T_PARENTLINK))) {
|
||||
|
||||
@@ -189,7 +189,7 @@ void CG_InstaMessageGroupE_f(void)
|
||||
|
||||
void CG_HudPrint_f(void)
|
||||
{
|
||||
cgi.Printf("\x1%s", cgi.Argv(0));
|
||||
cgi.Printf("\x1%s", cgi.Argv(1));
|
||||
}
|
||||
|
||||
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time)
|
||||
|
||||
+127
-7
@@ -504,6 +504,44 @@ static int CG_CalcFov(void)
|
||||
return inwater;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_SetupFog
|
||||
|
||||
Prepares fog values for rendering
|
||||
===============
|
||||
*/
|
||||
void CG_SetupFog() {
|
||||
cg.refdef.farplane_distance = cg.farplane_distance;
|
||||
cg.refdef.farplane_bias = cg.farplane_bias;
|
||||
cg.refdef.farplane_color[0] = cg.farplane_color[0];
|
||||
cg.refdef.farplane_color[1] = cg.farplane_color[1];
|
||||
cg.refdef.farplane_color[2] = cg.farplane_color[2];
|
||||
cg.refdef.farplane_cull = cg.farplane_cull;
|
||||
cg.refdef.skybox_farplane = cg.skyboxFarplane;
|
||||
cg.refdef.renderTerrain = cg.renderTerrain;
|
||||
cg.refdef.farclipOverride = cg.farclipOverride;
|
||||
cg.refdef.farplaneColorOverride[0] = cg.farplaneColorOverride[0];
|
||||
cg.refdef.farplaneColorOverride[1] = cg.farplaneColorOverride[1];
|
||||
cg.refdef.farplaneColorOverride[2] = cg.farplaneColorOverride[2];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_SetupPortalSky
|
||||
|
||||
Sets portalsky values for rendering
|
||||
===============
|
||||
*/
|
||||
void CG_SetupPortalSky() {
|
||||
cg.refdef.sky_alpha = cg.sky_alpha;
|
||||
cg.refdef.sky_portal = cg.sky_portal;
|
||||
VectorCopy(cg.sky_axis[0], cg.refdef.sky_axis[0]);
|
||||
VectorCopy(cg.sky_axis[1], cg.refdef.sky_axis[1]);
|
||||
VectorCopy(cg.sky_axis[2], cg.refdef.sky_axis[2]);
|
||||
VectorMA(cg.sky_origin, cg.skyboxSpeed, cg.refdef.vieworg, cg.refdef.sky_origin);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CalcViewValues
|
||||
@@ -520,6 +558,7 @@ static int CG_CalcViewValues(void)
|
||||
|
||||
// calculate size of 3D view
|
||||
CG_CalcVrect();
|
||||
CG_SetupFog();
|
||||
|
||||
// setup fog and far clipping plane
|
||||
cg.refdef.farplane_distance = cg.farplane_distance;
|
||||
@@ -604,7 +643,9 @@ static int CG_CalcViewValues(void)
|
||||
// Set the aural axis of the player
|
||||
VectorCopy(cg.refdefViewAngles, SoundAngles);
|
||||
// yaw is purposely inverted because of the miles sound system
|
||||
SoundAngles[YAW] = -SoundAngles[YAW];
|
||||
// Commented out in OPM
|
||||
// Useless as SDL audio/AL is used
|
||||
//SoundAngles[YAW] = -SoundAngles[YAW];
|
||||
AnglesToAxis(SoundAngles, cg.SoundAxis);
|
||||
|
||||
// decide on third person view
|
||||
@@ -623,6 +664,11 @@ static int CG_CalcViewValues(void)
|
||||
// Set the aural axis to the camera's angles
|
||||
VectorCopy(cg.camera_angles, cg.refdefViewAngles);
|
||||
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN && (ps->pm_flags & PMF_DAMAGE_ANGLES)) {
|
||||
// Handle camera shake
|
||||
VectorSubtract(cg.refdefViewAngles, cg.predicted_player_state.damage_angles, cg.refdefViewAngles);
|
||||
}
|
||||
|
||||
if (ps->camera_posofs[0] || ps->camera_posofs[1] || ps->camera_posofs[2]) {
|
||||
vec3_t vAxis[3], vOrg;
|
||||
AnglesToAxis(cg.refdefViewAngles, vAxis);
|
||||
@@ -633,6 +679,9 @@ static int CG_CalcViewValues(void)
|
||||
// copy view values
|
||||
VectorCopy(cg.refdef.vieworg, cg.currentViewPos);
|
||||
VectorCopy(cg.refdefViewAngles, cg.currentViewAngles);
|
||||
// since 2.0: also copy location data for sound
|
||||
VectorCopy(cg.refdef.vieworg, cg.SoundOrg);
|
||||
AnglesToAxis(cg.refdefViewAngles, cg.SoundAxis);
|
||||
}
|
||||
|
||||
// position eye reletive to origin
|
||||
@@ -774,10 +823,46 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
CG_ScoresDown_f();
|
||||
} else if (cg.bIntermissionDisplay) {
|
||||
if (cg.nextSnap) {
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cvar_t* pMission = cgi.Cvar_Get("g_mission", "", CVAR_ARCHIVE);
|
||||
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_ShowMenu("mission_success_1", 0);
|
||||
cgi.Cvar_Set("g_t2l1", "1");
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_ShowMenu("mission_success_2", 0);
|
||||
cgi.Cvar_Set("g_t3l1", "1");
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_ShowMenu("mission_success_3", 0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_ShowMenu("mission_failed_1", 0);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_ShowMenu("mission_failed_2", 0);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_ShowMenu("mission_failed_3", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
|
||||
} else {
|
||||
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -789,10 +874,44 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
if (cgs.gametype != GT_SINGLE_PLAYER) {
|
||||
CG_ScoresUp_f();
|
||||
} else {
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cvar_t* pMission = cgi.Cvar_Get("g_mission", "", CVAR_ARCHIVE);
|
||||
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_HideMenu("mission_success_1", CVAR_ARCHIVE);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_HideMenu("mission_success_2", CVAR_ARCHIVE);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_HideMenu("mission_success_3", CVAR_ARCHIVE);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (pMission->integer)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
cgi.UI_HideMenu("mission_failed_1", CVAR_ARCHIVE);
|
||||
break;
|
||||
case 2:
|
||||
cgi.UI_HideMenu("mission_failed_2", CVAR_ARCHIVE);
|
||||
break;
|
||||
case 3:
|
||||
cgi.UI_HideMenu("mission_failed_3", CVAR_ARCHIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
|
||||
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
|
||||
cgi.UI_HideMenu("StatsScreen_Success", qfalse);
|
||||
} else {
|
||||
cgi.UI_HideMenu("StatsScreen_Failed", qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,6 +925,7 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
|
||||
}
|
||||
|
||||
// finish up the rest of the refdef
|
||||
CG_SetupPortalSky();
|
||||
|
||||
cg.refdef.time = cg.time;
|
||||
memcpy(cg.refdef.areamask, cg.snap->areamask, sizeof(cg.refdef.areamask));
|
||||
|
||||
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_commands.h"
|
||||
#include "memarchiver.h"
|
||||
|
||||
const char *cg_vsstypes[] = {
|
||||
"default",
|
||||
@@ -214,6 +215,11 @@ void CG_ResetVSSSources()
|
||||
lastVSSFrameTime = cg.time;
|
||||
}
|
||||
|
||||
void CG_ArchiveVSSGlobals(MemArchiver& archiver)
|
||||
{
|
||||
archiver.ArchiveTime(&lastVSSFrameTime);
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::InitializeVSSSources()
|
||||
{
|
||||
int i;
|
||||
@@ -287,6 +293,7 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
|
||||
pSource->lastOrigin = pSource->newOrigin;
|
||||
|
||||
if (pSource->flags & 0x800) {
|
||||
trace.allsolid = qfalse;
|
||||
CG_ClipMoveToEntities(
|
||||
pSource->newOrigin, vec3_origin, vec3_origin, pSource->newOrigin, -1, MASK_VOLUMETRIC_SMOKE, &trace, qfalse
|
||||
);
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "memarchiver.h"
|
||||
#include "../qcommon/vector.h"
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
MemArchiver::MemArchiver()
|
||||
{
|
||||
state = MEMARC_WRITING;
|
||||
buffer = 0;
|
||||
allocatedSize = 0;
|
||||
bufferSize = 0;
|
||||
}
|
||||
|
||||
MemArchiver::~MemArchiver()
|
||||
{
|
||||
if (state == MEMARC_WRITING && buffer) {
|
||||
cgi.Free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::SetupForWriting(size_t initialSize)
|
||||
{
|
||||
state = MEMARC_WRITING;
|
||||
buffer = (byte*)cgi.Malloc(initialSize);
|
||||
allocatedSize = initialSize;
|
||||
bufferSize = 0;
|
||||
}
|
||||
|
||||
void MemArchiver::SetupForReading(byte* buffer, size_t size)
|
||||
{
|
||||
state = MEMARC_READING;
|
||||
buffer = buffer;
|
||||
allocatedSize = size;
|
||||
bufferSize = 0;
|
||||
}
|
||||
|
||||
void MemArchiver::SetBaseTime(unsigned int time)
|
||||
{
|
||||
svsTime = time;
|
||||
}
|
||||
|
||||
size_t MemArchiver::BufferSize() const
|
||||
{
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
byte* MemArchiver::ConfiscateBuffer()
|
||||
{
|
||||
byte* confiscatedBuffer = buffer;
|
||||
|
||||
buffer = NULL;
|
||||
allocatedSize = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
return confiscatedBuffer;
|
||||
}
|
||||
|
||||
bool MemArchiver::IsReading() const
|
||||
{
|
||||
return !IsWriting();
|
||||
}
|
||||
|
||||
bool MemArchiver::IsWriting() const
|
||||
{
|
||||
return state == MEMARC_WRITING;
|
||||
}
|
||||
|
||||
bool MemArchiver::FinishedReading() const
|
||||
{
|
||||
return bufferSize == allocatedSize;
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveByte(byte* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(byte));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveBoolean(qboolean* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(qboolean));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveChar(char* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(char));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveUChar(unsigned char* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveShort(short* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(short));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveInteger(int* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(int));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveSize(size_t* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(size_t));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveFloat(float* value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(float));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveVec3(vec3_t value)
|
||||
{
|
||||
ArchiveRaw(value, sizeof(vec3_t));
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveVector(Vector* value)
|
||||
{
|
||||
ArchiveFloat(&value->x);
|
||||
ArchiveFloat(&value->y);
|
||||
ArchiveFloat(&value->z);
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveString(str* value)
|
||||
{
|
||||
char tmp[4096];
|
||||
int current = 0;
|
||||
|
||||
if (IsReading()) {
|
||||
for (current = 0; current < 4096; current++) {
|
||||
ArchiveReadRaw(&tmp[current], sizeof(char));
|
||||
if (!tmp[current]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (current == 4096) {
|
||||
tmp[current - 1] = 0;
|
||||
}
|
||||
|
||||
*value = tmp;
|
||||
} else {
|
||||
ArchiveWriteRaw(value->c_str(), value->length() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveTime(int* value)
|
||||
{
|
||||
int time;
|
||||
|
||||
if (IsReading()) {
|
||||
ArchiveReadRaw(&time, sizeof(time));
|
||||
|
||||
if (time) {
|
||||
time += svsTime;
|
||||
}
|
||||
|
||||
*value = time;
|
||||
} else {
|
||||
time = *value;
|
||||
if (time) {
|
||||
time -= svsTime;
|
||||
}
|
||||
|
||||
ArchiveWriteRaw(&time, sizeof(time));
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveRaw(void* buffer, size_t size)
|
||||
{
|
||||
if (IsReading()) {
|
||||
ArchiveReadRaw(buffer, size);
|
||||
} else {
|
||||
ArchiveWriteRaw(buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveReadRaw(void* buffer, size_t size)
|
||||
{
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (size + this->bufferSize > this->allocatedSize) {
|
||||
Com_Error(ERR_DROP, "MemArchiver: tried to read past end of buffer");
|
||||
}
|
||||
|
||||
memcpy(buffer, this->buffer + this->bufferSize, size);
|
||||
this->bufferSize += size;
|
||||
}
|
||||
|
||||
void MemArchiver::ArchiveWriteRaw(const void* buffer, size_t size)
|
||||
{
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (size + this->bufferSize > this->allocatedSize) {
|
||||
if (!this->allocatedSize) {
|
||||
this->allocatedSize = 1024;
|
||||
this->buffer = (byte*)cgi.Malloc(this->allocatedSize);
|
||||
} else {
|
||||
byte* newBuffer;
|
||||
|
||||
do {
|
||||
this->allocatedSize *= 2;
|
||||
} while (size + this->bufferSize > this->allocatedSize);
|
||||
|
||||
newBuffer = (byte*)cgi.Malloc(this->allocatedSize);
|
||||
memcpy(newBuffer, this->buffer, this->bufferSize);
|
||||
cgi.Free(this->buffer);
|
||||
this->buffer = newBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(this->buffer + this->bufferSize, buffer, size);
|
||||
this->bufferSize += size;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// DESCRIPTION:
|
||||
// In-memory archiver
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
class Vector;
|
||||
class str;
|
||||
|
||||
typedef enum {
|
||||
MEMARC_WRITING,
|
||||
MEMARC_READING
|
||||
} archiverState_e;
|
||||
|
||||
class MemArchiver {
|
||||
public:
|
||||
MemArchiver();
|
||||
~MemArchiver();
|
||||
|
||||
void SetupForWriting(size_t initialSize);
|
||||
void SetupForReading(byte* buffer, size_t size);
|
||||
void SetBaseTime(unsigned int time);
|
||||
size_t BufferSize() const;
|
||||
byte* ConfiscateBuffer();
|
||||
bool IsReading() const;
|
||||
bool IsWriting() const;
|
||||
bool FinishedReading() const;
|
||||
|
||||
void ArchiveByte(byte* value);
|
||||
void ArchiveBoolean(qboolean* value);
|
||||
void ArchiveChar(char* value);
|
||||
void ArchiveUChar(unsigned char* value);
|
||||
void ArchiveShort(short* value);
|
||||
void ArchiveInteger(int* value);
|
||||
void ArchiveSize(size_t* value);
|
||||
void ArchiveFloat(float* value);
|
||||
void ArchiveVec3(vec3_t value);
|
||||
void ArchiveVector(Vector* value);
|
||||
void ArchiveString(str* value);
|
||||
void ArchiveTime(int* value);
|
||||
void ArchiveRaw(void* buffer, size_t size);
|
||||
void ArchiveReadRaw(void* buffer, size_t size);
|
||||
void ArchiveWriteRaw(const void* buffer, size_t size);
|
||||
|
||||
private:
|
||||
archiverState_e state;
|
||||
byte* buffer;
|
||||
size_t bufferSize;
|
||||
size_t allocatedSize;
|
||||
int svsTime;
|
||||
};
|
||||
@@ -8,7 +8,6 @@ file(GLOB_RECURSE SOURCES_UILIB "../uilib/*.c*")
|
||||
|
||||
# Made as an interface and not static, as static only links used methods
|
||||
add_library(omohclient INTERFACE)
|
||||
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
|
||||
target_compile_definitions(omohclient INTERFACE APP_MODULE)
|
||||
target_compile_features(omohclient INTERFACE cxx_nullptr)
|
||||
target_compile_features(omohclient INTERFACE c_variadic_macros)
|
||||
@@ -18,6 +17,33 @@ target_link_libraries(omohclient INTERFACE gcd)
|
||||
# Sound stuff
|
||||
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
|
||||
|
||||
if (USE_SOUND_NEW)
|
||||
# Try to use OpenAL
|
||||
find_package(OpenAL)
|
||||
if (OPENAL_FOUND)
|
||||
target_compile_definitions(omohclient INTERFACE USE_SOUND_NEW=1)
|
||||
if (MSVC)
|
||||
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
|
||||
else()
|
||||
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR})
|
||||
endif()
|
||||
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
|
||||
endif()
|
||||
|
||||
list(FILTER SOURCES_CLIENT EXCLUDE REGEX "./snd_([a-zA-Z0-9_]+)\.c$")
|
||||
endif()
|
||||
|
||||
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()
|
||||
endif()
|
||||
|
||||
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
|
||||
|
||||
add_subdirectory("../libmad-0.15.1b" "./libmad")
|
||||
target_link_libraries(omohclient INTERFACE libmad)
|
||||
target_include_directories(omohclient INTERFACE "../libmad-0.15.1b")
|
||||
target_link_libraries(omohclient INTERFACE libmad)
|
||||
@@ -334,6 +334,9 @@ writing the actual data can begin
|
||||
*/
|
||||
qboolean CL_OpenAVIForWriting( const char *fileName )
|
||||
{
|
||||
return qfalse;
|
||||
// Removed in OPM
|
||||
#if 0
|
||||
if( afd.fileOpen )
|
||||
return qfalse;
|
||||
|
||||
@@ -425,6 +428,7 @@ qboolean CL_OpenAVIForWriting( const char *fileName )
|
||||
afd.fileOpen = qtrue;
|
||||
|
||||
return qtrue;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+77
-15
@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "client.h"
|
||||
#include "cl_ui.h"
|
||||
#include "cl_uiradar.h"
|
||||
#include "../qcommon/tiki.h"
|
||||
#include "../qcommon/localization.h"
|
||||
#include "../qcommon/bg_compat.h"
|
||||
@@ -394,8 +395,8 @@ Set up argc/argv for the given command
|
||||
===================
|
||||
*/
|
||||
qboolean CL_GetServerCommand( int serverCommandNumber, qboolean differentServer ) {
|
||||
char *s;
|
||||
char *cmd;
|
||||
char *s;
|
||||
char *cmd;
|
||||
static char bigConfigString[BIG_INFO_STRING];
|
||||
|
||||
// if we have irretrievably lost a reliable command, drop the connection
|
||||
@@ -420,9 +421,39 @@ qboolean CL_GetServerCommand( int serverCommandNumber, qboolean differentServer
|
||||
Com_DPrintf( "serverCommand: %i : %s\n", serverCommandNumber, s );
|
||||
}
|
||||
|
||||
Cmd_TokenizeString( s );
|
||||
Cmd_TokenizeString(s);
|
||||
cmd = Cmd_Argv(0);
|
||||
|
||||
// Readded in OPM (from ioquake)
|
||||
// Configstring big buffer
|
||||
if (!strcmp(cmd, "bcs0")) {
|
||||
Com_sprintf(bigConfigString, BIG_INFO_STRING, "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2));
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "bcs1")) {
|
||||
s = Cmd_Argv(2);
|
||||
if (strlen(bigConfigString) + strlen(s) >= BIG_INFO_STRING) {
|
||||
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
|
||||
}
|
||||
strcat(bigConfigString, s);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "bcs2")) {
|
||||
s = Cmd_Argv(2);
|
||||
if (strlen(bigConfigString) + strlen(s) + 1 >= BIG_INFO_STRING) {
|
||||
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
|
||||
}
|
||||
strcat(bigConfigString, s);
|
||||
strcat(bigConfigString, "\"");
|
||||
s = bigConfigString;
|
||||
|
||||
// reparse
|
||||
Cmd_TokenizeString(s);
|
||||
cmd = Cmd_Argv(0);
|
||||
}
|
||||
|
||||
return CL_ProcessServerCommand(s, cmd, differentServer);
|
||||
}
|
||||
|
||||
@@ -434,10 +465,10 @@ CL_CM_LoadMap
|
||||
Just adds default parameters that cgame doesn't need to know about
|
||||
====================
|
||||
*/
|
||||
void CL_CM_LoadMap( const char *mapname ) {
|
||||
int checksum;
|
||||
|
||||
CM_LoadMap( mapname, qtrue, &checksum );
|
||||
void CL_CM_LoadMap( const char *mapname, int *checksum ) {
|
||||
CM_LoadMap( mapname, qtrue, checksum );
|
||||
// prepare world vis data
|
||||
re.SetWorldVisData(CM_VisibilityPointer());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -540,6 +571,29 @@ void CL_StartLocalSound(const char* soundName, qboolean forceLoad) {
|
||||
S_StartLocalSound(soundName, qfalse );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_RestoreSavedCgameState
|
||||
====================
|
||||
*/
|
||||
void CL_RestoreSavedCgameState() {
|
||||
if (cls.savedCgameState) {
|
||||
cge->CG_LoadStateToBuffer(&cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_ClearSavedCgameState
|
||||
====================
|
||||
*/
|
||||
void CL_ClearSavedCgameState() {
|
||||
if (cls.savedCgameState) {
|
||||
cls.savedCgameState = NULL;
|
||||
cls.savedCgameStateSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_InitCGameDLL
|
||||
@@ -556,6 +610,7 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
|
||||
cgi->Printf = Com_Printf;
|
||||
cgi->DPrintf = Com_DPrintf;
|
||||
cgi->DebugPrintf = Com_DebugPrintf;
|
||||
|
||||
cgi->Malloc = CL_CG_Malloc;
|
||||
cgi->Free = CL_CG_Free;
|
||||
@@ -581,6 +636,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->FS_FreeFile = FS_FreeFile;
|
||||
cgi->FS_WriteFile = FS_WriteFile;
|
||||
cgi->FS_WriteTextFile = FS_WriteTextFile;
|
||||
cgi->FS_ListFilteredFiles = FS_ListFilteredFiles;
|
||||
cgi->FS_FreeFileList = FS_FreeFileList;
|
||||
|
||||
cgi->SendConsoleCommand = Cbuf_AddText;
|
||||
|
||||
@@ -652,9 +709,11 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->R_RegisterModel = re.RegisterModel;
|
||||
cgi->R_SpawnEffectModel = re.SpawnEffectModel;
|
||||
cgi->R_RegisterServerModel = re.RegisterServerModel;
|
||||
cgi->R_GetModelName = re.GetModelName;
|
||||
cgi->R_UnregisterServerModel = re.UnregisterServerModel;
|
||||
cgi->R_RegisterShader = re.RegisterShader;
|
||||
cgi->R_RegisterShaderNoMip = re.RegisterShaderNoMip;
|
||||
cgi->R_GetShaderName = re.GetShaderName;
|
||||
|
||||
cgi->R_AddRefEntityToScene = re.AddRefEntityToScene;
|
||||
cgi->R_AddRefSpriteToScene = re.AddRefSpriteToScene;
|
||||
@@ -745,11 +804,14 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->UI_SetScoreBoardItem = UI_SetScoreBoardItem;
|
||||
cgi->UI_DeleteScoreBoardItems = UI_DeleteScoreBoardItems;
|
||||
cgi->UI_ToggleDMMessageConsole = UI_ToggleDMConsole;
|
||||
cgi->CL_InitRadar = CL_InitRadar;
|
||||
|
||||
cgi->TIKI_FindTiki = TIKI_FindTiki;
|
||||
|
||||
cgi->LoadResource = UI_LoadResource;
|
||||
cgi->FS_CanonicalFilename = FS_CanonicalFilename;
|
||||
cgi->CL_RestoreSavedCgameState = CL_RestoreSavedCgameState;
|
||||
cgi->CL_ClearSavedCgameState = CL_ClearSavedCgameState;
|
||||
|
||||
cgi->fsDebug = fs_debug;
|
||||
cgi->HudDrawElements = cls.HudDrawElements;
|
||||
@@ -904,8 +966,6 @@ qboolean CL_GameCommand( void ) {
|
||||
return cge->CG_ConsoleCommand();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_CGameRendering
|
||||
@@ -920,6 +980,10 @@ void CL_CGameRendering( stereoFrame_t stereo ) {
|
||||
cge->CG_DrawActiveFrame( cl.serverTime, cl.serverTime - cl.oldServerTime, stereo, clc.demoplaying );
|
||||
|
||||
cl.oldServerTime = cl.serverTime;
|
||||
//
|
||||
// Let cgame clean up temp models
|
||||
//
|
||||
cge->CG_CleanUpTempModels();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1095,16 +1159,14 @@ void CL_SetCGameTime( void ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
//if( ( cl.snap.snapFlags ^ lastSnapFlags ) & SNAPFLAG_SERVERCOUNT ) {
|
||||
// CL_ServerRestarted();
|
||||
//} else {
|
||||
|
||||
if( ( cl.snap.snapFlags ^ lastSnapFlags ) & SNAPFLAG_SERVERCOUNT ) {
|
||||
CL_ServerRestarted();
|
||||
} else {
|
||||
if( cl.snap.serverTime < cl.oldFrameServerTime ) {
|
||||
assert( 0 );
|
||||
Com_Error( ERR_DROP, "cl.snap.serverTime < cl.oldFrameServerTime" );
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
cl.oldFrameServerTime = cl.snap.serverTime;
|
||||
|
||||
|
||||
@@ -1091,6 +1091,8 @@ static void RoQReset( void ) {
|
||||
|
||||
static void RoQInterrupt(void)
|
||||
{
|
||||
// Removed in OPM
|
||||
#if 0
|
||||
byte *framedata;
|
||||
short sbuf[32768];
|
||||
int ssize;
|
||||
@@ -1214,6 +1216,7 @@ 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
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -1397,6 +1400,9 @@ 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;
|
||||
@@ -1478,6 +1484,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
|
||||
|
||||
RoQShutdown();
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CIN_SetExtents (int handle, int x, int y, int w, int h) {
|
||||
@@ -1612,7 +1619,7 @@ void CL_PlayCinematic_f(void) {
|
||||
bits |= CIN_loop;
|
||||
}
|
||||
|
||||
S_StopAllSounds( qtrue );
|
||||
S_StopAllSounds2( qtrue );
|
||||
|
||||
CL_handle = CIN_PlayCinematic( arg, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, bits );
|
||||
if (CL_handle >= 0) {
|
||||
@@ -1639,7 +1646,7 @@ void SCR_RunCinematic (void)
|
||||
void SCR_StopCinematic(void) {
|
||||
if (CL_handle >= 0 && CL_handle < MAX_VIDEO_HANDLES) {
|
||||
CIN_StopCinematic(CL_handle);
|
||||
S_StopAllSounds( qtrue );
|
||||
S_StopAllSounds2( qtrue );
|
||||
CL_handle = -1;
|
||||
}
|
||||
}
|
||||
@@ -575,6 +575,14 @@ void CL_MouseMove( usercmd_t *cmd ) {
|
||||
cl.viewangles[PITCH] += m_pitch->value * my;
|
||||
else
|
||||
cmd->forwardmove = ClampChar(cmd->forwardmove - m_forward->value * my);
|
||||
|
||||
if (!isfinite(cl.viewangles[PITCH]) || !isfinite(cl.viewangles[YAW])) {
|
||||
Com_Printf("Invalid client viewangles encountered!\n");
|
||||
Com_Printf("cgameSensitivity: %f - mx: %f - my: %f - m_pitch: %f - m_yaw: %f", cgameSensitivity, mx, my, m_pitch->value, m_yaw->value);
|
||||
Com_Printf("Resetting client viewangles");
|
||||
cl.viewangles[PITCH] = 0;
|
||||
cl.viewangles[YAW] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1051,8 +1059,8 @@ void CL_InitInput( void ) {
|
||||
Cmd_AddCommand("-leanleft", IN_LeanLeftUp);
|
||||
Cmd_AddCommand("+leanright", IN_LeanRightDown);
|
||||
Cmd_AddCommand("-leanright", IN_LeanRightUp);
|
||||
Cmd_AddCommand("+speed", IN_SpeedUp);
|
||||
Cmd_AddCommand("-speed", IN_SpeedDown);
|
||||
Cmd_AddCommand("+speed", IN_SpeedDown);
|
||||
Cmd_AddCommand("-speed", IN_SpeedUp);
|
||||
Cmd_AddCommand("+button0", IN_Button0Down);
|
||||
Cmd_AddCommand("-button0", IN_Button0Up);
|
||||
Cmd_AddCommand("+button1", IN_Button1Down);
|
||||
|
||||
+973
-130
File diff suppressed because it is too large.
Load diff
+173
-150
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,175 +20,198 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_INV_H__
|
||||
#define __CL_INV_H__
|
||||
#pragma once
|
||||
|
||||
typedef enum { INV_MOVE_NONE, INV_MOVE_BOB, INV_MOVE_SPIN } inv_move_type;
|
||||
typedef enum { INV_CASCADE_LEFT, INV_CASCADE_RIGHT } inv_cascade_type;
|
||||
typedef enum { INV_HUDANGLES_BASE, INV_HUDANGLES_COMPASS, INV_HUDANGLES_COMPASS_NEEDLE } inv_hudangles_type;
|
||||
typedef enum {
|
||||
INV_MOVE_NONE,
|
||||
INV_MOVE_BOB,
|
||||
INV_MOVE_SPIN
|
||||
} inv_move_type;
|
||||
|
||||
class item_properties_t : public Class {
|
||||
public:
|
||||
float scale;
|
||||
Vector angles;
|
||||
Vector angledeltas;
|
||||
Vector rotateoffset;
|
||||
Vector offset;
|
||||
inv_move_type move;
|
||||
str model;
|
||||
str anim;
|
||||
};
|
||||
typedef enum {
|
||||
INV_ALIGN_NONE,
|
||||
INV_ALIGN_LEFT,
|
||||
INV_ALIGN_RIGHT
|
||||
} inv_align_type;
|
||||
|
||||
class inventory_item_t : public Class {
|
||||
public:
|
||||
str name;
|
||||
str ammoname;
|
||||
int equip;
|
||||
int width;
|
||||
int height;
|
||||
int barwidth;
|
||||
int barheight;
|
||||
int baroffsetY;
|
||||
int baroffsetX;
|
||||
float modelWindowX;
|
||||
float modelWindowY;
|
||||
float modelWindowWidth;
|
||||
float modelWindowHeight;
|
||||
bool selShaderOnTop;
|
||||
bool checkammo;
|
||||
str command;
|
||||
inv_hudangles_type anglesType;
|
||||
item_properties_t hudprops;
|
||||
item_properties_t invprops;
|
||||
UIReggedMaterial *bgshader;
|
||||
UIReggedMaterial *barshader;
|
||||
UIReggedMaterial *selshader;
|
||||
};
|
||||
typedef enum {
|
||||
INV_CASCADE_LEFT,
|
||||
INV_CASCADE_RIGHT
|
||||
} inv_cascade_type;
|
||||
|
||||
class inventory_type_t {
|
||||
public:
|
||||
str name;
|
||||
bool bg_tile;
|
||||
UIReggedMaterial *texture;
|
||||
UIReggedMaterial *bg;
|
||||
UIReggedMaterial *hoverTexture;
|
||||
UIReggedMaterial *selTexture;
|
||||
Container<inventory_item_t *> items;
|
||||
typedef enum {
|
||||
INV_HUDANGLES_BASE,
|
||||
INV_HUDANGLES_COMPASS,
|
||||
INV_HUDANGLES_COMPASS_NEEDLE
|
||||
} inv_hudangles_type;
|
||||
|
||||
int IndexOfItemPtr( inventory_item_t *item );
|
||||
};
|
||||
|
||||
inline
|
||||
int inventory_type_t::IndexOfItemPtr( inventory_item_t *item )
|
||||
class item_properties_t : public Class
|
||||
{
|
||||
for( int i = items.NumObjects(); i > 0; i-- )
|
||||
{
|
||||
if( items.ObjectAt( i ) == item )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
public:
|
||||
float scale;
|
||||
Vector angles;
|
||||
Vector angledeltas;
|
||||
Vector rotateoffset;
|
||||
Vector offset;
|
||||
inv_move_type move;
|
||||
str model;
|
||||
str anim;
|
||||
};
|
||||
|
||||
return 0;
|
||||
class inventory_item_t : public Class
|
||||
{
|
||||
public:
|
||||
str name;
|
||||
str ammoname;
|
||||
int equip;
|
||||
int width;
|
||||
int height;
|
||||
int barwidth;
|
||||
int barheight;
|
||||
int baroffsetY;
|
||||
int baroffsetX;
|
||||
float modelWindowX;
|
||||
float modelWindowY;
|
||||
float modelWindowWidth;
|
||||
float modelWindowHeight;
|
||||
bool selShaderOnTop;
|
||||
bool checkammo;
|
||||
str command;
|
||||
inv_hudangles_type anglesType;
|
||||
item_properties_t hudprops;
|
||||
item_properties_t invprops;
|
||||
UIReggedMaterial *bgshader;
|
||||
UIReggedMaterial *barshader;
|
||||
UIReggedMaterial *selshader;
|
||||
};
|
||||
|
||||
class inventory_type_t
|
||||
{
|
||||
public:
|
||||
str name;
|
||||
bool bg_tile;
|
||||
UIReggedMaterial *texture;
|
||||
UIReggedMaterial *bg;
|
||||
UIReggedMaterial *hoverTexture;
|
||||
UIReggedMaterial *selTexture;
|
||||
Container<inventory_item_t *> items;
|
||||
|
||||
int IndexOfItemPtr(inventory_item_t *item);
|
||||
};
|
||||
|
||||
inline int inventory_type_t::IndexOfItemPtr(inventory_item_t *item)
|
||||
{
|
||||
for (int i = items.NumObjects(); i > 0; i--) {
|
||||
if (items.ObjectAt(i) == item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
class inventory_t {
|
||||
class inventory_t
|
||||
{
|
||||
public:
|
||||
int typewidth;
|
||||
int typeheight;
|
||||
int horizoffset;
|
||||
int vertoffset;
|
||||
int align;
|
||||
inv_cascade_type cascade;
|
||||
str selectsound;
|
||||
str rejectsound;
|
||||
str changesound;
|
||||
Container<inventory_type_t *> types;
|
||||
int typewidth;
|
||||
int typeheight;
|
||||
int horizoffset;
|
||||
int vertoffset;
|
||||
inv_align_type align;
|
||||
inv_cascade_type cascade;
|
||||
str selectsound;
|
||||
str rejectsound;
|
||||
str changesound;
|
||||
Container<inventory_type_t *> types;
|
||||
|
||||
void Clear() { types.ClearObjectList(); }
|
||||
public:
|
||||
inventory_t();
|
||||
~inventory_t();
|
||||
inventory_t(const inventory_t& other);
|
||||
inventory_t& operator=(const inventory_t& other);
|
||||
void Clear();
|
||||
};
|
||||
|
||||
class invlistener : public Listener {
|
||||
class invlistener : public Listener
|
||||
{
|
||||
protected:
|
||||
inventory_t *inv;
|
||||
inventory_type_t *curtype;
|
||||
inventory_item_t *curitem;
|
||||
int defaultWidth;
|
||||
int defaultHeight;
|
||||
int defaultBarWidth;
|
||||
int defaultBarHeight;
|
||||
int defaultBarOffsetX;
|
||||
int defaultBarOffsetY;
|
||||
inventory_t *inv;
|
||||
inventory_type_t *curtype;
|
||||
inventory_item_t *curitem;
|
||||
int defaultWidth;
|
||||
int defaultHeight;
|
||||
int defaultBarWidth;
|
||||
int defaultBarHeight;
|
||||
int defaultBarOffsetX;
|
||||
int defaultBarOffsetY;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( invlistener );
|
||||
CLASS_PROTOTYPE(invlistener);
|
||||
|
||||
protected:
|
||||
void verify_curitem( void );
|
||||
void verify_curtype( void );
|
||||
void verify_one_arg( Event *ev );
|
||||
void verify_curitem(void);
|
||||
void verify_curtype(void);
|
||||
void verify_one_arg(Event *ev);
|
||||
|
||||
public:
|
||||
invlistener( inventory_t *i );
|
||||
invlistener();
|
||||
invlistener(inventory_t *i);
|
||||
invlistener();
|
||||
|
||||
bool Load( Script& script );
|
||||
void InvSelectSound( Event *ev );
|
||||
void InvRejectSound( Event *ev );
|
||||
void InvChangeSound( Event *ev );
|
||||
void InvWidth( Event *ev );
|
||||
void InvHeight( Event *ev );
|
||||
void InvHorizOffset( Event *ev );
|
||||
void InvVertOffset( Event *ev );
|
||||
void InvAlign( Event *ev );
|
||||
void InvCascade( Event *ev );
|
||||
void Typedef( Event *ev );
|
||||
void OpenBrace( Event *ev );
|
||||
void CloseBrace( Event *ev );
|
||||
void ButtonShader( Event *ev );
|
||||
void HoverShader( Event *ev );
|
||||
void SelShader( Event *ev );
|
||||
void Background( Event *ev );
|
||||
void BackgroundTile( Event *ev );
|
||||
void Width( Event *ev );
|
||||
void Height( Event *ev );
|
||||
void BarWidth( Event *ev );
|
||||
void BarHeight( Event *ev );
|
||||
void BarOffsetX( Event *ev );
|
||||
void BarOffsetY( Event *ev );
|
||||
void Item( Event *ev );
|
||||
void Ammo( Event *ev );
|
||||
void Equip( Event *ev );
|
||||
void CheckAmmo( Event *ev );
|
||||
void Command( Event *ev );
|
||||
void BGShader( Event *ev );
|
||||
void BarShader( Event *ev );
|
||||
void SelItemShader( Event *ev );
|
||||
void SelItemShaderOnTop( Event *ev );
|
||||
void RotateOffset( Event *ev );
|
||||
void Offset( Event *ev );
|
||||
void Model( Event *ev );
|
||||
void Anim( Event *ev );
|
||||
void Scale( Event *ev );
|
||||
void Angles( Event *ev );
|
||||
void AngleDeltas( Event *ev );
|
||||
void Move( Event *ev );
|
||||
void ModelWindow( Event *ev );
|
||||
void HudRotateOffset( Event *ev );
|
||||
void HudOffset( Event *ev );
|
||||
void HudModel( Event *ev );
|
||||
void HudAnim( Event *ev );
|
||||
void HudScale( Event *ev );
|
||||
void HudAngles( Event *ev );
|
||||
void HudAngleDeltas( Event *ev );
|
||||
void HudMove( Event *ev );
|
||||
void HudCompassAngles( Event *ev );
|
||||
void HudCompassNeedleAngles( Event *ev );
|
||||
bool Load(Script& script);
|
||||
void InvSelectSound(Event *ev);
|
||||
void InvRejectSound(Event *ev);
|
||||
void InvChangeSound(Event *ev);
|
||||
void InvWidth(Event *ev);
|
||||
void InvHeight(Event *ev);
|
||||
void InvHorizOffset(Event *ev);
|
||||
void InvVertOffset(Event *ev);
|
||||
void InvAlign(Event *ev);
|
||||
void InvCascade(Event *ev);
|
||||
void Typedef(Event *ev);
|
||||
void OpenBrace(Event *ev);
|
||||
void CloseBrace(Event *ev);
|
||||
void ButtonShader(Event *ev);
|
||||
void HoverShader(Event *ev);
|
||||
void SelShader(Event *ev);
|
||||
void Background(Event *ev);
|
||||
void BackgroundTile(Event *ev);
|
||||
void Width(Event *ev);
|
||||
void Height(Event *ev);
|
||||
void BarWidth(Event *ev);
|
||||
void BarHeight(Event *ev);
|
||||
void BarOffsetX(Event *ev);
|
||||
void BarOffsetY(Event *ev);
|
||||
void Item(Event *ev);
|
||||
void Ammo(Event *ev);
|
||||
void Equip(Event *ev);
|
||||
void CheckAmmo(Event *ev);
|
||||
void Command(Event *ev);
|
||||
void BGShader(Event *ev);
|
||||
void BarShader(Event *ev);
|
||||
void SelItemShader(Event *ev);
|
||||
void SelItemShaderOnTop(Event *ev);
|
||||
void RotateOffset(Event *ev);
|
||||
void Offset(Event *ev);
|
||||
void Model(Event *ev);
|
||||
void Anim(Event *ev);
|
||||
void Scale(Event *ev);
|
||||
void Angles(Event *ev);
|
||||
void AngleDeltas(Event *ev);
|
||||
void Move(Event *ev);
|
||||
void ModelWindow(Event *ev);
|
||||
void HudRotateOffset(Event *ev);
|
||||
void HudOffset(Event *ev);
|
||||
void HudModel(Event *ev);
|
||||
void HudAnim(Event *ev);
|
||||
void HudScale(Event *ev);
|
||||
void HudAngles(Event *ev);
|
||||
void HudAngleDeltas(Event *ev);
|
||||
void HudMove(Event *ev);
|
||||
void HudCompassAngles(Event *ev);
|
||||
void HudCompassNeedleAngles(Event *ev);
|
||||
};
|
||||
|
||||
bool CL_LoadInventory( const char *filename, inventory_t *inv );
|
||||
inventory_item_t *CL_GetInvItemByName( inventory_t *inv, const char *name );
|
||||
qboolean CL_HasInventoryItem( const char *name );
|
||||
void CL_AmmoCount( const char *name, int *ammo_count, int *max_ammo_count );
|
||||
|
||||
#endif // __CL_INV_H__
|
||||
bool CL_LoadInventory(const char *filename, inventory_t *inv);
|
||||
inventory_item_t *CL_GetInvItemByName(inventory_t *inv, const char *name);
|
||||
qboolean CL_HasInventoryItem(const char *name);
|
||||
void CL_AmmoCount(const char *name, int *ammo_count, int *max_ammo_count);
|
||||
+965
-132
File diff suppressed because it is too large.
Load diff
+81
-58
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,79 +20,102 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_INVRENDER_H__
|
||||
#define __CL_INVRENDER_H__
|
||||
#pragma once
|
||||
|
||||
class FakkInventory;
|
||||
|
||||
typedef enum { selectsound, rejectsound, changesound } invsound_t;
|
||||
class FakkItemList : public UIWidget {
|
||||
typedef enum {
|
||||
selectsound,
|
||||
rejectsound,
|
||||
changesound
|
||||
} invsound_t;
|
||||
|
||||
class FakkItemList : public UIWidget
|
||||
{
|
||||
protected:
|
||||
inventory_type_t *type;
|
||||
uipopup_describe m_describe[ 10 ];
|
||||
inventory_item_t *m_hoveritem;
|
||||
inventory_item_t *m_lastmenuitem;
|
||||
FakkInventory *m_parent;
|
||||
float m_hovertop;
|
||||
inventory_type_t *type;
|
||||
uipopup_describe m_describe[10];
|
||||
inventory_item_t *m_hoveritem;
|
||||
inventory_item_t *m_lastmenuitem;
|
||||
FakkInventory *m_parent;
|
||||
float m_hovertop;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( FakkItemList );
|
||||
CLASS_PROTOTYPE(FakkItemList);
|
||||
|
||||
FakkItemList();
|
||||
~FakkItemList();
|
||||
FakkItemList();
|
||||
~FakkItemList();
|
||||
|
||||
void VerifyItemUp( inventory_item_t *item, qboolean warpmouse );
|
||||
void setType( inventory_type_t *t );
|
||||
void Create( float x, float y, FakkInventory *parent );
|
||||
bool HasAnyItems( void );
|
||||
void Draw( void ) override;
|
||||
void OnLeftMouseDown( Event *ev );
|
||||
void OnRightMouseDown( Event *ev );
|
||||
void OnLeftMouseUp( Event *ev );
|
||||
void OnRightMouseUp( Event *ev );
|
||||
void OnMouseMove( Event *ev );
|
||||
void OnMouseEnter( Event *ev );
|
||||
void OnMouseLeave( Event *ev );
|
||||
void OnMenuKilled( Event *ev );
|
||||
void EquipItem( Event *ev );
|
||||
void VerifyItemUp(inventory_item_t *item, qboolean warpmouse);
|
||||
void setType(inventory_type_t *t);
|
||||
void Create(float x, float y, FakkInventory *parent);
|
||||
bool HasAnyItems(void);
|
||||
void Draw(void) override;
|
||||
void OnLeftMouseDown(Event *ev);
|
||||
void OnRightMouseDown(Event *ev);
|
||||
void OnLeftMouseUp(Event *ev);
|
||||
void OnRightMouseUp(Event *ev);
|
||||
void OnMouseMove(Event *ev);
|
||||
void OnMouseEnter(Event *ev);
|
||||
void OnMouseLeave(Event *ev);
|
||||
void OnMenuKilled(Event *ev);
|
||||
void EquipItem(Event *ev);
|
||||
|
||||
inventory_item_t *getHoverItem() const;
|
||||
};
|
||||
|
||||
class FakkInventory : public UIWidget {
|
||||
class FakkInventory : public UIWidget
|
||||
{
|
||||
protected:
|
||||
inventory_t *m_inv;
|
||||
SafePtr<FakkItemList> m_currentlist;
|
||||
inventory_type_t *m_currenttype;
|
||||
int m_currentitemnum;
|
||||
inventory_t *m_inv;
|
||||
SafePtr<FakkItemList> m_currentlist;
|
||||
inventory_type_t *m_currenttype;
|
||||
int m_currentitemnum;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( FakkInventory );
|
||||
|
||||
protected:
|
||||
void VerifyItemUp( inventory_item_t *item, qboolean warpmouse );
|
||||
CLASS_PROTOTYPE(FakkInventory);
|
||||
|
||||
public:
|
||||
FakkInventory();
|
||||
~FakkInventory();
|
||||
qboolean m_mouse_active;
|
||||
|
||||
void setInventory( inventory_t *i );
|
||||
void Draw( void ) override;
|
||||
void OnMouseMove( Event *ev );
|
||||
void OnMouseLeave( Event *ev );
|
||||
void OnMouseEnter( Event *ev );
|
||||
void OnMouseDown( Event *ev );
|
||||
void WarpTo( const char *name );
|
||||
void WarpTo( int slotnum );
|
||||
void NextItem( void );
|
||||
void PrevItem( void );
|
||||
qboolean isDying( void );
|
||||
qboolean KeyEvent( int key, unsigned int time ) override;
|
||||
void PlaySound( invsound_t type );
|
||||
void Timeout( Event *ev );
|
||||
void ChangeItem( int sign );
|
||||
int FindFirstItem( int itemindex, int sign );
|
||||
protected:
|
||||
void VerifyTypeUp(inventory_type_t *t, qboolean warpmouse);
|
||||
|
||||
public:
|
||||
FakkInventory();
|
||||
~FakkInventory();
|
||||
|
||||
void setInventory(inventory_t *i);
|
||||
void Draw(void) override;
|
||||
void OnMouseMove(Event *ev);
|
||||
void OnMouseLeave(Event *ev);
|
||||
void OnMouseEnter(Event *ev);
|
||||
void OnMouseDown(Event *ev);
|
||||
void WarpTo(const char *name);
|
||||
void WarpTo(int slotnum);
|
||||
void NextItem(void);
|
||||
void PrevItem(void);
|
||||
qboolean isDying(void);
|
||||
qboolean KeyEvent(int key, unsigned int time) override;
|
||||
void PlaySound(invsound_t type);
|
||||
void Timeout(Event *ev);
|
||||
void ChangeItem(int sign);
|
||||
int FindFirstItem(int itemindex, int sign);
|
||||
};
|
||||
|
||||
void CL_Draw3DModel( float x, float y, float w, float h, qhandle_t model, vec3_t origin, vec3_t rotateoffset, vec3_t offset, vec3_t angle, vec3_t color, str anim );
|
||||
qboolean UI_CloseInventory( void );
|
||||
void CL_Draw3DModel(
|
||||
float x,
|
||||
float y,
|
||||
float w,
|
||||
float h,
|
||||
qhandle_t model,
|
||||
vec3_t origin,
|
||||
vec3_t rotateoffset,
|
||||
vec3_t offset,
|
||||
vec3_t angle,
|
||||
vec3_t color,
|
||||
str anim
|
||||
);
|
||||
|
||||
#endif // __CL_INVRENDER_H__
|
||||
void UI_DoInventory(qboolean activate_mouse);
|
||||
qboolean UI_CloseInventory(void);
|
||||
+927
-915
File diff suppressed because it is too large.
Load diff
+395
-214
File diff suppressed because it is too large.
Load diff
+68
-36
@@ -194,6 +194,69 @@ void CL_ParsePacketEntities( msg_t *msg, clSnapshot_t *oldframe, clSnapshot_t *n
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_UnpackNonPVSClient
|
||||
|
||||
Unpack info about non-visible client.
|
||||
================
|
||||
*/
|
||||
qboolean CL_UnpackNonPVSClient(int* packed, radarUnpacked_t* unpacked) {
|
||||
int x, y;
|
||||
int yaw;
|
||||
qboolean bValid;
|
||||
float range;
|
||||
|
||||
unpacked->clientNum = *packed & (MAX_CLIENTS - 1);
|
||||
if (unpacked->clientNum == cl.snap.ps.clientNum) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
x = ((*packed >> 6) & 0x7F) - (MAX_CLIENTS - 1);
|
||||
y = ((*packed >> 13) & 0x7F) - (MAX_CLIENTS - 1);
|
||||
yaw = (*packed >> 20) & 0x1F;
|
||||
bValid = (*packed >> 25) & 1;
|
||||
|
||||
if (com_radar_range && com_radar_range->value) {
|
||||
range = com_radar_range->value;
|
||||
} else {
|
||||
range = 0;
|
||||
}
|
||||
|
||||
unpacked->x = x * range / 63.f;
|
||||
unpacked->y = y * range / 63.f;
|
||||
|
||||
if (!bValid)
|
||||
{
|
||||
unpacked->x = x * range / 63.f * 1024;
|
||||
unpacked->y = y * range / 63.f * 1024;
|
||||
}
|
||||
|
||||
unpacked->yaw = yaw * 11.25f;
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ReadNonPVSClient
|
||||
|
||||
Reads packed info about non-visible client.
|
||||
================
|
||||
*/
|
||||
void CL_ReadNonPVSClient(int radarInfo) {
|
||||
radarUnpacked_t unpacked;
|
||||
|
||||
if (!cge) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CL_UnpackNonPVSClient(&radarInfo, &unpacked)) {
|
||||
unpacked.x += cl.snap.ps.origin[0];
|
||||
unpacked.y += cl.snap.ps.origin[1];
|
||||
cge->CG_ReadNonPVSClient(&unpacked);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
@@ -332,6 +395,9 @@ void CL_ParseSnapshot( msg_t *msg ) {
|
||||
}
|
||||
|
||||
cl.newSnapshots = qtrue;
|
||||
|
||||
// read radar info about invisible clients
|
||||
CL_ReadNonPVSClient(cl.snap.ps.radarInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -448,40 +514,6 @@ static void CL_ParseServerInfo(void)
|
||||
sizeof(clc.sv_dlURL));
|
||||
}
|
||||
|
||||
char* MSG_ReadGameStateChar_ver_15(msg_t* msg) {
|
||||
return MSG_ReadScrambledBigString(msg);
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime_ver_15(msg_t* msg) {
|
||||
return MSG_ReadFloat(msg);
|
||||
}
|
||||
|
||||
char* MSG_ReadGameStateChar_ver_6(msg_t* msg) {
|
||||
return MSG_ReadString(msg);
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime_ver_6(msg_t* msg) {
|
||||
return 1.f / atof(Info_ValueForKey(cl.gameState.stringData + cl.gameState.stringOffsets[CS_SYSTEMINFO], "sv_fps"));
|
||||
}
|
||||
|
||||
char* MSG_ReadGameStateChar(msg_t* msg) {
|
||||
if (MSG_IsProtocolVersion15()) {
|
||||
return MSG_ReadGameStateChar_ver_15(msg);
|
||||
} else {
|
||||
// smaller below version 15
|
||||
return MSG_ReadGameStateChar_ver_6(msg);
|
||||
}
|
||||
}
|
||||
|
||||
float MSG_ReadServerFrameTime(msg_t* msg) {
|
||||
if (MSG_IsProtocolVersion15()) {
|
||||
return MSG_ReadServerFrameTime_ver_15(msg);
|
||||
} else {
|
||||
// smaller below version 15
|
||||
return MSG_ReadServerFrameTime_ver_6(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseGamestate
|
||||
@@ -525,7 +557,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
if (csNum < 0 || csNum >= MAX_CONFIGSTRINGS) {
|
||||
Com_Error(ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
|
||||
}
|
||||
s = MSG_ReadGameStateChar(msg);
|
||||
s = MSG_ReadScrambledBigString(msg);
|
||||
len = strlen(s);
|
||||
|
||||
if (len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS) {
|
||||
@@ -554,7 +586,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
clc.clientNum = MSG_ReadLong(msg);
|
||||
// read the checksum feed
|
||||
clc.checksumFeed = MSG_ReadLong( msg );
|
||||
cls.serverFrameTime = MSG_ReadServerFrameTime(msg);
|
||||
cls.serverFrameTime = MSG_ReadServerFrameTime(msg, &cl.gameState);
|
||||
|
||||
// parse serverId and other cvars
|
||||
CL_SystemInfoChanged();
|
||||
|
||||
+3928
-4026
File diff suppressed because it is too large.
Load diff
+85
-66
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,110 +20,129 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UI_H__
|
||||
#define __CL_UI_H__
|
||||
#pragma once
|
||||
|
||||
#include "../uilib/ui_extern.h"
|
||||
#include "../uilib/uiwidget.h"
|
||||
|
||||
typedef struct {
|
||||
UIReggedMaterial *loading;
|
||||
UIReggedMaterial *loading;
|
||||
} static_media_t;
|
||||
|
||||
//
|
||||
// cvars
|
||||
//
|
||||
extern cvar_t* ui_health_start;
|
||||
extern cvar_t* ui_health_end;
|
||||
extern cvar_t *ui_health_start;
|
||||
extern cvar_t *ui_health_end;
|
||||
extern cvar_t *sound_overlay;
|
||||
|
||||
//
|
||||
// initialization
|
||||
//
|
||||
void CL_FillUIDef( void );
|
||||
void CL_InitializeUI( void );
|
||||
void CL_ShutdownUI( void );
|
||||
void CL_FillUIDef(void);
|
||||
void CL_InitializeUI(void);
|
||||
void CL_ShutdownUI(void);
|
||||
|
||||
//
|
||||
// general ui stuff
|
||||
//
|
||||
extern inventory_t client_inv;
|
||||
extern bind_t client_bind;
|
||||
extern cvar_t* cl_greenfps;
|
||||
extern bind_t client_bind;
|
||||
extern cvar_t *cl_greenfps;
|
||||
|
||||
const char *CvarGetForUI( const char *name, const char *defval );
|
||||
void UI_ClearState( void );
|
||||
void CL_BeginRegistration( void );
|
||||
void CL_EndRegistration(void);
|
||||
const char *CvarGetForUI(const char *name, const char *defval);
|
||||
void UI_ClearState(void);
|
||||
void CL_BeginRegistration(void);
|
||||
void CL_EndRegistration(void);
|
||||
|
||||
//
|
||||
// menu
|
||||
//
|
||||
extern Menu *ui_pLoadingMenu;
|
||||
|
||||
void UI_ShowMenu( const char *name, qboolean bForce );
|
||||
void UI_HideMenu( const char *name, qboolean bForce );
|
||||
void UI_ForceMenuOff( bool force );
|
||||
void UI_PushMenu( const char *name );
|
||||
void UI_ForceMenu( const char *name );
|
||||
qboolean UI_BindActive( void );
|
||||
void UI_ActivateView3D( void );
|
||||
void UI_MenuEscape( const char *name );
|
||||
void UI_CreateScoreboard( void );
|
||||
qboolean UI_MenuActive( void );
|
||||
qboolean UI_MenuUp( void );
|
||||
void UI_FocusMenuIfExists(void);
|
||||
void UI_DrawConnect( void );
|
||||
void UI_CreateDialog( const char *title, char *cvarname, const char *command, const char *cancelCommand, int width, int height, const char *shader, const char *okshader, const char *cancelshader );
|
||||
void UI_ToggleDMConsole( int iMode );
|
||||
void UI_ShowScoreboard_f( const char *pszMenuName );
|
||||
void UI_HideScoreboard_f( void );
|
||||
void UI_SetScoreBoardItem( int iItemNumber,
|
||||
const char *pszData1, const char *pszData2, const char *pszData3, const char *pszData4,
|
||||
const char *pszData5, const char *pszData6, const char *pszData7, const char *pszData8,
|
||||
const vec4_t pTextColor, const vec4_t pBackColor, qboolean bIsHeader );
|
||||
void UI_DeleteScoreBoardItems( int iMaxIndex );
|
||||
void UI_ShowMenu(const char *name, qboolean bForce);
|
||||
void UI_HideMenu(const char *name, qboolean bForce);
|
||||
void UI_ForceMenuOff(bool force);
|
||||
void UI_PushMenu(const char *name);
|
||||
void UI_ForceMenu(const char *name);
|
||||
qboolean UI_BindActive(void);
|
||||
void UI_SetReturnMenuToCurrent(void);
|
||||
void UI_ActivateView3D(void);
|
||||
void UI_MenuEscape(const char *name);
|
||||
void UI_CreateScoreboard(void);
|
||||
qboolean UI_MenuActive(void);
|
||||
qboolean UI_MenuUp(void);
|
||||
void UI_FocusMenuIfExists(void);
|
||||
void UI_DrawConnect(void);
|
||||
void UI_CreateDialog(
|
||||
const char *title,
|
||||
char *cvarname,
|
||||
const char *command,
|
||||
const char *cancelCommand,
|
||||
int width,
|
||||
int height,
|
||||
const char *shader,
|
||||
const char *okshader,
|
||||
const char *cancelshader
|
||||
);
|
||||
void UI_ToggleDMConsole(int iMode);
|
||||
void UI_ShowScoreboard_f(const char *pszMenuName);
|
||||
void UI_HideScoreboard_f(void);
|
||||
void UI_SetScoreBoardItem(
|
||||
int iItemNumber,
|
||||
const char *pszData1,
|
||||
const char *pszData2,
|
||||
const char *pszData3,
|
||||
const char *pszData4,
|
||||
const char *pszData5,
|
||||
const char *pszData6,
|
||||
const char *pszData7,
|
||||
const char *pszData8,
|
||||
const vec4_t pTextColor,
|
||||
const vec4_t pBackColor,
|
||||
qboolean bIsHeader
|
||||
);
|
||||
void UI_DeleteScoreBoardItems(int iMaxIndex);
|
||||
|
||||
//
|
||||
// ressources
|
||||
//
|
||||
void UI_BeginLoad( const char *pszMapName );
|
||||
void UI_EndLoad( void );
|
||||
void UI_AbortLoad( void );
|
||||
void UI_BeginLoadResource( void );
|
||||
void UI_EndLoadResource( void );
|
||||
void UI_EndLoadResource( const char *name );
|
||||
qboolean UI_IsResourceLoaded( const char *name );
|
||||
void UI_RegisterLoadResource( const char *name );
|
||||
void UI_ClearResource( void );
|
||||
void UI_LoadResource( const char *name );
|
||||
void UI_BeginLoad(const char *pszMapName);
|
||||
void UI_EndLoad(void);
|
||||
void UI_AbortLoad(void);
|
||||
void UI_BeginLoadResource(void);
|
||||
void UI_EndLoadResource(void);
|
||||
void UI_EndLoadResource(const char *name);
|
||||
qboolean UI_IsResourceLoaded(const char *name);
|
||||
void UI_RegisterLoadResource(const char *name);
|
||||
void UI_ClearResource(void);
|
||||
void UI_LoadResource(const char *name);
|
||||
|
||||
//
|
||||
// windows
|
||||
//
|
||||
void UI_DeactiveFloatingWindows( void );
|
||||
void UI_DeactiveFloatingWindows(void);
|
||||
|
||||
//
|
||||
// console
|
||||
//
|
||||
void UI_OpenConsole( void );
|
||||
qboolean UI_ConsoleIsVisible( void );
|
||||
qboolean UI_ConsoleIsOpen( void );
|
||||
void UI_CloseConsole( void );
|
||||
void UI_ToggleConsole( void );
|
||||
void UI_OpenDMConsole( int iMode );
|
||||
void UI_CloseDMConsole( void );
|
||||
void UI_ToggleDMConsole( int iMode );
|
||||
void UI_OpenDeveloperConsole( void );
|
||||
void UI_CloseDeveloperConsole( void );
|
||||
void UI_PrintConsole(const char* msg);
|
||||
void UI_OpenConsole(void);
|
||||
qboolean UI_ConsoleIsVisible(void);
|
||||
qboolean UI_ConsoleIsOpen(void);
|
||||
void UI_CloseConsole(void);
|
||||
void UI_ToggleConsole(void);
|
||||
void UI_OpenDMConsole(int iMode);
|
||||
void UI_CloseDMConsole(void);
|
||||
void UI_ToggleDMConsole(int iMode);
|
||||
void UI_OpenDeveloperConsole(void);
|
||||
void UI_CloseDeveloperConsole(void);
|
||||
void UI_PrintConsole(const char *msg);
|
||||
|
||||
//
|
||||
// callbacks
|
||||
//
|
||||
void UI_Update( void );
|
||||
void UI_ServerLoaded( void );
|
||||
void UI_ResolutionChange( void );
|
||||
void UI_KeyEvent( int key, unsigned int time );
|
||||
void UI_CharEvent( int ch );
|
||||
|
||||
#endif /* __CL_UI_H__ */
|
||||
void UI_Update(void);
|
||||
void UI_ServerLoaded(void);
|
||||
void UI_ResolutionChange(void);
|
||||
void UI_KeyEvent(int key, unsigned int time);
|
||||
void UI_CharEvent(int ch);
|
||||
+430
-182
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,281 +24,529 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
bind_t::bind_t()
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
|
||||
commandwidth = 100;
|
||||
commandheight = 20;
|
||||
primarykeywidth = 100;
|
||||
primarykeyheight = 20;
|
||||
alternatekeywidth = 100;
|
||||
alternatekeyheight = 20;
|
||||
fillwidth = 16;
|
||||
fillmaterial = NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(headermats); i++) {
|
||||
headermats[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bind_t::~bind_t()
|
||||
{
|
||||
Clear();
|
||||
Clear();
|
||||
}
|
||||
|
||||
void bind_t::Clear
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void bind_t::Clear(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
for (int i = binds.NumObjects(); i > 0; i--) {
|
||||
bind_item_t *bi;
|
||||
|
||||
bi = binds.ObjectAt(i);
|
||||
binds.RemoveObjectAt(i);
|
||||
|
||||
if (bi) {
|
||||
delete bi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( Listener, bindlistener, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
Event EV_Bind_Header
|
||||
(
|
||||
"header",
|
||||
EV_DEFAULT,
|
||||
"iss",
|
||||
"column_num name material",
|
||||
"Set the header of each column"
|
||||
);
|
||||
Event EV_Bind_Width
|
||||
(
|
||||
"bind_width",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"width",
|
||||
"Width of the bind menu"
|
||||
);
|
||||
Event EV_Bind_Height
|
||||
(
|
||||
"bind_height",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"height",
|
||||
"Height of the bind menu"
|
||||
);
|
||||
Event EV_Bind_FillWidth
|
||||
(
|
||||
"bind_fillwidth",
|
||||
EV_DEFAULT,
|
||||
"iS",
|
||||
"width material",
|
||||
"Width of the filling between widgets"
|
||||
);
|
||||
Event EV_Bind_CommandWidth
|
||||
(
|
||||
"bind_commandwidth",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"width",
|
||||
"Width of the command item"
|
||||
);
|
||||
Event EV_Bind_CommandHeight
|
||||
(
|
||||
"bind_commandheight",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"height",
|
||||
"Height of the command item"
|
||||
);
|
||||
Event EV_Bind_PrimaryKeyWidth
|
||||
(
|
||||
"bind_primarykeywidth",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"width",
|
||||
"Width of the primary key item"
|
||||
);
|
||||
Event EV_Bind_PrimaryKeyHeight
|
||||
(
|
||||
"bind_primarykeyheight",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"height",
|
||||
"Height of the primary key item"
|
||||
);
|
||||
Event EV_Bind_AlternateKeyWidth
|
||||
(
|
||||
"bind_alternatekeywidth",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"width",
|
||||
"Width of the alternate key item"
|
||||
);
|
||||
Event EV_Bind_AlternateKeyHeight
|
||||
(
|
||||
"bind_alternatekeyheight",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"height",
|
||||
"Height of the alternate key item"
|
||||
);
|
||||
Event EV_Bind_NewItem
|
||||
(
|
||||
"binditem",
|
||||
EV_DEFAULT,
|
||||
"ss",
|
||||
"name command",
|
||||
"Create a new bind item in the interface"
|
||||
);
|
||||
Event EV_Bind_Align
|
||||
(
|
||||
"align",
|
||||
EV_DEFAULT,
|
||||
"sSSSSS",
|
||||
"arg1 arg2 arg3 arg4 arg5 arg6",
|
||||
"Set the alignment on the bind menu"
|
||||
);
|
||||
Event EV_Bind_TitleForegroundColor
|
||||
(
|
||||
"titleforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the title foreground"
|
||||
);
|
||||
Event EV_Bind_TitleBackgroundColor
|
||||
(
|
||||
"titlebackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the title background"
|
||||
);
|
||||
Event EV_Bind_InactiveForegroundColor
|
||||
(
|
||||
"inactiveforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the inactive button foreground"
|
||||
);
|
||||
Event EV_Bind_InactiveBackgroundColor
|
||||
(
|
||||
"inactivebackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the inactive button background"
|
||||
);
|
||||
Event EV_Bind_ActiveForegroundColor
|
||||
(
|
||||
"activeforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the active button foreground"
|
||||
);
|
||||
Event EV_Bind_ActiveBackgroundColor
|
||||
(
|
||||
"activebackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the active button background"
|
||||
);
|
||||
Event EV_Bind_ActiveBorderColor
|
||||
(
|
||||
"activebordercolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the active button border"
|
||||
);
|
||||
Event EV_Bind_HighlightForegroundColor
|
||||
(
|
||||
"highlightforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the highlighted button foreground"
|
||||
);
|
||||
Event EV_Bind_HighlightBackgroundColor
|
||||
(
|
||||
"highlightbackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the highlighted button background"
|
||||
);
|
||||
Event EV_Bind_SelectForegroundColor
|
||||
(
|
||||
"selectforegroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the selected button foreground"
|
||||
);
|
||||
Event EV_Bind_SelectBackgroundColor
|
||||
(
|
||||
"selectbackgroundcolor",
|
||||
EV_DEFAULT,
|
||||
"ffff",
|
||||
"r g b a",
|
||||
"Set the color for the selected button background"
|
||||
);
|
||||
Event EV_Bind_ChangeSound
|
||||
(
|
||||
"changesound",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"soundname",
|
||||
"Set the name of the sound to play when the highlighted item changes"
|
||||
);
|
||||
Event EV_Bind_ActiveSound
|
||||
(
|
||||
"activesound",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"soundname",
|
||||
"Set the name of the sound to play when the item is made active"
|
||||
);
|
||||
Event EV_Bind_EnterSound
|
||||
(
|
||||
"entersound",
|
||||
EV_DEFAULT,
|
||||
"s",
|
||||
"soundname",
|
||||
"Set the name of the sound to play when the key is entered"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(Listener, bindlistener, NULL) {
|
||||
{&EV_Bind_Width, &bindlistener::Width },
|
||||
{&EV_Bind_Height, &bindlistener::Height },
|
||||
{&EV_Bind_FillWidth, &bindlistener::FillWidth },
|
||||
{&EV_Bind_CommandWidth, &bindlistener::CommandWidth },
|
||||
{&EV_Bind_CommandHeight, &bindlistener::CommandHeight },
|
||||
{&EV_Bind_PrimaryKeyWidth, &bindlistener::PrimaryKeyWidth },
|
||||
{&EV_Bind_PrimaryKeyHeight, &bindlistener::PrimaryKeyHeight },
|
||||
{&EV_Bind_AlternateKeyWidth, &bindlistener::AlternateKeyWidth },
|
||||
{&EV_Bind_AlternateKeyHeight, &bindlistener::AlternateKeyHeight },
|
||||
{&EV_Bind_Header, &bindlistener::Header },
|
||||
{&EV_Bind_NewItem, &bindlistener::NewItem },
|
||||
{&EV_Bind_Align, &bindlistener::Align },
|
||||
{&EV_Bind_TitleForegroundColor, &bindlistener::TitleForegroundColor },
|
||||
{&EV_Bind_TitleBackgroundColor, &bindlistener::TitleBackgroundColor },
|
||||
{&EV_Bind_InactiveForegroundColor, &bindlistener::InactiveForegroundColor },
|
||||
{&EV_Bind_InactiveBackgroundColor, &bindlistener::InactiveBackgroundColor },
|
||||
{&EV_Bind_ActiveForegroundColor, &bindlistener::ActiveForegroundColor },
|
||||
{&EV_Bind_ActiveBackgroundColor, &bindlistener::ActiveBackgroundColor },
|
||||
{&EV_Bind_ActiveBorderColor, &bindlistener::ActiveBorderColor },
|
||||
{&EV_Bind_HighlightForegroundColor, &bindlistener::HighlightForegroundColor},
|
||||
{&EV_Bind_HighlightBackgroundColor, &bindlistener::HighlightBackgroundColor},
|
||||
{&EV_Bind_SelectForegroundColor, &bindlistener::SelectForegroundColor },
|
||||
{&EV_Bind_SelectBackgroundColor, &bindlistener::SelectBackgroundColor },
|
||||
{&EV_Bind_ChangeSound, &bindlistener::ChangeSound },
|
||||
{&EV_Bind_ActiveSound, &bindlistener::ActiveSound },
|
||||
{&EV_Bind_EnterSound, &bindlistener::EnterSound },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
bindlistener::bindlistener()
|
||||
bindlistener::bindlistener() {}
|
||||
|
||||
bindlistener::bindlistener(bind_t *b)
|
||||
{
|
||||
bind = b;
|
||||
}
|
||||
|
||||
bindlistener::bindlistener
|
||||
(
|
||||
bind_t *b
|
||||
)
|
||||
|
||||
void bindlistener::Header(Event *ev)
|
||||
{
|
||||
bind = b;
|
||||
int num;
|
||||
|
||||
num = ev->GetInteger(1) - 1;
|
||||
if (num > ARRAY_LEN(bind_t::headers)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bind->headers[num] = ev->GetString(2);
|
||||
if (ev->NumArgs() > 2) {
|
||||
bind->headermats[num] = uWinMan.RegisterShader(ev->GetString(3));
|
||||
}
|
||||
}
|
||||
|
||||
bool bindlistener::Load
|
||||
(
|
||||
Script& script
|
||||
)
|
||||
|
||||
void bindlistener::ChangeSound(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
return false;
|
||||
bind->changesound = ev->GetString(1);
|
||||
}
|
||||
|
||||
void bindlistener::Header
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::ActiveSound(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->activesound = ev->GetString(1);
|
||||
}
|
||||
|
||||
void bindlistener::Width
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::EnterSound(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->entersound = ev->GetString(1);
|
||||
}
|
||||
|
||||
void bindlistener::FillWidth
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::SelectForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->selectfgcolor.r = ev->GetFloat(1);
|
||||
bind->selectfgcolor.g = ev->GetFloat(2);
|
||||
bind->selectfgcolor.b = ev->GetFloat(3);
|
||||
bind->selectfgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::Height
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::SelectBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->selectbgcolor.r = ev->GetFloat(1);
|
||||
bind->selectbgcolor.g = ev->GetFloat(2);
|
||||
bind->selectbgcolor.b = ev->GetFloat(3);
|
||||
bind->selectbgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::CommandWidth
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::TitleForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->titlefgcolor.r = ev->GetFloat(1);
|
||||
bind->titlefgcolor.g = ev->GetFloat(2);
|
||||
bind->titlefgcolor.b = ev->GetFloat(3);
|
||||
bind->titlefgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::CommandHeight
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::TitleBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->titlebgcolor.r = ev->GetFloat(1);
|
||||
bind->titlebgcolor.g = ev->GetFloat(2);
|
||||
bind->titlebgcolor.b = ev->GetFloat(3);
|
||||
bind->titlebgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::PrimaryKeyWidth
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::ActiveBorderColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->activebordercolor.r = ev->GetFloat(1);
|
||||
bind->activebordercolor.g = ev->GetFloat(2);
|
||||
bind->activebordercolor.b = ev->GetFloat(3);
|
||||
bind->activebordercolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::PrimaryKeyHeight
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::ActiveForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->activefgcolor.r = ev->GetFloat(1);
|
||||
bind->activefgcolor.g = ev->GetFloat(2);
|
||||
bind->activefgcolor.b = ev->GetFloat(3);
|
||||
bind->activefgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::AlternateKeyWidth
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::ActiveBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->activebgcolor.r = ev->GetFloat(1);
|
||||
bind->activebgcolor.g = ev->GetFloat(2);
|
||||
bind->activebgcolor.b = ev->GetFloat(3);
|
||||
bind->activebgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::AlternateKeyHeight
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::InactiveForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->inactivefgcolor.r = ev->GetFloat(1);
|
||||
bind->inactivefgcolor.g = ev->GetFloat(2);
|
||||
bind->inactivefgcolor.b = ev->GetFloat(3);
|
||||
bind->inactivefgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::NewItem
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::InactiveBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->inactivebgcolor.r = ev->GetFloat(1);
|
||||
bind->inactivebgcolor.g = ev->GetFloat(2);
|
||||
bind->inactivebgcolor.b = ev->GetFloat(3);
|
||||
bind->inactivebgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::Align
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::HighlightForegroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->highlightfgcolor.r = ev->GetFloat(1);
|
||||
bind->highlightfgcolor.g = ev->GetFloat(2);
|
||||
bind->highlightfgcolor.b = ev->GetFloat(3);
|
||||
bind->highlightfgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::TitleForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::HighlightBackgroundColor(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->highlightbgcolor.r = ev->GetFloat(1);
|
||||
bind->highlightbgcolor.g = ev->GetFloat(2);
|
||||
bind->highlightbgcolor.b = ev->GetFloat(3);
|
||||
bind->highlightbgcolor.a = ev->GetFloat(4);
|
||||
}
|
||||
|
||||
void bindlistener::TitleBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::Align(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= ev->NumArgs(); i++) {
|
||||
str align = ev->GetString(i);
|
||||
|
||||
if (!str::icmp(align, "left")) {
|
||||
bind->align |= WA_LEFT;
|
||||
} else if (!str::icmp(align, "right")) {
|
||||
bind->align |= WA_RIGHT;
|
||||
} else if (!str::icmp(align, "top")) {
|
||||
bind->align |= WA_TOP;
|
||||
} else if (!str::icmp(align, "bottom")) {
|
||||
bind->align |= WA_BOTTOM;
|
||||
} else if (!str::icmp(align, "centerx")) {
|
||||
bind->align |= WA_CENTERX;
|
||||
} else if (!str::icmp(align, "centery")) {
|
||||
bind->align |= WA_CENTERY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bindlistener::InactiveForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::NewItem(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind_item_t *bt;
|
||||
UIReggedMaterial *mat = NULL;
|
||||
|
||||
if (ev->NumArgs() > 2) {
|
||||
mat = uWinMan.RegisterShader(ev->GetString(3));
|
||||
}
|
||||
|
||||
str n = ev->GetString(1);
|
||||
str c = ev->GetString(2);
|
||||
|
||||
bt = new bind_item_t;
|
||||
bt->name = n;
|
||||
bt->command = c;
|
||||
bt->nameMaterial = mat;
|
||||
|
||||
bind->binds.AddObject(bt);
|
||||
}
|
||||
|
||||
void bindlistener::InactiveBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::Width(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->width = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::ActiveForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::Height(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->height = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::ActiveBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::FillWidth(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->fillwidth = ev->GetInteger(1);
|
||||
|
||||
if (ev->NumArgs() > 1) {
|
||||
bind->fillmaterial = uWinMan.RegisterShader(ev->GetString(2));
|
||||
}
|
||||
}
|
||||
|
||||
void bindlistener::ActiveBorderColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::CommandWidth(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->commandwidth = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::HighlightForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::CommandHeight(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->commandheight = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::HighlightBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::PrimaryKeyWidth(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->primarykeywidth = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::SelectForegroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::PrimaryKeyHeight(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->primarykeyheight = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::SelectBackgroundColor
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::AlternateKeyWidth(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->alternatekeywidth = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::ChangeSound
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void bindlistener::AlternateKeyHeight(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
bind->alternatekeyheight = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void bindlistener::ActiveSound
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
bool bindlistener::Load(Script& script)
|
||||
{
|
||||
// FIXME: stub
|
||||
str token;
|
||||
str errortext;
|
||||
|
||||
while (script.TokenAvailable(true)) {
|
||||
token = script.GetToken(true);
|
||||
|
||||
if (!token.length() || !ValidEvent(token)) {
|
||||
throw "invalid token";
|
||||
}
|
||||
|
||||
Event *event = new Event(token);
|
||||
|
||||
while (script.TokenAvailable(false)) {
|
||||
event->AddToken(script.GetToken(false));
|
||||
}
|
||||
|
||||
ProcessEvent(event);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void bindlistener::EnterSound
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
bool CL_LoadBind(const char *filename, bind_t *bind)
|
||||
{
|
||||
// FIXME: stub
|
||||
Script script;
|
||||
|
||||
bind->Clear();
|
||||
|
||||
bindlistener listener(bind);
|
||||
script.LoadFile(filename);
|
||||
// Load the bind file
|
||||
return listener.Load(script);
|
||||
}
|
||||
+82
-88
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,115 +20,109 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIBIND_H__
|
||||
#define __CL_UIBIND_H__
|
||||
#pragma once
|
||||
|
||||
class bind_item_t {
|
||||
class bind_item_t
|
||||
{
|
||||
public:
|
||||
str name;
|
||||
str command;
|
||||
UIReggedMaterial *nameMaterial;
|
||||
str name;
|
||||
str command;
|
||||
UIReggedMaterial *nameMaterial;
|
||||
|
||||
bind_item_t();
|
||||
bind_item_t( str name, str command, UIReggedMaterial *nameMaterial );
|
||||
bind_item_t();
|
||||
bind_item_t(str name, str command, UIReggedMaterial *nameMaterial);
|
||||
};
|
||||
|
||||
inline
|
||||
bind_item_t::bind_item_t()
|
||||
inline bind_item_t::bind_item_t()
|
||||
{
|
||||
nameMaterial = NULL;
|
||||
nameMaterial = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
bind_item_t::bind_item_t
|
||||
(
|
||||
str name,
|
||||
str command,
|
||||
UIReggedMaterial *nameMaterial
|
||||
)
|
||||
|
||||
inline bind_item_t::bind_item_t(str name, str command, UIReggedMaterial *nameMaterial)
|
||||
{
|
||||
this->name = name;
|
||||
this->command = command;
|
||||
this->nameMaterial = nameMaterial;
|
||||
this->name = name;
|
||||
this->command = command;
|
||||
this->nameMaterial = nameMaterial;
|
||||
}
|
||||
|
||||
class bind_t {
|
||||
class bind_t
|
||||
{
|
||||
public:
|
||||
int width;
|
||||
int height;
|
||||
int fillwidth;
|
||||
int commandwidth;
|
||||
int commandheight;
|
||||
int primarykeywidth;
|
||||
int primarykeyheight;
|
||||
int alternatekeywidth;
|
||||
int alternatekeyheight;
|
||||
int align;
|
||||
UColor titlebgcolor;
|
||||
UColor titlefgcolor;
|
||||
UColor activefgcolor;
|
||||
UColor activebgcolor;
|
||||
UColor activebordercolor;
|
||||
UColor inactivefgcolor;
|
||||
UColor inactivebgcolor;
|
||||
UColor highlightfgcolor;
|
||||
UColor highlightbgcolor;
|
||||
UColor selectfgcolor;
|
||||
UColor selectbgcolor;
|
||||
str changesound;
|
||||
str activesound;
|
||||
str entersound;
|
||||
str headers[ 3 ];
|
||||
UIReggedMaterial *headermats[ 3 ];
|
||||
UIReggedMaterial *fillmaterial;
|
||||
Container<bind_item_t *> binds;
|
||||
int width;
|
||||
int height;
|
||||
int fillwidth;
|
||||
int commandwidth;
|
||||
int commandheight;
|
||||
int primarykeywidth;
|
||||
int primarykeyheight;
|
||||
int alternatekeywidth;
|
||||
int alternatekeyheight;
|
||||
int align;
|
||||
UColor titlebgcolor;
|
||||
UColor titlefgcolor;
|
||||
UColor activefgcolor;
|
||||
UColor activebgcolor;
|
||||
UColor activebordercolor;
|
||||
UColor inactivefgcolor;
|
||||
UColor inactivebgcolor;
|
||||
UColor highlightfgcolor;
|
||||
UColor highlightbgcolor;
|
||||
UColor selectfgcolor;
|
||||
UColor selectbgcolor;
|
||||
str changesound;
|
||||
str activesound;
|
||||
str entersound;
|
||||
str headers[3];
|
||||
UIReggedMaterial *headermats[3];
|
||||
UIReggedMaterial *fillmaterial;
|
||||
Container<bind_item_t *> binds;
|
||||
|
||||
public:
|
||||
bind_t();
|
||||
~bind_t();
|
||||
bind_t();
|
||||
~bind_t();
|
||||
|
||||
void Clear( void );
|
||||
void Clear(void);
|
||||
};
|
||||
|
||||
class bindlistener : public Listener {
|
||||
class bindlistener : public Listener
|
||||
{
|
||||
protected:
|
||||
bind_t *bind;
|
||||
bind_t *bind;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( bindlistener );
|
||||
CLASS_PROTOTYPE(bindlistener);
|
||||
|
||||
public:
|
||||
bindlistener();
|
||||
bindlistener( bind_t *b );
|
||||
bindlistener();
|
||||
bindlistener(bind_t *b);
|
||||
|
||||
bool Load( Script& script );
|
||||
void Header( Event *ev );
|
||||
void Width( Event *ev );
|
||||
void FillWidth( Event *ev );
|
||||
void Height( Event *ev );
|
||||
void CommandWidth( Event *ev );
|
||||
void CommandHeight( Event *ev );
|
||||
void PrimaryKeyWidth( Event *ev );
|
||||
void PrimaryKeyHeight( Event *ev );
|
||||
void AlternateKeyWidth( Event *ev );
|
||||
void AlternateKeyHeight( Event *ev );
|
||||
void NewItem( Event *ev );
|
||||
void Align( Event *ev );
|
||||
void TitleForegroundColor( Event *ev );
|
||||
void TitleBackgroundColor( Event *ev );
|
||||
void InactiveForegroundColor( Event *ev );
|
||||
void InactiveBackgroundColor( Event *ev );
|
||||
void ActiveForegroundColor( Event *ev );
|
||||
void ActiveBackgroundColor( Event *ev );
|
||||
void ActiveBorderColor( Event *ev );
|
||||
void HighlightForegroundColor( Event *ev );
|
||||
void HighlightBackgroundColor( Event *ev );
|
||||
void SelectForegroundColor( Event *ev );
|
||||
void SelectBackgroundColor( Event *ev );
|
||||
void ChangeSound( Event *ev );
|
||||
void ActiveSound( Event *ev );
|
||||
void EnterSound( Event *ev );
|
||||
bool Load(Script& script);
|
||||
void Header(Event *ev);
|
||||
void Width(Event *ev);
|
||||
void FillWidth(Event *ev);
|
||||
void Height(Event *ev);
|
||||
void CommandWidth(Event *ev);
|
||||
void CommandHeight(Event *ev);
|
||||
void PrimaryKeyWidth(Event *ev);
|
||||
void PrimaryKeyHeight(Event *ev);
|
||||
void AlternateKeyWidth(Event *ev);
|
||||
void AlternateKeyHeight(Event *ev);
|
||||
void NewItem(Event *ev);
|
||||
void Align(Event *ev);
|
||||
void TitleForegroundColor(Event *ev);
|
||||
void TitleBackgroundColor(Event *ev);
|
||||
void InactiveForegroundColor(Event *ev);
|
||||
void InactiveBackgroundColor(Event *ev);
|
||||
void ActiveForegroundColor(Event *ev);
|
||||
void ActiveBackgroundColor(Event *ev);
|
||||
void ActiveBorderColor(Event *ev);
|
||||
void HighlightForegroundColor(Event *ev);
|
||||
void HighlightBackgroundColor(Event *ev);
|
||||
void SelectForegroundColor(Event *ev);
|
||||
void SelectBackgroundColor(Event *ev);
|
||||
void ChangeSound(Event *ev);
|
||||
void ActiveSound(Event *ev);
|
||||
void EnterSound(Event *ev);
|
||||
};
|
||||
|
||||
#endif
|
||||
bool CL_LoadBind(const char* filename, bind_t* bind);
|
||||
+209
-27
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,72 +22,254 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( USignal, FilePickerClass, NULL )
|
||||
class FilePickerItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str strings[3];
|
||||
|
||||
public:
|
||||
FilePickerItem(const str& fileName, const str& date, const str& size);
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
CLASS_DECLARATION(USignal, FilePickerClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &FilePickerClass::FileSelected },
|
||||
{&EV_UIListBase_ItemDoubleClicked, &FilePickerClass::FileChosen },
|
||||
{&W_Deactivated, &FilePickerClass::OnDeactivated},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
FilePickerClass::FilePickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
window = new UIFloatingWindow();
|
||||
window->Create(
|
||||
NULL,
|
||||
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
|
||||
"File Picker",
|
||||
UColor(0.15f, 0.195f, 0.278f),
|
||||
UHudColor
|
||||
);
|
||||
window->Connect(this, W_Deactivated, W_Deactivated);
|
||||
listbox = new UIListCtrl();
|
||||
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
|
||||
listbox->setBackgroundColor(UColor(0.02f, 0.07f, 0.005f), true);
|
||||
listbox->setForegroundColor(UHudColor);
|
||||
listbox->AddColumn("File Name", 0, 175, false, false);
|
||||
listbox->AddColumn("Date", 1, 125, false, false);
|
||||
listbox->AddColumn("Size", 2, 100, true, false);
|
||||
|
||||
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
listbox->AllowActivate(true);
|
||||
|
||||
// Added in 2.0
|
||||
// Don't localize elements
|
||||
listbox->SetDontLocalize();
|
||||
}
|
||||
|
||||
FilePickerClass::~FilePickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
if (listbox) {
|
||||
delete listbox;
|
||||
listbox = NULL;
|
||||
}
|
||||
|
||||
if (window) {
|
||||
delete window;
|
||||
window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void FilePickerClass::SetupFiles( void )
|
||||
void FilePickerClass::Setup(
|
||||
const char *root_directory, const char *current_directory, const char *ext, const char *ignore_files
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
Initialize(root_directory, current_directory, ext, ignore_files);
|
||||
}
|
||||
|
||||
void FilePickerClass::GotoParentDirectory( void )
|
||||
void FilePickerClass::Initialize(
|
||||
const char *root_directory, const char *current_directory, const char *ext, const char *ignore_files
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
rootDirectory = root_directory;
|
||||
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
|
||||
rootDirectory += "/";
|
||||
}
|
||||
|
||||
currentDirectory = current_directory;
|
||||
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
|
||||
currentDirectory += "/";
|
||||
}
|
||||
|
||||
extension = ext;
|
||||
ignoredFiles = ignore_files;
|
||||
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void FilePickerClass::GotoSubDirectory( str subdir )
|
||||
void FilePickerClass::GotoParentDirectory(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
|
||||
if (currentDirectory == rootDirectory) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = currentDirectory.length() - 2; i > 0; i--) {
|
||||
if (currentDirectory[i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentDirectory[i] == '/') {
|
||||
i++;
|
||||
}
|
||||
|
||||
currentDirectory = str(currentDirectory, 0, i);
|
||||
|
||||
// refresh files
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void FilePickerClass::Initialize( const char *root_directory, const char *current_directory, const char *ext )
|
||||
void FilePickerClass::GotoSubDirectory(str subdir)
|
||||
{
|
||||
// FIXME: stub
|
||||
currentDirectory += subdir + "/";
|
||||
|
||||
// refresh files
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void FilePickerClass::CloseWindow( void )
|
||||
void FilePickerClass::SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
str mappath;
|
||||
str work;
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
int i;
|
||||
char date[128];
|
||||
char size[128];
|
||||
|
||||
listbox->DeleteAllItems();
|
||||
|
||||
if (currentDirectory != rootDirectory) {
|
||||
// create the parent directory item
|
||||
listbox->AddItem(new FilePickerItem("..", "", ""));
|
||||
}
|
||||
|
||||
// retrieve directories
|
||||
filenames = FS_ListFiles(currentDirectory, "/", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
|
||||
if (filename[0] == '.' || !strlen(filename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
work = "[";
|
||||
work += filename;
|
||||
work += "]";
|
||||
|
||||
FS_FileTime(currentDirectory + filename, date, size);
|
||||
|
||||
listbox->AddItem(new FilePickerItem(work, date, size));
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
|
||||
filenames = FS_ListFiles(currentDirectory, extension, qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
|
||||
if (ignoredFiles.length() && strstr(filename, ignoredFiles)) {
|
||||
// Added in 2.0
|
||||
// Check for ignored files
|
||||
continue;
|
||||
}
|
||||
|
||||
work = filename;
|
||||
|
||||
FS_FileTime(currentDirectory + work, date, size);
|
||||
|
||||
listbox->AddItem(new FilePickerItem(work, date, size));
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
|
||||
window->setTitle(currentDirectory);
|
||||
}
|
||||
|
||||
void FilePickerClass::FileSelected( Event *ev )
|
||||
void FilePickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname) {}
|
||||
|
||||
void FilePickerClass::FileSelected(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
str name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
|
||||
|
||||
if (*name != '[' && *name != '.') {
|
||||
FileSelected(currentDirectory, name, currentDirectory + name);
|
||||
}
|
||||
|
||||
uii.Snd_PlaySound("sound/menu/scroll.wav");
|
||||
}
|
||||
|
||||
void FilePickerClass::FileSelected( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void FilePickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) {}
|
||||
|
||||
void FilePickerClass::FileChosen(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
str filename = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
|
||||
|
||||
if (*filename == '[') {
|
||||
uii.Snd_PlaySound("sound/menu/scroll.wav");
|
||||
|
||||
GotoSubDirectory(str(filename, 1, filename.length() - 1));
|
||||
} else if (*filename == '.') {
|
||||
GotoParentDirectory();
|
||||
} else {
|
||||
uii.Snd_PlaySound("sound/menu/apply.wav");
|
||||
|
||||
FileChosen(currentDirectory, filename, currentDirectory + filename);
|
||||
}
|
||||
}
|
||||
|
||||
void FilePickerClass::FileChosen( Event *ev )
|
||||
void FilePickerClass::CloseWindow(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
PostEvent(EV_Remove, 0);
|
||||
}
|
||||
|
||||
void FilePickerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void FilePickerClass::OnDeactivated(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void FilePickerClass::OnDeactivated( Event *ev )
|
||||
FilePickerItem::FilePickerItem(const str& fileName, const str& date, const str& size)
|
||||
{
|
||||
// FIXME: stub
|
||||
strings[0] = fileName;
|
||||
strings[1] = date;
|
||||
strings[2] = size;
|
||||
}
|
||||
|
||||
void FilePickerClass::Setup( const char *root_directory, const char *current_directory, const char *ext )
|
||||
int FilePickerItem::getListItemValue(int which) const
|
||||
{
|
||||
// FIXME: stub
|
||||
return atoi(strings[which]);
|
||||
}
|
||||
|
||||
griditemtype_t FilePickerItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str FilePickerItem::getListItemString(int which) const
|
||||
{
|
||||
return strings[which];
|
||||
}
|
||||
|
||||
void FilePickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean FilePickerItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,40 +20,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIFILEPICKER_H__
|
||||
#define __CL_UIFILEPICKER_H__
|
||||
#pragma once
|
||||
|
||||
class UIListCtrl;
|
||||
|
||||
class FilePickerClass : public USignal {
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
str extension;
|
||||
class FilePickerClass : public USignal
|
||||
{
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
str extension;
|
||||
// Added in 2.0
|
||||
str ignoredFiles;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( FilePickerClass );
|
||||
CLASS_PROTOTYPE(FilePickerClass);
|
||||
|
||||
private:
|
||||
void SetupFiles( void );
|
||||
void GotoParentDirectory( void );
|
||||
void GotoSubDirectory( str subdir );
|
||||
void Initialize( const char *root_directory, const char *current_directory, const char *ext );
|
||||
void SetupFiles(void);
|
||||
void GotoParentDirectory(void);
|
||||
void GotoSubDirectory(str subdir);
|
||||
// ignore_files parameter, added in 2.0
|
||||
void Initialize(const char *root_directory, const char *current_directory, const char *ext, const char* ignore_files);
|
||||
|
||||
protected:
|
||||
void CloseWindow( void );
|
||||
void FileSelected( Event *ev );
|
||||
virtual void FileSelected( str ¤tDirectory, str &partialName, str &fullname );
|
||||
void FileChosen( Event *ev );
|
||||
virtual void FileChosen( str ¤tDirectory, str &partialName, str &fullname );
|
||||
void OnDeactivated( Event *ev );
|
||||
void CloseWindow(void);
|
||||
void FileSelected(Event *ev);
|
||||
virtual void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void FileChosen(Event *ev);
|
||||
virtual void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void OnDeactivated(Event *ev);
|
||||
|
||||
public:
|
||||
FilePickerClass();
|
||||
~FilePickerClass();
|
||||
FilePickerClass();
|
||||
~FilePickerClass();
|
||||
|
||||
void Setup( const char *root_directory, const char *current_directory, const char *ext );
|
||||
void Setup(const char *root_directory, const char *current_directory, const char *ext, const char* ignore_files = NULL);
|
||||
};
|
||||
|
||||
#endif /* __CL_UIFILEPICKER_H__ */
|
||||
+183
-17
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -21,44 +21,210 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "../qcommon/localization.h"
|
||||
|
||||
CLASS_DECLARATION( UIListCtrl, UILANGameClass, NULL )
|
||||
class LANGameItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str strings[5];
|
||||
|
||||
public:
|
||||
LANGameItem();
|
||||
LANGameItem(
|
||||
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
|
||||
);
|
||||
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
Event EV_LANGame_JoinGame
|
||||
(
|
||||
"joingame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Join the currently selected server"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(UIListCtrl, UILANGameClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &UILANGameClass::SelectServer},
|
||||
{&EV_UIListBase_ItemDoubleClicked, &UILANGameClass::JoinServer },
|
||||
{&EV_LANGame_JoinGame, &UILANGameClass::JoinServer },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UILANGameClass::UILANGameClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
AllowActivate(true);
|
||||
setHeaderFont("facfont-20");
|
||||
|
||||
m_iLastUpdateTime = 0;
|
||||
m_noservers_mat = uWinMan.RegisterShader("textures/menu/noservers");
|
||||
}
|
||||
|
||||
void UILANGameClass::SetupServers( void )
|
||||
void UILANGameClass::Draw(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (cls.bNewLocalServerInfo) {
|
||||
SetupServers();
|
||||
}
|
||||
|
||||
UIListCtrl::Draw();
|
||||
|
||||
if (!getNumItems() && m_noservers_mat) {
|
||||
float x, y, w, h;
|
||||
|
||||
w = re.GetShaderWidth(m_noservers_mat->GetMaterial()) * m_vVirtualScale[0];
|
||||
h = re.GetShaderHeight(m_noservers_mat->GetMaterial()) * m_vVirtualScale[1];
|
||||
|
||||
UIRect2D frame = getClientFrame();
|
||||
x = (frame.size.width - w) * 0.5f;
|
||||
y = (frame.size.height - h) * 0.5f;
|
||||
|
||||
re.DrawStretchPic(x, y, w, h, 0, 0, 1, 1, m_noservers_mat->GetMaterial());
|
||||
}
|
||||
|
||||
if (m_iLastUpdateTime && m_iLastUpdateTime < cls.realtime) {
|
||||
Cvar_Set("cl_langamerefreshstatus", "Ready");
|
||||
m_iLastUpdateTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UILANGameClass::Draw( void )
|
||||
void UILANGameClass::UpdateUIElement(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
float width;
|
||||
|
||||
RemoveAllColumns();
|
||||
|
||||
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);
|
||||
|
||||
uWinMan.ActivateControl(this);
|
||||
|
||||
SetupServers();
|
||||
}
|
||||
|
||||
void UILANGameClass::SelectServer( Event *ev )
|
||||
void UILANGameClass::SetupServers(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
LANGameItem *pItem;
|
||||
const serverInfo_t *pServerInfo;
|
||||
|
||||
for (i = 1; i <= cls.numlocalservers; i++) {
|
||||
pServerInfo = &cls.localServers[i - 1];
|
||||
|
||||
if (i > getNumItems()) {
|
||||
pItem = new LANGameItem();
|
||||
AddItem(pItem);
|
||||
} else {
|
||||
pItem = static_cast<LANGameItem *>(GetItem(i));
|
||||
}
|
||||
|
||||
*pItem = LANGameItem(
|
||||
pServerInfo->hostName,
|
||||
pServerInfo->mapName,
|
||||
va("%02i/%02i", pServerInfo->clients, pServerInfo->maxClients),
|
||||
pServerInfo->gameTypeString,
|
||||
str(pServerInfo->ping)
|
||||
);
|
||||
}
|
||||
|
||||
while (cls.numlocalservers < getNumItems()) {
|
||||
DeleteItem(getNumItems());
|
||||
}
|
||||
|
||||
cls.bNewLocalServerInfo = false;
|
||||
m_iLastUpdateTime = 0;
|
||||
}
|
||||
|
||||
void UILANGameClass::JoinServer( Event *ev )
|
||||
void UILANGameClass::SelectServer(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
|
||||
static const char info[] = "\xFF\xFF\xFF\xFF\x02getinfo xxx";
|
||||
|
||||
Com_Printf("Requesting updated info from server...\n");
|
||||
Cvar_Set("cl_langamerefreshstatus", "Requesting updated info from server...");
|
||||
|
||||
NET_SendPacket(NS_CLIENT, sizeof(info), info, serverInfo.adr);
|
||||
m_iLastUpdateTime = cls.realtime + 3000;
|
||||
}
|
||||
|
||||
qboolean UILANGameClass::KeyEvent( int key, unsigned int time )
|
||||
void UILANGameClass::JoinServer(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
if (!getCurrentItem()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
|
||||
|
||||
UI_SetReturnMenuToCurrent();
|
||||
CL_Connect(NET_AdrToString(serverInfo.adr), netadrtype_t::NA_UNSPEC);
|
||||
}
|
||||
|
||||
void UILANGameClass::UpdateUIElement( void )
|
||||
qboolean UILANGameClass::KeyEvent(int key, unsigned int time)
|
||||
{
|
||||
// FIXME: stub
|
||||
switch (key) {
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
JoinServer(NULL);
|
||||
return true;
|
||||
case K_UPARROW:
|
||||
if (getCurrentItem() > 1) {
|
||||
TrySelectItem(getCurrentItem() - 1);
|
||||
SelectServer(NULL);
|
||||
}
|
||||
return false;
|
||||
case K_DOWNARROW:
|
||||
if (getCurrentItem() < getNumItems()) {
|
||||
TrySelectItem(getCurrentItem() + 1);
|
||||
SelectServer(NULL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return UIListBase::KeyEvent(key, time);
|
||||
}
|
||||
|
||||
LANGameItem::LANGameItem() {}
|
||||
|
||||
LANGameItem::LANGameItem(
|
||||
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
|
||||
)
|
||||
{
|
||||
strings[0] = hostName;
|
||||
strings[1] = mapName;
|
||||
strings[2] = players;
|
||||
strings[3] = gameTypeString;
|
||||
strings[4] = ping;
|
||||
}
|
||||
|
||||
int LANGameItem::getListItemValue(int which) const
|
||||
{
|
||||
return atoi(strings[which]);
|
||||
}
|
||||
|
||||
griditemtype_t LANGameItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str LANGameItem::getListItemString(int which) const
|
||||
{
|
||||
return strings[which];
|
||||
}
|
||||
|
||||
void LANGameItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean LANGameItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
+14
-16
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,29 +20,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UILANGAME_H__
|
||||
#define __CL_UILANGAME_H__
|
||||
#pragma once
|
||||
|
||||
class UILANGameClass : public UIListCtrl {
|
||||
class UILANGameClass : public UIListCtrl
|
||||
{
|
||||
protected:
|
||||
int m_iLastUpdateTime;
|
||||
UIReggedMaterial *m_noservers_mat;
|
||||
int m_iLastUpdateTime;
|
||||
UIReggedMaterial *m_noservers_mat;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UILANGameClass );
|
||||
CLASS_PROTOTYPE(UILANGameClass);
|
||||
|
||||
private:
|
||||
void SetupServers( void );
|
||||
void SetupServers(void);
|
||||
|
||||
protected:
|
||||
void Draw( void ) override;
|
||||
void SelectServer( Event *ev );
|
||||
void JoinServer( Event *ev );
|
||||
qboolean KeyEvent( int key, unsigned int time ) override;
|
||||
void UpdateUIElement( void ) override;
|
||||
void Draw(void) override;
|
||||
void SelectServer(Event *ev);
|
||||
void JoinServer(Event *ev);
|
||||
qboolean KeyEvent(int key, unsigned int time) override;
|
||||
void UpdateUIElement(void) override;
|
||||
|
||||
public:
|
||||
UILANGameClass();
|
||||
UILANGameClass();
|
||||
};
|
||||
|
||||
#endif /* __CL_UILANGAME_H__ */
|
||||
+314
-25
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -21,63 +21,352 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "../qcommon/localization.h"
|
||||
|
||||
CLASS_DECLARATION( UIListCtrl, UIFAKKLoadGameClass, NULL )
|
||||
class FAKKLoadGameItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str strings[4];
|
||||
|
||||
public:
|
||||
FAKKLoadGameItem(const str& missionName, const str& elapsedTime, const str& dateTime, const str& fileName);
|
||||
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
static UIFAKKLoadGameClass *loadgame_ui = NULL;
|
||||
|
||||
Event EV_FAKKLoadGame_LoadGame
|
||||
(
|
||||
"loadgame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Load the currently selected game"
|
||||
);
|
||||
Event EV_FAKKLoadGame_RemoveGame
|
||||
(
|
||||
"removegame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Delete the currently selected game"
|
||||
);
|
||||
Event EV_FAKKLoadGame_DeleteGame
|
||||
(
|
||||
"deletegame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Delete the currently selected game... for real"
|
||||
);
|
||||
Event EV_FAKKLoadGame_NoDeleteGame
|
||||
(
|
||||
"nodeletegame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Delete the currently selected game... for real"
|
||||
);
|
||||
Event EV_FAKKLoadGame_SaveGame
|
||||
(
|
||||
"savegame",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Save the currently selected game"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(UIListCtrl, UIFAKKLoadGameClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &UIFAKKLoadGameClass::SelectGame },
|
||||
{&EV_UIListBase_ItemDoubleClicked, &UIFAKKLoadGameClass::LoadGame },
|
||||
{&EV_FAKKLoadGame_RemoveGame, &UIFAKKLoadGameClass::RemoveGame },
|
||||
{&EV_FAKKLoadGame_DeleteGame, &UIFAKKLoadGameClass::DeleteGame },
|
||||
{&EV_FAKKLoadGame_NoDeleteGame, &UIFAKKLoadGameClass::NoDeleteGame},
|
||||
{&EV_FAKKLoadGame_LoadGame, &UIFAKKLoadGameClass::LoadGame },
|
||||
{&EV_FAKKLoadGame_SaveGame, &UIFAKKLoadGameClass::SaveGame },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UIFAKKLoadGameClass::UIFAKKLoadGameClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
AllowActivate(false);
|
||||
m_bRemovePending = false;
|
||||
|
||||
setHeaderFont("facfont-20");
|
||||
loadgame_ui = this;
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::SelectGame( Event *ev )
|
||||
UIFAKKLoadGameClass::~UIFAKKLoadGameClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
loadgame_ui = NULL;
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::LoadGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::UpdateUIElement(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
float width;
|
||||
|
||||
RemoveAllColumns();
|
||||
|
||||
width = getClientFrame().size.width;
|
||||
AddColumn(Sys_LV_CL_ConvertString("Mission"), 0, width * 0.555, false, false);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Elapsed Time"), 1, width * 0.17f, true, true);
|
||||
AddColumn(Sys_LV_CL_ConvertString("Date & Time Logged"), 2, width * 0.275f, true, true);
|
||||
|
||||
uWinMan.ActivateControl(this);
|
||||
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::SaveGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
int i;
|
||||
const char *searchFolder = Com_GetArchiveFolder();
|
||||
|
||||
// cleanup
|
||||
DeleteAllItems();
|
||||
|
||||
filenames = FS_ListFiles(searchFolder, "ssv", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename;
|
||||
str work;
|
||||
str gametime;
|
||||
str date;
|
||||
fileHandle_t f;
|
||||
savegamestruct_t save;
|
||||
|
||||
filename = filenames[i];
|
||||
work = searchFolder;
|
||||
work += "/";
|
||||
work += filename;
|
||||
|
||||
FS_FOpenFileRead(work, &f, qfalse, qtrue);
|
||||
if (!f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FS_Read(&save, sizeof(savegamestruct_t), f);
|
||||
FS_FCloseFile(f);
|
||||
|
||||
if (save.version != SAVEGAME_STRUCT_VERSION) {
|
||||
// wrong save game version
|
||||
continue;
|
||||
}
|
||||
|
||||
gametime = (save.mapTime / 1000);
|
||||
date = save.time;
|
||||
|
||||
AddItem(new FAKKLoadGameItem(save.comment, gametime, date, save.saveName));
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
|
||||
// sort by date
|
||||
SortByColumn(2);
|
||||
|
||||
// select the first item
|
||||
TrySelectItem(1);
|
||||
SelectGame(NULL);
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::RemoveGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::SelectGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
UIWidget *wid;
|
||||
const char *shotName;
|
||||
|
||||
if (getCurrentItem() > 0) {
|
||||
shotName = Com_GetArchiveFileName(GetItem(getCurrentItem())->getListItemString(3), "tga");
|
||||
} else {
|
||||
shotName = "textures/menu/no_saved_games.tga";
|
||||
}
|
||||
|
||||
wid = findSibling("LoadSaveShot");
|
||||
if (!wid) {
|
||||
return;
|
||||
}
|
||||
|
||||
wid->setMaterial(uWinMan.RefreshShader(shotName));
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::DeleteGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::RemoveGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (m_bRemovePending || getCurrentItem() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cbuf_ExecuteText(
|
||||
EXEC_NOW,
|
||||
"dialog \"\" \"\" \"widgetcommand LoadSaveList deletegame\" \"widgetcommand LoadSaveList nodeletegame\" 256 64 "
|
||||
"confirm_delete menu_button_trans menu_button_trans\n"
|
||||
);
|
||||
m_bRemovePending = true;
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::NoDeleteGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::NoDeleteGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
m_bRemovePending = false;
|
||||
}
|
||||
|
||||
qboolean UIFAKKLoadGameClass::KeyEvent( int key, unsigned int time )
|
||||
void UIFAKKLoadGameClass::DeleteGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
str name;
|
||||
cvar_t *var;
|
||||
m_bRemovePending = false;
|
||||
|
||||
if (getCurrentItem() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = GetItem(getCurrentItem())->getListItemString(3);
|
||||
var = Cvar_Get("g_lastsave", "", 0);
|
||||
|
||||
if (!strcmp(name, var->string)) {
|
||||
// Make sure the last save is not the save being deleted
|
||||
Cvar_Set("g_lastsave", "");
|
||||
}
|
||||
|
||||
Com_WipeSavegame(name);
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::UpdateUIElement( void )
|
||||
void UIFAKKLoadGameClass::LoadGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
char cmdString[266];
|
||||
str name;
|
||||
|
||||
if (getCurrentItem() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = GetItem(getCurrentItem())->getListItemString(3);
|
||||
// Execute the command
|
||||
Com_sprintf(cmdString, sizeof(cmdString), "loadgame %s\n", name.c_str());
|
||||
Cbuf_AddText(cmdString);
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::SetupFiles( void )
|
||||
void UIFAKKLoadGameClass::SaveGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
Cbuf_ExecuteText(EXEC_NOW, "savegame");
|
||||
}
|
||||
|
||||
void UI_SetupFiles( void ) {
|
||||
// FIXME: stub
|
||||
qboolean UIFAKKLoadGameClass::KeyEvent(int key, unsigned int time)
|
||||
{
|
||||
switch (key) {
|
||||
case K_DEL:
|
||||
RemoveGame(NULL);
|
||||
return qtrue;
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
LoadGame(NULL);
|
||||
return qtrue;
|
||||
case K_UPARROW:
|
||||
if (getCurrentItem() > 1) {
|
||||
TrySelectItem(getCurrentItem() - 1);
|
||||
SelectGame(NULL);
|
||||
return qtrue;
|
||||
}
|
||||
break;
|
||||
case K_DOWNARROW:
|
||||
if (getCurrentItem() < getNumItems()) {
|
||||
TrySelectItem(getCurrentItem() + 1);
|
||||
SelectGame(NULL);
|
||||
return qtrue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return UIListBase::KeyEvent(key, time);
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void UI_SetupFiles(void)
|
||||
{
|
||||
if (loadgame_ui && loadgame_ui->getShow()) {
|
||||
loadgame_ui->SetupFiles();
|
||||
}
|
||||
}
|
||||
|
||||
FAKKLoadGameItem::FAKKLoadGameItem(
|
||||
const str& missionName, const str& elapsedTime, const str& dateTime, const str& fileName
|
||||
)
|
||||
{
|
||||
strings[0] = missionName;
|
||||
strings[1] = elapsedTime;
|
||||
strings[2] = dateTime;
|
||||
strings[3] = fileName;
|
||||
}
|
||||
|
||||
int FAKKLoadGameItem::getListItemValue(int which) const
|
||||
{
|
||||
return atoi(strings[which]);
|
||||
}
|
||||
|
||||
griditemtype_t FAKKLoadGameItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str FAKKLoadGameItem::getListItemString(int which) const
|
||||
{
|
||||
str itemstring;
|
||||
|
||||
switch (which) {
|
||||
case 0:
|
||||
case 3:
|
||||
itemstring = strings[which];
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
int numseconds;
|
||||
int numseconds_hours;
|
||||
|
||||
// hours
|
||||
numseconds = atol(strings[1]);
|
||||
itemstring += (numseconds / 3600);
|
||||
itemstring += ":";
|
||||
|
||||
// minutes
|
||||
numseconds_hours = numseconds % 3600;
|
||||
if (numseconds_hours / 60 <= 9) {
|
||||
itemstring += "0";
|
||||
}
|
||||
itemstring += (numseconds_hours / 60);
|
||||
itemstring += ":";
|
||||
|
||||
// seconds
|
||||
if (numseconds_hours / 60 <= 9) {
|
||||
itemstring += "0";
|
||||
}
|
||||
itemstring += (numseconds_hours % 60);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
time_t time;
|
||||
char buffer[2048];
|
||||
|
||||
time = atol(strings[2]);
|
||||
strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y", localtime(&time));
|
||||
itemstring = buffer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return itemstring;
|
||||
}
|
||||
|
||||
void FAKKLoadGameItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean FAKKLoadGameItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
+18
-28
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,38 +20,28 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UILOADSAVE_H__
|
||||
#define __CL_UILOADSAVE_H__
|
||||
#pragma once
|
||||
|
||||
class UIFAKKLoadGameClass : public UIListCtrl {
|
||||
bool m_bRemovePending;
|
||||
class UIFAKKLoadGameClass : public UIListCtrl
|
||||
{
|
||||
bool m_bRemovePending;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIFAKKLoadGameClass );
|
||||
CLASS_PROTOTYPE(UIFAKKLoadGameClass);
|
||||
|
||||
protected:
|
||||
void SelectGame( Event *ev );
|
||||
void LoadGame( Event *ev );
|
||||
void SaveGame( Event *ev );
|
||||
void RemoveGame( Event *ev );
|
||||
void DeleteGame( Event *ev );
|
||||
void NoDeleteGame( Event *ev );
|
||||
qboolean KeyEvent( int key, unsigned int time ) override;
|
||||
void UpdateUIElement( void ) override;
|
||||
void SelectGame(Event *ev);
|
||||
void LoadGame(Event *ev);
|
||||
void SaveGame(Event *ev);
|
||||
void RemoveGame(Event *ev);
|
||||
void DeleteGame(Event *ev);
|
||||
void NoDeleteGame(Event *ev);
|
||||
qboolean KeyEvent(int key, unsigned int time) override;
|
||||
void UpdateUIElement(void) override;
|
||||
|
||||
public:
|
||||
UIFAKKLoadGameClass();
|
||||
UIFAKKLoadGameClass();
|
||||
~UIFAKKLoadGameClass();
|
||||
|
||||
void SetupFiles( void );
|
||||
void SetupFiles(void);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void UI_SetupFiles( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "cl_uimaprotationsetup.h"
|
||||
|
||||
Event EV_MapListBox_RefreshMapList
|
||||
(
|
||||
"RefreshMapList",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Refreshes the map list."
|
||||
);
|
||||
|
||||
Event EV_MapRotationListBox_RefreshRotationList
|
||||
(
|
||||
"RefreshRotationList",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Refreshed the map rotation list."
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(UIListBox, UIMapRotationListBox, NULL) {
|
||||
{&EV_MapRotationListBox_RefreshRotationList, &UIMapRotationListBox::RefreshRotationList},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UIMapRotationListBox::UIMapRotationListBox() {}
|
||||
|
||||
void UIMapRotationListBox::RefreshRotationList(Event *ev)
|
||||
{
|
||||
DeleteAllItems();
|
||||
PopulateRotationList();
|
||||
}
|
||||
|
||||
void UIMapRotationListBox::PopulateRotationList()
|
||||
{
|
||||
cvar_t *filter;
|
||||
cvar_t *maplistVar;
|
||||
const char *token;
|
||||
char mapBuffer[1024];
|
||||
|
||||
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
|
||||
if (!Q_stricmp(filter->string, "obj")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_obj", "", 0);
|
||||
} else if (!Q_stricmp(filter->string, "tow")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_tow", "", 0);
|
||||
} else if (!Q_stricmp(filter->string, "lib")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_lib", "", 0);
|
||||
} else if (!Q_stricmp(filter->string, "team")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_team", "", 0);
|
||||
} else if (!Q_stricmp(filter->string, "round")) {
|
||||
maplistVar = Cvar_Get("ui_maplist_round", "", 0);
|
||||
} else {
|
||||
maplistVar = Cvar_Get("ui_maplist_ffa", "", 0);
|
||||
}
|
||||
|
||||
strcpy(mapBuffer, maplistVar->string);
|
||||
|
||||
for (token = strtok(mapBuffer, " /"); token; token = strtok(NULL, " /")) {
|
||||
if (!Q_stricmp(token, "dm")) {
|
||||
continue;
|
||||
}
|
||||
if (!Q_stricmp(token, "obj")) {
|
||||
continue;
|
||||
}
|
||||
if (!Q_stricmp(token, "lib")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AddItem(token, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIListBox, UIMapListBox, NULL) {
|
||||
{&EV_MapListBox_RefreshMapList, &UIMapListBox::RefreshMapList},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
UIMapListBox::UIMapListBox() {}
|
||||
|
||||
void UIMapListBox::RefreshMapList(Event *ev)
|
||||
{
|
||||
DeleteAllItems();
|
||||
PopulateMapList();
|
||||
}
|
||||
|
||||
void UIMapListBox::PopulateMapList()
|
||||
{
|
||||
cvar_t *filter;
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
str path;
|
||||
int i;
|
||||
bool bTugOfWar = false;
|
||||
bool bObjective = false;
|
||||
bool bLiberation = false;
|
||||
|
||||
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
|
||||
if (!Q_stricmp(filter->string, "lib")) {
|
||||
path = "maps/lib/";
|
||||
bLiberation = true;
|
||||
} else if (!Q_stricmp(filter->string, "obj") || !Q_stricmp(filter->string, "tow")) {
|
||||
path = "maps/obj/";
|
||||
if (!Q_stricmp(filter->string, "tow")) {
|
||||
bTugOfWar = true;
|
||||
} else {
|
||||
bObjective = true;
|
||||
}
|
||||
} else {
|
||||
path = "maps/dm/";
|
||||
}
|
||||
|
||||
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
const char *token;
|
||||
char mapName[256];
|
||||
char tokenized[256];
|
||||
bool bHasMP = false;
|
||||
bool bHasTOW = false;
|
||||
bool bHasLib = false;
|
||||
|
||||
strcpy(mapName, filename);
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
|
||||
if (!COM_IsMapValid(mapName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bTugOfWar || bLiberation) {
|
||||
strcpy(tokenized, mapName);
|
||||
|
||||
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (bLiberation) {
|
||||
if (!Q_stricmp(token, "MP")) {
|
||||
bHasMP = true;
|
||||
}
|
||||
if (!Q_stricmp(token, "LIB")) {
|
||||
bHasLib = true;
|
||||
}
|
||||
if (bHasMP && bHasLib) {
|
||||
AddItem(mapName, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bTugOfWar) {
|
||||
if (!Q_stricmp(token, "MP")) {
|
||||
bHasMP = true;
|
||||
}
|
||||
if (!Q_stricmp(token, "TOW")) {
|
||||
bHasTOW = true;
|
||||
}
|
||||
if (bHasMP && bHasTOW) {
|
||||
AddItem(mapName, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (bObjective) {
|
||||
strcpy(tokenized, mapName);
|
||||
|
||||
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (!Q_stricmp(token, "obj")) {
|
||||
AddItem(mapName, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Q_stricmp(mapName, "mp_ship_lib")) {
|
||||
AddItem(mapName, NULL);
|
||||
}
|
||||
} else {
|
||||
AddItem(mapName, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (bObjective) {
|
||||
path = "maps/lib/";
|
||||
|
||||
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
const char *token;
|
||||
char mapName[256];
|
||||
char tokenized[256];
|
||||
|
||||
strcpy(mapName, filename);
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
strcpy(tokenized, mapName);
|
||||
|
||||
token = strtok(tokenized, "_");
|
||||
if (!Q_stricmp(token, "obj") || !Q_stricmp(mapName, "mp_ship_lib")) {
|
||||
AddItem(mapName, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bTugOfWar && !bObjective && !bLiberation) {
|
||||
int type;
|
||||
|
||||
for (type = 0; type < 2; type++) {
|
||||
if (type == 0) {
|
||||
path = "maps/obj/";
|
||||
} else {
|
||||
path = "maps/lib/";
|
||||
}
|
||||
|
||||
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
char mapName[256];
|
||||
|
||||
strcpy(mapName, filename);
|
||||
mapName[strlen(mapName) - 4] = 0;
|
||||
|
||||
if (!COM_IsMapValid(mapName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(mapName, "obj_team2") || !Q_stricmp(mapName, "obj_team4")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AddItem(mapName, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIAddToRotationButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIAddToRotationButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIAddToRotationButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *mapList;
|
||||
UIListBox *rotationList;
|
||||
size_t prefixLength;
|
||||
int i;
|
||||
|
||||
mapList = static_cast<UIListBox *>(uWinMan.FindWidget("Map List"));
|
||||
rotationList = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
|
||||
if (Cvar_Get("g_maprotation_filter", "ffa", 0)) {
|
||||
prefixLength = strlen("obj/") + 1;
|
||||
} else {
|
||||
prefixLength = 1;
|
||||
}
|
||||
|
||||
if (mapList && rotationList) {
|
||||
size_t mapLength = 0;
|
||||
int item = mapList->getCurrentItem();
|
||||
|
||||
for (i = 1; i <= rotationList->getNumItems(); i++) {
|
||||
str text = rotationList->getItemText(i);
|
||||
|
||||
mapLength += text.length();
|
||||
}
|
||||
|
||||
if (item) {
|
||||
str text = mapList->getItemText(item);
|
||||
|
||||
if (prefixLength + mapLength + text.length() < 256) {
|
||||
rotationList->AddItem(text, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIRemoveFromRotationButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIRemoveFromRotationButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIRemoveFromRotationButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *list;
|
||||
|
||||
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
if (list) {
|
||||
list->DeleteItem(list->getCurrentItem());
|
||||
}
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIRotationApplyButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIRotationApplyButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIRotationApplyButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *list;
|
||||
cvar_t *filter;
|
||||
str cvarName;
|
||||
str maplistStr;
|
||||
int i;
|
||||
bool bObjective = false;
|
||||
bool bLiberation = false;
|
||||
|
||||
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
|
||||
if (!Q_stricmp(filter->string, "obj")) {
|
||||
cvarName = "ui_maplist_obj";
|
||||
bObjective = true;
|
||||
} else if (!Q_stricmp(filter->string, "tow")) {
|
||||
cvarName = "ui_maplist_obj";
|
||||
bObjective = true;
|
||||
} else if (!Q_stricmp(filter->string, "lib")) {
|
||||
cvarName = "ui_maplist_lib";
|
||||
bLiberation = true;
|
||||
} else if (!Q_stricmp(filter->string, "team")) {
|
||||
cvarName = "ui_maplist_team";
|
||||
} else if (!Q_stricmp(filter->string, "round")) {
|
||||
cvarName = "ui_maplist_round";
|
||||
} else {
|
||||
cvarName = "ui_maplist_ffa";
|
||||
}
|
||||
Cvar_Set(cvarName, "");
|
||||
|
||||
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
if (list) {
|
||||
for (i = 1; i <= list->getNumItems(); i++) {
|
||||
const char *token;
|
||||
str text = list->getItemText(i);
|
||||
char map[256];
|
||||
bool bHasTOW = false, bHasObj = false, bHasLib = false, bHasShip = false;
|
||||
|
||||
strcpy(map, text);
|
||||
for (token = strtok(map, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (!Q_stricmp(token, "TOW")) {
|
||||
bHasTOW = true;
|
||||
break;
|
||||
}
|
||||
if (!Q_stricmp(token, "obj")) {
|
||||
bHasObj = true;
|
||||
break;
|
||||
}
|
||||
if (!Q_stricmp(token, "lib")) {
|
||||
bHasLib = true;
|
||||
break;
|
||||
}
|
||||
if (!Q_stricmp(token, "ship")) {
|
||||
bHasShip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bHasShip) {
|
||||
maplistStr += "lib/";
|
||||
} else if (bObjective || bHasTOW || bHasObj) {
|
||||
maplistStr += "obj/";
|
||||
} else if (bHasLib || bLiberation) {
|
||||
maplistStr += "lib/";
|
||||
} else {
|
||||
maplistStr += "dm/";
|
||||
}
|
||||
|
||||
maplistStr += text;
|
||||
maplistStr += " ";
|
||||
|
||||
if (i == 1) {
|
||||
Cvar_Set("ui_dmmap", maplistStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Cvar_Set(cvarName, maplistStr);
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIRotationMoveItemUpButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIRotationMoveItemUpButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIRotationMoveItemUpButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *list;
|
||||
int item;
|
||||
|
||||
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
item = list->getCurrentItem();
|
||||
|
||||
if (item < list->getNumItems() && list->getNumItems() > 1) {
|
||||
str text = list->getItemText(item + 1);
|
||||
|
||||
list->DeleteItem(list->getCurrentItem() - 1);
|
||||
list->InsertItem(text, item);
|
||||
list->setCurrentItem(item - 1);
|
||||
}
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIButton, UIRotationMoveItemDownButton, NULL) {
|
||||
{&W_LeftMouseUp, &UIRotationMoveItemDownButton::Released},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
void UIRotationMoveItemDownButton::Released(Event *ev)
|
||||
{
|
||||
UIListBox *list;
|
||||
int item;
|
||||
|
||||
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
|
||||
item = list->getCurrentItem();
|
||||
|
||||
if (item < list->getNumItems() && list->getNumItems() > 1) {
|
||||
str text = list->getItemText(item + 1);
|
||||
|
||||
list->DeleteItem(list->getCurrentItem() + 1);
|
||||
list->InsertItem(text, item);
|
||||
list->setCurrentItem(item + 1);
|
||||
}
|
||||
|
||||
UIButtonBase::Released(ev);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../uilib/uilistbox.h"
|
||||
|
||||
class UIMapRotationListBox : public UIListBox
|
||||
{
|
||||
CLASS_PROTOTYPE(UIMapRotationListBox);
|
||||
|
||||
public:
|
||||
UIMapRotationListBox();
|
||||
|
||||
void RefreshRotationList(Event *ev);
|
||||
void PopulateRotationList();
|
||||
};
|
||||
|
||||
class UIMapListBox : public UIListBox
|
||||
{
|
||||
CLASS_PROTOTYPE(UIMapListBox);
|
||||
|
||||
public:
|
||||
UIMapListBox();
|
||||
|
||||
void RefreshMapList(Event *ev);
|
||||
void PopulateMapList();
|
||||
};
|
||||
|
||||
class UIAddToRotationButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIAddToRotationButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
|
||||
class UIRemoveFromRotationButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIRemoveFromRotationButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
|
||||
class UIRotationApplyButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIRotationApplyButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
|
||||
class UIRotationMoveItemUpButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIRotationMoveItemUpButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
|
||||
class UIRotationMoveItemDownButton : public UIButton
|
||||
{
|
||||
CLASS_PROTOTYPE(UIRotationMoveItemDownButton);
|
||||
|
||||
public:
|
||||
void Released(Event *ev);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,47 +22,107 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, MapRunnerClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(FilePickerClass, MapRunnerClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void MapRunnerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void MapRunnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
str newName;
|
||||
|
||||
newName = "spmap " + str(fullname, 5, fullname.length() - 4) + "\n";
|
||||
// insert the command
|
||||
Cbuf_AddText(newName);
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, ViewSpawnerClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(FilePickerClass, UIPickFileClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void ViewSpawnerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
UIPickFileClass::UIPickFileClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
retobj = NULL;
|
||||
retevent = NULL;
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, LODSpawnerClass, NULL )
|
||||
UIPickFileClass::~UIPickFileClass()
|
||||
{
|
||||
{ NULL, NULL }
|
||||
if (retevent) {
|
||||
delete retevent;
|
||||
}
|
||||
}
|
||||
|
||||
void UIPickFileClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
if (!retobj || !retevent) {
|
||||
CloseWindow();
|
||||
return;
|
||||
}
|
||||
|
||||
retevent->AddString(fullname);
|
||||
retobj->ProcessEvent(retevent);
|
||||
|
||||
retevent = NULL;
|
||||
retobj = NULL;
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void PickFile(const char *name, Listener *obj, Event& event)
|
||||
{
|
||||
UIPickFileClass *picker;
|
||||
str currentpath;
|
||||
int i;
|
||||
|
||||
picker = new UIPickFileClass();
|
||||
picker->retevent = new Event(event);
|
||||
picker->retobj = obj;
|
||||
|
||||
if (name && *name && strchr(name, '/')) {
|
||||
currentpath = name;
|
||||
|
||||
for (i = currentpath.length(); i > 0; i--) {
|
||||
if (currentpath[i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentpath = str(currentpath, 0, i + 1);
|
||||
} else {
|
||||
currentpath = "";
|
||||
}
|
||||
|
||||
picker->Setup("", currentpath, ".*");
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(FilePickerClass, ViewSpawnerClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void LODSpawnerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void ViewSpawnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
str newName;
|
||||
|
||||
newName = "viewspawn " + fullname + "\n";
|
||||
// insert the command
|
||||
Cbuf_AddText(newName);
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, UIPickFileClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(FilePickerClass, LODSpawnerClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void UIPickFileClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void LODSpawnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
str newName;
|
||||
|
||||
void PickFile( const char *name, Listener *obj, Event& event )
|
||||
{
|
||||
// FIXME: stub
|
||||
newName = "lod_spawn " + fullname + "\n";
|
||||
// insert the command
|
||||
Cbuf_AddText(newName);
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,40 +20,44 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIMAPRUNNER_H__
|
||||
#define __CL_UIMAPRUNNER_H__
|
||||
#pragma once
|
||||
|
||||
class MapRunnerClass : public FilePickerClass {
|
||||
class MapRunnerClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( MapRunnerClass );
|
||||
CLASS_PROTOTYPE(MapRunnerClass);
|
||||
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
class ViewSpawnerClass : public FilePickerClass {
|
||||
class ViewSpawnerClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( ViewSpawnerClass );
|
||||
CLASS_PROTOTYPE(ViewSpawnerClass);
|
||||
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
class LODSpawnerClass : public FilePickerClass {
|
||||
class LODSpawnerClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( LODSpawnerClass );
|
||||
CLASS_PROTOTYPE(LODSpawnerClass);
|
||||
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
class UIPickFileClass : public FilePickerClass {
|
||||
class UIPickFileClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
Listener *retobj;
|
||||
Event *retevent;
|
||||
Listener *retobj;
|
||||
Event *retevent;
|
||||
|
||||
CLASS_PROTOTYPE( UIPickFileClass );
|
||||
CLASS_PROTOTYPE(UIPickFileClass);
|
||||
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
UIPickFileClass();
|
||||
~UIPickFileClass();
|
||||
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
void PickFile( const char *name, Listener *obj, Event& event );
|
||||
|
||||
#endif /* __CL_UIMAPRUNNER_H__ */
|
||||
void PickFile(const char *name, Listener *obj, Event& event);
|
||||
+138
-27
@@ -22,68 +22,179 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( UIWidget, FakkMiniconsole, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
Event EV_Minicon_Goin("_minicon_goin", EV_DEFAULT, NULL, NULL, "Event to make the miniconsole disappear");
|
||||
|
||||
CLASS_DECLARATION(UIWidget, FakkMiniconsole, NULL) {
|
||||
{&W_SizeChanged, &FakkMiniconsole::OnSizeChanged},
|
||||
{&EV_Minicon_Goin, &FakkMiniconsole::MoveInEvent },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
FakkMiniconsole::FakkMiniconsole()
|
||||
{
|
||||
// FIXME: stub
|
||||
m_maxlines = 0;
|
||||
m_reallyshown = true;
|
||||
m_boxstate = boxstate_t::box_in;
|
||||
m_boxtime = uid.time;
|
||||
m_movespeed = 500;
|
||||
}
|
||||
|
||||
|
||||
void FakkMiniconsole::VerifyBoxOut( void )
|
||||
void FakkMiniconsole::setShowState(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (m_reallyshown) {
|
||||
setShow(m_boxstate != boxstate_t::box_in);
|
||||
} else {
|
||||
setShow(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FakkMiniconsole::ChangeBoxState( boxstate_t state )
|
||||
void FakkMiniconsole::setRealShow(bool b)
|
||||
{
|
||||
// FIXME: stub
|
||||
m_reallyshown = b;
|
||||
setShowState();
|
||||
}
|
||||
|
||||
void FakkMiniconsole::HandleBoxMoving( void )
|
||||
void FakkMiniconsole::VerifyBoxOut(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
PostMoveinEvent();
|
||||
|
||||
if (m_boxstate && m_boxstate != boxstate_t::box_out) {
|
||||
ChangeBoxState(box_moving_out);
|
||||
}
|
||||
}
|
||||
|
||||
void FakkMiniconsole::PostMoveinEvent( void )
|
||||
void FakkMiniconsole::Print(const char *text)
|
||||
{
|
||||
// FIXME: stub
|
||||
str *lastline;
|
||||
const char *p;
|
||||
|
||||
if (!m_lines.NumObjects()) {
|
||||
m_lines.AddObject({});
|
||||
}
|
||||
|
||||
lastline = &m_lines.ObjectAt(m_lines.NumObjects());
|
||||
|
||||
if (*text) {
|
||||
for (p = text; *p; p++) {
|
||||
if (*p != '\n') {
|
||||
*lastline += *p;
|
||||
} else {
|
||||
m_lines.AddObject({});
|
||||
lastline = &m_lines.ObjectAt(m_lines.NumObjects());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastline && lastline->length() > 128) {
|
||||
Print("\n");
|
||||
}
|
||||
|
||||
if (m_maxlines < 0) {
|
||||
m_maxlines = 1;
|
||||
}
|
||||
|
||||
while (m_lines.NumObjects() > this->m_maxlines) {
|
||||
m_lines.RemoveObjectAt(1);
|
||||
}
|
||||
|
||||
VerifyBoxOut();
|
||||
}
|
||||
|
||||
void FakkMiniconsole::setShowState( void )
|
||||
void FakkMiniconsole::PostMoveinEvent(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (m_boxstate != boxstate_t::box_out) {
|
||||
return;
|
||||
}
|
||||
|
||||
CancelEventsOfType(EV_Minicon_Goin);
|
||||
PostEvent(new Event(EV_Minicon_Goin), 5.f);
|
||||
}
|
||||
|
||||
void FakkMiniconsole::OnSizeChanged( Event *ev )
|
||||
void FakkMiniconsole::OnSizeChanged(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
m_maxlines = m_frame.size.height / m_font->getHeight(false);
|
||||
}
|
||||
|
||||
void FakkMiniconsole::Print( const char *text )
|
||||
void FakkMiniconsole::MoveInEvent(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
ChangeBoxState(boxstate_t::box_moving_in);
|
||||
}
|
||||
|
||||
void FakkMiniconsole::Create( const UISize2D& size, const UColor& fore, const UColor& back, float alpha )
|
||||
void FakkMiniconsole::HandleBoxMoving(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
int delta;
|
||||
UIRect2D newRect;
|
||||
|
||||
if (m_boxstate == boxstate_t::box_out || m_boxstate == boxstate_t::box_in) {
|
||||
return;
|
||||
}
|
||||
|
||||
delta = m_movespeed * (uid.time - m_boxtime) / 1000;
|
||||
m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
|
||||
|
||||
switch (m_boxstate) {
|
||||
case boxstate_t::box_moving_in:
|
||||
newRect = UIRect2D(delta + m_frame.pos.x, m_frame.pos.y, m_frame.size.width, m_frame.size.height);
|
||||
if (newRect.pos.x >= uid.vidWidth) {
|
||||
newRect.pos.x = uid.vidWidth;
|
||||
ChangeBoxState(boxstate_t::box_in);
|
||||
}
|
||||
break;
|
||||
case boxstate_t::box_moving_out:
|
||||
newRect = UIRect2D(-delta + m_frame.pos.x, m_frame.pos.y, m_frame.size.width, m_frame.size.height);
|
||||
if (newRect.pos.x <= uid.vidWidth - newRect.size.width) {
|
||||
newRect.pos.x = uid.vidWidth - newRect.size.width;
|
||||
ChangeBoxState(boxstate_t::box_out);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ChangeBoxState(boxstate_t::box_in);
|
||||
break;
|
||||
}
|
||||
|
||||
setFrame(newRect);
|
||||
}
|
||||
|
||||
void FakkMiniconsole::MoveInEvent( Event *ev )
|
||||
void FakkMiniconsole::Draw(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
float aty;
|
||||
int i;
|
||||
|
||||
HandleBoxMoving();
|
||||
|
||||
m_font->setColor(m_foreground_color);
|
||||
aty = m_frame.size.height - m_font->getHeight(false);
|
||||
for (i = m_lines.NumObjects(); i > 0; i--) {
|
||||
if (-m_font->getHeight(false) >= aty) {
|
||||
break;
|
||||
}
|
||||
|
||||
m_font->Print(0, aty, m_lines.ObjectAt(i), -1, false);
|
||||
aty -= m_font->getHeight(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FakkMiniconsole::Draw( void )
|
||||
void FakkMiniconsole::Create(const UISize2D& size, const UColor& fore, const UColor& back, float alpha)
|
||||
{
|
||||
// FIXME: stub
|
||||
InitFrame(NULL, uid.vidWidth, 0, size.width, size.height, 0);
|
||||
|
||||
setBackgroundColor(back, true);
|
||||
setForegroundColor(fore);
|
||||
setBackgroundAlpha(alpha);
|
||||
Connect(this, W_SizeChanged, W_SizeChanged);
|
||||
OnSizeChanged(NULL);
|
||||
|
||||
m_movespeed = size.width * 3;
|
||||
|
||||
setShowState();
|
||||
}
|
||||
|
||||
void FakkMiniconsole::setRealShow( bool b )
|
||||
void FakkMiniconsole::ChangeBoxState(boxstate_t state)
|
||||
{
|
||||
// FIXME: stub
|
||||
m_boxstate = state;
|
||||
m_boxtime = uid.time;
|
||||
setShowState();
|
||||
if (state == boxstate_t::box_out) {
|
||||
PostMoveinEvent();
|
||||
}
|
||||
}
|
||||
+23
-25
@@ -20,38 +20,36 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIMINICON_H__
|
||||
#define __CL_UIMINICON_H__
|
||||
#pragma once
|
||||
|
||||
class FakkMiniconsole : public UIWidget {
|
||||
class FakkMiniconsole : public UIWidget
|
||||
{
|
||||
protected:
|
||||
Container<str> m_lines;
|
||||
int m_maxlines;
|
||||
bool m_reallyshown;
|
||||
bool m_boxmovingout;
|
||||
boxstate_t m_boxstate;
|
||||
int m_boxtime;
|
||||
int m_movespeed;
|
||||
Container<str> m_lines;
|
||||
int m_maxlines;
|
||||
bool m_reallyshown;
|
||||
bool m_boxmovingout;
|
||||
boxstate_t m_boxstate;
|
||||
int m_boxtime;
|
||||
int m_movespeed;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( FakkMiniconsole );
|
||||
CLASS_PROTOTYPE(FakkMiniconsole);
|
||||
|
||||
protected:
|
||||
void VerifyBoxOut( void );
|
||||
void ChangeBoxState( boxstate_t state );
|
||||
void HandleBoxMoving( void );
|
||||
void PostMoveinEvent( void );
|
||||
void setShowState( void );
|
||||
void VerifyBoxOut(void);
|
||||
void ChangeBoxState(boxstate_t state);
|
||||
void HandleBoxMoving(void);
|
||||
void PostMoveinEvent(void);
|
||||
void setShowState(void);
|
||||
|
||||
public:
|
||||
FakkMiniconsole();
|
||||
FakkMiniconsole();
|
||||
|
||||
void OnSizeChanged( Event *ev );
|
||||
void Print( const char *text );
|
||||
void Create( const UISize2D& size, const UColor& fore, const UColor& back, float alpha );
|
||||
void MoveInEvent( Event *ev );
|
||||
void Draw( void ) override;
|
||||
void setRealShow( bool b );
|
||||
void OnSizeChanged(Event *ev);
|
||||
void Print(const char *text);
|
||||
void Create(const UISize2D& size, const UColor& fore, const UColor& back, float alpha);
|
||||
void MoveInEvent(Event *ev);
|
||||
void Draw(void) override;
|
||||
void setRealShow(bool b);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -21,73 +21,337 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "../qcommon/localization.h"
|
||||
|
||||
CLASS_DECLARATION( USignal, MpMapPickerClass, NULL )
|
||||
class MpMapPickerItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str m_string;
|
||||
// Added in 2.0
|
||||
str m_directory;
|
||||
|
||||
public:
|
||||
MpMapPickerItem(const str& string, const str& directory);
|
||||
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
CLASS_DECLARATION(USignal, MpMapPickerClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &MpMapPickerClass::FileSelected },
|
||||
{&EV_UIListBase_ItemDoubleClicked, &MpMapPickerClass::FileChosen },
|
||||
{&W_Deactivated, &MpMapPickerClass::OnDeactivated},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
MpMapPickerClass::MpMapPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
window = new UIFloatingWindow();
|
||||
window->Create(
|
||||
NULL,
|
||||
UIRect2D((cls.glconfig.vidWidth - 300) / 2, (cls.glconfig.vidHeight - 200) / 2, 300, 200),
|
||||
"Select a Map",
|
||||
UColor(0.15f, 0.195f, 0.278f),
|
||||
UHudColor
|
||||
);
|
||||
window->setFont("facfont-20");
|
||||
window->PassEventToWidget("closebutton", new Event(EV_Widget_Disable));
|
||||
window->PassEventToWidget("minimizebutton", new Event(EV_Widget_Disable));
|
||||
window->Connect(this, W_Deactivated, W_Deactivated);
|
||||
|
||||
listbox = new UIListCtrl();
|
||||
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
|
||||
listbox->SetDrawHeader(false);
|
||||
listbox->setFont("facfont-20");
|
||||
listbox->FrameInitialized();
|
||||
listbox->AddColumn(Sys_LV_CL_ConvertString("Select a Map"), 0, 400, false, false);
|
||||
|
||||
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
listbox->AllowActivate(true);
|
||||
|
||||
// Added in 2.0
|
||||
// Don't localize elements
|
||||
listbox->SetDontLocalize();
|
||||
}
|
||||
|
||||
MpMapPickerClass::~MpMapPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
if (listbox) {
|
||||
delete listbox;
|
||||
listbox = NULL;
|
||||
}
|
||||
|
||||
if (window) {
|
||||
delete window;
|
||||
window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void MpMapPickerClass::SetupFiles( void )
|
||||
void MpMapPickerClass::Setup(const char *root_directory, const char *current_directory, const char *game_type)
|
||||
{
|
||||
// FIXME: stub
|
||||
Initialize(root_directory, current_directory, game_type);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::GotoParentDirectory( void )
|
||||
void MpMapPickerClass::Initialize(const char *root_directory, const char *current_directory, const char *game_type)
|
||||
{
|
||||
// FIXME: stub
|
||||
rootDirectory = root_directory;
|
||||
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
|
||||
rootDirectory += "/";
|
||||
}
|
||||
|
||||
currentDirectory = current_directory;
|
||||
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
|
||||
currentDirectory += "/";
|
||||
}
|
||||
|
||||
if (game_type) {
|
||||
gameType = game_type;
|
||||
}
|
||||
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void MpMapPickerClass::GotoSubDirectory( str subdir )
|
||||
void MpMapPickerClass::GotoParentDirectory(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
uintptr_t i;
|
||||
|
||||
if (currentDirectory == rootDirectory) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = currentDirectory.length() - 2; i > 0; i--) {
|
||||
if (currentDirectory[i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentDirectory[i] == '/') {
|
||||
i++;
|
||||
}
|
||||
|
||||
currentDirectory = str(currentDirectory, 0, i);
|
||||
|
||||
// refresh files
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void MpMapPickerClass::Initialize( const char *root_directory, const char *current_directory )
|
||||
void MpMapPickerClass::GotoSubDirectory(str subdir)
|
||||
{
|
||||
// FIXME: stub
|
||||
currentDirectory += subdir + "/";
|
||||
|
||||
// refresh files
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void MpMapPickerClass::CloseWindow( void )
|
||||
void MpMapPickerClass::SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
int i;
|
||||
char mapname[128];
|
||||
bool bTugOfWar = false, bObjective = false, bLiberation = false;
|
||||
|
||||
listbox->DeleteAllItems();
|
||||
|
||||
if (gameType == "tow") {
|
||||
bTugOfWar = true;
|
||||
} else if (gameType == "obj") {
|
||||
bObjective = true;
|
||||
} else if (gameType == "lib") {
|
||||
bLiberation = true;
|
||||
} else {
|
||||
// retrieve directories
|
||||
filenames = FS_ListFiles(rootDirectory, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
|
||||
strcpy(mapname, filename);
|
||||
mapname[strlen(mapname) - 4] = 0;
|
||||
|
||||
if (COM_IsMapValid(mapname)) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, rootDirectory));
|
||||
}
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
}
|
||||
|
||||
if (currentDirectory.length()) {
|
||||
if (currentDirectory == "maps/-/") {
|
||||
SetupSecondaryFiles(currentDirectory, bTugOfWar, bObjective, bLiberation);
|
||||
} else {
|
||||
SetupSecondaryFiles("maps/obj/", bTugOfWar, bObjective, bLiberation);
|
||||
SetupSecondaryFiles("maps/lib/", bTugOfWar, bObjective, bLiberation);
|
||||
}
|
||||
}
|
||||
|
||||
listbox->SortByColumn(0);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::FileSelected( Event *ev )
|
||||
void MpMapPickerClass::SetupSecondaryFiles(const char *path, bool bTugOfWar, bool bObjective, bool bLiberation)
|
||||
{
|
||||
// FIXME: stub
|
||||
char **filenames;
|
||||
int numfiles;
|
||||
int i;
|
||||
char mapname[128];
|
||||
char string[1024];
|
||||
|
||||
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
const char *filename = filenames[i];
|
||||
const char *token;
|
||||
|
||||
strcpy(mapname, filename);
|
||||
mapname[strlen(mapname) - 4] = 0;
|
||||
|
||||
if (!COM_IsMapValid(mapname)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bTugOfWar || bObjective || bLiberation) {
|
||||
bool bHasMP = false, bHasTOW = false, bHasLib = false;
|
||||
|
||||
strcpy(string, mapname);
|
||||
|
||||
for (token = strtok(string, "_"); token; token = strtok(NULL, "_")) {
|
||||
if (bObjective) {
|
||||
if (!Q_stricmp(token, "obj")) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
} else if (!Q_stricmp(token, "ship")) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
}
|
||||
}
|
||||
|
||||
if (bTugOfWar) {
|
||||
if (!Q_stricmp(token, "MP")) {
|
||||
bHasMP = true;
|
||||
}
|
||||
if (!Q_stricmp(token, "TOW")) {
|
||||
bHasTOW = true;
|
||||
}
|
||||
|
||||
if (bHasMP && bHasTOW) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
}
|
||||
}
|
||||
|
||||
if (bLiberation) {
|
||||
if (!Q_stricmp(token, "MP")) {
|
||||
bHasMP = true;
|
||||
}
|
||||
if (!Q_stricmp(token, "LIB")) {
|
||||
bHasLib = true;
|
||||
}
|
||||
|
||||
if (bHasMP && bHasLib) {
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!Q_stricmp(mapname, "obj_team2") || !Q_stricmp(mapname, "obj_team4")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listbox->AddItem(new MpMapPickerItem(mapname, path));
|
||||
}
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::FileSelected( str& currentDirectory, str& partialName, str& fullname )
|
||||
void MpMapPickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
FileChosen(currentDirectory, partialName, fullname);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::FileChosen( Event *ev )
|
||||
void MpMapPickerClass::FileSelected(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (!listbox->getCurrentItem()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uii.Snd_PlaySound("sound/menu/apply.wav");
|
||||
|
||||
UIListCtrlItem* item = listbox->GetItem(listbox->getCurrentItem());
|
||||
str name = item->getListItemString(0);
|
||||
str directory = item->getListItemString(1);
|
||||
|
||||
FileSelected(directory, name, directory + name);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::FileChosen( str& currentDirectory, str& partialName, str& fullname )
|
||||
void MpMapPickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
// FIXME: stub
|
||||
const char *pszFilename;
|
||||
str sCommand;
|
||||
|
||||
pszFilename = fullname.c_str();
|
||||
sCommand = va("ui_dmmap %s\n", pszFilename + 5);
|
||||
|
||||
Cbuf_AddText(sCommand);
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void MpMapPickerClass::OnDeactivated( Event *ev )
|
||||
void MpMapPickerClass::FileChosen(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
if (!listbox->getCurrentItem()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uii.Snd_PlaySound("sound/menu/apply.wav");
|
||||
|
||||
UIListCtrlItem* item = listbox->GetItem(listbox->getCurrentItem());
|
||||
str name = item->getListItemString(0);
|
||||
str directory = item->getListItemString(1);
|
||||
|
||||
FileSelected(directory, name, directory + name);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::Setup( const char *root_directory, const char *current_directory )
|
||||
void MpMapPickerClass::CloseWindow(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
PostEvent(EV_Remove, 0);
|
||||
}
|
||||
|
||||
void MpMapPickerClass::OnDeactivated(Event *ev)
|
||||
{
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
MpMapPickerItem::MpMapPickerItem(const str& string, const str& directory)
|
||||
{
|
||||
m_string = string;
|
||||
m_directory = directory;
|
||||
}
|
||||
|
||||
int MpMapPickerItem::getListItemValue(int which) const
|
||||
{
|
||||
return atoi(m_string);
|
||||
}
|
||||
|
||||
griditemtype_t MpMapPickerItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str MpMapPickerItem::getListItemString(int which) const
|
||||
{
|
||||
switch (which) {
|
||||
default:
|
||||
case 0:
|
||||
return m_string;
|
||||
case 1:
|
||||
return m_directory;
|
||||
}
|
||||
}
|
||||
|
||||
void MpMapPickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean MpMapPickerItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,39 +20,40 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIMPMAPPICKER_H__
|
||||
#define __CL_UIMPMAPPICKER_H__
|
||||
#pragma once
|
||||
|
||||
class UIFloatingWindow;
|
||||
|
||||
class MpMapPickerClass : public USignal {
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
class MpMapPickerClass : public USignal
|
||||
{
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
str gameType;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( MpMapPickerClass );
|
||||
CLASS_PROTOTYPE(MpMapPickerClass);
|
||||
|
||||
private:
|
||||
void SetupFiles( void );
|
||||
void GotoParentDirectory( void );
|
||||
void GotoSubDirectory( str subdir );
|
||||
void Initialize( const char *root_directory, const char *current_directory );
|
||||
void SetupFiles(void);
|
||||
void SetupSecondaryFiles(const char *path, bool bTugOfWar, bool bObjective, bool bLiberation);
|
||||
void GotoParentDirectory(void);
|
||||
void GotoSubDirectory(str subdir);
|
||||
void Initialize(const char *root_directory, const char *current_directory, const char *game_type);
|
||||
|
||||
protected:
|
||||
void CloseWindow( void );
|
||||
void FileSelected( Event *ev );
|
||||
virtual void FileSelected( str& currentDirectory, str& partialName, str& fullname );
|
||||
void FileChosen( Event *ev );
|
||||
virtual void FileChosen( str& currentDirectory, str& partialName, str& fullname );
|
||||
void OnDeactivated( Event *ev );
|
||||
void CloseWindow(void);
|
||||
void FileSelected(Event *ev);
|
||||
virtual void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void FileChosen(Event *ev);
|
||||
virtual void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void OnDeactivated(Event *ev);
|
||||
|
||||
public:
|
||||
MpMapPickerClass();
|
||||
~MpMapPickerClass();
|
||||
MpMapPickerClass();
|
||||
~MpMapPickerClass();
|
||||
|
||||
void Setup( const char *root_directory, const char *current_directory );
|
||||
// game_type was added in 2.0
|
||||
void Setup(const char *root_directory, const char *current_directory, const char *game_type = NULL);
|
||||
};
|
||||
|
||||
#endif /* __CL_UIMPMAPPICKER_H__ */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,62 +22,361 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( USignal, PlayerModelPickerClass, NULL )
|
||||
class PMPickerItem : public UIListCtrlItem
|
||||
{
|
||||
{ NULL, NULL }
|
||||
str m_string;
|
||||
|
||||
public:
|
||||
PMPickerItem(const str& string);
|
||||
|
||||
int getListItemValue(int which) const override;
|
||||
griditemtype_t getListItemType(int which) const override;
|
||||
str getListItemString(int which) const override;
|
||||
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
|
||||
qboolean IsHeaderEntry() const override;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char *fileName;
|
||||
const char *displayName;
|
||||
} PMPickerModel_t;
|
||||
|
||||
static const PMPickerModel_t pickerModels[] = {
|
||||
// 2.0 skins
|
||||
{"allied_101st_captain", "US - 101st Airborne Captain" },
|
||||
{"allied_101st_infantry", "US - 101st Airborne Private 1" },
|
||||
{"allied_101st_scout", "US - 101st Airborne Private 2" },
|
||||
{"allied_501st_pir_scout", "US - 501st Paratrooper 1" },
|
||||
{"allied_501st_pir_soldier", "US - 501st Paratrooper 2" },
|
||||
// 1.0 skins
|
||||
{"allied_airborne", "US - 501st Paratrooper 3" },
|
||||
// Readded in OPM (was removed in 2.0)
|
||||
{"allied_manon", "US - Manon" },
|
||||
// 2.0 skins
|
||||
{"allied_british_6th_airborne_captain", "UK - 6th Airborne Captain" },
|
||||
{"allied_british_6th_airborne_paratrooper", "UK - 6th Airborne Paratrooper" },
|
||||
// 1.0 skins
|
||||
{"allied_pilot", "US - Army Pilot" },
|
||||
// 2.0 skins
|
||||
{"allied_russian_corporal", "RA - Corporal" },
|
||||
{"allied_russian_crazy_boris", "RA - Crazy Boris" },
|
||||
{"allied_russian_recon_scout", "RA - Junior Lieutenant" },
|
||||
{"allied_russian_recon_soldier", "RA - Black Sea Petty Officer" },
|
||||
// 1.0 skins
|
||||
{"allied_sas", "UK - SAS Officer" },
|
||||
{"american_army", "US - Soldier" },
|
||||
{"american_ranger", "US - Ranger" },
|
||||
// 1.0 skins
|
||||
{"german_afrika_officer", "DE - Afrika Officer" },
|
||||
{"german_afrika_private", "DE - Afrika Private" },
|
||||
// 2.0 skins
|
||||
{"german_ardennes_artillery_commander", "DE - Artillery Commander" },
|
||||
{"german_dday_colonel", "DE - Normandy Colonel" },
|
||||
// 1.0 skins
|
||||
{"german_elite_officer", "DE - Elite Officer" },
|
||||
{"german_elite_sentry", "DE - Elite Sentry" },
|
||||
{"german_kradshutzen", "DE - Kradshutzen" },
|
||||
{"german_panzer_grenadier", "DE - Panzer Grenadier" },
|
||||
{"german_panzer_obershutze", "DE - Panzer Obershutze" },
|
||||
{"german_panzer_shutze", "DE - Panzer Shutze" },
|
||||
{"german_panzer_tankcommander", "DE - Panzer Tank Commander" },
|
||||
{"german_scientist", "DE - German Scientist" },
|
||||
// Those skins were superseded by german_waffenss
|
||||
{"german_waffen_officer", "DE - Waffen Officer" },
|
||||
{"german_waffen_shutze", "DE - Waffen Shutze" },
|
||||
// 1.0 skins
|
||||
{"german_waffenss_officer", "DE - Waffen Officer" },
|
||||
{"german_waffenss_shutze", "DE - Waffen Shutze" },
|
||||
{"german_wehrmacht_officer", "DE - Wehrmacht Officer" },
|
||||
{"german_wehrmacht_soldier", "DE - Wehrmacht Soldier" },
|
||||
{"german_winter_1", "DE - Winter Infantry 1" },
|
||||
{"german_winter_2", "DE - Winter Infantry 2" },
|
||||
{"german_worker", "DE - German Mechanic" },
|
||||
// 2.11 skins
|
||||
{"allied_british_tank_corporal", "UK - 6th Royal Tank Regiment" },
|
||||
{"allied_russian_seaman", "RA - Red Navy Seaman" },
|
||||
{"german_Panzer_Corporal", "DE - 1st Panzer Regiment" },
|
||||
{"allied_technician", "US - Air Force Technician" },
|
||||
{"german_stukageschwader", "DE - Stukageschwader" },
|
||||
// 2.30 skins
|
||||
{"It_AX_Ital_Vol", "IT - 10th Army XXI Corps" },
|
||||
{"SC_AX_Ital_Inf", "IT - 6th Army 202nd Coastal Div"},
|
||||
{"SC_AX_Ital_Inf2", "IT - 114th Inf Regiment" },
|
||||
{"SC_AX_ITAL_PARA", "IT - Paracadutista Militare" },
|
||||
// 2.40 skins
|
||||
{"allied_Wheathers", "US - General Wheathers" },
|
||||
{"allied_US_Tank", "US - II Corps Tank Commander" },
|
||||
{"allied_US_Mask", "US - II Corps Infantry" },
|
||||
{"allied_british_Cmd", "UK - 10th Corps" },
|
||||
{"allied_british_Tank", "UK - 8th Army" },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
const char *PM_FilenameToDisplayname(const char *fileName)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; pickerModels[i].fileName; i++) {
|
||||
const PMPickerModel_t& model = pickerModels[i];
|
||||
|
||||
if (!Q_stricmp(model.fileName, fileName)) {
|
||||
return model.displayName;
|
||||
}
|
||||
}
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
const char *PM_DisplaynameToFilename(const char *displayName)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; pickerModels[i].fileName; i++) {
|
||||
const PMPickerModel_t& model = pickerModels[i];
|
||||
|
||||
if (!Q_stricmp(model.displayName, displayName)) {
|
||||
return model.fileName;
|
||||
}
|
||||
}
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(USignal, PlayerModelPickerClass, NULL) {
|
||||
{&EV_UIListBase_ItemSelected, &PlayerModelPickerClass::FileSelected },
|
||||
{&EV_UIListBase_ItemDoubleClicked, &PlayerModelPickerClass::FileChosen },
|
||||
{&UIFloatingWindow::W_ClosePressed, &PlayerModelPickerClass::OnDeactivated},
|
||||
{&W_Deactivated, &PlayerModelPickerClass::OnDeactivated},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
PlayerModelPickerClass::PlayerModelPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
window = new UIFloatingWindow();
|
||||
window->Create(
|
||||
NULL,
|
||||
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
|
||||
"Player Model Select...",
|
||||
UColor(0.15f, 0.195f, 0.278f),
|
||||
UHudColor
|
||||
);
|
||||
window->setFont("facfont-20");
|
||||
window->PassEventToWidget("closebutton", new Event(EV_Widget_Disable));
|
||||
window->PassEventToWidget("minimizebutton", new Event(EV_Widget_Disable));
|
||||
window->Connect(this, W_Deactivated, W_Deactivated);
|
||||
|
||||
listbox = new UIListCtrl();
|
||||
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
|
||||
listbox->SetDrawHeader(false);
|
||||
listbox->setFont("facfont-20");
|
||||
listbox->FrameInitialized();
|
||||
listbox->AddColumn("Player Model", 0, 400, false, false);
|
||||
|
||||
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
|
||||
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
|
||||
listbox->AllowActivate(true);
|
||||
|
||||
// Added in 2.0
|
||||
// Don't localize elements
|
||||
listbox->SetDontLocalize();
|
||||
|
||||
m_bGermanModels = false;
|
||||
}
|
||||
|
||||
PlayerModelPickerClass::~PlayerModelPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
if (listbox) {
|
||||
delete listbox;
|
||||
listbox = NULL;
|
||||
}
|
||||
|
||||
if (window) {
|
||||
delete window;
|
||||
window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::SetupFiles( void )
|
||||
void PlayerModelPickerClass::Setup(const char *root_directory, const char *current_directory, qboolean bGermanModels)
|
||||
{
|
||||
// FIXME: stub
|
||||
Initialize(root_directory, current_directory, bGermanModels);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::Initialize( const char *root_directory, const char *current_directory, qboolean bGermanModels )
|
||||
void PlayerModelPickerClass::Initialize(
|
||||
const char *root_directory, const char *current_directory, qboolean bGermanModels
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
rootDirectory = root_directory;
|
||||
m_bGermanModels = bGermanModels;
|
||||
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
|
||||
rootDirectory += "/";
|
||||
}
|
||||
|
||||
currentDirectory = current_directory;
|
||||
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
|
||||
currentDirectory += "/";
|
||||
}
|
||||
|
||||
SetupFiles();
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::CloseWindow( void )
|
||||
void PlayerModelPickerClass::SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
str mappath;
|
||||
char work[128];
|
||||
char **filenames;
|
||||
const char *displayName;
|
||||
int numfiles;
|
||||
int i;
|
||||
int iLen;
|
||||
qboolean bIsGerman;
|
||||
|
||||
// cleanup
|
||||
listbox->DeleteAllItems();
|
||||
|
||||
if (m_bGermanModels) {
|
||||
window->setTitle("Select Your Axis Player Model");
|
||||
} else {
|
||||
window->setTitle("Select Your Allied Player Model");
|
||||
}
|
||||
|
||||
filenames = FS_ListFiles(currentDirectory, ".tik", qfalse, &numfiles);
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
Q_strncpyz(work, filenames[i], sizeof(work));
|
||||
|
||||
if (strstr(work, "_fps")) {
|
||||
// ignore view models
|
||||
continue;
|
||||
}
|
||||
|
||||
if (work[0] == '_') {
|
||||
// ignore hidden models
|
||||
continue;
|
||||
}
|
||||
|
||||
// allied_manon readded in OPM
|
||||
//if (!Q_stricmpn(work, "allied_manon")) {
|
||||
// continue;
|
||||
//}
|
||||
|
||||
bIsGerman = !Q_stricmpn(work, "german", 6u) || !Q_stricmpn(work, "axis", 4u) || !Q_stricmpn(work, "it", 2u)
|
||||
|| !Q_stricmpn(work, "sc", 2u);
|
||||
|
||||
if (m_bGermanModels != bIsGerman) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// strip the extension
|
||||
work[strlen(work) - 4] = 0;
|
||||
displayName = PM_FilenameToDisplayname(work);
|
||||
|
||||
listbox->AddItem(new PMPickerItem(displayName));
|
||||
}
|
||||
|
||||
FS_FreeFileList(filenames);
|
||||
|
||||
listbox->SortByColumn(0);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::FileSelected( Event *ev )
|
||||
void PlayerModelPickerClass::FileSelected(
|
||||
const str& name, const str& currentDirectory, const str& partialName, const str& fullname
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
FileChosen(name, currentDirectory, partialName, fullname);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::FileSelected( str& currentDirectory, str& partialName, str& fullname )
|
||||
void PlayerModelPickerClass::FileSelected(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
str name;
|
||||
char donotshowssindeorfr[64];
|
||||
str fullname;
|
||||
|
||||
name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
|
||||
fullname = PM_DisplaynameToFilename(name);
|
||||
|
||||
if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
|
||||
Q_strncpyz(donotshowssindeorfr, "german_waffen_", sizeof(donotshowssindeorfr));
|
||||
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
|
||||
} else {
|
||||
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));
|
||||
}
|
||||
|
||||
FileSelected(name, currentDirectory, fullname, currentDirectory + donotshowssindeorfr);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::FileChosen( Event *ev )
|
||||
void PlayerModelPickerClass::FileChosen(
|
||||
const str& name, const str& currentDirectory, const str& partialName, const str& fullname
|
||||
)
|
||||
{
|
||||
// FIXME: stub
|
||||
str sCommand;
|
||||
|
||||
if (m_bGermanModels) {
|
||||
sCommand += "ui_dm_playergermanmodel \"" + name;
|
||||
sCommand += "\" ; ui_dm_playergermanmodel_set " + partialName;
|
||||
sCommand += " ; ui_disp_playergermanmodel " + fullname + ".tik";
|
||||
} else {
|
||||
sCommand += "ui_dm_playermodel \"" + name;
|
||||
sCommand += "\" ; ui_dm_playermodel_set " + partialName;
|
||||
sCommand += " ; ui_disp_playermodel " + fullname + ".tik";
|
||||
}
|
||||
sCommand += "\n";
|
||||
|
||||
Cbuf_AddText(sCommand);
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::FileChosen( str& currentDirectory, str& partialName, str& fullname )
|
||||
void PlayerModelPickerClass::FileChosen(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
str name;
|
||||
char donotshowssindeorfr[64];
|
||||
str fullname;
|
||||
|
||||
name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
|
||||
fullname = PM_DisplaynameToFilename(name);
|
||||
|
||||
if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
|
||||
Q_strncpyz(donotshowssindeorfr, "german_waffen_", sizeof(donotshowssindeorfr));
|
||||
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
|
||||
} else {
|
||||
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));
|
||||
}
|
||||
|
||||
FileChosen(name, currentDirectory, fullname, currentDirectory + donotshowssindeorfr);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::OnDeactivated( Event *ev )
|
||||
void PlayerModelPickerClass::CloseWindow(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
PostEvent(EV_Remove, 0);
|
||||
}
|
||||
|
||||
void PlayerModelPickerClass::Setup( const char *root_directory, const char *current_directory, qboolean bGermanModels )
|
||||
void PlayerModelPickerClass::OnDeactivated(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
PMPickerItem::PMPickerItem(const str& string)
|
||||
{
|
||||
m_string = string;
|
||||
}
|
||||
|
||||
int PMPickerItem::getListItemValue(int which) const
|
||||
{
|
||||
return atoi(m_string);
|
||||
}
|
||||
|
||||
griditemtype_t PMPickerItem::getListItemType(int which) const
|
||||
{
|
||||
return griditemtype_t::TYPE_STRING;
|
||||
}
|
||||
|
||||
str PMPickerItem::getListItemString(int which) const
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
|
||||
void PMPickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
|
||||
|
||||
qboolean PMPickerItem::IsHeaderEntry() const
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,37 +20,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIPLAYERMODELPICKER_H__
|
||||
#define __CL_UIPLAYERMODELPICKER_H__
|
||||
#pragma once
|
||||
|
||||
class UIFloatingWindow;
|
||||
|
||||
class PlayerModelPickerClass : public USignal {
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
qboolean m_bGermanModels;
|
||||
class PlayerModelPickerClass : public USignal
|
||||
{
|
||||
UIFloatingWindow *window;
|
||||
UIListCtrl *listbox;
|
||||
str currentDirectory;
|
||||
str rootDirectory;
|
||||
qboolean m_bGermanModels;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( PlayerModelPickerClass );
|
||||
CLASS_PROTOTYPE(PlayerModelPickerClass);
|
||||
|
||||
private:
|
||||
void SetupFiles( void );
|
||||
void Initialize( const char *root_directory, const char *current_directory, qboolean bGermanModels );
|
||||
void SetupFiles(void);
|
||||
void Initialize(const char *root_directory, const char *current_directory, qboolean bGermanModels);
|
||||
|
||||
protected:
|
||||
void CloseWindow( void );
|
||||
void FileSelected( Event *ev );
|
||||
virtual void FileSelected( str& currentDirectory, str& partialName, str& fullname );
|
||||
void FileChosen( Event *ev );
|
||||
virtual void FileChosen( str& currentDirectory, str& partialName, str& fullname );
|
||||
void OnDeactivated( Event *ev );
|
||||
void CloseWindow(void);
|
||||
void FileSelected(Event *ev);
|
||||
// The name parameter was added in 2.0.
|
||||
virtual void FileSelected(const str& name, const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void FileChosen(Event *ev);
|
||||
// The name parameter was added in 2.0.
|
||||
virtual void FileChosen(const str& name, const str& currentDirectory, const str& partialName, const str& fullname);
|
||||
void OnDeactivated(Event *ev);
|
||||
|
||||
public:
|
||||
PlayerModelPickerClass();
|
||||
~PlayerModelPickerClass();
|
||||
PlayerModelPickerClass();
|
||||
~PlayerModelPickerClass();
|
||||
|
||||
void Setup( const char *root_directory, const char *current_directory, qboolean bGermanModels );
|
||||
void Setup(const char *root_directory, const char *current_directory, qboolean bGermanModels);
|
||||
};
|
||||
|
||||
#endif /* __CL_UIPLAYERMODELPICKER_H__ */
|
||||
const char* PM_FilenameToDisplayname(const char* fileName);
|
||||
const char* PM_DisplaynameToFilename(const char* displayName);
|
||||
@@ -20,7 +20,22 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// cl_uiradar.cpp: draw teammates
|
||||
// since 2.0
|
||||
|
||||
#include "cl_uiradar.h"
|
||||
#include "client.h"
|
||||
|
||||
radarClient_t* g_radarClients;
|
||||
qhandle_t* g_radarShaders;
|
||||
int g_radarClientNum;
|
||||
|
||||
void CL_InitRadar(radarClient_t* radars, qhandle_t* shaders, int clientNum)
|
||||
{
|
||||
g_radarClients = radars;
|
||||
g_radarShaders = shaders;
|
||||
g_radarClientNum = clientNum;
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( UIWidget, UIRadar, NULL )
|
||||
{
|
||||
@@ -30,5 +45,123 @@ CLASS_DECLARATION( UIWidget, UIRadar, NULL )
|
||||
UIRadar::UIRadar()
|
||||
{
|
||||
m_fRadius = 32.f;
|
||||
g_radarClients = NULL;
|
||||
}
|
||||
|
||||
UIRadar::~UIRadar()
|
||||
{
|
||||
}
|
||||
|
||||
void UIRadar::Draw(void)
|
||||
{
|
||||
radarClient_t* radar;
|
||||
float inv;
|
||||
float iconSize;
|
||||
int blinkTime, speakTime;
|
||||
float origin[2], axis[2];
|
||||
float halfScale;
|
||||
int i;
|
||||
|
||||
if (!g_radarClients) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cl.snap.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_radarClientNum < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
cge->CG_UpdateRadar();
|
||||
|
||||
radar = &g_radarClients[g_radarClientNum];
|
||||
if (!radar->time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (com_radar_range && com_radar_range->value > 0) {
|
||||
inv = 1.f / com_radar_range->value;
|
||||
} else {
|
||||
inv = 0;
|
||||
}
|
||||
|
||||
if (cl_radar_icon_size->value > 0) {
|
||||
iconSize = cl_radar_icon_size->value;
|
||||
} else {
|
||||
iconSize = 0;
|
||||
}
|
||||
|
||||
axis[0] = radar->axis[0];
|
||||
axis[1] = radar->axis[1];
|
||||
origin[0] = radar->origin[0];
|
||||
origin[1] = radar->origin[1];
|
||||
blinkTime = cl_radar_blink_time->value * 1000;
|
||||
speakTime = cl_radar_speak_time->value * 1000;
|
||||
|
||||
if (blinkTime < 100) blinkTime = 100;
|
||||
|
||||
halfScale = iconSize * 0.5f;
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
float delta[2];
|
||||
float newOrg[2];
|
||||
float screenOrg[2];
|
||||
float length;
|
||||
|
||||
radar = &g_radarClients[i];
|
||||
if (i == g_radarClientNum) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!g_radarClients[i].time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cl.snap.serverTime - radar->time >= 5000) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (radar->lastSpeakTime) {
|
||||
int delta = cl.snap.serverTime - radar->lastSpeakTime;
|
||||
// make the icon blink
|
||||
if (delta >= 0 && delta < speakTime && ((delta / blinkTime) % 2) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
newOrg[1] = (delta[0] * axis[1] + delta[1] * -axis[0]) * inv;
|
||||
length = VectorLength2D(newOrg);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
uii.Rend_DrawPicStretched2(
|
||||
screenOrg[0],
|
||||
screenOrg[1],
|
||||
m_vVirtualScale[0] * iconSize,
|
||||
m_vVirtualScale[1] * iconSize,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
radar->axis[0] * axis[0] - (-radar->axis[1] * axis[1]),
|
||||
radar->axis[0] * axis[1] + (-radar->axis[1] * axis[0]),
|
||||
g_radarShaders[radar->teamShader]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "../uilib/uiwidget.h"
|
||||
#include "../cgame/cg_public.h"
|
||||
|
||||
class UIRadar : public UIWidget {
|
||||
public:
|
||||
@@ -28,7 +29,12 @@ public:
|
||||
|
||||
public:
|
||||
UIRadar();
|
||||
~UIRadar();
|
||||
|
||||
void Draw(void) override;
|
||||
|
||||
private:
|
||||
float m_fRadius;
|
||||
};
|
||||
|
||||
void CL_InitRadar(radarClient_t* radars, qhandle_t* shaders, int clientNum);
|
||||
+1144
-16
File diff suppressed because it is too large.
Load diff
@@ -20,20 +20,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UISERVERLIST_H__
|
||||
#define __CL_UISERVERLIST_H__
|
||||
#pragma once
|
||||
|
||||
class UIFAKKServerList : public UIListCtrl {
|
||||
protected:
|
||||
// need a new struct instead of gamespy
|
||||
void *m_serverList;
|
||||
struct GServerListImplementation *m_serverList[2];
|
||||
bool m_bHasList;
|
||||
bool m_bLANListing;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIFAKKServerList );
|
||||
|
||||
bool m_bGettingList;
|
||||
bool m_bGettingList[2];
|
||||
bool m_bUpdatingList;
|
||||
|
||||
protected:
|
||||
@@ -54,5 +53,3 @@ public:
|
||||
void Draw( void ) override;
|
||||
void SortByColumn( int column ) override;
|
||||
};
|
||||
|
||||
#endif /* __CL_UISERVERLIST_H__ */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -22,22 +22,42 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( FilePickerClass, SoundPickerClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(FilePickerClass, SoundPickerClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
SoundPickerClass::SoundPickerClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
str soundpath;
|
||||
str currentpath;
|
||||
const char *varValue;
|
||||
int i;
|
||||
|
||||
soundpath = "sound";
|
||||
|
||||
varValue = UI_GetCvarString("ui_pickedsound", NULL);
|
||||
if (varValue && *varValue) {
|
||||
currentpath = varValue;
|
||||
|
||||
for (i = currentpath.length(); i > 0; i--) {
|
||||
if (currentpath[i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentpath = str(currentpath, 0, i + 1);
|
||||
} else {
|
||||
currentpath = soundpath;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundPickerClass::FileSelected( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void SoundPickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
|
||||
uii.Snd_PlaySound(fullname);
|
||||
}
|
||||
|
||||
void SoundPickerClass::FileChosen( str ¤tDirectory, str &partialName, str &fullname )
|
||||
void SoundPickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
|
||||
{
|
||||
|
||||
uii.Cvar_Set("ui_pickedsound", fullname);
|
||||
CloseWindow();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -20,17 +20,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UISOUNDPICKER_H__
|
||||
#define __CL_UISOUNDPICKER_H__
|
||||
#pragma once
|
||||
|
||||
class SoundPickerClass : public FilePickerClass {
|
||||
class SoundPickerClass : public FilePickerClass
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( SoundPickerClass );
|
||||
CLASS_PROTOTYPE(SoundPickerClass);
|
||||
|
||||
SoundPickerClass();
|
||||
SoundPickerClass();
|
||||
|
||||
void FileSelected( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileChosen( str ¤tDirectory, str &partialName, str &fullname ) override;
|
||||
void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
|
||||
};
|
||||
|
||||
#endif /* __CL_UISOUNDPICKER_H__ */
|
||||
+1210
-1162
File diff suppressed because it is too large.
Load diff
+73
-70
@@ -20,85 +20,88 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UISTD_H__
|
||||
#define __CL_UISTD_H__
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
L_STATBAR_NONE,
|
||||
L_STATBAR_HORIZONTAL,
|
||||
L_STATBAR_VERTICAL,
|
||||
L_STATBAR_VERTICAL_REVERSE,
|
||||
L_STATBAR_VERTICAL_STAGGER_EVEN,
|
||||
L_STATBAR_VERTICAL_STAGGER_ODD,
|
||||
L_STATBAR_CIRCULAR,
|
||||
L_STATBAR_NEEDLE,
|
||||
L_STATBAR_ROTATOR,
|
||||
L_STATBAR_COMPASS,
|
||||
L_STATBAR_SPINNER,
|
||||
L_STATBAR_HEADING_SPINNER
|
||||
L_STATBAR_NONE,
|
||||
L_STATBAR_HORIZONTAL,
|
||||
L_STATBAR_VERTICAL,
|
||||
L_STATBAR_VERTICAL_REVERSE,
|
||||
L_STATBAR_VERTICAL_STAGGER_EVEN,
|
||||
L_STATBAR_VERTICAL_STAGGER_ODD,
|
||||
L_STATBAR_CIRCULAR,
|
||||
L_STATBAR_NEEDLE,
|
||||
L_STATBAR_ROTATOR,
|
||||
L_STATBAR_COMPASS,
|
||||
L_STATBAR_SPINNER,
|
||||
L_STATBAR_HEADING_SPINNER
|
||||
} statbar_orientation_t;
|
||||
|
||||
class UIFakkLabel : public UILabel {
|
||||
extern Event EV_ClearInvItemReference;
|
||||
|
||||
class UIFakkLabel : public UILabel
|
||||
{
|
||||
protected:
|
||||
SafePtr<inventory_item_t> m_lastitem;
|
||||
int m_lastitemindex;
|
||||
int m_stat;
|
||||
int m_stat_configstring;
|
||||
int m_maxstat;
|
||||
int m_itemindex;
|
||||
int m_inventoryrendermodelindex;
|
||||
str m_sDrawModelName;
|
||||
qboolean m_rendermodel;
|
||||
statbar_orientation_t m_statbar_or;
|
||||
float m_statbar_min;
|
||||
float m_statbar_max;
|
||||
float m_lastfrac;
|
||||
float m_flashtime;
|
||||
vec3_t m_offset;
|
||||
vec3_t m_rotateoffset;
|
||||
vec3_t m_angles;
|
||||
float m_scale;
|
||||
str m_anim;
|
||||
UIReggedMaterial *m_statbar_material;
|
||||
UIReggedMaterial *m_statbar_material_flash;
|
||||
SafePtr<inventory_item_t> m_lastitem;
|
||||
int m_lastitemindex;
|
||||
int m_stat;
|
||||
int m_stat_alpha;
|
||||
int m_stat_configstring;
|
||||
int m_maxstat;
|
||||
int m_itemindex;
|
||||
int m_inventoryrendermodelindex;
|
||||
str m_sDrawModelName;
|
||||
qboolean m_rendermodel;
|
||||
statbar_orientation_t m_statbar_or;
|
||||
float m_statbar_min;
|
||||
float m_statbar_max;
|
||||
float m_lastfrac;
|
||||
float m_flashtime;
|
||||
vec3_t m_offset;
|
||||
vec3_t m_rotateoffset;
|
||||
vec3_t m_angles;
|
||||
float m_scale;
|
||||
str m_anim;
|
||||
UIReggedMaterial *m_statbar_material;
|
||||
UIReggedMaterial *m_statbar_material_flash;
|
||||
UIReggedMaterial *m_statbar_material_marker;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIFakkLabel );
|
||||
CLASS_PROTOTYPE(UIFakkLabel);
|
||||
|
||||
UIFakkLabel();
|
||||
UIFakkLabel();
|
||||
|
||||
void LayoutPlayerStat( Event *ev );
|
||||
void LayoutPlayerStatConfigstring( Event *ev );
|
||||
void LayoutMaxPlayerStat( Event *ev );
|
||||
void LayoutItemIndex( Event *ev );
|
||||
void InventoryRenderModelIndex( Event *ev );
|
||||
void LayoutModelName( Event *ev );
|
||||
void ClearInvItemReference( Event *ev );
|
||||
void LayoutStatbar( Event *ev );
|
||||
void LayoutStatbarShader( Event *ev );
|
||||
void LayoutStatbarTileShader( Event *ev );
|
||||
void LayoutStatbarShader_Flash( Event *ev );
|
||||
void LayoutStatbarEndAngles( Event *ev );
|
||||
void LayoutStatbarNeedleWidth( Event *ev );
|
||||
void LayoutStatbarRotatorSize( Event *ev );
|
||||
void LayoutStatbarTileShader_Flash( Event *ev );
|
||||
void LayoutRenderModel( Event *ev );
|
||||
void LayoutRenderModelOffset( Event *ev );
|
||||
void LayoutRenderModelRotateOffset( Event *ev );
|
||||
void LayoutRenderModelAngles( Event *ev );
|
||||
void LayoutRenderModelScale( Event *ev );
|
||||
void LayoutRenderModelAnim( Event *ev );
|
||||
void LayoutPlayerStat(Event *ev);
|
||||
void LayoutPlayerStatAlpha(Event *ev); // Added in 2.0
|
||||
void LayoutPlayerStatConfigstring(Event *ev);
|
||||
void LayoutMaxPlayerStat(Event *ev);
|
||||
void LayoutItemIndex(Event *ev);
|
||||
void InventoryRenderModelIndex(Event *ev);
|
||||
void LayoutModelName(Event *ev);
|
||||
void ClearInvItemReference(Event *ev);
|
||||
void LayoutStatbar(Event *ev);
|
||||
void LayoutStatbarShader(Event *ev);
|
||||
void LayoutStatbarTileShader(Event *ev);
|
||||
void LayoutStatbarShader_Flash(Event *ev);
|
||||
void LayoutStatbarShader_Marker(Event *ev); // Added in 2.0
|
||||
void LayoutStatbarEndAngles(Event *ev);
|
||||
void LayoutStatbarNeedleWidth(Event *ev);
|
||||
void LayoutStatbarRotatorSize(Event *ev);
|
||||
void LayoutStatbarTileShader_Flash(Event *ev);
|
||||
void LayoutRenderModel(Event *ev);
|
||||
void LayoutRenderModelOffset(Event *ev);
|
||||
void LayoutRenderModelRotateOffset(Event *ev);
|
||||
void LayoutRenderModelAngles(Event *ev);
|
||||
void LayoutRenderModelScale(Event *ev);
|
||||
void LayoutRenderModelAnim(Event *ev);
|
||||
|
||||
void DrawStatbar( float frac );
|
||||
void DrawStatCircle( float frac );
|
||||
void DrawStatNeedle( float frac );
|
||||
void DrawStatRotator( float frac );
|
||||
void DrawStatCompass( float frac );
|
||||
void DrawStatSpinner( float frac );
|
||||
void StatCircleTexCoord( float fAng, vec3_t vTexCoord );
|
||||
void DrawStatbar(float frac);
|
||||
void DrawStatCircle(float frac);
|
||||
void DrawStatNeedle(float frac);
|
||||
void DrawStatRotator(float frac);
|
||||
void DrawStatCompass(float frac);
|
||||
void DrawStatSpinner(float frac);
|
||||
void StatCircleTexCoord(float fAng, vec3_t vTexCoord);
|
||||
|
||||
void Draw( void ) override;
|
||||
void Draw(void) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+510
-290
@@ -21,355 +21,575 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cl_ui.h"
|
||||
#include "../qcommon/localization.h"
|
||||
|
||||
CLASS_DECLARATION( UIWidget, View3D, NULL )
|
||||
{
|
||||
{ &W_Activated, &View3D::OnActivate },
|
||||
{ &W_Deactivated, &View3D::OnDeactivate },
|
||||
{ &W_LeftMouseDown, &View3D::Pressed },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UIWidget, View3D, NULL) {
|
||||
{&W_Activated, &View3D::OnActivate },
|
||||
{&W_Deactivated, &View3D::OnDeactivate},
|
||||
{&W_LeftMouseDown, &View3D::Pressed },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
#define MAX_SUBTITLES 4
|
||||
|
||||
cvar_t *subs[MAX_SUBTITLES];
|
||||
cvar_t *teams[MAX_SUBTITLES];
|
||||
float fadeTime[MAX_SUBTITLES];
|
||||
float subLife[MAX_SUBTITLES];
|
||||
float alpha[MAX_SUBTITLES];
|
||||
char oldStrings[MAX_SUBTITLES][2048];
|
||||
|
||||
View3D::View3D()
|
||||
{
|
||||
// set as transparent
|
||||
setBackgroundColor(UClear, true);
|
||||
// no border
|
||||
setBorderStyle(border_none);
|
||||
AllowActivate(true);
|
||||
// set as transparent
|
||||
setBackgroundColor(UClear, true);
|
||||
// no border
|
||||
setBorderStyle(border_none);
|
||||
AllowActivate(true);
|
||||
|
||||
m_printfadetime = 0.0;
|
||||
m_print_mat = NULL;
|
||||
m_locationprint = qfalse;
|
||||
m_printfadetime = 0.0;
|
||||
m_print_mat = NULL;
|
||||
m_locationprint = qfalse;
|
||||
}
|
||||
|
||||
void View3D::Draw
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::UpdateLocationPrint(int x, int y, const char *s, float alpha)
|
||||
{
|
||||
if (clc.state != CA_DISCONNECTED) {
|
||||
SCR_DrawScreenField();
|
||||
}
|
||||
|
||||
set2D();
|
||||
|
||||
re.SavePerformanceCounters();
|
||||
|
||||
Draw2D();
|
||||
m_printstring = s;
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_x_coord = x;
|
||||
m_y_coord = y;
|
||||
m_locationprint = qtrue;
|
||||
}
|
||||
|
||||
void View3D::DrawLetterbox
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::UpdateCenterPrint(const char *s, float alpha)
|
||||
{
|
||||
// FIXME: stub
|
||||
m_printstring = s;
|
||||
|
||||
if (s[0] == '@') {
|
||||
m_print_mat = uWinMan.RegisterShader(s + 1);
|
||||
} else {
|
||||
m_print_mat = NULL;
|
||||
}
|
||||
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_locationprint = qfalse;
|
||||
}
|
||||
|
||||
void View3D::DrawFades
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::PrintSound(int channel, const char *name, float vol, int rvol, float pitch, float base, int& line)
|
||||
{
|
||||
// FIXME: stub
|
||||
char buf[255];
|
||||
float x;
|
||||
float xStep;
|
||||
float height;
|
||||
|
||||
height = m_font->getHeight(false);
|
||||
xStep = height;
|
||||
|
||||
x = 0;
|
||||
sprintf(buf, "%d", channel);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep + xStep;
|
||||
sprintf(buf, "%s", name);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep * 30.0;
|
||||
sprintf(buf, "vol:%.2f", vol);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep * 8;
|
||||
sprintf(buf, "rvol:%.2f", (float)(rvol / 128.f));
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep * 5;
|
||||
sprintf(buf, "pit:%.2f", pitch);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
x += xStep * 5;
|
||||
sprintf(buf, "base:%d", (int)base);
|
||||
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
|
||||
|
||||
line++;
|
||||
}
|
||||
|
||||
void View3D::Draw2D
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::Pressed(Event *ev)
|
||||
{
|
||||
if (!cls.no_menus) {
|
||||
DrawFades();
|
||||
}
|
||||
|
||||
DrawLetterbox();
|
||||
|
||||
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus)
|
||||
{
|
||||
SCR_DrawDebugGraph();
|
||||
}
|
||||
else if (!cls.no_menus)
|
||||
{
|
||||
if (cge) {
|
||||
cge->CG_Draw2D();
|
||||
}
|
||||
|
||||
if (m_locationprint) {
|
||||
LocationPrint();
|
||||
} else {
|
||||
CenterPrint();
|
||||
}
|
||||
|
||||
if (!cls.no_menus)
|
||||
{
|
||||
DrawSoundOverlay();
|
||||
DrawSubtitleOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
if (fps->integer && !cls.no_menus)
|
||||
{
|
||||
DrawFPS();
|
||||
DrawProf();
|
||||
}
|
||||
IN_MouseOff();
|
||||
OnActivate(ev);
|
||||
}
|
||||
|
||||
void View3D::DrawFPS
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::OnDeactivate(Event *ev)
|
||||
{
|
||||
char string[128];
|
||||
|
||||
setFont("verdana-14");
|
||||
if (fps->integer == 2)
|
||||
{
|
||||
re.SetColor(UBlack);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
|
||||
m_frame.pos.x + m_frame.size.width,
|
||||
m_font->getHeight(qfalse) * 4.0
|
||||
);
|
||||
}
|
||||
|
||||
sprintf(string, "FPS %4.1f", currentfps);
|
||||
if (currentfps > 23.94) {
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
} else if (currentfps > 18.0) {
|
||||
m_font->setColor(UYellow);
|
||||
} else {
|
||||
// low fps
|
||||
m_font->setColor(URed);
|
||||
}
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
// Draw elements count
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
}
|
||||
else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
|
||||
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
|
||||
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
cls.keyCatchers |= KEYCATCH_UI;
|
||||
}
|
||||
|
||||
void View3D::DrawProf
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::OnActivate(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void View3D::PrintSound
|
||||
(
|
||||
int channel,
|
||||
const char *name,
|
||||
float vol,
|
||||
int rvol,
|
||||
float pitch,
|
||||
float base,
|
||||
int& line
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void View3D::DrawSoundOverlay
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void View3D::CenterPrint
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void View3D::LocationPrint
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void View3D::OnActivate
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
{
|
||||
UIWidget* wid;
|
||||
UList<UIWidget*> widgets;
|
||||
UIWidget *wid;
|
||||
UList<UIWidget *> widgets;
|
||||
|
||||
UI_CloseInventory();
|
||||
cls.keyCatchers &= ~KEYCATCH_UI;
|
||||
|
||||
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid))
|
||||
{
|
||||
if (wid->getAlwaysOnBottom() && wid != this) {
|
||||
widgets.AddTail(wid);
|
||||
}
|
||||
}
|
||||
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid)) {
|
||||
if (wid->getAlwaysOnBottom() && wid != this) {
|
||||
widgets.AddTail(wid);
|
||||
}
|
||||
}
|
||||
|
||||
widgets.IterateFromHead();
|
||||
while (widgets.IsCurrentValid())
|
||||
{
|
||||
widgets.getCurrent()->BringToFrontPropogated();
|
||||
widgets.IterateNext();
|
||||
}
|
||||
widgets.IterateFromHead();
|
||||
while (widgets.IsCurrentValid()) {
|
||||
widgets.getCurrent()->BringToFrontPropogated();
|
||||
widgets.IterateNext();
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::OnDeactivate
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void View3D::LocationPrint(void)
|
||||
{
|
||||
cls.keyCatchers |= KEYCATCH_UI;
|
||||
fonthorzjustify_t horiz;
|
||||
fontvertjustify_t vert;
|
||||
int x, y;
|
||||
const char *p;
|
||||
float alpha;
|
||||
UIRect2D frame;
|
||||
|
||||
if (!m_printfadetime) {
|
||||
m_locationprint = false;
|
||||
return;
|
||||
}
|
||||
|
||||
horiz = FONT_JUSTHORZ_LEFT;
|
||||
vert = FONT_JUSTVERT_TOP;
|
||||
|
||||
p = Sys_LV_CL_ConvertString(m_printstring);
|
||||
if (m_printfadetime > 3250) {
|
||||
alpha = 1.f - (m_printfadetime - 3250.f) / 750.f * m_printalpha;
|
||||
} else if (m_printfadetime >= 750) {
|
||||
alpha = 1.f;
|
||||
} else {
|
||||
alpha = m_printfadetime / 750.f * m_printalpha;
|
||||
}
|
||||
|
||||
alpha = Q_clamp_float(alpha, 0, 1);
|
||||
|
||||
x = m_x_coord / 640.f * m_screenframe.size.width;
|
||||
y = (480 - m_font->getHeight(false) - m_y_coord) / 480.f * m_screenframe.size.height;
|
||||
|
||||
if (m_x_coord == -1) {
|
||||
horiz = FONT_JUSTHORZ_CENTER;
|
||||
x = 0;
|
||||
}
|
||||
if (m_y_coord == -1) {
|
||||
vert = FONT_JUSTVERT_CENTER;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
m_font->setColor(UColor(0, 0, 0, alpha));
|
||||
frame = getClientFrame();
|
||||
|
||||
m_font->PrintJustified(
|
||||
UIRect2D(frame.pos.x + x + 1, frame.pos.y + y + 1, frame.size.width, frame.size.height),
|
||||
horiz,
|
||||
vert,
|
||||
p,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha));
|
||||
frame = getClientFrame();
|
||||
|
||||
m_font->PrintJustified(
|
||||
UIRect2D(frame.pos.x + x, frame.pos.y + y, frame.size.width, frame.size.height),
|
||||
horiz,
|
||||
vert,
|
||||
p,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
m_printfadetime -= cls.frametime;
|
||||
|
||||
if (m_printfadetime < 0) {
|
||||
m_printfadetime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::DrawSubtitleOverlay
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
qboolean View3D::LetterboxActive(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
return m_letterbox_active;
|
||||
}
|
||||
|
||||
void View3D::ClearCenterPrint
|
||||
(
|
||||
void
|
||||
)
|
||||
float avWidth = 0.0;
|
||||
|
||||
void View3D::InitSubtitle(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
float totalWidth;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
|
||||
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
|
||||
strcpy(oldStrings[i], subs[i]->string);
|
||||
fadeTime[i] = 4000.0;
|
||||
subLife[i] = 4000.0;
|
||||
}
|
||||
|
||||
totalWidth = 0.0;
|
||||
for (char j = 'A'; j <= 'Z'; j++) {
|
||||
totalWidth += m_font->getCharWidth(j);
|
||||
}
|
||||
|
||||
avWidth = totalWidth / 26.0;
|
||||
}
|
||||
|
||||
void View3D::UpdateCenterPrint
|
||||
(
|
||||
const char *s,
|
||||
float alpha
|
||||
)
|
||||
|
||||
void View3D::FrameInitialized(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
Connect(this, W_Activated, W_Activated);
|
||||
Connect(this, W_Deactivated, W_Deactivated);
|
||||
}
|
||||
|
||||
void View3D::UpdateLocationPrint
|
||||
(
|
||||
int x,
|
||||
int y,
|
||||
const char *s,
|
||||
float alpha
|
||||
)
|
||||
|
||||
void View3D::DrawSubtitleOverlay(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
cvar_t *subAlpha;
|
||||
int i;
|
||||
float minX, maxY;
|
||||
int line;
|
||||
|
||||
subAlpha = Cvar_Get("subAlpha", "0.5", 0);
|
||||
|
||||
setFont("facfont-20");
|
||||
m_font->setColor(URed);
|
||||
|
||||
for (i = 0; i < MAX_SUBTITLES; i++) {
|
||||
if (strcmp(oldStrings[i], subs[i]->string)) {
|
||||
fadeTime[i] = 2500 * ((strlen(subs[i]->string) / 68) + 1.f) + 1500;
|
||||
subLife[i] = fadeTime[i];
|
||||
Q_strncpyz(oldStrings[i], subs[i]->string, sizeof(oldStrings[i]));
|
||||
}
|
||||
|
||||
if (fadeTime[i] > subLife[i] - 750.f) {
|
||||
alpha[i] = 1.f - (fadeTime[i] - (subLife[i] - 750.f)) / 750.f;
|
||||
} else if (fadeTime[i] < 750) {
|
||||
alpha[i] = fadeTime[i] / 750.f;
|
||||
} else {
|
||||
alpha[i] = 1.f;
|
||||
}
|
||||
|
||||
fadeTime[i] -= cls.frametime;
|
||||
if (fadeTime[i] < 0) {
|
||||
// Clear the subtitle
|
||||
fadeTime[i] = 0;
|
||||
oldStrings[i][0] = 0;
|
||||
Cvar_Set(va("subtitle%d", i), "");
|
||||
}
|
||||
}
|
||||
|
||||
minX = m_screenframe.size.height - m_font->getHeight(false) * 10;
|
||||
maxY = (m_frame.pos.x + m_frame.size.width) - (m_frame.pos.x + m_frame.size.width) * 0.2f;
|
||||
line = 0;
|
||||
|
||||
for (i = 0; i < MAX_SUBTITLES; i++) {
|
||||
if (m_font->getWidth(subs[i]->string, sizeof(oldStrings[i])) > maxY) {
|
||||
char buf[2048];
|
||||
char *c;
|
||||
char *end;
|
||||
char *start;
|
||||
float total;
|
||||
int blockcount;
|
||||
|
||||
c = buf;
|
||||
strcpy(buf, subs[i]->string);
|
||||
|
||||
total = 0;
|
||||
end = NULL;
|
||||
start = buf;
|
||||
while (*c) {
|
||||
blockcount = m_font->DBCSGetWordBlockCount(c, -1);
|
||||
if (!blockcount) {
|
||||
break;
|
||||
}
|
||||
|
||||
total += m_font->getWidth(c, blockcount);
|
||||
c += blockcount;
|
||||
|
||||
if (total > maxY) {
|
||||
total = 0;
|
||||
if (end < start) {
|
||||
Com_Printf("ERROR - word longer than possible line\n");
|
||||
break;
|
||||
}
|
||||
|
||||
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
|
||||
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, start, -1, false);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
|
||||
m_font->Print(20, m_font->getHeight(false) * line + minX, start, -1, false);
|
||||
|
||||
start = end + 1;
|
||||
c = end + 1;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
|
||||
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, start, -1, qfalse);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
|
||||
m_font->Print(20, m_font->getHeight(false) * line + minX, start, -1, qfalse);
|
||||
line++;
|
||||
} else {
|
||||
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
|
||||
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, subs[i]->string, -1, qfalse);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
|
||||
m_font->Print(20, m_font->getHeight(false) * line + minX, subs[i]->string, -1, qfalse);
|
||||
|
||||
line++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qboolean View3D::LetterboxActive
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::DrawSoundOverlay(void)
|
||||
{
|
||||
return m_letterbox_active;
|
||||
setFont("verdana-14");
|
||||
m_font->setColor(UWhite);
|
||||
|
||||
// FIXME: TODO
|
||||
if (sound_overlay->integer) {
|
||||
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
|
||||
Cvar_Set("sound_overlay", "0");
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::InitSubtitle
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::DrawProf(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// Normal empty function
|
||||
}
|
||||
|
||||
void View3D::FrameInitialized
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::DrawLetterbox(void)
|
||||
{
|
||||
Connect(this, W_Activated, W_Activated);
|
||||
Connect(this, W_Deactivated, W_Deactivated);
|
||||
float frac;
|
||||
vec4_t col;
|
||||
|
||||
col[0] = col[1] = col[2] = 0;
|
||||
col[3] = 1;
|
||||
|
||||
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
|
||||
if (frac > 0.0) {
|
||||
m_letterbox_active = true;
|
||||
re.SetColor(col);
|
||||
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_screenframe.size.height - m_screenframe.size.height * frac,
|
||||
m_screenframe.size.width,
|
||||
m_screenframe.size.height
|
||||
);
|
||||
} else {
|
||||
m_letterbox_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::Pressed
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void View3D::DrawFades(void)
|
||||
{
|
||||
IN_MouseOff();
|
||||
OnActivate(ev);
|
||||
if (cl.snap.ps.blend[3] > 0) {
|
||||
re.SetColor(cl.snap.ps.blend);
|
||||
if (cl.snap.ps.stats[STAT_ADDFADE]) {
|
||||
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
} else {
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( UIWidget, ConsoleView, NULL )
|
||||
void View3D::DrawFPS(void)
|
||||
{
|
||||
{ NULL, NULL }
|
||||
char string[128];
|
||||
|
||||
setFont("verdana-14");
|
||||
if (fps->integer == 2) {
|
||||
re.SetColor(UBlack);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
|
||||
m_frame.pos.x + m_frame.size.width,
|
||||
m_font->getHeight(qfalse) * 4.0
|
||||
);
|
||||
}
|
||||
|
||||
sprintf(string, "FPS %4.1f", currentfps);
|
||||
if (currentfps > 23.94) {
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
} else if (currentfps > 18.0) {
|
||||
m_font->setColor(UYellow);
|
||||
} else {
|
||||
// low fps
|
||||
m_font->setColor(URed);
|
||||
}
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
// Draw elements count
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
|
||||
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
}
|
||||
|
||||
void View3D::Draw2D(void)
|
||||
{
|
||||
if (!cls.no_menus) {
|
||||
DrawFades();
|
||||
}
|
||||
|
||||
DrawLetterbox();
|
||||
|
||||
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus) {
|
||||
SCR_DrawDebugGraph();
|
||||
} else if (!cls.no_menus) {
|
||||
if (cge) {
|
||||
cge->CG_Draw2D();
|
||||
}
|
||||
|
||||
if (m_locationprint) {
|
||||
LocationPrint();
|
||||
} else {
|
||||
CenterPrint();
|
||||
}
|
||||
|
||||
if (!cls.no_menus) {
|
||||
DrawSoundOverlay();
|
||||
DrawSubtitleOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
if (fps->integer && !cls.no_menus) {
|
||||
DrawFPS();
|
||||
DrawProf();
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::Draw(void)
|
||||
{
|
||||
if (clc.state != CA_DISCONNECTED) {
|
||||
SCR_DrawScreenField();
|
||||
}
|
||||
|
||||
set2D();
|
||||
|
||||
re.SavePerformanceCounters();
|
||||
|
||||
Draw2D();
|
||||
}
|
||||
|
||||
void View3D::ClearCenterPrint(void)
|
||||
{
|
||||
m_printfadetime = 0.0;
|
||||
}
|
||||
|
||||
void View3D::CenterPrint(void)
|
||||
{
|
||||
float alpha;
|
||||
const char *p;
|
||||
qhandle_t mat;
|
||||
float x, y;
|
||||
float w, h;
|
||||
|
||||
if (!m_printfadetime) {
|
||||
return;
|
||||
}
|
||||
|
||||
p = Sys_LV_CL_ConvertString(m_printstring);
|
||||
if (m_printfadetime > 3250) {
|
||||
alpha = 1.f - (m_printfadetime - 3250.f) / 750.f * m_printalpha;
|
||||
} else if (m_printfadetime >= 750) {
|
||||
alpha = 1.f;
|
||||
} else {
|
||||
alpha = m_printfadetime / 750.f * m_printalpha;
|
||||
}
|
||||
|
||||
alpha = Q_clamp_float(alpha, 0, 1);
|
||||
|
||||
if (!m_print_mat) {
|
||||
UIRect2D frame;
|
||||
m_font->setColor(UColor(0, 0, 0, alpha));
|
||||
|
||||
frame = getClientFrame();
|
||||
|
||||
m_font->PrintJustified(
|
||||
UIRect2D(frame.pos.x + 1, frame.pos.y + 1, frame.size.width, frame.size.height),
|
||||
m_iFontAlignmentHorizontal,
|
||||
m_iFontAlignmentVertical,
|
||||
p,
|
||||
m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
|
||||
m_font->setColor(UColor(1, 1, 1, alpha));
|
||||
|
||||
frame = getClientFrame();
|
||||
|
||||
m_font->PrintJustified(
|
||||
frame, m_iFontAlignmentHorizontal, m_iFontAlignmentVertical, p, m_bVirtual ? m_vVirtualScale : NULL
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
} else if ((mat = m_print_mat->GetMaterial())) {
|
||||
vec4_t col {alpha, alpha, alpha, alpha};
|
||||
|
||||
re.SetColor(col);
|
||||
|
||||
w = re.GetShaderWidth(mat);
|
||||
h = re.GetShaderHeight(mat);
|
||||
x = (m_frame.pos.x + m_frame.size.width - w) * 0.5f;
|
||||
y = (m_frame.pos.y + m_frame.size.height - h) * 0.5f;
|
||||
|
||||
re.DrawStretchPic(x, y, w, h, 0, 0, 1, 1, mat);
|
||||
}
|
||||
|
||||
m_printfadetime -= cls.frametime;
|
||||
|
||||
if (m_printfadetime < 0) {
|
||||
m_printfadetime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_DECLARATION(UIWidget, ConsoleView, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void ConsoleView::Draw
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void ConsoleView::Draw(void) {}
|
||||
+37
-38
@@ -20,55 +20,54 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UIVIEW3D__
|
||||
#define __CL_UIVIEW3D__
|
||||
#pragma once
|
||||
|
||||
class View3D : public UIWidget {
|
||||
float m_printfadetime;
|
||||
float m_printalpha;
|
||||
str m_printstring;
|
||||
UIReggedMaterial *m_print_mat;
|
||||
qboolean m_locationprint;
|
||||
int m_x_coord;
|
||||
int m_y_coord;
|
||||
qboolean m_letterbox_active;
|
||||
class View3D : public UIWidget
|
||||
{
|
||||
float m_printfadetime;
|
||||
float m_printalpha;
|
||||
str m_printstring;
|
||||
UIReggedMaterial *m_print_mat;
|
||||
qboolean m_locationprint;
|
||||
int m_x_coord;
|
||||
int m_y_coord;
|
||||
qboolean m_letterbox_active;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( View3D );
|
||||
CLASS_PROTOTYPE(View3D);
|
||||
|
||||
protected:
|
||||
void Draw( void ) override;
|
||||
void DrawLetterbox( void );
|
||||
void DrawFades( void );
|
||||
void Draw2D( void );
|
||||
void DrawFPS( void );
|
||||
void DrawProf( void );
|
||||
void PrintSound( int channel, const char *name, float vol, int rvol, float pitch, float base, int& line );
|
||||
void DrawSoundOverlay( void );
|
||||
void CenterPrint( void );
|
||||
void LocationPrint( void );
|
||||
void OnActivate( Event *ev );
|
||||
void OnDeactivate( Event *ev );
|
||||
void DrawSubtitleOverlay( void );
|
||||
void Draw(void) override;
|
||||
void DrawLetterbox(void);
|
||||
void DrawFades(void);
|
||||
void Draw2D(void);
|
||||
void DrawFPS(void);
|
||||
void DrawProf(void);
|
||||
void PrintSound(int channel, const char *name, float vol, int rvol, float pitch, float base, int& line);
|
||||
void DrawSoundOverlay(void);
|
||||
void CenterPrint(void);
|
||||
void LocationPrint(void);
|
||||
void OnActivate(Event *ev);
|
||||
void OnDeactivate(Event *ev);
|
||||
void DrawSubtitleOverlay(void);
|
||||
|
||||
public:
|
||||
View3D();
|
||||
View3D();
|
||||
|
||||
void ClearCenterPrint( void );
|
||||
void UpdateCenterPrint( const char *s, float alpha );
|
||||
void UpdateLocationPrint( int x, int y, const char *s, float alpha );
|
||||
qboolean LetterboxActive( void );
|
||||
void InitSubtitle( void );
|
||||
void FrameInitialized( void ) override;
|
||||
virtual void Pressed( Event *ev );
|
||||
void ClearCenterPrint(void);
|
||||
void UpdateCenterPrint(const char *s, float alpha);
|
||||
void UpdateLocationPrint(int x, int y, const char *s, float alpha);
|
||||
qboolean LetterboxActive(void);
|
||||
void InitSubtitle(void);
|
||||
void FrameInitialized(void) override;
|
||||
virtual void Pressed(Event *ev);
|
||||
};
|
||||
|
||||
class ConsoleView : public UIWidget {
|
||||
class ConsoleView : public UIWidget
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( ConsoleView );
|
||||
CLASS_PROTOTYPE(ConsoleView);
|
||||
|
||||
protected:
|
||||
void Draw( void ) override;
|
||||
void Draw(void) override;
|
||||
};
|
||||
|
||||
#endif /* __CL_UIVIEW3D__ */
|
||||
@@ -21,8 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// client.h -- primary header for client
|
||||
|
||||
#ifndef __CLIENT_H__
|
||||
#define __CLIENT_H__
|
||||
#pragma once
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
@@ -321,7 +320,7 @@ typedef struct {
|
||||
serverInfo_t globalServers[MAX_GLOBAL_SERVERS];
|
||||
// additional global servers
|
||||
int numGlobalServerAddresses;
|
||||
serverAddress_t globalServerAddresses[MAX_GLOBAL_SERVERS];
|
||||
netadr_t globalServerAddresses[MAX_GLOBAL_SERVERS];
|
||||
|
||||
int numfavoriteservers;
|
||||
serverInfo_t favoriteServers[MAX_OTHER_SERVERS];
|
||||
@@ -352,7 +351,7 @@ typedef struct {
|
||||
clientAnim_t anim;
|
||||
stopWatch_t stopwatch;
|
||||
void* savedCgameState;
|
||||
int savedCgameStateSize;
|
||||
size_t savedCgameStateSize;
|
||||
char gcdResponse[73];
|
||||
int unknown3_0;
|
||||
int currentRate;
|
||||
@@ -437,6 +436,9 @@ extern cvar_t *cl_inGameVideo;
|
||||
|
||||
extern cvar_t *cl_lanForcePackets;
|
||||
extern cvar_t *cl_langamerefreshstatus;
|
||||
extern cvar_t *cl_radar_icon_size;
|
||||
extern cvar_t *cl_radar_speak_time;
|
||||
extern cvar_t *cl_radar_blink_time;
|
||||
extern cvar_t *cl_autoRecordDemo;
|
||||
|
||||
extern cvar_t *cl_r_fullscreen;
|
||||
@@ -468,7 +470,7 @@ void CL_AddReliableCommand(const char *cmd, qboolean isDisconnectCmd);
|
||||
|
||||
void CL_StartHunkUsers( qboolean rendererOnly );
|
||||
|
||||
void CL_Connect( const char *server );
|
||||
void CL_Connect( const char *server, netadrtype_t family );
|
||||
|
||||
void CL_Disconnect_f (void);
|
||||
void CL_GetChallengePacket (void);
|
||||
@@ -570,6 +572,7 @@ void CL_FavoriteServers_f( void );
|
||||
void CL_Ping_f( void );
|
||||
void CL_SaveShot_f( void );
|
||||
void CL_Dialog_f( void );
|
||||
void CL_ServerRestarted( void );
|
||||
qboolean CL_UpdateVisiblePings_f( int source );
|
||||
|
||||
|
||||
@@ -686,5 +689,3 @@ void CL_InitConsoleCommands( void );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __CLIENT_H__
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int iFlags;
|
||||
char szName[64];
|
||||
} soundSfx_t;
|
||||
|
||||
typedef struct {
|
||||
qboolean bPlaying;
|
||||
int iStatus;
|
||||
soundSfx_t sfx;
|
||||
int iEntNum;
|
||||
int iEntChannel;
|
||||
float vOrigin[3];
|
||||
float fVolume;
|
||||
int iBaseRate;
|
||||
float fNewPitchMult;
|
||||
float fMinDist;
|
||||
float fMaxDist;
|
||||
int iStartTime;
|
||||
int iTime;
|
||||
int iNextCheckObstructionTime;
|
||||
int iEndTime;
|
||||
int iFlags;
|
||||
int iOffset;
|
||||
int iLoopCount;
|
||||
} channelbasesavegame_t;
|
||||
|
||||
typedef struct {
|
||||
channelbasesavegame_t Channels[MAX_CHANNELS];
|
||||
} soundsystemsavegame_t;
|
||||
|
||||
void S_ChannelFree_Callback(channel_t* v);
|
||||
void S_LoadData(soundsystemsavegame_t* pSave);
|
||||
void S_SaveData(soundsystemsavegame_t* pSave);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,9 +1,37 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../snd_local.h"
|
||||
|
||||
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
|
||||
|
||||
void S_Init2()
|
||||
{
|
||||
S_Init();
|
||||
SND_setup();
|
||||
|
||||
// HACK: S_RegisterSound returns 0 when unsuccessful, or it returns the the sfx handle
|
||||
// But the first sfx handle is also 0...
|
||||
S_RegisterSound("sound/null.wav", qfalse);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -33,7 +61,7 @@ void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t s
|
||||
S_StopAllSounds
|
||||
=================
|
||||
*/
|
||||
void S_StopAllSounds(qboolean stop_music)
|
||||
void S_StopAllSounds2(qboolean stop_music)
|
||||
{
|
||||
// Call the original function
|
||||
S_StopAllSounds();
|
||||
@@ -61,12 +89,29 @@ void S_Respatialize(int entityNum, const vec3_t origin,
|
||||
{
|
||||
S_Respatialize(entityNum, origin, axis, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartLocalSoundChannel
|
||||
=================
|
||||
*/
|
||||
void S_StartLocalSound(const char* sound_name, qboolean force_load)
|
||||
{
|
||||
sfxHandle_t h;
|
||||
|
||||
h = S_RegisterSound(sound_name, qfalse);
|
||||
|
||||
if (h) {
|
||||
S_StartLocalSound(h, CHAN_LOCAL_SOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartLocalSound
|
||||
=================
|
||||
*/
|
||||
void S_StartLocalSound(const char* sound_name, qboolean force_load)
|
||||
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, int channel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
@@ -90,11 +135,16 @@ void S_StopSound(int entnum, int channel)
|
||||
S_IsSoundPlaying
|
||||
=================
|
||||
*/
|
||||
int S_IsSoundPlaying(int channelNumber, const char* name)
|
||||
qboolean S_IsSoundPlaying(int channelNumber, const char* name)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
STUB();
|
||||
return 0;
|
||||
channel_t* v;
|
||||
if (channelNumber >= MAX_CHANNELS) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
v = &s_channels[channelNumber];
|
||||
|
||||
return v->thesfx ? qtrue : qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -379,4 +429,26 @@ void S_FadeSound(float fTime)
|
||||
|
||||
void S_TriggeredMusic_PlayIntroMusic() {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
}
|
||||
|
||||
void callbackServer(int entnum, int channel_number, const char* name) {
|
||||
if (com_sv_running->integer) {
|
||||
SV_SoundCallback(entnum, channel_number, name);
|
||||
}
|
||||
}
|
||||
|
||||
void S_ChannelFree_Callback(channel_t* v) {
|
||||
if (v->entnum & S_FLAG_DO_CALLBACK) {
|
||||
callbackServer(v->entnum & ~S_FLAG_DO_CALLBACK, v - s_channels, v->thesfx->soundName);
|
||||
}
|
||||
}
|
||||
|
||||
void S_LoadData(soundsystemsavegame_t* pSave) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_SaveData(soundsystemsavegame_t* pSave) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -8,8 +30,8 @@ void S_Respatialize(int entityNum, const vec3_t origin, vec3_t axis[3]);
|
||||
sfxHandle_t S_RegisterSound(const char* sample, qboolean compressed, qboolean streamed);
|
||||
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float minDist, float maxDist, float pitch, int flags);
|
||||
void S_StartLocalSound(const char* name, qboolean force_load);
|
||||
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, int channel);
|
||||
void S_StartSound(const vec3_t origin, int entNum, int entChannel, sfxHandle_t sfxHandle, float volume, float minDist, float pitch, float maxDist, qboolean streamed);
|
||||
void S_StopAllSounds(qboolean stop_music);
|
||||
void S_ClearLoopingSounds(void);
|
||||
qboolean S_IsSoundRegistered(const char* name);
|
||||
void S_Init2();
|
||||
@@ -43,10 +65,11 @@ void MUSIC_UpdateMusicVolumes(void);
|
||||
void MUSIC_CheckForStoppedSongs(void);
|
||||
|
||||
void S_StopSound(int entnum, int channel);
|
||||
void S_StopAllSounds2(qboolean stop_music);
|
||||
float S_GetSoundTime(sfxHandle_t handle);
|
||||
void S_SetGlobalAmbientVolumeLevel(float volume);
|
||||
void S_SetReverb(int reverb_type, float reverb_level);
|
||||
int S_IsSoundPlaying(int channelNumber, const char* name);
|
||||
qboolean S_IsSoundPlaying(int channelNumber, const char* name);
|
||||
|
||||
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t velocity, qboolean use_listener);
|
||||
void S_FadeSound(float fTime);
|
||||
|
||||
@@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "snd_codec.h"
|
||||
|
||||
// includes for the MP3 codec
|
||||
#include <mad.h>
|
||||
#include "../libmad-0.15.1b/synth.h"
|
||||
|
||||
#define MP3_SAMPLE_WIDTH 2
|
||||
#define MP3_PCMSAMPLES_PERSLICE 32
|
||||
|
||||
@@ -181,6 +181,7 @@ void S_Base_SoundList( void ) {
|
||||
|
||||
|
||||
void S_ChannelFree(channel_t *v) {
|
||||
S_ChannelFree_Callback(v);
|
||||
v->thesfx = NULL;
|
||||
*(channel_t **)v = freelist;
|
||||
freelist = (channel_t*)v;
|
||||
@@ -1580,7 +1581,9 @@ qboolean S_Base_Init( soundInterface_t *si ) {
|
||||
|
||||
if ( r ) {
|
||||
s_soundStarted = 1;
|
||||
s_soundMuted = 1;
|
||||
// Fixed in OPM
|
||||
// The UI must be able to play sounds
|
||||
// s_soundMuted = 1;
|
||||
// s_numSfx = 0;
|
||||
|
||||
Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH);
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#if USE_SOUND_NEW
|
||||
|
||||
#include "snd_local.h"
|
||||
#include "snd_openal_new.h"
|
||||
|
||||
typedef struct {
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
sfx_t *sfx;
|
||||
int mergeFrame;
|
||||
} loopSound_t;
|
||||
|
||||
# define MAX_SFX 1400
|
||||
# define MAX_SFX_INFOS 1000
|
||||
# define MAX_LOOP_SOUNDS 64
|
||||
|
||||
qboolean s_bLastInitSound = qfalse;
|
||||
qboolean s_bSoundStarted = qfalse;
|
||||
qboolean s_bSoundPaused = qfalse;
|
||||
qboolean s_bTryUnpause = qfalse;
|
||||
int s_iListenerNumber = 0;
|
||||
float s_fAmbientVolume = 1.f;
|
||||
|
||||
int number_of_sfx_infos = 0;
|
||||
|
||||
cvar_t *s_volume;
|
||||
cvar_t *s_loadas8bit;
|
||||
cvar_t *s_khz;
|
||||
cvar_t *s_show;
|
||||
cvar_t *s_testsound;
|
||||
cvar_t *s_separation;
|
||||
cvar_t *s_musicVolume;
|
||||
cvar_t *s_ambientVolume;
|
||||
|
||||
sfx_info_t sfx_infos[MAX_SFX_INFOS];
|
||||
|
||||
sfx_t s_knownSfx[MAX_SFX];
|
||||
int s_numSfx;
|
||||
|
||||
s_entity_t s_entity[MAX_GENTITIES];
|
||||
|
||||
static int s_registrationSequence;
|
||||
static qboolean s_inRegistration;
|
||||
|
||||
cvar_t *s_mixPreStep;
|
||||
cvar_t *s_dialogscale;
|
||||
|
||||
int numLoopSounds;
|
||||
loopSound_t loopSounds[MAX_LOOP_SOUNDS];
|
||||
|
||||
void S_SoundInfo_f()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_SoundDump_f()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_Init(qboolean full_startup)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_Shutdown(qboolean full_shutdown)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
qboolean S_NameExists(const char *name)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
sfx_t *S_FindName(const char *name, int sequenceNumber)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void S_BeginRegistration()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_DefaultSound(sfx_t *sfx)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
qboolean S_IsSoundRegistered(const char *name)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
sfxHandle_t S_RegisterSound(const char *name, int streamed, qboolean force_load)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
float S_GetSoundTime(sfxHandle_t handle)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
void S_EndRegistration()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_SetGlobalAmbientVolumeLevel(float volume)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_StartSound(
|
||||
const vec3_t origin,
|
||||
int entnum,
|
||||
int entchannel,
|
||||
sfxHandle_t sfxHandle,
|
||||
float volume,
|
||||
float min_dist,
|
||||
float pitch,
|
||||
float maxDist,
|
||||
int streamed
|
||||
)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_StartLocalSound(const char *sound_name, qboolean force_load)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_StartLocalSoundChannel(const char *sound_name, qboolean force_load, soundChannel_t channel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_StopAllSounds(qboolean stop_music)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_ClearLoopingSounds()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_AddLoopingSound(
|
||||
const vec3_t origin,
|
||||
const vec3_t velocity,
|
||||
sfxHandle_t sfxHandle,
|
||||
float volume,
|
||||
float min_dist,
|
||||
float max_dist,
|
||||
float pitch,
|
||||
int flags
|
||||
)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3])
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_Update()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_StopSound(int entnum, int channel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_SetReverb(int reverb_type, float reverb_level)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_Play()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_SoundList()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_ClearSoundBuffer()
|
||||
{
|
||||
// TODO: Remove once AL is fully implemented
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -21,11 +21,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// snd_local.h -- private sound definations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "snd_public.h"
|
||||
|
||||
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
|
||||
|
||||
#define PAINTBUFFER_SIZE 4096 // this is in samples
|
||||
|
||||
#define SND_CHUNK_SIZE 1024 // samples
|
||||
@@ -275,6 +278,12 @@ qboolean S_AL_Init( soundInterface_t *si );
|
||||
void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE], int snd_vol, channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset );
|
||||
#endif
|
||||
|
||||
#include "new/snd_local_new.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
# include "snd_local_new.h"
|
||||
#endif
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int format;
|
||||
float rate;
|
||||
|
||||
float width;
|
||||
int channels;
|
||||
int samples;
|
||||
|
||||
int dataofs;
|
||||
int datasize;
|
||||
} wavinfo_t;
|
||||
|
||||
typedef struct sfx_s {
|
||||
int iFlags;
|
||||
|
||||
int length;
|
||||
int width;
|
||||
byte *data;
|
||||
char name[64];
|
||||
|
||||
int registration_sequence;
|
||||
int sfx_info_index;
|
||||
float time_length;
|
||||
|
||||
wavinfo_t info;
|
||||
unsigned int buffer;
|
||||
} sfx_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned short wFormatTag;
|
||||
unsigned short nChannels;
|
||||
unsigned int nSamplesPerSec;
|
||||
unsigned int nAvgBytesPerSec;
|
||||
unsigned short nBlockAlign;
|
||||
unsigned short wBitsPerSample;
|
||||
unsigned short cbSize;
|
||||
} wavinfo_x_t;
|
||||
|
||||
typedef struct {
|
||||
char name[64];
|
||||
|
||||
int loop_start;
|
||||
int loop_end;
|
||||
|
||||
int max_number_playing;
|
||||
float max_factor;
|
||||
} sfx_info_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t position;
|
||||
vec3_t velocity;
|
||||
int time;
|
||||
qboolean use_listener;
|
||||
} s_entity_t;
|
||||
|
||||
typedef struct {
|
||||
char alias[32];
|
||||
char path[64];
|
||||
|
||||
int mood_num;
|
||||
int flags;
|
||||
float volume;
|
||||
float fadetime;
|
||||
|
||||
int current_pos;
|
||||
int current_state;
|
||||
} song_t;
|
||||
|
||||
typedef struct {
|
||||
int iFlags;
|
||||
char szName[64];
|
||||
} sfxsavegame_t;
|
||||
|
||||
typedef struct {
|
||||
qboolean bPlaying;
|
||||
int iStatus;
|
||||
sfxsavegame_t sfx;
|
||||
|
||||
int iEntNum;
|
||||
int iEntChannel;
|
||||
vec3_t vOrigin;
|
||||
float fVolume;
|
||||
int iBaseRate;
|
||||
float fNewPitchMult;
|
||||
float fMinDist;
|
||||
float fMaxDist;
|
||||
|
||||
int iStartTime;
|
||||
int iTime;
|
||||
int iNextCheckObstructionTime;
|
||||
int iEndTime;
|
||||
|
||||
int iFlags;
|
||||
int iOffset;
|
||||
int iLoopCount;
|
||||
} channelbasesavegame_t;
|
||||
|
||||
typedef struct {
|
||||
channelbasesavegame_t Channels[96];
|
||||
} soundsystemsavegame_t;
|
||||
|
||||
// The current sound driver.
|
||||
// Currently OPENAL
|
||||
#define SOUND_DRIVER OPENAL
|
||||
|
||||
sfx_t *S_FindName(const char *name, int sequenceNumber);
|
||||
void S_DefaultSound(sfx_t *sfx);
|
||||
|
||||
void S_LoadData(soundsystemsavegame_t *pSave);
|
||||
void S_SaveData(soundsystemsavegame_t *pSave);
|
||||
void S_ClearSoundBuffer();
|
||||
|
||||
#define S_StopAllSounds2 S_StopAllSounds
|
||||
|
||||
//
|
||||
// Driver-specific functions
|
||||
//
|
||||
#define S_Call_SndDriver(driver, func) S_##driver##_##func
|
||||
#define S_Call_SndDriverX(driver, func) S_Call_SndDriver(driver, func)
|
||||
|
||||
#define S_Driver_Init S_Call_SndDriverX(SOUND_DRIVER, Init)
|
||||
#define S_Driver_StartSound S_Call_SndDriverX(SOUND_DRIVER, StartSound)
|
||||
#define S_Driver_AddLoopingSound S_Call_SndDriverX(SOUND_DRIVER, AddLoopingSound)
|
||||
#define S_Driver_ClearLoopingSounds S_Call_SndDriverX(SOUND_DRIVER, ClearLoopingSounds)
|
||||
#define S_Driver_StopSound S_Call_SndDriverX(SOUND_DRIVER, StopSound)
|
||||
#define S_Driver_StopAllSounds S_Call_SndDriverX(SOUND_DRIVER, StopAllSounds)
|
||||
#define S_Driver_Respatialize S_Call_SndDriverX(SOUND_DRIVER, Respatialize)
|
||||
#define S_Driver_SetReverb S_Call_SndDriverX(SOUND_DRIVER, SetReverb)
|
||||
#define S_Driver_Update S_Call_SndDriverX(SOUND_DRIVER, Update)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,29 +1,25 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
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.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
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 Foobar; if not, write to the Free Software
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../qcommon/vm_local.h"
|
||||
|
||||
void VM_Compile( vm_t *vm, vmHeader_t *header ) {}
|
||||
int VM_CallCompiled( vm_t *vm, int *args ) {}
|
||||
|
||||
|
||||
// See the header file for information
|
||||
|
||||
#include "snd_miles_new.h"
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
//
|
||||
// This file exists in the original source code.
|
||||
// But this driver won't be implemented, as OpenAL is a better sound system!
|
||||
//
|
||||
|
||||
#pragma once
|
||||
@@ -0,0 +1,757 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#if USE_SOUND_NEW
|
||||
|
||||
# include "snd_local.h"
|
||||
# include "snd_openal_new.h"
|
||||
|
||||
typedef struct {
|
||||
char *funcname;
|
||||
void **funcptr;
|
||||
bool required;
|
||||
} extensions_table_t;
|
||||
|
||||
# define MAX_MUSIC_SONGS 16
|
||||
|
||||
static int s_iNextLoopingWarning = 0;
|
||||
static int s_iReverbType = 0;
|
||||
static float s_fReverbLevel = 0;
|
||||
static bool s_bReverbChanged = false;
|
||||
static bool s_bFading = false;
|
||||
static float s_fFadeVolume = 1.f;
|
||||
|
||||
cvar_t *s_milesdriver;
|
||||
cvar_t *s_openaldevice;
|
||||
cvar_t *s_reverb;
|
||||
cvar_t *s_show_cpu;
|
||||
cvar_t *s_show_num_active_sounds;
|
||||
cvar_t *s_show_sounds;
|
||||
cvar_t *s_speaker_type;
|
||||
cvar_t *s_obstruction_cal_time;
|
||||
cvar_t *s_lastSoundTime;
|
||||
|
||||
static float reverb_table[] = {
|
||||
0.5f, 0.25f, 0.417f, 0.653f, 0.208f, 0.5f, 0.403f, 0.5f, 0.5f,
|
||||
0.361f, 0.5f, 0.153f, 0.361f, 0.44400001f, 0.25f, 0.111f, 0.111f, 0.19400001f,
|
||||
1.0f, 0.097000003f, 0.208f, 0.65200001f, 1.0f, 0.875f, 0.139f, 0.486f,
|
||||
};
|
||||
|
||||
static vec3_t vec_zero = {0, 0, 0};
|
||||
int s_iNumMilesAudioProviders = 0;
|
||||
bool s_bProvidersEmunerated = false;
|
||||
static bool al_initialized = false;
|
||||
static bool al_use_reverb = false;
|
||||
static float al_current_volume = 0;
|
||||
static unsigned int al_frequency = 22050;
|
||||
static void *al_context_id = NULL;
|
||||
static ALCdevice *al_device = NULL;
|
||||
|
||||
static ALboolean (*_alutLoadMP3_LOKI)(unsigned int buffer, const byte *data, int length);
|
||||
static void (*_alReverbScale_LOKI)();
|
||||
static void (*_alReverbDelay_LOKI)();
|
||||
|
||||
static qboolean music_active = qfalse;
|
||||
int music_current_mood = 0;
|
||||
int music_fallback_mood = 0;
|
||||
float old_music_volume = 1.f;
|
||||
float music_volume = 1.f;
|
||||
float new_music_volume = 1.f;
|
||||
float music_volume_fade_time = 0;
|
||||
long int music_volume_start_time = 0;
|
||||
int music_volume_direction = 0;
|
||||
int music_volume_changed = 0;
|
||||
int music_loaded = 0;
|
||||
int music_numsongs = 0;
|
||||
int music_currentsong = 0;
|
||||
|
||||
song_t music_songs[MAX_MUSIC_SONGS];
|
||||
openal_internal_t openal;
|
||||
static float s_fFadeStartTime;
|
||||
static float s_fFadeStopTime;
|
||||
static char current_soundtrack[128];
|
||||
|
||||
static void __alDieIfError(char *file)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_OPENAL_NukeSource(ALuint *srcptr)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_OPENAL_NukeBuffer(ALuint *bufptr)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_OPENAL_NukeChannel(openal_channel *channel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_OPENAL_NukeContext()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static bool S_OPENAL_InitContext()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool S_OPENAL_InitExtensions()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool S_OPENAL_InitChannel(int idx, openal_channel *chan)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean S_OPENAL_Init()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void S_OPENAL_Shutdown()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_FadeSound(float fTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
float S_GetBaseVolume()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
qboolean S_NeedFullRestart()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void S_PrintInfo()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_DumpStatus(const char *pszChanName, int iChanNum, openal_channel *channel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_DumpInfo()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_OPENAL_Pitch()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static bool S_OPENAL_LoadMP3(const char *_path, openal_channel *chan)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return false;
|
||||
}
|
||||
|
||||
static void S_OPENAL_PlayMP3()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_OPENAL_StopMP3()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void MUSIC_Pause()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void MUSIC_Unpause()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_PauseSound()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_UnpauseSound()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static qboolean S_OPENAL_ShouldPlay(sfx_t *pSfx)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static qboolean S_OPENAL_ShouldStart(const vec3_t vOrigin, float fMinDist, float fMaxDist)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static int S_OPENAL_PickChannelBase(int iEntNum, int iEntChannel, int iFirstChannel, int iLastChannel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int S_OPENAL_PickChannel3D(int iEntNum, int iEntChannel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int S_OPENAL_PickChannel2D(int iEntNum, int iEntChannel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int S_OPENAL_PickChannel2DStreamed(int iEntNum, int iEntChannel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
void callbackServer(int entnum, int channel_number, const char *name)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_OPENAL_Start2DSound(
|
||||
const vec3_t vOrigin,
|
||||
int iEntNum,
|
||||
int iEntChannel,
|
||||
sfx_t *pSfx,
|
||||
float fVolume,
|
||||
float fMinDistance,
|
||||
float fPitch,
|
||||
float fMaxDistance
|
||||
)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_StartSound(
|
||||
const vec3_t vOrigin,
|
||||
int iEntNum,
|
||||
int iEntChannel,
|
||||
sfxHandle_t sfxHandle,
|
||||
float fVolume,
|
||||
float fMinDist,
|
||||
float fPitch,
|
||||
float fMaxDist,
|
||||
qboolean bStreamed
|
||||
)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_AddLoopingSound(
|
||||
const vec3_t vOrigin,
|
||||
const vec3_t vVelocity,
|
||||
sfxHandle_t sfxHandle,
|
||||
float fVolume,
|
||||
float fMinDist,
|
||||
float fMaxDist,
|
||||
float fPitch,
|
||||
int iFlags
|
||||
)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_StopLoopingSound(openal_loop_sound_t *pLoopSound)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_ClearLoopingSounds()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_StopLoopingSounds()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_StopSound(int iEntNum)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_StopAllSounds(qboolean bStopMusic)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static int S_OPENAL_Start2DLoopSound(
|
||||
openal_loop_sound_t *pLoopSound, float fVolume, float fVolumeToPlay, float fMinDistance, const vec3_t vLoopOrigin
|
||||
)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int S_OPENAL_Start3DLoopSound(
|
||||
openal_loop_sound_t *pLoopSound,
|
||||
float fVolumeToPlay,
|
||||
float fMinDistance,
|
||||
float fMaxDistance,
|
||||
const vec3_t vLoopOrigin,
|
||||
const vec3_t vListenerOrigin
|
||||
)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool S_OPENAL_UpdateLoopSound(
|
||||
openal_loop_sound_t *pLoopSound,
|
||||
float fVolumeToPlay,
|
||||
float fMinDistance,
|
||||
float fMaxDistance,
|
||||
const vec3_t vListenerOrigin,
|
||||
const vec3_t vTempAxis,
|
||||
const vec3_t vLoopOrigin
|
||||
)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return false;
|
||||
}
|
||||
|
||||
void S_OPENAL_AddLoopSounds(const vec3_t vTempAxis)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_Respatialize(int iEntNum, const vec3_t vHeadPos, const vec3_t vAxis[3])
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static int S_OPENAL_SpatializeStereoSound(const vec3_t listener_origin, const vec3_t listener_left, const vec3_t origin)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void S_OPENAL_reverb(int iChannel, int iReverbType, float fReverbLevel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_SetReverb(int iType, float fLevel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_OPENAL_Update()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
qboolean S_IsSoundPlaying(int channel_number, const char *sfxName)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static void S_StoreBase(channelbasesavegame_t *pBase, openal_channel *pChannel)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void
|
||||
S_StartSoundFromBase(channelbasesavegame_t *pBase, openal_channel *pChannel, sfx_t *pSfx, bool bStartUnpaused)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_LoadBase(channelbasesavegame_t *pBase, openal_channel *pChannel, bool bStartUnpaused)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_SaveData(soundsystemsavegame_t *pSave)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_ReLoad(soundsystemsavegame_t *pSave)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void S_InitBase(channelbasesavegame_t *pBase)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_LoadData(soundsystemsavegame_t *pSave)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_velocity(float v0, float v1, float v2)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_position(float v0, float v1, float v2)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_gain(float gain)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_no_3d()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_3d()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::play()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::pause()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::stop()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
ALint openal_channel::get_state()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool openal_channel::is_free()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return false;
|
||||
}
|
||||
|
||||
bool openal_channel::is_paused()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return false;
|
||||
}
|
||||
|
||||
bool openal_channel::is_playing()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return false;
|
||||
}
|
||||
|
||||
void openal_channel::force_free()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
bool openal_channel::set_sfx(sfx_t *pSfx)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return false;
|
||||
}
|
||||
|
||||
void openal_channel::start_sample()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::stop_sample()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::resume_sample()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::end_sample()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_sample_pan(S32 pan)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_sample_playback_rate(S32 rate)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
S32 openal_channel::sample_playback_rate()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
S32 openal_channel::sample_volume()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
U32 openal_channel::sample_offset()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
U32 openal_channel::sample_ms_offset()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
U32 openal_channel::sample_loop_count()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
void openal_channel::set_sample_offset(U32 offset)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_sample_ms_offset(U32 offset)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_sample_loop_count(S32 count)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void openal_channel::set_sample_loop_block(S32 start_offset, S32 end_offset)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
U32 openal_channel::sample_status()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
qboolean MUSIC_LoadSoundtrackFile(const char *filename)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
qboolean MUSIC_SongValid(const char *mood)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
qboolean MUSIC_Loaded()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void Music_Update()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void MUSIC_SongEnded()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void MUSIC_NewSoundtrack(const char *name)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void MUSIC_UpdateMood(int current, int fallback)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void MUSIC_UpdateVolume(float volume, float fade_time)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void MUSIC_StopAllSongs()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void MUSIC_FreeAllSongs()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
qboolean MUSIC_Playing()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
int MUSIC_FindSong(const char *name)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
void S_loadsoundtrack()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
const char *S_CurrentSoundtrack()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void S_PlaySong()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
int MUSIC_CurrentSongChannel()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MUSIC_StopChannel(int channel_number)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
qboolean MUSIC_PlaySong(const char *alias)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void MUSIC_UpdateMusicVolumes()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void MUSIC_CheckForStoppedSongs()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_TriggeredMusic_SetupHandle(const char *pszName, int iLoopCount, int iOffset, qboolean autostart)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_TriggeredMusic_Start()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_TriggeredMusic_StartLoop()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_TriggeredMusic_Stop()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_TriggeredMusic_Pause()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_TriggeredMusic_Unpause()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_TriggeredMusic_PlayIntroMusic()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_StopMovieAudio()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void S_SetupMovieAudio(const char *pszMovieName)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
int S_CurrentMoviePosition()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qal.h"
|
||||
|
||||
#undef OPENAL
|
||||
|
||||
typedef int S32;
|
||||
typedef unsigned int U32;
|
||||
|
||||
typedef enum {
|
||||
FADE_NONE,
|
||||
FADE_IN,
|
||||
FADE_OUT
|
||||
} fade_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t vOrigin;
|
||||
vec3_t vRelativeOrigin;
|
||||
vec3_t vVelocity;
|
||||
sfx_t *pSfx;
|
||||
qboolean bPlaying;
|
||||
int iChannel;
|
||||
float fVolume;
|
||||
float fPitch;
|
||||
int iStartTime;
|
||||
qboolean bInUse;
|
||||
qboolean bCombine;
|
||||
float fBaseVolume;
|
||||
float fMinDist;
|
||||
float fMaxDist;
|
||||
int iFlags;
|
||||
} openal_loop_sound_t;
|
||||
|
||||
struct openal_channel {
|
||||
sfx_t *pSfx;
|
||||
int iEntNum;
|
||||
int iEntChannel;
|
||||
vec3_t vOrigin;
|
||||
float fVolume;
|
||||
int iBaseRate;
|
||||
float fNewPitchMult;
|
||||
float fMinDist;
|
||||
float fMaxDist;
|
||||
int iStartTime;
|
||||
int iTime;
|
||||
int iEndTime;
|
||||
int iFlags;
|
||||
int iPausedOffset;
|
||||
int song_number;
|
||||
fade_t fading;
|
||||
int fade_time;
|
||||
int fade_start_time;
|
||||
ALuint source;
|
||||
ALuint buffer;
|
||||
ALubyte *bufferdata;
|
||||
|
||||
void play();
|
||||
void stop();
|
||||
void pause();
|
||||
|
||||
void set_no_3d();
|
||||
void set_3d();
|
||||
ALint get_state();
|
||||
|
||||
void set_gain(float gain);
|
||||
void set_velocity(float v0, float v1, float v2);
|
||||
void set_position(float v0, float v1, float v2);
|
||||
|
||||
bool is_free();
|
||||
bool is_paused();
|
||||
bool is_playing();
|
||||
|
||||
void force_free();
|
||||
bool set_sfx(sfx_t *pSfx);
|
||||
|
||||
void start_sample();
|
||||
void stop_sample();
|
||||
void resume_sample();
|
||||
void end_sample();
|
||||
|
||||
void set_sample_pan(S32 pan);
|
||||
void set_sample_playback_rate(S32 pan);
|
||||
S32 sample_playback_rate();
|
||||
|
||||
S32 sample_volume();
|
||||
U32 sample_offset();
|
||||
U32 sample_ms_offset();
|
||||
U32 sample_loop_count();
|
||||
void set_sample_offset(U32 offset);
|
||||
void set_sample_ms_offset(U32 offset);
|
||||
void set_sample_loop_count(S32 count);
|
||||
void set_sample_loop_block(S32 start_offset, S32 end_offset);
|
||||
|
||||
U32 sample_status();
|
||||
};
|
||||
|
||||
struct openal_internal_t {
|
||||
openal_channel chan_3D[32];
|
||||
openal_channel chan_2D[32];
|
||||
openal_channel chan_2D_stream[32];
|
||||
openal_channel chan_song[2];
|
||||
openal_channel chan_mp3;
|
||||
openal_channel chan_trig_music;
|
||||
openal_channel chan_movie;
|
||||
openal_channel *channel[101];
|
||||
openal_loop_sound_t loop_sounds[64];
|
||||
openal_channel movieChannel;
|
||||
sfx_t movieSFX;
|
||||
char tm_filename[64];
|
||||
int tm_loopcount;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
qboolean S_OPENAL_Init();
|
||||
void S_OPENAL_StartSound(
|
||||
const vec3_t vOrigin,
|
||||
int iEntNum,
|
||||
int iEntChannel,
|
||||
sfxHandle_t sfxHandle,
|
||||
float fVolume,
|
||||
float fMinDist,
|
||||
float fPitch,
|
||||
float fMaxDist,
|
||||
qboolean bStreamed
|
||||
);
|
||||
void S_OPENAL_AddLoopingSound(
|
||||
const vec3_t vOrigin,
|
||||
const vec3_t vVelocity,
|
||||
sfxHandle_t sfxHandle,
|
||||
float fVolume,
|
||||
float fMinDist,
|
||||
float fMaxDist,
|
||||
float fPitch,
|
||||
int iFlags
|
||||
);
|
||||
void S_OPENAL_ClearLoopingSounds();
|
||||
void S_OPENAL_StopSound(int iEntNum);
|
||||
void S_OPENAL_StopAllSounds(qboolean bStopMusic);
|
||||
void S_OPENAL_Respatialize(int iEntNum, const vec3_t vHeadPos, const vec3_t vAxis[3]);
|
||||
void S_OPENAL_SetReverb(int iType, float fLevel);
|
||||
void S_OPENAL_Update();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -89,3 +91,74 @@ void S_MasterGain(float gain);
|
||||
#endif
|
||||
|
||||
#include "new/snd_public_new.h"
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void S_SoundInfo_f();
|
||||
void S_SoundDump_f();
|
||||
void S_Init(qboolean full_startup);
|
||||
void S_Shutdown(qboolean full_shutdown);
|
||||
qboolean S_NameExists(const char* name);
|
||||
void S_BeginRegistration();
|
||||
qboolean S_IsSoundRegistered(const char* name);
|
||||
sfxHandle_t S_RegisterSound(const char* name, int streamed, qboolean force_load);
|
||||
float S_GetSoundTime(sfxHandle_t handle);
|
||||
void S_EndRegistration();
|
||||
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener);
|
||||
void S_SetGlobalAmbientVolumeLevel(float volume);
|
||||
void S_StartSound(const vec3_t origin, int entnum, int entchannel, sfxHandle_t sfxHandle, float volume, float min_dist, float pitch, float maxDist, int streamed);
|
||||
void S_StartLocalSound(const char* sound_name, qboolean force_load);
|
||||
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, soundChannel_t channel);
|
||||
void S_StopAllSounds(qboolean stop_music);
|
||||
void S_ClearLoopingSounds();
|
||||
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float min_dist, float max_dist, float pitch, int flags);
|
||||
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3]);
|
||||
void S_Update();
|
||||
void S_StopSound(int entnum, int channel);
|
||||
void S_SetReverb(int reverb_type, float reverb_level);
|
||||
void S_Play();
|
||||
void S_SoundList();
|
||||
|
||||
qboolean S_IsSoundPlaying(int channel_number, const char* sfxName);
|
||||
void S_FadeSound(float fTime);
|
||||
|
||||
qboolean MUSIC_LoadSoundtrackFile(const char* filename);
|
||||
qboolean MUSIC_SongValid(const char* mood);
|
||||
qboolean MUSIC_Loaded();
|
||||
void Music_Update();
|
||||
void MUSIC_SongEnded();
|
||||
void MUSIC_NewSoundtrack(const char* name);
|
||||
void MUSIC_UpdateMood(int current, int fallback);
|
||||
void MUSIC_UpdateVolume(float volume, float fade_time);
|
||||
void MUSIC_StopAllSongs();
|
||||
void MUSIC_FreeAllSongs();
|
||||
qboolean MUSIC_Playing();
|
||||
int MUSIC_FindSong(const char* name);
|
||||
void S_loadsoundtrack();
|
||||
const char* S_CurrentSoundtrack();
|
||||
void S_PlaySong();
|
||||
int MUSIC_CurrentSongChannel();
|
||||
void MUSIC_StopChannel(int channel_number);
|
||||
qboolean MUSIC_PlaySong(const char* alias);
|
||||
void MUSIC_UpdateMusicVolumes();
|
||||
void MUSIC_CheckForStoppedSongs();
|
||||
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart);
|
||||
void S_TriggeredMusic_Start();
|
||||
void S_TriggeredMusic_StartLoop();
|
||||
void S_TriggeredMusic_Stop();
|
||||
void S_TriggeredMusic_Pause();
|
||||
void S_TriggeredMusic_Unpause();
|
||||
void S_TriggeredMusic_PlayIntroMusic();
|
||||
void S_StopMovieAudio();
|
||||
void S_SetupMovieAudio(const char* pszMovieName);
|
||||
int S_CurrentMoviePosition();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -120,7 +120,7 @@ bool UConnection::SendEvent
|
||||
ptr = m_listeners.ObjectAt( i );
|
||||
if( ptr )
|
||||
{
|
||||
Event *e = new Event( m_events.ObjectAt( i ) );
|
||||
Event *e = new Event( *m_events.ObjectAt( i ) );
|
||||
|
||||
for( j = 1; j < numargs; j++ )
|
||||
{
|
||||
|
||||
@@ -16,7 +16,14 @@ set(SOURCES_SHARED
|
||||
"../qcommon/str.cpp"
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SOURCES_GAME "./*.c*" "../parser/*.c*" "../script/*.c*")
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
SOURCES_GAME
|
||||
"./*.c*"
|
||||
"../script/*.c*"
|
||||
"../parser/generated/*.c*"
|
||||
"../parser/parsetree.cpp"
|
||||
)
|
||||
|
||||
add_library(fgame SHARED ${SOURCES_GAME})
|
||||
|
||||
@@ -44,13 +51,13 @@ 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}${TARGET_CONFIG_SUFFIX}")
|
||||
set_target_properties(fgame PROPERTIES OUTPUT_NAME "game${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(fgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
|
||||
|
||||
INSTALL(
|
||||
TARGETS fgame
|
||||
DESTINATION "${TARGET_BASE_GAME}"
|
||||
ARCHIVE EXCLUDE_FROM_ALL
|
||||
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
|
||||
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "DrivableVehicleTandem.h"
|
||||
#include "vehicleturret.h"
|
||||
|
||||
CLASS_DECLARATION(DrivableVehicle, DrivableVehicleTandem, "DrivableVehicleTandem") {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
DrivableVehicleTandem::DrivableVehicleTandem()
|
||||
{
|
||||
}
|
||||
|
||||
DrivableVehicleTandem::~DrivableVehicleTandem()
|
||||
{
|
||||
}
|
||||
|
||||
void DrivableVehicleTandem::SpawnTurret(Event* ev)
|
||||
{
|
||||
VehicleTurretGunTandem* pTurret = new VehicleTurretGunTandem();
|
||||
int slot;
|
||||
|
||||
pTurret->SetBaseOrientation(orientation, NULL);
|
||||
pTurret->setModel(ev->GetString(2));
|
||||
|
||||
slot = ev->GetInteger(1);
|
||||
AttachTurretSlot(slot, pTurret, vec_zero, NULL);
|
||||
pTurret->SetVehicleOwner(this);
|
||||
|
||||
pTurret->PostEvent(EV_TakeDamage, EV_POSTSPAWN);
|
||||
|
||||
UpdateTurretSlot(slot);
|
||||
|
||||
pTurret->ProcessPendingEvents();
|
||||
}
|
||||
|
||||
void DrivableVehicleTandem::UpdateTurretSlot(int iSlot)
|
||||
{
|
||||
DrivableVehicle::UpdateTurretSlot(iSlot);
|
||||
|
||||
if (Turrets[iSlot].ent && Turrets[iSlot].ent->isSubclassOf(VehicleTurretGunTandem)) {
|
||||
VehicleTurretGunTandem* pTurret = static_cast<VehicleTurretGunTandem*>(Turrets[iSlot].ent.Pointer());
|
||||
pTurret->UpdateLinkedTurret();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vehicle.h"
|
||||
|
||||
class DrivableVehicleTandem : public DrivableVehicle {
|
||||
private:
|
||||
CLASS_PROTOTYPE(DrivableVehicleTandem);
|
||||
|
||||
public:
|
||||
DrivableVehicleTandem();
|
||||
~DrivableVehicleTandem();
|
||||
|
||||
void SpawnTurret(Event* ev) override;
|
||||
void UpdateTurretSlot(int iSlot) override;
|
||||
};
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "entity.h"
|
||||
#include "animate.h"
|
||||
|
||||
typedef enum {
|
||||
CONTROLLER_ALLIES,
|
||||
CONTROLLER_AXIS,
|
||||
CONTROLLER_DRAW
|
||||
} eController;
|
||||
|
||||
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
|
||||
#define PT_SPAWNFLAG_PLAY_MOTION_SOUND 2
|
||||
#define PT_SPAWNFLAG_TARGET_RANDOM 4
|
||||
#define PT_SPAWNFLAG_TURN_ON 8
|
||||
#define PT_SPAWNFLAG_ROTATE_YAW 16
|
||||
#define PT_SPAWNFLAG_ROTATE_ROLL 32
|
||||
#define PT_SPAWNFLAG_TARGET_PLAYER 64
|
||||
#define PT_SPAWNFLAG_HIDDEN 128
|
||||
|
||||
void ClearProjectileTargets();
|
||||
|
||||
class ProjectileTarget : public Entity
|
||||
{
|
||||
private:
|
||||
int m_iTarget;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileTarget);
|
||||
|
||||
ProjectileTarget();
|
||||
|
||||
void EventSetId(Event *ev);
|
||||
int GetTarget() const;
|
||||
};
|
||||
|
||||
#define MAX_PROJECTILE_GENERATOR_TARGETS 16
|
||||
|
||||
class ProjectileGenerator : public Animate
|
||||
{
|
||||
protected:
|
||||
int m_iId;
|
||||
int m_iCycles;
|
||||
float m_fMinDuration;
|
||||
float m_fMaxDuration;
|
||||
int m_iMinNumShots;
|
||||
int m_iMaxNumShots;
|
||||
float m_fMinDelay;
|
||||
float m_fMaxDelay;
|
||||
float m_fAccuracy;
|
||||
str m_sLaunchSound;
|
||||
bool m_bFireOnStartUp;
|
||||
qboolean m_bIsDonut;
|
||||
float m_fArcDonut;
|
||||
float m_fMinDonut;
|
||||
float m_fMaxDonut;
|
||||
float m_fCycleTime;
|
||||
float m_fShotsPerSec;
|
||||
float m_fCurrentTime;
|
||||
int m_iTargetIndex;
|
||||
float m_fLastShotTime;
|
||||
int m_iAnimSlot;
|
||||
bool m_bIsTurnedOn;
|
||||
int m_iCurrentCycle;
|
||||
Entity *m_pTarget;
|
||||
Container<ProjectileTarget *> m_projectileTargets;
|
||||
Entity *m_pCurrent;
|
||||
Vector m_vTargetOrg;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileGenerator);
|
||||
|
||||
ProjectileGenerator();
|
||||
|
||||
virtual void SetupNextCycle();
|
||||
virtual void BeginCycle(Event *ev);
|
||||
virtual void TickCycle(Event *ev);
|
||||
virtual void EndCycle(Event *ev);
|
||||
|
||||
bool ShouldStartOn() const;
|
||||
bool ShouldHideModel() const;
|
||||
bool ShouldPlayFireSound() const;
|
||||
bool ShouldPlayMotionSound() const;
|
||||
bool ShouldRotateYaw() const;
|
||||
bool ShouldRotateRoll() const;
|
||||
|
||||
void EventIsTurnedOn(Event *ev);
|
||||
void EventGetTargetEntity(Event *ev);
|
||||
void EventLaunchSound(Event *ev);
|
||||
void SetTarget(Event *ev);
|
||||
void SetTarget(Entity* ent);
|
||||
void OnInitialize(Event *ev);
|
||||
void TurnOff(Event *ev);
|
||||
void TurnOn(Event *ev);
|
||||
bool ShouldTargetRandom() const;
|
||||
Entity* ChooseTarget();
|
||||
|
||||
void GetLocalTargets();
|
||||
bool ShouldTargetPlayer() const;
|
||||
Vector GetTargetPos(Entity *target);
|
||||
void GetMuzzlePos(Vector& pos);
|
||||
void Fire();
|
||||
void TryLaunchSound();
|
||||
void SetWeaponAnim(const char* name, Event* ev);
|
||||
void EventAccuracy(Event *ev);
|
||||
void EventMaxDelay(Event *ev);
|
||||
void EventMinDelay(Event *ev);
|
||||
void EventFireOnStartUp(Event *ev);
|
||||
void EventMaxNumShots(Event *ev);
|
||||
void EventMinNumShots(Event *ev);
|
||||
void EventCycles(Event *ev);
|
||||
void EventMaxDuration(Event *ev);
|
||||
void EventMinDuration(Event *ev);
|
||||
void SetWeaponModel(Event *ev);
|
||||
void EventSetId(Event* ev);
|
||||
void EventmaxDonut(Event* ev);
|
||||
void EventminDonut(Event* ev);
|
||||
void EventarcDonut(Event* ev);
|
||||
void EventisDonut(Event* ev);
|
||||
virtual bool Attack(int count);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ProjectileGenerator_Projectile : public ProjectileGenerator
|
||||
{
|
||||
private:
|
||||
str m_sProjectileModel;
|
||||
str m_sPreImpactSound;
|
||||
float m_fImpactSoundTime;
|
||||
float m_fImpactSoundProbability;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileGenerator_Projectile);
|
||||
|
||||
ProjectileGenerator_Projectile();
|
||||
|
||||
void SetPreImpactSoundProbability(Event *ev);
|
||||
void SetPreImpactSoundTime(Event *ev);
|
||||
void SetPreImpactSound(Event *ev);
|
||||
void PlayPreImpactSound(Event *ev);
|
||||
void SetProjectileModel(Event *ev);
|
||||
|
||||
float EstimateImpactTime(const Vector& targetOrigin, const Vector& fromOrigin, float speed) const;
|
||||
bool Attack(int count) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ProjectileGenerator_Gun : public ProjectileGenerator
|
||||
{
|
||||
private:
|
||||
float m_fBulletRange;
|
||||
float m_fBulletDamage;
|
||||
int m_iBulletCount;
|
||||
Vector m_vBulletSpread;
|
||||
int m_iTracerFrequency;
|
||||
int m_iBulletLarge;
|
||||
qboolean m_bFakeBullets;
|
||||
int m_iMeansOfDeath;
|
||||
float m_fBulletThroughWood;
|
||||
float m_fBulletThroughMetal;
|
||||
float m_iBulletKnockback;
|
||||
int m_iAttackCount;
|
||||
float m_fFireDelay;
|
||||
float m_fTracerSpeed;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileGenerator_Gun);
|
||||
|
||||
ProjectileGenerator_Gun();
|
||||
|
||||
void SetFireDelay(Event *ev);
|
||||
void SetMeansOfDeath(Event *ev);
|
||||
void SetBulletThroughWood(Event *ev);
|
||||
void SetBulletThroughMetal(Event *ev);
|
||||
void SetBulletKnockback(Event *ev);
|
||||
void SetTracerSpeed(Event *ev);
|
||||
void SetBulletLarge(Event *ev);
|
||||
void SetFakeBullets(Event *ev);
|
||||
void SetBulletCount(Event *ev);
|
||||
void SetBulletDamage(Event *ev);
|
||||
void SetTracerFrequency(Event *ev);
|
||||
void SetBulletSpread(Event *ev);
|
||||
void SetBulletRange(Event *ev);
|
||||
|
||||
bool Attack(int count) override;
|
||||
bool TickWeaponAnim();
|
||||
void TickCycle(Event *ev) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ProjectileGenerator_Heavy : public ProjectileGenerator
|
||||
{
|
||||
private:
|
||||
str m_sProjectileModel;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileGenerator_Heavy);
|
||||
|
||||
ProjectileGenerator_Heavy();
|
||||
|
||||
void SetProjectileModel(Event *ev);
|
||||
|
||||
bool Attack(int count) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ThrobbingBox_Explosive : public Animate
|
||||
{
|
||||
protected:
|
||||
str m_sUsedModel;
|
||||
str m_sSound;
|
||||
bool m_bUsed;
|
||||
float m_fExplosionDamage;
|
||||
float m_fRadius;
|
||||
float m_fStopwatchDuration;
|
||||
str m_sActivateSound;
|
||||
str m_sTickSound;
|
||||
str m_sDestroyedModel;
|
||||
ScriptThreadLabel m_thread;
|
||||
ScriptThreadLabel m_useThread;
|
||||
str m_sEffect;
|
||||
Vector m_vOffset;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_Explosive);
|
||||
|
||||
ThrobbingBox_Explosive();
|
||||
|
||||
bool ShouldDoExplosion();
|
||||
|
||||
void SetExplosionOffset(Event *ev);
|
||||
void SetExplosionEffect(Event *ev);
|
||||
void SetTriggered(Event *ev);
|
||||
void DoExplosion(Event *ev);
|
||||
void SetUseThread(Event *ev);
|
||||
void SetThread(Event *ev);
|
||||
void SetStopWatchDuration(Event *ev);
|
||||
void SetRadius(Event *ev);
|
||||
void SetDamage(Event *ev);
|
||||
void TickSound(Event *ev);
|
||||
void ActivateSound(Event *ev);
|
||||
void ExplosionSound(Event *ev);
|
||||
void UsedModel(Event *ev);
|
||||
void SetDestroyModel(Event *ev);
|
||||
void OnBlowUp(Event *ev);
|
||||
void OnUse(Event *ev);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodePlayerFlak88 : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodePlayerFlak88);
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodeFlak88 : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodeFlak88);
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodeNebelwerfer : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodeNebelwerfer);
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodePlayerNebelwerfer : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodePlayerNebelwerfer);
|
||||
};
|
||||
|
||||
#define TBE_SPAWNFLAG_DESTROYED_MODEL 1
|
||||
#define TBE_SPAWNFLAG_MAKE_WET 2
|
||||
|
||||
class ThrobbingBox_Stickybomb : public ThrobbingBox_Explosive
|
||||
{
|
||||
private:
|
||||
float m_fStopwatchStartTime;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_Stickybomb);
|
||||
|
||||
void OnStickyBombWet(Event *ev);
|
||||
void OnStickyBombUse(Event *ev);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
#define OBJECTIVE_SPAWNFLAG_TURN_ON 1
|
||||
|
||||
class Objective : public Entity
|
||||
{
|
||||
private:
|
||||
str m_sText;
|
||||
int m_iObjectiveIndex;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(Objective);
|
||||
|
||||
Objective();
|
||||
|
||||
void Archive(Archiver &arc) override;
|
||||
void TurnOn(Event *ev);
|
||||
void TurnOff(Event *ev);
|
||||
void Complete(Event *ev);
|
||||
void SetCurrent(Event *ev);
|
||||
Vector GetOrigin() const;
|
||||
void SetObjectiveNbr(Event *ev);
|
||||
void SetText(Event *ev);
|
||||
int GetObjectiveIndex() const;
|
||||
};
|
||||
|
||||
class FencePost : public Entity
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(FencePost);
|
||||
};
|
||||
|
||||
class AISpawnPoint : public SimpleArchivedEntity
|
||||
{
|
||||
private:
|
||||
str m_sModel;
|
||||
int m_iHealth;
|
||||
str m_sEnemyName;
|
||||
float m_iAccuracy;
|
||||
int m_iAmmoGrenade;
|
||||
float m_iBalconyHeight;
|
||||
int m_iDisguiseLevel;
|
||||
float m_fDisguisePeriod;
|
||||
float m_fDisguiseRange;
|
||||
float m_fEnemyShareRange;
|
||||
float m_fFixedLeash;
|
||||
float m_fGrenadeAwareness;
|
||||
str m_sGun;
|
||||
float m_fMaxNoticeTimeScale;
|
||||
float m_fSoundAwareness;
|
||||
str m_sTypeAttack;
|
||||
str m_sTypeDisguise;
|
||||
str m_sTypeGrenade;
|
||||
str m_sTypeIdle;
|
||||
bool m_bPatrolWaitTrigger;
|
||||
float m_fHearing;
|
||||
float m_fSight;
|
||||
float m_fFov;
|
||||
float m_fLeash;
|
||||
float m_fMinDist;
|
||||
float m_fMaxDist;
|
||||
float m_fInterval;
|
||||
bool m_bDontDropWeapons;
|
||||
bool m_bDontDropHealth;
|
||||
str m_sFavoriteEnemy;
|
||||
bool m_bNoSurprise;
|
||||
str m_sPatrolPath;
|
||||
str m_sTurret;
|
||||
str m_sAlarmNode;
|
||||
str m_sWeapon;
|
||||
str m_sTarget;
|
||||
str m_sVoiceType;
|
||||
bool m_bForceDropWeapon;
|
||||
bool m_bForceDropHealth;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(AISpawnPoint);
|
||||
|
||||
AISpawnPoint();
|
||||
|
||||
void GetForceDropHealth(Event *ev);
|
||||
void SetForceDropHealth(Event *ev);
|
||||
void GetForceDropWeapon(Event *ev);
|
||||
void SetForceDropWeapon(Event *ev);
|
||||
void GetVoiceType(Event *ev);
|
||||
void SetVoiceType(Event *ev);
|
||||
void GetTarget(Event *ev);
|
||||
void SetTarget(Event *ev);
|
||||
void GetWeapon(Event *ev);
|
||||
void SetWeapon(Event *ev);
|
||||
void GetAlarmNode(Event *ev);
|
||||
void SetAlarmNode(Event *ev);
|
||||
void GetTurret(Event *ev);
|
||||
void SetTurret(Event *ev);
|
||||
void GetPatrolPath(Event *ev);
|
||||
void SetPatrolPath(Event *ev);
|
||||
void GetNoSurprise(Event *ev);
|
||||
void SetNoSurprise(Event *ev);
|
||||
void SetFavoriteEnemy(Event *ev);
|
||||
void GetFavoriteEnemy(Event *ev);
|
||||
void GetDontDropHealth(Event *ev);
|
||||
void SetDontDropHealth(Event *ev);
|
||||
void GetDontDropWeapons(Event *ev);
|
||||
void SetDontDropWeapons(Event *ev);
|
||||
void GetInterval(Event *ev);
|
||||
void SetInterval(Event *ev);
|
||||
void GetMaxDistance(Event *ev);
|
||||
void SetMaxDistance(Event *ev);
|
||||
void GetMinDistance(Event *ev);
|
||||
void SetMinDistance(Event *ev);
|
||||
void GetLeash(Event *ev);
|
||||
void SetLeash(Event *ev);
|
||||
void GetFov(Event *ev);
|
||||
void SetFov(Event *ev);
|
||||
void SetSight(Event *ev);
|
||||
void GetSight(Event *ev);
|
||||
void GetHearing(Event *ev);
|
||||
void SetHearing(Event *ev);
|
||||
void GetPatrolWaitTrigger(Event *ev);
|
||||
void SetPatrolWaitTrigger(Event *ev);
|
||||
void GetTypeIdle(Event *ev);
|
||||
void SetTypeIdle(Event *ev);
|
||||
void GetTypeGrenade(Event *ev);
|
||||
void SetTypeGrenade(Event *ev);
|
||||
void GetTypeDisguise(Event *ev);
|
||||
void SetTypeDisguise(Event *ev);
|
||||
void GetTypeAttack(Event *ev);
|
||||
void SetTypeAttack(Event *ev);
|
||||
void SetSoundAwareness(Event *ev);
|
||||
void GetSoundAwareness(Event *ev);
|
||||
void SetMaxNoticeTimeScale(Event *ev);
|
||||
void GetMaxNoticeTimeScale(Event *ev);
|
||||
void GetGun(Event *ev);
|
||||
void SetGun(Event *ev);
|
||||
void GetGrenadeAwareness(Event *ev);
|
||||
void SetGrenadeAwareness(Event *ev);
|
||||
void SetFixedLeash(Event *ev);
|
||||
void GetFixedLeash(Event *ev);
|
||||
void GetEnemyShareRange(Event *ev);
|
||||
void SetEnemyShareRange(Event *ev);
|
||||
void GetDisguiseRange(Event *ev);
|
||||
void SetDisguiseRange(Event *ev);
|
||||
void GetDisguisePeriod(Event *ev);
|
||||
void SetDisguisePeriod(Event *ev);
|
||||
void GetDisguiseLevel(Event *ev);
|
||||
void SetDisguiseLevel(Event *ev);
|
||||
void GetBalconyHeight(Event *ev);
|
||||
void SetBalconyHeight(Event *ev);
|
||||
void GetAmmoGrenade(Event *ev);
|
||||
void SetAmmoGrenade(Event *ev);
|
||||
void GetAccuracy(Event *ev);
|
||||
void SetAccuracy(Event *ev);
|
||||
void GetEnemyName(Event *ev);
|
||||
void SetEnemyName(Event *ev);
|
||||
void GetHealth(Event *ev);
|
||||
void SetHealth(Event *ev);
|
||||
void GetModel(Event *ev);
|
||||
void SetModel(Event *ev);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "Tow_Entities.h"
|
||||
#include "player.h"
|
||||
#include "scriptthread.h"
|
||||
|
||||
TOWObjectiveMan g_TOWObjectiveMan;
|
||||
|
||||
TOWObjectiveMan::TOWObjectiveMan()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void TOWObjectiveMan::Reset()
|
||||
{
|
||||
m_towObjectives.ClearObjectList();
|
||||
m_iNumAxisObjectives = 0;
|
||||
m_iNumAlliesObjectives = 0;
|
||||
}
|
||||
|
||||
void TOWObjectiveMan::AddObjective(TOWObjective *objective)
|
||||
{
|
||||
if (!objective) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (objective->GetController()) {
|
||||
case CONTROLLER_ALLIES:
|
||||
m_iNumAlliesObjectives++;
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
m_iNumAxisObjectives++;
|
||||
break;
|
||||
}
|
||||
|
||||
m_towObjectives.AddObject(objective);
|
||||
}
|
||||
|
||||
void TOWObjectiveMan::TakeOverObjective(eController controller, eController controllingTeam)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (controllingTeam == CONTROLLER_DRAW) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (controllingTeam) {
|
||||
case CONTROLLER_ALLIES:
|
||||
m_iNumAlliesObjectives++;
|
||||
if (m_iNumAxisObjectives) {
|
||||
m_iNumAxisObjectives--;
|
||||
}
|
||||
dmManager.CheckEndMatch();
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
m_iNumAxisObjectives++;
|
||||
if (m_iNumAlliesObjectives) {
|
||||
m_iNumAlliesObjectives--;
|
||||
}
|
||||
dmManager.CheckEndMatch();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < game.maxclients; i++) {
|
||||
gentity_t *ent = &g_entities[i];
|
||||
Player *player;
|
||||
bool bSameTeam;
|
||||
|
||||
if (!ent->inuse || !ent->entity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
player = static_cast<Player *>(ent->entity);
|
||||
|
||||
switch (controllingTeam) {
|
||||
case CONTROLLER_ALLIES:
|
||||
bSameTeam = player->GetTeam() == TEAM_ALLIES;
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
bSameTeam = player->GetTeam() == TEAM_AXIS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// play a different sound for the losing team
|
||||
if (bSameTeam) {
|
||||
player->PlayInstantMessageSound("success");
|
||||
} else {
|
||||
player->PlayInstantMessageSound("failure");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
/*QUAKED func_TOWObjective (1.0 0.0 1.0) (-12 -12 -12) (12 12 12) StartOn Respawner
|
||||
|
||||
This object is an extension of the standard objective object. It is used for Tug of War
|
||||
Maps.
|
||||
|
||||
object used to simplify placing objectives. You may optionally connect this object to the
|
||||
target you want to use for the compass position....
|
||||
|
||||
Checkboxes:
|
||||
StartOn - check this if you want this objective to be displayed when the level first loads
|
||||
|
||||
Respawner - check this if the objective is the respawn point for a team. If you set this
|
||||
you must set ControlledBy to a valid team and not Neutral.
|
||||
|
||||
|
||||
Parameters:
|
||||
ControlledBy 0 = Axis, 1 = Allies, 2 = Neutral
|
||||
AxisObjNum 1 - 5. Set the objective number for the axis. This will associate the objective with
|
||||
the check box for the corresponding text in the score screen.
|
||||
AlliesObjNum 1 - 5. Set the objective number for the allies. This will associate the objective with
|
||||
the check box for the corresponding text in the score screen.
|
||||
|
||||
ObjectiveNbr <nObjNbr=0> Please ignore this for now.
|
||||
|
||||
Events:
|
||||
TurnOn
|
||||
TurnOff
|
||||
Complete
|
||||
Text <sNewText>
|
||||
SetCurrent
|
||||
SetController <ControlledBy> - This will set the starting controller default is neutral. See ControlledBy var above.
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Event EV_SetController
|
||||
(
|
||||
"ControlledBy",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"ControlledBy",
|
||||
"Sets the team controlling the objective",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_TakeOver
|
||||
(
|
||||
"TakeOver",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"TeamNum",
|
||||
"Sets the team controlling the objective. 0 = Axis, 1 = Allies",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_SetAxisObjNum
|
||||
(
|
||||
"AxisObjNum",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"AxisObjNum",
|
||||
"Sets the objective number for the axis team",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_SetAlliesObjNum
|
||||
(
|
||||
"AlliesObjNum",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"AlliesObjNum",
|
||||
"Sets the objective number for the allies team",
|
||||
EV_NORMAL
|
||||
);
|
||||
static Event EV_Initialize
|
||||
(
|
||||
"initialize",
|
||||
EV_DEFAULT,
|
||||
0,
|
||||
0,
|
||||
"Initialize object",
|
||||
EV_NORMAL
|
||||
);
|
||||
static Event EV_SetCurrent
|
||||
(
|
||||
"SetCurrent",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"TeamNum",
|
||||
"Set this objective as the current objective for the specified team.",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_GetController
|
||||
(
|
||||
"ControlledBy",
|
||||
EV_DEFAULT,
|
||||
0,
|
||||
0,
|
||||
"Objective controller",
|
||||
EV_GETTER
|
||||
);
|
||||
|
||||
CLASS_DECLARATION(Objective, TOWObjective, "func_towobjective") {
|
||||
{&EV_SetController, &TOWObjective::SetController },
|
||||
{&EV_TakeOver, &TOWObjective::TakeOver },
|
||||
{&EV_SetAxisObjNum, &TOWObjective::SetAxisObjNum },
|
||||
{&EV_SetAlliesObjNum, &TOWObjective::SetAlliesObjNum},
|
||||
{&EV_Initialize, &TOWObjective::OnInitialize },
|
||||
{&EV_SetCurrent, &TOWObjective::SetCurrent },
|
||||
{&EV_GetController, &TOWObjective::GetController },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
TOWObjective::TOWObjective()
|
||||
{
|
||||
m_eController = CONTROLLER_DRAW;
|
||||
m_eLeadingController = CONTROLLER_DRAW;
|
||||
m_bNoRespawnForLeading = false;
|
||||
m_iAxisObjNum = 1;
|
||||
m_iAlliesObjNum = 1;
|
||||
m_sAxisObjName = "default";
|
||||
m_sAlliesObjName = "default";
|
||||
|
||||
if (spawnflags & TOWOBJECTIVE_SPAWNFLAG_NO_RESPAWN) {
|
||||
m_bNoRespawnForLeading = true;
|
||||
}
|
||||
|
||||
PostEvent(EV_Initialize, 0.001f);
|
||||
}
|
||||
|
||||
void TOWObjective::SetController(Event *ev)
|
||||
{
|
||||
m_eController = static_cast<eController>(ev->GetInteger(1));
|
||||
|
||||
if (m_bNoRespawnForLeading) {
|
||||
m_eLeadingController = m_eController;
|
||||
}
|
||||
|
||||
if (m_eController != CONTROLLER_ALLIES && m_eController != CONTROLLER_AXIS) {
|
||||
m_eController = CONTROLLER_DRAW;
|
||||
}
|
||||
}
|
||||
|
||||
void TOWObjective::GetController(Event *ev)
|
||||
{
|
||||
ev->AddInteger(m_eController);
|
||||
}
|
||||
|
||||
void TOWObjective::TakeOver(Event *ev)
|
||||
{
|
||||
eController controller = static_cast<eController>(ev->GetInteger(1));
|
||||
if (controller == m_eController || controller == CONTROLLER_DRAW) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_TOWObjectiveMan.TakeOverObjective(m_eController, controller);
|
||||
m_eController = controller;
|
||||
|
||||
if (m_bNoRespawnForLeading) {
|
||||
//
|
||||
// Disable team respawn for the leading team
|
||||
//
|
||||
dmManager.StopTeamRespawn(m_eLeadingController);
|
||||
}
|
||||
}
|
||||
|
||||
void TOWObjective::SetAlliesObjNum(Event *ev)
|
||||
{
|
||||
m_iAlliesObjNum = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void TOWObjective::SetAxisObjNum(Event *ev)
|
||||
{
|
||||
m_iAxisObjNum = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void TOWObjective::OnInitialize(Event *ev)
|
||||
{
|
||||
m_sAlliesObjName = "tow_allied_obj" + str(m_iAlliesObjNum);
|
||||
m_sAxisObjName = "tow_axis_obj" + str(m_iAxisObjNum);
|
||||
|
||||
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_DRAW:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "0");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!LoadingSavegame) {
|
||||
g_TOWObjectiveMan.AddObjective(this);
|
||||
}
|
||||
}
|
||||
|
||||
void TOWObjective::SetCurrent(Event *ev)
|
||||
{
|
||||
eController controller = static_cast<eController>(ev->GetInteger(1));
|
||||
switch (controller) {
|
||||
case CONTROLLER_ALLIES:
|
||||
ScriptThread::SetCurrentObjective(GetObjectiveIndex(), TEAM_ALLIES);
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
ScriptThread::SetCurrentObjective(GetObjectiveIndex(), TEAM_AXIS);
|
||||
break;
|
||||
default:
|
||||
SetCurrent(ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int TOWObjective::GetController() const
|
||||
{
|
||||
return m_eController;
|
||||
}
|
||||
|
||||
void TOWObjective::Archive(Archiver& arc)
|
||||
{
|
||||
arc.ArchiveInteger(&m_iAxisObjNum);
|
||||
arc.ArchiveInteger(&m_iAlliesObjNum);
|
||||
ArchiveEnum(m_eController, eController);
|
||||
ArchiveEnum(m_eLeadingController, eController);
|
||||
arc.ArchiveBool(&m_bNoRespawnForLeading);
|
||||
arc.ArchiveString(&m_sAxisObjName);
|
||||
arc.ArchiveString(&m_sAlliesObjName);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Entities.h"
|
||||
|
||||
#define TOWOBJECTIVE_SPAWNFLAG_NO_RESPAWN 2
|
||||
|
||||
class TOWObjective : public Objective
|
||||
{
|
||||
private:
|
||||
int m_iAxisObjNum;
|
||||
int m_iAlliesObjNum;
|
||||
eController m_eController;
|
||||
eController m_eLeadingController;
|
||||
bool m_bNoRespawnForLeading;
|
||||
str m_sAxisObjName;
|
||||
str m_sAlliesObjName;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(TOWObjective);
|
||||
|
||||
TOWObjective();
|
||||
|
||||
void SetController(Event *ev);
|
||||
void GetController(Event *ev);
|
||||
void TakeOver(Event *ev);
|
||||
void SetAlliesObjNum(Event *ev);
|
||||
void SetAxisObjNum(Event *ev);
|
||||
void OnInitialize(Event *ev);
|
||||
void SetCurrent(Event *ev);
|
||||
|
||||
int GetController() const;
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class TOWObjectiveMan
|
||||
{
|
||||
private:
|
||||
Container<TOWObjective *> m_towObjectives;
|
||||
int m_iNumAxisObjectives;
|
||||
int m_iNumAlliesObjectives;
|
||||
|
||||
public:
|
||||
TOWObjectiveMan();
|
||||
|
||||
void Reset();
|
||||
void AddObjective(TOWObjective *objective);
|
||||
void TakeOverObjective(eController controller, eController controllingTeam);
|
||||
};
|
||||
|
||||
extern TOWObjectiveMan g_TOWObjectiveMan;
|
||||
@@ -45,12 +45,11 @@ VehicleCollisionEntity::VehicleCollisionEntity
|
||||
m_pOwner = ent;
|
||||
takedamage = DAMAGE_YES;
|
||||
|
||||
edict->s.renderfx &= ~RF_DONTDRAW;
|
||||
edict->r.svFlags &= ~SVF_NOCLIENT;
|
||||
|
||||
showModel();
|
||||
setMoveType( MOVETYPE_PUSH );
|
||||
setSolidType(SOLID_NOT);
|
||||
|
||||
edict->clipmask |= MASK_CLIP;
|
||||
edict->clipmask |= MASK_VEHICLE;
|
||||
edict->s.eFlags |= EF_LINKANGLES;
|
||||
}
|
||||
|
||||
@@ -72,9 +71,7 @@ void VehicleCollisionEntity::EventDamage
|
||||
Event *ev
|
||||
)
|
||||
{
|
||||
Event *event = new Event( ev );
|
||||
|
||||
m_pOwner->ProcessEvent( event );
|
||||
m_pOwner->ProcessEvent(*ev);
|
||||
}
|
||||
|
||||
void VehicleCollisionEntity::Solid
|
||||
|
||||
+124
-96
@@ -28,131 +28,159 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
cVehicleSlot::cVehicleSlot()
|
||||
{
|
||||
prev_takedamage = ( damage_t )-1;
|
||||
prev_solid = ( solid_t )-1;
|
||||
prev_contents = -1;
|
||||
prev_takedamage = (damage_t)-1;
|
||||
prev_solid = (solid_t)-1;
|
||||
prev_contents = -1;
|
||||
}
|
||||
|
||||
void cVehicleSlot::NotSolid
|
||||
(
|
||||
void
|
||||
)
|
||||
void cVehicleSlot::NotSolid(void)
|
||||
{
|
||||
if( !( flags & FL_SWIM ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(flags & SLOT_BUSY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save previous values
|
||||
prev_takedamage = ent->takedamage;
|
||||
prev_solid = ent->edict->solid;
|
||||
prev_contents = ent->edict->r.contents;
|
||||
|
||||
ent->takedamage = DAMAGE_NO;
|
||||
ent->setSolidType( SOLID_NOT );
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save previous values
|
||||
prev_takedamage = ent->takedamage;
|
||||
prev_solid = ent->edict->solid;
|
||||
prev_contents = ent->edict->r.contents;
|
||||
|
||||
ent->takedamage = DAMAGE_NO;
|
||||
ent->setSolidType(SOLID_NOT);
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ent->IsSubclassOfPlayer()) {
|
||||
ent->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
|
||||
void cVehicleSlot::Solid
|
||||
(
|
||||
void
|
||||
)
|
||||
void cVehicleSlot::Solid(void)
|
||||
{
|
||||
if( !( flags & FL_SWIM ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(flags & FL_SWIM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Restore previous values
|
||||
ent->takedamage = prev_takedamage;
|
||||
ent->setSolidType( prev_solid );
|
||||
ent->edict->r.contents = prev_contents;
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save previous values
|
||||
prev_takedamage = ( damage_t )-1;
|
||||
prev_solid = ( solid_t )-1;
|
||||
prev_contents = -1;
|
||||
// Restore previous values
|
||||
ent->takedamage = prev_takedamage;
|
||||
ent->setSolidType(prev_solid);
|
||||
ent->setContents(prev_contents);
|
||||
|
||||
// Save previous values
|
||||
prev_takedamage = (damage_t)-1;
|
||||
prev_solid = (solid_t)-1;
|
||||
prev_contents = -1;
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_BBOX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cTurretSlot::cTurretSlot()
|
||||
{
|
||||
owner_prev_takedamage = ( damage_t )-1;
|
||||
owner_prev_solid = ( solid_t )-1;
|
||||
owner_prev_contents = -1;
|
||||
owner_prev_takedamage = (damage_t)-1;
|
||||
owner_prev_solid = (solid_t)-1;
|
||||
owner_prev_contents = -1;
|
||||
}
|
||||
|
||||
void cTurretSlot::NotSolid
|
||||
(
|
||||
void
|
||||
)
|
||||
void cTurretSlot::NotSolid(void)
|
||||
{
|
||||
if( !( flags & FL_SWIM ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(flags & FL_SWIM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
cVehicleSlot::NotSolid();
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( ent->IsSubclassOfTurretGun() )
|
||||
{
|
||||
TurretGun *turret = ( TurretGun * )ent.Pointer();
|
||||
Entity *owner = turret->GetOwner();
|
||||
// Save previous values
|
||||
prev_takedamage = ent->takedamage;
|
||||
prev_solid = ent->edict->solid;
|
||||
prev_contents = ent->edict->r.contents;
|
||||
|
||||
if( owner )
|
||||
{
|
||||
owner_prev_takedamage = owner->takedamage;
|
||||
owner_prev_solid = owner->edict->solid;
|
||||
owner_prev_contents = owner->edict->r.contents;
|
||||
ent->takedamage = DAMAGE_NO;
|
||||
ent->setSolidType(SOLID_NOT);
|
||||
|
||||
owner->takedamage = DAMAGE_NO;
|
||||
owner->setSolidType( SOLID_NOT );
|
||||
}
|
||||
}
|
||||
if (ent->IsSubclassOfTurretGun()) {
|
||||
TurretGun *turret = static_cast<TurretGun *>(ent.Pointer());
|
||||
Entity *owner = turret->GetOwner();
|
||||
|
||||
if (owner) {
|
||||
owner_prev_takedamage = owner->takedamage;
|
||||
owner_prev_solid = owner->edict->solid;
|
||||
owner_prev_contents = owner->edict->r.contents;
|
||||
|
||||
owner->takedamage = DAMAGE_NO;
|
||||
owner->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cTurretSlot::Solid
|
||||
(
|
||||
void
|
||||
)
|
||||
void cTurretSlot::Solid(void)
|
||||
{
|
||||
if( !( flags & FL_SWIM ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(flags & FL_SWIM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
cVehicleSlot::NotSolid();
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( ent->IsSubclassOfTurretGun() )
|
||||
{
|
||||
TurretGun *turret = ( TurretGun * )ent.Pointer();
|
||||
Entity *owner = turret->GetOwner();
|
||||
// Restore previous values
|
||||
ent->takedamage = prev_takedamage;
|
||||
ent->setSolidType(prev_solid);
|
||||
|
||||
if( owner )
|
||||
{
|
||||
owner->takedamage = owner_prev_takedamage;
|
||||
owner->setSolidType( owner_prev_solid );
|
||||
// Save previous values
|
||||
prev_takedamage = (damage_t)-1;
|
||||
prev_solid = (solid_t)-1;
|
||||
|
||||
owner_prev_takedamage = ( damage_t )-1;
|
||||
owner_prev_solid = ( solid_t )-1;
|
||||
}
|
||||
}
|
||||
if (ent->IsSubclassOfTurretGun()) {
|
||||
TurretGun *turret = static_cast<TurretGun *>(ent.Pointer());
|
||||
Entity *owner = turret->GetOwner();
|
||||
|
||||
if (owner) {
|
||||
owner->takedamage = owner_prev_takedamage;
|
||||
owner->setSolidType(owner_prev_solid);
|
||||
|
||||
owner_prev_takedamage = (damage_t)-1;
|
||||
owner_prev_solid = (solid_t)-1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ent->numchildren; i++) {
|
||||
Entity *sub = G_GetEntity(ent->children[i]);
|
||||
if (sub && !sub->IsSubclassOfWeapon()) {
|
||||
sub->setSolidType(SOLID_BBOX);
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
-50
@@ -23,78 +23,69 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// VehicleSlot.h
|
||||
//
|
||||
|
||||
#ifndef __VEHICLESLOT_H__
|
||||
#define __VEHICLESLOT_H__
|
||||
#pragma once
|
||||
|
||||
#include "g_local.h"
|
||||
#include "class.h"
|
||||
#include "entity.h"
|
||||
|
||||
#define SLOT_FREE 1
|
||||
#define SLOT_BUSY 2
|
||||
#define SLOT_UNUSED 4
|
||||
#define SLOT_FREE 1
|
||||
#define SLOT_BUSY 2
|
||||
#define SLOT_UNUSED 4
|
||||
|
||||
class cVehicleSlot : public Class {
|
||||
class cVehicleSlot : public Class
|
||||
{
|
||||
public:
|
||||
SafePtr<Entity> ent;
|
||||
int flags;
|
||||
int boneindex;
|
||||
int enter_boneindex;
|
||||
SafePtr<Entity> ent;
|
||||
int flags;
|
||||
int boneindex;
|
||||
int enter_boneindex;
|
||||
|
||||
private:
|
||||
damage_t prev_takedamage;
|
||||
solid_t prev_solid;
|
||||
int prev_contents;
|
||||
protected:
|
||||
damage_t prev_takedamage;
|
||||
solid_t prev_solid;
|
||||
int prev_contents;
|
||||
|
||||
public:
|
||||
cVehicleSlot();
|
||||
cVehicleSlot();
|
||||
|
||||
virtual void NotSolid( void );
|
||||
virtual void Solid( void );
|
||||
void Archive( Archiver& arc ) override;
|
||||
virtual void NotSolid(void);
|
||||
virtual void Solid(void);
|
||||
void Archive(Archiver &arc) override;
|
||||
};
|
||||
|
||||
inline
|
||||
void cVehicleSlot::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline void cVehicleSlot::Archive(Archiver& arc)
|
||||
{
|
||||
Class::Archive( arc );
|
||||
Class::Archive(arc);
|
||||
|
||||
arc.ArchiveSafePointer( &ent );
|
||||
arc.ArchiveInteger( &flags );
|
||||
arc.ArchiveInteger( &boneindex );
|
||||
arc.ArchiveInteger( &enter_boneindex );
|
||||
ArchiveEnum( prev_takedamage, damage_t );
|
||||
ArchiveEnum( prev_solid, solid_t );
|
||||
arc.ArchiveInteger( &prev_contents );
|
||||
arc.ArchiveSafePointer(&ent);
|
||||
arc.ArchiveInteger(&flags);
|
||||
arc.ArchiveInteger(&boneindex);
|
||||
arc.ArchiveInteger(&enter_boneindex);
|
||||
ArchiveEnum(prev_takedamage, damage_t);
|
||||
ArchiveEnum(prev_solid, solid_t);
|
||||
arc.ArchiveInteger(&prev_contents);
|
||||
}
|
||||
|
||||
class cTurretSlot : public cVehicleSlot {
|
||||
damage_t owner_prev_takedamage;
|
||||
solid_t owner_prev_solid;
|
||||
int owner_prev_contents;
|
||||
class cTurretSlot : public cVehicleSlot
|
||||
{
|
||||
damage_t owner_prev_takedamage;
|
||||
solid_t owner_prev_solid;
|
||||
int owner_prev_contents;
|
||||
|
||||
public:
|
||||
cTurretSlot();
|
||||
cTurretSlot();
|
||||
|
||||
void NotSolid( void ) override;
|
||||
void Solid( void ) override;
|
||||
void Archive( Archiver& arc ) override;
|
||||
void NotSolid(void) override;
|
||||
void Solid(void) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
inline
|
||||
void cTurretSlot::Archive
|
||||
(
|
||||
Archiver& arc
|
||||
)
|
||||
inline void cTurretSlot::Archive(Archiver& arc)
|
||||
{
|
||||
cVehicleSlot::Archive( arc );
|
||||
cVehicleSlot::Archive(arc);
|
||||
|
||||
ArchiveEnum( owner_prev_takedamage, damage_t );
|
||||
ArchiveEnum( owner_prev_solid, solid_t );
|
||||
arc.ArchiveInteger( &owner_prev_contents );
|
||||
ArchiveEnum(owner_prev_takedamage, damage_t);
|
||||
ArchiveEnum(owner_prev_solid, solid_t);
|
||||
arc.ArchiveInteger(&owner_prev_contents);
|
||||
}
|
||||
|
||||
#endif // __VEHICLESLOT_H__
|
||||
+494
-74
@@ -23,127 +23,547 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "vehicle.h"
|
||||
#include "vehicleturret.h"
|
||||
#include "player.h"
|
||||
#include "g_phys.h"
|
||||
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleTank, "VehicleTank")
|
||||
{
|
||||
{ &EV_Damage, &VehicleTank::EventDamage },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(DrivableVehicle, VehicleTank, "VehicleTank") {
|
||||
{&EV_Damage, &VehicleTank::EventDamage},
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
VehicleTank::VehicleTank()
|
||||
{
|
||||
entflags |= FL_ROTATEDBOUNDS;
|
||||
entflags |= FL_ROTATEDBOUNDS;
|
||||
}
|
||||
|
||||
VehicleTank::~VehicleTank()
|
||||
{
|
||||
entflags &= ~FL_ROTATEDBOUNDS;
|
||||
entflags &= ~FL_ROTATEDBOUNDS;
|
||||
}
|
||||
|
||||
qboolean VehicleTank::Drive(usercmd_t *ucmd)
|
||||
{
|
||||
Vector i;
|
||||
Vector j;
|
||||
Vector k;
|
||||
Vector vTmp;
|
||||
Vector i;
|
||||
Vector j;
|
||||
Vector k;
|
||||
Vector vTmp;
|
||||
|
||||
vTmp = velocity;
|
||||
VectorNormalize(vTmp);
|
||||
vTmp = velocity;
|
||||
vTmp.normalize();
|
||||
|
||||
if (!driver.ent || !driver.ent->client)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
if (!driver.ent || !driver.ent->isClient()) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!drivable)
|
||||
{
|
||||
driver.ent->client->ps.pm_flags |= PMF_FROZEN;
|
||||
ucmd->forwardmove = 0;
|
||||
ucmd->rightmove = 0;
|
||||
ucmd->upmove = 0;
|
||||
return qfalse;
|
||||
}
|
||||
if (!drivable) {
|
||||
driver.ent->client->ps.pm_flags |= PMF_FROZEN;
|
||||
ucmd->forwardmove = 0;
|
||||
ucmd->rightmove = 0;
|
||||
ucmd->upmove = 0;
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
moveimpulse = ucmd->forwardmove * (vTmp.length() + 1.0);
|
||||
|
||||
m_bIsBraking = ucmd->forwardmove >> 31;
|
||||
if (!m_bAutoPilot) {
|
||||
//
|
||||
// ignore client's control if the vehicle is in auto-pilot mode
|
||||
//
|
||||
moveimpulse = ucmd->forwardmove * (vTmp.length() + 1.0);
|
||||
m_bIsBraking = ucmd->forwardmove < 0;
|
||||
m_fAccelerator += ucmd->forwardmove * 0.005;
|
||||
// acceleration must be an alpha value between [0, 1]
|
||||
m_fAccelerator = Q_clamp_float(m_fAccelerator, 0, 1);
|
||||
|
||||
m_fAccelerator += ucmd->forwardmove * 0.005;
|
||||
turnimpulse = -ucmd->rightmove;
|
||||
jumpimpulse = ucmd->upmove;
|
||||
}
|
||||
|
||||
if (m_fAccelerator < 0)
|
||||
{
|
||||
m_fAccelerator = 0.0;
|
||||
}
|
||||
VehicleTurretGun *vtg = (VehicleTurretGun *)Turrets[0].ent.Pointer();
|
||||
|
||||
turnimpulse = -ucmd->rightmove;
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient()) {
|
||||
vtg->RemoteControl(ucmd, (Sentient *)driver.ent.Pointer());
|
||||
|
||||
VehicleTurretGun *vtg = (VehicleTurretGun *)Turrets[0].ent.Pointer();
|
||||
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient())
|
||||
{
|
||||
vtg->RemoteControl(ucmd, (Sentient *)driver.ent.Pointer());
|
||||
|
||||
if (ucmd->upmove)
|
||||
turnimpulse -= AngleSubtract(angles[1], vtg->angles[1]);
|
||||
}
|
||||
return qtrue;
|
||||
if (ucmd->upmove) {
|
||||
turnimpulse -= AngleSubtract(angles[1], vtg->angles[1]);
|
||||
}
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
void VehicleTank::EventDamage(Event *ev)
|
||||
{
|
||||
int mod;
|
||||
mod = ev->GetInteger(9);
|
||||
int mod;
|
||||
mod = ev->GetInteger(9);
|
||||
|
||||
if (mod > MOD_VEHICLE && mod != MOD_SHOTGUN && mod != MOD_GRENADE)
|
||||
{
|
||||
Vehicle::EventDamage(ev);
|
||||
if (g_gametype->integer == GT_SINGLE_PLAYER)
|
||||
{
|
||||
Player *p = (Player *)driver.ent.Pointer();
|
||||
if (p)
|
||||
{
|
||||
if (p->IsSubclassOfPlayer())
|
||||
{
|
||||
p->m_iNumHitsTaken++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (g_gametype->integer == GT_TOW && !dmManager.RoundActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mod) {
|
||||
case MOD_BULLET:
|
||||
case MOD_BASH:
|
||||
case MOD_FAST_BULLET:
|
||||
case MOD_VEHICLE:
|
||||
case MOD_SHOTGUN:
|
||||
case MOD_GRENADE:
|
||||
return;
|
||||
}
|
||||
|
||||
Vehicle::EventDamage(ev);
|
||||
|
||||
if (g_gametype->integer == GT_SINGLE_PLAYER) {
|
||||
Player *p = (Player *)driver.ent.Pointer();
|
||||
if (p) {
|
||||
if (p->IsSubclassOfPlayer()) {
|
||||
p->m_iNumHitsTaken++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::Think()
|
||||
{
|
||||
flags |= FL_POSTTHINK;
|
||||
flags |= FL_POSTTHINK;
|
||||
}
|
||||
|
||||
void VehicleTank::Postthink()
|
||||
{
|
||||
// FIXME: STUB
|
||||
float turn;
|
||||
Vector i, j, k;
|
||||
Vector normalsum;
|
||||
Vector temp;
|
||||
Vector pitch, roll;
|
||||
Vector acceleration;
|
||||
Vector atmp, atmp2, aup;
|
||||
VehicleBase *v, *last;
|
||||
float drivespeed;
|
||||
Vector primal_angles, primal_origin;
|
||||
Vector vTmp;
|
||||
Vector vAddedAngles;
|
||||
Vector n_angles;
|
||||
float dot;
|
||||
Vector newvel, flatvel;
|
||||
Vector anglediff;
|
||||
|
||||
primal_angles = angles;
|
||||
primal_origin = origin;
|
||||
|
||||
if (!g_vehicle->integer || edict->s.renderfx & RF_DONTDRAW) {
|
||||
// don't process physics
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pCollisionEntity) {
|
||||
// use the collision entity for collision
|
||||
setSolidType(SOLID_NOT);
|
||||
m_pCollisionEntity->Solid();
|
||||
}
|
||||
|
||||
prev_velocity = velocity;
|
||||
SetSlotsNonSolid();
|
||||
|
||||
if (m_bAnimMove) {
|
||||
AnimMoveVehicle();
|
||||
} else {
|
||||
if (!m_bMovementLocked) {
|
||||
FactorOutAnglesOffset();
|
||||
FactorOutOriginOffset();
|
||||
}
|
||||
|
||||
MoveVehicle();
|
||||
}
|
||||
|
||||
SetSlotsSolid();
|
||||
|
||||
if (m_vOldMins != vec_zero && m_vOldMaxs != vec_zero) {
|
||||
mins = m_vOldMins;
|
||||
maxs = m_vOldMaxs;
|
||||
} else if (mins != vec_zero && maxs != vec_zero) {
|
||||
m_vOldMins = mins;
|
||||
m_vOldMaxs = maxs;
|
||||
}
|
||||
|
||||
if (m_bAnimMove) {
|
||||
moveimpulse = velocity.length() * level.frametime;
|
||||
turnimpulse = avelocity[1] * level.frametime;
|
||||
} else if (m_bAutoPilot) {
|
||||
AutoPilot();
|
||||
}
|
||||
|
||||
currentspeed = moveimpulse;
|
||||
turnangle = turnangle * 0.25 + turnimpulse;
|
||||
turnangle = Q_clamp_float(turnangle, -maxturnrate, maxturnrate);
|
||||
|
||||
real_velocity = origin - prev_origin;
|
||||
prev_origin = origin;
|
||||
prev_acceleration = real_acceleration;
|
||||
real_acceleration = real_velocity - prev_velocity;
|
||||
prev_velocity = real_velocity;
|
||||
acceleration = real_acceleration - prev_acceleration;
|
||||
|
||||
UpdateBones();
|
||||
UpdateShaderOffset();
|
||||
UpdateTires();
|
||||
UpdateNormals();
|
||||
|
||||
temp = angles;
|
||||
temp.AngleVectorsLeft(&i, &j, &k);
|
||||
|
||||
velocity[0] *= 0.925f;
|
||||
velocity[1] *= 0.925f;
|
||||
turn = turnangle / 200.0;
|
||||
|
||||
flatvel = orientation[0];
|
||||
velocity += flatvel * currentspeed;
|
||||
flatvel[2] = 0;
|
||||
|
||||
dot = velocity * flatvel;
|
||||
dot = Q_clamp_float(dot, -speed, speed);
|
||||
newvel = flatvel * dot;
|
||||
velocity[0] = newvel[0];
|
||||
velocity[1] = newvel[1];
|
||||
avelocity *= 0.05f;
|
||||
if (dot < 350) {
|
||||
dot = 350;
|
||||
}
|
||||
|
||||
avelocity.y += turn * dot;
|
||||
angles += avelocity * level.frametime;
|
||||
setAngles(angles);
|
||||
|
||||
if (Turrets[0].ent && Turrets[0].ent->IsSubclassOfVehicleTurretGun() && driver.ent
|
||||
&& driver.ent->IsSubclassOfSentient()) {
|
||||
VehicleTurretGun *pTurret = static_cast<VehicleTurretGun *>(Turrets[0].ent.Pointer());
|
||||
if (jumpimpulse != 0) {
|
||||
pTurret->SetUserViewAngles(pTurret->GetUserViewAngles() - Vector(0, avelocity[1] * level.frametime, 0));
|
||||
}
|
||||
}
|
||||
|
||||
drivespeed = acceleration * orientation[0];
|
||||
UpdateSound();
|
||||
|
||||
if (AssertRotation(angles, primal_angles) != true) {
|
||||
angles = primal_angles;
|
||||
}
|
||||
|
||||
CalculateAnglesOffset(acceleration);
|
||||
CalculateOriginOffset();
|
||||
|
||||
last_origin = origin;
|
||||
anglediff = (angles - primal_angles) * level.frametime;
|
||||
|
||||
if (anglediff.x > 180 || anglediff.x < -180) anglediff.x = 0;
|
||||
if (anglediff.y > 180 || anglediff.y < -180) anglediff.y = 0;
|
||||
if (anglediff.z > 180 || anglediff.z < -180) anglediff.z = 0;
|
||||
|
||||
if (anglediff.x > -1 || anglediff.x < 1) anglediff.x = 0;
|
||||
if (anglediff.y > -1 || anglediff.y < 1) anglediff.y = 0;
|
||||
if (anglediff.z > -1 || anglediff.z < 1) anglediff.z = 0;
|
||||
|
||||
avelocity = anglediff;
|
||||
|
||||
if (!m_bAnimMove && !m_bMovementLocked) {
|
||||
FactorInOriginOffset();
|
||||
FactorInAnglesOffset(&vAddedAngles);
|
||||
}
|
||||
|
||||
CalculateAnimationData(vAddedAngles, m_vOriginOffset + m_vOriginOffset2);
|
||||
if (m_pCollisionEntity) {
|
||||
Vector vaDelta;
|
||||
|
||||
SetSlotsNonSolid();
|
||||
|
||||
vaDelta[0] = angledist(angles[0] - m_pCollisionEntity->angles[0]);
|
||||
vaDelta[1] = angledist(angles[1] - m_pCollisionEntity->angles[1]);
|
||||
vaDelta[2] = angledist(angles[2] - m_pCollisionEntity->angles[2]);
|
||||
|
||||
m_pCollisionEntity->Solid();
|
||||
|
||||
G_PushMove(m_pCollisionEntity, origin - primal_origin, vaDelta);
|
||||
G_TouchTriggers(m_pCollisionEntity);
|
||||
|
||||
SetSlotsSolid();
|
||||
|
||||
m_pCollisionEntity->setOrigin(origin);
|
||||
m_pCollisionEntity->setAngles(angles);
|
||||
}
|
||||
|
||||
SetupVehicleSoundEntities();
|
||||
i = orientation[0];
|
||||
j = orientation[1];
|
||||
k = orientation[2];
|
||||
|
||||
//
|
||||
// update slots
|
||||
//
|
||||
for (int ii = 0; ii < MAX_PASSENGERS; ii++) {
|
||||
UpdatePassengerSlot(ii);
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < MAX_TURRETS; ii++) {
|
||||
UpdateTurretSlot(ii);
|
||||
}
|
||||
|
||||
for (last = this; last->vlink; last = v) {
|
||||
v = last->vlink;
|
||||
|
||||
v->setOrigin(origin + i * v->offset.x + j * v->offset.y + k * v->offset.z);
|
||||
v->avelocity = avelocity;
|
||||
v->velocity = velocity;
|
||||
|
||||
v->angles[ROLL] = angles[ROLL];
|
||||
v->angles[YAW] = angles[YAW];
|
||||
v->angles[PITCH] = (int)(drivespeed / 4.f + v->angles[PITCH]) % 360;
|
||||
v->setAngles(v->angles);
|
||||
}
|
||||
|
||||
CheckWater();
|
||||
WorldEffects();
|
||||
|
||||
if (m_pCollisionEntity) {
|
||||
setSolidType(SOLID_NOT);
|
||||
m_pCollisionEntity->Solid();
|
||||
} else {
|
||||
setSolidType(SOLID_BBOX);
|
||||
setContents(CONTENTS_UNKNOWN2);
|
||||
}
|
||||
|
||||
if ((driver.flags & SLOT_BUSY) && driver.ent) {
|
||||
if (driver.ent->IsSubclassOfPlayer()) {
|
||||
driver.ent->takedamage = DAMAGE_YES;
|
||||
// Fixed in OPM.
|
||||
// It's probably a mistake in moh 2.0 and above,
|
||||
// the tank was non-solid with a player driver,
|
||||
// instead of the driver being non-solid.
|
||||
//setSolidType(SOLID_NOT);
|
||||
driver.ent->setSolidType(SOLID_NOT);
|
||||
} else {
|
||||
driver.ent->takedamage = DAMAGE_NO;
|
||||
driver.ent->setSolidType(SOLID_NOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::CalculateOriginOffset()
|
||||
{
|
||||
// FIXME: STUB
|
||||
int index;
|
||||
Vector vTireAvg;
|
||||
Vector vMissHit;
|
||||
Vector temp;
|
||||
int iNum = 0;
|
||||
Vector acceleration;
|
||||
Vector oldoffset;
|
||||
|
||||
oldoffset = m_vOriginOffset;
|
||||
m_vOriginOffset += m_vOriginOffset2;
|
||||
m_vOriginOffset2 = vec_zero;
|
||||
|
||||
for (index = 0; index < NUM_VEHICLE_TIRES; index++) {
|
||||
if (m_bTireHit[index]) {
|
||||
vTireAvg += origin - m_vTireEnd[index];
|
||||
iNum++;
|
||||
} else {
|
||||
vMissHit = Corners[index];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_iNumNormals > 0 && iNum == NUM_VEHICLE_TIRES - 1) {
|
||||
Vector point;
|
||||
|
||||
temp = m_vNormalSum * (1.f / m_iNumNormals);
|
||||
temp.normalize();
|
||||
ProjectPointOnPlane(point, vMissHit, temp);
|
||||
vTireAvg += point;
|
||||
|
||||
iNum++;
|
||||
}
|
||||
|
||||
if (iNum == NUM_VEHICLE_TIRES) {
|
||||
vec3_t vOriginCornerOffset;
|
||||
|
||||
vTireAvg *= 1.f / NUM_VEHICLE_TIRES;
|
||||
MatrixTransformVector(m_vOriginCornerOffset, orientation, vOriginCornerOffset);
|
||||
vTireAvg -= vOriginCornerOffset;
|
||||
m_vOriginOffset2 += vTireAvg;
|
||||
}
|
||||
|
||||
//m_vOriginOffset2 += vec_zero;
|
||||
m_vOriginOffset -= m_vOriginOffset2;
|
||||
|
||||
if (!isfinite(m_vOriginOffset[0]) || !isfinite(m_vOriginOffset[1]) || !isfinite(m_vOriginOffset[2])) {
|
||||
m_vOriginOffset = oldoffset;
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::UpdateSound()
|
||||
{
|
||||
// FIXME: STUB
|
||||
float pitch = 1.f;
|
||||
float volume = 1.f;
|
||||
|
||||
if (level.time < m_fNextSoundState) {
|
||||
return;
|
||||
}
|
||||
|
||||
pitch = (velocity.length() - m_fSoundMinSpeed) / (m_fSoundMaxSpeed - m_fSoundMinSpeed);
|
||||
pitch = Q_clamp_float(pitch, 0, 1);
|
||||
pitch = (m_fSoundMaxPitch - m_fSoundMinPitch) * pitch + m_fSoundMinPitch;
|
||||
|
||||
volume = (velocity.length() - m_fVolumeMinSpeed) / (m_fVolumeMaxSpeed - m_fVolumeMinSpeed);
|
||||
volume = Q_clamp_float(volume, 0, 1);
|
||||
volume = (m_fVolumeMaxPitch - m_fVolumeMinPitch) * volume + m_fVolumeMinPitch;
|
||||
|
||||
if (level.intermissiontime) {
|
||||
m_eSoundState = ST_OFF;
|
||||
}
|
||||
|
||||
switch (m_eSoundState) {
|
||||
case ST_OFF:
|
||||
StopLoopSound();
|
||||
TurnOffVehicleSoundEntities();
|
||||
m_fNextSoundState = level.time;
|
||||
if (driver.ent || m_bAutoPilot) {
|
||||
m_eSoundState = ST_OFF_TRANS_IDLE;
|
||||
}
|
||||
break;
|
||||
case ST_OFF_TRANS_IDLE:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_IDLE;
|
||||
Sound(m_sSoundSet + "snd_on", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_idle");
|
||||
break;
|
||||
case ST_IDLE_TRANS_OFF:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_OFF;
|
||||
Sound(m_sSoundSet + "snd_off", CHAN_AUTO);
|
||||
StopLoopSound();
|
||||
break;
|
||||
case ST_IDLE:
|
||||
m_fNextSoundState = level.time;
|
||||
if (driver.ent || m_bAutoPilot) {
|
||||
if (fabs(velocity * orientation[0]) > 150) {
|
||||
m_eSoundState = ST_IDLE_TRANS_RUN;
|
||||
} else if (fabs(turnimpulse) > 1) {
|
||||
m_eSoundState = ST_IDLE_TRANS_TURN;
|
||||
}
|
||||
} else {
|
||||
m_eSoundState = ST_IDLE_TRANS_OFF;
|
||||
}
|
||||
|
||||
LoopSound(m_sSoundSet + "snd_idle");
|
||||
TurnOffVehicleSoundEntities();
|
||||
break;
|
||||
case ST_IDLE_TRANS_RUN:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_RUN;
|
||||
Sound(m_sSoundSet + "snd_revup", CHAN_AUTO);
|
||||
Sound(m_sSoundSet + "snd_shift", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_run", volume, -1, -1, pitch);
|
||||
break;
|
||||
case ST_RUN:
|
||||
m_fNextSoundState = level.time;
|
||||
if (fabs(velocity * orientation[0]) < 150) {
|
||||
m_eSoundState = ST_RUN_TRANS_IDLE;
|
||||
}
|
||||
TurnOnVehicleSoundEntities();
|
||||
LoopSound(m_sSoundSet + "snd_run", volume, -1, -1, pitch);
|
||||
break;
|
||||
case ST_RUN_TRANS_IDLE:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_IDLE;
|
||||
Sound(m_sSoundSet + "snd_revdown", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_idle");
|
||||
break;
|
||||
case ST_IDLE_TRANS_TURN:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_TURN;
|
||||
Sound(m_sSoundSet + "snd_revup", CHAN_AUTO);
|
||||
Sound(m_sSoundSet + "snd_shift", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_run", volume, -1, -1, pitch);
|
||||
break;
|
||||
case ST_TURN:
|
||||
m_fNextSoundState = level.time;
|
||||
if (fabs(turnimpulse) < 1) {
|
||||
m_eSoundState = ST_TURN_TRANS_IDLE;
|
||||
}
|
||||
LoopSound(m_sSoundSet + "snd_run", volume, -1, -1, pitch);
|
||||
break;
|
||||
case ST_TURN_TRANS_IDLE:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_IDLE;
|
||||
Sound(m_sSoundSet + "snd_revdown", CHAN_AUTO);
|
||||
LoopSound(m_sSoundSet + "snd_idle");
|
||||
break;
|
||||
default:
|
||||
m_fNextSoundState = level.time;
|
||||
m_eSoundState = ST_OFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::AttachDriverSlot(Event* ev)
|
||||
//
|
||||
// Fixed in OPM:
|
||||
// This method only work when called from script.
|
||||
// But it is not called automatically when the player actually uses the vehicle
|
||||
// when that vehicle is unlocked.
|
||||
// So the other native method is overriden instead
|
||||
/*
|
||||
void VehicleTank::AttachDriverSlot(Event *ev)
|
||||
{
|
||||
Vehicle::AttachDriverSlot(ev);
|
||||
Vehicle::AttachDriverSlot(ev);
|
||||
|
||||
VehicleTurretGun *vtg = (VehicleTurretGun *)Turrets[0].ent.Pointer();
|
||||
if (!driver.ent) {
|
||||
//
|
||||
// Added in OPM.
|
||||
// original mohaa doesn't check if driver.ent is valid, which can cause crash if the attached entity is null.
|
||||
// on single-player, it would crash while loading m5l2a when sv_maxclients is above 1.
|
||||
// The reason of the crash is that attachdriverslot is called with $player which can be NULL on prespawn.
|
||||
// $player is not created on prespawn when sv_maxclients is above 1
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient())
|
||||
{
|
||||
vtg->SetOwner((Sentient *)driver.ent.Pointer());
|
||||
Think();
|
||||
Postthink();
|
||||
vtg->Think();
|
||||
}
|
||||
VehicleTurretGun *vtg = (VehicleTurretGun *)Turrets[0].ent.Pointer();
|
||||
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient()) {
|
||||
vtg->SetRemoteOwner(static_cast<Sentient *>(driver.ent.Pointer()));
|
||||
Think();
|
||||
Postthink();
|
||||
vtg->Think();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void VehicleTank::AttachDriverSlot(int slot, Entity* ent, Vector vExitPosition)
|
||||
{
|
||||
Vehicle::AttachDriverSlot(slot, ent, vExitPosition);
|
||||
|
||||
if (!driver.ent) {
|
||||
//
|
||||
// Added in OPM.
|
||||
// original mohaa doesn't check if driver.ent is valid, which can cause crash if the attached entity is null.
|
||||
// on single-player, it would crash while loading m5l2a when sv_maxclients is above 1.
|
||||
// The reason of the crash is that attachdriverslot is called with $player which can be NULL on prespawn.
|
||||
// $player is not created on prespawn when sv_maxclients is above 1
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
VehicleTurretGun* vtg = static_cast<VehicleTurretGun*>(Turrets[0].ent.Pointer());
|
||||
|
||||
if (vtg && vtg->IsSubclassOfVehicleTurretGun() && driver.ent->IsSubclassOfSentient()) {
|
||||
vtg->SetRemoteOwner(static_cast<Sentient*>(driver.ent.Pointer()));
|
||||
Think();
|
||||
Postthink();
|
||||
vtg->Think();
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTank::DriverAdded()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_TURRETS; i++) {
|
||||
if (Turrets[i].flags & SLOT_BUSY && Turrets[i].ent && Turrets[i].ent->IsSubclassOfVehicleTurretGun()) {
|
||||
VehicleTurretGun *pTurret = static_cast<VehicleTurretGun *>(Turrets[i].ent.Pointer());
|
||||
pTurret->TurretHasBeenMounted();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 577 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user