codemp/game/g_main.c

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 Id Software, Inc.
00002 //
00003 
00004 #include "g_local.h"
00005 #include "g_ICARUScb.h"
00006 #include "g_nav.h"
00007 #include "bg_saga.h"
00008 
00009 level_locals_t  level;
00010 
00011 int             eventClearTime = 0;
00012 static int navCalcPathTime = 0;
00013 extern int fatalErrors;
00014 
00015 int killPlayerTimer = 0;
00016 
00017 typedef struct {
00018         vmCvar_t        *vmCvar;
00019         char            *cvarName;
00020         char            *defaultString;
00021         int                     cvarFlags;
00022         int                     modificationCount;  // for tracking changes
00023         qboolean        trackChange;        // track this variable, and announce if changed
00024   qboolean teamShader;        // track and if changed, update shader state
00025 } cvarTable_t;
00026 
00027 gentity_t               g_entities[MAX_GENTITIES];
00028 gclient_t               g_clients[MAX_CLIENTS];
00029 
00030 qboolean gDuelExit = qfalse;
00031 
00032 vmCvar_t        g_trueJedi;
00033 
00034 vmCvar_t        g_gametype;
00035 vmCvar_t        g_MaxHolocronCarry;
00036 vmCvar_t        g_ff_objectives;
00037 vmCvar_t        g_autoMapCycle;
00038 vmCvar_t        g_dmflags;
00039 vmCvar_t        g_maxForceRank;
00040 vmCvar_t        g_forceBasedTeams;
00041 vmCvar_t        g_privateDuel;
00042 
00043 vmCvar_t        g_allowNPC;
00044 
00045 vmCvar_t        g_armBreakage;
00046 
00047 vmCvar_t        g_saberLocking;
00048 vmCvar_t        g_saberLockFactor;
00049 vmCvar_t        g_saberTraceSaberFirst;
00050 
00051 vmCvar_t        d_saberKickTweak;
00052 
00053 vmCvar_t        d_powerDuelPrint;
00054 
00055 vmCvar_t        d_saberGhoul2Collision;
00056 vmCvar_t        g_saberBladeFaces;
00057 vmCvar_t        d_saberAlwaysBoxTrace;
00058 vmCvar_t        d_saberBoxTraceSize;
00059 
00060 vmCvar_t        d_siegeSeekerNPC;
00061 
00062 vmCvar_t        g_debugMelee;
00063 vmCvar_t        g_stepSlideFix;
00064 
00065 vmCvar_t        g_noSpecMove;
00066 
00067 #ifdef _DEBUG
00068 vmCvar_t        g_disableServerG2;
00069 #endif
00070 
00071 vmCvar_t        d_perPlayerGhoul2;
00072 
00073 vmCvar_t        d_projectileGhoul2Collision;
00074 
00075 vmCvar_t        g_g2TraceLod;
00076 
00077 vmCvar_t        g_optvehtrace;
00078 
00079 vmCvar_t        g_locationBasedDamage;
00080 
00081 vmCvar_t        g_allowHighPingDuelist;
00082 
00083 vmCvar_t        g_logClientInfo;
00084 
00085 vmCvar_t        g_slowmoDuelEnd;
00086 
00087 vmCvar_t        g_saberDamageScale;
00088 
00089 vmCvar_t        g_useWhileThrowing;
00090 
00091 vmCvar_t        g_RMG;
00092 
00093 vmCvar_t        g_svfps;
00094 
00095 vmCvar_t        g_forceRegenTime;
00096 vmCvar_t        g_spawnInvulnerability;
00097 vmCvar_t        g_forcePowerDisable;
00098 vmCvar_t        g_weaponDisable;
00099 vmCvar_t        g_duelWeaponDisable;
00100 vmCvar_t        g_allowDuelSuicide;
00101 vmCvar_t        g_fraglimitVoteCorrection;
00102 vmCvar_t        g_fraglimit;
00103 vmCvar_t        g_duel_fraglimit;
00104 vmCvar_t        g_timelimit;
00105 vmCvar_t        g_capturelimit;
00106 vmCvar_t        d_saberInterpolate;
00107 vmCvar_t        g_friendlyFire;
00108 vmCvar_t        g_friendlySaber;
00109 vmCvar_t        g_password;
00110 vmCvar_t        g_needpass;
00111 vmCvar_t        g_maxclients;
00112 vmCvar_t        g_maxGameClients;
00113 vmCvar_t        g_dedicated;
00114 vmCvar_t        g_developer;
00115 vmCvar_t        g_speed;
00116 vmCvar_t        g_gravity;
00117 vmCvar_t        g_cheats;
00118 vmCvar_t        g_knockback;
00119 vmCvar_t        g_quadfactor;
00120 vmCvar_t        g_forcerespawn;
00121 vmCvar_t        g_siegeRespawn;
00122 vmCvar_t        g_inactivity;
00123 vmCvar_t        g_debugMove;
00124 #ifndef FINAL_BUILD
00125 vmCvar_t        g_debugDamage;
00126 #endif
00127 vmCvar_t        g_debugAlloc;
00128 vmCvar_t        g_debugServerSkel;
00129 vmCvar_t        g_weaponRespawn;
00130 vmCvar_t        g_weaponTeamRespawn;
00131 vmCvar_t        g_adaptRespawn;
00132 vmCvar_t        g_motd;
00133 vmCvar_t        g_synchronousClients;
00134 vmCvar_t        g_warmup;
00135 vmCvar_t        g_doWarmup;
00136 vmCvar_t        g_restarted;
00137 vmCvar_t        g_log;
00138 vmCvar_t        g_logSync;
00139 vmCvar_t        g_statLog;
00140 vmCvar_t        g_statLogFile;
00141 vmCvar_t        g_blood;
00142 vmCvar_t        g_podiumDist;
00143 vmCvar_t        g_podiumDrop;
00144 vmCvar_t        g_allowVote;
00145 vmCvar_t        g_teamAutoJoin;
00146 vmCvar_t        g_teamForceBalance;
00147 vmCvar_t        g_banIPs;
00148 vmCvar_t        g_filterBan;
00149 vmCvar_t        g_debugForward;
00150 vmCvar_t        g_debugRight;
00151 vmCvar_t        g_debugUp;
00152 vmCvar_t        g_smoothClients;
00153 
00154 #include "../namespace_begin.h"
00155 vmCvar_t        pmove_fixed;
00156 vmCvar_t        pmove_msec;
00157 #include "../namespace_end.h"
00158 
00159 vmCvar_t        g_listEntity;
00160 //vmCvar_t      g_redteam;
00161 //vmCvar_t      g_blueteam;
00162 vmCvar_t        g_singlePlayer;
00163 vmCvar_t        g_enableBreath;
00164 vmCvar_t        g_dismember;
00165 vmCvar_t        g_forceDodge;
00166 vmCvar_t        g_timeouttospec;
00167 
00168 vmCvar_t        g_saberDmgVelocityScale;
00169 vmCvar_t        g_saberDmgDelay_Idle;
00170 vmCvar_t        g_saberDmgDelay_Wound;
00171 
00172 vmCvar_t        g_saberDebugPrint;
00173 
00174 vmCvar_t        g_siegeTeamSwitch;
00175 
00176 vmCvar_t        bg_fighterAltControl;
00177 
00178 #ifdef DEBUG_SABER_BOX
00179 vmCvar_t        g_saberDebugBox;
00180 #endif
00181 
00182 //NPC nav debug
00183 vmCvar_t        d_altRoutes;
00184 vmCvar_t        d_patched;
00185 
00186 vmCvar_t                g_saberRealisticCombat;
00187 vmCvar_t                g_saberRestrictForce;
00188 vmCvar_t                d_saberSPStyleDamage;
00189 vmCvar_t                g_debugSaberLocks;
00190 vmCvar_t                g_saberLockRandomNess;
00191 // nmckenzie: SABER_DAMAGE_WALLS
00192 vmCvar_t                g_saberWallDamageScale;
00193 
00194 vmCvar_t                d_saberStanceDebug;
00195 // ai debug cvars
00196 vmCvar_t                debugNPCAI;                     // used to print out debug info about the bot AI
00197 vmCvar_t                debugNPCFreeze;         // set to disable bot ai and temporarily freeze them in place
00198 vmCvar_t                debugNPCAimingBeam;
00199 vmCvar_t                debugBreak;
00200 vmCvar_t                debugNoRoam;
00201 vmCvar_t                d_saberCombat;
00202 vmCvar_t                d_JediAI;
00203 vmCvar_t                d_noGroupAI;
00204 vmCvar_t                d_asynchronousGroupAI;
00205 vmCvar_t                d_slowmodeath;
00206 vmCvar_t                d_noIntermissionWait;
00207 
00208 vmCvar_t                g_spskill;
00209 
00210 
00211 vmCvar_t                g_siegeTeam1;
00212 vmCvar_t                g_siegeTeam2;
00213 
00214 vmCvar_t        g_austrian;
00215 
00216 vmCvar_t        g_powerDuelStartHealth;
00217 vmCvar_t        g_powerDuelEndHealth;
00218 
00219 // nmckenzie: temporary way to show player healths in duels - some iface gfx in game would be better, of course.
00220 // DUEL_HEALTH
00221 vmCvar_t                g_showDuelHealths;
00222 
00223 // bk001129 - made static to avoid aliasing
00224 static cvarTable_t              gameCvarTable[] = {
00225         // don't override the cheat state set by the system
00226         { &g_cheats, "sv_cheats", "", 0, 0, qfalse },
00227 
00228         { &g_debugMelee, "g_debugMelee", "0", CVAR_SERVERINFO, 0, qtrue  },
00229         { &g_stepSlideFix, "g_stepSlideFix", "1", CVAR_SERVERINFO, 0, qtrue  },
00230 
00231         { &g_noSpecMove, "g_noSpecMove", "0", CVAR_SERVERINFO, 0, qtrue },
00232 
00233         // noset vars
00234         { NULL, "gamename", GAMEVERSION , CVAR_SERVERINFO | CVAR_ROM, 0, qfalse  },
00235         { NULL, "gamedate", __DATE__ , CVAR_ROM, 0, qfalse  },
00236         { &g_restarted, "g_restarted", "0", CVAR_ROM, 0, qfalse  },
00237         { NULL, "sv_mapname", "", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse  },
00238 
00239         // latched vars
00240         { &g_gametype, "g_gametype", "0", CVAR_SERVERINFO | CVAR_LATCH, 0, qfalse  },
00241         { &g_MaxHolocronCarry, "g_MaxHolocronCarry", "3", CVAR_SERVERINFO | CVAR_LATCH, 0, qfalse  },
00242 
00243         { &g_maxclients, "sv_maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse  },
00244         { &g_maxGameClients, "g_maxGameClients", "0", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse  },
00245 
00246         { &g_trueJedi, "g_jediVmerc", "0", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qtrue },
00247 
00248         // change anytime vars
00249         { &g_ff_objectives, "g_ff_objectives", "0", /*CVAR_SERVERINFO |*/ CVAR_CHEAT | CVAR_NORESTART, 0, qtrue },
00250 
00251         { &g_autoMapCycle, "g_autoMapCycle", "0", CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
00252         { &g_dmflags, "dmflags", "0", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue  },
00253         
00254         { &g_maxForceRank, "g_maxForceRank", "6", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH, 0, qfalse  },
00255         { &g_forceBasedTeams, "g_forceBasedTeams", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH, 0, qfalse  },
00256         { &g_privateDuel, "g_privateDuel", "1", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue  },
00257 
00258         { &g_allowNPC, "g_allowNPC", "1", CVAR_SERVERINFO | CVAR_CHEAT, 0, qtrue  },
00259 
00260         { &g_armBreakage, "g_armBreakage", "0", 0, 0, qtrue  },
00261 
00262         { &g_saberLocking, "g_saberLocking", "1", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue  },
00263         { &g_saberLockFactor, "g_saberLockFactor", "2", CVAR_ARCHIVE, 0, qtrue  },
00264         { &g_saberTraceSaberFirst, "g_saberTraceSaberFirst", "0", CVAR_ARCHIVE, 0, qtrue  },
00265 
00266         { &d_saberKickTweak, "d_saberKickTweak", "1", 0, 0, qtrue  },
00267 
00268         { &d_powerDuelPrint, "d_powerDuelPrint", "0", 0, qtrue },
00269 
00270         { &d_saberGhoul2Collision, "d_saberGhoul2Collision", "1", CVAR_CHEAT, 0, qtrue  },
00271         { &g_saberBladeFaces, "g_saberBladeFaces", "1", 0, 0, qtrue  },
00272 
00273         { &d_saberAlwaysBoxTrace, "d_saberAlwaysBoxTrace", "0", CVAR_CHEAT, 0, qtrue  },
00274         { &d_saberBoxTraceSize, "d_saberBoxTraceSize", "0", CVAR_CHEAT, 0, qtrue  },
00275 
00276         { &d_siegeSeekerNPC, "d_siegeSeekerNPC", "0", CVAR_CHEAT, 0, qtrue },
00277 
00278 #ifdef _DEBUG
00279         { &g_disableServerG2, "g_disableServerG2", "0", 0, 0, qtrue },
00280 #endif
00281 
00282         { &d_perPlayerGhoul2, "d_perPlayerGhoul2", "0", CVAR_CHEAT, 0, qtrue },
00283 
00284         { &d_projectileGhoul2Collision, "d_projectileGhoul2Collision", "1", CVAR_CHEAT, 0, qtrue  },
00285 
00286         { &g_g2TraceLod, "g_g2TraceLod", "3", 0, 0, qtrue  },
00287 
00288         { &g_optvehtrace, "com_optvehtrace", "0", 0, 0, qtrue  },
00289 
00290         { &g_locationBasedDamage, "g_locationBasedDamage", "1", 0, 0, qtrue },
00291 
00292         { &g_allowHighPingDuelist, "g_allowHighPingDuelist", "1", 0, 0, qtrue },
00293 
00294         { &g_logClientInfo, "g_logClientInfo", "0", CVAR_ARCHIVE, 0, qtrue  },
00295 
00296         { &g_slowmoDuelEnd, "g_slowmoDuelEnd", "0", CVAR_ARCHIVE, 0, qtrue  },
00297 
00298         { &g_saberDamageScale, "g_saberDamageScale", "1", CVAR_ARCHIVE, 0, qtrue  },
00299 
00300         { &g_useWhileThrowing, "g_useWhileThrowing", "1", 0, 0, qtrue  },
00301 
00302         { &g_RMG, "RMG", "0", 0, 0, qtrue  },
00303 
00304         { &g_svfps, "sv_fps", "20", 0, 0, qtrue },
00305 
00306         { &g_forceRegenTime, "g_forceRegenTime", "200", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue  },
00307 
00308         { &g_spawnInvulnerability, "g_spawnInvulnerability", "3000", CVAR_ARCHIVE, 0, qtrue  },
00309 
00310         { &g_forcePowerDisable, "g_forcePowerDisable", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH, 0, qtrue  },
00311         { &g_weaponDisable, "g_weaponDisable", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH, 0, qtrue  },
00312         { &g_duelWeaponDisable, "g_duelWeaponDisable", "1", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH, 0, qtrue  },
00313 
00314         { &g_allowDuelSuicide, "g_allowDuelSuicide", "1", CVAR_ARCHIVE, 0, qtrue },
00315 
00316         { &g_fraglimitVoteCorrection, "g_fraglimitVoteCorrection", "1", CVAR_ARCHIVE, 0, qtrue },
00317 
00318         { &g_fraglimit, "fraglimit", "20", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
00319         { &g_duel_fraglimit, "duel_fraglimit", "10", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
00320         { &g_timelimit, "timelimit", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
00321         { &g_capturelimit, "capturelimit", "8", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
00322 
00323         { &g_synchronousClients, "g_synchronousClients", "0", CVAR_SYSTEMINFO, 0, qfalse  },
00324 
00325         { &d_saberInterpolate, "d_saberInterpolate", "0", CVAR_CHEAT, 0, qtrue },
00326 
00327         { &g_friendlyFire, "g_friendlyFire", "0", CVAR_ARCHIVE, 0, qtrue  },
00328         { &g_friendlySaber, "g_friendlySaber", "0", CVAR_ARCHIVE, 0, qtrue  },
00329 
00330         { &g_teamAutoJoin, "g_teamAutoJoin", "0", CVAR_ARCHIVE  },
00331         { &g_teamForceBalance, "g_teamForceBalance", "0", CVAR_ARCHIVE  },
00332 
00333         { &g_warmup, "g_warmup", "20", CVAR_ARCHIVE, 0, qtrue  },
00334         { &g_doWarmup, "g_doWarmup", "0", 0, 0, qtrue  },
00335         { &g_log, "g_log", "games.log", CVAR_ARCHIVE, 0, qfalse  },
00336         { &g_logSync, "g_logSync", "0", CVAR_ARCHIVE, 0, qfalse  },
00337 
00338         { &g_statLog, "g_statLog", "0", CVAR_ARCHIVE, 0, qfalse },
00339         { &g_statLogFile, "g_statLogFile", "statlog.log", CVAR_ARCHIVE, 0, qfalse },
00340 
00341         { &g_password, "g_password", "", CVAR_USERINFO, 0, qfalse  },
00342 
00343         { &g_banIPs, "g_banIPs", "", CVAR_ARCHIVE, 0, qfalse  },
00344         { &g_filterBan, "g_filterBan", "1", CVAR_ARCHIVE, 0, qfalse  },
00345 
00346         { &g_needpass, "g_needpass", "0", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse },
00347 
00348         { &g_dedicated, "dedicated", "0", 0, 0, qfalse  },
00349 
00350         { &g_developer, "developer", "0", 0, 0, qfalse },
00351 
00352         { &g_speed, "g_speed", "250", 0, 0, qtrue  },
00353         { &g_gravity, "g_gravity", "800", 0, 0, qtrue  },
00354         { &g_knockback, "g_knockback", "1000", 0, 0, qtrue  },
00355         { &g_quadfactor, "g_quadfactor", "3", 0, 0, qtrue  },
00356         { &g_weaponRespawn, "g_weaponrespawn", "5", 0, 0, qtrue  },
00357         { &g_weaponTeamRespawn, "g_weaponTeamRespawn", "5", 0, 0, qtrue },
00358         { &g_adaptRespawn, "g_adaptrespawn", "1", 0, 0, qtrue  },               // Make weapons respawn faster with a lot of players.
00359         { &g_forcerespawn, "g_forcerespawn", "60", 0, 0, qtrue },               // One minute force respawn.  Give a player enough time to reallocate force.
00360         { &g_siegeRespawn, "g_siegeRespawn", "20", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue }, //siege respawn wave time
00361         { &g_inactivity, "g_inactivity", "0", 0, 0, qtrue },
00362         { &g_debugMove, "g_debugMove", "0", 0, 0, qfalse },
00363 #ifndef FINAL_BUILD
00364         { &g_debugDamage, "g_debugDamage", "0", 0, 0, qfalse },
00365 #endif
00366         { &g_debugAlloc, "g_debugAlloc", "0", 0, 0, qfalse },
00367         { &g_debugServerSkel, "g_debugServerSkel", "0", CVAR_CHEAT, 0, qfalse },
00368         { &g_motd, "g_motd", "", 0, 0, qfalse },
00369         { &g_blood, "com_blood", "1", 0, 0, qfalse },
00370 
00371         { &g_podiumDist, "g_podiumDist", "80", 0, 0, qfalse },
00372         { &g_podiumDrop, "g_podiumDrop", "70", 0, 0, qfalse },
00373 
00374         { &g_allowVote, "g_allowVote", "1", CVAR_ARCHIVE, 0, qfalse },
00375         { &g_listEntity, "g_listEntity", "0", 0, 0, qfalse },
00376 
00377 #if 0
00378         { &g_debugForward, "g_debugForward", "0", 0, 0, qfalse },
00379         { &g_debugRight, "g_debugRight", "0", 0, 0, qfalse },
00380         { &g_debugUp, "g_debugUp", "0", 0, 0, qfalse },
00381 #endif
00382 
00383 //      { &g_redteam, "g_redteam", "Empire", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_USERINFO , 0, qtrue, qtrue },
00384 //      { &g_blueteam, "g_blueteam", "Rebellion", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_USERINFO , 0, qtrue, qtrue  },
00385         { &g_singlePlayer, "ui_singlePlayerActive", "", 0, 0, qfalse, qfalse  },
00386 
00387         { &g_enableBreath, "g_enableBreath", "0", 0, 0, qtrue, qfalse },
00388         { &g_smoothClients, "g_smoothClients", "1", 0, 0, qfalse},
00389         { &pmove_fixed, "pmove_fixed", "0", CVAR_SYSTEMINFO, 0, qfalse},
00390         { &pmove_msec, "pmove_msec", "8", CVAR_SYSTEMINFO, 0, qfalse},
00391 
00392         { &g_dismember, "g_dismember", "0", CVAR_ARCHIVE, 0, qtrue  },
00393         { &g_forceDodge, "g_forceDodge", "1", 0, 0, qtrue  },
00394 
00395         { &g_timeouttospec, "g_timeouttospec", "70", CVAR_ARCHIVE, 0, qfalse },
00396 
00397         { &g_saberDmgVelocityScale, "g_saberDmgVelocityScale", "0", CVAR_ARCHIVE, 0, qtrue  },
00398         { &g_saberDmgDelay_Idle, "g_saberDmgDelay_Idle", "350", CVAR_ARCHIVE, 0, qtrue  },
00399         { &g_saberDmgDelay_Wound, "g_saberDmgDelay_Wound", "0", CVAR_ARCHIVE, 0, qtrue  },
00400 
00401 #ifndef FINAL_BUILD
00402         { &g_saberDebugPrint, "g_saberDebugPrint", "0", CVAR_CHEAT, 0, qfalse  },
00403 #endif
00404         { &g_debugSaberLocks, "g_debugSaberLocks", "0", CVAR_CHEAT, 0, qfalse },
00405         { &g_saberLockRandomNess, "g_saberLockRandomNess", "2", CVAR_CHEAT, 0, qfalse },
00406 // nmckenzie: SABER_DAMAGE_WALLS
00407         { &g_saberWallDamageScale, "g_saberWallDamageScale", "0.4", CVAR_SERVERINFO, 0, qfalse },
00408 
00409         { &d_saberStanceDebug, "d_saberStanceDebug", "0", 0, 0, qfalse },
00410 
00411         { &g_siegeTeamSwitch, "g_siegeTeamSwitch", "1", CVAR_SERVERINFO|CVAR_ARCHIVE, qfalse },
00412 
00413         { &bg_fighterAltControl, "bg_fighterAltControl", "0", CVAR_SERVERINFO, 0, qtrue },
00414 
00415 #ifdef DEBUG_SABER_BOX
00416         { &g_saberDebugBox, "g_saberDebugBox", "0", CVAR_CHEAT, 0, qfalse },
00417 #endif
00418 
00419         { &d_altRoutes, "d_altRoutes", "0", CVAR_CHEAT, 0, qfalse },
00420         { &d_patched, "d_patched", "0", CVAR_CHEAT, 0, qfalse },
00421 
00422         { &g_saberRealisticCombat, "g_saberRealisticCombat", "0", CVAR_CHEAT },
00423         { &g_saberRestrictForce, "g_saberRestrictForce", "0", CVAR_CHEAT },
00424         { &d_saberSPStyleDamage, "d_saberSPStyleDamage", "1", CVAR_CHEAT },
00425 
00426         { &debugNoRoam, "d_noroam", "0", CVAR_CHEAT },
00427         { &debugNPCAimingBeam, "d_npcaiming", "0", CVAR_CHEAT },
00428         { &debugBreak, "d_break", "0", CVAR_CHEAT },
00429         { &debugNPCAI, "d_npcai", "0", CVAR_CHEAT },
00430         { &debugNPCFreeze, "d_npcfreeze", "0", CVAR_CHEAT },
00431         { &d_JediAI, "d_JediAI", "0", CVAR_CHEAT },
00432         { &d_noGroupAI, "d_noGroupAI", "0", CVAR_CHEAT },
00433         { &d_asynchronousGroupAI, "d_asynchronousGroupAI", "0", CVAR_CHEAT },
00434         
00435         //0 = never (BORING)
00436         //1 = kyle only
00437         //2 = kyle and last enemy jedi
00438         //3 = kyle and any enemy jedi
00439         //4 = kyle and last enemy in a group
00440         //5 = kyle and any enemy
00441         //6 = also when kyle takes pain or enemy jedi dodges player saber swing or does an acrobatic evasion
00442 
00443         { &d_slowmodeath, "d_slowmodeath", "0", CVAR_CHEAT },
00444 
00445         { &d_saberCombat, "d_saberCombat", "0", CVAR_CHEAT },
00446 
00447         { &g_spskill, "g_npcspskill", "0", CVAR_ARCHIVE | CVAR_INTERNAL },
00448 
00449         //for overriding the level defaults
00450         { &g_siegeTeam1, "g_siegeTeam1", "none", CVAR_ARCHIVE|CVAR_SERVERINFO, 0, qfalse  },
00451         { &g_siegeTeam2, "g_siegeTeam2", "none", CVAR_ARCHIVE|CVAR_SERVERINFO, 0, qfalse  },
00452 
00453         //mainly for debugging with bots while I'm not around (want the server to
00454         //cycle through levels naturally)
00455         { &d_noIntermissionWait, "d_noIntermissionWait", "0", CVAR_CHEAT, 0, qfalse  },
00456 
00457         { &g_austrian, "g_austrian", "0", CVAR_ARCHIVE, 0, qfalse  },
00458 // nmckenzie:
00459 // DUEL_HEALTH
00460         { &g_showDuelHealths, "g_showDuelHealths", "0", CVAR_SERVERINFO },
00461         { &g_powerDuelStartHealth, "g_powerDuelStartHealth", "150", CVAR_ARCHIVE, 0, qtrue  },
00462         { &g_powerDuelEndHealth, "g_powerDuelEndHealth", "90", CVAR_ARCHIVE, 0, qtrue  },
00463 };
00464 
00465 // bk001129 - made static to avoid aliasing
00466 static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[0] );
00467 
00468 
00469 void G_InitGame                                 ( int levelTime, int randomSeed, int restart );
00470 void G_RunFrame                                 ( int levelTime );
00471 void G_ShutdownGame                             ( int restart );
00472 void CheckExitRules                             ( void );
00473 void G_ROFF_NotetrackCallback   ( gentity_t *cent, const char *notetrack);
00474 
00475 extern stringID_table_t setTable[];
00476 
00477 qboolean G_ParseSpawnVars( qboolean inSubBSP );
00478 void G_SpawnGEntityFromSpawnVars( qboolean inSubBSP );
00479 
00480 
00481 qboolean NAV_ClearPathToPoint( gentity_t *self, vec3_t pmins, vec3_t pmaxs, vec3_t point, int clipmask, int okToHitEntNum );
00482 qboolean NPC_ClearLOS2( gentity_t *ent, const vec3_t end );
00483 int NAVNEW_ClearPathBetweenPoints(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int ignore, int clipmask);
00484 qboolean NAV_CheckNodeFailedForEnt( gentity_t *ent, int nodeNum );
00485 qboolean G_EntIsUnlockedDoor( int entityNum );
00486 qboolean G_EntIsDoor( int entityNum );
00487 qboolean G_EntIsBreakable( int entityNum );
00488 qboolean G_EntIsRemovableUsable( int entNum );
00489 void CP_FindCombatPointWaypoints( void );
00490 
00491 /*
00492 ================
00493 vmMain
00494 
00495 This is the only way control passes into the module.
00496 This must be the very first function compiled into the .q3vm file
00497 ================
00498 */
00499 #include "../namespace_begin.h"
00500 #ifdef __linux__
00501 extern "C" {
00502 #endif
00503 int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11  ) {
00504         switch ( command ) {
00505         case GAME_INIT:
00506                 G_InitGame( arg0, arg1, arg2 );
00507                 return 0;
00508         case GAME_SHUTDOWN:
00509                 G_ShutdownGame( arg0 );
00510                 return 0;
00511         case GAME_CLIENT_CONNECT:
00512                 return (int)ClientConnect( arg0, arg1, arg2 );
00513         case GAME_CLIENT_THINK:
00514                 ClientThink( arg0, NULL );
00515                 return 0;
00516         case GAME_CLIENT_USERINFO_CHANGED:
00517                 ClientUserinfoChanged( arg0 );
00518                 return 0;
00519         case GAME_CLIENT_DISCONNECT:
00520                 ClientDisconnect( arg0 );
00521                 return 0;
00522         case GAME_CLIENT_BEGIN:
00523                 ClientBegin( arg0, qtrue );
00524                 return 0;
00525         case GAME_CLIENT_COMMAND:
00526                 ClientCommand( arg0 );
00527                 return 0;
00528         case GAME_RUN_FRAME:
00529                 G_RunFrame( arg0 );
00530                 return 0;
00531         case GAME_CONSOLE_COMMAND:
00532                 return ConsoleCommand();
00533         case BOTAI_START_FRAME:
00534                 return BotAIStartFrame( arg0 );
00535         case GAME_ROFF_NOTETRACK_CALLBACK:
00536                 G_ROFF_NotetrackCallback( &g_entities[arg0], (const char *)arg1 );
00537                 return 0;
00538         case GAME_SPAWN_RMG_ENTITY:
00539                 if (G_ParseSpawnVars(qfalse))
00540                 {
00541                         G_SpawnGEntityFromSpawnVars(qfalse);
00542                 }
00543                 return 0;
00544 
00545         //rww - begin icarus callbacks
00546         case GAME_ICARUS_PLAYSOUND:
00547                 {
00548                         T_G_ICARUS_PLAYSOUND *sharedMem = (T_G_ICARUS_PLAYSOUND *)gSharedBuffer;
00549                         return Q3_PlaySound(sharedMem->taskID, sharedMem->entID, sharedMem->name, sharedMem->channel);
00550                 }
00551         case GAME_ICARUS_SET:
00552                 {
00553                         T_G_ICARUS_SET *sharedMem = (T_G_ICARUS_SET *)gSharedBuffer;
00554                         return Q3_Set(sharedMem->taskID, sharedMem->entID, sharedMem->type_name, sharedMem->data);
00555                 }
00556         case GAME_ICARUS_LERP2POS:
00557                 {
00558                         T_G_ICARUS_LERP2POS *sharedMem = (T_G_ICARUS_LERP2POS *)gSharedBuffer;
00559                         if (sharedMem->nullAngles)
00560                         {
00561                                 Q3_Lerp2Pos(sharedMem->taskID, sharedMem->entID, sharedMem->origin, NULL, sharedMem->duration);
00562                         }
00563                         else
00564                         {
00565                                 Q3_Lerp2Pos(sharedMem->taskID, sharedMem->entID, sharedMem->origin, sharedMem->angles, sharedMem->duration);
00566                         }
00567                 }
00568                 return 0;
00569         case GAME_ICARUS_LERP2ORIGIN:
00570                 {
00571                         T_G_ICARUS_LERP2ORIGIN *sharedMem = (T_G_ICARUS_LERP2ORIGIN *)gSharedBuffer;
00572                         Q3_Lerp2Origin(sharedMem->taskID, sharedMem->entID, sharedMem->origin, sharedMem->duration);
00573                 }
00574                 return 0;
00575         case GAME_ICARUS_LERP2ANGLES:
00576                 {
00577                         T_G_ICARUS_LERP2ANGLES *sharedMem = (T_G_ICARUS_LERP2ANGLES *)gSharedBuffer;
00578                         Q3_Lerp2Angles(sharedMem->taskID, sharedMem->entID, sharedMem->angles, sharedMem->duration);
00579                 }
00580                 return 0;
00581         case GAME_ICARUS_GETTAG:
00582                 {
00583                         T_G_ICARUS_GETTAG *sharedMem = (T_G_ICARUS_GETTAG *)gSharedBuffer;
00584                         return Q3_GetTag(sharedMem->entID, sharedMem->name, sharedMem->lookup, sharedMem->info);
00585                 }
00586         case GAME_ICARUS_LERP2START:
00587                 {
00588                         T_G_ICARUS_LERP2START *sharedMem = (T_G_ICARUS_LERP2START *)gSharedBuffer;
00589                         Q3_Lerp2Start(sharedMem->entID, sharedMem->taskID, sharedMem->duration);
00590                 }
00591                 return 0;
00592         case GAME_ICARUS_LERP2END:
00593                 {
00594                         T_G_ICARUS_LERP2END *sharedMem = (T_G_ICARUS_LERP2END *)gSharedBuffer;
00595                         Q3_Lerp2End(sharedMem->entID, sharedMem->taskID, sharedMem->duration);
00596                 }
00597                 return 0;
00598         case GAME_ICARUS_USE:
00599                 {
00600                         T_G_ICARUS_USE *sharedMem = (T_G_ICARUS_USE *)gSharedBuffer;
00601                         Q3_Use(sharedMem->entID, sharedMem->target);
00602                 }
00603                 return 0;
00604         case GAME_ICARUS_KILL:
00605                 {
00606                         T_G_ICARUS_KILL *sharedMem = (T_G_ICARUS_KILL *)gSharedBuffer;
00607                         Q3_Kill(sharedMem->entID, sharedMem->name);
00608                 }
00609                 return 0;
00610         case GAME_ICARUS_REMOVE:
00611                 {
00612                         T_G_ICARUS_REMOVE *sharedMem = (T_G_ICARUS_REMOVE *)gSharedBuffer;
00613                         Q3_Remove(sharedMem->entID, sharedMem->name);
00614                 }
00615                 return 0;
00616         case GAME_ICARUS_PLAY:
00617                 {
00618                         T_G_ICARUS_PLAY *sharedMem = (T_G_ICARUS_PLAY *)gSharedBuffer;
00619                         Q3_Play(sharedMem->taskID, sharedMem->entID, sharedMem->type, sharedMem->name);
00620                 }
00621                 return 0;
00622         case GAME_ICARUS_GETFLOAT:
00623                 {
00624                         T_G_ICARUS_GETFLOAT *sharedMem = (T_G_ICARUS_GETFLOAT *)gSharedBuffer;
00625                         return Q3_GetFloat(sharedMem->entID, sharedMem->type, sharedMem->name, &sharedMem->value);
00626                 }
00627         case GAME_ICARUS_GETVECTOR:
00628                 {
00629                         T_G_ICARUS_GETVECTOR *sharedMem = (T_G_ICARUS_GETVECTOR *)gSharedBuffer;
00630                         return Q3_GetVector(sharedMem->entID, sharedMem->type, sharedMem->name, sharedMem->value);
00631                 }
00632         case GAME_ICARUS_GETSTRING:
00633                 {
00634                         T_G_ICARUS_GETSTRING *sharedMem = (T_G_ICARUS_GETSTRING *)gSharedBuffer;
00635                         int r;
00636                         char *crap = NULL; //I am sorry for this -rww
00637                         char **morecrap = &crap; //and this
00638                         r = Q3_GetString(sharedMem->entID, sharedMem->type, sharedMem->name, morecrap);
00639 
00640                         if (crap)
00641                         { //success!
00642                                 strcpy(sharedMem->value, crap);
00643                         }
00644 
00645                         return r;
00646                 }
00647         case GAME_ICARUS_SOUNDINDEX:
00648                 {
00649                         T_G_ICARUS_SOUNDINDEX *sharedMem = (T_G_ICARUS_SOUNDINDEX *)gSharedBuffer;
00650                         G_SoundIndex(sharedMem->filename);
00651                 }
00652                 return 0;
00653         case GAME_ICARUS_GETSETIDFORSTRING:
00654                 {
00655                         T_G_ICARUS_GETSETIDFORSTRING *sharedMem = (T_G_ICARUS_GETSETIDFORSTRING *)gSharedBuffer;
00656                         return GetIDForString(setTable, sharedMem->string);
00657                 }
00658         //rww - end icarus callbacks
00659 
00660         case GAME_NAV_CLEARPATHTOPOINT:
00661                 return NAV_ClearPathToPoint(&g_entities[arg0], (float *)arg1, (float *)arg2, (float *)arg3, arg4, arg5);
00662         case GAME_NAV_CLEARLOS:
00663                 return NPC_ClearLOS2(&g_entities[arg0], (const float *)arg1);
00664         case GAME_NAV_CLEARPATHBETWEENPOINTS:
00665                 return NAVNEW_ClearPathBetweenPoints((float *)arg0, (float *)arg1, (float *)arg2, (float *)arg3, arg4, arg5);
00666         case GAME_NAV_CHECKNODEFAILEDFORENT:
00667                 return NAV_CheckNodeFailedForEnt(&g_entities[arg0], arg1);
00668         case GAME_NAV_ENTISUNLOCKEDDOOR:
00669                 return G_EntIsUnlockedDoor(arg0);
00670         case GAME_NAV_ENTISDOOR:
00671                 return G_EntIsDoor(arg0);
00672         case GAME_NAV_ENTISBREAKABLE:
00673                 return G_EntIsBreakable(arg0);
00674         case GAME_NAV_ENTISREMOVABLEUSABLE:
00675                 return G_EntIsRemovableUsable(arg0);
00676         case GAME_NAV_FINDCOMBATPOINTWAYPOINTS:
00677                 CP_FindCombatPointWaypoints();
00678                 return 0;
00679         case GAME_GETITEMINDEXBYTAG:
00680                 return BG_GetItemIndexByTag(arg0, arg1);
00681         }
00682 
00683         return -1;
00684 }
00685 #ifdef __linux__
00686 }
00687 #endif
00688 #include "../namespace_end.h"
00689 
00690 
00691 void QDECL G_Printf( const char *fmt, ... ) {
00692         va_list         argptr;
00693         char            text[1024];
00694 
00695         va_start (argptr, fmt);
00696         vsprintf (text, fmt, argptr);
00697         va_end (argptr);
00698 
00699         trap_Printf( text );
00700 }
00701 
00702 void QDECL G_Error( const char *fmt, ... ) {
00703         va_list         argptr;
00704         char            text[1024];
00705 
00706         va_start (argptr, fmt);
00707         vsprintf (text, fmt, argptr);
00708         va_end (argptr);
00709 
00710         trap_Error( text );
00711 }
00712 
00713 /*
00714 ================
00715 G_FindTeams
00716 
00717 Chain together all entities with a matching team field.
00718 Entity teams are used for item groups and multi-entity mover groups.
00719 
00720 All but the first will have the FL_TEAMSLAVE flag set and teammaster field set
00721 All but the last will have the teamchain field set to the next one
00722 ================
00723 */
00724 void G_FindTeams( void ) {
00725         gentity_t       *e, *e2;
00726         int             i, j;
00727         int             c, c2;
00728 
00729         c = 0;
00730         c2 = 0;
00731         for ( i=1, e=g_entities+i ; i < level.num_entities ; i++,e++ ){
00732                 if (!e->inuse)
00733                         continue;
00734                 if (!e->team)
00735                         continue;
00736                 if (e->flags & FL_TEAMSLAVE)
00737                         continue;
00738                 if (e->r.contents==CONTENTS_TRIGGER)
00739                         continue;//triggers NEVER link up in teams!
00740                 e->teammaster = e;
00741                 c++;
00742                 c2++;
00743                 for (j=i+1, e2=e+1 ; j < level.num_entities ; j++,e2++)
00744                 {
00745                         if (!e2->inuse)
00746                                 continue;
00747                         if (!e2->team)
00748                                 continue;
00749                         if (e2->flags & FL_TEAMSLAVE)
00750                                 continue;
00751                         if (!strcmp(e->team, e2->team))
00752                         {
00753                                 c2++;
00754                                 e2->teamchain = e->teamchain;
00755                                 e->teamchain = e2;
00756                                 e2->teammaster = e;
00757                                 e2->flags |= FL_TEAMSLAVE;
00758 
00759                                 // make sure that targets only point at the master
00760                                 if ( e2->targetname ) {
00761                                         e->targetname = e2->targetname;
00762                                         e2->targetname = NULL;
00763                                 }
00764                         }
00765                 }
00766         }
00767 
00768 //      G_Printf ("%i teams with %i entities\n", c, c2);
00769 }
00770 
00771 void G_RemapTeamShaders( void ) {
00772 #if 0
00773         char string[1024];
00774         float f = level.time * 0.001;
00775         Com_sprintf( string, sizeof(string), "team_icon/%s_red", g_redteam.string );
00776         AddRemap("textures/ctf2/redteam01", string, f); 
00777         AddRemap("textures/ctf2/redteam02", string, f); 
00778         Com_sprintf( string, sizeof(string), "team_icon/%s_blue", g_blueteam.string );
00779         AddRemap("textures/ctf2/blueteam01", string, f); 
00780         AddRemap("textures/ctf2/blueteam02", string, f); 
00781         trap_SetConfigstring(CS_SHADERSTATE, BuildShaderStateConfig());
00782 #endif
00783 }
00784 
00785 
00786 /*
00787 =================
00788 G_RegisterCvars
00789 =================
00790 */
00791 void G_RegisterCvars( void ) {
00792         int                     i;
00793         cvarTable_t     *cv;
00794         qboolean remapped = qfalse;
00795 
00796         for ( i = 0, cv = gameCvarTable ; i < gameCvarTableSize ; i++, cv++ ) {
00797                 trap_Cvar_Register( cv->vmCvar, cv->cvarName,
00798                         cv->defaultString, cv->cvarFlags );
00799                 if ( cv->vmCvar )
00800                         cv->modificationCount = cv->vmCvar->modificationCount;
00801 
00802                 if (cv->teamShader) {
00803                         remapped = qtrue;
00804                 }
00805         }
00806 
00807         if (remapped) {
00808                 G_RemapTeamShaders();
00809         }
00810 
00811         // check some things
00812         if ( g_gametype.integer < 0 || g_gametype.integer >= GT_MAX_GAME_TYPE ) {
00813                 G_Printf( "g_gametype %i is out of range, defaulting to 0\n", g_gametype.integer );
00814                 trap_Cvar_Set( "g_gametype", "0" );
00815         }
00816         else if (g_gametype.integer == GT_HOLOCRON)
00817         {
00818                 G_Printf( "This gametype is not supported.\n" );
00819                 trap_Cvar_Set( "g_gametype", "0" );
00820         }
00821         else if (g_gametype.integer == GT_JEDIMASTER)
00822         {
00823                 G_Printf( "This gametype is not supported.\n" );
00824                 trap_Cvar_Set( "g_gametype", "0" );
00825         }
00826         else if (g_gametype.integer == GT_CTY)
00827         {
00828                 G_Printf( "This gametype is not supported.\n" );
00829                 trap_Cvar_Set( "g_gametype", "0" );
00830         }
00831 
00832         level.warmupModificationCount = g_warmup.modificationCount;
00833 }
00834 
00835 /*
00836 =================
00837 G_UpdateCvars
00838 =================
00839 */
00840 void G_UpdateCvars( void ) {
00841         int                     i;
00842         cvarTable_t     *cv;
00843         qboolean remapped = qfalse;
00844 
00845         for ( i = 0, cv = gameCvarTable ; i < gameCvarTableSize ; i++, cv++ ) {
00846                 if ( cv->vmCvar ) {
00847                         trap_Cvar_Update( cv->vmCvar );
00848 
00849                         if ( cv->modificationCount != cv->vmCvar->modificationCount ) {
00850                                 cv->modificationCount = cv->vmCvar->modificationCount;
00851 
00852                                 if ( cv->trackChange ) {
00853                                         trap_SendServerCommand( -1, va("print \"Server: %s changed to %s\n\"", 
00854                                                 cv->cvarName, cv->vmCvar->string ) );
00855                                 }
00856 
00857                                 if (cv->teamShader) {
00858                                         remapped = qtrue;
00859                                 }                               
00860                         }
00861                 }
00862         }
00863 
00864         if (remapped) {
00865                 G_RemapTeamShaders();
00866         }
00867 }
00868 
00869 char gSharedBuffer[MAX_G_SHARED_BUFFER_SIZE];
00870 
00871 #include "../namespace_begin.h"
00872 void WP_SaberLoadParms( void );
00873 void BG_VehicleLoadParms( void );
00874 #include "../namespace_end.h"
00875 
00876 /*
00877 ============
00878 G_InitGame
00879 
00880 ============
00881 */
00882 extern void RemoveAllWP(void);
00883 extern void BG_ClearVehicleParseParms(void);
00884 void G_InitGame( int levelTime, int randomSeed, int restart ) {
00885         int                                     i;
00886         vmCvar_t        mapname;
00887         vmCvar_t        ckSum;
00888 
00889 #ifdef _XBOX
00890         if(restart) {
00891                 BG_ClearVehicleParseParms();
00892                 RemoveAllWP();
00893         }
00894 #endif
00895 
00896         //Init RMG to 0, it will be autoset to 1 if there is terrain on the level.
00897         trap_Cvar_Set("RMG", "0");
00898         g_RMG.integer = 0;
00899 
00900         //Clean up any client-server ghoul2 instance attachments that may still exist exe-side
00901         trap_G2API_CleanEntAttachments();
00902 
00903         BG_InitAnimsets(); //clear it out
00904 
00905         B_InitAlloc(); //make sure everything is clean
00906 
00907         trap_SV_RegisterSharedMemory(gSharedBuffer);
00908 
00909         //Load external vehicle data
00910         BG_VehicleLoadParms();
00911 
00912         G_Printf ("------- Game Initialization -------\n");
00913         G_Printf ("gamename: %s\n", GAMEVERSION);
00914         G_Printf ("gamedate: %s\n", __DATE__);
00915 
00916         srand( randomSeed );
00917 
00918         G_RegisterCvars();
00919 
00920         G_ProcessIPBans();
00921 
00922         G_InitMemory();
00923 
00924         // set some level globals
00925         memset( &level, 0, sizeof( level ) );
00926         level.time = levelTime;
00927         level.startTime = levelTime;
00928 
00929         level.snd_fry = G_SoundIndex("sound/player/fry.wav");   // FIXME standing in lava /