1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4 Copyright (C) 2000-2006 Tim Angus
5
6 This file is part of Tremulous.
7
8 Tremulous is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the License,
11 or (at your option) any later version.
12
13 Tremulous is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Tremulous; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 ===========================================================================
22 */
23
24 // bg_misc.c -- both games misc functions, all completely stateless
25
26 #include "../qcommon/q_shared.h"
27 #include "bg_public.h"
28
29 int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode );
30 void trap_FS_Read( void *buffer, int len, fileHandle_t f );
31 void trap_FS_Write( const void *buffer, int len, fileHandle_t f );
32 void trap_FS_FCloseFile( fileHandle_t f );
33 void trap_FS_Seek( fileHandle_t f, long offset, fsOrigin_t origin ); // fsOrigin_t
34
35 buildableAttributes_t bg_buildableList[ ] =
36 {
37 {
38 BA_A_SPAWN, //int buildNum;
39 "eggpod", //char *buildName;
40 "Egg", //char *humanName;
41 "team_alien_spawn", //char *entityName;
42 { "models/buildables/eggpod/eggpod.md3", 0, 0, 0 },
43 1.0f, //float modelScale;
44 { -15, -15, -15 }, //vec3_t mins;
45 { 15, 15, 15 }, //vec3_t maxs;
46 0.0f, //float zOffset;
47 TR_GRAVITY, //trType_t traj;
48 0.0, //float bounce;
49 ASPAWN_BP, //int buildPoints;
50 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
51 ASPAWN_HEALTH, //int health;
52 ASPAWN_REGEN, //int regenRate;
53 ASPAWN_SPLASHDAMAGE, //int splashDamage;
54 ASPAWN_SPLASHRADIUS, //int splashRadius;
55 MOD_ASPAWN, //int meansOfDeath;
56 BIT_ALIENS, //int team;
57 ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
58 BANIM_IDLE1, //int idleAnim;
59 100, //int nextthink;
60 ASPAWN_BT, //int buildTime;
61 qfalse, //qboolean usable;
62 0, //int turretRange;
63 0, //int turretFireSpeed;
64 WP_NONE, //weapon_t turretProjType;
65 0.5f, //float minNormal;
66 qtrue, //qboolean invertNormal;
67 qfalse, //qboolean creepTest;
68 ASPAWN_CREEPSIZE, //int creepSize;
69 qfalse, //qboolean dccTest;
70 qfalse //qboolean reactorTest;
71 },
72 {
73 BA_A_BARRICADE, //int buildNum;
74 "barricade", //char *buildName;
75 "Barricade", //char *humanName;
76 "team_alien_barricade",//char *entityName;
77 { "models/buildables/barricade/barricade.md3", 0, 0, 0 },
78 1.0f, //float modelScale;
79 { -35, -35, -15 }, //vec3_t mins;
80 { 35, 35, 60 }, //vec3_t maxs;
81 0.0f, //float zOffset;
82 TR_GRAVITY, //trType_t traj;
83 0.0, //float bounce;
84 BARRICADE_BP, //int buildPoints;
85 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
86 BARRICADE_HEALTH, //int health;
87 BARRICADE_REGEN, //int regenRate;
88 BARRICADE_SPLASHDAMAGE,//int splashDamage;
89 BARRICADE_SPLASHRADIUS,//int splashRadius;
90 MOD_ASPAWN, //int meansOfDeath;
91 BIT_ALIENS, //int team;
92 ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
93 BANIM_IDLE1, //int idleAnim;
94 100, //int nextthink;
95 BARRICADE_BT, //int buildTime;
96 qfalse, //qboolean usable;
97 0, //int turretRange;
98 0, //int turretFireSpeed;
99 WP_NONE, //weapon_t turretProjType;
100 0.707f, //float minNormal;
101 qfalse, //qboolean invertNormal;
102 qtrue, //qboolean creepTest;
103 BARRICADE_CREEPSIZE, //int creepSize;
104 qfalse, //qboolean dccTest;
105 qfalse //qboolean reactorTest;
106 },
107 {
108 BA_A_BOOSTER, //int buildNum;
109 "booster", //char *buildName;
110 "Booster", //char *humanName;
111 "team_alien_booster", //char *entityName;
112 { "models/buildables/booster/booster.md3", 0, 0, 0 },
113 1.0f, //float modelScale;
114 { -26, -26, -9 }, //vec3_t mins;
115 { 26, 26, 9 }, //vec3_t maxs;
116 0.0f, //float zOffset;
117 TR_GRAVITY, //trType_t traj;
118 0.0, //float bounce;
119 BOOSTER_BP, //int buildPoints;
120 ( 1 << S2 )|( 1 << S3 ), //int stages
121 BOOSTER_HEALTH, //int health;
122 BOOSTER_REGEN, //int regenRate;
123 BOOSTER_SPLASHDAMAGE, //int splashDamage;
124 BOOSTER_SPLASHRADIUS, //int splashRadius;
125 MOD_ASPAWN, //int meansOfDeath;
126 BIT_ALIENS, //int team;
127 ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
128 BANIM_IDLE1, //int idleAnim;
129 100, //int nextthink;
130 BOOSTER_BT, //int buildTime;
131 qfalse, //qboolean usable;
132 0, //int turretRange;
133 0, //int turretFireSpeed;
134 WP_NONE, //weapon_t turretProjType;
135 0.707f, //float minNormal;
136 qfalse, //qboolean invertNormal;
137 qtrue, //qboolean creepTest;
138 BOOSTER_CREEPSIZE, //int creepSize;
139 qfalse, //qboolean dccTest;
140 qfalse //qboolean reactorTest;
141 },
142 {
143 BA_A_ACIDTUBE, //int buildNum;
144 "acid_tube", //char *buildName;
145 "Acid Tube", //char *humanName;
146 "team_alien_acid_tube",//char *entityName;
147 { "models/buildables/acid_tube/acid_tube.md3", 0, 0, 0 },
148 1.0f, //float modelScale;
149 { -25, -25, -25 }, //vec3_t mins;
150 { 25, 25, 25 }, //vec3_t maxs;
151 -15.0f, //float zOffset;
152 TR_GRAVITY, //trType_t traj;
153 0.0, //float bounce;
154 ACIDTUBE_BP, //int buildPoints;
155 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
156 ACIDTUBE_HEALTH, //int health;
157 ACIDTUBE_REGEN, //int regenRate;
158 ACIDTUBE_SPLASHDAMAGE, //int splashDamage;
159 ACIDTUBE_SPLASHRADIUS, //int splashRadius;
160 MOD_ATUBE, //int meansOfDeath;
161 BIT_ALIENS, //int team;
162 ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
163 BANIM_IDLE1, //int idleAnim;
164 200, //int nextthink;
165 ACIDTUBE_BT, //int buildTime;
166 qfalse, //qboolean usable;
167 0, //int turretRange;
168 0, //int turretFireSpeed;
169 WP_NONE, //weapon_t turretProjType;
170 0.0f, //float minNormal;
171 qtrue, //qboolean invertNormal;
172 qtrue, //qboolean creepTest;
173 ACIDTUBE_CREEPSIZE, //int creepSize;
174 qfalse, //qboolean dccTest;
175 qfalse //qboolean reactorTest;
176 },
177 {
178 BA_A_HIVE, //int buildNum;
179 "hive", //char *buildName;
180 "Hive", //char *humanName;
181 "team_alien_hive", //char *entityName;
182 { "models/buildables/acid_tube/acid_tube.md3", 0, 0, 0 },
183 1.0f, //float modelScale;
184 { -35, -35, -25 }, //vec3_t mins;
185 { 35, 35, 25 }, //vec3_t maxs;
186 -15.0f, //float zOffset;
187 TR_GRAVITY, //trType_t traj;
188 0.0, //float bounce;
189 HIVE_BP, //int buildPoints;
190 ( 1 << S3 ), //int stages
191 HIVE_HEALTH, //int health;
192 HIVE_REGEN, //int regenRate;
193 HIVE_SPLASHDAMAGE, //int splashDamage;
194 HIVE_SPLASHRADIUS, //int splashRadius;
195 MOD_ASPAWN, //int meansOfDeath;
196 BIT_ALIENS, //int team;
197 ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
198 BANIM_IDLE1, //int idleAnim;
199 500, //int nextthink;
200 HIVE_BT, //int buildTime;
201 qfalse, //qboolean usable;
202 0, //int turretRange;
203 0, //int turretFireSpeed;
204 WP_HIVE, //weapon_t turretProjType;
205 0.0f, //float minNormal;
206 qtrue, //qboolean invertNormal;
207 qtrue, //qboolean creepTest;
208 HIVE_CREEPSIZE, //int creepSize;
209 qfalse, //qboolean dccTest;
210 qfalse //qboolean reactorTest;
211 },
212 {
213 BA_A_TRAPPER, //int buildNum;
214 "trapper", //char *buildName;
215 "Trapper", //char *humanName;
216 "team_alien_trapper", //char *entityName;
217 { "models/buildables/trapper/trapper.md3", 0, 0, 0 },
218 1.0f, //float modelScale;
219 { -15, -15, -15 }, //vec3_t mins;
220 { 15, 15, 15 }, //vec3_t maxs;
221 0.0f, //float zOffset;
222 TR_GRAVITY, //trType_t traj;
223 0.0, //float bounce;
224 TRAPPER_BP, //int buildPoints;
225 ( 1 << S2 )|( 1 << S3 ), //int stages //NEEDS ADV BUILDER SO S2 AND UP
226 TRAPPER_HEALTH, //int health;
227 TRAPPER_REGEN, //int regenRate;
228 TRAPPER_SPLASHDAMAGE, //int splashDamage;
229 TRAPPER_SPLASHRADIUS, //int splashRadius;
230 MOD_ASPAWN, //int meansOfDeath;
231 BIT_ALIENS, //int team;
232 ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
233 BANIM_IDLE1, //int idleAnim;
234 100, //int nextthink;
235 TRAPPER_BT, //int buildTime;
236 qfalse, //qboolean usable;
237 TRAPPER_RANGE, //int turretRange;
238 TRAPPER_REPEAT, //int turretFireSpeed;
239 WP_LOCKBLOB_LAUNCHER, //weapon_t turretProjType;
240 0.0f, //float minNormal;
241 qtrue, //qboolean invertNormal;
242 qtrue, //qboolean creepTest;
243 TRAPPER_CREEPSIZE, //int creepSize;
244 qfalse, //qboolean dccTest;
245 qfalse //qboolean reactorTest;
246 },
247 {
248 BA_A_OVERMIND, //int buildNum;
249 "overmind", //char *buildName;
250 "Overmind", //char *humanName;
251 "team_alien_overmind", //char *entityName;
252 { "models/buildables/overmind/overmind.md3", 0, 0, 0 },
253 1.0f, //float modelScale;
254 { -45, -45, -15 }, //vec3_t mins;
255 { 45, 45, 95 }, //vec3_t maxs;
256 0.0f, //float zOffset;
257 TR_GRAVITY, //trType_t traj;
258 0.0, //float bounce;
259 OVERMIND_BP, //int buildPoints;
260 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
261 OVERMIND_HEALTH, //int health;
262 OVERMIND_REGEN, //int regenRate;
263 OVERMIND_SPLASHDAMAGE, //int splashDamage;
264 OVERMIND_SPLASHRADIUS, //int splashRadius;
265 MOD_ASPAWN, //int meansOfDeath;
266 BIT_ALIENS, //int team;
267 ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
268 BANIM_IDLE1, //int idleAnim;
269 OVERMIND_ATTACK_REPEAT,//int nextthink;
270 OVERMIND_BT, //int buildTime;
271 qfalse, //qboolean usable;
272 0, //int turretRange;
273 0, //int turretFireSpeed;
274 WP_NONE, //weapon_t turretProjType;
275 0.95f, //float minNormal;
276 qfalse, //qboolean invertNormal;
277 qfalse, //qboolean creepTest;
278 OVERMIND_CREEPSIZE, //int creepSize;
279 qfalse, //qboolean dccTest;
280 qtrue //qboolean reactorTest;
281 },
282 {
283 BA_A_HOVEL, //int buildNum;
284 "hovel", //char *buildName;
285 "Hovel", //char *humanName;
286 "team_alien_hovel", //char *entityName;
287 { "models/buildables/hovel/hovel.md3", 0, 0, 0 },
288 1.0f, //float modelScale;
289 { -50, -50, -20 }, //vec3_t mins;
290 { 50, 50, 20 }, //vec3_t maxs;
291 0.0f, //float zOffset;
292 TR_GRAVITY, //trType_t traj;
293 0.0, //float bounce;
294 HOVEL_BP, //int buildPoints;
295 ( 1 << S3 ), //int stages
296 HOVEL_HEALTH, //int health;
297 HOVEL_REGEN, //int regenRate;
298 HOVEL_SPLASHDAMAGE, //int splashDamage;
299 HOVEL_SPLASHRADIUS, //int splashRadius;
300 MOD_ASPAWN, //int meansOfDeath;
301 BIT_ALIENS, //int team;
302 ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
303 BANIM_IDLE1, //int idleAnim;
304 150, //int nextthink;
305 HOVEL_BT, //int buildTime;
306 qtrue, //qboolean usable;
307 0, //int turretRange;
308 0, //int turretFireSpeed;
309 WP_NONE, //weapon_t turretProjType;
310 0.95f, //float minNormal;
311 qfalse, //qboolean invertNormal;
312 qtrue, //qboolean creepTest;
313 HOVEL_CREEPSIZE, //int creepSize;
314 qfalse, //qboolean dccTest;
315 qtrue //qboolean reactorTest;
316 },
317 {
318 BA_H_SPAWN, //int buildNum;
319 "telenode", //char *buildName;
320 "Telenode", //char *humanName;
321 "team_human_spawn", //char *entityName;
322 { "models/buildables/telenode/telenode.md3", 0, 0, 0 },
323 1.0f, //float modelScale;
324 { -40, -40, -4 }, //vec3_t mins;
325 { 40, 40, 4 }, //vec3_t maxs;
326 0.0f, //float zOffset;
327 TR_GRAVITY, //trType_t traj;
328 0.0, //float bounce;
329 HSPAWN_BP, //int buildPoints;
330 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
331 HSPAWN_HEALTH, //int health;
332 0, //int regenRate;
333 HSPAWN_SPLASHDAMAGE, //int splashDamage;
334 HSPAWN_SPLASHRADIUS, //int splashRadius;
335 MOD_HSPAWN, //int meansOfDeath;
336 BIT_HUMANS, //int team;
337 ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
338 BANIM_IDLE1, //int idleAnim;
339 100, //int nextthink;
340 HSPAWN_BT, //int buildTime;
341 qfalse, //qboolean usable;
342 0, //int turretRange;
343 0, //int turretFireSpeed;
344 WP_NONE, //weapon_t turretProjType;
345 0.95f, //float minNormal;
346 qfalse, //qboolean invertNormal;
347 qfalse, //qboolean creepTest;
348 0, //int creepSize;
349 qfalse, //qboolean dccTest;
350 qfalse //qboolean reactorTest;
351 },
352 {
353 BA_H_MEDISTAT, //int buildNum;
354 "medistat", //char *buildName;
355 "Medistation", //char *humanName;
356 "team_human_medistat", //char *entityName;
357 { "models/buildables/medistat/medistat.md3", 0, 0, 0 },
358 1.0f, //float modelScale;
359 { -35, -35, -7 }, //vec3_t mins;
360 { 35, 35, 7 }, //vec3_t maxs;
361 0.0f, //float zOffset;
362 TR_GRAVITY, //trType_t traj;
363 0.0, //float bounce;
364 MEDISTAT_BP, //int buildPoints;
365 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
366 MEDISTAT_HEALTH, //int health;
367 0, //int regenRate;
368 MEDISTAT_SPLASHDAMAGE, //int splashDamage;
369 MEDISTAT_SPLASHRADIUS, //int splashRadius;
370 MOD_HSPAWN, //int meansOfDeath;
371 BIT_HUMANS, //int team;
372 ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
373 BANIM_IDLE1, //int idleAnim;
374 100, //int nextthink;
375 MEDISTAT_BT, //int buildTime;
376 qfalse, //qboolean usable;
377 0, //int turretRange;
378 0, //int turretFireSpeed;
379 WP_NONE, //weapon_t turretProjType;
380 0.95f, //float minNormal;
381 qfalse, //qboolean invertNormal;
382 qfalse, //qboolean creepTest;
383 0, //int creepSize;
384 qfalse, //qboolean dccTest;
385 qfalse //qboolean reactorTest;
386 },
387 {
388 BA_H_MGTURRET, //int buildNum;
389 "mgturret", //char *buildName;
390 "Machinegun Turret", //char *humanName;
391 "team_human_mgturret", //char *entityName;
392 { "models/buildables/mgturret/turret_base.md3",
393 "models/buildables/mgturret/turret_barrel.md3",
394 "models/buildables/mgturret/turret_top.md3", 0 },
395 1.0f, //float modelScale;
396 { -25, -25, -20 }, //vec3_t mins;
397 { 25, 25, 20 }, //vec3_t maxs;
398 0.0f, //float zOffset;
399 TR_GRAVITY, //trType_t traj;
400 0.0, //float bounce;
401 MGTURRET_BP, //int buildPoints;
402 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
403 MGTURRET_HEALTH, //int health;
404 0, //int regenRate;
405 MGTURRET_SPLASHDAMAGE, //int splashDamage;
406 MGTURRET_SPLASHRADIUS, //int splashRadius;
407 MOD_HSPAWN, //int meansOfDeath;
408 BIT_HUMANS, //int team;
409 ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
410 BANIM_IDLE1, //int idleAnim;
411 50, //int nextthink;
412 MGTURRET_BT, //int buildTime;
413 qfalse, //qboolean usable;
414 MGTURRET_RANGE, //int turretRange;
415 MGTURRET_REPEAT, //int turretFireSpeed;
416 WP_MGTURRET, //weapon_t turretProjType;
417 0.95f, //float minNormal;
418 qfalse, //qboolean invertNormal;
419 qfalse, //qboolean creepTest;
420 0, //int creepSize;
421 qfalse, //qboolean dccTest;
422 qfalse //qboolean reactorTest;
423 },
424 {
425 BA_H_TESLAGEN, //int buildNum;
426 "tesla", //char *buildName;
427 "Tesla Generator", //char *humanName;
428 "team_human_tesla", //char *entityName;
429 { "models/buildables/tesla/tesla.md3", 0, 0, 0 },
430 1.0f, //float modelScale;
431 { -22, -22, -40 }, //vec3_t mins;
432 { 22, 22, 40 }, //vec3_t maxs;
433 0.0f, //float zOffset;
434 TR_GRAVITY, //trType_t traj;
435 0.0, //float bounce;
436 TESLAGEN_BP, //int buildPoints;
437 ( 1 << S3 ), //int stages
438 TESLAGEN_HEALTH, //int health;
439 0, //int regenRate;
440 TESLAGEN_SPLASHDAMAGE, //int splashDamage;
441 TESLAGEN_SPLASHRADIUS, //int splashRadius;
442 MOD_HSPAWN, //int meansOfDeath;
443 BIT_HUMANS, //int team;
444 ( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
445 BANIM_IDLE1, //int idleAnim;
446 150, //int nextthink;
447 TESLAGEN_BT, //int buildTime;
448 qfalse, //qboolean usable;
449 TESLAGEN_RANGE, //int turretRange;
450 TESLAGEN_REPEAT, //int turretFireSpeed;
451 WP_TESLAGEN, //weapon_t turretProjType;
452 0.95f, //float minNormal;
453 qfalse, //qboolean invertNormal;
454 qfalse, //qboolean creepTest;
455 0, //int creepSize;
456 qtrue, //qboolean dccTest;
457 qfalse //qboolean reactorTest;
458 },
459 {
460 BA_H_DCC, //int buildNum;
461 "dcc", //char *buildName;
462 "Defence Computer", //char *humanName;
463 "team_human_dcc", //char *entityName;
464 { "models/buildables/dcc/dcc.md3", 0, 0, 0 },
465 1.0f, //float modelScale;
466 { -35, -35, -13 }, //vec3_t mins;
467 { 35, 35, 47 }, //vec3_t maxs;
468 0.0f, //float zOffset;
469 TR_GRAVITY, //trType_t traj;
470 0.0, //float bounce;
471 DC_BP, //int buildPoints;
472 ( 1 << S2 )|( 1 << S3 ), //int stages
473 DC_HEALTH, //int health;
474 0, //int regenRate;
475 DC_SPLASHDAMAGE, //int splashDamage;
476 DC_SPLASHRADIUS, //int splashRadius;
477 MOD_HSPAWN, //int meansOfDeath;
478 BIT_HUMANS, //int team;
479 ( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
480 BANIM_IDLE1, //int idleAnim;
481 100, //int nextthink;
482 DC_BT, //int buildTime;
483 qfalse, //qboolean usable;
484 0, //int turretRange;
485 0, //int turretFireSpeed;
486 WP_NONE, //weapon_t turretProjType;
487 0.95f, //float minNormal;
488 qfalse, //qboolean invertNormal;
489 qfalse, //qboolean creepTest;
490 0, //int creepSize;
491 qfalse, //qboolean dccTest;
492 qfalse //qboolean reactorTest;
493 },
494 {
495 BA_H_ARMOURY, //int buildNum;
496 "arm", //char *buildName;
497 "Armoury", //char *humanName;
498 "team_human_armoury", //char *entityName;
499 { "models/buildables/arm/arm.md3", 0, 0, 0 },
500 1.0f, //float modelScale;
501 { -40, -40, -13 }, //vec3_t mins;
502 { 40, 40, 50 }, //vec3_t maxs;
503 0.0f, //float zOffset;
504 TR_GRAVITY, //trType_t traj;
505 0.0, //float bounce;
506 ARMOURY_BP, //int buildPoints;
507 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
508 ARMOURY_HEALTH, //int health;
509 0, //int regenRate;
510 ARMOURY_SPLASHDAMAGE, //int splashDamage;
511 ARMOURY_SPLASHRADIUS, //int splashRadius;
512 MOD_HSPAWN, //int meansOfDeath;
513 BIT_HUMANS, //int team;
514 ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
515 BANIM_IDLE1, //int idleAnim;
516 100, //int nextthink;
517 ARMOURY_BT, //int buildTime;
518 qtrue, //qboolean usable;
519 0, //int turretRange;
520 0, //int turretFireSpeed;
521 WP_NONE, //weapon_t turretProjType;
522 0.95f, //float minNormal;
523 qfalse, //qboolean invertNormal;
524 qfalse, //qboolean creepTest;
525 0, //int creepSize;
526 qfalse, //qboolean dccTest;
527 qfalse //qboolean reactorTest;
528 },
529 {
530 BA_H_REACTOR, //int buildNum;
531 "reactor", //char *buildName;
532 "Reactor", //char *humanName;
533 "team_human_reactor", //char *entityName;
534 { "models/buildables/reactor/reactor.md3", 0, 0, 0 },
535 1.0f, //float modelScale;
536 { -50, -50, -15 }, //vec3_t mins;
537 { 50, 50, 95 }, //vec3_t maxs;
538 0.0f, //float zOffset;
539 TR_GRAVITY, //trType_t traj;
540 0.0, //float bounce;
541 REACTOR_BP, //int buildPoints;
542 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
543 REACTOR_HEALTH, //int health;
544 0, //int regenRate;
545 REACTOR_SPLASHDAMAGE, //int splashDamage;
546 REACTOR_SPLASHRADIUS, //int splashRadius;
547 MOD_HSPAWN, //int meansOfDeath;
548 BIT_HUMANS, //int team;
549 ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
550 BANIM_IDLE1, //int idleAnim;
551 REACTOR_ATTACK_REPEAT, //int nextthink;
552 REACTOR_BT, //int buildTime;
553 qtrue, //qboolean usable;
554 0, //int turretRange;
555 0, //int turretFireSpeed;
556 WP_NONE, //weapon_t turretProjType;
557 0.95f, //float minNormal;
558 qfalse, //qboolean invertNormal;
559 qfalse, //qboolean creepTest;
560 0, //int creepSize;
561 qfalse, //qboolean dccTest;
562 qtrue //qboolean reactorTest;
563 },
564 {
565 BA_H_REPEATER, //int buildNum;
566 "repeater", //char *buildName;
567 "Repeater", //char *humanName;
568 "team_human_repeater", //char *entityName;
569 { "models/buildables/repeater/repeater.md3", 0, 0, 0 },
570 1.0f, //float modelScale;
571 { -15, -15, -15 }, //vec3_t mins;
572 { 15, 15, 25 }, //vec3_t maxs;
573 0.0f, //float zOffset;
574 TR_GRAVITY, //trType_t traj;
575 0.0, //float bounce;
576 REPEATER_BP, //int buildPoints;
577 ( 1 << S2 )|( 1 << S3 ), //int stages
578 REPEATER_HEALTH, //int health;
579 0, //int regenRate;
580 REPEATER_SPLASHDAMAGE, //int splashDamage;
581 REPEATER_SPLASHRADIUS, //int splashRadius;
582 MOD_HSPAWN, //int meansOfDeath;
583 BIT_HUMANS, //int team;
584 ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
585 BANIM_IDLE1, //int idleAnim;
586 100, //int nextthink;
587 REPEATER_BT, //int buildTime;
588 qtrue, //qboolean usable;
589 0, //int turretRange;
590 0, //int turretFireSpeed;
591 WP_NONE, //weapon_t turretProjType;
592 0.95f, //float minNormal;
593 qfalse, //qboolean invertNormal;
594 qfalse, //qboolean creepTest;
595 0, //int creepSize;
596 qfalse, //qboolean dccTest;
597 qfalse //qboolean reactorTest;
598 }
599 };
600
601 int bg_numBuildables = sizeof( bg_buildableList ) / sizeof( bg_buildableList[ 0 ] );
602
603 //separate from bg_buildableList to work around char struct init bug
604 buildableAttributeOverrides_t bg_buildableOverrideList[ BA_NUM_BUILDABLES ];
605
606 /*
607 ==============
608 BG_FindBuildNumForName
609 ==============
610 */
BG_FindBuildNumForName(char * name)611 int BG_FindBuildNumForName( char *name )
612 {
613 int i;
614
615 for( i = 0; i < bg_numBuildables; i++ )
616 {
617 if( !Q_stricmp( bg_buildableList[ i ].buildName, name ) )
618 return bg_buildableList[ i ].buildNum;
619 }
620
621 //wimp out
622 return BA_NONE;
623 }
624
625 /*
626 ==============
627 BG_FindBuildNumForEntityName
628 ==============
629 */
BG_FindBuildNumForEntityName(char * name)630 int BG_FindBuildNumForEntityName( char *name )
631 {
632 int i;
633
634 for( i = 0; i < bg_numBuildables; i++ )
635 {
636 if( !Q_stricmp( bg_buildableList[ i ].entityName, name ) )
637 return bg_buildableList[ i ].buildNum;
638 }
639
640 //wimp out
641 return BA_NONE;
642 }
643
644 /*
645 ==============
646 BG_FindNameForBuildNum
647 ==============
648 */
BG_FindNameForBuildable(int bclass)649 char *BG_FindNameForBuildable( int bclass )
650 {
651 int i;
652
653 for( i = 0; i < bg_numBuildables; i++ )
654 {
655 if( bg_buildableList[ i ].buildNum == bclass )
656 return bg_buildableList[ i ].buildName;
657 }
658
659 //wimp out
660 return 0;
661 }
662
663 /*
664 ==============
665 BG_FindHumanNameForBuildNum
666 ==============
667 */
BG_FindHumanNameForBuildable(int bclass)668 char *BG_FindHumanNameForBuildable( int bclass )
669 {
670 int i;
671
672 for( i = 0; i < bg_numBuildables; i++ )
673 {
674 if( bg_buildableList[ i ].buildNum == bclass )
675 return bg_buildableList[ i ].humanName;
676 }
677
678 //wimp out
679 return 0;
680 }
681
682 /*
683 ==============
684 BG_FindEntityNameForBuildNum
685 ==============
686 */
BG_FindEntityNameForBuildable(int bclass)687 char *BG_FindEntityNameForBuildable( int bclass )
688 {
689 int i;
690
691 for( i = 0; i < bg_numBuildables; i++ )
692 {
693 if( bg_buildableList[ i ].buildNum == bclass )
694 return bg_buildableList[ i ].entityName;
695 }
696
697 //wimp out
698 return 0;
699 }
700
701 /*
702 ==============
703 BG_FindModelsForBuildNum
704 ==============
705 */
BG_FindModelsForBuildable(int bclass,int modelNum)706 char *BG_FindModelsForBuildable( int bclass, int modelNum )
707 {
708 int i;
709
710 if( bg_buildableOverrideList[ bclass ].models[ modelNum ][ 0 ] != 0 )
711 return bg_buildableOverrideList[ bclass ].models[ modelNum ];
712
713 for( i = 0; i < bg_numBuildables; i++ )
714 {
715 if( bg_buildableList[ i ].buildNum == bclass )
716 return bg_buildableList[ i ].models[ modelNum ];
717 }
718
719 //wimp out
720 return 0;
721 }
722
723 /*
724 ==============
725 BG_FindModelScaleForBuildable
726 ==============
727 */
BG_FindModelScaleForBuildable(int bclass)728 float BG_FindModelScaleForBuildable( int bclass )
729 {
730 int i;
731
732 if( bg_buildableOverrideList[ bclass ].modelScale != 0.0f )
733 return bg_buildableOverrideList[ bclass ].modelScale;
734
735 for( i = 0; i < bg_numBuildables; i++ )
736 {
737 if( bg_buildableList[ i ].buildNum == bclass )
738 return bg_buildableList[ i ].modelScale;
739 }
740
741 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelScaleForBuildable( %d )\n", bclass );
742 return 1.0f;
743 }
744
745 /*
746 ==============
747 BG_FindBBoxForBuildable
748 ==============
749 */
BG_FindBBoxForBuildable(int bclass,vec3_t mins,vec3_t maxs)750 void BG_FindBBoxForBuildable( int bclass, vec3_t mins, vec3_t maxs )
751 {
752 int i;
753
754 for( i = 0; i < bg_numBuildables; i++ )
755 {
756 if( bg_buildableList[ i ].buildNum == bclass )
757 {
758 if( mins != NULL )
759 {
760 VectorCopy( bg_buildableList[ i ].mins, mins );
761
762 if( VectorLength( bg_buildableOverrideList[ bclass ].mins ) )
763 VectorCopy( bg_buildableOverrideList[ bclass ].mins, mins );
764 }
765
766 if( maxs != NULL )
767 {
768 VectorCopy( bg_buildableList[ i ].maxs, maxs );
769
770 if( VectorLength( bg_buildableOverrideList[ bclass ].maxs ) )
771 VectorCopy( bg_buildableOverrideList[ bclass ].maxs, maxs );
772 }
773
774 return;
775 }
776 }
777
778 if( mins != NULL )
779 VectorCopy( bg_buildableList[ 0 ].mins, mins );
780
781 if( maxs != NULL )
782 VectorCopy( bg_buildableList[ 0 ].maxs, maxs );
783 }
784
785 /*
786 ==============
787 BG_FindZOffsetForBuildable
788 ==============
789 */
BG_FindZOffsetForBuildable(int bclass)790 float BG_FindZOffsetForBuildable( int bclass )
791 {
792 int i;
793
794 if( bg_buildableOverrideList[ bclass ].zOffset != 0.0f )
795 return bg_buildableOverrideList[ bclass ].zOffset;
796
797 for( i = 0; i < bg_numBuildables; i++ )
798 {
799 if( bg_buildableList[ i ].buildNum == bclass )
800 {
801 return bg_buildableList[ i ].zOffset;
802 }
803 }
804
805 return 0.0f;
806 }
807
808 /*
809 ==============
810 BG_FindTrajectoryForBuildable
811 ==============
812 */
BG_FindTrajectoryForBuildable(int bclass)813 trType_t BG_FindTrajectoryForBuildable( int bclass )
814 {
815 int i;
816
817 for( i = 0; i < bg_numBuildables; i++ )
818 {
819 if( bg_buildableList[ i ].buildNum == bclass )
820 {
821 return bg_buildableList[ i ].traj;
822 }
823 }
824
825 return TR_GRAVITY;
826 }
827
828 /*
829 ==============
830 BG_FindBounceForBuildable
831 ==============
832 */
BG_FindBounceForBuildable(int bclass)833 float BG_FindBounceForBuildable( int bclass )
834 {
835 int i;
836
837 for( i = 0; i < bg_numBuildables; i++ )
838 {
839 if( bg_buildableList[ i ].buildNum == bclass )
840 {
841 return bg_buildableList[ i ].bounce;
842 }
843 }
844
845 return 0.0;
846 }
847
848 /*
849 ==============
850 BG_FindBuildPointsForBuildable
851 ==============
852 */
BG_FindBuildPointsForBuildable(int bclass)853 int BG_FindBuildPointsForBuildable( int bclass )
854 {
855 int i;
856
857 for( i = 0; i < bg_numBuildables; i++ )
858 {
859 if( bg_buildableList[ i ].buildNum == bclass )
860 {
861 return bg_buildableList[ i ].buildPoints;
862 }
863 }
864
865 return 1000;
866 }
867
868 /*
869 ==============
870 BG_FindStagesForBuildable
871 ==============
872 */
BG_FindStagesForBuildable(int bclass,stage_t stage)873 qboolean BG_FindStagesForBuildable( int bclass, stage_t stage )
874 {
875 int i;
876
877 for( i = 0; i < bg_numBuildables; i++ )
878 {
879 if( bg_buildableList[ i ].buildNum == bclass )
880 {
881 if( bg_buildableList[ i ].stages & ( 1 << stage ) )
882 return qtrue;
883 else
884 return qfalse;
885 }
886 }
887
888 return qfalse;
889 }
890
891 /*
892 ==============
893 BG_FindHealthForBuildable
894 ==============
895 */
BG_FindHealthForBuildable(int bclass)896 int BG_FindHealthForBuildable( int bclass )
897 {
898 int i;
899
900 for( i = 0; i < bg_numBuildables; i++ )
901 {
902 if( bg_buildableList[ i ].buildNum == bclass )
903 {
904 return bg_buildableList[ i ].health;
905 }
906 }
907
908 return 1000;
909 }
910
911 /*
912 ==============
913 BG_FindRegenRateForBuildable
914 ==============
915 */
BG_FindRegenRateForBuildable(int bclass)916 int BG_FindRegenRateForBuildable( int bclass )
917 {
918 int i;
919
920 for( i = 0; i < bg_numBuildables; i++ )
921 {
922 if( bg_buildableList[ i ].buildNum == bclass )
923 {
924 return bg_buildableList[ i ].regenRate;
925 }
926 }
927
928 return 0;
929 }
930
931 /*
932 ==============
933 BG_FindSplashDamageForBuildable
934 ==============
935 */
BG_FindSplashDamageForBuildable(int bclass)936 int BG_FindSplashDamageForBuildable( int bclass )
937 {
938 int i;
939
940 for( i = 0; i < bg_numBuildables; i++ )
941 {
942 if( bg_buildableList[ i ].buildNum == bclass )
943 {
944 return bg_buildableList[ i ].splashDamage;
945 }
946 }
947
948 return 50;
949 }
950
951 /*
952 ==============
953 BG_FindSplashRadiusForBuildable
954 ==============
955 */
BG_FindSplashRadiusForBuildable(int bclass)956 int BG_FindSplashRadiusForBuildable( int bclass )
957 {
958 int i;
959
960 for( i = 0; i < bg_numBuildables; i++ )
961 {
962 if( bg_buildableList[ i ].buildNum == bclass )
963 {
964 return bg_buildableList[ i ].splashRadius;
965 }
966 }
967
968 return 200;
969 }
970
971 /*
972 ==============
973 BG_FindMODForBuildable
974 ==============
975 */
BG_FindMODForBuildable(int bclass)976 int BG_FindMODForBuildable( int bclass )
977 {
978 int i;
979
980 for( i = 0; i < bg_numBuildables; i++ )
981 {
982 if( bg_buildableList[ i ].buildNum == bclass )
983 {
984 return bg_buildableList[ i ].meansOfDeath;
985 }
986 }
987
988 return MOD_UNKNOWN;
989 }
990
991 /*
992 ==============
993 BG_FindTeamForBuildable
994 ==============
995 */
BG_FindTeamForBuildable(int bclass)996 int BG_FindTeamForBuildable( int bclass )
997 {
998 int i;
999
1000 for( i = 0; i < bg_numBuildables; i++ )
1001 {
1002 if( bg_buildableList[ i ].buildNum == bclass )
1003 {
1004 return bg_buildableList[ i ].team;
1005 }
1006 }
1007
1008 return BIT_NONE;
1009 }
1010
1011 /*
1012 ==============
1013 BG_FindBuildWeaponForBuildable
1014 ==============
1015 */
BG_FindBuildWeaponForBuildable(int bclass)1016 weapon_t BG_FindBuildWeaponForBuildable( int bclass )
1017 {
1018 int i;
1019
1020 for( i = 0; i < bg_numBuildables; i++ )
1021 {
1022 if( bg_buildableList[ i ].buildNum == bclass )
1023 {
1024 return bg_buildableList[ i ].buildWeapon;
1025 }
1026 }
1027
1028 return BA_NONE;
1029 }
1030
1031 /*
1032 ==============
1033 BG_FindAnimForBuildable
1034 ==============
1035 */
BG_FindAnimForBuildable(int bclass)1036 int BG_FindAnimForBuildable( int bclass )
1037 {
1038 int i;
1039
1040 for( i = 0; i < bg_numBuildables; i++ )
1041 {
1042 if( bg_buildableList[ i ].buildNum == bclass )
1043 {
1044 return bg_buildableList[ i ].idleAnim;
1045 }
1046 }
1047
1048 return BANIM_IDLE1;
1049 }
1050
1051 /*
1052 ==============
1053 BG_FindNextThinkForBuildable
1054 ==============
1055 */
BG_FindNextThinkForBuildable(int bclass)1056 int BG_FindNextThinkForBuildable( int bclass )
1057 {
1058 int i;
1059
1060 for( i = 0; i < bg_numBuildables; i++ )
1061 {
1062 if( bg_buildableList[ i ].buildNum == bclass )
1063 {
1064 return bg_buildableList[ i ].nextthink;
1065 }
1066 }
1067
1068 return 100;
1069 }
1070
1071 /*
1072 ==============
1073 BG_FindBuildTimeForBuildable
1074 ==============
1075 */
BG_FindBuildTimeForBuildable(int bclass)1076 int BG_FindBuildTimeForBuildable( int bclass )
1077 {
1078 int i;
1079
1080 for( i = 0; i < bg_numBuildables; i++ )
1081 {
1082 if( bg_buildableList[ i ].buildNum == bclass )
1083 {
1084 return bg_buildableList[ i ].buildTime;
1085 }
1086 }
1087
1088 return 10000;
1089 }
1090
1091 /*
1092 ==============
1093 BG_FindUsableForBuildable
1094 ==============
1095 */
BG_FindUsableForBuildable(int bclass)1096 qboolean BG_FindUsableForBuildable( int bclass )
1097 {
1098 int i;
1099
1100 for( i = 0; i < bg_numBuildables; i++ )
1101 {
1102 if( bg_buildableList[ i ].buildNum == bclass )
1103 {
1104 return bg_buildableList[ i ].usable;
1105 }
1106 }
1107
1108 return qfalse;
1109 }
1110
1111 /*
1112 ==============
1113 BG_FindFireSpeedForBuildable
1114 ==============
1115 */
BG_FindFireSpeedForBuildable(int bclass)1116 int BG_FindFireSpeedForBuildable( int bclass )
1117 {
1118 int i;
1119
1120 for( i = 0; i < bg_numBuildables; i++ )
1121 {
1122 if( bg_buildableList[ i ].buildNum == bclass )
1123 {
1124 return bg_buildableList[ i ].turretFireSpeed;
1125 }
1126 }
1127
1128 return 1000;
1129 }
1130
1131 /*
1132 ==============
1133 BG_FindRangeForBuildable
1134 ==============
1135 */
BG_FindRangeForBuildable(int bclass)1136 int BG_FindRangeForBuildable( int bclass )
1137 {
1138 int i;
1139
1140 for( i = 0; i < bg_numBuildables; i++ )
1141 {
1142 if( bg_buildableList[ i ].buildNum == bclass )
1143 {
1144 return bg_buildableList[ i ].turretRange;
1145 }
1146 }
1147
1148 return 1000;
1149 }
1150
1151 /*
1152 ==============
1153 BG_FindProjTypeForBuildable
1154 ==============
1155 */
BG_FindProjTypeForBuildable(int bclass)1156 weapon_t BG_FindProjTypeForBuildable( int bclass )
1157 {
1158 int i;
1159
1160 for( i = 0; i < bg_numBuildables; i++ )
1161 {
1162 if( bg_buildableList[ i ].buildNum == bclass )
1163 {
1164 return bg_buildableList[ i ].turretProjType;
1165 }
1166 }
1167
1168 return WP_NONE;
1169 }
1170
1171 /*
1172 ==============
1173 BG_FindMinNormalForBuildable
1174 ==============
1175 */
BG_FindMinNormalForBuildable(int bclass)1176 float BG_FindMinNormalForBuildable( int bclass )
1177 {
1178 int i;
1179
1180 for( i = 0; i < bg_numBuildables; i++ )
1181 {
1182 if( bg_buildableList[ i ].buildNum == bclass )
1183 {
1184 return bg_buildableList[ i ].minNormal;
1185 }
1186 }
1187
1188 return 0.707f;
1189 }
1190
1191 /*
1192 ==============
1193 BG_FindInvertNormalForBuildable
1194 ==============
1195 */
BG_FindInvertNormalForBuildable(int bclass)1196 qboolean BG_FindInvertNormalForBuildable( int bclass )
1197 {
1198 int i;
1199
1200 for( i = 0; i < bg_numBuildables; i++ )
1201 {
1202 if( bg_buildableList[ i ].buildNum == bclass )
1203 {
1204 return bg_buildableList[ i ].invertNormal;
1205 }
1206 }
1207
1208 return qfalse;
1209 }
1210
1211 /*
1212 ==============
1213 BG_FindCreepTestForBuildable
1214 ==============
1215 */
BG_FindCreepTestForBuildable(int bclass)1216 int BG_FindCreepTestForBuildable( int bclass )
1217 {
1218 int i;
1219
1220 for( i = 0; i < bg_numBuildables; i++ )
1221 {
1222 if( bg_buildableList[ i ].buildNum == bclass )
1223 {
1224 return bg_buildableList[ i ].creepTest;
1225 }
1226 }
1227
1228 return qfalse;
1229 }
1230
1231 /*
1232 ==============
1233 BG_FindCreepSizeForBuildable
1234 ==============
1235 */
BG_FindCreepSizeForBuildable(int bclass)1236 int BG_FindCreepSizeForBuildable( int bclass )
1237 {
1238 int i;
1239
1240 for( i = 0; i < bg_numBuildables; i++ )
1241 {
1242 if( bg_buildableList[ i ].buildNum == bclass )
1243 {
1244 return bg_buildableList[ i ].creepSize;
1245 }
1246 }
1247
1248 return CREEP_BASESIZE;
1249 }
1250
1251 /*
1252 ==============
1253 BG_FindDCCTestForBuildable
1254 ==============
1255 */
BG_FindDCCTestForBuildable(int bclass)1256 int BG_FindDCCTestForBuildable( int bclass )
1257 {
1258 int i;
1259
1260 for( i = 0; i < bg_numBuildables; i++ )
1261 {
1262 if( bg_buildableList[ i ].buildNum == bclass )
1263 {
1264 return bg_buildableList[ i ].dccTest;
1265 }
1266 }
1267
1268 return qfalse;
1269 }
1270
1271 /*
1272 ==============
1273 BG_FindUniqueTestForBuildable
1274 ==============
1275 */
BG_FindUniqueTestForBuildable(int bclass)1276 int BG_FindUniqueTestForBuildable( int bclass )
1277 {
1278 int i;
1279
1280 for( i = 0; i < bg_numBuildables; i++ )
1281 {
1282 if( bg_buildableList[ i ].buildNum == bclass )
1283 {
1284 return bg_buildableList[ i ].reactorTest;
1285 }
1286 }
1287
1288 return qfalse;
1289 }
1290
1291 /*
1292 ==============
1293 BG_FindOverrideForBuildable
1294 ==============
1295 */
BG_FindOverrideForBuildable(int bclass)1296 static buildableAttributeOverrides_t *BG_FindOverrideForBuildable( int bclass )
1297 {
1298 return &bg_buildableOverrideList[ bclass ];
1299 }
1300
1301 /*
1302 ======================
1303 BG_ParseBuildableFile
1304
1305 Parses a configuration file describing a builable
1306 ======================
1307 */
BG_ParseBuildableFile(const char * filename,buildableAttributeOverrides_t * bao)1308 static qboolean BG_ParseBuildableFile( const char *filename, buildableAttributeOverrides_t *bao )
1309 {
1310 char *text_p;
1311 int i;
1312 int len;
1313 char *token;
1314 char text[ 20000 ];
1315 fileHandle_t f;
1316 float scale;
1317
1318
1319 // load the file
1320 len = trap_FS_FOpenFile( filename, &f, FS_READ );
1321 if( len <= 0 )
1322 return qfalse;
1323
1324 if( len >= sizeof( text ) - 1 )
1325 {
1326 Com_Printf( S_COLOR_RED "ERROR: Buildable file %s too long\n", filename );
1327 return qfalse;
1328 }
1329
1330 trap_FS_Read( text, len, f );
1331 text[ len ] = 0;
1332 trap_FS_FCloseFile( f );
1333
1334 // parse the text
1335 text_p = text;
1336
1337 // read optional parameters
1338 while( 1 )
1339 {
1340 token = COM_Parse( &text_p );
1341
1342 if( !token )
1343 break;
1344
1345 if( !Q_stricmp( token, "" ) )
1346 break;
1347
1348 if( !Q_stricmp( token, "model" ) )
1349 {
1350 int index = 0;
1351
1352 token = COM_Parse( &text_p );
1353 if( !token )
1354 break;
1355
1356 index = atoi( token );
1357
1358 if( index < 0 )
1359 index = 0;
1360 else if( index > 3 )
1361 index = 3;
1362
1363 token = COM_Parse( &text_p );
1364 if( !token )
1365 break;
1366
1367 Q_strncpyz( bao->models[ index ], token, sizeof( bao->models[ 0 ] ) );
1368
1369 continue;
1370 }
1371 else if( !Q_stricmp( token, "modelScale" ) )
1372 {
1373 token = COM_Parse( &text_p );
1374 if( !token )
1375 break;
1376
1377 scale = atof( token );
1378
1379 if( scale < 0.0f )
1380 scale = 0.0f;
1381
1382 bao->modelScale = scale;
1383
1384 continue;
1385 }
1386 else if( !Q_stricmp( token, "mins" ) )
1387 {
1388 for( i = 0; i <= 2; i++ )
1389 {
1390 token = COM_Parse( &text_p );
1391 if( !token )
1392 break;
1393
1394 bao->mins[ i ] = atof( token );
1395 }
1396
1397 continue;
1398 }
1399 else if( !Q_stricmp( token, "maxs" ) )
1400 {
1401 for( i = 0; i <= 2; i++ )
1402 {
1403 token = COM_Parse( &text_p );
1404 if( !token )
1405 break;
1406
1407 bao->maxs[ i ] = atof( token );
1408 }
1409
1410 continue;
1411 }
1412 else if( !Q_stricmp( token, "zOffset" ) )
1413 {
1414 float offset;
1415
1416 token = COM_Parse( &text_p );
1417 if( !token )
1418 break;
1419
1420 offset = atof( token );
1421
1422 bao->zOffset = offset;
1423
1424 continue;
1425 }
1426
1427
1428 Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token );
1429 return qfalse;
1430 }
1431
1432 return qtrue;
1433 }
1434
1435 /*
1436 ===============
1437 BG_InitBuildableOverrides
1438
1439 Set any overrides specfied by file
1440 ===============
1441 */
BG_InitBuildableOverrides(void)1442 void BG_InitBuildableOverrides( void )
1443 {
1444 int i;
1445 buildableAttributeOverrides_t *bao;
1446
1447 for( i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++ )
1448 {
1449 bao = BG_FindOverrideForBuildable( i );
1450
1451 BG_ParseBuildableFile( va( "overrides/buildables/%s.cfg", BG_FindNameForBuildable( i ) ), bao );
1452 }
1453 }
1454
1455 ////////////////////////////////////////////////////////////////////////////////
1456
1457 classAttributes_t bg_classList[ ] =
1458 {
1459 {
1460 PCL_NONE, //int classnum;
1461 "spectator", //char *className;
1462 "Spectator", //char *humanName;
1463 "", //char *modelname;
1464 1.0f, //float modelScale;
1465 "", //char *skinname;
1466 1.0f, //float shadowScale;
1467 "", //char *hudname;
1468 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
1469 { -15, -15, -15 }, //vec3_t mins;
1470 { 15, 15, 15 }, //vec3_t maxs;
1471 { 15, 15, 15 }, //vec3_t crouchmaxs;
1472 { -15, -15, -15 }, //vec3_t deadmins;
1473 { 15, 15, 15 }, //vec3_t deadmaxs;
1474 0.0f, //float zOffset
1475 0, 0, //int viewheight, crouchviewheight;
1476 0, //int health;
1477 0.0f, //float fallDamage;
1478 0, //int regenRate;
1479 0, //int abilities;
1480 WP_NONE, //weapon_t startWeapon
1481 0.0f, //float buildDist;
1482 90, //int fov;
1483 0.000f, //float bob;
1484 1.0f, //float bobCycle;
1485 0, //int steptime;
1486 600, //float speed;
1487 10.0f, //float acceleration;
1488 1.0f, //float airAcceleration;
1489 6.0f, //float friction;
1490 100.0f, //float stopSpeed;
1491 270.0f, //float jumpMagnitude;
1492 1.0f, //float knockbackScale;
1493 { PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
1494 0, //int cost;
1495 0 //int value;
1496 },
1497 {
1498 PCL_ALIEN_BUILDER0, //int classnum;
1499 "builder", //char *className;
1500 "Builder", //char *humanName;
1501 "builder", //char *modelname;
1502 1.0f, //float modelScale;
1503 "default", //char *skinname;
1504 1.0f, //float shadowScale;
1505 "alien_builder_hud", //char *hudname;
1506 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
1507 { -15, -15, -20 }, //vec3_t mins;
1508 { 15, 15, 20 }, //vec3_t maxs;
1509 { 15, 15, 20 }, //vec3_t crouchmaxs;
1510 { -15, -15, -4 }, //vec3_t deadmins;
1511 { 15, 15, 4 }, //vec3_t deadmaxs;
1512 0.0f, //float zOffset
1513 0, 0, //int viewheight, crouchviewheight;
1514 ABUILDER_HEALTH, //int health;
1515 0.2f, //float fallDamage;
1516 ABUILDER_REGEN, //int regenRate;
1517 SCA_TAKESFALLDAMAGE|SCA_FOVWARPS|SCA_ALIENSENSE,//int abilities;
1518 WP_ABUILD, //weapon_t startWeapon
1519 95.0f, //float buildDist;
1520 80, //int fov;
1521 0.001f, //float bob;
1522 2.0f, //float bobCycle;
1523 150, //int steptime;
1524 ABUILDER_SPEED, //float speed;
1525 10.0f, //float acceleration;
1526 1.0f, //float airAcceleration;
1527 6.0f, //float friction;
1528 100.0f, //float stopSpeed;
1529 195.0f, //float jumpMagnitude;
1530 1.0f, //float knockbackScale;
1531 { PCL_ALIEN_BUILDER0_UPG, PCL_ALIEN_LEVEL0, PCL_NONE }, //int children[ 3 ];
1532 ABUILDER_COST, //int cost;
1533 ABUILDER_VALUE //int value;
1534 },
1535 {
1536 PCL_ALIEN_BUILDER0_UPG, //int classnum;
1537 "builderupg", //char *classname;
1538 "Advanced Builder", //char *humanname;
1539 "builder", //char *modelname;
1540 1.0f, //float modelScale;
1541 "advanced", //char *skinname;
1542 1.0f, //float shadowScale;
1543 "alien_builder_hud", //char *hudname;
1544 ( 1 << S2 )|( 1 << S3 ), //int stages
1545 { -20, -20, -20 }, //vec3_t mins;
1546 { 20, 20, 20 }, //vec3_t maxs;
1547 { 20, 20, 20 }, //vec3_t crouchmaxs;
1548 { -20, -20, -4 }, //vec3_t deadmins;
1549 { 20, 20, 4 }, //vec3_t deadmaxs;
1550 0.0f, //float zOffset
1551 0, 0, //int viewheight, crouchviewheight;
1552 ABUILDER_UPG_HEALTH, //int health;
1553 0.0f, //float fallDamage;
1554 ABUILDER_UPG_REGEN, //int regenRate;
1555 SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities;
1556 WP_ABUILD2, //weapon_t startWeapon
1557 105.0f, //float buildDist;
1558 110, //int fov;
1559 0.001f, //float bob;
1560 2.0f, //float bobCycle;
1561 100, //int steptime;
1562 ABUILDER_UPG_SPEED, //float speed;
1563 10.0f, //float acceleration;
1564 1.0f, //float airAcceleration;
1565 6.0f, //float friction;
1566 100.0f, //float stopSpeed;
1567 270.0f, //float jumpMagnitude;
1568 1.0f, //float knockbackScale;
1569 { PCL_ALIEN_LEVEL0, PCL_NONE, PCL_NONE }, //int children[ 3 ];
1570 ABUILDER_UPG_COST, //int cost;
1571 ABUILDER_UPG_VALUE //int value;
1572 },
1573 {
1574 PCL_ALIEN_LEVEL0, //int classnum;
1575 "level0", //char *classname;
1576 "Soldier", //char *humanname;
1577 "jumper", //char *modelname;
1578 0.2f, //float modelScale;
1579 "default", //char *skinname;
1580 0.3f, //float shadowScale;
1581 "alien_general_hud", //char *hudname;
1582 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
1583 { -15, -15, -15 }, //vec3_t mins;
1584 { 15, 15, 15 }, //vec3_t maxs;
1585 { 15, 15, 15 }, //vec3_t crouchmaxs;
1586 { -15, -15, -4 }, //vec3_t deadmins;
1587 { 15, 15, 4 }, //vec3_t deadmaxs;
1588 -8.0f, //float zOffset
1589 0, 0, //int viewheight, crouchviewheight;
1590 LEVEL0_HEALTH, //int health;
1591 0.0f, //float fallDamage;
1592 LEVEL0_REGEN, //int regenRate;
1593 SCA_WALLCLIMBER|SCA_NOWEAPONDRIFT|
1594 SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
1595 WP_ALEVEL0, //weapon_t startWeapon
1596 0.0f, //float buildDist;
1597 140, //int fov;
1598 0.0f, //float bob;
1599 2.5f, //float bobCycle;
1600 25, //int steptime;
1601 LEVEL0_SPEED, //float speed;
1602 10.0f, //float acceleration;
1603 1.0f, //float airAcceleration;
1604 6.0f, //float friction;
1605 400.0f, //float stopSpeed;
1606 250.0f, //float jumpMagnitude;
1607 2.0f, //float knockbackScale;
1608 { PCL_ALIEN_LEVEL1, PCL_NONE, PCL_NONE }, //int children[ 3 ];
1609 LEVEL0_COST, //int cost;
1610 LEVEL0_VALUE //int value;
1611 },
1612 {
1613 PCL_ALIEN_LEVEL1, //int classnum;
1614 "level1", //char *classname;
1615 "Hydra", //char *humanname;
1616 "spitter", //char *modelname;
1617 0.6f, //float modelScale;
1618 "default", //char *skinname;
1619 1.0f, //float shadowScale;
1620 "alien_general_hud", //char *hudname;
1621 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
1622 { -18, -18, -18 }, //vec3_t mins;
1623 { 18, 18, 18 }, //vec3_t maxs;
1624 { 18, 18, 18 }, //vec3_t crouchmaxs;
1625 { -18, -18, -4 }, //vec3_t deadmins;
1626 { 18, 18, 4 }, //vec3_t deadmaxs;
1627 0.0f, //float zOffset
1628 0, 0, //int viewheight, crouchviewheight;
1629 LEVEL1_HEALTH, //int health;
1630 0.0f, //float fallDamage;
1631 LEVEL1_REGEN, //int regenRate;
1632 SCA_NOWEAPONDRIFT|
1633 SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities;
1634 WP_ALEVEL1, //weapon_t startWeapon
1635 0.0f, //float buildDist;
1636 120, //int fov;
1637 0.001f, //float bob;
1638 1.8f, //float bobCycle;
1639 60, //int steptime;
1640 LEVEL1_SPEED, //float speed;
1641 10.0f, //float acceleration;
1642 1.0f, //float airAcceleration;
1643 6.0f, //float friction;
1644 300.0f, //float stopSpeed;
1645 270.0f, //float jumpMagnitude;
1646 1.2f, //float knockbackScale;
1647 { PCL_ALIEN_LEVEL2, PCL_ALIEN_LEVEL1_UPG, PCL_NONE }, //int children[ 3 ];
1648 LEVEL1_COST, //int cost;
1649 LEVEL1_VALUE //int value;
1650 },
1651 {
1652 PCL_ALIEN_LEVEL1_UPG, //int classnum;
1653 "level1upg", //char *classname;
1654 "Hydra Upgrade", //char *humanname;
1655 "spitter", //char *modelname;
1656 0.7f, //float modelScale;
1657 "blue", //char *skinname;
1658 1.0f, //float shadowScale;
1659 "alien_general_hud", //char *hudname;
1660 ( 1 << S2 )|( 1 << S3 ), //int stages
1661 { -20, -20, -20 }, //vec3_t mins;
1662 { 20, 20, 20 }, //vec3_t maxs;
1663 { 20, 20, 20 }, //vec3_t crouchmaxs;
1664 { -20, -20, -4 }, //vec3_t deadmins;
1665 { 20, 20, 4 }, //vec3_t deadmaxs;
1666 0.0f, //float zOffset
1667 0, 0, //int viewheight, crouchviewheight;
1668 LEVEL1_UPG_HEALTH, //int health;
1669 0.0f, //float fallDamage;
1670 LEVEL1_UPG_REGEN, //int regenRate;
1671 SCA_NOWEAPONDRIFT|SCA_FOVWARPS|
1672 SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities;
1673 WP_ALEVEL1_UPG, //weapon_t startWeapon
1674 0.0f, //float buildDist;
1675 120, //int fov;
1676 0.001f, //float bob;
1677 1.8f, //float bobCycle;
1678 60, //int steptime;
1679 LEVEL1_UPG_SPEED, //float speed;
1680 10.0f, //float acceleration;
1681 1.0f, //float airAcceleration;
1682 6.0f, //float friction;
1683 300.0f, //float stopSpeed;
1684 270.0f, //float jumpMagnitude;
1685 1.1f, //float knockbackScale;
1686 { PCL_ALIEN_LEVEL2, PCL_NONE, PCL_NONE }, //int children[ 3 ];
1687 LEVEL1_UPG_COST, //int cost;
1688 LEVEL1_UPG_VALUE //int value;
1689 },
1690 {
1691 PCL_ALIEN_LEVEL2, //int classnum;
1692 "level2", //char *classname;
1693 "Chimera", //char *humanname;
1694 "tarantula", //char *modelname;
1695 0.75f, //float modelScale;
1696 "default", //char *skinname;
1697 1.0f, //float shadowScale;
1698 "alien_general_hud", //char *hudname;
1699 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
1700 { -22, -22, -22 }, //vec3_t mins;
1701 { 22, 22, 22 }, //vec3_t maxs;
1702 { 22, 22, 22 }, //vec3_t crouchmaxs;
1703 { -22, -22, -4 }, //vec3_t deadmins;
1704 { 22, 22, 4 }, //vec3_t deadmaxs;
1705 0.0f, //float zOffset
1706 10, 10, //int viewheight, crouchviewheight;
1707 LEVEL2_HEALTH, //int health;
1708 0.0f, //float fallDamage;
1709 LEVEL2_REGEN, //int regenRate;
1710 SCA_NOWEAPONDRIFT|SCA_WALLJUMPER|
1711 SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
1712 WP_ALEVEL2, //weapon_t startWeapon
1713 0.0f, //float buildDist;
1714 90, //int fov;
1715 0.001f, //float bob;
1716 1.5f, //float bobCycle;
1717 80, //int steptime;
1718 LEVEL2_SPEED, //float speed;
1719 10.0f, //float acceleration;
1720 2.0f, //float airAcceleration;
1721 6.0f, //float friction;
1722 100.0f, //float stopSpeed;
1723 400.0f, //float jumpMagnitude;
1724 0.8f, //float knockbackScale;
1725 { PCL_ALIEN_LEVEL3, PCL_ALIEN_LEVEL2_UPG, PCL_NONE }, //int children[ 3 ];
1726 LEVEL2_COST, //int cost;
1727 LEVEL2_VALUE //int value;
1728 },
1729 {
1730 PCL_ALIEN_LEVEL2_UPG, //int classnum;
1731 "level2upg", //char *classname;
1732 "Chimera Upgrade", //char *humanname;
1733 "tarantula", //char *modelname;
1734 0.9f, //float modelScale;
1735 "red", //char *skinname;
1736 1.0f, //float shadowScale;
1737 "alien_general_hud", //char *hudname;
1738 ( 1 << S2 )|( 1 << S3 ), //int stages
1739 { -24, -24, -24 }, //vec3_t mins;
1740 { 24, 24, 24 }, //vec3_t maxs;
1741 { 24, 24, 24 }, //vec3_t crouchmaxs;
1742 { -24, -24, -4 }, //vec3_t deadmins;
1743 { 24, 24, 4 }, //vec3_t deadmaxs;
1744 0.0f, //float zOffset
1745 12, 12, //int viewheight, crouchviewheight;
1746 LEVEL2_UPG_HEALTH, //int health;
1747 0.0f, //float fallDamage;
1748 LEVEL2_UPG_REGEN, //int regenRate;
1749 SCA_NOWEAPONDRIFT|SCA_WALLJUMPER|
1750 SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
1751 WP_ALEVEL2_UPG, //weapon_t startWeapon
1752 0.0f, //float buildDist;
1753 90, //int fov;
1754 0.001f, //float bob;
1755 1.5f, //float bobCycle;
1756 80, //int steptime;
1757 LEVEL2_UPG_SPEED, //float speed;
1758 10.0f, //float acceleration;
1759 2.0f, //float airAcceleration;
1760 6.0f, //float friction;
1761 100.0f, //float stopSpeed;
1762 400.0f, //float jumpMagnitude;
1763 0.7f, //float knockbackScale;
1764 { PCL_ALIEN_LEVEL3, PCL_NONE, PCL_NONE }, //int children[ 3 ];
1765 LEVEL2_UPG_COST, //int cost;
1766 LEVEL2_UPG_VALUE //int value;
1767 },
1768 {
1769 PCL_ALIEN_LEVEL3, //int classnum;
1770 "level3", //char *classname;
1771 "Dragoon", //char *humanname;
1772 "prowl", //char *modelname;
1773 1.0f, //float modelScale;
1774 "default", //char *skinname;
1775 1.0f, //float shadowScale;
1776 "alien_general_hud", //char *hudname;
1777 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
1778 { -32, -32, -21 }, //vec3_t mins;
1779 { 32, 32, 21 }, //vec3_t maxs;
1780 { 32, 32, 21 }, //vec3_t crouchmaxs;
1781 { -32, -32, -4 }, //vec3_t deadmins;
1782 { 32, 32, 4 }, //vec3_t deadmaxs;
1783 0.0f, //float zOffset
1784 24, 24, //int viewheight, crouchviewheight;
1785 LEVEL3_HEALTH, //int health;
1786 0.0f, //float fallDamage;
1787 LEVEL3_REGEN, //int regenRate;
1788 SCA_NOWEAPONDRIFT|
1789 SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
1790 WP_ALEVEL3, //weapon_t startWeapon
1791 0.0f, //float buildDist;
1792 110, //int fov;
1793 0.0005f, //float bob;
1794 1.3f, //float bobCycle;
1795 90, //int steptime;
1796 LEVEL3_SPEED, //float speed;
1797 10.0f, //float acceleration;
1798 1.0f, //float airAcceleration;
1799 6.0f, //float friction;
1800 200.0f, //float stopSpeed;
1801 270.0f, //float jumpMagnitude;
1802 0.5f, //float knockbackScale;
1803 { PCL_ALIEN_LEVEL4, PCL_ALIEN_LEVEL3_UPG, PCL_NONE }, //int children[ 3 ];
1804 LEVEL3_COST, //int cost;
1805 LEVEL3_VALUE //int value;
1806 },
1807 {
1808 PCL_ALIEN_LEVEL3_UPG, //int classnum;
1809 "level3upg", //char *classname;
1810 "Dragoon Upgrade", //char *humanname;
1811 "prowl", //char *modelname;
1812 1.0f, //float modelScale;
1813 "default", //char *skinname;
1814 1.0f, //float shadowScale;
1815 "alien_general_hud", //char *hudname;
1816 ( 1 << S3 ), //int stages
1817 { -32, -32, -21 }, //vec3_t mins;
1818 { 32, 32, 21 }, //vec3_t maxs;
1819 { 32, 32, 21 }, //vec3_t crouchmaxs;
1820 { -32, -32, -4 }, //vec3_t deadmins;
1821 { 32, 32, 4 }, //vec3_t deadmaxs;
1822 0.0f, //float zOffset
1823 27, 27, //int viewheight, crouchviewheight;
1824 LEVEL3_UPG_HEALTH, //int health;
1825 0.0f, //float fallDamage;
1826 LEVEL3_UPG_REGEN, //int regenRate;
1827 SCA_NOWEAPONDRIFT|
1828 SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
1829 WP_ALEVEL3_UPG, //weapon_t startWeapon
1830 0.0f, //float buildDist;
1831 110, //int fov;
1832 0.0005f, //float bob;
1833 1.3f, //float bobCycle;
1834 90, //int steptime;
1835 LEVEL3_UPG_SPEED, //float speed;
1836 10.0f, //float acceleration;
1837 1.0f, //float airAcceleration;
1838 6.0f, //float friction;
1839 200.0f, //float stopSpeed;
1840 270.0f, //float jumpMagnitude;
1841 0.4f, //float knockbackScale;
1842 { PCL_ALIEN_LEVEL4, PCL_NONE, PCL_NONE }, //int children[ 3 ];
1843 LEVEL3_UPG_COST, //int cost;
1844 LEVEL3_UPG_VALUE //int value;
1845 },
1846 {
1847 PCL_ALIEN_LEVEL4, //int classnum;
1848 "level4", //char *classname;
1849 "Big Mofo", //char *humanname;
1850 "mofo", //char *modelname;
1851 1.0f, //float modelScale;
1852 "default", //char *skinname;
1853 2.0f, //float shadowScale;
1854 "alien_general_hud", //char *hudname;
1855 ( 1 << S3 ), //int stages
1856 { -30, -30, -20 }, //vec3_t mins;
1857 { 30, 30, 20 }, //vec3_t maxs;
1858 { 30, 30, 20 }, //vec3_t crouchmaxs;
1859 { -15, -15, -4 }, //vec3_t deadmins;
1860 { 15, 15, 4 }, //vec3_t deadmaxs;
1861 0.0f, //float zOffset
1862 35, 35, //int viewheight, crouchviewheight;
1863 LEVEL4_HEALTH, //int health;
1864 0.0f, //float fallDamage;
1865 LEVEL4_REGEN, //int regenRate;
1866 SCA_NOWEAPONDRIFT|
1867 SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
1868 WP_ALEVEL4, //weapon_t startWeapon
1869 0.0f, //float buildDist;
1870 90, //int fov;
1871 0.001f, //float bob;
1872 1.1f, //float bobCycle;
1873 100, //int steptime;
1874 LEVEL4_SPEED, //float speed;
1875 10.0f, //float acceleration;
1876 1.0f, //float airAcceleration;
1877 6.0f, //float friction;
1878 100.0f, //float stopSpeed;
1879 170.0f, //float jumpMagnitude;
1880 0.1f, //float knockbackScale;
1881 { PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
1882 LEVEL4_COST, //int cost;
1883 LEVEL4_VALUE //int value;
1884 },
1885 {
1886 PCL_HUMAN, //int classnum;
1887 "human_base", //char *classname;
1888 "Human", //char *humanname;
1889 "sarge", //char *modelname;
1890 1.0f, //float modelScale;
1891 "default", //char *skinname;
1892 1.0f, //float shadowScale;
1893 "human_hud", //char *hudname;
1894 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
1895 { -15, -15, -24 }, //vec3_t mins;
1896 { 15, 15, 32 }, //vec3_t maxs;
1897 { 15, 15, 16 }, //vec3_t crouchmaxs;
1898 { -15, -15, -4 }, //vec3_t deadmins;
1899 { 15, 15, 4 }, //vec3_t deadmaxs;
1900 0.0f, //float zOffset
1901 26, 12, //int viewheight, crouchviewheight;
1902 100, //int health;
1903 1.0f, //float fallDamage;
1904 0, //int regenRate;
1905 SCA_TAKESFALLDAMAGE|
1906 SCA_CANUSELADDERS, //int abilities;
1907 WP_NONE, //special-cased in g_client.c //weapon_t startWeapon
1908 110.0f, //float buildDist;
1909 90, //int fov;
1910 0.002f, //float bob;
1911 1.0f, //float bobCycle;
1912 100, //int steptime;
1913 1.0f, //float speed;
1914 10.0f, //float acceleration;
1915 1.0f, //float airAcceleration;
1916 6.0f, //float friction;
1917 100.0f, //float stopSpeed;
1918 220.0f, //float jumpMagnitude;
1919 1.0f, //float knockbackScale;
1920 { PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
1921 0, //int cost;
1922 0 //int value;
1923 },
1924 {
1925 //this isn't a real class, but a dummy to force the client to precache the model
1926 //FIXME: one day do this in a less hacky fashion
1927 PCL_HUMAN_BSUIT, "human_bsuit", "bsuit",
1928
1929 "keel",
1930 1.0f,
1931 "default",
1932 1.0f,
1933
1934 "bsuit", ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), { 0, 0, 0 }, { 0, 0, 0, },
1935 { 0, 0, 0, }, { 0, 0, 0, }, { 0, 0, 0, }, 0.0f, 0, 0, 0, 0.0f, 0, 0, WP_NONE, 0.0f, 0,
1936 0.0f, 1.0f, 0, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 270.0f, 1.0f, { PCL_NONE, PCL_NONE, PCL_NONE }, 0, 0
1937 }
1938 };
1939
1940 int bg_numPclasses = sizeof( bg_classList ) / sizeof( bg_classList[ 0 ] );
1941
1942 //separate from bg_classList to work around char struct init bug
1943 classAttributeOverrides_t bg_classOverrideList[ PCL_NUM_CLASSES ];
1944
1945 /*
1946 ==============
1947 BG_FindClassNumForName
1948 ==============
1949 */
BG_FindClassNumForName(char * name)1950 int BG_FindClassNumForName( char *name )
1951 {
1952 int i;
1953
1954 for( i = 0; i < bg_numPclasses; i++ )
1955 {
1956 if( !Q_stricmp( bg_classList[ i ].className, name ) )
1957 return bg_classList[ i ].classNum;
1958 }
1959
1960 //wimp out
1961 return PCL_NONE;
1962 }
1963
1964 /*
1965 ==============
1966 BG_FindNameForClassNum
1967 ==============
1968 */
BG_FindNameForClassNum(int pclass)1969 char *BG_FindNameForClassNum( int pclass )
1970 {
1971 int i;
1972
1973 for( i = 0; i < bg_numPclasses; i++ )
1974 {
1975 if( bg_classList[ i ].classNum == pclass )
1976 return bg_classList[ i ].className;
1977 }
1978
1979 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindNameForClassNum\n" );
1980 //wimp out
1981 return 0;
1982 }
1983
1984 /*
1985 ==============
1986 BG_FindHumanNameForClassNum
1987 ==============
1988 */
BG_FindHumanNameForClassNum(int pclass)1989 char *BG_FindHumanNameForClassNum( int pclass )
1990 {
1991 int i;
1992
1993 if( bg_classOverrideList[ pclass ].humanName[ 0 ] != 0 )
1994 return bg_classOverrideList[ pclass ].humanName;
1995
1996 for( i = 0; i < bg_numPclasses; i++ )
1997 {
1998 if( bg_classList[ i ].classNum == pclass )
1999 return bg_classList[ i ].humanName;
2000 }
2001
2002 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHumanNameForClassNum\n" );
2003 //wimp out
2004 return 0;
2005 }
2006
2007 /*
2008 ==============
2009 BG_FindModelNameForClass
2010 ==============
2011 */
BG_FindModelNameForClass(int pclass)2012 char *BG_FindModelNameForClass( int pclass )
2013 {
2014 int i;
2015
2016 if( bg_classOverrideList[ pclass ].modelName[ 0 ] != 0 )
2017 return bg_classOverrideList[ pclass ].modelName;
2018
2019 for( i = 0; i < bg_numPclasses; i++ )
2020 {
2021 if( bg_classList[ i ].classNum == pclass )
2022 return bg_classList[ i ].modelName;
2023 }
2024
2025 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelNameForClass\n" );
2026 //note: must return a valid modelName!
2027 return bg_classList[ 0 ].modelName;
2028 }
2029
2030 /*
2031 ==============
2032 BG_FindModelScaleForClass
2033 ==============
2034 */
BG_FindModelScaleForClass(int pclass)2035 float BG_FindModelScaleForClass( int pclass )
2036 {
2037 int i;
2038
2039 if( bg_classOverrideList[ pclass ].modelScale != 0.0f )
2040 return bg_classOverrideList[ pclass ].modelScale;
2041
2042 for( i = 0; i < bg_numPclasses; i++ )
2043 {
2044 if( bg_classList[ i ].classNum == pclass )
2045 {
2046 return bg_classList[ i ].modelScale;
2047 }
2048 }
2049
2050 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelScaleForClass( %d )\n", pclass );
2051 return 1.0f;
2052 }
2053
2054 /*
2055 ==============
2056 BG_FindSkinNameForClass
2057 ==============
2058 */
BG_FindSkinNameForClass(int pclass)2059 char *BG_FindSkinNameForClass( int pclass )
2060 {
2061 int i;
2062
2063 if( bg_classOverrideList[ pclass ].skinName[ 0 ] != 0 )
2064 return bg_classOverrideList[ pclass ].skinName;
2065
2066 for( i = 0; i < bg_numPclasses; i++ )
2067 {
2068 if( bg_classList[ i ].classNum == pclass )
2069 return bg_classList[ i ].skinName;
2070 }
2071
2072 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSkinNameForClass\n" );
2073 //note: must return a valid modelName!
2074 return bg_classList[ 0 ].skinName;
2075 }
2076
2077 /*
2078 ==============
2079 BG_FindShadowScaleForClass
2080 ==============
2081 */
BG_FindShadowScaleForClass(int pclass)2082 float BG_FindShadowScaleForClass( int pclass )
2083 {
2084 int i;
2085
2086 if( bg_classOverrideList[ pclass ].shadowScale != 0.0f )
2087 return bg_classOverrideList[ pclass ].shadowScale;
2088
2089 for( i = 0; i < bg_numPclasses; i++ )
2090 {
2091 if( bg_classList[ i ].classNum == pclass )
2092 {
2093 return bg_classList[ i ].shadowScale;
2094 }
2095 }
2096
2097 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindShadowScaleForClass( %d )\n", pclass );
2098 return 1.0f;
2099 }
2100
2101 /*
2102 ==============
2103 BG_FindHudNameForClass
2104 ==============
2105 */
BG_FindHudNameForClass(int pclass)2106 char *BG_FindHudNameForClass( int pclass )
2107 {
2108 int i;
2109
2110 if( bg_classOverrideList[ pclass ].hudName[ 0 ] != 0 )
2111 return bg_classOverrideList[ pclass ].hudName;
2112
2113 for( i = 0; i < bg_numPclasses; i++ )
2114 {
2115 if( bg_classList[ i ].classNum == pclass )
2116 return bg_classList[ i ].hudName;
2117 }
2118
2119 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHudNameForClass\n" );
2120 //note: must return a valid hudName!
2121 return bg_classList[ 0 ].hudName;
2122 }
2123
2124 /*
2125 ==============
2126 BG_FindStagesForClass
2127 ==============
2128 */
BG_FindStagesForClass(int pclass,stage_t stage)2129 qboolean BG_FindStagesForClass( int pclass, stage_t stage )
2130 {
2131 int i;
2132
2133 for( i = 0; i < bg_numPclasses; i++ )
2134 {
2135 if( bg_classList[ i ].classNum == pclass )
2136 {
2137 if( bg_classList[ i ].stages & ( 1 << stage ) )
2138 return qtrue;
2139 else
2140 return qfalse;
2141 }
2142 }
2143
2144 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStagesForClass\n" );
2145 return qfalse;
2146 }
2147
2148 /*
2149 ==============
2150 BG_FindBBoxForClass
2151 ==============
2152 */
BG_FindBBoxForClass(int pclass,vec3_t mins,vec3_t maxs,vec3_t cmaxs,vec3_t dmins,vec3_t dmaxs)2153 void BG_FindBBoxForClass( int pclass, vec3_t mins, vec3_t maxs, vec3_t cmaxs, vec3_t dmins, vec3_t dmaxs )
2154 {
2155 int i;
2156
2157 for( i = 0; i < bg_numPclasses; i++ )
2158 {
2159 if( bg_classList[ i ].classNum == pclass )
2160 {
2161 if( mins != NULL )
2162 {
2163 VectorCopy( bg_classList[ i ].mins, mins );
2164
2165 if( VectorLength( bg_classOverrideList[ pclass ].mins ) )
2166 VectorCopy( bg_classOverrideList[ pclass ].mins, mins );
2167 }
2168
2169 if( maxs != NULL )
2170 {
2171 VectorCopy( bg_classList[ i ].maxs, maxs );
2172
2173 if( VectorLength( bg_classOverrideList[ pclass ].maxs ) )
2174 VectorCopy( bg_classOverrideList[ pclass ].maxs, maxs );
2175 }
2176
2177 if( cmaxs != NULL )
2178 {
2179 VectorCopy( bg_classList[ i ].crouchMaxs, cmaxs );
2180
2181 if( VectorLength( bg_classOverrideList[ pclass ].crouchMaxs ) )
2182 VectorCopy( bg_classOverrideList[ pclass ].crouchMaxs, cmaxs );
2183 }
2184
2185 if( dmins != NULL )
2186 {
2187 VectorCopy( bg_classList[ i ].deadMins, dmins );
2188
2189 if( VectorLength( bg_classOverrideList[ pclass ].deadMins ) )
2190 VectorCopy( bg_classOverrideList[ pclass ].deadMins, dmins );
2191 }
2192
2193 if( dmaxs != NULL )
2194 {
2195 VectorCopy( bg_classList[ i ].deadMaxs, dmaxs );
2196
2197 if( VectorLength( bg_classOverrideList[ pclass ].deadMaxs ) )
2198 VectorCopy( bg_classOverrideList[ pclass ].deadMaxs, dmaxs );
2199 }
2200
2201 return;
2202 }
2203 }
2204
2205 if( mins != NULL )
2206 VectorCopy( bg_classList[ 0 ].mins, mins );
2207
2208 if( maxs != NULL )
2209 VectorCopy( bg_classList[ 0 ].maxs, maxs );
2210
2211 if( cmaxs != NULL )
2212 VectorCopy( bg_classList[ 0 ].crouchMaxs, cmaxs );
2213
2214 if( dmins != NULL )
2215 VectorCopy( bg_classList[ 0 ].deadMins, dmins );
2216
2217 if( dmaxs != NULL )
2218 VectorCopy( bg_classList[ 0 ].deadMaxs, dmaxs );
2219 }
2220
2221 /*
2222 ==============
2223 BG_FindZOffsetForClass
2224 ==============
2225 */
BG_FindZOffsetForClass(int pclass)2226 float BG_FindZOffsetForClass( int pclass )
2227 {
2228 int i;
2229
2230 if( bg_classOverrideList[ pclass ].zOffset != 0.0f )
2231 return bg_classOverrideList[ pclass ].zOffset;
2232
2233 for( i = 0; i < bg_numPclasses; i++ )
2234 {
2235 if( bg_classList[ i ].classNum == pclass )
2236 {
2237 return bg_classList[ i ].zOffset;
2238 }
2239 }
2240
2241 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindZOffsetForClass\n" );
2242 return 0.0f;
2243 }
2244
2245 /*
2246 ==============
2247 BG_FindViewheightForClass
2248 ==============
2249 */
BG_FindViewheightForClass(int pclass,int * viewheight,int * cViewheight)2250 void BG_FindViewheightForClass( int pclass, int *viewheight, int *cViewheight )
2251 {
2252 int i;
2253
2254 for( i = 0; i < bg_numPclasses; i++ )
2255 {
2256 if( bg_classList[ i ].classNum == pclass )
2257 {
2258 if( viewheight != NULL )
2259 *viewheight = bg_classList[ i ].viewheight;
2260
2261 if( cViewheight != NULL )
2262 *cViewheight = bg_classList[ i ].crouchViewheight;
2263
2264 return;
2265 }
2266 }
2267
2268 if( viewheight != NULL )
2269 *viewheight = bg_classList[ 0 ].viewheight;
2270
2271 if( cViewheight != NULL )
2272 *cViewheight = bg_classList[ 0 ].crouchViewheight;
2273 }
2274
2275 /*
2276 ==============
2277 BG_FindHealthForClass
2278 ==============
2279 */
BG_FindHealthForClass(int pclass)2280 int BG_FindHealthForClass( int pclass )
2281 {
2282 int i;
2283
2284 for( i = 0; i < bg_numPclasses; i++ )
2285 {
2286 if( bg_classList[ i ].classNum == pclass )
2287 {
2288 return bg_classList[ i ].health;
2289 }
2290 }
2291
2292 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHealthForClass\n" );
2293 return 100;
2294 }
2295
2296 /*
2297 ==============
2298 BG_FindFallDamageForClass
2299 ==============
2300 */
BG_FindFallDamageForClass(int pclass)2301 float BG_FindFallDamageForClass( int pclass )
2302 {
2303 int i;
2304
2305 for( i = 0; i < bg_numPclasses; i++ )
2306 {
2307 if( bg_classList[ i ].classNum == pclass )
2308 {
2309 return bg_classList[ i ].fallDamage;
2310 }
2311 }
2312
2313 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFallDamageForClass\n" );
2314 return 100;
2315 }
2316
2317 /*
2318 ==============
2319 BG_FindRegenRateForClass
2320 ==============
2321 */
BG_FindRegenRateForClass(int pclass)2322 int BG_FindRegenRateForClass( int pclass )
2323 {
2324 int i;
2325
2326 for( i = 0; i < bg_numPclasses; i++ )
2327 {
2328 if( bg_classList[ i ].classNum == pclass )
2329 {
2330 return bg_classList[ i ].regenRate;
2331 }
2332 }
2333
2334 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindRegenRateForClass\n" );
2335 return 0;
2336 }
2337
2338 /*
2339 ==============
2340 BG_FindFovForClass
2341 ==============
2342 */
BG_FindFovForClass(int pclass)2343 int BG_FindFovForClass( int pclass )
2344 {
2345 int i;
2346
2347 for( i = 0; i < bg_numPclasses; i++ )
2348 {
2349 if( bg_classList[ i ].classNum == pclass )
2350 {
2351 return bg_classList[ i ].fov;
2352 }
2353 }
2354
2355 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFovForClass\n" );
2356 return 90;
2357 }
2358
2359 /*
2360 ==============
2361 BG_FindBobForClass
2362 ==============
2363 */
BG_FindBobForClass(int pclass)2364 float BG_FindBobForClass( int pclass )
2365 {
2366 int i;
2367
2368 for( i = 0; i < bg_numPclasses; i++ )
2369 {
2370 if( bg_classList[ i ].classNum == pclass )
2371 {
2372 return bg_classList[ i ].bob;
2373 }
2374 }
2375
2376 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBobForClass\n" );
2377 return 0.002;
2378 }
2379
2380 /*
2381 ==============
2382 BG_FindBobCycleForClass
2383 ==============
2384 */
BG_FindBobCycleForClass(int pclass)2385 float BG_FindBobCycleForClass( int pclass )
2386 {
2387 int i;
2388
2389 for( i = 0; i < bg_numPclasses; i++ )
2390 {
2391 if( bg_classList[ i ].classNum == pclass )
2392 {
2393 return bg_classList[ i ].bobCycle;
2394 }
2395 }
2396
2397 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBobCycleForClass\n" );
2398 return 1.0f;
2399 }
2400
2401 /*
2402 ==============
2403 BG_FindSpeedForClass
2404 ==============
2405 */
BG_FindSpeedForClass(int pclass)2406 float BG_FindSpeedForClass( int pclass )
2407 {
2408 int i;
2409
2410 for( i = 0; i < bg_numPclasses; i++ )
2411 {
2412 if( bg_classList[ i ].classNum == pclass )
2413 {
2414 return bg_classList[ i ].speed;
2415 }
2416 }
2417
2418 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSpeedForClass\n" );
2419 return 1.0f;
2420 }
2421
2422 /*
2423 ==============
2424 BG_FindAccelerationForClass
2425 ==============
2426 */
BG_FindAccelerationForClass(int pclass)2427 float BG_FindAccelerationForClass( int pclass )
2428 {
2429 int i;
2430
2431 for( i = 0; i < bg_numPclasses; i++ )
2432 {
2433 if( bg_classList[ i ].classNum == pclass )
2434 {
2435 return bg_classList[ i ].acceleration;
2436 }
2437 }
2438
2439 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindAccelerationForClass\n" );
2440 return 10.0f;
2441 }
2442
2443 /*
2444 ==============
2445 BG_FindAirAccelerationForClass
2446 ==============
2447 */
BG_FindAirAccelerationForClass(int pclass)2448 float BG_FindAirAccelerationForClass( int pclass )
2449 {
2450 int i;
2451
2452 for( i = 0; i < bg_numPclasses; i++ )
2453 {
2454 if( bg_classList[ i ].classNum == pclass )
2455 {
2456 return bg_classList[ i ].airAcceleration;
2457 }
2458 }
2459
2460 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindAirAccelerationForClass\n" );
2461 return 1.0f;
2462 }
2463
2464 /*
2465 ==============
2466 BG_FindFrictionForClass
2467 ==============
2468 */
BG_FindFrictionForClass(int pclass)2469 float BG_FindFrictionForClass( int pclass )
2470 {
2471 int i;
2472
2473 for( i = 0; i < bg_numPclasses; i++ )
2474 {
2475 if( bg_classList[ i ].classNum == pclass )
2476 {
2477 return bg_classList[ i ].friction;
2478 }
2479 }
2480
2481 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFrictionForClass\n" );
2482 return 6.0f;
2483 }
2484
2485 /*
2486 ==============
2487 BG_FindStopSpeedForClass
2488 ==============
2489 */
BG_FindStopSpeedForClass(int pclass)2490 float BG_FindStopSpeedForClass( int pclass )
2491 {
2492 int i;
2493
2494 for( i = 0; i < bg_numPclasses; i++ )
2495 {
2496 if( bg_classList[ i ].classNum == pclass )
2497 {
2498 return bg_classList[ i ].stopSpeed;
2499 }
2500 }
2501
2502 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStopSpeedForClass\n" );
2503 return 100.0f;
2504 }
2505
2506 /*
2507 ==============
2508 BG_FindJumpMagnitudeForClass
2509 ==============
2510 */
BG_FindJumpMagnitudeForClass(int pclass)2511 float BG_FindJumpMagnitudeForClass( int pclass )
2512 {
2513 int i;
2514
2515 for( i = 0; i < bg_numPclasses; i++ )
2516 {
2517 if( bg_classList[ i ].classNum == pclass )
2518 {
2519 return bg_classList[ i ].jumpMagnitude;
2520 }
2521 }
2522
2523 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindJumpMagnitudeForClass\n" );
2524 return 270.0f;
2525 }
2526
2527 /*
2528 ==============
2529 BG_FindKnockbackScaleForClass
2530 ==============
2531 */
BG_FindKnockbackScaleForClass(int pclass)2532 float BG_FindKnockbackScaleForClass( int pclass )
2533 {
2534 int i;
2535
2536 for( i = 0; i < bg_numPclasses; i++ )
2537 {
2538 if( bg_classList[ i ].classNum == pclass )
2539 {
2540 return bg_classList[ i ].knockbackScale;
2541 }
2542 }
2543
2544 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindKnockbackScaleForClass\n" );
2545 return 1.0f;
2546 }
2547
2548 /*
2549 ==============
2550 BG_FindSteptimeForClass
2551 ==============
2552 */
BG_FindSteptimeForClass(int pclass)2553 int BG_FindSteptimeForClass( int pclass )
2554 {
2555 int i;
2556
2557 for( i = 0; i < bg_numPclasses; i++ )
2558 {
2559 if( bg_classList[ i ].classNum == pclass )
2560 {
2561 return bg_classList[ i ].steptime;
2562 }
2563 }
2564
2565 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSteptimeForClass\n" );
2566 return 200;
2567 }
2568
2569 /*
2570 ==============
2571 BG_ClassHasAbility
2572 ==============
2573 */
BG_ClassHasAbility(int pclass,int ability)2574 qboolean BG_ClassHasAbility( int pclass, int ability )
2575 {
2576 int i;
2577
2578 for( i = 0; i < bg_numPclasses; i++ )
2579 {
2580 if( bg_classList[ i ].classNum == pclass )
2581 {
2582 return ( bg_classList[ i ].abilities & ability );
2583 }
2584 }
2585
2586 return qfalse;
2587 }
2588
2589 /*
2590 ==============
2591 BG_FindStartWeaponForClass
2592 ==============
2593 */
BG_FindStartWeaponForClass(int pclass)2594 weapon_t BG_FindStartWeaponForClass( int pclass )
2595 {
2596 int i;
2597
2598 for( i = 0; i < bg_numPclasses; i++ )
2599 {
2600 if( bg_classList[ i ].classNum == pclass )
2601 {
2602 return bg_classList[ i ].startWeapon;
2603 }
2604 }
2605
2606 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStartWeaponForClass\n" );
2607 return WP_NONE;
2608 }
2609
2610 /*
2611 ==============
2612 BG_FindBuildDistForClass
2613 ==============
2614 */
BG_FindBuildDistForClass(int pclass)2615 float BG_FindBuildDistForClass( int pclass )
2616 {
2617 int i;
2618
2619 for( i = 0; i < bg_numPclasses; i++ )
2620 {
2621 if( bg_classList[ i ].classNum == pclass )
2622 {
2623 return bg_classList[ i ].buildDist;
2624 }
2625 }
2626
2627 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBuildDistForClass\n" );
2628 return 0.0f;
2629 }
2630
2631 /*
2632 ==============
2633 BG_ClassCanEvolveFromTo
2634 ==============
2635 */
BG_ClassCanEvolveFromTo(int fclass,int tclass,int credits,int num)2636 int BG_ClassCanEvolveFromTo( int fclass, int tclass, int credits, int num )
2637 {
2638 int i, j, cost;
2639
2640 cost = BG_FindCostOfClass( tclass );
2641
2642 //base case
2643 if( credits < cost )
2644 return -1;
2645
2646 if( fclass == PCL_NONE || tclass == PCL_NONE )
2647 return -1;
2648
2649 for( i = 0; i < bg_numPclasses; i++ )
2650 {
2651 if( bg_classList[ i ].classNum == fclass )
2652 {
2653 for( j = 0; j < 3; j++ )
2654 if( bg_classList[ i ].children[ j ] == tclass )
2655 return num + cost;
2656
2657 for( j = 0; j < 3; j++ )
2658 {
2659 int sub;
2660
2661 cost = BG_FindCostOfClass( bg_classList[ i ].children[ j ] );
2662 sub = BG_ClassCanEvolveFromTo( bg_classList[ i ].children[ j ],
2663 tclass, credits - cost, num + cost );
2664 if( sub >= 0 )
2665 return sub;
2666 }
2667
2668 return -1; //may as well return by this point
2669 }
2670 }
2671
2672 return -1;
2673 }
2674
2675 /*
2676 ==============
2677 BG_FindValueOfClass
2678 ==============
2679 */
BG_FindValueOfClass(int pclass)2680 int BG_FindValueOfClass( int pclass )
2681 {
2682 int i;
2683
2684 for( i = 0; i < bg_numPclasses; i++ )
2685 {
2686 if( bg_classList[ i ].classNum == pclass )
2687 {
2688 return bg_classList[ i ].value;
2689 }
2690 }
2691
2692 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindValueOfClass\n" );
2693 return 0;
2694 }
2695
2696 /*
2697 ==============
2698 BG_FindCostOfClass
2699 ==============
2700 */
BG_FindCostOfClass(int pclass)2701 int BG_FindCostOfClass( int pclass )
2702 {
2703 int i;
2704
2705 for( i = 0; i < bg_numPclasses; i++ )
2706 {
2707 if( bg_classList[ i ].classNum == pclass )
2708 {
2709 return bg_classList[ i ].cost;
2710 }
2711 }
2712
2713 Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindCostOfClass\n" );
2714 return 0;
2715 }
2716
2717 /*
2718 ==============
2719 BG_FindOverrideForClass
2720 ==============
2721 */
BG_FindOverrideForClass(int pclass)2722 static classAttributeOverrides_t *BG_FindOverrideForClass( int pclass )
2723 {
2724 return &bg_classOverrideList[ pclass ];
2725 }
2726
2727 /*
2728 ======================
2729 BG_ParseClassFile
2730
2731 Parses a configuration file describing a class
2732 ======================
2733 */
BG_ParseClassFile(const char * filename,classAttributeOverrides_t * cao)2734 static qboolean BG_ParseClassFile( const char *filename, classAttributeOverrides_t *cao )
2735 {
2736 char *text_p;
2737 int i;
2738 int len;
2739 char *token;
2740 char text[ 20000 ];
2741 fileHandle_t f;
2742 float scale = 0.0f;
2743
2744
2745 // load the file
2746 len = trap_FS_FOpenFile( filename, &f, FS_READ );
2747 if( len <= 0 )
2748 return qfalse;
2749
2750 if( len >= sizeof( text ) - 1 )
2751 {
2752 Com_Printf( S_COLOR_RED "ERROR: Class file %s too long\n", filename );
2753 return qfalse;
2754 }
2755
2756 trap_FS_Read( text, len, f );
2757 text[ len ] = 0;
2758 trap_FS_FCloseFile( f );
2759
2760 // parse the text
2761 text_p = text;
2762
2763 // read optional parameters
2764 while( 1 )
2765 {
2766 token = COM_Parse( &text_p );
2767
2768 if( !token )
2769 break;
2770
2771 if( !Q_stricmp( token, "" ) )
2772 break;
2773
2774 if( !Q_stricmp( token, "model" ) )
2775 {
2776 token = COM_Parse( &text_p );
2777 if( !token )
2778 break;
2779
2780 Q_strncpyz( cao->modelName, token, sizeof( cao->modelName ) );
2781
2782 continue;
2783 }
2784 else if( !Q_stricmp( token, "skin" ) )
2785 {
2786 token = COM_Parse( &text_p );
2787 if( !token )
2788 break;
2789
2790 Q_strncpyz( cao->skinName, token, sizeof( cao->skinName ) );
2791
2792 continue;
2793 }
2794 else if( !Q_stricmp( token, "hud" ) )
2795 {
2796 token = COM_Parse( &text_p );
2797 if( !token )
2798 break;
2799
2800 Q_strncpyz( cao->hudName, token, sizeof( cao->hudName ) );
2801
2802 continue;
2803 }
2804 else if( !Q_stricmp( token, "modelScale" ) )
2805 {
2806 token = COM_Parse( &text_p );
2807 if( !token )
2808 break;
2809
2810 scale = atof( token );
2811
2812 if( scale < 0.0f )
2813 scale = 0.0f;
2814
2815 cao->modelScale = scale;
2816
2817 continue;
2818 }
2819 else if( !Q_stricmp( token, "shadowScale" ) )
2820 {
2821 token = COM_Parse( &text_p );
2822 if( !token )
2823 break;
2824
2825 scale = atof( token );
2826
2827 if( scale < 0.0f )
2828 scale = 0.0f;
2829
2830 cao->shadowScale = scale;
2831
2832 continue;
2833 }
2834 else if( !Q_stricmp( token, "mins" ) )
2835 {
2836 for( i = 0; i <= 2; i++ )
2837 {
2838 token = COM_Parse( &text_p );
2839 if( !token )
2840 break;
2841
2842 cao->mins[ i ] = atof( token );
2843 }
2844
2845 continue;
2846 }
2847 else if( !Q_stricmp( token, "maxs" ) )
2848 {
2849 for( i = 0; i <= 2; i++ )
2850 {
2851 token = COM_Parse( &text_p );
2852 if( !token )
2853 break;
2854
2855 cao->maxs[ i ] = atof( token );
2856 }
2857
2858 continue;
2859 }
2860 else if( !Q_stricmp( token, "deadMins" ) )
2861 {
2862 for( i = 0; i <= 2; i++ )
2863 {
2864 token = COM_Parse( &text_p );
2865 if( !token )
2866 break;
2867
2868 cao->deadMins[ i ] = atof( token );
2869 }
2870
2871 continue;
2872 }
2873 else if( !Q_stricmp( token, "deadMaxs" ) )
2874 {
2875 for( i = 0; i <= 2; i++ )
2876 {
2877 token = COM_Parse( &text_p );
2878 if( !token )
2879 break;
2880
2881 cao->deadMaxs[ i ] = atof( token );
2882 }
2883
2884 continue;
2885 }
2886 else if( !Q_stricmp( token, "crouchMaxs" ) )
2887 {
2888 for( i = 0; i <= 2; i++ )
2889 {
2890 token = COM_Parse( &text_p );
2891 if( !token )
2892 break;
2893
2894 cao->crouchMaxs[ i ] = atof( token );
2895 }
2896
2897 continue;
2898 }
2899 else if( !Q_stricmp( token, "zOffset" ) )
2900 {
2901 float offset;
2902
2903 token = COM_Parse( &text_p );
2904 if( !token )
2905 break;
2906
2907 offset = atof( token );
2908
2909 cao->zOffset = offset;
2910
2911 continue;
2912 }
2913 else if( !Q_stricmp( token, "name" ) )
2914 {
2915 token = COM_Parse( &text_p );
2916 if( !token )
2917 break;
2918
2919 Q_strncpyz( cao->humanName, token, sizeof( cao->humanName ) );
2920
2921 continue;
2922 }
2923
2924
2925 Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token );
2926 return qfalse;
2927 }
2928
2929 return qtrue;
2930 }
2931
2932 /*
2933 ===============
2934 BG_InitClassOverrides
2935
2936 Set any overrides specfied by file
2937 ===============
2938 */
BG_InitClassOverrides(void)2939 void BG_InitClassOverrides( void )
2940 {
2941 int i;
2942 classAttributeOverrides_t *cao;
2943
2944 for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
2945 {
2946 cao = BG_FindOverrideForClass( i );
2947
2948 BG_ParseClassFile( va( "overrides/classes/%s.cfg", BG_FindNameForClassNum( i ) ), cao );
2949 }
2950 }
2951
2952 ////////////////////////////////////////////////////////////////////////////////
2953
2954 weaponAttributes_t bg_weapons[ ] =
2955 {
2956 {
2957 WP_BLASTER, //int weaponNum;
2958 0, //int price;
2959 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
2960 0, //int slots;
2961 "blaster", //char *weaponName;
2962 "Blaster", //char *weaponHumanName;
2963 0, //int maxAmmo;
2964 0, //int maxClips;
2965 qtrue, //int infiniteAmmo;
2966 qfalse, //int usesEnergy;
2967 BLASTER_REPEAT, //int repeatRate1;
2968 0, //int repeatRate2;
2969 0, //int repeatRate3;
2970 0, //int reloadTime;
2971 qfalse, //qboolean hasAltMode;
2972 qfalse, //qboolean hasThirdMode;
2973 qfalse, //qboolean canZoom;
2974 90.0f, //float zoomFov;
2975 qfalse, //qboolean purchasable;
2976 0, //int buildDelay;
2977 WUT_HUMANS //WUTeam_t team;
2978 },
2979 {
2980 WP_MACHINEGUN, //int weaponNum;
2981 RIFLE_PRICE, //int price;
2982 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
2983 SLOT_WEAPON, //int slots;
2984 "rifle", //char *weaponName;
2985 "Rifle", //char *weaponHumanName;
2986 RIFLE_CLIPSIZE, //int maxAmmo;
2987 RIFLE_MAXCLIPS, //int maxClips;
2988 qfalse, //int infiniteAmmo;
2989 qfalse, //int usesEnergy;
2990 RIFLE_REPEAT, //int repeatRate1;
2991 0, //int repeatRate2;
2992 0, //int repeatRate3;
2993 RIFLE_RELOAD, //int reloadTime;
2994 qfalse, //qboolean hasAltMode;
2995 qfalse, //qboolean hasThirdMode;
2996 qfalse, //qboolean canZoom;
2997 90.0f, //float zoomFov;
2998 qtrue, //qboolean purchasable;
2999 0, //int buildDelay;
3000 WUT_HUMANS //WUTeam_t team;
3001 },
3002 {
3003 WP_SHOTGUN, //int weaponNum;
3004 SHOTGUN_PRICE, //int price;
3005 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3006 SLOT_WEAPON, //int slots;
3007 "shotgun", //char *weaponName;
3008 "Shotgun", //char *weaponHumanName;
3009 SHOTGUN_SHELLS, //int maxAmmo;
3010 SHOTGUN_MAXCLIPS, //int maxClips;
3011 qfalse, //int infiniteAmmo;
3012 qfalse, //int usesEnergy;
3013 SHOTGUN_REPEAT, //int repeatRate1;
3014 0, //int repeatRate2;
3015 0, //int repeatRate3;
3016 SHOTGUN_RELOAD, //int reloadTime;
3017 qfalse, //qboolean hasAltMode;
3018 qfalse, //qboolean hasThirdMode;
3019 qfalse, //qboolean canZoom;
3020 90.0f, //float zoomFov;
3021 qtrue, //qboolean purchasable;
3022 0, //int buildDelay;
3023 WUT_HUMANS //WUTeam_t team;
3024 },
3025 {
3026 WP_FLAMER, //int weaponNum;
3027 FLAMER_PRICE, //int price;
3028 ( 1 << S2 )|( 1 << S3 ), //int stages
3029 SLOT_WEAPON, //int slots;
3030 "flamer", //char *weaponName;
3031 "Flame Thrower", //char *weaponHumanName;
3032 FLAMER_GAS, //int maxAmmo;
3033 0, //int maxClips;
3034 qfalse, //int infiniteAmmo;
3035 qfalse, //int usesEnergy;
3036 FLAMER_REPEAT, //int repeatRate1;
3037 0, //int repeatRate2;
3038 0, //int repeatRate3;
3039 0, //int reloadTime;
3040 qfalse, //qboolean hasAltMode;
3041 qfalse, //qboolean hasThirdMode;
3042 qfalse, //qboolean canZoom;
3043 90.0f, //float zoomFov;
3044 qtrue, //qboolean purchasable;
3045 0, //int buildDelay;
3046 WUT_HUMANS //WUTeam_t team;
3047 },
3048 {
3049 WP_CHAINGUN, //int weaponNum;
3050 CHAINGUN_PRICE, //int price;
3051 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3052 SLOT_WEAPON, //int slots;
3053 "chaingun", //char *weaponName;
3054 "Chaingun", //char *weaponHumanName;
3055 CHAINGUN_BULLETS, //int maxAmmo;
3056 0, //int maxClips;
3057 qfalse, //int infiniteAmmo;
3058 qfalse, //int usesEnergy;
3059 CHAINGUN_REPEAT, //int repeatRate1;
3060 0, //int repeatRate2;
3061 0, //int repeatRate3;
3062 0, //int reloadTime;
3063 qfalse, //qboolean hasAltMode;
3064 qfalse, //qboolean hasThirdMode;
3065 qfalse, //qboolean canZoom;
3066 90.0f, //float zoomFov;
3067 qtrue, //qboolean purchasable;
3068 0, //int buildDelay;
3069 WUT_HUMANS //WUTeam_t team;
3070 },
3071 {
3072 WP_MASS_DRIVER, //int weaponNum;
3073 MDRIVER_PRICE, //int price;
3074 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3075 SLOT_WEAPON, //int slots;
3076 "mdriver", //char *weaponName;
3077 "Mass Driver", //char *weaponHumanName;
3078 MDRIVER_CLIPSIZE, //int maxAmmo;
3079 MDRIVER_MAXCLIPS, //int maxClips;
3080 qfalse, //int infiniteAmmo;
3081 qtrue, //int usesEnergy;
3082 MDRIVER_REPEAT, //int repeatRate1;
3083 0, //int repeatRate2;
3084 0, //int repeatRate3;
3085 MDRIVER_RELOAD, //int reloadTime;
3086 qfalse, //qboolean hasAltMode;
3087 qfalse, //qboolean hasThirdMode;
3088 qtrue, //qboolean canZoom;
3089 20.0f, //float zoomFov;
3090 qtrue, //qboolean purchasable;
3091 0, //int buildDelay;
3092 WUT_HUMANS //WUTeam_t team;
3093 },
3094 {
3095 WP_PULSE_RIFLE, //int weaponNum;
3096 PRIFLE_PRICE, //int price;
3097 ( 1 << S2 )|( 1 << S3 ), //int stages
3098 SLOT_WEAPON, //int slots;
3099 "prifle", //char *weaponName;
3100 "Pulse Rifle", //char *weaponHumanName;
3101 PRIFLE_CLIPS, //int maxAmmo;
3102 PRIFLE_MAXCLIPS, //int maxClips;
3103 qfalse, //int infiniteAmmo;
3104 qtrue, //int usesEnergy;
3105 PRIFLE_REPEAT, //int repeatRate1;
3106 0, //int repeatRate2;
3107 0, //int repeatRate3;
3108 PRIFLE_RELOAD, //int reloadTime;
3109 qfalse, //qboolean hasAltMode;
3110 qfalse, //qboolean hasThirdMode;
3111 qfalse, //qboolean canZoom;
3112 90.0f, //float zoomFov;
3113 qtrue, //qboolean purchasable;
3114 0, //int buildDelay;
3115 WUT_HUMANS //WUTeam_t team;
3116 },
3117 {
3118 WP_LUCIFER_CANNON, //int weaponNum;
3119 LCANNON_PRICE, //int price;
3120 ( 1 << S3 ), //int stages
3121 SLOT_WEAPON, //int slots;
3122 "lcannon", //char *weaponName;
3123 "Lucifer Cannon", //char *weaponHumanName;
3124 LCANNON_AMMO, //int maxAmmo;
3125 0, //int maxClips;
3126 qfalse, //int infiniteAmmo;
3127 qtrue, //int usesEnergy;
3128 LCANNON_REPEAT, //int repeatRate1;
3129 LCANNON_CHARGEREPEAT, //int repeatRate2;
3130 0, //int repeatRate3;
3131 LCANNON_RELOAD, //int reloadTime;
3132 qtrue, //qboolean hasAltMode;
3133 qfalse, //qboolean hasThirdMode;
3134 qfalse, //qboolean canZoom;
3135 90.0f, //float zoomFov;
3136 qtrue, //qboolean purchasable;
3137 0, //int buildDelay;
3138 WUT_HUMANS //WUTeam_t team;
3139 },
3140 {
3141 WP_LAS_GUN, //int weaponNum;
3142 LASGUN_PRICE, //int price;
3143 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3144 SLOT_WEAPON, //int slots;
3145 "lgun", //char *weaponName;
3146 "Las Gun", //char *weaponHumanName;
3147 LASGUN_AMMO, //int maxAmmo;
3148 0, //int maxClips;
3149 qfalse, //int infiniteAmmo;
3150 qtrue, //int usesEnergy;
3151 LASGUN_REPEAT, //int repeatRate1;
3152 0, //int repeatRate2;
3153 0, //int repeatRate3;
3154 LASGUN_RELOAD, //int reloadTime;
3155 qfalse, //qboolean hasAltMode;
3156 qfalse, //qboolean hasThirdMode;
3157 qfalse, //qboolean canZoom;
3158 90.0f, //float zoomFov;
3159 qtrue, //qboolean purchasable;
3160 0, //int buildDelay;
3161 WUT_HUMANS //WUTeam_t team;
3162 },
3163 {
3164 WP_PAIN_SAW, //int weaponNum;
3165 PAINSAW_PRICE, //int price;
3166 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3167 SLOT_WEAPON, //int slots;
3168 "psaw", //char *weaponName;
3169 "Pain Saw", //char *weaponHumanName;
3170 0, //int maxAmmo;
3171 0, //int maxClips;
3172 qtrue, //int infiniteAmmo;
3173 qfalse, //int usesEnergy;
3174 PAINSAW_REPEAT, //int repeatRate1;
3175 0, //int repeatRate2;
3176 0, //int repeatRate3;
3177 0, //int reloadTime;
3178 qfalse, //qboolean hasAltMode;
3179 qfalse, //qboolean hasThirdMode;
3180 qfalse, //qboolean canZoom;
3181 90.0f, //float zoomFov;
3182 qtrue, //qboolean purchasable;
3183 0, //int buildDelay;
3184 WUT_HUMANS //WUTeam_t team;
3185 },
3186 {
3187 WP_GRENADE, //int weaponNum;
3188 GRENADE_PRICE, //int price;
3189 ( 1 << S2 )|( 1 << S3 ), //int stages
3190 SLOT_NONE, //int slots;
3191 "grenade", //char *weaponName;
3192 "Grenade", //char *weaponHumanName;
3193 1, //int maxAmmo;
3194 0, //int maxClips;
3195 qfalse, //int infiniteAmmo;
3196 qfalse, //int usesEnergy;
3197 GRENADE_REPEAT, //int repeatRate1;
3198 0, //int repeatRate2;
3199 0, //int repeatRate3;
3200 0, //int reloadTime;
3201 qfalse, //qboolean hasAltMode;
3202 qfalse, //qboolean hasThirdMode;
3203 qfalse, //qboolean canZoom;
3204 90.0f, //float zoomFov;
3205 qfalse, //qboolean purchasable;
3206 0, //int buildDelay;
3207 WUT_HUMANS //WUTeam_t team;
3208 },
3209 {
3210 WP_HBUILD, //int weaponNum;
3211 HBUILD_PRICE, //int price;
3212 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3213 SLOT_WEAPON, //int slots;
3214 "ckit", //char *weaponName;
3215 "Construction Kit", //char *weaponHumanName;
3216 0, //int maxAmmo;
3217 0, //int maxClips;
3218 qtrue, //int infiniteAmmo;
3219 qfalse, //int usesEnergy;
3220 HBUILD_REPEAT, //int repeatRate1;
3221 HBUILD_REPEAT, //int repeatRate2;
3222 0, //int repeatRate3;
3223 0, //int reloadTime;
3224 qtrue, //qboolean hasAltMode;
3225 qfalse, //qboolean hasThirdMode;
3226 qfalse, //qboolean canZoom;
3227 90.0f, //float zoomFov;
3228 qtrue, //qboolean purchasable;
3229 HBUILD_DELAY, //int buildDelay;
3230 WUT_HUMANS //WUTeam_t team;
3231 },
3232 {
3233 WP_HBUILD2, //int weaponNum;
3234 HBUILD2_PRICE, //int price;
3235 ( 1 << S2 )|( 1 << S3 ), //int stages
3236 SLOT_WEAPON, //int slots;
3237 "ackit", //char *weaponName;
3238 "Adv Construction Kit",//char *weaponHumanName;
3239 0, //int maxAmmo;
3240 0, //int maxClips;
3241 qtrue, //int infiniteAmmo;
3242 qfalse, //int usesEnergy;
3243 HBUILD2_REPEAT, //int repeatRate1;
3244 HBUILD2_REPEAT, //int repeatRate2;
3245 0, //int repeatRate3;
3246 0, //int reloadTime;
3247 qtrue, //qboolean hasAltMode;
3248 qfalse, //qboolean hasThirdMode;
3249 qfalse, //qboolean canZoom;
3250 90.0f, //float zoomFov;
3251 qtrue, //qboolean purchasable;
3252 HBUILD2_DELAY, //int buildDelay;
3253 WUT_HUMANS //WUTeam_t team;
3254 },
3255 {
3256 WP_ABUILD, //int weaponNum;
3257 0, //int price;
3258 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3259 SLOT_WEAPON, //int slots;
3260 "abuild", //char *weaponName;
3261 "Alien build weapon", //char *weaponHumanName;
3262 0, //int maxAmmo;
3263 0, //int maxClips;
3264 qtrue, //int infiniteAmmo;
3265 qfalse, //int usesEnergy;
3266 ABUILDER_BUILD_REPEAT,//int repeatRate1;
3267 ABUILDER_BUILD_REPEAT,//int repeatRate2;
3268 0, //int repeatRate3;
3269 0, //int reloadTime;
3270 qtrue, //qboolean hasAltMode;
3271 qfalse, //qboolean hasThirdMode;
3272 qfalse, //qboolean canZoom;
3273 90.0f, //float zoomFov;
3274 qtrue, //qboolean purchasable;
3275 ABUILDER_BASE_DELAY, //int buildDelay;
3276 WUT_ALIENS //WUTeam_t team;
3277 },
3278 {
3279 WP_ABUILD2, //int weaponNum;
3280 0, //int price;
3281 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3282 SLOT_WEAPON, //int slots;
3283 "abuildupg", //char *weaponName;
3284 "Alien build weapon2",//char *weaponHumanName;
3285 0, //int maxAmmo;
3286 0, //int maxClips;
3287 qtrue, //int infiniteAmmo;
3288 qfalse, //int usesEnergy;
3289 ABUILDER_BUILD_REPEAT,//int repeatRate1;
3290 ABUILDER_CLAW_REPEAT, //int repeatRate2;
3291 ABUILDER_BLOB_REPEAT, //int repeatRate3;
3292 0, //int reloadTime;
3293 qtrue, //qboolean hasAltMode;
3294 qtrue, //qboolean hasThirdMode;
3295 qfalse, //qboolean canZoom;
3296 90.0f, //float zoomFov;
3297 qtrue, //qboolean purchasable;
3298 ABUILDER_ADV_DELAY, //int buildDelay;
3299 WUT_ALIENS //WUTeam_t team;
3300 },
3301 {
3302 WP_ALEVEL0, //int weaponNum;
3303 0, //int price;
3304 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3305 SLOT_WEAPON, //int slots;
3306 "level0", //char *weaponName;
3307 "Bite", //char *weaponHumanName;
3308 0, //int maxAmmo;
3309 0, //int maxClips;
3310 qtrue, //int infiniteAmmo;
3311 qfalse, //int usesEnergy;
3312 LEVEL0_BITE_REPEAT, //int repeatRate1;
3313 0, //int repeatRate2;
3314 0, //int repeatRate3;
3315 0, //int reloadTime;
3316 qfalse, //qboolean hasAltMode;
3317 qfalse, //qboolean hasThirdMode;
3318 qfalse, //qboolean canZoom;
3319 90.0f, //float zoomFov;
3320 qfalse, //qboolean purchasable;
3321 0, //int buildDelay;
3322 WUT_ALIENS //WUTeam_t team;
3323 },
3324 {
3325 WP_ALEVEL1, //int weaponNum;
3326 0, //int price;
3327 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3328 SLOT_WEAPON, //int slots;
3329 "level1", //char *weaponName;
3330 "Claws", //char *weaponHumanName;
3331 0, //int maxAmmo;
3332 0, //int maxClips;
3333 qtrue, //int infiniteAmmo;
3334 qfalse, //int usesEnergy;
3335 LEVEL1_CLAW_REPEAT, //int repeatRate1;
3336 0, //int repeatRate2;
3337 0, //int repeatRate3;
3338 0, //int reloadTime;
3339 qfalse, //qboolean hasAltMode;
3340 qfalse, //qboolean hasThirdMode;
3341 qfalse, //qboolean canZoom;
3342 90.0f, //float zoomFov;
3343 qfalse, //qboolean purchasable;
3344 0, //int buildDelay;
3345 WUT_ALIENS //WUTeam_t team;
3346 },
3347 {
3348 WP_ALEVEL1_UPG, //int weaponNum;
3349 0, //int price;
3350 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3351 SLOT_WEAPON, //int slots;
3352 "level1upg", //char *weaponName;
3353 "Claws Upgrade", //char *weaponHumanName;
3354 0, //int maxAmmo;
3355 0, //int maxClips;
3356 qtrue, //int infiniteAmmo;
3357 qfalse, //int usesEnergy;
3358 LEVEL1_CLAW_U_REPEAT, //int repeatRate1;
3359 LEVEL1_PCLOUD_REPEAT, //int repeatRate2;
3360 0, //int repeatRate3;
3361 0, //int reloadTime;
3362 qtrue, //qboolean hasAltMode;
3363 qfalse, //qboolean hasThirdMode;
3364 qfalse, //qboolean canZoom;
3365 90.0f, //float zoomFov;
3366 qfalse, //qboolean purchasable;
3367 0, //int buildDelay;
3368 WUT_ALIENS //WUTeam_t team;
3369 },
3370 {
3371 WP_ALEVEL2, //int weaponNum;
3372 0, //int price;
3373 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3374 SLOT_WEAPON, //int slots;
3375 "level2", //char *weaponName;
3376 "Bite", //char *weaponHumanName;
3377 0, //int maxAmmo;
3378 0, //int maxClips;
3379 qtrue, //int infiniteAmmo;
3380 qfalse, //int usesEnergy;
3381 LEVEL2_CLAW_REPEAT, //int repeatRate1;
3382 0, //int repeatRate2;
3383 0, //int repeatRate3;
3384 0, //int reloadTime;
3385 qfalse, //qboolean hasAltMode;
3386 qfalse, //qboolean hasThirdMode;
3387 qfalse, //qboolean canZoom;
3388 90.0f, //float zoomFov;
3389 qfalse, //qboolean purchasable;
3390 0, //int buildDelay;
3391 WUT_ALIENS //WUTeam_t team;
3392 },
3393 {
3394 WP_ALEVEL2_UPG, //int weaponNum;
3395 0, //int price;
3396 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3397 SLOT_WEAPON, //int slots;
3398 "level2upg", //char *weaponName;
3399 "Zap", //char *weaponHumanName;
3400 0, //int maxAmmo;
3401 0, //int maxClips;
3402 qtrue, //int infiniteAmmo;
3403 qfalse, //int usesEnergy;
3404 LEVEL2_CLAW_U_REPEAT, //int repeatRate1;
3405 LEVEL2_AREAZAP_REPEAT,//int repeatRate2;
3406 0, //int repeatRate3;
3407 0, //int reloadTime;
3408 qtrue, //qboolean hasAltMode;
3409 qfalse, //qboolean hasThirdMode;
3410 qfalse, //qboolean canZoom;
3411 90.0f, //float zoomFov;
3412 qfalse, //qboolean purchasable;
3413 0, //int buildDelay;
3414 WUT_ALIENS //WUTeam_t team;
3415 },
3416 {
3417 WP_ALEVEL3, //int weaponNum;
3418 0, //int price;
3419 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3420 SLOT_WEAPON, //int slots;
3421 "level3", //char *weaponName;
3422 "Pounce", //char *weaponHumanName;
3423 0, //int maxAmmo;
3424 0, //int maxClips;
3425 qtrue, //int infiniteAmmo;
3426 qfalse, //int usesEnergy;
3427 LEVEL3_CLAW_REPEAT, //int repeatRate1;
3428 0, //int repeatRate2;
3429 0, //int repeatRate3;
3430 0, //int reloadTime;
3431 qfalse, //qboolean hasAltMode;
3432 qfalse, //qboolean hasThirdMode;
3433 qfalse, //qboolean canZoom;
3434 90.0f, //float zoomFov;
3435 qfalse, //qboolean purchasable;
3436 0, //int buildDelay;
3437 WUT_ALIENS //WUTeam_t team;
3438 },
3439 {
3440 WP_ALEVEL3_UPG, //int weaponNum;
3441 0, //int price;
3442 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3443 SLOT_WEAPON, //int slots;
3444 "level3upg", //char *weaponName;
3445 "Pounce (upgrade)", //char *weaponHumanName;
3446 3, //int maxAmmo;
3447 0, //int maxClips;
3448 qtrue, //int infiniteAmmo;
3449 qfalse, //int usesEnergy;
3450 LEVEL3_CLAW_U_REPEAT, //int repeatRate1;
3451 0, //int repeatRate2;
3452 LEVEL3_BOUNCEBALL_REPEAT,//int repeatRate3;
3453 0, //int reloadTime;
3454 qfalse, //qboolean hasAltMode;
3455 qtrue, //qboolean hasThirdMode;
3456 qfalse, //qboolean canZoom;
3457 90.0f, //float zoomFov;
3458 qfalse, //qboolean purchasable;
3459 0, //int buildDelay;
3460 WUT_ALIENS //WUTeam_t team;
3461 },
3462 {
3463 WP_ALEVEL4, //int weaponNum;
3464 0, //int price;
3465 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3466 SLOT_WEAPON, //int slots;
3467 "level4", //char *weaponName;
3468 "Charge", //char *weaponHumanName;
3469 0, //int maxAmmo;
3470 0, //int maxClips;
3471 qtrue, //int infiniteAmmo;
3472 qfalse, //int usesEnergy;
3473 LEVEL4_CLAW_REPEAT, //int repeatRate1;
3474 0, //int repeatRate2;
3475 0, //int repeatRate3;
3476 0, //int reloadTime;
3477 qfalse, //qboolean hasAltMode;
3478 qfalse, //qboolean hasThirdMode;
3479 qfalse, //qboolean canZoom;
3480 90.0f, //float zoomFov;
3481 qfalse, //qboolean purchasable;
3482 0, //int buildDelay;
3483 WUT_ALIENS //WUTeam_t team;
3484 },
3485 {
3486 WP_LOCKBLOB_LAUNCHER, //int weaponNum;
3487 0, //int price;
3488 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3489 SLOT_WEAPON, //int slots;
3490 "lockblob", //char *weaponName;
3491 "Lock Blob", //char *weaponHumanName;
3492 0, //int maxAmmo;
3493 0, //int maxClips;
3494 qtrue, //int infiniteAmmo;
3495 qfalse, //int usesEnergy;
3496 500, //int repeatRate1;
3497 500, //int repeatRate2;
3498 500, //int repeatRate3;
3499 0, //int reloadTime;
3500 qfalse, //qboolean hasAltMode;
3501 qfalse, //qboolean hasThirdMode;
3502 qfalse, //qboolean canZoom;
3503 90.0f, //float zoomFov;
3504 qfalse, //qboolean purchasable;
3505 0, //int buildDelay;
3506 WUT_ALIENS //WUTeam_t team;
3507 },
3508 {
3509 WP_HIVE, //int weaponNum;
3510 0, //int price;
3511 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3512 SLOT_WEAPON, //int slots;
3513 "hive", //char *weaponName;
3514 "Hive", //char *weaponHumanName;
3515 0, //int maxAmmo;
3516 0, //int maxClips;
3517 qtrue, //int infiniteAmmo;
3518 qfalse, //int usesEnergy;
3519 500, //int repeatRate1;
3520 500, //int repeatRate2;
3521 500, //int repeatRate3;
3522 0, //int reloadTime;
3523 qfalse, //qboolean hasAltMode;
3524 qfalse, //qboolean hasThirdMode;
3525 qfalse, //qboolean canZoom;
3526 90.0f, //float zoomFov;
3527 qfalse, //qboolean purchasable;
3528 0, //int buildDelay;
3529 WUT_ALIENS //WUTeam_t team;
3530 },
3531 {
3532 WP_MGTURRET, //int weaponNum;
3533 0, //int price;
3534 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3535 SLOT_WEAPON, //int slots;
3536 "mgturret", //char *weaponName;
3537 "Machinegun Turret", //char *weaponHumanName;
3538 0, //int maxAmmo;
3539 0, //int maxClips;
3540 qtrue, //int infiniteAmmo;
3541 qfalse, //int usesEnergy;
3542 0, //int repeatRate1;
3543 0, //int repeatRate2;
3544 0, //int repeatRate3;
3545 0, //int reloadTime;
3546 qfalse, //qboolean hasAltMode;
3547 qfalse, //qboolean hasThirdMode;
3548 qfalse, //qboolean canZoom;
3549 90.0f, //float zoomFov;
3550 qfalse, //qboolean purchasable;
3551 0, //int buildDelay;
3552 WUT_HUMANS //WUTeam_t team;
3553 },
3554 {
3555 WP_TESLAGEN, //int weaponNum;
3556 0, //int price;
3557 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3558 SLOT_WEAPON, //int slots;
3559 "teslagen", //char *weaponName;
3560 "Tesla Generator", //char *weaponHumanName;
3561 0, //int maxAmmo;
3562 0, //int maxClips;
3563 qtrue, //int infiniteAmmo;
3564 qtrue, //int usesEnergy;
3565 500, //int repeatRate1;
3566 500, //int repeatRate2;
3567 500, //int repeatRate3;
3568 0, //int reloadTime;
3569 qfalse, //qboolean hasAltMode;
3570 qfalse, //qboolean hasThirdMode;
3571 qfalse, //qboolean canZoom;
3572 90.0f, //float zoomFov;
3573 qfalse, //qboolean purchasable;
3574 0, //int buildDelay;
3575 WUT_HUMANS //WUTeam_t team;
3576 }
3577 };
3578
3579 int bg_numWeapons = sizeof( bg_weapons ) / sizeof( bg_weapons[ 0 ] );
3580
3581 /*
3582 ==============
3583 BG_FindPriceForWeapon
3584 ==============
3585 */
BG_FindPriceForWeapon(int weapon)3586 int BG_FindPriceForWeapon( int weapon )
3587 {
3588 int i;
3589
3590 for( i = 0; i < bg_numWeapons; i++ )
3591 {
3592 if( bg_weapons[ i ].weaponNum == weapon )
3593 {
3594 return bg_weapons[ i ].price;
3595 }
3596 }
3597
3598 return 100;
3599 }
3600
3601 /*
3602 ==============
3603 BG_FindStagesForWeapon
3604 ==============
3605 */
BG_FindStagesForWeapon(int weapon,stage_t stage)3606 qboolean BG_FindStagesForWeapon( int weapon, stage_t stage )
3607 {
3608 int i;
3609
3610 for( i = 0; i < bg_numWeapons; i++ )
3611 {
3612 if( bg_weapons[ i ].weaponNum == weapon )
3613 {
3614 if( bg_weapons[ i ].stages & ( 1 << stage ) )
3615 return qtrue;
3616 else
3617 return qfalse;
3618 }
3619 }
3620
3621 return qfalse;
3622 }
3623
3624 /*
3625 ==============
3626 BG_FindSlotsForWeapon
3627 ==============
3628 */
BG_FindSlotsForWeapon(int weapon)3629 int BG_FindSlotsForWeapon( int weapon )
3630 {
3631 int i;
3632
3633 for( i = 0; i < bg_numWeapons; i++ )
3634 {
3635 if( bg_weapons[ i ].weaponNum == weapon )
3636 {
3637 return bg_weapons[ i ].slots;
3638 }
3639 }
3640
3641 return SLOT_WEAPON;
3642 }
3643
3644 /*
3645 ==============
3646 BG_FindNameForWeapon
3647 ==============
3648 */
BG_FindNameForWeapon(int weapon)3649 char *BG_FindNameForWeapon( int weapon )
3650 {
3651 int i;
3652
3653 for( i = 0; i < bg_numWeapons; i++ )
3654 {
3655 if( bg_weapons[ i ].weaponNum == weapon )
3656 return bg_weapons[ i ].weaponName;
3657 }
3658
3659 //wimp out
3660 return 0;
3661 }
3662
3663 /*
3664 ==============
3665 BG_FindWeaponNumForName
3666 ==============
3667 */
BG_FindWeaponNumForName(char * name)3668 int BG_FindWeaponNumForName( char *name )
3669 {
3670 int i;
3671
3672 for( i = 0; i < bg_numWeapons; i++ )
3673 {
3674 if( !Q_stricmp( bg_weapons[ i ].weaponName, name ) )
3675 return bg_weapons[ i ].weaponNum;
3676 }
3677
3678 //wimp out
3679 return WP_NONE;
3680 }
3681
3682 /*
3683 ==============
3684 BG_FindHumanNameForWeapon
3685 ==============
3686 */
BG_FindHumanNameForWeapon(int weapon)3687 char *BG_FindHumanNameForWeapon( int weapon )
3688 {
3689 int i;
3690
3691 for( i = 0; i < bg_numWeapons; i++ )
3692 {
3693 if( bg_weapons[ i ].weaponNum == weapon )
3694 return bg_weapons[ i ].weaponHumanName;
3695 }
3696
3697 //wimp out
3698 return 0;
3699 }
3700
3701 /*
3702 ==============
3703 BG_FindAmmoForWeapon
3704 ==============
3705 */
BG_FindAmmoForWeapon(int weapon,int * maxAmmo,int * maxClips)3706 void BG_FindAmmoForWeapon( int weapon, int *maxAmmo, int *maxClips )
3707 {
3708 int i;
3709
3710 for( i = 0; i < bg_numWeapons; i++ )
3711 {
3712 if( bg_weapons[ i ].weaponNum == weapon )
3713 {
3714 if( maxAmmo != NULL )
3715 *maxAmmo = bg_weapons[ i ].maxAmmo;
3716 if( maxClips != NULL )
3717 *maxClips = bg_weapons[ i ].maxClips;
3718
3719 //no need to keep going
3720 break;
3721 }
3722 }
3723 }
3724
3725 /*
3726 ==============
3727 BG_FindInfinteAmmoForWeapon
3728 ==============
3729 */
BG_FindInfinteAmmoForWeapon(int weapon)3730 qboolean BG_FindInfinteAmmoForWeapon( int weapon )
3731 {
3732 int i;
3733
3734 for( i = 0; i < bg_numWeapons; i++ )
3735 {
3736 if( bg_weapons[ i ].weaponNum == weapon )
3737 {
3738 return bg_weapons[ i ].infiniteAmmo;
3739 }
3740 }
3741
3742 return qfalse;
3743 }
3744
3745 /*
3746 ==============
3747 BG_FindUsesEnergyForWeapon
3748 ==============
3749 */
BG_FindUsesEnergyForWeapon(int weapon)3750 qboolean BG_FindUsesEnergyForWeapon( int weapon )
3751 {
3752 int i;
3753
3754 for( i = 0; i < bg_numWeapons; i++ )
3755 {
3756 if( bg_weapons[ i ].weaponNum == weapon )
3757 {
3758 return bg_weapons[ i ].usesEnergy;
3759 }
3760 }
3761
3762 return qfalse;
3763 }
3764
3765 /*
3766 ==============
3767 BG_FindRepeatRate1ForWeapon
3768 ==============
3769 */
BG_FindRepeatRate1ForWeapon(int weapon)3770 int BG_FindRepeatRate1ForWeapon( int weapon )
3771 {
3772 int i;
3773
3774 for( i = 0; i < bg_numWeapons; i++ )
3775 {
3776 if( bg_weapons[ i ].weaponNum == weapon )
3777 return bg_weapons[ i ].repeatRate1;
3778 }
3779
3780 return 1000;
3781 }
3782
3783 /*
3784 ==============
3785 BG_FindRepeatRate2ForWeapon
3786 ==============
3787 */
BG_FindRepeatRate2ForWeapon(int weapon)3788 int BG_FindRepeatRate2ForWeapon( int weapon )
3789 {
3790 int i;
3791
3792 for( i = 0; i < bg_numWeapons; i++ )
3793 {
3794 if( bg_weapons[ i ].weaponNum == weapon )
3795 return bg_weapons[ i ].repeatRate2;
3796 }
3797
3798 return 1000;
3799 }
3800
3801 /*
3802 ==============
3803 BG_FindRepeatRate3ForWeapon
3804 ==============
3805 */
BG_FindRepeatRate3ForWeapon(int weapon)3806 int BG_FindRepeatRate3ForWeapon( int weapon )
3807 {
3808 int i;
3809
3810 for( i = 0; i < bg_numWeapons; i++ )
3811 {
3812 if( bg_weapons[ i ].weaponNum == weapon )
3813 return bg_weapons[ i ].repeatRate3;
3814 }
3815
3816 return 1000;
3817 }
3818
3819 /*
3820 ==============
3821 BG_FindReloadTimeForWeapon
3822 ==============
3823 */
BG_FindReloadTimeForWeapon(int weapon)3824 int BG_FindReloadTimeForWeapon( int weapon )
3825 {
3826 int i;
3827
3828 for( i = 0; i < bg_numWeapons; i++ )
3829 {
3830 if( bg_weapons[ i ].weaponNum == weapon )
3831 {
3832 return bg_weapons[ i ].reloadTime;
3833 }
3834 }
3835
3836 return 1000;
3837 }
3838
3839 /*
3840 ==============
3841 BG_WeaponHasAltMode
3842 ==============
3843 */
BG_WeaponHasAltMode(int weapon)3844 qboolean BG_WeaponHasAltMode( int weapon )
3845 {
3846 int i;
3847
3848 for( i = 0; i < bg_numWeapons; i++ )
3849 {
3850 if( bg_weapons[ i ].weaponNum == weapon )
3851 {
3852 return bg_weapons[ i ].hasAltMode;
3853 }
3854 }
3855
3856 return qfalse;
3857 }
3858
3859 /*
3860 ==============
3861 BG_WeaponHasThirdMode
3862 ==============
3863 */
BG_WeaponHasThirdMode(int weapon)3864 qboolean BG_WeaponHasThirdMode( int weapon )
3865 {
3866 int i;
3867
3868 for( i = 0; i < bg_numWeapons; i++ )
3869 {
3870 if( bg_weapons[ i ].weaponNum == weapon )
3871 {
3872 return bg_weapons[ i ].hasThirdMode;
3873 }
3874 }
3875
3876 return qfalse;
3877 }
3878
3879 /*
3880 ==============
3881 BG_WeaponCanZoom
3882 ==============
3883 */
BG_WeaponCanZoom(int weapon)3884 qboolean BG_WeaponCanZoom( int weapon )
3885 {
3886 int i;
3887
3888 for( i = 0; i < bg_numWeapons; i++ )
3889 {
3890 if( bg_weapons[ i ].weaponNum == weapon )
3891 {
3892 return bg_weapons[ i ].canZoom;
3893 }
3894 }
3895
3896 return qfalse;
3897 }
3898
3899 /*
3900 ==============
3901 BG_FindZoomFovForWeapon
3902 ==============
3903 */
BG_FindZoomFovForWeapon(int weapon)3904 float BG_FindZoomFovForWeapon( int weapon )
3905 {
3906 int i;
3907
3908 for( i = 0; i < bg_numWeapons; i++ )
3909 {
3910 if( bg_weapons[ i ].weaponNum == weapon )
3911 {
3912 return bg_weapons[ i ].zoomFov;
3913 }
3914 }
3915
3916 return qfalse;
3917 }
3918
3919 /*
3920 ==============
3921 BG_FindPurchasableForWeapon
3922 ==============
3923 */
BG_FindPurchasableForWeapon(int weapon)3924 qboolean BG_FindPurchasableForWeapon( int weapon )
3925 {
3926 int i;
3927
3928 for( i = 0; i < bg_numWeapons; i++ )
3929 {
3930 if( bg_weapons[ i ].weaponNum == weapon )
3931 {
3932 return bg_weapons[ i ].purchasable;
3933 }
3934 }
3935
3936 return qfalse;
3937 }
3938
3939 /*
3940 ==============
3941 BG_FindBuildDelayForWeapon
3942 ==============
3943 */
BG_FindBuildDelayForWeapon(int weapon)3944 int BG_FindBuildDelayForWeapon( int weapon )
3945 {
3946 int i;
3947
3948 for( i = 0; i < bg_numWeapons; i++ )
3949 {
3950 if( bg_weapons[ i ].weaponNum == weapon )
3951 {
3952 return bg_weapons[ i ].buildDelay;
3953 }
3954 }
3955
3956 return 0;
3957 }
3958
3959 /*
3960 ==============
3961 BG_FindTeamForWeapon
3962 ==============
3963 */
BG_FindTeamForWeapon(int weapon)3964 WUTeam_t BG_FindTeamForWeapon( int weapon )
3965 {
3966 int i;
3967
3968 for( i = 0; i < bg_numWeapons; i++ )
3969 {
3970 if( bg_weapons[ i ].weaponNum == weapon )
3971 {
3972 return bg_weapons[ i ].team;
3973 }
3974 }
3975
3976 return WUT_NONE;
3977 }
3978
3979 ////////////////////////////////////////////////////////////////////////////////
3980
3981 upgradeAttributes_t bg_upgrades[ ] =
3982 {
3983 {
3984 UP_LIGHTARMOUR, //int upgradeNum;
3985 LIGHTARMOUR_PRICE, //int price;
3986 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
3987 SLOT_TORSO|SLOT_ARMS|SLOT_LEGS, //int slots;
3988 "larmour", //char *upgradeName;
3989 "Light Armour", //char *upgradeHumanName;
3990 "icons/iconu_larmour",
3991 qtrue, //qboolean purchasable
3992 qfalse, //qboolean usable
3993 WUT_HUMANS //WUTeam_t team;
3994 },
3995 {
3996 UP_HELMET, //int upgradeNum;
3997 HELMET_PRICE, //int price;
3998 ( 1 << S2 )|( 1 << S3 ), //int stages
3999 SLOT_HEAD, //int slots;
4000 "helmet", //char *upgradeName;
4001 "Helmet", //char *upgradeHumanName;
4002 "icons/iconu_helmet",
4003 qtrue, //qboolean purchasable
4004 qfalse, //qboolean usable
4005 WUT_HUMANS //WUTeam_t team;
4006 },
4007 {
4008 UP_MEDKIT, //int upgradeNum;
4009 MEDKIT_PRICE, //int price;
4010 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
4011 SLOT_NONE, //int slots;
4012 "medkit", //char *upgradeName;
4013 "Medkit", //char *upgradeHumanName;
4014 "icons/iconu_atoxin",
4015 qfalse, //qboolean purchasable
4016 qtrue, //qboolean usable
4017 WUT_HUMANS //WUTeam_t team;
4018 },
4019 {
4020 UP_BATTPACK, //int upgradeNum;
4021 BATTPACK_PRICE, //int price;
4022 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
4023 SLOT_BACKPACK, //int slots;
4024 "battpack", //char *upgradeName;
4025 "Battery Pack", //char *upgradeHumanName;
4026 "icons/iconu_battpack",
4027 qtrue, //qboolean purchasable
4028 qfalse, //qboolean usable
4029 WUT_HUMANS //WUTeam_t team;
4030 },
4031 {
4032 UP_JETPACK, //int upgradeNum;
4033 JETPACK_PRICE, //int price;
4034 ( 1 << S2 )|( 1 << S3 ), //int stages
4035 SLOT_BACKPACK, //int slots;
4036 "jetpack", //char *upgradeName;
4037 "Jet Pack", //char *upgradeHumanName;
4038 "icons/iconu_jetpack",
4039 qtrue, //qboolean purchasable
4040 qtrue, //qboolean usable
4041 WUT_HUMANS //WUTeam_t team;
4042 },
4043 {
4044 UP_BATTLESUIT, //int upgradeNum;
4045 BSUIT_PRICE, //int price;
4046 ( 1 << S3 ), //int stages
4047 SLOT_HEAD|SLOT_TORSO|SLOT_ARMS|SLOT_LEGS|SLOT_BACKPACK, //int slots;
4048 "bsuit", //char *upgradeName;
4049 "Battlesuit", //char *upgradeHumanName;
4050 "icons/iconu_bsuit",
4051 qtrue, //qboolean purchasable
4052 qfalse, //qboolean usable
4053 WUT_HUMANS //WUTeam_t team;
4054 },
4055 {
4056 UP_GRENADE, //int upgradeNum;
4057 GRENADE_PRICE, //int price;
4058 ( 1 << S2 )|( 1 << S3 ),//int stages
4059 SLOT_NONE, //int slots;
4060 "gren", //char *upgradeName;
4061 "Grenade", //char *upgradeHumanName;
4062 0,
4063 qtrue, //qboolean purchasable
4064 qtrue, //qboolean usable
4065 WUT_HUMANS //WUTeam_t team;
4066 },
4067 {
4068 UP_AMMO, //int upgradeNum;
4069 0, //int price;
4070 ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
4071 SLOT_NONE, //int slots;
4072 "ammo", //char *upgradeName;
4073 "Ammunition", //char *upgradeHumanName;
4074 0,
4075 qtrue, //qboolean purchasable
4076 qfalse, //qboolean usable
4077 WUT_HUMANS //WUTeam_t team;
4078 }
4079 };
4080
4081 int bg_numUpgrades = sizeof( bg_upgrades ) / sizeof( bg_upgrades[ 0 ] );
4082
4083 /*
4084 ==============
4085 BG_FindPriceForUpgrade
4086 ==============
4087 */
BG_FindPriceForUpgrade(int upgrade)4088 int BG_FindPriceForUpgrade( int upgrade )
4089 {
4090 int i;
4091
4092 for( i = 0; i < bg_numUpgrades; i++ )
4093 {
4094 if( bg_upgrades[ i ].upgradeNum == upgrade )
4095 {
4096 return bg_upgrades[ i ].price;
4097 }
4098 }
4099
4100 return 100;
4101 }
4102
4103 /*
4104 ==============
4105 BG_FindStagesForUpgrade
4106 ==============
4107 */
BG_FindStagesForUpgrade(int upgrade,stage_t stage)4108 qboolean BG_FindStagesForUpgrade( int upgrade, stage_t stage )
4109 {
4110 int i;
4111
4112 for( i = 0; i < bg_numUpgrades; i++ )
4113 {
4114 if( bg_upgrades[ i ].upgradeNum == upgrade )
4115 {
4116 if( bg_upgrades[ i ].stages & ( 1 << stage ) )
4117 return qtrue;
4118 else
4119 return qfalse;
4120 }
4121 }
4122
4123 return qfalse;
4124 }
4125
4126 /*
4127 ==============
4128 BG_FindSlotsForUpgrade
4129 ==============
4130 */
BG_FindSlotsForUpgrade(int upgrade)4131 int BG_FindSlotsForUpgrade( int upgrade )
4132 {
4133 int i;
4134
4135 for( i = 0; i < bg_numUpgrades; i++ )
4136 {
4137 if( bg_upgrades[ i ].upgradeNum == upgrade )
4138 {
4139 return bg_upgrades[ i ].slots;
4140 }
4141 }
4142
4143 return SLOT_NONE;
4144 }
4145
4146 /*
4147 ==============
4148 BG_FindNameForUpgrade
4149 ==============
4150 */
BG_FindNameForUpgrade(int upgrade)4151 char *BG_FindNameForUpgrade( int upgrade )
4152 {
4153 int i;
4154
4155 for( i = 0; i < bg_numUpgrades; i++ )
4156 {
4157 if( bg_upgrades[ i ].upgradeNum == upgrade )
4158 return bg_upgrades[ i ].upgradeName;
4159 }
4160
4161 //wimp out
4162 return 0;
4163 }
4164
4165 /*
4166 ==============
4167 BG_FindUpgradeNumForName
4168 ==============
4169 */
BG_FindUpgradeNumForName(char * name)4170 int BG_FindUpgradeNumForName( char *name )
4171 {
4172 int i;
4173
4174 for( i = 0; i < bg_numUpgrades; i++ )
4175 {
4176 if( !Q_stricmp( bg_upgrades[ i ].upgradeName, name ) )
4177 return bg_upgrades[ i ].upgradeNum;
4178 }
4179
4180 //wimp out
4181 return UP_NONE;
4182 }
4183
4184 /*
4185 ==============
4186 BG_FindHumanNameForUpgrade
4187 ==============
4188 */
BG_FindHumanNameForUpgrade(int upgrade)4189 char *BG_FindHumanNameForUpgrade( int upgrade )
4190 {
4191 int i;
4192
4193 for( i = 0; i < bg_numUpgrades; i++ )
4194 {
4195 if( bg_upgrades[ i ].upgradeNum == upgrade )
4196 return bg_upgrades[ i ].upgradeHumanName;
4197 }
4198
4199 //wimp out
4200 return 0;
4201 }
4202
4203 /*
4204 ==============
4205 BG_FindIconForUpgrade
4206 ==============
4207 */
BG_FindIconForUpgrade(int upgrade)4208 char *BG_FindIconForUpgrade( int upgrade )
4209 {
4210 int i;
4211
4212 for( i = 0; i < bg_numUpgrades; i++ )
4213 {
4214 if( bg_upgrades[ i ].upgradeNum == upgrade )
4215 return bg_upgrades[ i ].icon;
4216 }
4217
4218 //wimp out
4219 return 0;
4220 }
4221
4222 /*
4223 ==============
4224 BG_FindPurchasableForUpgrade
4225 ==============
4226 */
BG_FindPurchasableForUpgrade(int upgrade)4227 qboolean BG_FindPurchasableForUpgrade( int upgrade )
4228 {
4229 int i;
4230
4231 for( i = 0; i < bg_numUpgrades; i++ )
4232 {
4233 if( bg_upgrades[ i ].upgradeNum == upgrade )
4234 return bg_upgrades[ i ].purchasable;
4235 }
4236
4237 return qfalse;
4238 }
4239
4240 /*
4241 ==============
4242 BG_FindUsableForUpgrade
4243 ==============
4244 */
BG_FindUsableForUpgrade(int upgrade)4245 qboolean BG_FindUsableForUpgrade( int upgrade )
4246 {
4247 int i;
4248
4249 for( i = 0; i < bg_numUpgrades; i++ )
4250 {
4251 if( bg_upgrades[ i ].upgradeNum == upgrade )
4252 return bg_upgrades[ i ].usable;
4253 }
4254
4255 return qfalse;
4256 }
4257
4258 /*
4259 ==============
4260 BG_FindTeamForUpgrade
4261 ==============
4262 */
BG_FindTeamForUpgrade(int upgrade)4263 WUTeam_t BG_FindTeamForUpgrade( int upgrade )
4264 {
4265 int i;
4266
4267 for( i = 0; i < bg_numUpgrades; i++ )
4268 {
4269 if( bg_upgrades[ i ].upgradeNum == upgrade )
4270 {
4271 return bg_upgrades[ i ].team;
4272 }
4273 }
4274
4275 return WUT_NONE;
4276 }
4277
4278 ////////////////////////////////////////////////////////////////////////////////
4279
4280 /*
4281 ================
4282 BG_EvaluateTrajectory
4283
4284 ================
4285 */
BG_EvaluateTrajectory(const trajectory_t * tr,int atTime,vec3_t result)4286 void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result )
4287 {
4288 float deltaTime;
4289 float phase;
4290
4291 switch( tr->trType )
4292 {
4293 case TR_STATIONARY:
4294 case TR_INTERPOLATE:
4295 VectorCopy( tr->trBase, result );
4296 break;
4297
4298 case TR_LINEAR:
4299 deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
4300 VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
4301 break;
4302
4303 case TR_SINE:
4304 deltaTime = ( atTime - tr->trTime ) / (float)tr->trDuration;
4305 phase = sin( deltaTime * M_PI * 2 );
4306 VectorMA( tr->trBase, phase, tr->trDelta, result );
4307 break;
4308
4309 case TR_LINEAR_STOP:
4310 if( atTime > tr->trTime + tr->trDuration )
4311 atTime = tr->trTime + tr->trDuration;
4312
4313 deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
4314 if( deltaTime < 0 )
4315 deltaTime = 0;
4316
4317 VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
4318 break;
4319
4320 case TR_GRAVITY:
4321 deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
4322 VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
4323 result[ 2 ] -= 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime; // FIXME: local gravity...
4324 break;
4325
4326 case TR_BUOYANCY:
4327 deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
4328 VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
4329 result[ 2 ] += 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime; // FIXME: local gravity...
4330 break;
4331
4332 default:
4333 Com_Error( ERR_DROP, "BG_EvaluateTrajectory: unknown trType: %i", tr->trTime );
4334 break;
4335 }
4336 }
4337
4338 /*
4339 ================
4340 BG_EvaluateTrajectoryDelta
4341
4342 For determining velocity at a given time
4343 ================
4344 */
BG_EvaluateTrajectoryDelta(const trajectory_t * tr,int atTime,vec3_t result)4345 void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result )
4346 {
4347 float deltaTime;
4348 float phase;
4349
4350 switch( tr->trType )
4351 {
4352 case TR_STATIONARY:
4353 case TR_INTERPOLATE:
4354 VectorClear( result );
4355 break;
4356
4357 case TR_LINEAR:
4358 VectorCopy( tr->trDelta, result );
4359 break;
4360
4361 case TR_SINE:
4362 deltaTime = ( atTime - tr->trTime ) / (float)tr->trDuration;
4363 phase = cos( deltaTime * M_PI * 2 ); // derivative of sin = cos
4364 phase *= 0.5;
4365 VectorScale( tr->trDelta, phase, result );
4366 break;
4367
4368 case TR_LINEAR_STOP:
4369 if( atTime > tr->trTime + tr->trDuration )
4370 {
4371 VectorClear( result );
4372 return;
4373 }
4374 VectorCopy( tr->trDelta, result );
4375 break;
4376
4377 case TR_GRAVITY:
4378 deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
4379 VectorCopy( tr->trDelta, result );
4380 result[ 2 ] -= DEFAULT_GRAVITY * deltaTime; // FIXME: local gravity...
4381 break;
4382
4383 case TR_BUOYANCY:
4384 deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
4385 VectorCopy( tr->trDelta, result );
4386 result[ 2 ] += DEFAULT_GRAVITY * deltaTime; // FIXME: local gravity...
4387 break;
4388
4389 default:
4390 Com_Error( ERR_DROP, "BG_EvaluateTrajectoryDelta: unknown trType: %i", tr->trTime );
4391 break;
4392 }
4393 }
4394
4395 char *eventnames[ ] =
4396 {
4397 "EV_NONE",
4398
4399 "EV_FOOTSTEP",
4400 "EV_FOOTSTEP_METAL",
4401 "EV_FOOTSTEP_SQUELCH",
4402 "EV_FOOTSPLASH",
4403 "EV_FOOTWADE",
4404 "EV_SWIM",
4405
4406 "EV_STEP_4",
4407 "EV_STEP_8",
4408 "EV_STEP_12",
4409 "EV_STEP_16",
4410
4411 "EV_STEPDN_4",
4412 "EV_STEPDN_8",
4413 "EV_STEPDN_12",
4414 "EV_STEPDN_16",
4415
4416 "EV_FALL_SHORT",
4417 "EV_FALL_MEDIUM",
4418 "EV_FALL_FAR",
4419 "EV_FALLING",
4420
4421 "EV_JUMP",
4422 "EV_WATER_TOUCH", // foot touches
4423 "EV_WATER_LEAVE", // foot leaves
4424 "EV_WATER_UNDER", // head touches
4425 "EV_WATER_CLEAR", // head leaves
4426
4427 "EV_NOAMMO",
4428 "EV_CHANGE_WEAPON",
4429 "EV_FIRE_WEAPON",
4430 "EV_FIRE_WEAPON2",
4431 "EV_FIRE_WEAPON3",
4432
4433 "EV_PLAYER_RESPAWN", //TA: for fovwarp effects
4434 "EV_PLAYER_TELEPORT_IN",
4435 "EV_PLAYER_TELEPORT_OUT",
4436
4437 "EV_GRENADE_BOUNCE", // eventParm will be the soundindex
4438
4439 "EV_GENERAL_SOUND",
4440 "EV_GLOBAL_SOUND", // no attenuation
4441
4442 "EV_BULLET_HIT_FLESH",
4443 "EV_BULLET_HIT_WALL",
4444
4445 "EV_SHOTGUN",
4446
4447 "EV_MISSILE_HIT",
4448 "EV_MISSILE_MISS",
4449 "EV_MISSILE_MISS_METAL",
4450 "EV_TESLATRAIL",
4451 "EV_BULLET", // otherEntity is the shooter
4452
4453 "EV_LEV1_GRAB",
4454 "EV_LEV4_CHARGE_PREPARE",
4455 "EV_LEV4_CHARGE_START",
4456
4457 "EV_PAIN",
4458 "EV_DEATH1",
4459 "EV_DEATH2",
4460 "EV_DEATH3",
4461 "EV_OBITUARY",
4462
4463 "EV_GIB_PLAYER", // gib a previously living player
4464
4465 "EV_BUILD_CONSTRUCT", //TA
4466 "EV_BUILD_DESTROY", //TA
4467 "EV_BUILD_DELAY", //TA: can't build yet
4468 "EV_BUILD_REPAIR", //TA: repairing buildable
4469 "EV_BUILD_REPAIRED", //TA: buildable has full health
4470 "EV_HUMAN_BUILDABLE_EXPLOSION",
4471 "EV_ALIEN_BUILDABLE_EXPLOSION",
4472 "EV_ALIEN_ACIDTUBE",
4473
4474 "EV_MEDKIT_USED",
4475
4476 "EV_ALIEN_EVOLVE",
4477 "EV_ALIEN_EVOLVE_FAILED",
4478
4479 "EV_DEBUG_LINE",
4480 "EV_STOPLOOPINGSOUND",
4481 "EV_TAUNT",
4482
4483 "EV_OVERMIND_ATTACK", //TA: overmind under attack
4484 "EV_OVERMIND_DYING", //TA: overmind close to death
4485 "EV_OVERMIND_SPAWNS", //TA: overmind needs spawns
4486
4487 "EV_DCC_ATTACK", //TA: dcc under attack
4488
4489 "EV_RPTUSE_SOUND" //TA: trigger a sound
4490 };
4491
4492 /*
4493 ===============
4494 BG_AddPredictableEventToPlayerstate
4495
4496 Handles the sequence numbers
4497 ===============
4498 */
4499
4500 void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
4501
BG_AddPredictableEventToPlayerstate(int newEvent,int eventParm,playerState_t * ps)4502 void BG_AddPredictableEventToPlayerstate( int newEvent, int eventParm, playerState_t *ps )
4503 {
4504 #ifdef _DEBUG
4505 {
4506 char buf[ 256 ];
4507 trap_Cvar_VariableStringBuffer( "showevents", buf, sizeof( buf ) );
4508
4509 if( atof( buf ) != 0 )
4510 {
4511 #ifdef QAGAME
4512 Com_Printf( " game event svt %5d -> %5d: num = %20s parm %d\n",
4513 ps->pmove_framecount/*ps->commandTime*/, ps->eventSequence, eventnames[ newEvent ], eventParm);
4514 #else
4515 Com_Printf( "Cgame event svt %5d -> %5d: num = %20s parm %d\n",
4516 ps->pmove_framecount/*ps->commandTime*/, ps->eventSequence, eventnames[ newEvent ], eventParm);
4517 #endif
4518 }
4519 }
4520 #endif
4521 ps->events[ ps->eventSequence & ( MAX_PS_EVENTS - 1 ) ] = newEvent;
4522 ps->eventParms[ ps->eventSequence & ( MAX_PS_EVENTS - 1 ) ] = eventParm;
4523 ps->eventSequence++;
4524 }
4525
4526
4527 /*
4528 ========================
4529 BG_PlayerStateToEntityState
4530
4531 This is done after each set of usercmd_t on the server,
4532 and after local prediction on the client
4533 ========================
4534 */
BG_PlayerStateToEntityState(playerState_t * ps,entityState_t * s,qboolean snap)4535 void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap )
4536 {
4537 int i;
4538
4539 if( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR || ps->pm_type == PM_FREEZE )
4540 s->eType = ET_INVISIBLE;
4541 else if( ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
4542 s->eType = ET_INVISIBLE;
4543 else
4544 s->eType = ET_PLAYER;
4545
4546 s->number = ps->clientNum;
4547
4548 s->pos.trType = TR_INTERPOLATE;
4549 VectorCopy( ps->origin, s->pos.trBase );
4550
4551 if( snap )
4552 SnapVector( s->pos.trBase );
4553
4554 //set the trDelta for flag direction
4555 VectorCopy( ps->velocity, s->pos.trDelta );
4556
4557 s->apos.trType = TR_INTERPOLATE;
4558 VectorCopy( ps->viewangles, s->apos.trBase );
4559
4560 if( snap )
4561 SnapVector( s->apos.trBase );
4562
4563 //TA: i need for other things :)
4564 //s->angles2[YAW] = ps->movementDir;
4565 s->time2 = ps->movementDir;
4566 s->legsAnim = ps->legsAnim;
4567 s->torsoAnim = ps->torsoAnim;
4568 s->clientNum = ps->clientNum; // ET_PLAYER looks here instead of at number
4569 // so corpses can also reference the proper config
4570 s->eFlags = ps->eFlags;
4571 if( ps->stats[STAT_HEALTH] <= 0 )
4572 s->eFlags |= EF_DEAD;
4573 else
4574 s->eFlags &= ~EF_DEAD;
4575
4576 if( ps->stats[ STAT_STATE ] & SS_BLOBLOCKED )
4577 s->eFlags |= EF_BLOBLOCKED;
4578 else
4579 s->eFlags &= ~EF_BLOBLOCKED;
4580
4581 if( ps->externalEvent )
4582 {
4583 s->event = ps->externalEvent;
4584 s->eventParm = ps->externalEventParm;
4585 }
4586 else if( ps->entityEventSequence < ps->eventSequence )
4587 {
4588 int seq;
4589
4590 if( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS )
4591 ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
4592
4593 seq = ps->entityEventSequence & ( MAX_PS_EVENTS - 1 );
4594 s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
4595 s->eventParm = ps->eventParms[ seq ];
4596 ps->entityEventSequence++;
4597 }
4598
4599 s->weapon = ps->weapon;
4600 s->groundEntityNum = ps->groundEntityNum;
4601
4602 //store items held and active items in otherEntityNum
4603 s->modelindex = 0;
4604 s->modelindex2 = 0;
4605 for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
4606 {
4607 if( BG_InventoryContainsUpgrade( i, ps->stats ) )
4608 {
4609 s->modelindex |= 1 << i;
4610
4611 if( BG_UpgradeIsActive( i, ps->stats ) )
4612 s->modelindex2 |= 1 << i;
4613 }
4614 }
4615
4616 //TA: use powerups field to store team/class info:
4617 s->powerups = ps->stats[ STAT_PTEAM ] | ( ps->stats[ STAT_PCLASS ] << 8 );
4618
4619 //TA: have to get the surfNormal thru somehow...
4620 VectorCopy( ps->grapplePoint, s->angles2 );
4621 if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
4622 s->eFlags |= EF_WALLCLIMBCEILING;
4623
4624 s->loopSound = ps->loopSound;
4625 s->generic1 = ps->generic1;
4626
4627 if( s->generic1 <= WPM_NONE || s->generic1 >= WPM_NUM_WEAPONMODES )
4628 s->generic1 = WPM_PRIMARY;
4629 }
4630
4631
4632 /*
4633 ========================
4634 BG_PlayerStateToEntityStateExtraPolate
4635
4636 This is done after each set of usercmd_t on the server,
4637 and after local prediction on the client
4638 ========================
4639 */
BG_PlayerStateToEntityStateExtraPolate(playerState_t * ps,entityState_t * s,int time,qboolean snap)4640 void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s, int time, qboolean snap )
4641 {
4642 int i;
4643
4644 if( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR || ps->pm_type == PM_FREEZE )
4645 s->eType = ET_INVISIBLE;
4646 else if( ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
4647 s->eType = ET_INVISIBLE;
4648 else
4649 s->eType = ET_PLAYER;
4650
4651 s->number = ps->clientNum;
4652
4653 s->pos.trType = TR_LINEAR_STOP;
4654 VectorCopy( ps->origin, s->pos.trBase );
4655
4656 if( snap )
4657 SnapVector( s->pos.trBase );
4658
4659 // set the trDelta for flag direction and linear prediction
4660 VectorCopy( ps->velocity, s->pos.trDelta );
4661 // set the time for linear prediction
4662 s->pos.trTime = time;
4663 // set maximum extra polation time
4664 s->pos.trDuration = 50; // 1000 / sv_fps (default = 20)
4665
4666 s->apos.trType = TR_INTERPOLATE;
4667 VectorCopy( ps->viewangles, s->apos.trBase );
4668 if( snap )
4669 SnapVector( s->apos.trBase );
4670
4671 //TA: i need for other things :)
4672 //s->angles2[YAW] = ps->movementDir;
4673 s->time2 = ps->movementDir;
4674 s->legsAnim = ps->legsAnim;
4675 s->torsoAnim = ps->torsoAnim;
4676 s->clientNum = ps->clientNum; // ET_PLAYER looks here instead of at number
4677 // so corpses can also reference the proper config
4678 s->eFlags = ps->eFlags;
4679
4680 if( ps->stats[STAT_HEALTH] <= 0 )
4681 s->eFlags |= EF_DEAD;
4682 else
4683 s->eFlags &= ~EF_DEAD;
4684
4685 if( ps->stats[ STAT_STATE ] & SS_BLOBLOCKED )
4686 s->eFlags |= EF_BLOBLOCKED;
4687 else
4688 s->eFlags &= ~EF_BLOBLOCKED;
4689
4690 if( ps->externalEvent )
4691 {
4692 s->event = ps->externalEvent;
4693 s->eventParm = ps->externalEventParm;
4694 }
4695 else if( ps->entityEventSequence < ps->eventSequence )
4696 {
4697 int seq;
4698
4699 if( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS )
4700 ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
4701
4702 seq = ps->entityEventSequence & ( MAX_PS_EVENTS - 1 );
4703 s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
4704 s->eventParm = ps->eventParms[ seq ];
4705 ps->entityEventSequence++;
4706 }
4707
4708 s->weapon = ps->weapon;
4709 s->groundEntityNum = ps->groundEntityNum;
4710
4711 //store items held and active items in otherEntityNum
4712 s->modelindex = 0;
4713 s->modelindex2 = 0;
4714
4715 for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
4716 {
4717 if( BG_InventoryContainsUpgrade( i, ps->stats ) )
4718 {
4719 s->modelindex |= 1 << i;
4720
4721 if( BG_UpgradeIsActive( i, ps->stats ) )
4722 s->modelindex2 |= 1 << i;
4723 }
4724 }
4725
4726 //TA: use powerups field to store team/class info:
4727 s->powerups = ps->stats[ STAT_PTEAM ] | ( ps->stats[ STAT_PCLASS ] << 8 );
4728
4729 //TA: have to get the surfNormal thru somehow...
4730 VectorCopy( ps->grapplePoint, s->angles2 );
4731 if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
4732 s->eFlags |= EF_WALLCLIMBCEILING;
4733
4734 s->loopSound = ps->loopSound;
4735 s->generic1 = ps->generic1;
4736
4737 if( s->generic1 <= WPM_NONE || s->generic1 >= WPM_NUM_WEAPONMODES )
4738 s->generic1 = WPM_PRIMARY;
4739 }
4740
4741 /*
4742 ========================
4743 BG_UnpackAmmoArray
4744
4745 Extract the ammo quantity from the array
4746 ========================
4747 */
BG_UnpackAmmoArray(int weapon,int psAmmo[],int psAmmo2[],int * ammo,int * clips)4748 void BG_UnpackAmmoArray( int weapon, int psAmmo[ ], int psAmmo2[ ], int *ammo, int *clips )
4749 {
4750 int ammoarray[ 32 ];
4751 int i;
4752
4753 for( i = 0; i <= 15; i++ )
4754 ammoarray[ i ] = psAmmo[ i ];
4755
4756 for( i = 16; i <= 31; i++ )
4757 ammoarray[ i ] = psAmmo2[ i - 16 ];
4758
4759 if( ammo != NULL )
4760 *ammo = ammoarray[ weapon ] & 0x0FFF;
4761
4762 if( clips != NULL )
4763 *clips = ( ammoarray[ weapon ] >> 12 ) & 0x0F;
4764 }
4765
4766 /*
4767 ========================
4768 BG_PackAmmoArray
4769
4770 Pack the ammo quantity into the array
4771 ========================
4772 */
BG_PackAmmoArray(int weapon,int psAmmo[],int psAmmo2[],int ammo,int clips)4773 void BG_PackAmmoArray( int weapon, int psAmmo[ ], int psAmmo2[ ], int ammo, int clips )
4774 {
4775 int weaponvalue;
4776
4777 weaponvalue = ammo | ( clips << 12 );
4778
4779 if( weapon <= 15 )
4780 psAmmo[ weapon ] = weaponvalue;
4781 else if( weapon >= 16 )
4782 psAmmo2[ weapon - 16 ] = weaponvalue;
4783 }
4784
4785 /*
4786 ========================
4787 BG_WeaponIsFull
4788
4789 Check if a weapon has full ammo
4790 ========================
4791 */
BG_WeaponIsFull(weapon_t weapon,int stats[],int psAmmo[],int psAmmo2[])4792 qboolean BG_WeaponIsFull( weapon_t weapon, int stats[ ], int psAmmo[ ], int psAmmo2[ ] )
4793 {
4794 int maxAmmo, maxClips;
4795 int ammo, clips;
4796
4797 BG_FindAmmoForWeapon( weapon, &maxAmmo, &maxClips );
4798 BG_UnpackAmmoArray( weapon, psAmmo, psAmmo2, &ammo, &clips );
4799
4800 if( BG_InventoryContainsUpgrade( UP_BATTPACK, stats ) )
4801 maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER );
4802
4803 return ( maxAmmo == ammo ) && ( maxClips == clips );
4804 }
4805
4806 /*
4807 ========================
4808 BG_AddWeaponToInventory
4809
4810 Give a player a weapon
4811 ========================
4812 */
BG_AddWeaponToInventory(int weapon,int stats[])4813 void BG_AddWeaponToInventory( int weapon, int stats[ ] )
4814 {
4815 int weaponList;
4816
4817 weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 );
4818
4819 weaponList |= ( 1 << weapon );
4820
4821 stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF;
4822 stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16;
4823
4824 if( stats[ STAT_SLOTS ] & BG_FindSlotsForWeapon( weapon ) )
4825 Com_Printf( S_COLOR_YELLOW "WARNING: Held items conflict with weapon %d\n", weapon );
4826
4827 stats[ STAT_SLOTS ] |= BG_FindSlotsForWeapon( weapon );
4828 }
4829
4830 /*
4831 ========================
4832 BG_RemoveWeaponToInventory
4833
4834 Take a weapon from a player
4835 ========================
4836 */
BG_RemoveWeaponFromInventory(int weapon,int stats[])4837 void BG_RemoveWeaponFromInventory( int weapon, int stats[ ] )
4838 {
4839 int weaponList;
4840
4841 weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 );
4842
4843 weaponList &= ~( 1 << weapon );
4844
4845 stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF;
4846 stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16;
4847
4848 stats[ STAT_SLOTS ] &= ~BG_FindSlotsForWeapon( weapon );
4849 }
4850
4851 /*
4852 ========================
4853 BG_InventoryContainsWeapon
4854
4855 Does the player hold a weapon?
4856 ========================
4857 */
BG_InventoryContainsWeapon(int weapon,int stats[])4858 qboolean BG_InventoryContainsWeapon( int weapon, int stats[ ] )
4859 {
4860 int weaponList;
4861
4862 weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 );
4863
4864 return( weaponList & ( 1 << weapon ) );
4865 }
4866
4867 /*
4868 ========================
4869 BG_AddUpgradeToInventory
4870
4871 Give the player an upgrade
4872 ========================
4873 */
BG_AddUpgradeToInventory(int item,int stats[])4874 void BG_AddUpgradeToInventory( int item, int stats[ ] )
4875 {
4876 stats[ STAT_ITEMS ] |= ( 1 << item );
4877
4878 if( stats[ STAT_SLOTS ] & BG_FindSlotsForUpgrade( item ) )
4879 Com_Printf( S_COLOR_YELLOW "WARNING: Held items conflict with upgrade %d\n", item );
4880
4881 stats[ STAT_SLOTS ] |= BG_FindSlotsForUpgrade( item );
4882 }
4883
4884 /*
4885 ========================
4886 BG_RemoveUpgradeFromInventory
4887
4888 Take an upgrade from the player
4889 ========================
4890 */
BG_RemoveUpgradeFromInventory(int item,int stats[])4891 void BG_RemoveUpgradeFromInventory( int item, int stats[ ] )
4892 {
4893 stats[ STAT_ITEMS ] &= ~( 1 << item );
4894
4895 stats[ STAT_SLOTS ] &= ~BG_FindSlotsForUpgrade( item );
4896 }
4897
4898 /*
4899 ========================
4900 BG_InventoryContainsUpgrade
4901
4902 Does the player hold an upgrade?
4903 ========================
4904 */
BG_InventoryContainsUpgrade(int item,int stats[])4905 qboolean BG_InventoryContainsUpgrade( int item, int stats[ ] )
4906 {
4907 return( stats[ STAT_ITEMS ] & ( 1 << item ) );
4908 }
4909
4910 /*
4911 ========================
4912 BG_ActivateUpgrade
4913
4914 Activates an upgrade
4915 ========================
4916 */
BG_ActivateUpgrade(int item,int stats[])4917 void BG_ActivateUpgrade( int item, int stats[ ] )
4918 {
4919 stats[ STAT_ACTIVEITEMS ] |= ( 1 << item );
4920 }
4921
4922 /*
4923 ========================
4924 BG_DeactivateUpgrade
4925
4926 Deactivates an upgrade
4927 ========================
4928 */
BG_DeactivateUpgrade(int item,int stats[])4929 void BG_DeactivateUpgrade( int item, int stats[ ] )
4930 {
4931 stats[ STAT_ACTIVEITEMS ] &= ~( 1 << item );
4932 }
4933
4934 /*
4935 ========================
4936 BG_UpgradeIsActive
4937
4938 Is this upgrade active?
4939 ========================
4940 */
BG_UpgradeIsActive(int item,int stats[])4941 qboolean BG_UpgradeIsActive( int item, int stats[ ] )
4942 {
4943 return( stats[ STAT_ACTIVEITEMS ] & ( 1 << item ) );
4944 }
4945
4946 /*
4947 ===============
4948 BG_RotateAxis
4949
4950 Shared axis rotation function
4951 ===============
4952 */
BG_RotateAxis(vec3_t surfNormal,vec3_t inAxis[3],vec3_t outAxis[3],qboolean inverse,qboolean ceiling)4953 qboolean BG_RotateAxis( vec3_t surfNormal, vec3_t inAxis[ 3 ],
4954 vec3_t outAxis[ 3 ], qboolean inverse, qboolean ceiling )
4955 {
4956 vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
4957 vec3_t ceilingNormal = { 0.0f, 0.0f, -1.0f };
4958 vec3_t localNormal, xNormal;
4959 float rotAngle;
4960
4961 //the grapplePoint being a surfNormal rotation Normal hack... see above :)
4962 if( ceiling )
4963 {
4964 VectorCopy( ceilingNormal, localNormal );
4965 VectorCopy( surfNormal, xNormal );
4966 }
4967 else
4968 {
4969 //cross the reference normal and the surface normal to get the rotation axis
4970 VectorCopy( surfNormal, localNormal );
4971 CrossProduct( localNormal, refNormal, xNormal );
4972 VectorNormalize( xNormal );
4973 }
4974
4975 //can't rotate with no rotation vector
4976 if( VectorLength( xNormal ) != 0.0f )
4977 {
4978 rotAngle = RAD2DEG( acos( DotProduct( localNormal, refNormal ) ) );
4979
4980 if( inverse )
4981 rotAngle = -rotAngle;
4982
4983 AngleNormalize180( rotAngle );
4984
4985 //hmmm could get away with only one rotation and some clever stuff later... but i'm lazy
4986 RotatePointAroundVector( outAxis[ 0 ], xNormal, inAxis[ 0 ], -rotAngle );
4987 RotatePointAroundVector( outAxis[ 1 ], xNormal, inAxis[ 1 ], -rotAngle );
4988 RotatePointAroundVector( outAxis[ 2 ], xNormal, inAxis[ 2 ], -rotAngle );
4989 }
4990 else
4991 return qfalse;
4992
4993 return qtrue;
4994 }
4995
4996 /*
4997 ===============
4998 BG_PositionBuildableRelativeToPlayer
4999
5000 Find a place to build a buildable
5001 ===============
5002 */
BG_PositionBuildableRelativeToPlayer(const playerState_t * ps,const vec3_t mins,const vec3_t maxs,void (* trace)(trace_t *,const vec3_t,const vec3_t,const vec3_t,const vec3_t,int,int),vec3_t outOrigin,vec3_t outAngles,trace_t * tr)5003 void BG_PositionBuildableRelativeToPlayer( const playerState_t *ps,
5004 const vec3_t mins, const vec3_t maxs,
5005 void (*trace)( trace_t *, const vec3_t, const vec3_t,
5006 const vec3_t, const vec3_t, int, int ),
5007 vec3_t outOrigin, vec3_t outAngles, trace_t *tr )
5008 {
5009 vec3_t forward, entityOrigin, targetOrigin;
5010 vec3_t angles, playerOrigin, playerNormal;
5011 float buildDist;
5012
5013 if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING )
5014 {
5015 if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
5016 VectorSet( playerNormal, 0.0f, 0.0f, -1.0f );
5017 else
5018 VectorCopy( ps->grapplePoint, playerNormal );
5019 }
5020 else
5021 VectorSet( playerNormal, 0.0f, 0.0f, 1.0f );
5022
5023 VectorCopy( ps->viewangles, angles );
5024 VectorCopy( ps->origin, playerOrigin );
5025 buildDist = BG_FindBuildDistForClass( ps->stats[ STAT_PCLASS ] );
5026
5027 AngleVectors( angles, forward, NULL, NULL );
5028 ProjectPointOnPlane( forward, forward, playerNormal );
5029 VectorNormalize( forward );
5030
5031 VectorMA( playerOrigin, buildDist, forward, entityOrigin );
5032
5033 VectorCopy( entityOrigin, targetOrigin );
5034
5035 //so buildings can be placed facing slopes
5036 VectorMA( entityOrigin, 32, playerNormal, entityOrigin );
5037
5038 //so buildings drop to floor
5039 VectorMA( targetOrigin, -128, playerNormal, targetOrigin );
5040
5041 (*trace)( tr, entityOrigin, mins, maxs, targetOrigin, ps->clientNum, MASK_PLAYERSOLID );
5042 VectorCopy( tr->endpos, entityOrigin );
5043 VectorMA( entityOrigin, 0.1f, playerNormal, outOrigin );
5044 vectoangles( forward, outAngles );
5045 }
5046
5047 /*
5048 ===============
5049 BG_GetValueOfHuman
5050
5051 Returns the kills value of some human player
5052 ===============
5053 */
BG_GetValueOfHuman(playerState_t * ps)5054 int BG_GetValueOfHuman( playerState_t *ps )
5055 {
5056 int i, worth = 0;
5057 float portion;
5058
5059 for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
5060 {
5061 if( BG_InventoryContainsUpgrade( i, ps->stats ) )
5062 worth += BG_FindPriceForUpgrade( i );
5063 }
5064
5065 for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
5066 {
5067 if( BG_InventoryContainsWeapon( i, ps->stats ) )
5068 worth += BG_FindPriceForWeapon( i );
5069 }
5070
5071 portion = worth / (float)HUMAN_MAXED;
5072
5073 if( portion < 0.01f )
5074 portion = 0.01f;
5075 else if( portion > 1.0f )
5076 portion = 1.0f;
5077
5078 return ceil( ALIEN_MAX_SINGLE_KILLS * portion );
5079 }
5080
5081 /*
5082 ===============
5083 atof_neg
5084
5085 atof with an allowance for negative values
5086 ===============
5087 */
atof_neg(char * token,qboolean allowNegative)5088 float atof_neg( char *token, qboolean allowNegative )
5089 {
5090 float value;
5091
5092 value = atof( token );
5093
5094 if( !allowNegative && value < 0.0f )
5095 value = 1.0f;
5096
5097 return value;
5098 }
5099
5100 /*
5101 ===============
5102 atoi_neg
5103
5104 atoi with an allowance for negative values
5105 ===============
5106 */
atoi_neg(char * token,qboolean allowNegative)5107 int atoi_neg( char *token, qboolean allowNegative )
5108 {
5109 int value;
5110
5111 value = atoi( token );
5112
5113 if( !allowNegative && value < 0 )
5114 value = 1;
5115
5116 return value;
5117 }
5118
5119 /*
5120 ===============
5121 BG_ParseCSVEquipmentList
5122 ===============
5123 */
BG_ParseCSVEquipmentList(const char * string,weapon_t * weapons,int weaponsSize,upgrade_t * upgrades,int upgradesSize)5124 void BG_ParseCSVEquipmentList( const char *string, weapon_t *weapons, int weaponsSize,
5125 upgrade_t *upgrades, int upgradesSize )
5126 {
5127 char buffer[ MAX_STRING_CHARS ];
5128 int i = 0, j = 0;
5129 char *p, *q;
5130 qboolean EOS = qfalse;
5131
5132 Q_strncpyz( buffer, string, MAX_STRING_CHARS );
5133
5134 p = q = buffer;
5135
5136 while( *p != '\0' )
5137 {
5138 //skip to first , or EOS
5139 while( *p != ',' && *p != '\0' )
5140 p++;
5141
5142 if( *p == '\0' )
5143 EOS = qtrue;
5144
5145 *p = '\0';
5146
5147 //strip leading whitespace
5148 while( *q == ' ' )
5149 q++;
5150
5151 if( weaponsSize )
5152 weapons[ i ] = BG_FindWeaponNumForName( q );
5153
5154 if( upgradesSize )
5155 upgrades[ j ] = BG_FindUpgradeNumForName( q );
5156
5157 if( weaponsSize && weapons[ i ] == WP_NONE &&
5158 upgradesSize && upgrades[ j ] == UP_NONE )
5159 Com_Printf( S_COLOR_YELLOW "WARNING: unknown equipment %s\n", q );
5160 else if( weaponsSize && weapons[ i ] != WP_NONE )
5161 i++;
5162 else if( upgradesSize && upgrades[ j ] != UP_NONE )
5163 j++;
5164
5165 if( !EOS )
5166 {
5167 p++;
5168 q = p;
5169 }
5170 else
5171 break;
5172
5173 if( i == ( weaponsSize - 1 ) || j == ( upgradesSize - 1 ) )
5174 break;
5175 }
5176
5177 if( weaponsSize )
5178 weapons[ i ] = WP_NONE;
5179
5180 if( upgradesSize )
5181 upgrades[ j ] = UP_NONE;
5182 }
5183
5184 /*
5185 ===============
5186 BG_ParseCSVClassList
5187 ===============
5188 */
BG_ParseCSVClassList(const char * string,pClass_t * classes,int classesSize)5189 void BG_ParseCSVClassList( const char *string, pClass_t *classes, int classesSize )
5190 {
5191 char buffer[ MAX_STRING_CHARS ];
5192 int i = 0;
5193 char *p, *q;
5194 qboolean EOS = qfalse;
5195
5196 Q_strncpyz( buffer, string, MAX_STRING_CHARS );
5197
5198 p = q = buffer;
5199
5200 while( *p != '\0' )
5201 {
5202 //skip to first , or EOS
5203 while( *p != ',' && *p != '\0' )
5204 p++;
5205
5206 if( *p == '\0' )
5207 EOS = qtrue;
5208
5209 *p = '\0';
5210
5211 //strip leading whitespace
5212 while( *q == ' ' )
5213 q++;
5214
5215 classes[ i ] = BG_FindClassNumForName( q );
5216
5217 if( classes[ i ] == PCL_NONE )
5218 Com_Printf( S_COLOR_YELLOW "WARNING: unknown class %s\n", q );
5219 else
5220 i++;
5221
5222 if( !EOS )
5223 {
5224 p++;
5225 q = p;
5226 }
5227 else
5228 break;
5229 }
5230
5231 classes[ i ] = PCL_NONE;
5232 }
5233
5234 /*
5235 ===============
5236 BG_ParseCSVBuildableList
5237 ===============
5238 */
BG_ParseCSVBuildableList(const char * string,buildable_t * buildables,int buildablesSize)5239 void BG_ParseCSVBuildableList( const char *string, buildable_t *buildables, int buildablesSize )
5240 {
5241 char buffer[ MAX_STRING_CHARS ];
5242 int i = 0;
5243 char *p, *q;
5244 qboolean EOS = qfalse;
5245
5246 Q_strncpyz( buffer, string, MAX_STRING_CHARS );
5247
5248 p = q = buffer;
5249
5250 while( *p != '\0' )
5251 {
5252 //skip to first , or EOS
5253 while( *p != ',' && *p != '\0' )
5254 p++;
5255
5256 if( *p == '\0' )
5257 EOS = qtrue;
5258
5259 *p = '\0';
5260
5261 //strip leading whitespace
5262 while( *q == ' ' )
5263 q++;
5264
5265 buildables[ i ] = BG_FindClassNumForName( q );
5266
5267 if( buildables[ i ] == BA_NONE )
5268 Com_Printf( S_COLOR_YELLOW "WARNING: unknown buildable %s\n", q );
5269 else
5270 i++;
5271
5272 if( !EOS )
5273 {
5274 p++;
5275 q = p;
5276 }
5277 else
5278 break;
5279 }
5280
5281 buildables[ i ] = BA_NONE;
5282 }
5283
5284 /*
5285 ============
5286 BG_UpgradeClassAvailable
5287 ============
5288 */
BG_UpgradeClassAvailable(playerState_t * ps)5289 qboolean BG_UpgradeClassAvailable( playerState_t *ps )
5290 {
5291 int i;
5292 char buffer[ MAX_STRING_CHARS ];
5293 stage_t currentStage;
5294
5295 trap_Cvar_VariableStringBuffer( "g_alienStage", buffer, MAX_STRING_CHARS );
5296 currentStage = atoi( buffer );
5297
5298 for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
5299 {
5300 if( BG_ClassCanEvolveFromTo( ps->stats[ STAT_PCLASS ], i,
5301 ps->persistant[ PERS_CREDIT ], 0 ) >= 0 &&
5302 BG_FindStagesForClass( i, currentStage ) &&
5303 BG_ClassIsAllowed( i ) )
5304 {
5305 return qtrue;
5306 }
5307 }
5308
5309 return qfalse;
5310 }
5311
5312 typedef struct gameElements_s
5313 {
5314 buildable_t buildables[ BA_NUM_BUILDABLES ];
5315 pClass_t classes[ PCL_NUM_CLASSES ];
5316 weapon_t weapons[ WP_NUM_WEAPONS ];
5317 upgrade_t upgrades[ UP_NUM_UPGRADES ];
5318 } gameElements_t;
5319
5320 static gameElements_t bg_disabledGameElements;
5321
5322 /*
5323 ============
5324 BG_InitAllowedGameElements
5325 ============
5326 */
BG_InitAllowedGameElements(void)5327 void BG_InitAllowedGameElements( void )
5328 {
5329 char cvar[ MAX_CVAR_VALUE_STRING ];
5330
5331 trap_Cvar_VariableStringBuffer( "g_disabledEquipment",
5332 cvar, MAX_CVAR_VALUE_STRING );
5333
5334 BG_ParseCSVEquipmentList( cvar,
5335 bg_disabledGameElements.weapons, WP_NUM_WEAPONS,
5336 bg_disabledGameElements.upgrades, UP_NUM_UPGRADES );
5337
5338 trap_Cvar_VariableStringBuffer( "g_disabledClasses",
5339 cvar, MAX_CVAR_VALUE_STRING );
5340
5341 BG_ParseCSVClassList( cvar,
5342 bg_disabledGameElements.classes, PCL_NUM_CLASSES );
5343
5344 trap_Cvar_VariableStringBuffer( "g_disabledBuildables",
5345 cvar, MAX_CVAR_VALUE_STRING );
5346
5347 BG_ParseCSVBuildableList( cvar,
5348 bg_disabledGameElements.buildables, BA_NUM_BUILDABLES );
5349 }
5350
5351 /*
5352 ============
5353 BG_WeaponIsAllowed
5354 ============
5355 */
BG_WeaponIsAllowed(weapon_t weapon)5356 qboolean BG_WeaponIsAllowed( weapon_t weapon )
5357 {
5358 int i;
5359
5360 for( i = 0; i < WP_NUM_WEAPONS &&
5361 bg_disabledGameElements.weapons[ i ] != WP_NONE; i++ )
5362 {
5363 if( bg_disabledGameElements.weapons[ i ] == weapon )
5364 return qfalse;
5365 }
5366
5367 return qtrue;
5368 }
5369
5370 /*
5371 ============
5372 BG_UpgradeIsAllowed
5373 ============
5374 */
BG_UpgradeIsAllowed(upgrade_t upgrade)5375 qboolean BG_UpgradeIsAllowed( upgrade_t upgrade )
5376 {
5377 int i;
5378
5379 for( i = 0; i < UP_NUM_UPGRADES &&
5380 bg_disabledGameElements.upgrades[ i ] != UP_NONE; i++ )
5381 {
5382 if( bg_disabledGameElements.upgrades[ i ] == upgrade )
5383 return qfalse;
5384 }
5385
5386 return qtrue;
5387 }
5388
5389 /*
5390 ============
5391 BG_ClassIsAllowed
5392 ============
5393 */
BG_ClassIsAllowed(pClass_t class)5394 qboolean BG_ClassIsAllowed( pClass_t class )
5395 {
5396 int i;
5397
5398 for( i = 0; i < PCL_NUM_CLASSES &&
5399 bg_disabledGameElements.classes[ i ] != PCL_NONE; i++ )
5400 {
5401 if( bg_disabledGameElements.classes[ i ] == class )
5402 return qfalse;
5403 }
5404
5405 return qtrue;
5406 }
5407
5408 /*
5409 ============
5410 BG_BuildableIsAllowed
5411 ============
5412 */
BG_BuildableIsAllowed(buildable_t buildable)5413 qboolean BG_BuildableIsAllowed( buildable_t buildable )
5414 {
5415 int i;
5416
5417 for( i = 0; i < BA_NUM_BUILDABLES &&
5418 bg_disabledGameElements.buildables[ i ] != BA_NONE; i++ )
5419 {
5420 if( bg_disabledGameElements.buildables[ i ] == buildable )
5421 return qfalse;
5422 }
5423
5424 return qtrue;
5425 }
5426