Added g_proximityMinesPrice cvar, for setting price of mines Layout now uses !restart instead of !map, to prevent client map reloads.
5890 lines
174 KiB
C
5890 lines
174 KiB
C
/*
|
|
===========================================================================
|
|
Copyright (C) 1999-2005 Id Software, Inc.
|
|
Copyright (C) 2000-2006 Tim Angus
|
|
|
|
This file is part of Tremulous.
|
|
|
|
Tremulous is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
Tremulous is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Tremulous; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
// bg_misc.c -- both games misc functions, all completely stateless
|
|
|
|
#include "../qcommon/q_shared.h"
|
|
#include "bg_public.h"
|
|
|
|
int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode );
|
|
void trap_FS_Read( void *buffer, int len, fileHandle_t f );
|
|
void trap_FS_Write( const void *buffer, int len, fileHandle_t f );
|
|
void trap_FS_FCloseFile( fileHandle_t f );
|
|
void trap_FS_Seek( fileHandle_t f, long offset, fsOrigin_t origin ); // fsOrigin_t
|
|
|
|
modExtremeType_t modEntry[ MOD_BG_COUNT ];
|
|
|
|
buildableAttributes_t bg_buildableList[ ] =
|
|
{
|
|
{
|
|
BA_A_SPAWN, //int buildNum;
|
|
"eggpod", //char *buildName;
|
|
"Egg", //char *humanName;
|
|
"team_alien_spawn", //char *entityName;
|
|
{ "models/buildables/eggpod/eggpod.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -15, -15, -15 }, //vec3_t mins;
|
|
{ 15, 15, 15 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
ASPAWN_BP, //int buildPoints;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
ASPAWN_HEALTH, //int health;
|
|
ASPAWN_REGEN, //int regenRate;
|
|
ASPAWN_SPLASHDAMAGE, //int splashDamage;
|
|
ASPAWN_SPLASHRADIUS, //int splashRadius;
|
|
MOD_ASPAWN, //int meansOfDeath;
|
|
BIT_ALIENS, //int team;
|
|
( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
100, //int nextthink;
|
|
ASPAWN_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.5f, //float minNormal;
|
|
qtrue, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
ASPAWN_CREEPSIZE, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qfalse, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_A_BARRICADE, //int buildNum;
|
|
"barricade", //char *buildName;
|
|
"Barricade", //char *humanName;
|
|
"team_alien_barricade",//char *entityName;
|
|
{ "models/buildables/barricade/barricade.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -35, -35, -15 }, //vec3_t mins;
|
|
{ 35, 35, 60 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
BARRICADE_BP, //int buildPoints;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
BARRICADE_HEALTH, //int health;
|
|
BARRICADE_REGEN, //int regenRate;
|
|
BARRICADE_SPLASHDAMAGE,//int splashDamage;
|
|
BARRICADE_SPLASHRADIUS,//int splashRadius;
|
|
MOD_ASPAWN, //int meansOfDeath;
|
|
BIT_ALIENS, //int team;
|
|
( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
100, //int nextthink;
|
|
BARRICADE_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.707f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qtrue, //qboolean creepTest;
|
|
BARRICADE_CREEPSIZE, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qfalse, //qboolean replaceable;
|
|
},
|
|
{
|
|
BA_A_BOOSTER, //int buildNum;
|
|
"booster", //char *buildName;
|
|
"Booster", //char *humanName;
|
|
"team_alien_booster", //char *entityName;
|
|
{ "models/buildables/booster/booster.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -26, -26, -9 }, //vec3_t mins;
|
|
{ 26, 26, 9 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
BOOSTER_BP, //int buildPoints;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
BOOSTER_HEALTH, //int health;
|
|
BOOSTER_REGEN, //int regenRate;
|
|
BOOSTER_SPLASHDAMAGE, //int splashDamage;
|
|
BOOSTER_SPLASHRADIUS, //int splashRadius;
|
|
MOD_ASPAWN, //int meansOfDeath;
|
|
BIT_ALIENS, //int team;
|
|
( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
100, //int nextthink;
|
|
BOOSTER_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.707f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qtrue, //qboolean creepTest;
|
|
BOOSTER_CREEPSIZE, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qtrue, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qtrue, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_A_ACIDTUBE, //int buildNum;
|
|
"acid_tube", //char *buildName;
|
|
"Acid Tube", //char *humanName;
|
|
"team_alien_acid_tube",//char *entityName;
|
|
{ "models/buildables/acid_tube/acid_tube.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -25, -25, -25 }, //vec3_t mins;
|
|
{ 25, 25, 25 }, //vec3_t maxs;
|
|
-15.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
ACIDTUBE_BP, //int buildPoints;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
ACIDTUBE_HEALTH, //int health;
|
|
ACIDTUBE_REGEN, //int regenRate;
|
|
ACIDTUBE_SPLASHDAMAGE, //int splashDamage;
|
|
ACIDTUBE_SPLASHRADIUS, //int splashRadius;
|
|
MOD_ATUBE, //int meansOfDeath;
|
|
BIT_ALIENS, //int team;
|
|
( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
200, //int nextthink;
|
|
ACIDTUBE_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.0f, //float minNormal;
|
|
qtrue, //qboolean invertNormal;
|
|
qtrue, //qboolean creepTest;
|
|
ACIDTUBE_CREEPSIZE, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qfalse, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_A_HIVE, //int buildNum;
|
|
"hive", //char *buildName;
|
|
"Hive", //char *humanName;
|
|
"team_alien_hive", //char *entityName;
|
|
{ "models/buildables/acid_tube/acid_tube.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -35, -35, -25 }, //vec3_t mins;
|
|
{ 35, 35, 25 }, //vec3_t maxs;
|
|
-15.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
HIVE_BP, //int buildPoints;
|
|
( 1 << S3 ), //int stages
|
|
HIVE_HEALTH, //int health;
|
|
HIVE_REGEN, //int regenRate;
|
|
HIVE_SPLASHDAMAGE, //int splashDamage;
|
|
HIVE_SPLASHRADIUS, //int splashRadius;
|
|
MOD_ASPAWN, //int meansOfDeath;
|
|
BIT_ALIENS, //int team;
|
|
( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
500, //int nextthink;
|
|
HIVE_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_HIVE, //weapon_t turretProjType;
|
|
0.0f, //float minNormal;
|
|
qtrue, //qboolean invertNormal;
|
|
qtrue, //qboolean creepTest;
|
|
HIVE_CREEPSIZE, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qfalse, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_A_TRAPPER, //int buildNum;
|
|
"trapper", //char *buildName;
|
|
"Trapper", //char *humanName;
|
|
"team_alien_trapper", //char *entityName;
|
|
{ "models/buildables/trapper/trapper.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -15, -15, -15 }, //vec3_t mins;
|
|
{ 15, 15, 15 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
TRAPPER_BP, //int buildPoints;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages //NEEDS ADV BUILDER SO S2 AND UP
|
|
TRAPPER_HEALTH, //int health;
|
|
TRAPPER_REGEN, //int regenRate;
|
|
TRAPPER_SPLASHDAMAGE, //int splashDamage;
|
|
TRAPPER_SPLASHRADIUS, //int splashRadius;
|
|
MOD_ASPAWN, //int meansOfDeath;
|
|
BIT_ALIENS, //int team;
|
|
( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
100, //int nextthink;
|
|
TRAPPER_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
TRAPPER_RANGE, //int turretRange;
|
|
TRAPPER_REPEAT, //int turretFireSpeed;
|
|
WP_LOCKBLOB_LAUNCHER, //weapon_t turretProjType;
|
|
0.0f, //float minNormal;
|
|
qtrue, //qboolean invertNormal;
|
|
qtrue, //qboolean creepTest;
|
|
TRAPPER_CREEPSIZE, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qtrue, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qfalse, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_A_OVERMIND, //int buildNum;
|
|
"overmind", //char *buildName;
|
|
"Overmind", //char *humanName;
|
|
"team_alien_overmind", //char *entityName;
|
|
{ "models/buildables/overmind/overmind.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -45, -45, -15 }, //vec3_t mins;
|
|
{ 45, 45, 95 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
OVERMIND_BP, //int buildPoints;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
OVERMIND_HEALTH, //int health;
|
|
OVERMIND_REGEN, //int regenRate;
|
|
OVERMIND_SPLASHDAMAGE, //int splashDamage;
|
|
OVERMIND_SPLASHRADIUS, //int splashRadius;
|
|
MOD_ASPAWN, //int meansOfDeath;
|
|
BIT_ALIENS, //int team;
|
|
( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
OVERMIND_ATTACK_REPEAT,//int nextthink;
|
|
OVERMIND_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
OVERMIND_CREEPSIZE, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qtrue, //qboolean reactorTest;
|
|
qtrue, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_A_HOVEL, //int buildNum;
|
|
"hovel", //char *buildName;
|
|
"Hovel", //char *humanName;
|
|
"team_alien_hovel", //char *entityName;
|
|
{ "models/buildables/hovel/hovel.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -50, -50, -20 }, //vec3_t mins;
|
|
{ 50, 50, 20 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
HOVEL_BP, //int buildPoints;
|
|
( 1 << S3 ), //int stages
|
|
HOVEL_HEALTH, //int health;
|
|
HOVEL_REGEN, //int regenRate;
|
|
HOVEL_SPLASHDAMAGE, //int splashDamage;
|
|
HOVEL_SPLASHRADIUS, //int splashRadius;
|
|
MOD_ASPAWN, //int meansOfDeath;
|
|
BIT_ALIENS, //int team;
|
|
( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
150, //int nextthink;
|
|
HOVEL_BT, //int buildTime;
|
|
qtrue, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qtrue, //qboolean creepTest;
|
|
HOVEL_CREEPSIZE, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qtrue, //qboolean reactorTest;
|
|
qfalse, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_H_SPAWN, //int buildNum;
|
|
"telenode", //char *buildName;
|
|
"Telenode", //char *humanName;
|
|
"team_human_spawn", //char *entityName;
|
|
{ "models/buildables/telenode/telenode.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -40, -40, -4 }, //vec3_t mins;
|
|
{ 40, 40, 4 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
HSPAWN_BP, //int buildPoints;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
HSPAWN_HEALTH, //int health;
|
|
0, //int regenRate;
|
|
HSPAWN_SPLASHDAMAGE, //int splashDamage;
|
|
HSPAWN_SPLASHRADIUS, //int splashRadius;
|
|
MOD_HSPAWN, //int meansOfDeath;
|
|
BIT_HUMANS, //int team;
|
|
( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
100, //int nextthink;
|
|
HSPAWN_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
0, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qtrue, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qfalse, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_H_MEDISTAT, //int buildNum;
|
|
"medistat", //char *buildName;
|
|
"Medistation", //char *humanName;
|
|
"team_human_medistat", //char *entityName;
|
|
{ "models/buildables/medistat/medistat.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -35, -35, -7 }, //vec3_t mins;
|
|
{ 35, 35, 7 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
MEDISTAT_BP, //int buildPoints;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
MEDISTAT_HEALTH, //int health;
|
|
0, //int regenRate;
|
|
MEDISTAT_SPLASHDAMAGE, //int splashDamage;
|
|
MEDISTAT_SPLASHRADIUS, //int splashRadius;
|
|
MOD_HSPAWN, //int meansOfDeath;
|
|
BIT_HUMANS, //int team;
|
|
( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
100, //int nextthink;
|
|
MEDISTAT_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
0, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qtrue, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qtrue, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_H_MGTURRET, //int buildNum;
|
|
"mgturret", //char *buildName;
|
|
"Machinegun Turret", //char *humanName;
|
|
"team_human_mgturret", //char *entityName;
|
|
{ "models/buildables/mgturret/turret_base.md3",
|
|
"models/buildables/mgturret/turret_barrel.md3",
|
|
"models/buildables/mgturret/turret_top.md3", 0 },
|
|
1.0f, //float modelScale;
|
|
{ -25, -25, -20 }, //vec3_t mins;
|
|
{ 25, 25, 20 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
MGTURRET_BP, //int buildPoints;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
MGTURRET_HEALTH, //int health;
|
|
0, //int regenRate;
|
|
MGTURRET_SPLASHDAMAGE, //int splashDamage;
|
|
MGTURRET_SPLASHRADIUS, //int splashRadius;
|
|
MOD_HSPAWN, //int meansOfDeath;
|
|
BIT_HUMANS, //int team;
|
|
( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
50, //int nextthink;
|
|
MGTURRET_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
MGTURRET_RANGE, //int turretRange;
|
|
MGTURRET_REPEAT, //int turretFireSpeed;
|
|
WP_MGTURRET, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
0, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qtrue, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qfalse, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_H_TESLAGEN, //int buildNum;
|
|
"tesla", //char *buildName;
|
|
"Tesla Generator", //char *humanName;
|
|
"team_human_tesla", //char *entityName;
|
|
{ "models/buildables/tesla/tesla.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -22, -22, -40 }, //vec3_t mins;
|
|
{ 22, 22, 40 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
TESLAGEN_BP, //int buildPoints;
|
|
( 1 << S3 ), //int stages
|
|
TESLAGEN_HEALTH, //int health;
|
|
0, //int regenRate;
|
|
TESLAGEN_SPLASHDAMAGE, //int splashDamage;
|
|
TESLAGEN_SPLASHRADIUS, //int splashRadius;
|
|
MOD_HSPAWN, //int meansOfDeath;
|
|
BIT_HUMANS, //int team;
|
|
( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
150, //int nextthink;
|
|
TESLAGEN_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
TESLAGEN_RANGE, //int turretRange;
|
|
TESLAGEN_REPEAT, //int turretFireSpeed;
|
|
WP_TESLAGEN, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
0, //int creepSize;
|
|
qtrue, //qboolean dccTest;
|
|
qtrue, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qfalse, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_H_DCC, //int buildNum;
|
|
"dcc", //char *buildName;
|
|
"Defence Computer", //char *humanName;
|
|
"team_human_dcc", //char *entityName;
|
|
{ "models/buildables/dcc/dcc.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -35, -35, -13 }, //vec3_t mins;
|
|
{ 35, 35, 47 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
DC_BP, //int buildPoints;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
DC_HEALTH, //int health;
|
|
0, //int regenRate;
|
|
DC_SPLASHDAMAGE, //int splashDamage;
|
|
DC_SPLASHRADIUS, //int splashRadius;
|
|
MOD_HSPAWN, //int meansOfDeath;
|
|
BIT_HUMANS, //int team;
|
|
( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
100, //int nextthink;
|
|
DC_BT, //int buildTime;
|
|
qfalse, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
0, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qtrue, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_H_ARMOURY, //int buildNum;
|
|
"arm", //char *buildName;
|
|
"Armoury", //char *humanName;
|
|
"team_human_armoury", //char *entityName;
|
|
{ "models/buildables/arm/arm.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -40, -40, -13 }, //vec3_t mins;
|
|
{ 40, 40, 50 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
ARMOURY_BP, //int buildPoints;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
ARMOURY_HEALTH, //int health;
|
|
0, //int regenRate;
|
|
ARMOURY_SPLASHDAMAGE, //int splashDamage;
|
|
ARMOURY_SPLASHRADIUS, //int splashRadius;
|
|
MOD_HSPAWN, //int meansOfDeath;
|
|
BIT_HUMANS, //int team;
|
|
( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
100, //int nextthink;
|
|
ARMOURY_BT, //int buildTime;
|
|
qtrue, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
0, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qtrue, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_H_REACTOR, //int buildNum;
|
|
"reactor", //char *buildName;
|
|
"Reactor", //char *humanName;
|
|
"team_human_reactor", //char *entityName;
|
|
{ "models/buildables/reactor/reactor.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -50, -50, -15 }, //vec3_t mins;
|
|
{ 50, 50, 95 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
REACTOR_BP, //int buildPoints;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
REACTOR_HEALTH, //int health;
|
|
0, //int regenRate;
|
|
REACTOR_SPLASHDAMAGE, //int splashDamage;
|
|
REACTOR_SPLASHRADIUS, //int splashRadius;
|
|
MOD_HSPAWN, //int meansOfDeath;
|
|
BIT_HUMANS, //int team;
|
|
( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
REACTOR_ATTACK_REPEAT, //int nextthink;
|
|
REACTOR_BT, //int buildTime;
|
|
qtrue, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
0, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qtrue, //qboolean reactorTest;
|
|
qtrue, //qboolean replacable;
|
|
},
|
|
{
|
|
BA_H_REPEATER, //int buildNum;
|
|
"repeater", //char *buildName;
|
|
"Repeater", //char *humanName;
|
|
"team_human_repeater", //char *entityName;
|
|
{ "models/buildables/repeater/repeater.md3", 0, 0, 0 },
|
|
1.0f, //float modelScale;
|
|
{ -15, -15, -15 }, //vec3_t mins;
|
|
{ 15, 15, 25 }, //vec3_t maxs;
|
|
0.0f, //float zOffset;
|
|
TR_GRAVITY, //trType_t traj;
|
|
0.0, //float bounce;
|
|
REPEATER_BP, //int buildPoints;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
REPEATER_HEALTH, //int health;
|
|
0, //int regenRate;
|
|
REPEATER_SPLASHDAMAGE, //int splashDamage;
|
|
REPEATER_SPLASHRADIUS, //int splashRadius;
|
|
MOD_HSPAWN, //int meansOfDeath;
|
|
BIT_HUMANS, //int team;
|
|
( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ), //weapon_t buildWeapon;
|
|
BANIM_IDLE1, //int idleAnim;
|
|
100, //int nextthink;
|
|
REPEATER_BT, //int buildTime;
|
|
qtrue, //qboolean usable;
|
|
0, //int turretRange;
|
|
0, //int turretFireSpeed;
|
|
WP_NONE, //weapon_t turretProjType;
|
|
0.95f, //float minNormal;
|
|
qfalse, //qboolean invertNormal;
|
|
qfalse, //qboolean creepTest;
|
|
0, //int creepSize;
|
|
qfalse, //qboolean dccTest;
|
|
qfalse, //qboolean transparentTest;
|
|
qfalse, //qboolean reactorTest;
|
|
qtrue, //qboolean replacable;
|
|
}
|
|
};
|
|
|
|
int bg_numBuildables = sizeof( bg_buildableList ) / sizeof( bg_buildableList[ 0 ] );
|
|
|
|
//separate from bg_buildableList to work around char struct init bug
|
|
buildableAttributeOverrides_t bg_buildableOverrideList[ BA_NUM_BUILDABLES ];
|
|
|
|
/*
|
|
==============
|
|
BG_FindBuildNumForName
|
|
==============
|
|
*/
|
|
int BG_FindBuildNumForName( char *name )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( !Q_stricmp( bg_buildableList[ i ].buildName, name ) )
|
|
return bg_buildableList[ i ].buildNum;
|
|
}
|
|
|
|
//wimp out
|
|
return BA_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBuildNumForEntityName
|
|
==============
|
|
*/
|
|
int BG_FindBuildNumForEntityName( char *name )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( !Q_stricmp( bg_buildableList[ i ].entityName, name ) )
|
|
return bg_buildableList[ i ].buildNum;
|
|
}
|
|
|
|
//wimp out
|
|
return BA_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindNameForBuildNum
|
|
==============
|
|
*/
|
|
char *BG_FindNameForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
return bg_buildableList[ i ].buildName;
|
|
}
|
|
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindHumanNameForBuildNum
|
|
==============
|
|
*/
|
|
char *BG_FindHumanNameForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
return bg_buildableList[ i ].humanName;
|
|
}
|
|
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindEntityNameForBuildNum
|
|
==============
|
|
*/
|
|
char *BG_FindEntityNameForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
return bg_buildableList[ i ].entityName;
|
|
}
|
|
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindModelsForBuildNum
|
|
==============
|
|
*/
|
|
char *BG_FindModelsForBuildable( int bclass, int modelNum )
|
|
{
|
|
int i;
|
|
|
|
if( bg_buildableOverrideList[ bclass ].models[ modelNum ][ 0 ] != 0 )
|
|
return bg_buildableOverrideList[ bclass ].models[ modelNum ];
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
return bg_buildableList[ i ].models[ modelNum ];
|
|
}
|
|
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindModelScaleForBuildable
|
|
==============
|
|
*/
|
|
float BG_FindModelScaleForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
if( bg_buildableOverrideList[ bclass ].modelScale != 0.0f )
|
|
return bg_buildableOverrideList[ bclass ].modelScale;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
return bg_buildableList[ i ].modelScale;
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelScaleForBuildable( %d )\n", bclass );
|
|
return 1.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBBoxForBuildable
|
|
==============
|
|
*/
|
|
void BG_FindBBoxForBuildable( int bclass, vec3_t mins, vec3_t maxs )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
if( mins != NULL )
|
|
{
|
|
VectorCopy( bg_buildableList[ i ].mins, mins );
|
|
|
|
if( VectorLength( bg_buildableOverrideList[ bclass ].mins ) )
|
|
VectorCopy( bg_buildableOverrideList[ bclass ].mins, mins );
|
|
}
|
|
|
|
if( maxs != NULL )
|
|
{
|
|
VectorCopy( bg_buildableList[ i ].maxs, maxs );
|
|
|
|
if( VectorLength( bg_buildableOverrideList[ bclass ].maxs ) )
|
|
VectorCopy( bg_buildableOverrideList[ bclass ].maxs, maxs );
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( mins != NULL )
|
|
VectorCopy( bg_buildableList[ 0 ].mins, mins );
|
|
|
|
if( maxs != NULL )
|
|
VectorCopy( bg_buildableList[ 0 ].maxs, maxs );
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindZOffsetForBuildable
|
|
==============
|
|
*/
|
|
float BG_FindZOffsetForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
if( bg_buildableOverrideList[ bclass ].zOffset != 0.0f )
|
|
return bg_buildableOverrideList[ bclass ].zOffset;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].zOffset;
|
|
}
|
|
}
|
|
|
|
return 0.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindTrajectoryForBuildable
|
|
==============
|
|
*/
|
|
trType_t BG_FindTrajectoryForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].traj;
|
|
}
|
|
}
|
|
|
|
return TR_GRAVITY;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBounceForBuildable
|
|
==============
|
|
*/
|
|
float BG_FindBounceForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].bounce;
|
|
}
|
|
}
|
|
|
|
return 0.0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBuildPointsForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindBuildPointsForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].buildPoints;
|
|
}
|
|
}
|
|
|
|
return 1000;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindStagesForBuildable
|
|
==============
|
|
*/
|
|
qboolean BG_FindStagesForBuildable( int bclass, stage_t stage )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
if( bg_buildableList[ i ].stages & ( 1 << stage ) )
|
|
return qtrue;
|
|
else
|
|
return qfalse;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindHealthForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindHealthForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].health;
|
|
}
|
|
}
|
|
|
|
return 1000;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindRegenRateForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindRegenRateForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].regenRate;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindSplashDamageForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindSplashDamageForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].splashDamage;
|
|
}
|
|
}
|
|
|
|
return 50;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindSplashRadiusForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindSplashRadiusForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].splashRadius;
|
|
}
|
|
}
|
|
|
|
return 200;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindMODForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindMODForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].meansOfDeath;
|
|
}
|
|
}
|
|
|
|
return MOD_UNKNOWN;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindTeamForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindTeamForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].team;
|
|
}
|
|
}
|
|
|
|
return BIT_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBuildWeaponForBuildable
|
|
==============
|
|
*/
|
|
weapon_t BG_FindBuildWeaponForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].buildWeapon;
|
|
}
|
|
}
|
|
|
|
return BA_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindAnimForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindAnimForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].idleAnim;
|
|
}
|
|
}
|
|
|
|
return BANIM_IDLE1;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindNextThinkForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindNextThinkForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].nextthink;
|
|
}
|
|
}
|
|
|
|
return 100;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBuildTimeForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindBuildTimeForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].buildTime;
|
|
}
|
|
}
|
|
|
|
return 10000;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindUsableForBuildable
|
|
==============
|
|
*/
|
|
qboolean BG_FindUsableForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].usable;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindFireSpeedForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindFireSpeedForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].turretFireSpeed;
|
|
}
|
|
}
|
|
|
|
return 1000;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindRangeForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindRangeForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].turretRange;
|
|
}
|
|
}
|
|
|
|
return 1000;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindProjTypeForBuildable
|
|
==============
|
|
*/
|
|
weapon_t BG_FindProjTypeForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].turretProjType;
|
|
}
|
|
}
|
|
|
|
return WP_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindMinNormalForBuildable
|
|
==============
|
|
*/
|
|
float BG_FindMinNormalForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].minNormal;
|
|
}
|
|
}
|
|
|
|
return 0.707f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindInvertNormalForBuildable
|
|
==============
|
|
*/
|
|
qboolean BG_FindInvertNormalForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].invertNormal;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindCreepTestForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindCreepTestForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].creepTest;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindCreepSizeForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindCreepSizeForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].creepSize;
|
|
}
|
|
}
|
|
|
|
return CREEP_BASESIZE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindDCCTestForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindDCCTestForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].dccTest;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindUniqueTestForBuildable
|
|
==============
|
|
*/
|
|
int BG_FindUniqueTestForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].reactorTest;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindReplaceableTestForBuildable
|
|
==============
|
|
*/
|
|
qboolean BG_FindReplaceableTestForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].replaceable;
|
|
}
|
|
}
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindOverrideForBuildable
|
|
==============
|
|
*/
|
|
static buildableAttributeOverrides_t *BG_FindOverrideForBuildable( int bclass )
|
|
{
|
|
return &bg_buildableOverrideList[ bclass ];
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindTransparentTestForBuildable
|
|
==============
|
|
*/
|
|
qboolean BG_FindTransparentTestForBuildable( int bclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( bg_buildableList[ i ].buildNum == bclass )
|
|
{
|
|
return bg_buildableList[ i ].transparentTest;
|
|
}
|
|
}
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
======================
|
|
BG_ParseBuildableFile
|
|
|
|
Parses a configuration file describing a builable
|
|
======================
|
|
*/
|
|
static qboolean BG_ParseBuildableFile( const char *filename, buildableAttributeOverrides_t *bao )
|
|
{
|
|
char *text_p;
|
|
int i;
|
|
int len;
|
|
char *token;
|
|
char text[ 20000 ];
|
|
fileHandle_t f;
|
|
float scale;
|
|
|
|
|
|
// load the file
|
|
len = trap_FS_FOpenFile( filename, &f, FS_READ );
|
|
if( len <= 0 )
|
|
return qfalse;
|
|
|
|
if( len >= sizeof( text ) - 1 )
|
|
{
|
|
Com_Printf( S_COLOR_RED "ERROR: Buildable file %s too long\n", filename );
|
|
return qfalse;
|
|
}
|
|
|
|
trap_FS_Read( text, len, f );
|
|
text[ len ] = 0;
|
|
trap_FS_FCloseFile( f );
|
|
|
|
// parse the text
|
|
text_p = text;
|
|
|
|
// read optional parameters
|
|
while( 1 )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
|
|
if( !token )
|
|
break;
|
|
|
|
if( !Q_stricmp( token, "" ) )
|
|
break;
|
|
|
|
if( !Q_stricmp( token, "model" ) )
|
|
{
|
|
int index = 0;
|
|
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
index = atoi( token );
|
|
|
|
if( index < 0 )
|
|
index = 0;
|
|
else if( index > 3 )
|
|
index = 3;
|
|
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
Q_strncpyz( bao->models[ index ], token, sizeof( bao->models[ 0 ] ) );
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "modelScale" ) )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
scale = atof( token );
|
|
|
|
if( scale < 0.0f )
|
|
scale = 0.0f;
|
|
|
|
bao->modelScale = scale;
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "mins" ) )
|
|
{
|
|
for( i = 0; i <= 2; i++ )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
bao->mins[ i ] = atof( token );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "maxs" ) )
|
|
{
|
|
for( i = 0; i <= 2; i++ )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
bao->maxs[ i ] = atof( token );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "zOffset" ) )
|
|
{
|
|
float offset;
|
|
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
offset = atof( token );
|
|
|
|
bao->zOffset = offset;
|
|
|
|
continue;
|
|
}
|
|
|
|
|
|
Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token );
|
|
return qfalse;
|
|
}
|
|
|
|
return qtrue;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
BG_InitBuildableOverrides
|
|
|
|
Set any overrides specfied by file
|
|
===============
|
|
*/
|
|
void BG_InitBuildableOverrides( void )
|
|
{
|
|
int i;
|
|
buildableAttributeOverrides_t *bao;
|
|
|
|
for( i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++ )
|
|
{
|
|
bao = BG_FindOverrideForBuildable( i );
|
|
|
|
BG_ParseBuildableFile( va( "overrides/buildables/%s.cfg", BG_FindNameForBuildable( i ) ), bao );
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
classAttributes_t bg_classList[ ] =
|
|
{
|
|
{
|
|
PCL_NONE, //int classnum;
|
|
"spectator", //char *className;
|
|
"Spectator", //char *humanName;
|
|
"", //char *modelname;
|
|
1.0f, //float modelScale;
|
|
"", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"", //char *hudname;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -15, -15, -15 }, //vec3_t mins;
|
|
{ 15, 15, 15 }, //vec3_t maxs;
|
|
{ 15, 15, 15 }, //vec3_t crouchmaxs;
|
|
{ -15, -15, -15 }, //vec3_t deadmins;
|
|
{ 15, 15, 15 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
0, 0, //int viewheight, crouchviewheight;
|
|
0, //int health;
|
|
0.0f, //float fallDamage;
|
|
0, //int regenRate;
|
|
0, //int abilities;
|
|
WP_NONE, //weapon_t startWeapon
|
|
0.0f, //float buildDist;
|
|
90, //int fov;
|
|
0.000f, //float bob;
|
|
1.0f, //float bobCycle;
|
|
0, //int steptime;
|
|
600, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
100.0f, //float stopSpeed;
|
|
270.0f, //float jumpMagnitude;
|
|
1.0f, //float knockbackScale;
|
|
{ PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
|
|
0, //int cost;
|
|
0 //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_BUILDER0, //int classnum;
|
|
"builder", //char *className;
|
|
"Builder", //char *humanName;
|
|
"builder", //char *modelname;
|
|
1.0f, //float modelScale;
|
|
"default", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"alien_builder_hud", //char *hudname;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -15, -15, -20 }, //vec3_t mins;
|
|
{ 15, 15, 20 }, //vec3_t maxs;
|
|
{ 15, 15, 20 }, //vec3_t crouchmaxs;
|
|
{ -15, -15, -4 }, //vec3_t deadmins;
|
|
{ 15, 15, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
0, 0, //int viewheight, crouchviewheight;
|
|
ABUILDER_HEALTH, //int health;
|
|
0.2f, //float fallDamage;
|
|
ABUILDER_REGEN, //int regenRate;
|
|
SCA_TAKESFALLDAMAGE|SCA_FOVWARPS|SCA_ALIENSENSE,//int abilities;
|
|
WP_ABUILD, //weapon_t startWeapon
|
|
95.0f, //float buildDist;
|
|
80, //int fov;
|
|
0.001f, //float bob;
|
|
2.0f, //float bobCycle;
|
|
150, //int steptime;
|
|
ABUILDER_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
100.0f, //float stopSpeed;
|
|
195.0f, //float jumpMagnitude;
|
|
1.0f, //float knockbackScale;
|
|
{ PCL_ALIEN_BUILDER0_UPG, PCL_ALIEN_LEVEL0, PCL_NONE }, //int children[ 3 ];
|
|
ABUILDER_COST, //int cost;
|
|
ABUILDER_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_BUILDER0_UPG, //int classnum;
|
|
"builderupg", //char *classname;
|
|
"Advanced Builder", //char *humanname;
|
|
"builder", //char *modelname;
|
|
1.0f, //float modelScale;
|
|
"advanced", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"alien_builder_hud", //char *hudname;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -20, -20, -20 }, //vec3_t mins;
|
|
{ 20, 20, 20 }, //vec3_t maxs;
|
|
{ 20, 20, 20 }, //vec3_t crouchmaxs;
|
|
{ -20, -20, -4 }, //vec3_t deadmins;
|
|
{ 20, 20, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
0, 0, //int viewheight, crouchviewheight;
|
|
ABUILDER_UPG_HEALTH, //int health;
|
|
0.0f, //float fallDamage;
|
|
ABUILDER_UPG_REGEN, //int regenRate;
|
|
SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities;
|
|
WP_ABUILD2, //weapon_t startWeapon
|
|
105.0f, //float buildDist;
|
|
110, //int fov;
|
|
0.001f, //float bob;
|
|
2.0f, //float bobCycle;
|
|
100, //int steptime;
|
|
ABUILDER_UPG_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
100.0f, //float stopSpeed;
|
|
270.0f, //float jumpMagnitude;
|
|
1.0f, //float knockbackScale;
|
|
{ PCL_ALIEN_LEVEL0, PCL_NONE, PCL_NONE }, //int children[ 3 ];
|
|
ABUILDER_UPG_COST, //int cost;
|
|
ABUILDER_UPG_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_LEVEL0, //int classnum;
|
|
"level0", //char *classname;
|
|
"Soldier", //char *humanname;
|
|
"jumper", //char *modelname;
|
|
0.2f, //float modelScale;
|
|
"default", //char *skinname;
|
|
0.3f, //float shadowScale;
|
|
"alien_general_hud", //char *hudname;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -15, -15, -15 }, //vec3_t mins;
|
|
{ 15, 15, 15 }, //vec3_t maxs;
|
|
{ 15, 15, 15 }, //vec3_t crouchmaxs;
|
|
{ -15, -15, -4 }, //vec3_t deadmins;
|
|
{ 15, 15, 4 }, //vec3_t deadmaxs;
|
|
-8.0f, //float zOffset
|
|
0, 0, //int viewheight, crouchviewheight;
|
|
LEVEL0_HEALTH, //int health;
|
|
0.0f, //float fallDamage;
|
|
LEVEL0_REGEN, //int regenRate;
|
|
SCA_WALLCLIMBER|SCA_NOWEAPONDRIFT|
|
|
SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
|
|
WP_ALEVEL0, //weapon_t startWeapon
|
|
0.0f, //float buildDist;
|
|
140, //int fov;
|
|
0.0f, //float bob;
|
|
2.5f, //float bobCycle;
|
|
25, //int steptime;
|
|
LEVEL0_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
400.0f, //float stopSpeed;
|
|
250.0f, //float jumpMagnitude;
|
|
2.0f, //float knockbackScale;
|
|
{ PCL_ALIEN_LEVEL1, PCL_NONE, PCL_NONE }, //int children[ 3 ];
|
|
LEVEL0_COST, //int cost;
|
|
LEVEL0_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_LEVEL1, //int classnum;
|
|
"level1", //char *classname;
|
|
"Hydra", //char *humanname;
|
|
"spitter", //char *modelname;
|
|
0.6f, //float modelScale;
|
|
"default", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"alien_general_hud", //char *hudname;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -18, -18, -18 }, //vec3_t mins;
|
|
{ 18, 18, 18 }, //vec3_t maxs;
|
|
{ 18, 18, 18 }, //vec3_t crouchmaxs;
|
|
{ -18, -18, -4 }, //vec3_t deadmins;
|
|
{ 18, 18, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
0, 0, //int viewheight, crouchviewheight;
|
|
LEVEL1_HEALTH, //int health;
|
|
0.0f, //float fallDamage;
|
|
LEVEL1_REGEN, //int regenRate;
|
|
SCA_NOWEAPONDRIFT|
|
|
SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities;
|
|
WP_ALEVEL1, //weapon_t startWeapon
|
|
0.0f, //float buildDist;
|
|
120, //int fov;
|
|
0.001f, //float bob;
|
|
1.8f, //float bobCycle;
|
|
60, //int steptime;
|
|
LEVEL1_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
300.0f, //float stopSpeed;
|
|
270.0f, //float jumpMagnitude;
|
|
1.2f, //float knockbackScale;
|
|
{ PCL_ALIEN_LEVEL2, PCL_ALIEN_LEVEL1_UPG, PCL_NONE }, //int children[ 3 ];
|
|
LEVEL1_COST, //int cost;
|
|
LEVEL1_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_LEVEL1_UPG, //int classnum;
|
|
"level1upg", //char *classname;
|
|
"Hydra Upgrade", //char *humanname;
|
|
"spitter", //char *modelname;
|
|
0.7f, //float modelScale;
|
|
"blue", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"alien_general_hud", //char *hudname;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -20, -20, -20 }, //vec3_t mins;
|
|
{ 20, 20, 20 }, //vec3_t maxs;
|
|
{ 20, 20, 20 }, //vec3_t crouchmaxs;
|
|
{ -20, -20, -4 }, //vec3_t deadmins;
|
|
{ 20, 20, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
0, 0, //int viewheight, crouchviewheight;
|
|
LEVEL1_UPG_HEALTH, //int health;
|
|
0.0f, //float fallDamage;
|
|
LEVEL1_UPG_REGEN, //int regenRate;
|
|
SCA_NOWEAPONDRIFT|SCA_FOVWARPS|
|
|
SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities;
|
|
WP_ALEVEL1_UPG, //weapon_t startWeapon
|
|
0.0f, //float buildDist;
|
|
120, //int fov;
|
|
0.001f, //float bob;
|
|
1.8f, //float bobCycle;
|
|
60, //int steptime;
|
|
LEVEL1_UPG_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
300.0f, //float stopSpeed;
|
|
270.0f, //float jumpMagnitude;
|
|
1.1f, //float knockbackScale;
|
|
{ PCL_ALIEN_LEVEL2, PCL_NONE, PCL_NONE }, //int children[ 3 ];
|
|
LEVEL1_UPG_COST, //int cost;
|
|
LEVEL1_UPG_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_LEVEL2, //int classnum;
|
|
"level2", //char *classname;
|
|
"Chimera", //char *humanname;
|
|
"tarantula", //char *modelname;
|
|
0.75f, //float modelScale;
|
|
"default", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"alien_general_hud", //char *hudname;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -22, -22, -22 }, //vec3_t mins;
|
|
{ 22, 22, 22 }, //vec3_t maxs;
|
|
{ 22, 22, 22 }, //vec3_t crouchmaxs;
|
|
{ -22, -22, -4 }, //vec3_t deadmins;
|
|
{ 22, 22, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
10, 10, //int viewheight, crouchviewheight;
|
|
LEVEL2_HEALTH, //int health;
|
|
0.0f, //float fallDamage;
|
|
LEVEL2_REGEN, //int regenRate;
|
|
SCA_NOWEAPONDRIFT|SCA_WALLJUMPER|
|
|
SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
|
|
WP_ALEVEL2, //weapon_t startWeapon
|
|
0.0f, //float buildDist;
|
|
90, //int fov;
|
|
0.001f, //float bob;
|
|
1.5f, //float bobCycle;
|
|
80, //int steptime;
|
|
LEVEL2_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
2.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
100.0f, //float stopSpeed;
|
|
400.0f, //float jumpMagnitude;
|
|
0.8f, //float knockbackScale;
|
|
{ PCL_ALIEN_LEVEL3, PCL_ALIEN_LEVEL2_UPG, PCL_NONE }, //int children[ 3 ];
|
|
LEVEL2_COST, //int cost;
|
|
LEVEL2_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_LEVEL2_UPG, //int classnum;
|
|
"level2upg", //char *classname;
|
|
"Chimera Upgrade", //char *humanname;
|
|
"tarantula", //char *modelname;
|
|
0.9f, //float modelScale;
|
|
"red", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"alien_general_hud", //char *hudname;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -24, -24, -24 }, //vec3_t mins;
|
|
{ 24, 24, 24 }, //vec3_t maxs;
|
|
{ 24, 24, 24 }, //vec3_t crouchmaxs;
|
|
{ -24, -24, -4 }, //vec3_t deadmins;
|
|
{ 24, 24, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
12, 12, //int viewheight, crouchviewheight;
|
|
LEVEL2_UPG_HEALTH, //int health;
|
|
0.0f, //float fallDamage;
|
|
LEVEL2_UPG_REGEN, //int regenRate;
|
|
SCA_NOWEAPONDRIFT|SCA_WALLJUMPER|
|
|
SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
|
|
WP_ALEVEL2_UPG, //weapon_t startWeapon
|
|
0.0f, //float buildDist;
|
|
90, //int fov;
|
|
0.001f, //float bob;
|
|
1.5f, //float bobCycle;
|
|
80, //int steptime;
|
|
LEVEL2_UPG_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
2.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
100.0f, //float stopSpeed;
|
|
400.0f, //float jumpMagnitude;
|
|
0.7f, //float knockbackScale;
|
|
{ PCL_ALIEN_LEVEL3, PCL_NONE, PCL_NONE }, //int children[ 3 ];
|
|
LEVEL2_UPG_COST, //int cost;
|
|
LEVEL2_UPG_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_LEVEL3, //int classnum;
|
|
"level3", //char *classname;
|
|
"Dragoon", //char *humanname;
|
|
"prowl", //char *modelname;
|
|
1.0f, //float modelScale;
|
|
"default", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"alien_general_hud", //char *hudname;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -32, -32, -21 }, //vec3_t mins;
|
|
{ 32, 32, 21 }, //vec3_t maxs;
|
|
{ 32, 32, 21 }, //vec3_t crouchmaxs;
|
|
{ -32, -32, -4 }, //vec3_t deadmins;
|
|
{ 32, 32, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
24, 24, //int viewheight, crouchviewheight;
|
|
LEVEL3_HEALTH, //int health;
|
|
0.0f, //float fallDamage;
|
|
LEVEL3_REGEN, //int regenRate;
|
|
SCA_NOWEAPONDRIFT|
|
|
SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
|
|
WP_ALEVEL3, //weapon_t startWeapon
|
|
0.0f, //float buildDist;
|
|
110, //int fov;
|
|
0.0005f, //float bob;
|
|
1.3f, //float bobCycle;
|
|
90, //int steptime;
|
|
LEVEL3_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
200.0f, //float stopSpeed;
|
|
270.0f, //float jumpMagnitude;
|
|
0.5f, //float knockbackScale;
|
|
{ PCL_ALIEN_LEVEL4, PCL_ALIEN_LEVEL3_UPG, PCL_NONE }, //int children[ 3 ];
|
|
LEVEL3_COST, //int cost;
|
|
LEVEL3_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_LEVEL3_UPG, //int classnum;
|
|
"level3upg", //char *classname;
|
|
"Dragoon Upgrade", //char *humanname;
|
|
"prowl", //char *modelname;
|
|
1.0f, //float modelScale;
|
|
"default", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"alien_general_hud", //char *hudname;
|
|
( 1 << S3 ), //int stages
|
|
{ -32, -32, -21 }, //vec3_t mins;
|
|
{ 32, 32, 21 }, //vec3_t maxs;
|
|
{ 32, 32, 21 }, //vec3_t crouchmaxs;
|
|
{ -32, -32, -4 }, //vec3_t deadmins;
|
|
{ 32, 32, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
27, 27, //int viewheight, crouchviewheight;
|
|
LEVEL3_UPG_HEALTH, //int health;
|
|
0.0f, //float fallDamage;
|
|
LEVEL3_UPG_REGEN, //int regenRate;
|
|
SCA_NOWEAPONDRIFT|
|
|
SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
|
|
WP_ALEVEL3_UPG, //weapon_t startWeapon
|
|
0.0f, //float buildDist;
|
|
110, //int fov;
|
|
0.0005f, //float bob;
|
|
1.3f, //float bobCycle;
|
|
90, //int steptime;
|
|
LEVEL3_UPG_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
200.0f, //float stopSpeed;
|
|
270.0f, //float jumpMagnitude;
|
|
0.4f, //float knockbackScale;
|
|
{ PCL_ALIEN_LEVEL4, PCL_NONE, PCL_NONE }, //int children[ 3 ];
|
|
LEVEL3_UPG_COST, //int cost;
|
|
LEVEL3_UPG_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_ALIEN_LEVEL4, //int classnum;
|
|
"level4", //char *classname;
|
|
"Big Mofo", //char *humanname;
|
|
"mofo", //char *modelname;
|
|
1.0f, //float modelScale;
|
|
"default", //char *skinname;
|
|
2.0f, //float shadowScale;
|
|
"alien_general_hud", //char *hudname;
|
|
( 1 << S3 ), //int stages
|
|
{ -30, -30, -20 }, //vec3_t mins;
|
|
{ 30, 30, 20 }, //vec3_t maxs;
|
|
{ 30, 30, 20 }, //vec3_t crouchmaxs;
|
|
{ -15, -15, -4 }, //vec3_t deadmins;
|
|
{ 15, 15, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
35, 35, //int viewheight, crouchviewheight;
|
|
LEVEL4_HEALTH, //int health;
|
|
0.0f, //float fallDamage;
|
|
LEVEL4_REGEN, //int regenRate;
|
|
SCA_NOWEAPONDRIFT|
|
|
SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities;
|
|
WP_ALEVEL4, //weapon_t startWeapon
|
|
0.0f, //float buildDist;
|
|
90, //int fov;
|
|
0.001f, //float bob;
|
|
1.1f, //float bobCycle;
|
|
100, //int steptime;
|
|
LEVEL4_SPEED, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
100.0f, //float stopSpeed;
|
|
170.0f, //float jumpMagnitude;
|
|
0.1f, //float knockbackScale;
|
|
{ PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
|
|
LEVEL4_COST, //int cost;
|
|
LEVEL4_VALUE //int value;
|
|
},
|
|
{
|
|
PCL_HUMAN, //int classnum;
|
|
"human_base", //char *classname;
|
|
"Human", //char *humanname;
|
|
"sarge", //char *modelname;
|
|
1.0f, //float modelScale;
|
|
"default", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"human_hud", //char *hudname;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
{ -15, -15, -24 }, //vec3_t mins;
|
|
{ 15, 15, 32 }, //vec3_t maxs;
|
|
{ 15, 15, 16 }, //vec3_t crouchmaxs;
|
|
{ -15, -15, -4 }, //vec3_t deadmins;
|
|
{ 15, 15, 4 }, //vec3_t deadmaxs;
|
|
0.0f, //float zOffset
|
|
26, 12, //int viewheight, crouchviewheight;
|
|
100, //int health;
|
|
1.0f, //float fallDamage;
|
|
0, //int regenRate;
|
|
SCA_TAKESFALLDAMAGE|
|
|
SCA_CANUSELADDERS, //int abilities;
|
|
WP_NONE, //special-cased in g_client.c //weapon_t startWeapon
|
|
110.0f, //float buildDist;
|
|
90, //int fov;
|
|
0.002f, //float bob;
|
|
1.0f, //float bobCycle;
|
|
100, //int steptime;
|
|
1.0f, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
100.0f, //float stopSpeed;
|
|
220.0f, //float jumpMagnitude;
|
|
1.0f, //float knockbackScale;
|
|
{ PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
|
|
0, //int cost;
|
|
0 //int value;
|
|
},
|
|
{
|
|
PCL_HUMAN_BSUIT, //int classnum;
|
|
"human_bsuit", //char *classname;
|
|
"bsuit", //char *humanname;
|
|
"keel", //char *modelname;
|
|
1.0f, //float modelScale;
|
|
"default", //char *skinname;
|
|
1.0f, //float shadowScale;
|
|
"human_hud", //char *hudname;
|
|
( 1 << S3 ), //int stages
|
|
{ -15, -15, -38 }, //vec3_t mins;
|
|
{ 15, 15, 38 }, //vec3_t maxs;
|
|
{ 15, 15, 38 }, //vec3_t crouchmaxs;
|
|
{ -15, -15, -4 }, //vec3_t deadmins;
|
|
{ 15, 15, 4 }, //vec3_t deadmaxs;
|
|
-16.0f, //float zOffset
|
|
35, 35, //int viewheight, crouchviewheight;
|
|
100, //int health;
|
|
1.0f, //float fallDamage;
|
|
0, //int regenRate;
|
|
SCA_TAKESFALLDAMAGE|
|
|
SCA_CANUSELADDERS, //int abilities;
|
|
WP_NONE, //special-cased in g_client.c //weapon_t startWeapon
|
|
110.0f, //float buildDist;
|
|
90, //int fov;
|
|
0.002f, //float bob;
|
|
1.0f, //float bobCycle;
|
|
100, //int steptime;
|
|
1.0f, //float speed;
|
|
10.0f, //float acceleration;
|
|
1.0f, //float airAcceleration;
|
|
6.0f, //float friction;
|
|
100.0f, //float stopSpeed;
|
|
270.0f, //float jumpMagnitude;
|
|
1.0f, //float knockbackScale;
|
|
{ PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
|
|
0, //int cost;
|
|
0 //int value;
|
|
},
|
|
};
|
|
|
|
int bg_numPclasses = sizeof( bg_classList ) / sizeof( bg_classList[ 0 ] );
|
|
|
|
//separate from bg_classList to work around char struct init bug
|
|
classAttributeOverrides_t bg_classOverrideList[ PCL_NUM_CLASSES ];
|
|
|
|
/*
|
|
==============
|
|
BG_FindClassNumForName
|
|
==============
|
|
*/
|
|
int BG_FindClassNumForName( char *name )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( !Q_stricmp( bg_classList[ i ].className, name ) )
|
|
return bg_classList[ i ].classNum;
|
|
}
|
|
|
|
//wimp out
|
|
return PCL_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindNameForClassNum
|
|
==============
|
|
*/
|
|
char *BG_FindNameForClassNum( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
return bg_classList[ i ].className;
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindNameForClassNum\n" );
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindHumanNameForClassNum
|
|
==============
|
|
*/
|
|
char *BG_FindHumanNameForClassNum( int pclass )
|
|
{
|
|
int i;
|
|
|
|
if( bg_classOverrideList[ pclass ].humanName[ 0 ] != 0 )
|
|
return bg_classOverrideList[ pclass ].humanName;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
return bg_classList[ i ].humanName;
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHumanNameForClassNum\n" );
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindModelNameForClass
|
|
==============
|
|
*/
|
|
char *BG_FindModelNameForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
if( bg_classOverrideList[ pclass ].modelName[ 0 ] != 0 )
|
|
return bg_classOverrideList[ pclass ].modelName;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
return bg_classList[ i ].modelName;
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelNameForClass\n" );
|
|
//note: must return a valid modelName!
|
|
return bg_classList[ 0 ].modelName;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindModelScaleForClass
|
|
==============
|
|
*/
|
|
float BG_FindModelScaleForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
if( bg_classOverrideList[ pclass ].modelScale != 0.0f )
|
|
return bg_classOverrideList[ pclass ].modelScale;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].modelScale;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelScaleForClass( %d )\n", pclass );
|
|
return 1.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindSkinNameForClass
|
|
==============
|
|
*/
|
|
char *BG_FindSkinNameForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
if( bg_classOverrideList[ pclass ].skinName[ 0 ] != 0 )
|
|
return bg_classOverrideList[ pclass ].skinName;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
return bg_classList[ i ].skinName;
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSkinNameForClass\n" );
|
|
//note: must return a valid modelName!
|
|
return bg_classList[ 0 ].skinName;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindShadowScaleForClass
|
|
==============
|
|
*/
|
|
float BG_FindShadowScaleForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
if( bg_classOverrideList[ pclass ].shadowScale != 0.0f )
|
|
return bg_classOverrideList[ pclass ].shadowScale;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].shadowScale;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindShadowScaleForClass( %d )\n", pclass );
|
|
return 1.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindHudNameForClass
|
|
==============
|
|
*/
|
|
char *BG_FindHudNameForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
if( bg_classOverrideList[ pclass ].hudName[ 0 ] != 0 )
|
|
return bg_classOverrideList[ pclass ].hudName;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
return bg_classList[ i ].hudName;
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHudNameForClass\n" );
|
|
//note: must return a valid hudName!
|
|
return bg_classList[ 0 ].hudName;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindStagesForClass
|
|
==============
|
|
*/
|
|
qboolean BG_FindStagesForClass( int pclass, stage_t stage )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
if( bg_classList[ i ].stages & ( 1 << stage ) )
|
|
return qtrue;
|
|
else
|
|
return qfalse;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStagesForClass\n" );
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBBoxForClass
|
|
==============
|
|
*/
|
|
void BG_FindBBoxForClass( int pclass, vec3_t mins, vec3_t maxs, vec3_t cmaxs, vec3_t dmins, vec3_t dmaxs )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
if( mins != NULL )
|
|
{
|
|
VectorCopy( bg_classList[ i ].mins, mins );
|
|
|
|
if( VectorLength( bg_classOverrideList[ pclass ].mins ) )
|
|
VectorCopy( bg_classOverrideList[ pclass ].mins, mins );
|
|
}
|
|
|
|
if( maxs != NULL )
|
|
{
|
|
VectorCopy( bg_classList[ i ].maxs, maxs );
|
|
|
|
if( VectorLength( bg_classOverrideList[ pclass ].maxs ) )
|
|
VectorCopy( bg_classOverrideList[ pclass ].maxs, maxs );
|
|
}
|
|
|
|
if( cmaxs != NULL )
|
|
{
|
|
VectorCopy( bg_classList[ i ].crouchMaxs, cmaxs );
|
|
|
|
if( VectorLength( bg_classOverrideList[ pclass ].crouchMaxs ) )
|
|
VectorCopy( bg_classOverrideList[ pclass ].crouchMaxs, cmaxs );
|
|
}
|
|
|
|
if( dmins != NULL )
|
|
{
|
|
VectorCopy( bg_classList[ i ].deadMins, dmins );
|
|
|
|
if( VectorLength( bg_classOverrideList[ pclass ].deadMins ) )
|
|
VectorCopy( bg_classOverrideList[ pclass ].deadMins, dmins );
|
|
}
|
|
|
|
if( dmaxs != NULL )
|
|
{
|
|
VectorCopy( bg_classList[ i ].deadMaxs, dmaxs );
|
|
|
|
if( VectorLength( bg_classOverrideList[ pclass ].deadMaxs ) )
|
|
VectorCopy( bg_classOverrideList[ pclass ].deadMaxs, dmaxs );
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( mins != NULL )
|
|
VectorCopy( bg_classList[ 0 ].mins, mins );
|
|
|
|
if( maxs != NULL )
|
|
VectorCopy( bg_classList[ 0 ].maxs, maxs );
|
|
|
|
if( cmaxs != NULL )
|
|
VectorCopy( bg_classList[ 0 ].crouchMaxs, cmaxs );
|
|
|
|
if( dmins != NULL )
|
|
VectorCopy( bg_classList[ 0 ].deadMins, dmins );
|
|
|
|
if( dmaxs != NULL )
|
|
VectorCopy( bg_classList[ 0 ].deadMaxs, dmaxs );
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindZOffsetForClass
|
|
==============
|
|
*/
|
|
float BG_FindZOffsetForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
if( bg_classOverrideList[ pclass ].zOffset != 0.0f )
|
|
return bg_classOverrideList[ pclass ].zOffset;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].zOffset;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindZOffsetForClass\n" );
|
|
return 0.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindViewheightForClass
|
|
==============
|
|
*/
|
|
void BG_FindViewheightForClass( int pclass, int *viewheight, int *cViewheight )
|
|
{
|
|
int i;
|
|
int vh = 0;
|
|
int cvh = 0;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
vh = bg_classList[ i ].viewheight;
|
|
cvh = bg_classList[ i ].crouchViewheight;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( bg_classOverrideList[ pclass ].viewheight != 0 )
|
|
vh = bg_classOverrideList[ pclass ].viewheight;
|
|
if( bg_classOverrideList[ pclass ].crouchViewheight != 0 )
|
|
cvh = bg_classOverrideList[ pclass ].crouchViewheight;
|
|
|
|
|
|
if( vh == 0 )
|
|
vh = bg_classList[ 0 ].viewheight;
|
|
if( cvh == 0 )
|
|
cvh = bg_classList[ 0 ].crouchViewheight;
|
|
|
|
if( viewheight != NULL )
|
|
*viewheight = vh;
|
|
if( cViewheight != NULL )
|
|
*cViewheight = cvh;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindHealthForClass
|
|
==============
|
|
*/
|
|
int BG_FindHealthForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].health;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHealthForClass\n" );
|
|
return 100;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindFallDamageForClass
|
|
==============
|
|
*/
|
|
float BG_FindFallDamageForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].fallDamage;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFallDamageForClass\n" );
|
|
return 100;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindRegenRateForClass
|
|
==============
|
|
*/
|
|
int BG_FindRegenRateForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].regenRate;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindRegenRateForClass\n" );
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindFovForClass
|
|
==============
|
|
*/
|
|
int BG_FindFovForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].fov;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFovForClass\n" );
|
|
return 90;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBobForClass
|
|
==============
|
|
*/
|
|
float BG_FindBobForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].bob;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBobForClass\n" );
|
|
return 0.002;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBobCycleForClass
|
|
==============
|
|
*/
|
|
float BG_FindBobCycleForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].bobCycle;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBobCycleForClass\n" );
|
|
return 1.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindSpeedForClass
|
|
==============
|
|
*/
|
|
float BG_FindSpeedForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].speed;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSpeedForClass\n" );
|
|
return 1.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindAccelerationForClass
|
|
==============
|
|
*/
|
|
float BG_FindAccelerationForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].acceleration;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindAccelerationForClass\n" );
|
|
return 10.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindAirAccelerationForClass
|
|
==============
|
|
*/
|
|
float BG_FindAirAccelerationForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].airAcceleration;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindAirAccelerationForClass\n" );
|
|
return 1.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindFrictionForClass
|
|
==============
|
|
*/
|
|
float BG_FindFrictionForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].friction;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFrictionForClass\n" );
|
|
return 6.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindStopSpeedForClass
|
|
==============
|
|
*/
|
|
float BG_FindStopSpeedForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].stopSpeed;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStopSpeedForClass\n" );
|
|
return 100.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindJumpMagnitudeForClass
|
|
==============
|
|
*/
|
|
float BG_FindJumpMagnitudeForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].jumpMagnitude;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindJumpMagnitudeForClass\n" );
|
|
return 270.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindKnockbackScaleForClass
|
|
==============
|
|
*/
|
|
float BG_FindKnockbackScaleForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].knockbackScale;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindKnockbackScaleForClass\n" );
|
|
return 1.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindSteptimeForClass
|
|
==============
|
|
*/
|
|
int BG_FindSteptimeForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].steptime;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSteptimeForClass\n" );
|
|
return 200;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_ClassHasAbility
|
|
==============
|
|
*/
|
|
qboolean BG_ClassHasAbility( int pclass, int ability )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return ( bg_classList[ i ].abilities & ability );
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindStartWeaponForClass
|
|
==============
|
|
*/
|
|
weapon_t BG_FindStartWeaponForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].startWeapon;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStartWeaponForClass\n" );
|
|
return WP_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBuildDistForClass
|
|
==============
|
|
*/
|
|
float BG_FindBuildDistForClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].buildDist;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBuildDistForClass\n" );
|
|
return 0.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_ClassCanEvolveFromTo
|
|
==============
|
|
*/
|
|
int BG_ClassCanEvolveFromTo( int fclass, int tclass, int credits, int num )
|
|
{
|
|
int i, j, cost;
|
|
|
|
cost = BG_FindCostOfClass( tclass );
|
|
|
|
//base case
|
|
if( credits < cost )
|
|
return -1;
|
|
|
|
if( fclass == PCL_NONE || tclass == PCL_NONE )
|
|
return -1;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == fclass )
|
|
{
|
|
for( j = 0; j < 3; j++ )
|
|
if( bg_classList[ i ].children[ j ] == tclass )
|
|
return num + cost;
|
|
|
|
for( j = 0; j < 3; j++ )
|
|
{
|
|
int sub;
|
|
|
|
cost = BG_FindCostOfClass( bg_classList[ i ].children[ j ] );
|
|
sub = BG_ClassCanEvolveFromTo( bg_classList[ i ].children[ j ],
|
|
tclass, credits - cost, num + cost );
|
|
if( sub >= 0 )
|
|
return sub;
|
|
}
|
|
|
|
return -1; //may as well return by this point
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindValueOfClass
|
|
==============
|
|
*/
|
|
int BG_FindValueOfClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].value;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindValueOfClass\n" );
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindCostOfClass
|
|
==============
|
|
*/
|
|
int BG_FindCostOfClass( int pclass )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == pclass )
|
|
{
|
|
return bg_classList[ i ].cost;
|
|
}
|
|
}
|
|
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindCostOfClass\n" );
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindOverrideForClass
|
|
==============
|
|
*/
|
|
static classAttributeOverrides_t *BG_FindOverrideForClass( int pclass )
|
|
{
|
|
return &bg_classOverrideList[ pclass ];
|
|
}
|
|
|
|
/*
|
|
======================
|
|
BG_ParseClassFile
|
|
|
|
Parses a configuration file describing a class
|
|
======================
|
|
*/
|
|
static qboolean BG_ParseClassFile( const char *filename, classAttributeOverrides_t *cao )
|
|
{
|
|
char *text_p;
|
|
int i;
|
|
int len;
|
|
char *token;
|
|
char text[ 20000 ];
|
|
fileHandle_t f;
|
|
float scale = 0.0f;
|
|
|
|
|
|
// load the file
|
|
len = trap_FS_FOpenFile( filename, &f, FS_READ );
|
|
if( len <= 0 )
|
|
return qfalse;
|
|
|
|
if( len >= sizeof( text ) - 1 )
|
|
{
|
|
Com_Printf( S_COLOR_RED "ERROR: Class file %s too long\n", filename );
|
|
return qfalse;
|
|
}
|
|
|
|
trap_FS_Read( text, len, f );
|
|
text[ len ] = 0;
|
|
trap_FS_FCloseFile( f );
|
|
|
|
// parse the text
|
|
text_p = text;
|
|
|
|
// read optional parameters
|
|
while( 1 )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
|
|
if( !token )
|
|
break;
|
|
|
|
if( !Q_stricmp( token, "" ) )
|
|
break;
|
|
|
|
if( !Q_stricmp( token, "model" ) )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
Q_strncpyz( cao->modelName, token, sizeof( cao->modelName ) );
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "skin" ) )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
Q_strncpyz( cao->skinName, token, sizeof( cao->skinName ) );
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "hud" ) )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
Q_strncpyz( cao->hudName, token, sizeof( cao->hudName ) );
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "modelScale" ) )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
scale = atof( token );
|
|
|
|
if( scale < 0.0f )
|
|
scale = 0.0f;
|
|
|
|
cao->modelScale = scale;
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "shadowScale" ) )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
scale = atof( token );
|
|
|
|
if( scale < 0.0f )
|
|
scale = 0.0f;
|
|
|
|
cao->shadowScale = scale;
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "mins" ) )
|
|
{
|
|
for( i = 0; i <= 2; i++ )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
cao->mins[ i ] = atof( token );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "maxs" ) )
|
|
{
|
|
for( i = 0; i <= 2; i++ )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
cao->maxs[ i ] = atof( token );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "deadMins" ) )
|
|
{
|
|
for( i = 0; i <= 2; i++ )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
cao->deadMins[ i ] = atof( token );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "deadMaxs" ) )
|
|
{
|
|
for( i = 0; i <= 2; i++ )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
cao->deadMaxs[ i ] = atof( token );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "crouchMaxs" ) )
|
|
{
|
|
for( i = 0; i <= 2; i++ )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
cao->crouchMaxs[ i ] = atof( token );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "viewheight" ) )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
cao->viewheight = atoi( token );
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "crouchViewheight" ) )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
cao->crouchViewheight = atoi( token );
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "zOffset" ) )
|
|
{
|
|
float offset;
|
|
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
offset = atof( token );
|
|
|
|
cao->zOffset = offset;
|
|
|
|
continue;
|
|
}
|
|
else if( !Q_stricmp( token, "name" ) )
|
|
{
|
|
token = COM_Parse( &text_p );
|
|
if( !token )
|
|
break;
|
|
|
|
Q_strncpyz( cao->humanName, token, sizeof( cao->humanName ) );
|
|
|
|
continue;
|
|
}
|
|
|
|
|
|
Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token );
|
|
return qfalse;
|
|
}
|
|
|
|
return qtrue;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
BG_InitClassOverrides
|
|
|
|
Set any overrides specfied by file
|
|
===============
|
|
*/
|
|
void BG_InitClassOverrides( void )
|
|
{
|
|
int i;
|
|
classAttributeOverrides_t *cao;
|
|
|
|
for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
|
|
{
|
|
cao = BG_FindOverrideForClass( i );
|
|
|
|
BG_ParseClassFile( va( "overrides/classes/%s.cfg", BG_FindNameForClassNum( i ) ), cao );
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
weaponAttributes_t bg_weapons[ ] =
|
|
{
|
|
{
|
|
WP_BLASTER, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
0, //int slots;
|
|
"blaster", //char *weaponName;
|
|
"Blaster", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
BLASTER_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
BLASTER_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_MACHINEGUN, //int weaponNum;
|
|
RIFLE_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"rifle", //char *weaponName;
|
|
"Rifle", //char *weaponHumanName;
|
|
RIFLE_CLIPSIZE, //int maxAmmo;
|
|
RIFLE_MAXCLIPS, //int maxClips;
|
|
qfalse, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
RIFLE_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
RIFLE_RELOAD, //int reloadTime;
|
|
RIFLE_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_SHOTGUN, //int weaponNum;
|
|
SHOTGUN_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"shotgun", //char *weaponName;
|
|
"Shotgun", //char *weaponHumanName;
|
|
SHOTGUN_SHELLS, //int maxAmmo;
|
|
SHOTGUN_MAXCLIPS, //int maxClips;
|
|
qfalse, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
SHOTGUN_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
SHOTGUN_RELOAD, //int reloadTime;
|
|
SHOTGUN_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_FLAMER, //int weaponNum;
|
|
FLAMER_PRICE, //int price;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"flamer", //char *weaponName;
|
|
"Flame Thrower", //char *weaponHumanName;
|
|
FLAMER_GAS, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qfalse, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
FLAMER_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
FLAMER_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_CHAINGUN, //int weaponNum;
|
|
CHAINGUN_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"chaingun", //char *weaponName;
|
|
"Chaingun", //char *weaponHumanName;
|
|
CHAINGUN_BULLETS, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qfalse, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
CHAINGUN_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
CHAINGUN_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_MASS_DRIVER, //int weaponNum;
|
|
MDRIVER_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"mdriver", //char *weaponName;
|
|
"Mass Driver", //char *weaponHumanName;
|
|
MDRIVER_CLIPSIZE, //int maxAmmo;
|
|
MDRIVER_MAXCLIPS, //int maxClips;
|
|
qfalse, //int infiniteAmmo;
|
|
qtrue, //int usesEnergy;
|
|
MDRIVER_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
MDRIVER_RELOAD, //int reloadTime;
|
|
MDRIVER_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qtrue, //qboolean canZoom;
|
|
20.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_PULSE_RIFLE, //int weaponNum;
|
|
PRIFLE_PRICE, //int price;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"prifle", //char *weaponName;
|
|
"Pulse Rifle", //char *weaponHumanName;
|
|
PRIFLE_CLIPS, //int maxAmmo;
|
|
PRIFLE_MAXCLIPS, //int maxClips;
|
|
qfalse, //int infiniteAmmo;
|
|
qtrue, //int usesEnergy;
|
|
PRIFLE_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
PRIFLE_RELOAD, //int reloadTime;
|
|
PRIFLE_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_LUCIFER_CANNON, //int weaponNum;
|
|
LCANNON_PRICE, //int price;
|
|
( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"lcannon", //char *weaponName;
|
|
"Lucifer Cannon", //char *weaponHumanName;
|
|
LCANNON_AMMO, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qfalse, //int infiniteAmmo;
|
|
qtrue, //int usesEnergy;
|
|
LCANNON_REPEAT, //int repeatRate1;
|
|
LCANNON_CHARGEREPEAT, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
LCANNON_RELOAD, //int reloadTime;
|
|
LCANNON_K_SCALE, //float knockbackScale;
|
|
qtrue, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_LAS_GUN, //int weaponNum;
|
|
LASGUN_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"lgun", //char *weaponName;
|
|
"Las Gun", //char *weaponHumanName;
|
|
LASGUN_AMMO, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qfalse, //int infiniteAmmo;
|
|
qtrue, //int usesEnergy;
|
|
LASGUN_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
LASGUN_RELOAD, //int reloadTime;
|
|
LASGUN_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_PAIN_SAW, //int weaponNum;
|
|
PAINSAW_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"psaw", //char *weaponName;
|
|
"Pain Saw", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
PAINSAW_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
PAINSAW_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_GRENADE, //int weaponNum;
|
|
GRENADE_PRICE, //int price;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_NONE, //int slots;
|
|
"grenade", //char *weaponName;
|
|
"Grenade", //char *weaponHumanName;
|
|
1, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qfalse, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
GRENADE_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
GRENADE_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_HBUILD, //int weaponNum;
|
|
HBUILD_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"ckit", //char *weaponName;
|
|
"Construction Kit", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
HBUILD_REPEAT, //int repeatRate1;
|
|
HBUILD_REPEAT, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
0.0f, //float knockbackScale;
|
|
qtrue, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
HBUILD_DELAY, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_HBUILD2, //int weaponNum;
|
|
HBUILD2_PRICE, //int price;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"ackit", //char *weaponName;
|
|
"Adv Construction Kit",//char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
HBUILD2_REPEAT, //int repeatRate1;
|
|
HBUILD2_REPEAT, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
0.0f, //float knockbackScale;
|
|
qtrue, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
HBUILD2_DELAY, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ABUILD, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"abuild", //char *weaponName;
|
|
"Alien build weapon", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
ABUILDER_BUILD_REPEAT,//int repeatRate1;
|
|
ABUILDER_BUILD_REPEAT,//int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
0.0f, //float knockbackScale;
|
|
qtrue, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
ABUILDER_BASE_DELAY, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ABUILD2, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"abuildupg", //char *weaponName;
|
|
"Alien build weapon2",//char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
ABUILDER_BUILD_REPEAT,//int repeatRate1;
|
|
ABUILDER_CLAW_REPEAT, //int repeatRate2;
|
|
ABUILDER_BLOB_REPEAT, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
ABUILDER_CLAW_K_SCALE,//float knockbackScale;
|
|
qtrue, //qboolean hasAltMode;
|
|
qtrue, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qtrue, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
ABUILDER_ADV_DELAY, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ALEVEL0, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"level0", //char *weaponName;
|
|
"Bite", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
LEVEL0_BITE_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
LEVEL0_BITE_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ALEVEL1, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"level1", //char *weaponName;
|
|
"Claws", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
LEVEL1_CLAW_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
LEVEL1_CLAW_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ALEVEL1_UPG, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"level1upg", //char *weaponName;
|
|
"Claws Upgrade", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
LEVEL1_CLAW_U_REPEAT, //int repeatRate1;
|
|
LEVEL1_PCLOUD_REPEAT, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
LEVEL1_CLAW_U_K_SCALE,//float knockbackScale;
|
|
qtrue, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ALEVEL2, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"level2", //char *weaponName;
|
|
"Bite", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
LEVEL2_CLAW_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
LEVEL2_CLAW_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ALEVEL2_UPG, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"level2upg", //char *weaponName;
|
|
"Zap", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
LEVEL2_CLAW_U_REPEAT, //int repeatRate1;
|
|
LEVEL2_AREAZAP_REPEAT,//int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
LEVEL2_CLAW_U_K_SCALE,//float knockbackScale;
|
|
qtrue, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ALEVEL3, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"level3", //char *weaponName;
|
|
"Pounce", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
LEVEL3_CLAW_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
LEVEL3_CLAW_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ALEVEL3_UPG, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"level3upg", //char *weaponName;
|
|
"Pounce (upgrade)", //char *weaponHumanName;
|
|
3, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
LEVEL3_CLAW_U_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
LEVEL3_BOUNCEBALL_REPEAT,//int repeatRate3;
|
|
0, //int reloadTime;
|
|
LEVEL3_CLAW_U_K_SCALE,//float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qtrue, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qtrue, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_ALEVEL4, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"level4", //char *weaponName;
|
|
"Charge", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
LEVEL4_CLAW_REPEAT, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
LEVEL4_CLAW_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_LOCKBLOB_LAUNCHER, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"lockblob", //char *weaponName;
|
|
"Lock Blob", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
500, //int repeatRate1;
|
|
500, //int repeatRate2;
|
|
500, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
LOCKBLOB_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_HIVE, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"hive", //char *weaponName;
|
|
"Hive", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
500, //int repeatRate1;
|
|
500, //int repeatRate2;
|
|
500, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
HIVE_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_ALIENS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_MGTURRET, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"mgturret", //char *weaponName;
|
|
"Machinegun Turret", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qfalse, //int usesEnergy;
|
|
0, //int repeatRate1;
|
|
0, //int repeatRate2;
|
|
0, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
MGTURRET_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
WP_TESLAGEN, //int weaponNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_WEAPON, //int slots;
|
|
"teslagen", //char *weaponName;
|
|
"Tesla Generator", //char *weaponHumanName;
|
|
0, //int maxAmmo;
|
|
0, //int maxClips;
|
|
qtrue, //int infiniteAmmo;
|
|
qtrue, //int usesEnergy;
|
|
500, //int repeatRate1;
|
|
500, //int repeatRate2;
|
|
500, //int repeatRate3;
|
|
0, //int reloadTime;
|
|
TESLAGEN_K_SCALE, //float knockbackScale;
|
|
qfalse, //qboolean hasAltMode;
|
|
qfalse, //qboolean hasThirdMode;
|
|
qfalse, //qboolean canZoom;
|
|
90.0f, //float zoomFov;
|
|
qfalse, //qboolean purchasable;
|
|
qfalse, //qboolean longRanged;
|
|
0, //int buildDelay;
|
|
WUT_HUMANS //WUTeam_t team;
|
|
}
|
|
};
|
|
|
|
int bg_numWeapons = sizeof( bg_weapons ) / sizeof( bg_weapons[ 0 ] );
|
|
|
|
/*
|
|
==============
|
|
BG_UpdateWeaponData
|
|
==============
|
|
*/
|
|
void BG_UpdateWeaponData(int proximityMine, int price) {
|
|
int i;
|
|
|
|
for(i=0; i<bg_numWeapons; i++) {
|
|
if(bg_weapons[i].weaponNum == WP_GRENADE) {
|
|
if(proximityMine) {
|
|
bg_weapons[i].price = price;
|
|
} else {
|
|
bg_weapons[i].price = GRENADE_PRICE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindPriceForWeapon
|
|
==============
|
|
*/
|
|
int BG_FindPriceForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].price;
|
|
}
|
|
}
|
|
|
|
return 100;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindStagesForWeapon
|
|
==============
|
|
*/
|
|
qboolean BG_FindStagesForWeapon( int weapon, stage_t stage )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
if( bg_weapons[ i ].stages & ( 1 << stage ) )
|
|
return qtrue;
|
|
else
|
|
return qfalse;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindSlotsForWeapon
|
|
==============
|
|
*/
|
|
int BG_FindSlotsForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].slots;
|
|
}
|
|
}
|
|
|
|
return SLOT_WEAPON;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindNameForWeapon
|
|
==============
|
|
*/
|
|
char *BG_FindNameForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
return bg_weapons[ i ].weaponName;
|
|
}
|
|
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindWeaponNumForName
|
|
==============
|
|
*/
|
|
int BG_FindWeaponNumForName( char *name )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( !Q_stricmp( bg_weapons[ i ].weaponName, name ) )
|
|
return bg_weapons[ i ].weaponNum;
|
|
}
|
|
|
|
//wimp out
|
|
return WP_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindHumanNameForWeapon
|
|
==============
|
|
*/
|
|
char *BG_FindHumanNameForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
return bg_weapons[ i ].weaponHumanName;
|
|
}
|
|
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindAmmoForWeapon
|
|
==============
|
|
*/
|
|
void BG_FindAmmoForWeapon( int weapon, int *maxAmmo, int *maxClips )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
if( maxAmmo != NULL )
|
|
*maxAmmo = bg_weapons[ i ].maxAmmo;
|
|
if( maxClips != NULL )
|
|
*maxClips = bg_weapons[ i ].maxClips;
|
|
|
|
//no need to keep going
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindInfinteAmmoForWeapon
|
|
==============
|
|
*/
|
|
qboolean BG_FindInfinteAmmoForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].infiniteAmmo;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindUsesEnergyForWeapon
|
|
==============
|
|
*/
|
|
qboolean BG_FindUsesEnergyForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].usesEnergy;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindRepeatRate1ForWeapon
|
|
==============
|
|
*/
|
|
int BG_FindRepeatRate1ForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
return bg_weapons[ i ].repeatRate1;
|
|
}
|
|
|
|
return 1000;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindRepeatRate2ForWeapon
|
|
==============
|
|
*/
|
|
int BG_FindRepeatRate2ForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
return bg_weapons[ i ].repeatRate2;
|
|
}
|
|
|
|
return 1000;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindRepeatRate3ForWeapon
|
|
==============
|
|
*/
|
|
int BG_FindRepeatRate3ForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
return bg_weapons[ i ].repeatRate3;
|
|
}
|
|
|
|
return 1000;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindReloadTimeForWeapon
|
|
==============
|
|
*/
|
|
int BG_FindReloadTimeForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].reloadTime;
|
|
}
|
|
}
|
|
|
|
return 1000;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindKnockbackScaleForWeapon
|
|
==============
|
|
*/
|
|
float BG_FindKnockbackScaleForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].knockbackScale;
|
|
}
|
|
}
|
|
|
|
return 1.0f;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_WeaponHasAltMode
|
|
==============
|
|
*/
|
|
qboolean BG_WeaponHasAltMode( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].hasAltMode;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_WeaponHasThirdMode
|
|
==============
|
|
*/
|
|
qboolean BG_WeaponHasThirdMode( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].hasThirdMode;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_WeaponCanZoom
|
|
==============
|
|
*/
|
|
qboolean BG_WeaponCanZoom( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].canZoom;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindZoomFovForWeapon
|
|
==============
|
|
*/
|
|
float BG_FindZoomFovForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].zoomFov;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindPurchasableForWeapon
|
|
==============
|
|
*/
|
|
qboolean BG_FindPurchasableForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].purchasable;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindLongRangeForWeapon
|
|
==============
|
|
*/
|
|
qboolean BG_FindLongRangedForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].longRanged;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindBuildDelayForWeapon
|
|
==============
|
|
*/
|
|
int BG_FindBuildDelayForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].buildDelay;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindTeamForWeapon
|
|
==============
|
|
*/
|
|
WUTeam_t BG_FindTeamForWeapon( int weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( bg_weapons[ i ].weaponNum == weapon )
|
|
{
|
|
return bg_weapons[ i ].team;
|
|
}
|
|
}
|
|
|
|
return WUT_NONE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
upgradeAttributes_t bg_upgrades[ ] =
|
|
{
|
|
{
|
|
UP_LIGHTARMOUR, //int upgradeNum;
|
|
LIGHTARMOUR_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_TORSO|SLOT_ARMS|SLOT_LEGS, //int slots;
|
|
"larmour", //char *upgradeName;
|
|
"Light Armour", //char *upgradeHumanName;
|
|
"icons/iconu_larmour",
|
|
qtrue, //qboolean purchasable
|
|
qfalse, //qboolean usable
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
UP_HELMET, //int upgradeNum;
|
|
HELMET_PRICE, //int price;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_HEAD, //int slots;
|
|
"helmet", //char *upgradeName;
|
|
"Helmet", //char *upgradeHumanName;
|
|
"icons/iconu_helmet",
|
|
qtrue, //qboolean purchasable
|
|
qfalse, //qboolean usable
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
UP_MEDKIT, //int upgradeNum;
|
|
MEDKIT_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_NONE, //int slots;
|
|
"medkit", //char *upgradeName;
|
|
"Medkit", //char *upgradeHumanName;
|
|
"icons/iconu_atoxin",
|
|
qfalse, //qboolean purchasable
|
|
qtrue, //qboolean usable
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
UP_BATTPACK, //int upgradeNum;
|
|
BATTPACK_PRICE, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_BACKPACK, //int slots;
|
|
"battpack", //char *upgradeName;
|
|
"Battery Pack", //char *upgradeHumanName;
|
|
"icons/iconu_battpack",
|
|
qtrue, //qboolean purchasable
|
|
qfalse, //qboolean usable
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
UP_JETPACK, //int upgradeNum;
|
|
JETPACK_PRICE, //int price;
|
|
( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_BACKPACK, //int slots;
|
|
"jetpack", //char *upgradeName;
|
|
"Jet Pack", //char *upgradeHumanName;
|
|
"icons/iconu_jetpack",
|
|
qtrue, //qboolean purchasable
|
|
qtrue, //qboolean usable
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
UP_BATTLESUIT, //int upgradeNum;
|
|
BSUIT_PRICE, //int price;
|
|
( 1 << S3 ), //int stages
|
|
SLOT_HEAD|SLOT_TORSO|SLOT_ARMS|SLOT_LEGS|SLOT_BACKPACK, //int slots;
|
|
"bsuit", //char *upgradeName;
|
|
"Battlesuit", //char *upgradeHumanName;
|
|
"icons/iconu_bsuit",
|
|
qtrue, //qboolean purchasable
|
|
qfalse, //qboolean usable
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
UP_GRENADE, //int upgradeNum;
|
|
GRENADE_PRICE, //int price;
|
|
( 1 << S2 )|( 1 << S3 ),//int stages
|
|
SLOT_NONE, //int slots;
|
|
"gren", //char *upgradeName;
|
|
"Grenade", //char *upgradeHumanName;
|
|
0,
|
|
qtrue, //qboolean purchasable
|
|
qtrue, //qboolean usable
|
|
WUT_HUMANS //WUTeam_t team;
|
|
},
|
|
{
|
|
UP_AMMO, //int upgradeNum;
|
|
0, //int price;
|
|
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
|
|
SLOT_NONE, //int slots;
|
|
"ammo", //char *upgradeName;
|
|
"Ammunition", //char *upgradeHumanName;
|
|
0,
|
|
qtrue, //qboolean purchasable
|
|
qfalse, //qboolean usable
|
|
WUT_HUMANS //WUTeam_t team;
|
|
}
|
|
};
|
|
|
|
int bg_numUpgrades = sizeof( bg_upgrades ) / sizeof( bg_upgrades[ 0 ] );
|
|
|
|
/*
|
|
==============
|
|
BG_UpdateUpgradeData
|
|
==============
|
|
*/
|
|
void BG_UpdateUpgradeData(int proximityMine, int price) {
|
|
int i;
|
|
|
|
for(i=0; i<bg_numUpgrades; i++) {
|
|
if(bg_upgrades[i].upgradeNum == UP_GRENADE) {
|
|
if(proximityMine) {
|
|
bg_upgrades[i].price = price;
|
|
} else {
|
|
bg_upgrades[i].price = GRENADE_PRICE;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindPriceForUpgrade
|
|
==============
|
|
*/
|
|
int BG_FindPriceForUpgrade( int upgrade )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( bg_upgrades[ i ].upgradeNum == upgrade )
|
|
{
|
|
return bg_upgrades[ i ].price;
|
|
}
|
|
}
|
|
|
|
return 100;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindStagesForUpgrade
|
|
==============
|
|
*/
|
|
qboolean BG_FindStagesForUpgrade( int upgrade, stage_t stage )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( bg_upgrades[ i ].upgradeNum == upgrade )
|
|
{
|
|
if( bg_upgrades[ i ].stages & ( 1 << stage ) )
|
|
return qtrue;
|
|
else
|
|
return qfalse;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindSlotsForUpgrade
|
|
==============
|
|
*/
|
|
int BG_FindSlotsForUpgrade( int upgrade )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( bg_upgrades[ i ].upgradeNum == upgrade )
|
|
{
|
|
return bg_upgrades[ i ].slots;
|
|
}
|
|
}
|
|
|
|
return SLOT_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindNameForUpgrade
|
|
==============
|
|
*/
|
|
char *BG_FindNameForUpgrade( int upgrade )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( bg_upgrades[ i ].upgradeNum == upgrade )
|
|
return bg_upgrades[ i ].upgradeName;
|
|
}
|
|
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindUpgradeNumForName
|
|
==============
|
|
*/
|
|
int BG_FindUpgradeNumForName( char *name )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( !Q_stricmp( bg_upgrades[ i ].upgradeName, name ) )
|
|
return bg_upgrades[ i ].upgradeNum;
|
|
}
|
|
|
|
//wimp out
|
|
return UP_NONE;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindHumanNameForUpgrade
|
|
==============
|
|
*/
|
|
char *BG_FindHumanNameForUpgrade( int upgrade )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( bg_upgrades[ i ].upgradeNum == upgrade )
|
|
return bg_upgrades[ i ].upgradeHumanName;
|
|
}
|
|
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindIconForUpgrade
|
|
==============
|
|
*/
|
|
char *BG_FindIconForUpgrade( int upgrade )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( bg_upgrades[ i ].upgradeNum == upgrade )
|
|
return bg_upgrades[ i ].icon;
|
|
}
|
|
|
|
//wimp out
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindPurchasableForUpgrade
|
|
==============
|
|
*/
|
|
qboolean BG_FindPurchasableForUpgrade( int upgrade )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( bg_upgrades[ i ].upgradeNum == upgrade )
|
|
return bg_upgrades[ i ].purchasable;
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindUsableForUpgrade
|
|
==============
|
|
*/
|
|
qboolean BG_FindUsableForUpgrade( int upgrade )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( bg_upgrades[ i ].upgradeNum == upgrade )
|
|
return bg_upgrades[ i ].usable;
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
BG_FindTeamForUpgrade
|
|
==============
|
|
*/
|
|
WUTeam_t BG_FindTeamForUpgrade( int upgrade )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < bg_numUpgrades; i++ )
|
|
{
|
|
if( bg_upgrades[ i ].upgradeNum == upgrade )
|
|
{
|
|
return bg_upgrades[ i ].team;
|
|
}
|
|
}
|
|
|
|
return WUT_NONE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*
|
|
================
|
|
BG_EvaluateTrajectory
|
|
|
|
================
|
|
*/
|
|
void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result )
|
|
{
|
|
float deltaTime;
|
|
float phase;
|
|
|
|
switch( tr->trType )
|
|
{
|
|
case TR_STATIONARY:
|
|
case TR_INTERPOLATE:
|
|
VectorCopy( tr->trBase, result );
|
|
break;
|
|
|
|
case TR_LINEAR:
|
|
deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
|
|
VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
|
|
break;
|
|
|
|
case TR_SINE:
|
|
deltaTime = ( atTime - tr->trTime ) / (float)tr->trDuration;
|
|
phase = sin( deltaTime * M_PI * 2 );
|
|
VectorMA( tr->trBase, phase, tr->trDelta, result );
|
|
break;
|
|
|
|
case TR_LINEAR_STOP:
|
|
if( atTime > tr->trTime + tr->trDuration )
|
|
atTime = tr->trTime + tr->trDuration;
|
|
|
|
deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
|
|
if( deltaTime < 0 )
|
|
deltaTime = 0;
|
|
|
|
VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
|
|
break;
|
|
|
|
case TR_GRAVITY:
|
|
deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
|
|
VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
|
|
result[ 2 ] -= 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime; // FIXME: local gravity...
|
|
break;
|
|
|
|
case TR_BUOYANCY:
|
|
deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
|
|
VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
|
|
result[ 2 ] += 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime; // FIXME: local gravity...
|
|
break;
|
|
|
|
default:
|
|
Com_Error( ERR_DROP, "BG_EvaluateTrajectory: unknown trType: %i", tr->trTime );
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
BG_EvaluateTrajectoryDelta
|
|
|
|
For determining velocity at a given time
|
|
================
|
|
*/
|
|
void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result )
|
|
{
|
|
float deltaTime;
|
|
float phase;
|
|
|
|
switch( tr->trType )
|
|
{
|
|
case TR_STATIONARY:
|
|
case TR_INTERPOLATE:
|
|
VectorClear( result );
|
|
break;
|
|
|
|
case TR_LINEAR:
|
|
VectorCopy( tr->trDelta, result );
|
|
break;
|
|
|
|
case TR_SINE:
|
|
deltaTime = ( atTime - tr->trTime ) / (float)tr->trDuration;
|
|
phase = cos( deltaTime * M_PI * 2 ); // derivative of sin = cos
|
|
phase *= 0.5;
|
|
VectorScale( tr->trDelta, phase, result );
|
|
break;
|
|
|
|
case TR_LINEAR_STOP:
|
|
if( atTime > tr->trTime + tr->trDuration )
|
|
{
|
|
VectorClear( result );
|
|
return;
|
|
}
|
|
VectorCopy( tr->trDelta, result );
|
|
break;
|
|
|
|
case TR_GRAVITY:
|
|
deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
|
|
VectorCopy( tr->trDelta, result );
|
|
result[ 2 ] -= DEFAULT_GRAVITY * deltaTime; // FIXME: local gravity...
|
|
break;
|
|
|
|
case TR_BUOYANCY:
|
|
deltaTime = ( atTime - tr->trTime ) * 0.001; // milliseconds to seconds
|
|
VectorCopy( tr->trDelta, result );
|
|
result[ 2 ] += DEFAULT_GRAVITY * deltaTime; // FIXME: local gravity...
|
|
break;
|
|
|
|
default:
|
|
Com_Error( ERR_DROP, "BG_EvaluateTrajectoryDelta: unknown trType: %i", tr->trTime );
|
|
break;
|
|
}
|
|
}
|
|
|
|
char *eventnames[ ] =
|
|
{
|
|
"EV_NONE",
|
|
|
|
"EV_FOOTSTEP",
|
|
"EV_FOOTSTEP_METAL",
|
|
"EV_FOOTSTEP_SQUELCH",
|
|
"EV_FOOTSPLASH",
|
|
"EV_FOOTWADE",
|
|
"EV_SWIM",
|
|
|
|
"EV_STEP_4",
|
|
"EV_STEP_8",
|
|
"EV_STEP_12",
|
|
"EV_STEP_16",
|
|
|
|
"EV_STEPDN_4",
|
|
"EV_STEPDN_8",
|
|
"EV_STEPDN_12",
|
|
"EV_STEPDN_16",
|
|
|
|
"EV_FALL_SHORT",
|
|
"EV_FALL_MEDIUM",
|
|
"EV_FALL_FAR",
|
|
"EV_FALLING",
|
|
|
|
"EV_JUMP",
|
|
"EV_WATER_TOUCH", // foot touches
|
|
"EV_WATER_LEAVE", // foot leaves
|
|
"EV_WATER_UNDER", // head touches
|
|
"EV_WATER_CLEAR", // head leaves
|
|
|
|
"EV_NOAMMO",
|
|
"EV_CHANGE_WEAPON",
|
|
"EV_FIRE_WEAPON",
|
|
"EV_FIRE_WEAPON2",
|
|
"EV_FIRE_WEAPON3",
|
|
|
|
"EV_PLAYER_RESPAWN", //TA: for fovwarp effects
|
|
"EV_PLAYER_TELEPORT_IN",
|
|
"EV_PLAYER_TELEPORT_OUT",
|
|
|
|
"EV_GRENADE_BOUNCE", // eventParm will be the soundindex
|
|
|
|
"EV_GENERAL_SOUND",
|
|
"EV_GLOBAL_SOUND", // no attenuation
|
|
|
|
"EV_BULLET_HIT_FLESH",
|
|
"EV_BULLET_HIT_WALL",
|
|
|
|
"EV_SHOTGUN",
|
|
|
|
"EV_MISSILE_HIT",
|
|
"EV_MISSILE_MISS",
|
|
"EV_MISSILE_MISS_METAL",
|
|
"EV_TESLATRAIL",
|
|
"EV_BULLET", // otherEntity is the shooter
|
|
|
|
"EV_LEV1_GRAB",
|
|
"EV_LEV4_CHARGE_PREPARE",
|
|
"EV_LEV4_CHARGE_START",
|
|
|
|
"EV_PAIN",
|
|
"EV_DEATH1",
|
|
"EV_DEATH2",
|
|
"EV_DEATH3",
|
|
"EV_OBITUARY",
|
|
|
|
"EV_GIB_PLAYER", // gib a previously living player
|
|
|
|
"EV_BUILD_CONSTRUCT", //TA
|
|
"EV_BUILD_DESTROY", //TA
|
|
"EV_BUILD_DELAY", //TA: can't build yet
|
|
"EV_BUILD_REPAIR", //TA: repairing buildable
|
|
"EV_BUILD_REPAIRED", //TA: buildable has full health
|
|
"EV_HUMAN_BUILDABLE_EXPLOSION",
|
|
"EV_ALIEN_BUILDABLE_EXPLOSION",
|
|
"EV_ALIEN_ACIDTUBE",
|
|
|
|
"EV_MEDKIT_USED",
|
|
|
|
"EV_ALIEN_EVOLVE",
|
|
"EV_ALIEN_EVOLVE_FAILED",
|
|
|
|
"EV_DEBUG_LINE",
|
|
"EV_STOPLOOPINGSOUND",
|
|
"EV_TAUNT",
|
|
|
|
"EV_OVERMIND_ATTACK", //TA: overmind under attack
|
|
"EV_OVERMIND_DYING", //TA: overmind close to death
|
|
"EV_OVERMIND_SPAWNS", //TA: overmind needs spawns
|
|
|
|
"EV_DCC_ATTACK", //TA: dcc under attack
|
|
|
|
"EV_RPTUSE_SOUND" //TA: trigger a sound
|
|
};
|
|
|
|
/*
|
|
===============
|
|
BG_AddPredictableEventToPlayerstate
|
|
|
|
Handles the sequence numbers
|
|
===============
|
|
*/
|
|
|
|
void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
|
|
|
|
void BG_AddPredictableEventToPlayerstate( int newEvent, int eventParm, playerState_t *ps )
|
|
{
|
|
#ifdef _DEBUG
|
|
{
|
|
char buf[ 256 ];
|
|
trap_Cvar_VariableStringBuffer( "showevents", buf, sizeof( buf ) );
|
|
|
|
if( atof( buf ) != 0 )
|
|
{
|
|
#ifdef QAGAME
|
|
Com_Printf( " game event svt %5d -> %5d: num = %20s parm %d\n",
|
|
ps->pmove_framecount/*ps->commandTime*/, ps->eventSequence, eventnames[ newEvent ], eventParm);
|
|
#else
|
|
Com_Printf( "Cgame event svt %5d -> %5d: num = %20s parm %d\n",
|
|
ps->pmove_framecount/*ps->commandTime*/, ps->eventSequence, eventnames[ newEvent ], eventParm);
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
ps->events[ ps->eventSequence & ( MAX_PS_EVENTS - 1 ) ] = newEvent;
|
|
ps->eventParms[ ps->eventSequence & ( MAX_PS_EVENTS - 1 ) ] = eventParm;
|
|
ps->eventSequence++;
|
|
}
|
|
|
|
|
|
/*
|
|
========================
|
|
BG_PlayerStateToEntityState
|
|
|
|
This is done after each set of usercmd_t on the server,
|
|
and after local prediction on the client
|
|
========================
|
|
*/
|
|
void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap )
|
|
{
|
|
int i;
|
|
|
|
if( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR || ps->pm_type == PM_FREEZE )
|
|
s->eType = ET_INVISIBLE;
|
|
else if( ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
|
|
s->eType = ET_INVISIBLE;
|
|
else
|
|
s->eType = ET_PLAYER;
|
|
|
|
s->number = ps->clientNum;
|
|
|
|
s->pos.trType = TR_INTERPOLATE;
|
|
VectorCopy( ps->origin, s->pos.trBase );
|
|
|
|
if( snap )
|
|
SnapVector( s->pos.trBase );
|
|
|
|
//set the trDelta for flag direction
|
|
VectorCopy( ps->velocity, s->pos.trDelta );
|
|
|
|
s->apos.trType = TR_INTERPOLATE;
|
|
VectorCopy( ps->viewangles, s->apos.trBase );
|
|
|
|
if( snap )
|
|
SnapVector( s->apos.trBase );
|
|
|
|
//TA: i need for other things :)
|
|
//s->angles2[YAW] = ps->movementDir;
|
|
s->time2 = ps->movementDir;
|
|
s->legsAnim = ps->legsAnim;
|
|
s->torsoAnim = ps->torsoAnim;
|
|
s->clientNum = ps->clientNum; // ET_PLAYER looks here instead of at number
|
|
// so corpses can also reference the proper config
|
|
s->eFlags = ps->eFlags;
|
|
if( ps->stats[STAT_HEALTH] <= 0 )
|
|
s->eFlags |= EF_DEAD;
|
|
else
|
|
s->eFlags &= ~EF_DEAD;
|
|
|
|
if( ps->stats[ STAT_STATE ] & SS_BLOBLOCKED )
|
|
s->eFlags |= EF_BLOBLOCKED;
|
|
else
|
|
s->eFlags &= ~EF_BLOBLOCKED;
|
|
|
|
if( ps->externalEvent )
|
|
{
|
|
s->event = ps->externalEvent;
|
|
s->eventParm = ps->externalEventParm;
|
|
}
|
|
else if( ps->entityEventSequence < ps->eventSequence )
|
|
{
|
|
int seq;
|
|
|
|
if( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS )
|
|
ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
|
|
|
|
seq = ps->entityEventSequence & ( MAX_PS_EVENTS - 1 );
|
|
s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
|
|
s->eventParm = ps->eventParms[ seq ];
|
|
ps->entityEventSequence++;
|
|
}
|
|
|
|
s->weapon = ps->weapon;
|
|
s->groundEntityNum = ps->groundEntityNum;
|
|
|
|
//store items held and active items in modelindex and modelindex2
|
|
s->modelindex = 0;
|
|
s->modelindex2 = 0;
|
|
for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
|
|
{
|
|
if( BG_InventoryContainsUpgrade( i, ps->stats ) )
|
|
{
|
|
s->modelindex |= 1 << i;
|
|
|
|
if( BG_UpgradeIsActive( i, ps->stats ) )
|
|
s->modelindex2 |= 1 << i;
|
|
}
|
|
}
|
|
|
|
//TA: use powerups field to store team/class info:
|
|
s->powerups = ps->stats[ STAT_PTEAM ] | ( ps->stats[ STAT_PCLASS ] << 8 );
|
|
|
|
//TA: have to get the surfNormal thru somehow...
|
|
VectorCopy( ps->grapplePoint, s->angles2 );
|
|
if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
|
|
s->eFlags |= EF_WALLCLIMBCEILING;
|
|
|
|
s->loopSound = ps->loopSound;
|
|
s->generic1 = ps->generic1;
|
|
|
|
if( s->generic1 <= WPM_NONE || s->generic1 >= WPM_NUM_WEAPONMODES )
|
|
s->generic1 = WPM_PRIMARY;
|
|
|
|
s->otherEntityNum = ps->otherEntityNum;
|
|
}
|
|
|
|
|
|
/*
|
|
========================
|
|
BG_PlayerStateToEntityStateExtraPolate
|
|
|
|
This is done after each set of usercmd_t on the server,
|
|
and after local prediction on the client
|
|
========================
|
|
*/
|
|
void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s, int time, qboolean snap )
|
|
{
|
|
int i;
|
|
|
|
if( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR || ps->pm_type == PM_FREEZE )
|
|
s->eType = ET_INVISIBLE;
|
|
else if( ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
|
|
s->eType = ET_INVISIBLE;
|
|
else
|
|
s->eType = ET_PLAYER;
|
|
|
|
s->number = ps->clientNum;
|
|
|
|
s->pos.trType = TR_LINEAR_STOP;
|
|
VectorCopy( ps->origin, s->pos.trBase );
|
|
|
|
if( snap )
|
|
SnapVector( s->pos.trBase );
|
|
|
|
// set the trDelta for flag direction and linear prediction
|
|
VectorCopy( ps->velocity, s->pos.trDelta );
|
|
// set the time for linear prediction
|
|
s->pos.trTime = time;
|
|
// set maximum extra polation time
|
|
s->pos.trDuration = 50; // 1000 / sv_fps (default = 20)
|
|
|
|
s->apos.trType = TR_INTERPOLATE;
|
|
VectorCopy( ps->viewangles, s->apos.trBase );
|
|
if( snap )
|
|
SnapVector( s->apos.trBase );
|
|
|
|
//TA: i need for other things :)
|
|
//s->angles2[YAW] = ps->movementDir;
|
|
s->time2 = ps->movementDir;
|
|
s->legsAnim = ps->legsAnim;
|
|
s->torsoAnim = ps->torsoAnim;
|
|
s->clientNum = ps->clientNum; // ET_PLAYER looks here instead of at number
|
|
// so corpses can also reference the proper config
|
|
s->eFlags = ps->eFlags;
|
|
|
|
if( ps->stats[STAT_HEALTH] <= 0 )
|
|
s->eFlags |= EF_DEAD;
|
|
else
|
|
s->eFlags &= ~EF_DEAD;
|
|
|
|
if( ps->stats[ STAT_STATE ] & SS_BLOBLOCKED )
|
|
s->eFlags |= EF_BLOBLOCKED;
|
|
else
|
|
s->eFlags &= ~EF_BLOBLOCKED;
|
|
|
|
if( ps->externalEvent )
|
|
{
|
|
s->event = ps->externalEvent;
|
|
s->eventParm = ps->externalEventParm;
|
|
}
|
|
else if( ps->entityEventSequence < ps->eventSequence )
|
|
{
|
|
int seq;
|
|
|
|
if( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS )
|
|
ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
|
|
|
|
seq = ps->entityEventSequence & ( MAX_PS_EVENTS - 1 );
|
|
s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
|
|
s->eventParm = ps->eventParms[ seq ];
|
|
ps->entityEventSequence++;
|
|
}
|
|
|
|
s->weapon = ps->weapon;
|
|
s->groundEntityNum = ps->groundEntityNum;
|
|
|
|
//store items held and active items in modelindex and modelindex2
|
|
s->modelindex = 0;
|
|
s->modelindex2 = 0;
|
|
|
|
for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
|
|
{
|
|
if( BG_InventoryContainsUpgrade( i, ps->stats ) )
|
|
{
|
|
s->modelindex |= 1 << i;
|
|
|
|
if( BG_UpgradeIsActive( i, ps->stats ) )
|
|
s->modelindex2 |= 1 << i;
|
|
}
|
|
}
|
|
|
|
//TA: use powerups field to store team/class info:
|
|
s->powerups = ps->stats[ STAT_PTEAM ] | ( ps->stats[ STAT_PCLASS ] << 8 );
|
|
|
|
//TA: have to get the surfNormal thru somehow...
|
|
VectorCopy( ps->grapplePoint, s->angles2 );
|
|
if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
|
|
s->eFlags |= EF_WALLCLIMBCEILING;
|
|
|
|
s->loopSound = ps->loopSound;
|
|
s->generic1 = ps->generic1;
|
|
|
|
if( s->generic1 <= WPM_NONE || s->generic1 >= WPM_NUM_WEAPONMODES )
|
|
s->generic1 = WPM_PRIMARY;
|
|
|
|
s->otherEntityNum = ps->otherEntityNum;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_UnpackAmmoArray
|
|
|
|
Extract the ammo quantity from the array
|
|
========================
|
|
*/
|
|
void BG_UnpackAmmoArray( int weapon, int psAmmo[ ], int psAmmo2[ ], int *ammo, int *clips )
|
|
{
|
|
int ammoarray[ 32 ];
|
|
int i;
|
|
|
|
for( i = 0; i <= 15; i++ )
|
|
ammoarray[ i ] = psAmmo[ i ];
|
|
|
|
for( i = 16; i <= 31; i++ )
|
|
ammoarray[ i ] = psAmmo2[ i - 16 ];
|
|
|
|
if( ammo != NULL )
|
|
*ammo = ammoarray[ weapon ] & 0x0FFF;
|
|
|
|
if( clips != NULL )
|
|
*clips = ( ammoarray[ weapon ] >> 12 ) & 0x0F;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_PackAmmoArray
|
|
|
|
Pack the ammo quantity into the array
|
|
========================
|
|
*/
|
|
void BG_PackAmmoArray( int weapon, int psAmmo[ ], int psAmmo2[ ], int ammo, int clips )
|
|
{
|
|
int weaponvalue;
|
|
|
|
weaponvalue = ammo | ( clips << 12 );
|
|
|
|
if( weapon <= 15 )
|
|
psAmmo[ weapon ] = weaponvalue;
|
|
else if( weapon >= 16 )
|
|
psAmmo2[ weapon - 16 ] = weaponvalue;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_WeaponIsFull
|
|
|
|
Check if a weapon has full ammo
|
|
========================
|
|
*/
|
|
qboolean BG_WeaponIsFull( weapon_t weapon, int stats[ ], int psAmmo[ ], int psAmmo2[ ] )
|
|
{
|
|
int maxAmmo, maxClips;
|
|
int ammo, clips;
|
|
|
|
BG_FindAmmoForWeapon( weapon, &maxAmmo, &maxClips );
|
|
BG_UnpackAmmoArray( weapon, psAmmo, psAmmo2, &ammo, &clips );
|
|
|
|
if( BG_InventoryContainsUpgrade( UP_BATTPACK, stats ) )
|
|
maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER );
|
|
|
|
return ( maxAmmo == ammo ) && ( maxClips == clips );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_AddWeaponToInventory
|
|
|
|
Give a player a weapon
|
|
========================
|
|
*/
|
|
void BG_AddWeaponToInventory( int weapon, int stats[ ] )
|
|
{
|
|
int weaponList;
|
|
|
|
weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 );
|
|
|
|
weaponList |= ( 1 << weapon );
|
|
|
|
stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF;
|
|
stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16;
|
|
|
|
if( stats[ STAT_SLOTS ] & BG_FindSlotsForWeapon( weapon ) )
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: Held items conflict with weapon %d\n", weapon );
|
|
|
|
stats[ STAT_SLOTS ] |= BG_FindSlotsForWeapon( weapon );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_RemoveWeaponToInventory
|
|
|
|
Take a weapon from a player
|
|
========================
|
|
*/
|
|
void BG_RemoveWeaponFromInventory( int weapon, int stats[ ] )
|
|
{
|
|
int weaponList;
|
|
|
|
weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 );
|
|
|
|
weaponList &= ~( 1 << weapon );
|
|
|
|
stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF;
|
|
stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16;
|
|
|
|
stats[ STAT_SLOTS ] &= ~BG_FindSlotsForWeapon( weapon );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_InventoryContainsWeapon
|
|
|
|
Does the player hold a weapon?
|
|
========================
|
|
*/
|
|
qboolean BG_InventoryContainsWeapon( int weapon, int stats[ ] )
|
|
{
|
|
int weaponList;
|
|
|
|
weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 );
|
|
|
|
return( weaponList & ( 1 << weapon ) );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_AddUpgradeToInventory
|
|
|
|
Give the player an upgrade
|
|
========================
|
|
*/
|
|
void BG_AddUpgradeToInventory( int item, int stats[ ] )
|
|
{
|
|
stats[ STAT_ITEMS ] |= ( 1 << item );
|
|
|
|
if( stats[ STAT_SLOTS ] & BG_FindSlotsForUpgrade( item ) )
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: Held items conflict with upgrade %d\n", item );
|
|
|
|
stats[ STAT_SLOTS ] |= BG_FindSlotsForUpgrade( item );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_RemoveUpgradeFromInventory
|
|
|
|
Take an upgrade from the player
|
|
========================
|
|
*/
|
|
void BG_RemoveUpgradeFromInventory( int item, int stats[ ] )
|
|
{
|
|
stats[ STAT_ITEMS ] &= ~( 1 << item );
|
|
|
|
stats[ STAT_SLOTS ] &= ~BG_FindSlotsForUpgrade( item );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_InventoryContainsUpgrade
|
|
|
|
Does the player hold an upgrade?
|
|
========================
|
|
*/
|
|
qboolean BG_InventoryContainsUpgrade( int item, int stats[ ] )
|
|
{
|
|
return( stats[ STAT_ITEMS ] & ( 1 << item ) );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_ActivateUpgrade
|
|
|
|
Activates an upgrade
|
|
========================
|
|
*/
|
|
void BG_ActivateUpgrade( int item, int stats[ ] )
|
|
{
|
|
stats[ STAT_ACTIVEITEMS ] |= ( 1 << item );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_DeactivateUpgrade
|
|
|
|
Deactivates an upgrade
|
|
========================
|
|
*/
|
|
void BG_DeactivateUpgrade( int item, int stats[ ] )
|
|
{
|
|
stats[ STAT_ACTIVEITEMS ] &= ~( 1 << item );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
BG_UpgradeIsActive
|
|
|
|
Is this upgrade active?
|
|
========================
|
|
*/
|
|
qboolean BG_UpgradeIsActive( int item, int stats[ ] )
|
|
{
|
|
return( stats[ STAT_ACTIVEITEMS ] & ( 1 << item ) );
|
|
}
|
|
|
|
/*
|
|
===============
|
|
BG_RotateAxis
|
|
|
|
Shared axis rotation function
|
|
===============
|
|
*/
|
|
qboolean BG_RotateAxis( vec3_t surfNormal, vec3_t inAxis[ 3 ],
|
|
vec3_t outAxis[ 3 ], qboolean inverse, qboolean ceiling )
|
|
{
|
|
vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
|
|
vec3_t ceilingNormal = { 0.0f, 0.0f, -1.0f };
|
|
vec3_t localNormal, xNormal;
|
|
float rotAngle;
|
|
|
|
//the grapplePoint being a surfNormal rotation Normal hack... see above :)
|
|
if( ceiling )
|
|
{
|
|
VectorCopy( ceilingNormal, localNormal );
|
|
VectorCopy( surfNormal, xNormal );
|
|
}
|
|
else
|
|
{
|
|
//cross the reference normal and the surface normal to get the rotation axis
|
|
VectorCopy( surfNormal, localNormal );
|
|
CrossProduct( localNormal, refNormal, xNormal );
|
|
VectorNormalize( xNormal );
|
|
}
|
|
|
|
//can't rotate with no rotation vector
|
|
if( VectorLength( xNormal ) != 0.0f )
|
|
{
|
|
rotAngle = RAD2DEG( acos( DotProduct( localNormal, refNormal ) ) );
|
|
|
|
if( inverse )
|
|
rotAngle = -rotAngle;
|
|
|
|
AngleNormalize180( rotAngle );
|
|
|
|
//hmmm could get away with only one rotation and some clever stuff later... but i'm lazy
|
|
RotatePointAroundVector( outAxis[ 0 ], xNormal, inAxis[ 0 ], -rotAngle );
|
|
RotatePointAroundVector( outAxis[ 1 ], xNormal, inAxis[ 1 ], -rotAngle );
|
|
RotatePointAroundVector( outAxis[ 2 ], xNormal, inAxis[ 2 ], -rotAngle );
|
|
}
|
|
else
|
|
return qfalse;
|
|
|
|
return qtrue;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
BG_PositionBuildableRelativeToPlayer
|
|
|
|
Find a place to build a buildable
|
|
===============
|
|
*/
|
|
void 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 )
|
|
{
|
|
vec3_t forward, entityOrigin, targetOrigin;
|
|
vec3_t angles, playerOrigin, playerNormal;
|
|
float buildDist;
|
|
|
|
if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING )
|
|
{
|
|
if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
|
|
VectorSet( playerNormal, 0.0f, 0.0f, -1.0f );
|
|
else
|
|
VectorCopy( ps->grapplePoint, playerNormal );
|
|
}
|
|
else
|
|
VectorSet( playerNormal, 0.0f, 0.0f, 1.0f );
|
|
|
|
VectorCopy( ps->viewangles, angles );
|
|
VectorCopy( ps->origin, playerOrigin );
|
|
buildDist = BG_FindBuildDistForClass( ps->stats[ STAT_PCLASS ] );
|
|
|
|
AngleVectors( angles, forward, NULL, NULL );
|
|
ProjectPointOnPlane( forward, forward, playerNormal );
|
|
VectorNormalize( forward );
|
|
|
|
VectorMA( playerOrigin, buildDist, forward, entityOrigin );
|
|
|
|
VectorCopy( entityOrigin, targetOrigin );
|
|
|
|
//so buildings can be placed facing slopes
|
|
VectorMA( entityOrigin, 32, playerNormal, entityOrigin );
|
|
|
|
//so buildings drop to floor
|
|
VectorMA( targetOrigin, -128, playerNormal, targetOrigin );
|
|
|
|
(*trace)( tr, entityOrigin, mins, maxs, targetOrigin, ps->clientNum, MASK_DEADSOLID );
|
|
VectorCopy( tr->endpos, entityOrigin );
|
|
VectorMA( entityOrigin, 0.1f, playerNormal, outOrigin );
|
|
vectoangles( forward, outAngles );
|
|
}
|
|
|
|
/*
|
|
===============
|
|
BG_GetValueOfEquipment
|
|
|
|
Returns the equipment value of some human player's gear
|
|
===============
|
|
*/
|
|
int BG_GetValueOfEquipment( playerState_t *ps ) {
|
|
int i, worth = 0;
|
|
|
|
for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
|
|
{
|
|
if( BG_InventoryContainsUpgrade( i, ps->stats ) )
|
|
worth += BG_FindPriceForUpgrade( i );
|
|
}
|
|
|
|
for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
|
|
{
|
|
if( BG_InventoryContainsWeapon( i, ps->stats ) )
|
|
worth += BG_FindPriceForWeapon( i );
|
|
}
|
|
|
|
return worth;
|
|
}
|
|
/*
|
|
===============
|
|
BG_GetValueOfHuman
|
|
|
|
Returns the kills value of some human player
|
|
===============
|
|
*/
|
|
int BG_GetValueOfHuman( playerState_t *ps )
|
|
{
|
|
float portion = BG_GetValueOfEquipment( ps ) / (float)HUMAN_MAXED;
|
|
|
|
|
|
if( portion < 0.01f )
|
|
portion = 0.01f;
|
|
else if( portion > 1.0f )
|
|
portion = 1.0f;
|
|
|
|
return ceil( ALIEN_MAX_SINGLE_KILLS * portion );
|
|
}
|
|
|
|
/*
|
|
===============
|
|
atof_neg
|
|
|
|
atof with an allowance for negative values
|
|
===============
|
|
*/
|
|
float atof_neg( char *token, qboolean allowNegative )
|
|
{
|
|
float value;
|
|
|
|
value = atof( token );
|
|
|
|
if( !allowNegative && value < 0.0f )
|
|
value = 1.0f;
|
|
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
atoi_neg
|
|
|
|
atoi with an allowance for negative values
|
|
===============
|
|
*/
|
|
int atoi_neg( char *token, qboolean allowNegative )
|
|
{
|
|
int value;
|
|
|
|
value = atoi( token );
|
|
|
|
if( !allowNegative && value < 0 )
|
|
value = 1;
|
|
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
BG_ParseCSVEquipmentList
|
|
===============
|
|
*/
|
|
void BG_ParseCSVEquipmentList( const char *string, weapon_t *weapons, int weaponsSize,
|
|
upgrade_t *upgrades, int upgradesSize )
|
|
{
|
|
char buffer[ MAX_STRING_CHARS ];
|
|
int i = 0, j = 0;
|
|
char *p, *q;
|
|
qboolean EOS = qfalse;
|
|
|
|
Q_strncpyz( buffer, string, MAX_STRING_CHARS );
|
|
|
|
p = q = buffer;
|
|
|
|
while( *p != '\0' )
|
|
{
|
|
//skip to first , or EOS
|
|
while( *p != ',' && *p != '\0' )
|
|
p++;
|
|
|
|
if( *p == '\0' )
|
|
EOS = qtrue;
|
|
|
|
*p = '\0';
|
|
|
|
//strip leading whitespace
|
|
while( *q == ' ' )
|
|
q++;
|
|
|
|
if( weaponsSize )
|
|
weapons[ i ] = BG_FindWeaponNumForName( q );
|
|
|
|
if( upgradesSize )
|
|
upgrades[ j ] = BG_FindUpgradeNumForName( q );
|
|
|
|
if( weaponsSize && weapons[ i ] == WP_NONE &&
|
|
upgradesSize && upgrades[ j ] == UP_NONE )
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: unknown equipment %s\n", q );
|
|
else if( weaponsSize && weapons[ i ] != WP_NONE )
|
|
i++;
|
|
else if( upgradesSize && upgrades[ j ] != UP_NONE )
|
|
j++;
|
|
|
|
if( !EOS )
|
|
{
|
|
p++;
|
|
q = p;
|
|
}
|
|
else
|
|
break;
|
|
|
|
if( i == ( weaponsSize - 1 ) || j == ( upgradesSize - 1 ) )
|
|
break;
|
|
}
|
|
|
|
if( weaponsSize )
|
|
weapons[ i ] = WP_NONE;
|
|
|
|
if( upgradesSize )
|
|
upgrades[ j ] = UP_NONE;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
BG_ParseCSVClassList
|
|
===============
|
|
*/
|
|
void BG_ParseCSVClassList( const char *string, pClass_t *classes, int classesSize )
|
|
{
|
|
char buffer[ MAX_STRING_CHARS ];
|
|
int i = 0;
|
|
char *p, *q;
|
|
qboolean EOS = qfalse;
|
|
|
|
Q_strncpyz( buffer, string, MAX_STRING_CHARS );
|
|
|
|
p = q = buffer;
|
|
|
|
while( *p != '\0' )
|
|
{
|
|
//skip to first , or EOS
|
|
while( *p != ',' && *p != '\0' )
|
|
p++;
|
|
|
|
if( *p == '\0' )
|
|
EOS = qtrue;
|
|
|
|
*p = '\0';
|
|
|
|
//strip leading whitespace
|
|
while( *q == ' ' )
|
|
q++;
|
|
|
|
classes[ i ] = BG_FindClassNumForName( q );
|
|
|
|
if( classes[ i ] == PCL_NONE )
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: unknown class %s\n", q );
|
|
else
|
|
i++;
|
|
|
|
if( !EOS )
|
|
{
|
|
p++;
|
|
q = p;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
classes[ i ] = PCL_NONE;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
BG_ParseCSVBuildableList
|
|
===============
|
|
*/
|
|
void BG_ParseCSVBuildableList( const char *string, buildable_t *buildables, int buildablesSize )
|
|
{
|
|
char buffer[ MAX_STRING_CHARS ];
|
|
int i = 0;
|
|
char *p, *q;
|
|
qboolean EOS = qfalse;
|
|
|
|
Q_strncpyz( buffer, string, MAX_STRING_CHARS );
|
|
|
|
p = q = buffer;
|
|
|
|
while( *p != '\0' )
|
|
{
|
|
//skip to first , or EOS
|
|
while( *p != ',' && *p != '\0' )
|
|
p++;
|
|
|
|
if( *p == '\0' )
|
|
EOS = qtrue;
|
|
|
|
*p = '\0';
|
|
|
|
//strip leading whitespace
|
|
while( *q == ' ' )
|
|
q++;
|
|
|
|
buildables[ i ] = BG_FindClassNumForName( q );
|
|
|
|
if( buildables[ i ] == BA_NONE )
|
|
Com_Printf( S_COLOR_YELLOW "WARNING: unknown buildable %s\n", q );
|
|
else
|
|
i++;
|
|
|
|
if( !EOS )
|
|
{
|
|
p++;
|
|
q = p;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
buildables[ i ] = BA_NONE;
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_UpgradeClassAvailable
|
|
============
|
|
*/
|
|
qboolean BG_UpgradeClassAvailable( playerState_t *ps )
|
|
{
|
|
int i;
|
|
char buffer[ MAX_STRING_CHARS ];
|
|
stage_t currentStage;
|
|
|
|
trap_Cvar_VariableStringBuffer( "g_alienStage", buffer, MAX_STRING_CHARS );
|
|
currentStage = atoi( buffer );
|
|
|
|
for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
|
|
{
|
|
if( BG_ClassCanEvolveFromTo( ps->stats[ STAT_PCLASS ], i,
|
|
ps->persistant[ PERS_CREDIT ], 0 ) >= 0 &&
|
|
BG_FindStagesForClass( i, currentStage ) &&
|
|
BG_ClassIsAllowed( i ) )
|
|
{
|
|
return qtrue;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
typedef struct gameElements_s
|
|
{
|
|
buildable_t buildables[ BA_NUM_BUILDABLES ];
|
|
pClass_t classes[ PCL_NUM_CLASSES ];
|
|
weapon_t weapons[ WP_NUM_WEAPONS ];
|
|
upgrade_t upgrades[ UP_NUM_UPGRADES ];
|
|
} gameElements_t;
|
|
|
|
static gameElements_t bg_disabledGameElements;
|
|
|
|
/*
|
|
============
|
|
BG_InitAllowedGameElements
|
|
============
|
|
*/
|
|
void BG_InitAllowedGameElements( void )
|
|
{
|
|
char cvar[ MAX_CVAR_VALUE_STRING ];
|
|
|
|
trap_Cvar_VariableStringBuffer( "g_disabledEquipment",
|
|
cvar, MAX_CVAR_VALUE_STRING );
|
|
|
|
BG_ParseCSVEquipmentList( cvar,
|
|
bg_disabledGameElements.weapons, WP_NUM_WEAPONS,
|
|
bg_disabledGameElements.upgrades, UP_NUM_UPGRADES );
|
|
|
|
trap_Cvar_VariableStringBuffer( "g_disabledClasses",
|
|
cvar, MAX_CVAR_VALUE_STRING );
|
|
|
|
BG_ParseCSVClassList( cvar,
|
|
bg_disabledGameElements.classes, PCL_NUM_CLASSES );
|
|
|
|
trap_Cvar_VariableStringBuffer( "g_disabledBuildables",
|
|
cvar, MAX_CVAR_VALUE_STRING );
|
|
|
|
BG_ParseCSVBuildableList( cvar,
|
|
bg_disabledGameElements.buildables, BA_NUM_BUILDABLES );
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_WeaponIsAllowed
|
|
============
|
|
*/
|
|
qboolean BG_WeaponIsAllowed( weapon_t weapon )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < WP_NUM_WEAPONS &&
|
|
bg_disabledGameElements.weapons[ i ] != WP_NONE; i++ )
|
|
{
|
|
if( bg_disabledGameElements.weapons[ i ] == weapon )
|
|
return qfalse;
|
|
}
|
|
|
|
return qtrue;
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_UpgradeIsAllowed
|
|
============
|
|
*/
|
|
qboolean BG_UpgradeIsAllowed( upgrade_t upgrade )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < UP_NUM_UPGRADES &&
|
|
bg_disabledGameElements.upgrades[ i ] != UP_NONE; i++ )
|
|
{
|
|
if( bg_disabledGameElements.upgrades[ i ] == upgrade )
|
|
return qfalse;
|
|
}
|
|
|
|
return qtrue;
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_ClassIsAllowed
|
|
============
|
|
*/
|
|
qboolean BG_ClassIsAllowed( pClass_t class )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < PCL_NUM_CLASSES &&
|
|
bg_disabledGameElements.classes[ i ] != PCL_NONE; i++ )
|
|
{
|
|
if( bg_disabledGameElements.classes[ i ] == class )
|
|
return qfalse;
|
|
}
|
|
|
|
return qtrue;
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_BuildableIsAllowed
|
|
============
|
|
*/
|
|
qboolean BG_BuildableIsAllowed( buildable_t buildable )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < BA_NUM_BUILDABLES &&
|
|
bg_disabledGameElements.buildables[ i ] != BA_NONE; i++ )
|
|
{
|
|
if( bg_disabledGameElements.buildables[ i ] == buildable )
|
|
return qfalse;
|
|
}
|
|
|
|
return qtrue;
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_ClientListTest
|
|
============
|
|
*/
|
|
qboolean BG_ClientListTest( clientList_t *list, int clientNum )
|
|
{
|
|
if( clientNum < 0 || clientNum >= MAX_CLIENTS || !list )
|
|
return qfalse;
|
|
if( clientNum < 32 )
|
|
return ( ( list->lo & ( 1 << clientNum ) ) != 0 );
|
|
else
|
|
return ( ( list->hi & ( 1 << ( clientNum - 32 ) ) ) != 0 );
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_ClientListAdd
|
|
============
|
|
*/
|
|
void BG_ClientListAdd( clientList_t *list, int clientNum )
|
|
{
|
|
if( clientNum < 0 || clientNum >= MAX_CLIENTS || !list )
|
|
return;
|
|
if( clientNum < 32 )
|
|
list->lo |= ( 1 << clientNum );
|
|
else
|
|
list->hi |= ( 1 << ( clientNum - 32 ) );
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_ClientListRemove
|
|
============
|
|
*/
|
|
void BG_ClientListRemove( clientList_t *list, int clientNum )
|
|
{
|
|
if( clientNum < 0 || clientNum >= MAX_CLIENTS || !list )
|
|
return;
|
|
if( clientNum < 32 )
|
|
list->lo &= ~( 1 << clientNum );
|
|
else
|
|
list->hi &= ~( 1 << ( clientNum - 32 ) );
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_ClientListString
|
|
============
|
|
*/
|
|
char *BG_ClientListString( clientList_t *list )
|
|
{
|
|
static char s[ 17 ];
|
|
|
|
s[ 0 ] = '\0';
|
|
if( !list )
|
|
return s;
|
|
Com_sprintf( s, sizeof( s ), "%08x%08x", list->hi, list->lo );
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
============
|
|
BG_ClientListParse
|
|
============
|
|
*/
|
|
void BG_ClientListParse( clientList_t *list, const char *s )
|
|
{
|
|
if( !list )
|
|
return;
|
|
list->lo = 0;
|
|
list->hi = 0;
|
|
if( !s )
|
|
return;
|
|
if( strlen( s ) != 16 )
|
|
return;
|
|
sscanf( s, "%x%x", &list->hi, &list->lo );
|
|
}
|
|
|
|
void BG_MOD_set( modExtremeType_t entry, int value )
|
|
{
|
|
if( entry >= 0 && entry < MOD_BG_COUNT )
|
|
{
|
|
if( value < 0 )
|
|
value = 0;
|
|
|
|
modEntry[ entry ] = value;
|
|
}
|
|
}
|
|
|
|
void BG_MOD_update( void )
|
|
{
|
|
static qboolean updated = qfalse;
|
|
int i;
|
|
|
|
if( updated ) return;
|
|
updated = qtrue;
|
|
|
|
for( i = 0; i < bg_numBuildables; i++ )
|
|
{
|
|
if( modEntry[ MOD_BG_BUILDABLE_HEALTH ] )
|
|
{
|
|
bg_buildableList[ i ].health =
|
|
bg_buildableList[ i ].health * modEntry[ MOD_BG_BUILDABLE_HEALTH ] / 100;
|
|
}
|
|
|
|
if( modEntry[ MOD_BG_BUILDABLE_SPEED ] )
|
|
{
|
|
bg_buildableList[ i ].turretFireSpeed =
|
|
bg_buildableList[ i ].turretFireSpeed * 100 / modEntry[ MOD_BG_BUILDABLE_SPEED ];
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < bg_numPclasses; i++ )
|
|
{
|
|
if( bg_classList[ i ].classNum == PCL_HUMAN ||
|
|
bg_classList[ i ].classNum == PCL_HUMAN_BSUIT )
|
|
{
|
|
if( modEntry[ MOD_BG_HUMAN_HEALTH ] )
|
|
{
|
|
bg_classList[ i ].health =
|
|
bg_classList[ i ].health * modEntry[ MOD_BG_HUMAN_HEALTH ] / 100;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( modEntry[ MOD_BG_ALIEN_HEALTH ] )
|
|
bg_classList[ i ].health =
|
|
bg_classList[ i ].health * modEntry[ MOD_BG_ALIEN_HEALTH ] / 100;
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < bg_numWeapons; i++ )
|
|
{
|
|
if( modEntry[ MOD_BG_WEAPON_AMMO ] &&
|
|
bg_weapons[ i ].weaponNum != WP_ALEVEL3_UPG )
|
|
{
|
|
bg_weapons[ i ].maxAmmo =
|
|
bg_weapons[ i ].maxAmmo * modEntry[ MOD_BG_WEAPON_AMMO ] / 100;
|
|
}
|
|
|
|
if( modEntry[ MOD_BG_ALIEN_RATE ] &&
|
|
bg_weapons[ i ].weaponNum >= WP_ALEVEL0 &&
|
|
bg_weapons[ i ].weaponNum <= WP_ALEVEL4 )
|
|
{
|
|
bg_weapons[ i ].repeatRate1 =
|
|
bg_weapons[ i ].repeatRate1 * 100 / modEntry[ MOD_BG_ALIEN_RATE ];
|
|
bg_weapons[ i ].repeatRate2 =
|
|
bg_weapons[ i ].repeatRate2 * 100 / modEntry[ MOD_BG_ALIEN_RATE ];
|
|
bg_weapons[ i ].repeatRate3 =
|
|
bg_weapons[ i ].repeatRate3 * 100 / modEntry[ MOD_BG_ALIEN_RATE ];
|
|
}
|
|
|
|
if( modEntry[ MOD_BG_HUMAN_RATE ] &&
|
|
bg_weapons[ i ].weaponNum >= WP_BLASTER &&
|
|
bg_weapons[ i ].weaponNum <= WP_LUCIFER_CANNON )
|
|
{
|
|
bg_weapons[ i ].repeatRate1 =
|
|
bg_weapons[ i ].repeatRate1 * 100 / modEntry[ MOD_BG_HUMAN_RATE ];
|
|
bg_weapons[ i ].repeatRate2 =
|
|
bg_weapons[ i ].repeatRate2 * 100 / modEntry[ MOD_BG_HUMAN_RATE ];
|
|
bg_weapons[ i ].repeatRate3 =
|
|
bg_weapons[ i ].repeatRate3 * 100 / modEntry[ MOD_BG_HUMAN_RATE ];
|
|
}
|
|
|
|
if( modEntry[ MOD_BG_BUILDABLE_HEALTH ] &&
|
|
modEntry[ MOD_BG_HUMAN_RATE ] &&
|
|
( bg_weapons[ i ].weaponNum == WP_ABUILD || bg_weapons[ i ].weaponNum == WP_ABUILD2 ) )
|
|
{
|
|
int avg;
|
|
|
|
avg = ( modEntry[ MOD_BG_BUILDABLE_HEALTH ] + MOD_BG_HUMAN_RATE ) / 2;
|
|
bg_weapons[ i ].repeatRate1 = bg_weapons[ i ].repeatRate1 * 100 / avg;
|
|
bg_weapons[ i ].repeatRate2 = bg_weapons[ i ].repeatRate2 * 100 / avg;
|
|
bg_weapons[ i ].repeatRate3 = bg_weapons[ i ].repeatRate3 * 100 / avg;
|
|
}
|
|
|
|
if( modEntry[ MOD_BG_BUILDABLE_HEALTH ] &&
|
|
modEntry[ MOD_BG_ALIEN_RATE ] &&
|
|
( bg_weapons[ i ].weaponNum == WP_HBUILD || bg_weapons[ i ].weaponNum == WP_HBUILD2 ) )
|
|
{
|
|
int avg;
|
|
|
|
avg = ( modEntry[ MOD_BG_BUILDABLE_HEALTH ] + MOD_BG_ALIEN_RATE ) / 2;
|
|
bg_weapons[ i ].repeatRate1 = bg_weapons[ i ].repeatRate1 * 100 / avg;
|
|
bg_weapons[ i ].repeatRate2 = bg_weapons[ i ].repeatRate2 * 100 / avg;
|
|
bg_weapons[ i ].repeatRate3 = bg_weapons[ i ].repeatRate3 * 100 / avg;
|
|
}
|
|
|
|
if( modEntry[ MOD_BG_WEAPON_RELOAD ] )
|
|
{
|
|
bg_weapons[ i ].reloadTime =
|
|
bg_weapons[ i ].reloadTime * 100 / modEntry[ MOD_BG_WEAPON_RELOAD ];
|
|
}
|
|
}
|
|
}
|
|
|