2061 lines
55 KiB
C++
2061 lines
55 KiB
C++
|
|
||
|
#include "g_local.h"
|
||
|
#include "g_spawn.h"
|
||
|
#include "fields.h"
|
||
|
#include "ai_pathfinding.h"
|
||
|
#include "p_body.h"
|
||
|
#include "..\qcommon\configstring.h"
|
||
|
|
||
|
#if TIME_ENTS
|
||
|
#include <windows.h>
|
||
|
#endif
|
||
|
|
||
|
void CalculatePlayerEntryWeapons(int *weaponsAvailable);
|
||
|
|
||
|
byte entSoundsToCache[NUM_CLSFX];
|
||
|
char entDebrisToCache[NUM_CLGHL];
|
||
|
|
||
|
// 1/12/99 sfs -- this should fix the crummy randomness in pakfile creating
|
||
|
static cvar_t *fs_createpak;
|
||
|
|
||
|
extern spawn_t environSpawns[];
|
||
|
extern spawn_t funcSpawns[];
|
||
|
extern spawn_t triggerSpawns[];
|
||
|
extern spawn_t targetSpawns[];
|
||
|
extern spawn_t lightSpawns[];
|
||
|
extern spawn_t bosniaSpawns[];
|
||
|
extern spawn_t castleSpawns[];
|
||
|
extern spawn_t iraqSpawns[];
|
||
|
extern spawn_t genericSpawns[];
|
||
|
extern spawn_t newyorkSpawns[];
|
||
|
extern spawn_t siberiaSpawns[];
|
||
|
extern spawn_t tokyoSpawns[];
|
||
|
extern spawn_t ugandaSpawns[];
|
||
|
extern spawn_t dmSpawns[];
|
||
|
|
||
|
void CleanUpGame (void);
|
||
|
|
||
|
// info_...
|
||
|
//void SP_info_merc_start (edict_t *ent);
|
||
|
void SP_info_notnull (edict_t *self);
|
||
|
void SP_info_null (edict_t *self);
|
||
|
void SP_info_player_start (edict_t *ent);
|
||
|
void SP_info_player_deathmatch (edict_t *ent);
|
||
|
void SP_info_player_team1 (edict_t *ent);
|
||
|
void SP_info_player_team2 (edict_t *ent);
|
||
|
//void SP_info_player_coop (edict_t *ent);
|
||
|
void SP_info_player_intermission (edict_t *ent);
|
||
|
|
||
|
int ai_loadAllBolts = 0;
|
||
|
|
||
|
|
||
|
// misc non-id stuff
|
||
|
void SP_func_remote_camera(edict_t *Self);
|
||
|
void SP_misc_ctf_base (edict_t *self);
|
||
|
|
||
|
|
||
|
// misc_ id stuff
|
||
|
void SP_path_corner (edict_t *self);
|
||
|
void SP_point_combat (edict_t *self);
|
||
|
void SP_misc_gib_arm (edict_t *self);
|
||
|
void SP_misc_gib_leg (edict_t *self);
|
||
|
void SP_misc_gib_head (edict_t *self);
|
||
|
|
||
|
void SP_spawner(edict_t *ent);
|
||
|
void SP_spawner_monster(edict_t *ent);
|
||
|
void SP_spawner_boosterpack(edict_t *ent);
|
||
|
|
||
|
// worldspawn...
|
||
|
void SP_worldspawn (edict_t *ent);
|
||
|
|
||
|
// testing things
|
||
|
void SP_ghoul_model (edict_t *ent);
|
||
|
void SP_test_model (edict_t *ent);
|
||
|
void SP_test_rj (edict_t *ent);
|
||
|
|
||
|
extern void SP_script_runner (edict_t *ent);
|
||
|
|
||
|
void InitEntSoundCaching(void);
|
||
|
void InitEntMetalSoundCaching(void);
|
||
|
void InitEntDebrisCaching(void);
|
||
|
void CacheEntDebrisAndSounds(edict_t *ent);
|
||
|
void CacheAllDebris(void);
|
||
|
void CacheAllWallEffects(void);
|
||
|
void CacheAllSounds(void);
|
||
|
|
||
|
spawn_t spawns[] =
|
||
|
{
|
||
|
// info_...
|
||
|
// {"info_merc_start", SP_info_merc_start},
|
||
|
{"info_null", SP_info_null},
|
||
|
{"info_notnull", SP_info_notnull},
|
||
|
// {"info_player_coop", SP_info_player_coop},
|
||
|
{"info_player_deathmatch", SP_info_player_deathmatch},
|
||
|
{"info_player_team1", SP_info_player_team1},
|
||
|
{"info_player_team2", SP_info_player_team2},
|
||
|
{"info_player_intermission", SP_info_player_intermission},
|
||
|
{"info_player_start", SP_info_player_start},
|
||
|
|
||
|
// misc_nonid stuff
|
||
|
{"func_remote_camera", SP_func_remote_camera},
|
||
|
{"misc_ctf_base", SP_misc_ctf_base},
|
||
|
|
||
|
// misc_ id stuff
|
||
|
{"path_corner", SP_path_corner},
|
||
|
{"point_combat", SP_point_combat},
|
||
|
|
||
|
// monster_...
|
||
|
{"m_x_romulan", SP_m_x_romulan},
|
||
|
{"m_x_tank", SP_m_x_tank},
|
||
|
{"m_x_snowcat", SP_m_x_snowcat},
|
||
|
{"m_x_husky", SP_m_x_husky},
|
||
|
{"m_x_rottweiler", SP_m_x_rottweiler},
|
||
|
{"m_x_germanshep", SP_m_x_germanshep},
|
||
|
{"m_x_raiderdog", SP_m_x_raiderdog},
|
||
|
{"m_x_bull", SP_m_x_bull},
|
||
|
{"m_x_chopper_black", SP_m_x_chopper_black},
|
||
|
{"m_x_chopper_green", SP_m_x_chopper_green},
|
||
|
{"m_x_chopper_white", SP_m_x_chopper_white},
|
||
|
{"m_x_hind", SP_m_x_hind},
|
||
|
{"m_x_mcharacter", SP_m_x_mcharacter},
|
||
|
{"m_x_mcharacter_snow", SP_m_x_mcharacter_snow},
|
||
|
{"m_x_mcharacter_desert", SP_m_x_mcharacter_desert},
|
||
|
{"m_x_mmerc", SP_m_x_mmerc},
|
||
|
{"m_x_mhurtmerc", SP_m_x_mhurtmerc},
|
||
|
{"m_x_msam", SP_m_x_msam},
|
||
|
{"m_x_miraqboss", SP_m_x_miraqboss},
|
||
|
{"m_x_mraiderboss1", SP_m_x_mraiderboss1},
|
||
|
{"m_x_mraiderboss2", SP_m_x_mraiderboss2},
|
||
|
{"m_x_ftaylor", SP_m_x_ftaylor},
|
||
|
{"m_x_mskinboss", SP_m_x_mskinboss},
|
||
|
|
||
|
{"m_sib_mtrooper1a", SP_m_sib_mtrooper1a},
|
||
|
{"m_sib_mtrooper1b", SP_m_sib_mtrooper1b},
|
||
|
{"m_sib_mtrooper2", SP_m_sib_mtrooper2},
|
||
|
{"m_sib_mguard1", SP_m_sib_mguard1},
|
||
|
{"m_sib_fguard2", SP_m_sib_fguard2},
|
||
|
{"m_sib_mguard3", SP_m_sib_mguard3},
|
||
|
{"m_sib_mguard4", SP_m_sib_mguard4},
|
||
|
{"m_sib_mcleansuit", SP_m_sib_mcleansuit},
|
||
|
{"m_sib_eofficer", SP_m_sib_eofficer},
|
||
|
{"m_sib_mmechanic", SP_m_sib_mmechanic},
|
||
|
{"m_sib_escientist1", SP_m_sib_escientist1},
|
||
|
{"m_sib_fscientist2", SP_m_sib_fscientist2},
|
||
|
|
||
|
{"m_afr_msoldier1a", SP_m_afr_msoldier1a},
|
||
|
{"m_afr_msoldier1b", SP_m_afr_msoldier1b},
|
||
|
{"m_afr_msoldier2", SP_m_afr_msoldier2},
|
||
|
{"m_afr_msoldier3", SP_m_afr_msoldier3},
|
||
|
{"m_afr_msniper", SP_m_afr_msniper},
|
||
|
{"m_afr_ecommander", SP_m_afr_ecommander},
|
||
|
{"m_afr_eworker", SP_m_afr_eworker},
|
||
|
{"m_afr_mbrute", SP_m_afr_mbrute},
|
||
|
{"m_afr_mrocket", SP_m_afr_mrocket},
|
||
|
|
||
|
{"m_kos_mgrunt1", SP_m_kos_mgrunt1},
|
||
|
{"m_kos_mgrunt2", SP_m_kos_mgrunt2},
|
||
|
{"m_kos_mgrunt3", SP_m_kos_mgrunt3},
|
||
|
{"m_kos_msniper1a", SP_m_kos_msniper1a},
|
||
|
{"m_kos_msniper1b", SP_m_kos_msniper1b},
|
||
|
{"m_kos_mcomtroop", SP_m_kos_mcomtroop},
|
||
|
{"m_kos_eofficer", SP_m_kos_eofficer},
|
||
|
{"m_kos_mbrute1a", SP_m_kos_mbrute1a},
|
||
|
{"m_kos_mbrute1b", SP_m_kos_mbrute1b},
|
||
|
{"m_kos_mmechanic", SP_m_kos_mmechanic},
|
||
|
{"m_kos_mrebel", SP_m_kos_mrebel},
|
||
|
{"m_kos_mklaleader", SP_m_kos_mklaleader},
|
||
|
{"m_kos_erefugee", SP_m_kos_erefugee},
|
||
|
|
||
|
{"m_tok_mman1", SP_m_tok_mman1},
|
||
|
{"m_tok_mman2", SP_m_tok_mman2},
|
||
|
{"m_tok_mhench1", SP_m_tok_mhench1},
|
||
|
{"m_tok_mhench2", SP_m_tok_mhench2},
|
||
|
{"m_tok_mkiller", SP_m_tok_mkiller},
|
||
|
{"m_tok_fassassin", SP_m_tok_fassassin},
|
||
|
{"m_tok_mninja", SP_m_tok_mninja},
|
||
|
{"m_tok_mbrute", SP_m_tok_mbrute},
|
||
|
{"m_tok_fwoman1", SP_m_tok_fwoman1},
|
||
|
{"m_tok_fwoman2", SP_m_tok_fwoman2},
|
||
|
|
||
|
{"m_irq_msoldier1", SP_m_irq_msoldier1},
|
||
|
{"m_irq_msoldier2a", SP_m_irq_msoldier2a},
|
||
|
{"m_irq_msoldier2b", SP_m_irq_msoldier2b},
|
||
|
{"m_irq_mrepguard1a", SP_m_irq_mrepguard1a},
|
||
|
{"m_irq_mrepguard1b", SP_m_irq_mrepguard1b},
|
||
|
{"m_irq_mpolice", SP_m_irq_mpolice},
|
||
|
{"m_irq_eofficer", SP_m_irq_eofficer},
|
||
|
{"m_irq_mcommander", SP_m_irq_mcommander},
|
||
|
{"m_irq_mbrute1a", SP_m_irq_mbrute1a},
|
||
|
{"m_irq_mbrute1b", SP_m_irq_mbrute1b},
|
||
|
{"m_irq_mbodyguard", SP_m_irq_mbodyguard},
|
||
|
{"m_irq_mrocket", SP_m_irq_mrocket},
|
||
|
{"m_irq_msaddam", SP_m_irq_msaddam},
|
||
|
{"m_irq_moilworker", SP_m_irq_moilworker},
|
||
|
{"m_irq_eman1", SP_m_irq_eman1},
|
||
|
{"m_irq_mman2", SP_m_irq_mman2},
|
||
|
{"m_irq_fwoman1", SP_m_irq_fwoman1},
|
||
|
{"m_irq_fwoman2", SP_m_irq_fwoman2},
|
||
|
|
||
|
{"m_cas_mraider1", SP_m_cas_mraider1},
|
||
|
{"m_cas_mraider2a", SP_m_cas_mraider2a},
|
||
|
{"m_cas_mraider2b", SP_m_cas_mraider2b},
|
||
|
{"m_cas_mbrute", SP_m_cas_mbrute},
|
||
|
{"m_cas_ffemale", SP_m_cas_ffemale},
|
||
|
{"m_cas_mrocket", SP_m_cas_mrocket},
|
||
|
|
||
|
{"m_nyc_mskinhead1", SP_m_nyc_mskinhead1},
|
||
|
{"m_nyc_mskinhead2a", SP_m_nyc_mskinhead2a},
|
||
|
{"m_nyc_mskinhead2b", SP_m_nyc_mskinhead2b},
|
||
|
{"m_nyc_eskinhead3", SP_m_nyc_eskinhead3},
|
||
|
{"m_nyc_fskinchick", SP_m_nyc_fskinchick},
|
||
|
{"m_nyc_mpunk", SP_m_nyc_mpunk},
|
||
|
{"m_nyc_epunk", SP_m_nyc_epunk},
|
||
|
{"m_nyc_mswat", SP_m_nyc_mswat},
|
||
|
{"m_nyc_mswatleader", SP_m_nyc_mswatleader},
|
||
|
{"m_nyc_estockbroker", SP_m_nyc_estockbroker},
|
||
|
{"m_nyc_ebum", SP_m_nyc_ebum},
|
||
|
{"m_nyc_etourist", SP_m_nyc_etourist},
|
||
|
{"m_nyc_mpolitician", SP_m_nyc_mpolitician},
|
||
|
{"m_nyc_fwoman", SP_m_nyc_fwoman},
|
||
|
|
||
|
|
||
|
{"script_runner", SP_script_runner},
|
||
|
|
||
|
{"spawner", SP_spawner},
|
||
|
{"spawner_monster", SP_spawner_monster},
|
||
|
{"spawner_boosterpack", SP_spawner_boosterpack},
|
||
|
|
||
|
// worldspawn
|
||
|
{"worldspawn", SP_worldspawn},
|
||
|
|
||
|
// testing stuff
|
||
|
{"ghoul_model", SP_ghoul_model},
|
||
|
{"test_model", SP_test_model},
|
||
|
{"test_rj", SP_test_rj},
|
||
|
|
||
|
|
||
|
{NULL, NULL}
|
||
|
};
|
||
|
|
||
|
field_t fields[] =
|
||
|
{
|
||
|
{"classname", FOFS(classname), F_STRING},
|
||
|
{"origin", FOFS(s.origin), F_VECTOR},
|
||
|
{"model", FOFS(model), F_STRING},
|
||
|
{"spawnflags", FOFS(spawnflags), F_INT},
|
||
|
{"speed", FOFS(speed), F_FLOAT},
|
||
|
{"accel", FOFS(accel), F_FLOAT},
|
||
|
{"decel", FOFS(decel), F_FLOAT},
|
||
|
{"target", FOFS(target), F_STRING},
|
||
|
{"targetname", FOFS(targetname), F_STRING},
|
||
|
{"scripttarget", FOFS(scripttarget), F_STRING},
|
||
|
{"pathtarget", FOFS(pathtarget), F_STRING},
|
||
|
{"deathtarget", FOFS(deathtarget), F_STRING},
|
||
|
{"killtarget", FOFS(killtarget), F_STRING},
|
||
|
{"killfacing", FOFS(killfacing), F_STRING},
|
||
|
{"combattarget", FOFS(combattarget), F_STRING},
|
||
|
{"soundname", FOFS(soundName), F_STRING},
|
||
|
{"spawn1", FOFS(spawn1), F_STRING},
|
||
|
{"spawn2", FOFS(spawn2), F_STRING},
|
||
|
{"spawn3", FOFS(spawn3), F_STRING},
|
||
|
{"message", FOFS(message), F_STRING},
|
||
|
{"sp_message", FOFS(sp_message), F_INT},
|
||
|
{"team", FOFS(team), F_STRING},
|
||
|
{"wait", FOFS(wait), F_FLOAT},
|
||
|
{"delay", FOFS(delay), F_FLOAT},
|
||
|
{"random", FOFS(random), F_FLOAT},
|
||
|
{"style", FOFS(style), F_INT},
|
||
|
{"count", FOFS(count), F_INT},
|
||
|
{"health", FOFS(health), F_INT},
|
||
|
{"sounds", FOFS(sounds), F_INT},
|
||
|
{"light", 0, F_IGNORE},
|
||
|
{"dmg", FOFS(dmg), F_INT},
|
||
|
{"angles", FOFS(s.angles), F_VECTOR},
|
||
|
{"angle", FOFS(s.angles), F_ANGLEHACK},
|
||
|
{"mass", FOFS(mass), F_INT},
|
||
|
{"volume", FOFS(volume), F_FLOAT},
|
||
|
{"attenuation", FOFS(attenuation), F_FLOAT},
|
||
|
{"map", FOFS(map), F_STRING},
|
||
|
{"skin",FOFS(s.skinnum), F_INT},
|
||
|
{"alertradius", FOFS(alertRadius), F_FLOAT},
|
||
|
{"personality", FOFS(personality), F_INT},
|
||
|
|
||
|
// temp spawn vars -- only valid when the spawn function is called
|
||
|
{"lip", STOFS(lip), F_INT, FFL_SPAWNTEMP},
|
||
|
{"distance", STOFS(distance), F_INT, FFL_SPAWNTEMP},
|
||
|
{"height", STOFS(height), F_INT, FFL_SPAWNTEMP},
|
||
|
{"noise", STOFS(noise), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"pausetime", STOFS(pausetime), F_FLOAT, FFL_SPAWNTEMP},
|
||
|
{"item", STOFS(item), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"gravity", STOFS(gravity), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"sky", STOFS(sky), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"skyrotate", STOFS(skyrotate), F_FLOAT, FFL_SPAWNTEMP},
|
||
|
{"skyaxis", STOFS(skyaxis), F_VECTOR, FFL_SPAWNTEMP},
|
||
|
{"terrainset", STOFS(terrainSet), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"musicSet", STOFS(musicSet), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"color", STOFS(color), F_VECTOR, FFL_SPAWNTEMP},
|
||
|
{"endpoint", STOFS(endpoint), F_VECTOR, FFL_SPAWNTEMP},
|
||
|
{"minyaw", STOFS(minyaw), F_FLOAT, FFL_SPAWNTEMP},
|
||
|
{"maxyaw", STOFS(maxyaw), F_FLOAT, FFL_SPAWNTEMP},
|
||
|
{"minpitch", STOFS(minpitch), F_FLOAT, FFL_SPAWNTEMP},
|
||
|
{"maxpitch", STOFS(maxpitch), F_FLOAT, FFL_SPAWNTEMP},
|
||
|
{"nextmap", STOFS(nextmap), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"script", STOFS(script), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"killedvalue", STOFS(killedValue), F_INT, FFL_SPAWNTEMP},
|
||
|
{"survivalvalue", STOFS(survivalValue), F_INT, FFL_SPAWNTEMP},
|
||
|
{"material", STOFS(material), F_INT, FFL_SPAWNTEMP},
|
||
|
{"scale", STOFS(scale), F_FLOAT, FFL_SPAWNTEMP},
|
||
|
{"merctype", STOFS(merctype), F_INT, FFL_SPAWNTEMP},
|
||
|
{"mercnum", STOFS(mercnum), F_INT, FFL_SPAWNTEMP},
|
||
|
{"waitaction1", STOFS(waitAction1), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"waitaction2", STOFS(waitAction2), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"waitaction3", STOFS(waitAction3), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"waitaction4", STOFS(waitAction4), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"waitaction5", STOFS(waitAction5), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"waitaction6", STOFS(waitAction6), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"moveaction", STOFS(moveAction), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"screeneffect", STOFS(screeneffect), F_INT, FFL_SPAWNTEMP},
|
||
|
{"spawnfrequency", STOFS(spawnfrequency), F_FLOAT, FFL_SPAWNTEMP},
|
||
|
{"parm1", STOFS(parms[0]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"parm2", STOFS(parms[1]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"parm3", STOFS(parms[2]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"parm4", STOFS(parms[3]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"parm5", STOFS(parms[4]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"parm6", STOFS(parms[5]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"parm7", STOFS(parms[6]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"parm8", STOFS(parms[7]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"parm9", STOFS(parms[8]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"parm10", STOFS(parms[9]), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"surfacetype", STOFS(surfaceType), F_INT, FFL_SPAWNTEMP},
|
||
|
{"noweapons", STOFS(noweapons), F_INT, FFL_SPAWNTEMP},
|
||
|
{"setweapons", STOFS(setweapons), F_INT, FFL_SPAWNTEMP},
|
||
|
{"maxDeadHostages", STOFS(maxDeadHostages), F_INT, FFL_SPAWNTEMP},
|
||
|
{"ambientSet", STOFS(ambientSet), F_STRING, FFL_SPAWNTEMP},
|
||
|
{"startmusic", STOFS(startmusic), F_INT, FFL_SPAWNTEMP},
|
||
|
{"forceHUD", STOFS(forceHUD), F_INT, FFL_SPAWNTEMP},
|
||
|
{"weaponsAvailable", STOFS(weaponsAvailable), F_INT, FFL_SPAWNTEMP},
|
||
|
{"ainame", STOFS(ai_name), F_STRING, FFL_SPAWNTEMP},
|
||
|
|
||
|
// BSP dummy options
|
||
|
{"distcull", STOFS(dummy), F_INT, FFL_SPAWNTEMP},
|
||
|
{"chopsky", STOFS(dummy), F_INT, FFL_SPAWNTEMP},
|
||
|
|
||
|
{NULL, 0, F_INT}
|
||
|
};
|
||
|
|
||
|
typedef spawn_t *spawnPtr;
|
||
|
|
||
|
spawnPtr spawnLists[] =
|
||
|
{
|
||
|
environSpawns,
|
||
|
funcSpawns,
|
||
|
triggerSpawns,
|
||
|
targetSpawns,
|
||
|
lightSpawns,
|
||
|
bosniaSpawns,
|
||
|
castleSpawns,
|
||
|
iraqSpawns,
|
||
|
genericSpawns,
|
||
|
newyorkSpawns,
|
||
|
siberiaSpawns,
|
||
|
tokyoSpawns,
|
||
|
ugandaSpawns,
|
||
|
dmSpawns,
|
||
|
spawns,
|
||
|
NULL
|
||
|
};
|
||
|
|
||
|
#if TIME_ENTS
|
||
|
|
||
|
void ClearTimings(bool DoCount)
|
||
|
{
|
||
|
spawnPtr *table;
|
||
|
spawn_t *s;
|
||
|
|
||
|
for(table = spawnLists; *table; table++)
|
||
|
{
|
||
|
for (s=*table; s->name ; s++)
|
||
|
{
|
||
|
s->time_used = 0;
|
||
|
if (DoCount)
|
||
|
{
|
||
|
s->count = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PrintTimings(void)
|
||
|
{
|
||
|
spawnPtr *table;
|
||
|
spawn_t *s;
|
||
|
char temp[1024];
|
||
|
unsigned long total=0;
|
||
|
multimap<long,pair<char *,int> > sortit;
|
||
|
|
||
|
for(table = spawnLists; *table; table++)
|
||
|
{
|
||
|
for (s=*table; s->name ; s++)
|
||
|
{
|
||
|
if (s->time_used)
|
||
|
{
|
||
|
sortit.insert(pair<long,pair<char *,int> >(-s->time_used,pair<char *,int>(s->name, s->count)));
|
||
|
total+=s->time_used;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (total)
|
||
|
{
|
||
|
OutputDebugString("Entity Timing Report\n");
|
||
|
OutputDebugString("================================\n");
|
||
|
multimap<long,pair<char *,int> >::iterator i;
|
||
|
for (i=sortit.begin();i!=sortit.end();i++)
|
||
|
{
|
||
|
float p=100.0f*float(-(*i).first)/float(total);
|
||
|
sprintf(temp,"%4.1f\t%3d\t%s\n",p,(*i).second.second,(*i).second.first);
|
||
|
OutputDebugString(temp);
|
||
|
}
|
||
|
OutputDebugString("================================\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
===============
|
||
|
ED_CallSpawn
|
||
|
|
||
|
Finds the spawn function for the entity and calls it
|
||
|
===============
|
||
|
*/
|
||
|
void ED_CallSpawn (edict_t *ent)
|
||
|
{
|
||
|
spawnPtr *table;
|
||
|
spawn_t *s;
|
||
|
Pickup *pickup = NULL;
|
||
|
|
||
|
if (!ent->classname)
|
||
|
{
|
||
|
gi.dprintf ("ED_CallSpawn: NULL classname\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (ent->classname[0] == '_')
|
||
|
{
|
||
|
G_FreeEdict(ent);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Don't spawn fluff objects.
|
||
|
if (gl_pictip->value)
|
||
|
{
|
||
|
if ((strncmp (ent->classname, "misc_", 5)==0) && (ent->spawnflags & SF_FLUFF))
|
||
|
{
|
||
|
G_FreeEdict(ent);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check item spawn functions.
|
||
|
if (pickup = thePickupList.GetPickupFromEdict(ent))
|
||
|
{
|
||
|
if (dm->checkItemSpawn(ent, &pickup))
|
||
|
{
|
||
|
I_Spawn(ent, pickup);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Check normal spawn functions.
|
||
|
for(table = spawnLists; *table; table++)
|
||
|
{
|
||
|
for (s=*table; s->name ; s++)
|
||
|
{
|
||
|
if (!strcmp(s->name, ent->classname))
|
||
|
{
|
||
|
// Found it.
|
||
|
s->spawn (ent);
|
||
|
#if TIME_ENTS
|
||
|
ent->owner_spawn = s;
|
||
|
s->count++;
|
||
|
#endif
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// No spawn func == no exist.
|
||
|
gi.dprintf ("%s doesn't have a spawn function\n", ent->classname);
|
||
|
G_FreeEdict(ent);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============
|
||
|
ED_NewString
|
||
|
=============
|
||
|
*/
|
||
|
char *ED_NewString (char *string)
|
||
|
{
|
||
|
char *newb, *new_p;
|
||
|
int i,l;
|
||
|
|
||
|
l = strlen(string) + 1;
|
||
|
|
||
|
newb = (char*)gi.TagMalloc (l, TAG_LEVEL);
|
||
|
|
||
|
new_p = newb;
|
||
|
|
||
|
for (i=0 ; i< l ; i++)
|
||
|
{
|
||
|
if (string[i] == '\\' && i < l-1)
|
||
|
{
|
||
|
i++;
|
||
|
if (string[i] == 'n')
|
||
|
*new_p++ = '\n';
|
||
|
else
|
||
|
*new_p++ = '\\';
|
||
|
}
|
||
|
else
|
||
|
*new_p++ = string[i];
|
||
|
}
|
||
|
|
||
|
return newb;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===============
|
||
|
ED_ParseField
|
||
|
|
||
|
Takes a key/value pair and sets the binary values
|
||
|
in an edict
|
||
|
===============
|
||
|
*/
|
||
|
void ED_ParseField (char *key, char *value, edict_t *ent)
|
||
|
{
|
||
|
field_t *f;
|
||
|
byte *b;
|
||
|
float v;
|
||
|
vec3_t vec;
|
||
|
|
||
|
for (f=fields ; f->name ; f++)
|
||
|
{
|
||
|
if (!stricmp(f->name, key))
|
||
|
{ // found it
|
||
|
if (f->flags & FFL_SPAWNTEMP)
|
||
|
b = (byte *)&st;
|
||
|
else
|
||
|
b = (byte *)ent;
|
||
|
|
||
|
switch (f->type)
|
||
|
{
|
||
|
case F_STRING:
|
||
|
*(char **)(b+f->ofs) = ED_NewString (value);
|
||
|
break;
|
||
|
case F_VECTOR:
|
||
|
sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]);
|
||
|
((float *)(b+f->ofs))[0] = vec[0];
|
||
|
((float *)(b+f->ofs))[1] = vec[1];
|
||
|
((float *)(b+f->ofs))[2] = vec[2];
|
||
|
break;
|
||
|
case F_INT:
|
||
|
*(int *)(b+f->ofs) = atoi(value);
|
||
|
break;
|
||
|
case F_SHORT:
|
||
|
*(short *)(b+f->ofs) = (short)atoi(value);
|
||
|
break;
|
||
|
case F_FLOAT:
|
||
|
*(float *)(b+f->ofs) = atof(value);
|
||
|
break;
|
||
|
case F_ANGLEHACK:
|
||
|
v = atof(value);
|
||
|
((float *)(b+f->ofs))[0] = 0;
|
||
|
((float *)(b+f->ofs))[1] = v;
|
||
|
((float *)(b+f->ofs))[2] = 0;
|
||
|
break;
|
||
|
case F_IGNORE:
|
||
|
break;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
gi.dprintf ("%s is not a field\n", key);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
====================
|
||
|
ED_ParseEdict
|
||
|
|
||
|
Parses an edict out of the given string, returning the new position
|
||
|
ed should be a properly initialized empty edict.
|
||
|
====================
|
||
|
*/
|
||
|
char *ED_ParseEdict (char *data, edict_t *ent)
|
||
|
{
|
||
|
qboolean init;
|
||
|
char keyname[256];
|
||
|
char *com_token;
|
||
|
|
||
|
init = false;
|
||
|
memset (&st, 0, sizeof(st));
|
||
|
|
||
|
// go through all the dictionary pairs
|
||
|
while (1)
|
||
|
{
|
||
|
// parse key
|
||
|
com_token = COM_Parse (&data);
|
||
|
if (com_token[0] == '}')
|
||
|
break;
|
||
|
if (!data)
|
||
|
gi.error ("ED_ParseEntity: EOF without closing brace");
|
||
|
|
||
|
strncpy (keyname, com_token, sizeof(keyname)-1);
|
||
|
|
||
|
// parse value
|
||
|
com_token = COM_Parse (&data);
|
||
|
if (!data)
|
||
|
gi.error ("ED_ParseEntity: EOF without closing brace");
|
||
|
|
||
|
if (com_token[0] == '}')
|
||
|
gi.error ("ED_ParseEntity: closing brace without data");
|
||
|
|
||
|
init = true;
|
||
|
|
||
|
// keynames with a leading underscore are used for utility comments,
|
||
|
// and are immediately discarded by quake
|
||
|
if (keyname[0] == '_')
|
||
|
continue;
|
||
|
|
||
|
ED_ParseField (keyname, com_token, ent);
|
||
|
}
|
||
|
|
||
|
if (!init)
|
||
|
memset (ent, 0, sizeof(*ent));
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
G_FindTeams
|
||
|
|
||
|
Chain together all entities with a matching team field.
|
||
|
|
||
|
All but the first will have the FL_TEAMSLAVE flag set.
|
||
|
All but the last will have the teamchain field set to the next one
|
||
|
================
|
||
|
*/
|
||
|
void G_FindTeams (void)
|
||
|
{
|
||
|
edict_t *e, *e2, *chain;
|
||
|
int i, j;
|
||
|
int c, c2;
|
||
|
|
||
|
c = 0;
|
||
|
c2 = 0;
|
||
|
for (i=1, e=g_edicts+i ; i < globals.num_edicts ; i++,e++)
|
||
|
{
|
||
|
if (!e->inuse)
|
||
|
continue;
|
||
|
if (!e->team)
|
||
|
continue;
|
||
|
if (e->flags & FL_TEAMSLAVE)
|
||
|
continue;
|
||
|
chain = e;
|
||
|
e->teammaster = e;
|
||
|
c++;
|
||
|
c2++;
|
||
|
for (j=i+1, e2=e+1 ; j < globals.num_edicts ; j++,e2++)
|
||
|
{
|
||
|
if (!e2->inuse)
|
||
|
continue;
|
||
|
if (!e2->team)
|
||
|
continue;
|
||
|
if (e2->flags & FL_TEAMSLAVE)
|
||
|
continue;
|
||
|
if (!strcmp(e->team, e2->team))
|
||
|
{
|
||
|
c2++;
|
||
|
chain->teamchain = e2;
|
||
|
e2->teammaster = e;
|
||
|
chain = e2;
|
||
|
e2->flags |= FL_TEAMSLAVE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
gi.dprintf ("%i teams with %i entities\n", c, c2);
|
||
|
}
|
||
|
|
||
|
void HackPrecacheLevelSounds(void);
|
||
|
|
||
|
|
||
|
void RegisterCommonStringPackets(void)
|
||
|
{
|
||
|
gi.SP_Register("items");
|
||
|
gi.SP_Register("weapons");
|
||
|
gi.SP_Register("general");
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
==============
|
||
|
SpawnEntities
|
||
|
|
||
|
Creates a server's entity / program execution context by
|
||
|
parsing textual entity definitions out of an ent file.
|
||
|
==============
|
||
|
*/
|
||
|
|
||
|
edict_t* WorldSpawnScriptRunner;
|
||
|
extern float walldamagetime; // rjr: yeah, yucky extern here, but reserving real words for what I feel...
|
||
|
|
||
|
void SpawnEntities (char *mapname, char *entities, char *spawnpoint)
|
||
|
{
|
||
|
edict_t *ent;
|
||
|
int inhibit;
|
||
|
char *com_token;
|
||
|
int i;
|
||
|
|
||
|
WorldSpawnScriptRunner = NULL;
|
||
|
|
||
|
PreserveClientData ();
|
||
|
|
||
|
ShutdownScripts();
|
||
|
gi.FreeTags (TAG_LEVEL);
|
||
|
|
||
|
memset (&level, 0, sizeof(level));
|
||
|
G_FreeAllEdicts();
|
||
|
|
||
|
gmonster.Init();
|
||
|
|
||
|
strncpy (level.mapname, mapname, sizeof(level.mapname)-1);
|
||
|
strncpy (game.spawnpoint, spawnpoint, sizeof(game.spawnpoint)-1);
|
||
|
|
||
|
// set client fields on player ents
|
||
|
for (i=0 ; i<game.maxclients ; i++)
|
||
|
{
|
||
|
g_edicts[i+1].health = 100;
|
||
|
g_edicts[i+1].client = game.clients + i;
|
||
|
}
|
||
|
|
||
|
ent = NULL;
|
||
|
inhibit = 0;
|
||
|
game.cinematicfreeze = 0;
|
||
|
|
||
|
gi.Update(0.05f, true);
|
||
|
//cache all the ghoul stuff we're going to need for this level
|
||
|
game_ghoul.LevelPrecache();
|
||
|
|
||
|
gi.Update(0.075f, true);
|
||
|
W_InitWorldWeaponModels();
|
||
|
|
||
|
// init list of client sfx and debris models needed for entities
|
||
|
InitEntSoundCaching();
|
||
|
|
||
|
InitEntMetalSoundCaching(); // this is necessary because the routine that is supposed to read in textures isn't
|
||
|
// properly reading them in on ladders. Since I doubt that routine is going to be
|
||
|
// fixed (which is the proper solution), I poop this here.
|
||
|
|
||
|
InitEntDebrisCaching();
|
||
|
|
||
|
FX_Init();
|
||
|
InitDeathmatchSystem();
|
||
|
|
||
|
gi.Update(0.1f, true);
|
||
|
RegisterCommonStringPackets();
|
||
|
|
||
|
aiPoints.load();
|
||
|
|
||
|
gi.Update(0.15f, true);
|
||
|
PB_PrecacheAllPlayerModels();
|
||
|
|
||
|
// 12/27/99 kef -- just need to call this sometime before we start making calls to ED_CallSpawn. it inits
|
||
|
//our global list of pickup items. see CWeaponInfo.h.
|
||
|
thePickupList.PreSpawnInit();
|
||
|
|
||
|
#if TIME_ENTS
|
||
|
ClearTimings(true);
|
||
|
#endif // _DEBUG
|
||
|
|
||
|
fs_createpak = gi.cvar("fs_createpak", "0", 0);
|
||
|
if (fs_createpak && fs_createpak->value)
|
||
|
{
|
||
|
ai_loadAllBolts=1;
|
||
|
}
|
||
|
// parse ents
|
||
|
while (1)
|
||
|
{
|
||
|
// parse the opening brace
|
||
|
com_token = COM_Parse (&entities);
|
||
|
if (!entities)
|
||
|
break;
|
||
|
if (com_token[0] != '{')
|
||
|
gi.error ("ED_LoadFromFile: found %s when expecting {",com_token);
|
||
|
|
||
|
if (!ent)
|
||
|
ent = g_edicts;
|
||
|
else
|
||
|
ent = G_Spawn ();
|
||
|
entities = ED_ParseEdict (entities, ent);
|
||
|
|
||
|
// remove things (except the world) from different skill levels or deathmatch
|
||
|
if (ent != g_edicts)
|
||
|
{
|
||
|
if (dm->isDM())
|
||
|
{
|
||
|
if ( ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH )
|
||
|
{
|
||
|
G_FreeEdict (ent);
|
||
|
inhibit++;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if ((((game.playerSkills.getEnemyValue() == 0) || (game.playerSkills.getEnemyValue() == 1)) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) ||
|
||
|
(((game.playerSkills.getEnemyValue() == 2)) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) ||
|
||
|
(((game.playerSkills.getEnemyValue() == 3) || (game.playerSkills.getEnemyValue() == 4)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)))
|
||
|
{
|
||
|
G_FreeEdict (ent);
|
||
|
inhibit++;
|
||
|
continue;
|
||
|
}
|
||
|
// 12/27/99 kef -- here is where we should remove fluff objects...currently done in ED_CallSpawn, I think
|
||
|
}
|
||
|
|
||
|
|
||
|
ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY|SPAWNFLAG_NOT_MEDIUM|SPAWNFLAG_NOT_HARD|SPAWNFLAG_NOT_DEATHMATCH);
|
||
|
// ent->spawnflags &= ~(SPAWNFLAG_NOT_DEATHMATCH);
|
||
|
}
|
||
|
|
||
|
// put skill level item check here -- dk wubba
|
||
|
|
||
|
ED_CallSpawn (ent);
|
||
|
// cache necessary debris models based on ent's material
|
||
|
CacheEntDebrisAndSounds(ent);
|
||
|
}
|
||
|
|
||
|
// 1/31/00 kef -- just need to call this sometime after spawning all pickups. see CWeaponInfo.h.
|
||
|
thePickupList.PostSpawnInit();
|
||
|
|
||
|
|
||
|
ai_loadAllBolts=0;
|
||
|
|
||
|
// Gametype specific initialisation.
|
||
|
|
||
|
dm->levelInit();
|
||
|
|
||
|
gi.Update(0.25f, true);
|
||
|
CacheAllDebris();
|
||
|
CacheAllSounds();
|
||
|
CacheAllWallEffects();
|
||
|
|
||
|
gi.dprintf ("%i entities inhibited\n", inhibit);
|
||
|
|
||
|
G_FindTeams ();
|
||
|
|
||
|
PlayerTrail_Init ();
|
||
|
|
||
|
gi.Update(0.28f, true);
|
||
|
SndInitWorldSounds();
|
||
|
|
||
|
CalculatePlayerEntryWeapons(&level.weaponsAvailable);
|
||
|
|
||
|
gi.Update(0.30f, true);
|
||
|
|
||
|
// Clear out all the (now invalid) pointers to the weapon ghoul objects.
|
||
|
pe->UncacheViewWeaponModels();
|
||
|
|
||
|
// level.weaponsAvailable - this will take care of everything enemies are
|
||
|
// carrying / items lying around - players come later.
|
||
|
pe->PrecacheViewWeaponModels(level.weaponsAvailable);
|
||
|
|
||
|
gi.CreateGhoulConfigStrings();
|
||
|
gi.Update(0.33f, true);
|
||
|
|
||
|
walldamagetime = -999999.0;
|
||
|
}
|
||
|
|
||
|
|
||
|
//===================================================================
|
||
|
|
||
|
void PrecacheSurfaceTypes(void)
|
||
|
{
|
||
|
byte List[256], count;
|
||
|
|
||
|
count = gi.SurfaceTypeList(List, sizeof(List));
|
||
|
|
||
|
while(count)
|
||
|
{
|
||
|
count--;
|
||
|
|
||
|
switch(List[count])
|
||
|
{
|
||
|
case SURF_DEFAULT:
|
||
|
break;
|
||
|
case SURF_METAL:
|
||
|
break;
|
||
|
case SURF_SAND_YELLOW:
|
||
|
break;
|
||
|
case SURF_SAND_WHITE:
|
||
|
break;
|
||
|
case SURF_SAND_LBROWN:
|
||
|
break;
|
||
|
case SURF_SAND_DBROWN:
|
||
|
break;
|
||
|
|
||
|
case SURF_GRAVEL_GREY:
|
||
|
break;
|
||
|
case SURF_GRAVEL_DBROWN:
|
||
|
break;
|
||
|
case SURF_GRAVEL_LBROWN:
|
||
|
break;
|
||
|
|
||
|
case SURF_SNOW:
|
||
|
break;
|
||
|
|
||
|
case SURF_LIQUID_BLUE:
|
||
|
break;
|
||
|
case SURF_LIQUID_GREEN:
|
||
|
break;
|
||
|
case SURF_LIQUID_ORANGE:
|
||
|
break;
|
||
|
case SURF_LIQUID_BROWN:
|
||
|
break;
|
||
|
|
||
|
case SURF_WOOD_LBROWN:
|
||
|
break;
|
||
|
case SURF_WOOD_DBROWN:
|
||
|
break;
|
||
|
case SURF_WOOD_LGREY:
|
||
|
break;
|
||
|
|
||
|
case SURF_STONE_LGREY:
|
||
|
break;
|
||
|
case SURF_STONE_DGREY:
|
||
|
break;
|
||
|
case SURF_STONE_LBROWN:
|
||
|
break;
|
||
|
case SURF_STONE_DBROWN:
|
||
|
break;
|
||
|
case SURF_STONE_WHITE:
|
||
|
break;
|
||
|
case SURF_STONE_GREEN:
|
||
|
break;
|
||
|
case SURF_STONE_RED:
|
||
|
break;
|
||
|
case SURF_STONE_BLACK:
|
||
|
break;
|
||
|
|
||
|
case SURF_GRASS_GREEN:
|
||
|
break;
|
||
|
case SURF_GRASS_BROWN:
|
||
|
break;
|
||
|
|
||
|
case SURF_LIQUID_RED:
|
||
|
break;
|
||
|
|
||
|
case SURF_METAL_STEAM:
|
||
|
break;
|
||
|
case SURF_METAL_WATERJET:
|
||
|
break;
|
||
|
case SURF_METAL_OILSPURT:
|
||
|
break;
|
||
|
case SURF_METAL_CHEMSPURT:
|
||
|
break;
|
||
|
case SURF_METAL_COMPUTERS:
|
||
|
break;
|
||
|
|
||
|
case SURF_SNOW_LBROWN:
|
||
|
break;
|
||
|
case SURF_SNOW_GREY:
|
||
|
break;
|
||
|
case SURF_BLOOD:
|
||
|
break;
|
||
|
case SURF_LIQUID_BLACK:
|
||
|
break;
|
||
|
case SURF_GLASS:
|
||
|
break;
|
||
|
case SURF_GLASS_COMPUTER:
|
||
|
break;
|
||
|
case SURF_SODAMACHINE:
|
||
|
break;
|
||
|
case SURF_PAPERWALL:
|
||
|
break;
|
||
|
case SURF_NEWSPAPER_DAMAGE:
|
||
|
break;
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PrecacheSpawningEnemies(edict_t *ent)
|
||
|
{
|
||
|
edict_t *newGuy;
|
||
|
char *curSpawn;
|
||
|
int oldLoadAllBolts=ai_loadAllBolts;
|
||
|
|
||
|
ai_loadAllBolts = 1;
|
||
|
|
||
|
for(int i = 0; i < 3; i++)
|
||
|
{
|
||
|
switch(i)
|
||
|
{
|
||
|
case 0:
|
||
|
curSpawn = ent->spawn1;
|
||
|
break;
|
||
|
case 1:
|
||
|
curSpawn = ent->spawn2;
|
||
|
break;
|
||
|
case 2:
|
||
|
curSpawn = ent->spawn3;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(!curSpawn)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if(!strcmp(curSpawn, ""))
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
newGuy = G_Spawn();
|
||
|
|
||
|
newGuy->classname = curSpawn;
|
||
|
ED_CallSpawn (newGuy);
|
||
|
G_FreeEdict(newGuy);
|
||
|
}
|
||
|
ai_loadAllBolts = oldLoadAllBolts;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*QUAKED worldspawn (0 0 0) ?
|
||
|
|
||
|
Only used for the world.
|
||
|
"sky" environment map name
|
||
|
"skyaxis" vector axis for rotating sky
|
||
|
"skyrotate" speed of rotation in degrees/second
|
||
|
"sounds" music cd track number
|
||
|
"gravity" 800 is default gravity
|
||
|
"message" text to print at user logon
|
||
|
"musicset" filename of the musicset for this level
|
||
|
"terrainset" filename of the terrainset for this level
|
||
|
"distcull" sets the maximum distance for vis (100 is good)
|
||
|
"chop" sets the surface patch size for lighting
|
||
|
"chopsky" sets the surface patch size for sky
|
||
|
"chopwarp" sets the surface patch size for warp surfaces
|
||
|
"script" filename of a script to run at map loadtime
|
||
|
"raffel" set this to 1 if you want your map to run slower
|
||
|
"jersey" set this to 1 to make all enemies talk funny
|
||
|
"screeneffect" sets the style of general screen effect
|
||
|
"spawn1"
|
||
|
"spawn2"
|
||
|
"spawn3" types of guys that will be spawned into the world from combat
|
||
|
"spawnfrequency" 0..1 (from no guys to very likely) - default is 0
|
||
|
"noweapons" for levels like the armory where the player gets no weapons. set to 1 for no weapons.
|
||
|
"setweapons" set the player's inventory. For TRN1 and TSR1 use 1. overridden by noweapons.
|
||
|
"maxDeadHostages" number of dead hostages allowed before you fail this mission
|
||
|
"ambientset" filename of the ambient set for this level
|
||
|
"startmusic" set if you want to force a specific song at startup
|
||
|
"forceHUD" set this for the tutorial level. draws HUD even with no weapon.
|
||
|
"weaponsAvailable" magic number for precaching weapons. ask a programmer. (68 for tutorial level)
|
||
|
"ainame" over-ride for per-level enemy set
|
||
|
*/
|
||
|
|
||
|
void SP_worldspawn (edict_t *ent)
|
||
|
{
|
||
|
int nWeapons = -1;
|
||
|
|
||
|
ent->movetype = MOVETYPE_PUSH;
|
||
|
ent->solid = SOLID_BSP;
|
||
|
ent->inuse = true; // since the world doesn't use G_Spawn()
|
||
|
ent->s.modelindex = 1; // world model is always index 1
|
||
|
|
||
|
level.spawnFrequency = st.spawnfrequency;
|
||
|
level.playerLoudness = 0;//defaults to this
|
||
|
level.spawnRushTime = -999;
|
||
|
level.spawnSoundTime = 0;
|
||
|
level.lullTime = 0;
|
||
|
level.lastSpawn = 0;
|
||
|
level.weaponsAvailable = 0;
|
||
|
level.lastEnemyKill = 0;
|
||
|
memset(level.clearedNodes, 0, MAX_NODES);
|
||
|
if (st.ai_name)
|
||
|
{
|
||
|
strcpy(level_ai_name, st.ai_name);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
level_ai_name[0] = 0;
|
||
|
}
|
||
|
|
||
|
level.forceHUD = st.forceHUD;
|
||
|
level.weaponsAvailable = st.weaponsAvailable;
|
||
|
if (st.noweapons)
|
||
|
{
|
||
|
nWeapons = 0;
|
||
|
}
|
||
|
else if (st.setweapons)
|
||
|
{
|
||
|
nWeapons = st.setweapons;
|
||
|
}
|
||
|
if (nWeapons >= 0)
|
||
|
{
|
||
|
// oh my gosh this is so lame
|
||
|
if (!ent->objInfo)
|
||
|
{ // create a baseObjInfo_c for our edict
|
||
|
baseObjInfo_c *newInfo = new baseObjInfo_c(ent);
|
||
|
|
||
|
// somewhere in the newInfo struct note the fact that this is a "no weapons" level
|
||
|
if (ent->objInfo = newInfo)
|
||
|
{
|
||
|
objFlipInfo_c *pFlipInfo = (objFlipInfo_c*)newInfo->GetInfo(OIT_FLIP);
|
||
|
switch(nWeapons)
|
||
|
{
|
||
|
case 0:
|
||
|
pFlipInfo->radius = -1; // tried to make this lamer. couldn't.
|
||
|
break;
|
||
|
case 1:
|
||
|
pFlipInfo->radius = -2;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (st.maxDeadHostages)
|
||
|
{ // how many hostages are allowed to die before you fail this mission
|
||
|
level.maxDeadHostages = st.maxDeadHostages;
|
||
|
}
|
||
|
else
|
||
|
{ // if there's no value here, save a good flag-value
|
||
|
level.maxDeadHostages = -1;
|
||
|
}
|
||
|
|
||
|
// init the status of our countdown timer (if there isn't one in this level, who cares?)
|
||
|
level.countdownEnded = 0;
|
||
|
// just starting the mission...no status yet
|
||
|
level.missionStatus = MISSION_NONE;
|
||
|
|
||
|
//---------------
|
||
|
|
||
|
// reserve some spots for dead player bodies for coop / deathmatch
|
||
|
InitBodyQue ();
|
||
|
|
||
|
// set configstrings for items
|
||
|
// SetItemNames ();
|
||
|
|
||
|
if (st.nextmap)
|
||
|
strcpy (level.nextmap, st.nextmap);
|
||
|
|
||
|
// make some data visible to the server
|
||
|
|
||
|
if (ent->message && ent->message[0])
|
||
|
{
|
||
|
gi.configstring (CS_NAME, ent->message);
|
||
|
strncpy (level.level_name, ent->message, sizeof(level.level_name));
|
||
|
}
|
||
|
else
|
||
|
strncpy (level.level_name, level.mapname, sizeof(level.level_name));
|
||
|
|
||
|
if (st.sky && st.sky[0])
|
||
|
gi.configstring (CS_SKY, st.sky);
|
||
|
else
|
||
|
gi.configstring (CS_SKY, "none");
|
||
|
|
||
|
if (st.terrainSet && st.terrainSet[0])
|
||
|
{
|
||
|
gi.configstring (CS_TERRAINNAME, va("%s", st.terrainSet));
|
||
|
}
|
||
|
|
||
|
gi.configstring (CS_SKYROTATE, va("%f", st.skyrotate) );
|
||
|
|
||
|
gi.configstring (CS_SKYAXIS, va("%f %f %f",
|
||
|
st.skyaxis[0], st.skyaxis[1], st.skyaxis[2]) );
|
||
|
|
||
|
gi.configstring (CS_CDTRACK, va("%i", ent->sounds) );
|
||
|
|
||
|
gi.configstring (CS_MAXCLIENTS, va("%i", (int)(maxclients->value) ) );
|
||
|
|
||
|
gi.configstring (CS_SCREENEFFECT, va("%i", (int)(st.screeneffect) ) );
|
||
|
|
||
|
if (st.musicSet && st.musicSet[0])
|
||
|
{
|
||
|
gi.configstring (CS_MUSICSET, va("%s", st.musicSet) );
|
||
|
}
|
||
|
|
||
|
// set ambient sound set name.
|
||
|
// if its blank, then force it to "sounds/sound.amb"
|
||
|
if (st.ambientSet && st.ambientSet[0])
|
||
|
{
|
||
|
gi.configstring (CS_AMBSET, va("%s", st.ambientSet));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gi.configstring (CS_AMBSET, "sound/sound.ams");
|
||
|
}
|
||
|
|
||
|
if(st.startmusic)
|
||
|
{
|
||
|
level.baseSong = st.startmusic;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
level.baseSong = 0;
|
||
|
}
|
||
|
|
||
|
if(st.script)
|
||
|
{
|
||
|
/* edict_t *runner;
|
||
|
|
||
|
runner =
|
||
|
runner->classname = "script_runner";
|
||
|
|
||
|
ED_CallSpawn(runner);
|
||
|
|
||
|
runner->use(runner, runner, runner);
|
||
|
*/
|
||
|
|
||
|
WorldSpawnScriptRunner = G_Spawn();
|
||
|
WorldSpawnScriptRunner->classname = "script_runner";
|
||
|
ED_CallSpawn(WorldSpawnScriptRunner);
|
||
|
}
|
||
|
|
||
|
//---------------
|
||
|
|
||
|
|
||
|
// help icon for statusbar
|
||
|
// level.pic_health = gi.imageindex ("pics/status/i_health");
|
||
|
level.alertedStatus = 0;
|
||
|
|
||
|
//sniper scope images
|
||
|
gi.imageindex ("pics/scope/arrows128_1");
|
||
|
gi.imageindex ("pics/scope/arrows128_2");
|
||
|
gi.imageindex ("pics/scope/arrows128_3");
|
||
|
gi.imageindex ("pics/scope/arrows128_4");
|
||
|
|
||
|
|
||
|
if (!st.gravity)
|
||
|
gi.cvar_set("sv_gravity", "800");
|
||
|
else
|
||
|
gi.cvar_set("sv_gravity", st.gravity);
|
||
|
|
||
|
//
|
||
|
// Setup light animation tables. 'a' is total darkness, 'z' is doublebright.
|
||
|
//
|
||
|
|
||
|
// 0 normal
|
||
|
gi.configstring(CS_LIGHTS+0, "m");
|
||
|
|
||
|
// 1 FLICKER (first variety)
|
||
|
gi.configstring(CS_LIGHTS+1, "mmnmmommommnonmmonqnmmo");
|
||
|
|
||
|
// 2 SLOW STRONG PULSE
|
||
|
gi.configstring(CS_LIGHTS+2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcb");
|
||
|
|
||
|
// 3 CANDLE (first variety)
|
||
|
gi.configstring(CS_LIGHTS+3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
|
||
|
|
||
|
// 4 FAST STROBE
|
||
|
gi.configstring(CS_LIGHTS+4, "mamamamamama");
|
||
|
|
||
|
// 5 GENTLE PULSE 1
|
||
|
gi.configstring(CS_LIGHTS+5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
|
||
|
|
||
|
// 6 FLICKER (second variety)
|
||
|
gi.configstring(CS_LIGHTS+6, "nmonqnmomnmomomno");
|
||
|
|
||
|
// 7 CANDLE (second variety)
|
||
|
gi.configstring(CS_LIGHTS+7, "mmmaaaabcdefgmmmmaaaammmaamm");
|
||
|
|
||
|
// 8 CANDLE (third variety)
|
||
|
gi.configstring(CS_LIGHTS+8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
|
||
|
|
||
|
// 9 SLOW STROBE (fourth variety)
|
||
|
gi.configstring(CS_LIGHTS+9, "aaaaaaaazzzzzzzz");
|
||
|
|
||
|
// 10 FLUORESCENT FLICKER
|
||
|
gi.configstring(CS_LIGHTS+10, "mmamammmmammamamaaamammma");
|
||
|
|
||
|
// 11 SLOW PULSE NOT FADE TO BLACK
|
||
|
gi.configstring(CS_LIGHTS+11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
|
||
|
|
||
|
// 12 FAST PULSE FOR JEREMY
|
||
|
gi.configstring(CS_LIGHTS+12, "mkigegik");
|
||
|
|
||
|
// 13 Special sky lightning on client - don't muck with this, por favor...
|
||
|
gi.configstring(CS_LIGHTS+CL_WORLDSKYLIGHT, "ex");
|
||
|
|
||
|
|
||
|
// styles 32-62 are assigned by the light program for switchable lights
|
||
|
|
||
|
// 63 testing
|
||
|
gi.configstring(CS_LIGHTS+63, "a");
|
||
|
|
||
|
gi.cvar_set("timescale", "1.0");//in case a script was interrupted...
|
||
|
|
||
|
// precache stuff - this should probably be handled better...
|
||
|
PrecacheSurfaceTypes();
|
||
|
|
||
|
PrecacheSpawningEnemies(ent);
|
||
|
}
|
||
|
|
||
|
void SetSkyColor(float red, float blue, float green)
|
||
|
{
|
||
|
gi.configstring (CS_SKYCOLOR, va("%f %f %f", red, green, blue) );
|
||
|
}
|
||
|
|
||
|
void InitEntMetalSoundCaching(void)
|
||
|
{
|
||
|
int i = 0;
|
||
|
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
|
||
|
for (i = CLSFX_METALSTRIKE1; i <= CLSFX_METALSTRIKE3; i++)
|
||
|
{
|
||
|
entSoundsToCache[i] = 1;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < NUM_FOOTSTEPS_PER_GROUP; i++)
|
||
|
{
|
||
|
entSoundsToCache[CLSFX_FOOTSTEP_METAL + i] = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void InitEntSoundCaching(void)
|
||
|
{
|
||
|
int i = 0, stepsnd = -1;
|
||
|
byte List[256], count;
|
||
|
|
||
|
memset(entSoundsToCache, 0, sizeof(byte)*NUM_CLSFX);
|
||
|
|
||
|
// world geometry sounds (ricochets, wood splintering, etc)
|
||
|
count = gi.SurfaceTypeList(List, sizeof(List));
|
||
|
|
||
|
while(count)
|
||
|
{
|
||
|
count--;
|
||
|
|
||
|
// references to CLSFX_METALIMPACT have been commented out because we're forcing Metal sound Precaching anyway :/
|
||
|
switch(List[count])
|
||
|
{
|
||
|
case SURF_DEFAULT:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_METAL:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_SAND_YELLOW:
|
||
|
//CLSFX_FOOTSTEP_SAND, CLSFX_SANDIMPACT, CLSFX_LAND_SAND,
|
||
|
stepsnd = CLSFX_FOOTSTEP_SAND;
|
||
|
entSoundsToCache[CLSFX_SANDIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_SAND] = 1;
|
||
|
break;
|
||
|
case SURF_SAND_WHITE:
|
||
|
//CLSFX_FOOTSTEP_SAND, CLSFX_SANDIMPACT, CLSFX_LAND_SAND,
|
||
|
stepsnd = CLSFX_FOOTSTEP_SAND;
|
||
|
entSoundsToCache[CLSFX_SANDIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_SAND] = 1;
|
||
|
break;
|
||
|
case SURF_SAND_LBROWN:
|
||
|
//CLSFX_FOOTSTEP_SAND, CLSFX_SANDIMPACT, CLSFX_LAND_SAND,
|
||
|
stepsnd = CLSFX_FOOTSTEP_SAND;
|
||
|
entSoundsToCache[CLSFX_SANDIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_SAND] = 1;
|
||
|
break;
|
||
|
case SURF_SAND_DBROWN:
|
||
|
//CLSFX_FOOTSTEP_SAND, CLSFX_SANDIMPACT, CLSFX_LAND_SAND,
|
||
|
stepsnd = CLSFX_FOOTSTEP_SAND;
|
||
|
entSoundsToCache[CLSFX_SANDIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_SAND] = 1;
|
||
|
break;
|
||
|
case SURF_GRAVEL_GREY:
|
||
|
//CLSFX_FOOTSTEP_GRAVEL, CLSFX_GRAVELIMPACT, CLSFX_LAND_GRAVEL
|
||
|
stepsnd = CLSFX_FOOTSTEP_GRAVEL;
|
||
|
entSoundsToCache[CLSFX_GRAVELIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_GRAVEL] = 1;
|
||
|
break;
|
||
|
case SURF_GRAVEL_DBROWN:
|
||
|
//CLSFX_FOOTSTEP_GRAVEL, CLSFX_GRAVELIMPACT, CLSFX_LAND_GRAVEL
|
||
|
stepsnd = CLSFX_FOOTSTEP_GRAVEL;
|
||
|
entSoundsToCache[CLSFX_GRAVELIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_GRAVEL] = 1;
|
||
|
break;
|
||
|
case SURF_GRAVEL_LBROWN:
|
||
|
//CLSFX_FOOTSTEP_GRAVEL, CLSFX_GRAVELIMPACT, CLSFX_LAND_GRAVEL
|
||
|
stepsnd = CLSFX_FOOTSTEP_GRAVEL;
|
||
|
entSoundsToCache[CLSFX_GRAVELIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_GRAVEL] = 1;
|
||
|
break;
|
||
|
case SURF_SNOW:
|
||
|
//CLSFX_FOOTSTEP_SNOW, CLSFX_SNOWIMPACT, CLSFX_LAND_SNOW,
|
||
|
stepsnd = CLSFX_FOOTSTEP_SNOW;
|
||
|
entSoundsToCache[CLSFX_SNOWIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_SNOW] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_BLUE:
|
||
|
//CLSFX_FOOTSTEP_WATER, CLSFX_WATERIMPACT, CLSFX_LAND_WATER,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WATER;
|
||
|
entSoundsToCache[CLSFX_WATERIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WATER] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_GREEN:
|
||
|
//CLSFX_FOOTSTEP_WATER, CLSFX_WATERIMPACT, CLSFX_LAND_WATER,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WATER;
|
||
|
entSoundsToCache[CLSFX_WATERIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WATER] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_ORANGE:
|
||
|
//CLSFX_FOOTSTEP_WATER, CLSFX_WATERIMPACT, CLSFX_LAND_WATER,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WATER;
|
||
|
entSoundsToCache[CLSFX_WATERIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WATER] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_BROWN:
|
||
|
//CLSFX_FOOTSTEP_WATER, CLSFX_WATERIMPACT, CLSFX_LAND_WATER,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WATER;
|
||
|
entSoundsToCache[CLSFX_WATERIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WATER] = 1;
|
||
|
break;
|
||
|
case SURF_WOOD_LBROWN:
|
||
|
//CLSFX_FOOTSTEP_WOOD, CLSFX_WOODIMPACT, CLSFX_LAND_WOOD,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WOOD;
|
||
|
entSoundsToCache[CLSFX_WOODIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WOOD] = 1;
|
||
|
break;
|
||
|
case SURF_WOOD_DBROWN:
|
||
|
//CLSFX_FOOTSTEP_WOOD, CLSFX_WOODIMPACT, CLSFX_LAND_WOOD,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WOOD;
|
||
|
entSoundsToCache[CLSFX_WOODIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WOOD] = 1;
|
||
|
break;
|
||
|
case SURF_WOOD_LGREY:
|
||
|
//CLSFX_FOOTSTEP_WOOD, CLSFX_WOODIMPACT, CLSFX_LAND_WOOD,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WOOD;
|
||
|
entSoundsToCache[CLSFX_WOODIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WOOD] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_LGREY:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_DGREY:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_LBROWN:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_DBROWN:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_WHITE:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_GREEN:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_RED:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_BLACK:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_GRASS_GREEN:
|
||
|
//CLSFX_FOOTSTEP_GRASS, CLSFX_GRASSIMPACT, CLSFX_LAND_GRASS,
|
||
|
stepsnd = CLSFX_FOOTSTEP_GRASS;
|
||
|
entSoundsToCache[CLSFX_GRASSIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_GRASS] = 1;
|
||
|
break;
|
||
|
case SURF_GRASS_BROWN:
|
||
|
//CLSFX_FOOTSTEP_GRASS, CLSFX_GRASSIMPACT, CLSFX_LAND_GRASS,
|
||
|
stepsnd = CLSFX_FOOTSTEP_GRASS;
|
||
|
entSoundsToCache[CLSFX_GRASSIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_GRASS] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_RED:
|
||
|
//CLSFX_FOOTSTEP_WATER, CLSFX_WATERIMPACT, CLSFX_LAND_WATER,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WATER;
|
||
|
entSoundsToCache[CLSFX_WATERIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WATER] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_STEAM:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_WATERJET:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_OILSPURT:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_CHEMSPURT:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_COMPUTERS:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
//CLSFX_SPARK1, CLSFX_EXP_SMALL
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
// if damaged, the surface requires certain sounds...
|
||
|
entSoundsToCache[CLSFX_SPARK1] = 1;
|
||
|
entSoundsToCache[CLSFX_SPARK2] = 1;
|
||
|
entSoundsToCache[CLSFX_EXP_SMALL] = 1;
|
||
|
break;
|
||
|
case SURF_SNOW_LBROWN:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_SNOW_GREY:
|
||
|
//CLSFX_FOOTSTEP_STONE, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_BLOOD:
|
||
|
//CLSFX_STONEIMPACT, CLSFX_STONEIMPACT, CLSFX_LAND_STONE,
|
||
|
stepsnd = CLSFX_FOOTSTEP_STONE;
|
||
|
entSoundsToCache[CLSFX_STONEIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_BLACK:
|
||
|
//CLSFX_FOOTSTEP_WATER, CLSFX_WATERIMPACT, CLSFX_LAND_WATER,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WATER;
|
||
|
entSoundsToCache[CLSFX_WATERIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WATER] = 1;
|
||
|
break;
|
||
|
case SURF_GLASS:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
//CLSFX_BREAK_GLASSSMALL
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
// if damaged, the surface requires a certain sound...
|
||
|
entSoundsToCache[CLSFX_BREAK_GLASSSMALL] = 1;
|
||
|
break;
|
||
|
case SURF_GLASS_COMPUTER:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
//CLSFX_BREAK_GLASSSMALL
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
// if damaged, the surface requires a certain sound...
|
||
|
entSoundsToCache[CLSFX_BREAK_GLASSSMALL] = 1;
|
||
|
break;
|
||
|
case SURF_SODAMACHINE:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_PAPERWALL:
|
||
|
//CLSFX_FOOTSTEP_WOOD, CLSFX_WOODIMPACT, CLSFX_LAND_WOOD,
|
||
|
stepsnd = CLSFX_FOOTSTEP_WOOD;
|
||
|
entSoundsToCache[CLSFX_WOODIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_WOOD] = 1;
|
||
|
break;
|
||
|
case SURF_NEWSPAPER_DAMAGE:
|
||
|
//CLSFX_FOOTSTEP_METAL, CLSFX_METALIMPACT, CLSFX_LAND_METAL,
|
||
|
stepsnd = CLSFX_FOOTSTEP_METAL;
|
||
|
// entSoundsToCache[CLSFX_METALIMPACT] = 1;
|
||
|
entSoundsToCache[CLSFX_LAND_METAL] = 1;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (stepsnd >= 0)
|
||
|
{
|
||
|
for (i = 0; i < NUM_FOOTSTEPS_PER_GROUP; i++)
|
||
|
{
|
||
|
entSoundsToCache[stepsnd + i] = 1;
|
||
|
}
|
||
|
}
|
||
|
stepsnd = -1;
|
||
|
}
|
||
|
|
||
|
entSoundsToCache[CLSFX_SPARK1] = 1;
|
||
|
entSoundsToCache[CLSFX_SPARK2] = 1;
|
||
|
|
||
|
}
|
||
|
|
||
|
void InitEntDebrisCaching(void)
|
||
|
{
|
||
|
int i = 0;
|
||
|
|
||
|
memset(entDebrisToCache, 'n', sizeof(char)*NUM_CLGHL);
|
||
|
|
||
|
// there may be some debris models that we'll always want to cache, but I
|
||
|
//can't think of 'em right now
|
||
|
|
||
|
}
|
||
|
|
||
|
void CacheEntDebrisAndSounds(edict_t *ent)
|
||
|
{
|
||
|
// cache the debris that this ent turns into when it breaks/dies/explodes
|
||
|
switch(ent->material)
|
||
|
{
|
||
|
case MAT_BRICK_BROWN:
|
||
|
case MAT_BRICK_LBROWN:
|
||
|
case MAT_BRICK_LGREY:
|
||
|
case MAT_BRICK_DGREY:
|
||
|
case MAT_BRICK_RED:
|
||
|
entDebrisToCache[CLGHL_CHUNKBRICK] = DEBRIS_YES;
|
||
|
break;
|
||
|
|
||
|
case MAT_GLASS:
|
||
|
entDebrisToCache[CLGHL_CHUNKGLASSSM] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKGLASSMED] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKGLASSLRG] = DEBRIS_YES;
|
||
|
break;
|
||
|
|
||
|
case MAT_METAL_LGREY:
|
||
|
case MAT_METAL_DGREY:
|
||
|
case MAT_METAL_RUSTY:
|
||
|
case MAT_METAL_SHINY:
|
||
|
entDebrisToCache[CLGHL_CHUNKMETALSM] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKMETALMED] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKMETALLRG] = DEBRIS_YES;
|
||
|
break;
|
||
|
|
||
|
case MAT_ROCK_BROWN:
|
||
|
case MAT_ROCK_LBROWN:
|
||
|
case MAT_ROCK_DBROWN:
|
||
|
case MAT_ROCK_LGREY:
|
||
|
case MAT_ROCK_DGREY:
|
||
|
case MAT_ROCK_FLESH:
|
||
|
entDebrisToCache[CLGHL_CHUNKROCKSM] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKROCKMED] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKROCKLRG] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKROCKTINY] = DEBRIS_YES;
|
||
|
break;
|
||
|
|
||
|
case MAT_WOOD_LBROWN:
|
||
|
case MAT_WOOD_DBROWN:
|
||
|
case MAT_WOOD_DGREY:
|
||
|
case MAT_WOOD_LGREY:
|
||
|
entDebrisToCache[CLGHL_CHUNKWOODSM] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKWOODMED] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKWOODLRG] = DEBRIS_YES;
|
||
|
break;
|
||
|
|
||
|
case MAT_WALL_BLACK:
|
||
|
case MAT_WALL_BROWN:
|
||
|
case MAT_WALL_DARKBROWN:
|
||
|
case MAT_WALL_LIGHTBROWN:
|
||
|
case MAT_WALL_GREY:
|
||
|
case MAT_WALL_DARKGREY:
|
||
|
case MAT_WALL_LIGHTGREY:
|
||
|
case MAT_WALL_GREEN:
|
||
|
case MAT_WALL_ORANGE:
|
||
|
case MAT_WALL_RED:
|
||
|
case MAT_WALL_WHITE:
|
||
|
case MAT_WALL_STRAW:
|
||
|
entDebrisToCache[CLGHL_CHUNKWALLSM] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKWALLMED] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKWALLLRG] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKWALLTINY] = DEBRIS_YES;
|
||
|
break;
|
||
|
case MAT_ROCK_SNOW:
|
||
|
entDebrisToCache[CLGHL_CHUNKROCKSM] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKROCKMED] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKROCKLRG] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKROCKTINY] = DEBRIS_YES;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// kef -- have to keep some of the precaching stuff out for now cuz it crashes final/nyc with
|
||
|
// an index overflow in the soundlist
|
||
|
#if 1
|
||
|
// some surfaceTypes have various client fx associated with their death. these
|
||
|
//fx tend to generate a lot of chunks. also, the sounds needed by the client function
|
||
|
//HandleDebris() are precached here.
|
||
|
switch(ent->surfaceType)
|
||
|
{
|
||
|
case SURF_DEFAULT:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_WOOD_LBROWN:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_WOOD] = 1;
|
||
|
break;
|
||
|
case SURF_WOOD_DBROWN:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_WOOD] = 1;
|
||
|
break;
|
||
|
case SURF_WOOD_LGREY:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_WOOD] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_LGREY:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_DGREY:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_LBROWN:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_DBROWN:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_WHITE:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_GREEN:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_RED:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_STONE_BLACK:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_GRASS_GREEN:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_GRASS_BROWN:
|
||
|
// MakeDefaultWallEffect -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_METAL:
|
||
|
// MakeSparks -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_SAND_YELLOW:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_SAND_WHITE:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_SAND_LBROWN:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_SAND_DBROWN:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_GRAVEL_GREY:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_GRAVEL_DBROWN:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_GRAVEL_LBROWN:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_SNOW:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_SNOW_LBROWN:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_SNOW_GREY:
|
||
|
// MakeSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_BLUE:
|
||
|
// MakeSplatWater -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_GREEN:
|
||
|
// MakeSplatWater -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_ORANGE:
|
||
|
// MakeSplatWater -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_BROWN:
|
||
|
// MakeSplatWater -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_RED:
|
||
|
// MakeSplatWater -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_LIQUID_BLACK:
|
||
|
// MakeSplatWater -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_STEAM:
|
||
|
// MakeShortSteam -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_WATERJET:
|
||
|
// MakeLiquidSpurt -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_OILSPURT:
|
||
|
// MakeLiquidSpurt -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_CHEMSPURT:
|
||
|
// MakeLiquidSpurt -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_METAL] = 1;
|
||
|
break;
|
||
|
case SURF_METAL_COMPUTERS:
|
||
|
// MakeComputerDamage -- calls ThrowChunks with surfaceType SURF_STONE_DGREY
|
||
|
//CLSFX_SPARK1, CLSFX_EXP_SMALL
|
||
|
entDebrisToCache[CLGHL_CHUNKWALLSM] = DEBRIS_YES;
|
||
|
entSoundsToCache[CLSFX_BREAK_METAL] = 1;
|
||
|
entSoundsToCache[CLSFX_SPARK1] = 1;
|
||
|
entSoundsToCache[CLSFX_EXP_SMALL] = 1;
|
||
|
break;
|
||
|
case SURF_BLOOD:
|
||
|
// MakeBloodSplatter -- no chunks
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
case SURF_GLASS:
|
||
|
// MakeSplatGlass -- throws some glass chunks
|
||
|
//CLSFX_BREAK_GLASSSMALL,CLSFX_BREAK_GLASSMED,CLSFX_BREAK_GLASSBIG
|
||
|
entDebrisToCache[CLGHL_CHUNKGLASSSM] = DEBRIS_YES;
|
||
|
entSoundsToCache[CLSFX_BREAK_GLASSSMALL] = 1;
|
||
|
entSoundsToCache[CLSFX_BREAK_GLASSMED] = 1;
|
||
|
entSoundsToCache[CLSFX_BREAK_GLASSBIG] = 1;
|
||
|
break;
|
||
|
case SURF_GLASS_COMPUTER:
|
||
|
// MakeComputerGlassDamage
|
||
|
//CLSFX_BREAK_GLASSSMALL,CLSFX_BREAK_GLASSMED,CLSFX_BREAK_GLASSBIG
|
||
|
entDebrisToCache[CLGHL_CHUNKGLASSSM] = DEBRIS_YES;
|
||
|
entDebrisToCache[CLGHL_CHUNKWALLSM] = DEBRIS_YES;
|
||
|
entSoundsToCache[CLSFX_BREAK_GLASSSMALL] = 1;
|
||
|
entSoundsToCache[CLSFX_BREAK_GLASSMED] = 1;
|
||
|
entSoundsToCache[CLSFX_BREAK_GLASSBIG] = 1;
|
||
|
break;
|
||
|
case SURF_SODAMACHINE:
|
||
|
// MakeSodaDamage -- you guessed it...spews cans
|
||
|
entDebrisToCache[CLGHL_CAN] = DEBRIS_YES;
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
|
||
|
case SURF_PAPERWALL:
|
||
|
// MakePaperWallDamage
|
||
|
//CLSFX_WOODIMPACT
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
|
||
|
case SURF_NEWSPAPER_DAMAGE:
|
||
|
// MakeNewspaperDamage
|
||
|
entDebrisToCache[CLGHL_PAPER] = DEBRIS_YES;
|
||
|
entSoundsToCache[CLSFX_BREAK_STONE] = 1;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void CacheAllDebris(void)
|
||
|
{
|
||
|
|
||
|
if (NUM_CLGHL > MAX_QPATH) // Too many different types of debris
|
||
|
{
|
||
|
Com_Printf("ERROR: NUM_CLGHL > MAX_QPATH!\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
gi.configstring(CS_DEBRISPRECACHE,entDebrisToCache); // Set up string to send across
|
||
|
}
|
||
|
|
||
|
void CacheAllSounds(void)
|
||
|
{
|
||
|
int i = 0;
|
||
|
|
||
|
// never know when we'll have water available, so make sure the 'I entered water' sound
|
||
|
//is always precached
|
||
|
entSoundsToCache[CLSFX_LAND_WATER] = 1;
|
||
|
for (i = 0; i < NUM_CLSFX; i++)
|
||
|
{
|
||
|
if (entSoundsToCache[i])
|
||
|
{
|
||
|
gi.soundindex(cl_fxs[i].filename);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// this is less than cool
|
||
|
void CacheAllWallEffects(void)
|
||
|
{
|
||
|
gi.effectindex("environ/waterspurt");
|
||
|
gi.effectindex("environ/oilspurt");
|
||
|
gi.effectindex("environ/chemspurt");
|
||
|
gi.effectindex("environ/metal_computer");
|
||
|
gi.effectindex("environ/glass_computer");
|
||
|
gi.effectindex("environ/metal_steam");
|
||
|
gi.effectindex("environ/bulletsplash");
|
||
|
gi.effectindex("environ/splatgreen");
|
||
|
gi.effectindex("environ/splatorange");
|
||
|
gi.effectindex("environ/splatred");
|
||
|
gi.effectindex("environ/splatbrown");
|
||
|
gi.effectindex("environ/splatblack");
|
||
|
}
|
||
|
|
||
|
char *weaponList[] =
|
||
|
{ "nothing",
|
||
|
"knife",
|
||
|
"pistol2",
|
||
|
"pistol1",
|
||
|
"mpistol",
|
||
|
"assault",
|
||
|
"sniper",
|
||
|
"slugger",
|
||
|
"shotgun",
|
||
|
"machinegun",
|
||
|
"rocket",
|
||
|
"mpg",
|
||
|
"flamegun",
|
||
|
0
|
||
|
};
|
||
|
|
||
|
void CalculatePlayerEntryWeapons(int *weaponsAvailable)
|
||
|
{
|
||
|
char *curSpot;
|
||
|
char *curTokSpot;
|
||
|
char token[256];
|
||
|
char temp[256];
|
||
|
int value;
|
||
|
|
||
|
//assume curSpot is somewhere decent
|
||
|
|
||
|
curSpot = gi.cvar_info(CVAR_WEAPON | CVAR_ITEM | CVAR_AMMO);
|
||
|
|
||
|
if(!curSpot || (!strcmp(curSpot, "")))
|
||
|
{ // if there is nothing, plug in the defaults
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
while(*curSpot)
|
||
|
{
|
||
|
curTokSpot = token;
|
||
|
|
||
|
if(*curSpot == '\\')
|
||
|
{
|
||
|
curSpot++;
|
||
|
}
|
||
|
|
||
|
while(*curSpot && (*curSpot != '\\'))
|
||
|
{
|
||
|
*curTokSpot++ = *curSpot++;
|
||
|
}
|
||
|
*curTokSpot = 0;
|
||
|
|
||
|
assert(*curSpot);
|
||
|
|
||
|
if(*curSpot == '\\')
|
||
|
{
|
||
|
curSpot++;
|
||
|
}
|
||
|
|
||
|
curTokSpot = temp;
|
||
|
while((*curSpot) && (*curSpot != '\\'))
|
||
|
{
|
||
|
*curTokSpot++ = *curSpot++;
|
||
|
}
|
||
|
*curTokSpot = 0;
|
||
|
value = atoi(temp);
|
||
|
|
||
|
// okay, we have the two tokens... let's do stuff with them now...
|
||
|
|
||
|
|
||
|
char *testString;
|
||
|
int curCheck;
|
||
|
int found = 0;
|
||
|
|
||
|
|
||
|
|
||
|
// look for weapons
|
||
|
|
||
|
curCheck = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
testString = weaponList[curCheck];
|
||
|
|
||
|
if(!stricmp(token, testString))
|
||
|
{ // hey, I have one of these! Cool!
|
||
|
if(value)
|
||
|
{// add the weapon
|
||
|
*weaponsAvailable |= (1<<curCheck);
|
||
|
}
|
||
|
found = 1;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
curCheck++;
|
||
|
}while(weaponList[curCheck]);
|
||
|
|
||
|
if(found)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|