codemp/game/g_main.c File Reference

#include "g_local.h"
#include "g_ICARUScb.h"
#include "g_nav.h"
#include "bg_saga.h"
#include "../namespace_begin.h"
#include "../namespace_end.h"

Go to the source code of this file.

Data Structures

struct  cvarTable_t

Defines

#define JETPACK_DEFUEL_RATE   200
#define JETPACK_REFUEL_RATE   150
#define CLOAK_DEFUEL_RATE   200
#define CLOAK_REFUEL_RATE   150

Functions

void G_InitGame (int levelTime, int randomSeed, int restart)
void G_RunFrame (int levelTime)
void G_ShutdownGame (int restart)
void CheckExitRules (void)
void G_ROFF_NotetrackCallback (gentity_t *cent, const char *notetrack)
qboolean G_ParseSpawnVars (qboolean inSubBSP)
void G_SpawnGEntityFromSpawnVars (qboolean inSubBSP)
qboolean NAV_ClearPathToPoint (gentity_t *self, vec3_t pmins, vec3_t pmaxs, vec3_t point, int clipmask, int okToHitEntNum)
qboolean NPC_ClearLOS2 (gentity_t *ent, const vec3_t end)
int NAVNEW_ClearPathBetweenPoints (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int ignore, int clipmask)
qboolean NAV_CheckNodeFailedForEnt (gentity_t *ent, int nodeNum)
qboolean G_EntIsUnlockedDoor (int entityNum)
qboolean G_EntIsDoor (int entityNum)
qboolean G_EntIsBreakable (int entityNum)
qboolean G_EntIsRemovableUsable (int entNum)
void CP_FindCombatPointWaypoints (void)
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)
void QDECL G_Printf (const char *fmt,...)
void QDECL G_Error (const char *fmt,...)
void G_FindTeams (void)
void G_RemapTeamShaders (void)
void G_RegisterCvars (void)
void G_UpdateCvars (void)
void WP_SaberLoadParms (void)
void BG_VehicleLoadParms (void)
void RemoveAllWP (void)
void BG_ClearVehicleParseParms (void)
void QDECL Com_Error (int level, const char *error,...)
void QDECL Com_Printf (const char *msg,...)
void AddTournamentPlayer (void)
void RemoveTournamentLoser (void)
void G_PowerDuelCount (int *loners, int *doubles, qboolean countSpec)
void AddPowerDuelPlayers (void)
void RemovePowerDuelLosers (void)
void RemoveDuelDrawLoser (void)
void RemoveTournamentWinner (void)
void AdjustTournamentScores (void)
int QDECL SortRanks (const void *a, const void *b)
qboolean G_CanResetDuelists (void)
void G_ResetDuelists (void)
void CalculateRanks (void)
void SendScoreboardMessageToAllClients (void)
void MoveClientToIntermission (gentity_t *ent)
void FindIntermissionPoint (void)
qboolean DuelLimitHit (void)
void BeginIntermission (void)
void DuelResetWinsLosses (void)
void SiegeDoTeamAssign (void)
void ExitLevel (void)
void QDECL G_LogPrintf (const char *fmt,...)
void LogExit (const char *string)
void CheckIntermissionExit (void)
qboolean ScoreIsTied (void)
void G_RemoveDuelist (int team)
void CheckTournament (void)
void G_KickAllBots (void)
void CheckVote (void)
void PrintTeam (int team, char *message)
void SetLeader (int team, int client)
void CheckTeamLeader (int team)
void CheckTeamVote (int team)
void CheckCvars (void)
void G_RunThink (gentity_t *ent)
void NAV_CheckCalcPaths (void)
int BG_GetTime (void)
void ClearNPCGlobals (void)
void AI_UpdateGroups (void)
void ClearPlayerAlertEvents (void)
void SiegeCheckTimers (void)
void WP_SaberStartMissileBlockCheck (gentity_t *self, usercmd_t *ucmd)
void Jedi_Decloak (gentity_t *self)
qboolean G_PointInBounds (vec3_t point, vec3_t mins, vec3_t maxs)
const char * G_GetStringEdString (char *refSection, char *refName)

Variables

level_locals_t level
int eventClearTime = 0
int fatalErrors
int killPlayerTimer = 0
gentity_t g_entities [MAX_GENTITIES]
gclient_t g_clients [MAX_CLIENTS]
qboolean gDuelExit = qfalse
vmCvar_t g_trueJedi
vmCvar_t g_gametype
vmCvar_t g_MaxHolocronCarry
vmCvar_t g_ff_objectives
vmCvar_t g_autoMapCycle
vmCvar_t g_dmflags
vmCvar_t g_maxForceRank
vmCvar_t g_forceBasedTeams
vmCvar_t g_privateDuel
vmCvar_t g_allowNPC
vmCvar_t g_armBreakage
vmCvar_t g_saberLocking
vmCvar_t g_saberLockFactor
vmCvar_t g_saberTraceSaberFirst
vmCvar_t d_saberKickTweak
vmCvar_t d_powerDuelPrint
vmCvar_t d_saberGhoul2Collision
vmCvar_t g_saberBladeFaces
vmCvar_t d_saberAlwaysBoxTrace
vmCvar_t d_saberBoxTraceSize
vmCvar_t d_siegeSeekerNPC
vmCvar_t g_debugMelee
vmCvar_t g_stepSlideFix
vmCvar_t g_noSpecMove
vmCvar_t d_perPlayerGhoul2
vmCvar_t d_projectileGhoul2Collision
vmCvar_t g_g2TraceLod
vmCvar_t g_optvehtrace
vmCvar_t g_locationBasedDamage
vmCvar_t g_allowHighPingDuelist
vmCvar_t g_logClientInfo
vmCvar_t g_slowmoDuelEnd
vmCvar_t g_saberDamageScale
vmCvar_t g_useWhileThrowing
vmCvar_t g_RMG
vmCvar_t g_svfps
vmCvar_t g_forceRegenTime
vmCvar_t g_spawnInvulnerability
vmCvar_t g_forcePowerDisable
vmCvar_t g_weaponDisable
vmCvar_t g_duelWeaponDisable
vmCvar_t g_allowDuelSuicide
vmCvar_t g_fraglimitVoteCorrection
vmCvar_t g_fraglimit
vmCvar_t g_duel_fraglimit
vmCvar_t g_timelimit
vmCvar_t g_capturelimit
vmCvar_t d_saberInterpolate
vmCvar_t g_friendlyFire
vmCvar_t g_friendlySaber
vmCvar_t g_password
vmCvar_t g_needpass
vmCvar_t g_maxclients
vmCvar_t g_maxGameClients
vmCvar_t g_dedicated
vmCvar_t g_developer
vmCvar_t g_speed
vmCvar_t g_gravity
vmCvar_t g_cheats
vmCvar_t g_knockback
vmCvar_t g_quadfactor
vmCvar_t g_forcerespawn
vmCvar_t g_siegeRespawn
vmCvar_t g_inactivity
vmCvar_t g_debugMove
vmCvar_t g_debugDamage
vmCvar_t g_debugAlloc
vmCvar_t g_debugServerSkel
vmCvar_t g_weaponRespawn
vmCvar_t g_weaponTeamRespawn
vmCvar_t g_adaptRespawn
vmCvar_t g_motd
vmCvar_t g_synchronousClients
vmCvar_t g_warmup
vmCvar_t g_doWarmup
vmCvar_t g_restarted
vmCvar_t g_log
vmCvar_t g_logSync
vmCvar_t g_statLog
vmCvar_t g_statLogFile
vmCvar_t g_blood
vmCvar_t g_podiumDist
vmCvar_t g_podiumDrop
vmCvar_t g_allowVote
vmCvar_t g_teamAutoJoin
vmCvar_t g_teamForceBalance
vmCvar_t g_banIPs
vmCvar_t g_filterBan
vmCvar_t g_debugForward
vmCvar_t g_debugRight
vmCvar_t g_debugUp
vmCvar_t g_smoothClients
vmCvar_t pmove_fixed
vmCvar_t pmove_msec
vmCvar_t g_listEntity
vmCvar_t g_singlePlayer
vmCvar_t g_enableBreath
vmCvar_t g_dismember
vmCvar_t g_forceDodge
vmCvar_t g_timeouttospec
vmCvar_t g_saberDmgVelocityScale
vmCvar_t g_saberDmgDelay_Idle
vmCvar_t g_saberDmgDelay_Wound
vmCvar_t g_saberDebugPrint
vmCvar_t g_siegeTeamSwitch
vmCvar_t bg_fighterAltControl
vmCvar_t g_saberDebugBox
vmCvar_t d_altRoutes
vmCvar_t d_patched
vmCvar_t g_saberRealisticCombat
vmCvar_t g_saberRestrictForce
vmCvar_t d_saberSPStyleDamage
vmCvar_t g_debugSaberLocks
vmCvar_t g_saberLockRandomNess
vmCvar_t g_saberWallDamageScale
vmCvar_t d_saberStanceDebug
vmCvar_t debugNPCAI
vmCvar_t debugNPCFreeze
vmCvar_t debugNPCAimingBeam
vmCvar_t debugBreak
vmCvar_t debugNoRoam
vmCvar_t d_saberCombat
vmCvar_t d_JediAI
vmCvar_t d_noGroupAI
vmCvar_t d_asynchronousGroupAI
vmCvar_t d_slowmodeath
vmCvar_t d_noIntermissionWait
vmCvar_t g_spskill
vmCvar_t g_siegeTeam1
vmCvar_t g_siegeTeam2
vmCvar_t g_austrian
vmCvar_t g_powerDuelStartHealth
vmCvar_t g_powerDuelEndHealth
vmCvar_t g_showDuelHealths
stringID_table_t setTable []
char gSharedBuffer [MAX_G_SHARED_BUFFER_SIZE]
qboolean g_duelAssigning = qfalse
qboolean g_dontFrickinCheck = qfalse
qboolean gQueueScoreMessage = qfalse
int gQueueScoreMessageTime = 0
qboolean g_noPDuelCheck = qfalse
qboolean gSiegeRoundBegun
qboolean gSiegeRoundEnded
qboolean gSiegeRoundWinningTeam
siegePers_t g_siegePersistant
qboolean gDidDuelStuff = qfalse
qboolean g_endPDuel = qfalse
int g_duelPrintTimer = 0
int g_LastFrameTime = 0
int g_TimeSinceLastFrame = 0
qboolean gDoSlowMoDuel = qfalse
int gSlowMoDuelTime = 0
int g_siegeRespawnCheck = 0


Define Documentation

#define CLOAK_DEFUEL_RATE   200
 

Referenced by G_RunFrame().

#define CLOAK_REFUEL_RATE   150
 

Referenced by G_RunFrame().

#define JETPACK_DEFUEL_RATE   200
 

Referenced by G_RunFrame().

#define JETPACK_REFUEL_RATE   150
 

Referenced by G_RunFrame().


Function Documentation

void AddPowerDuelPlayers void   ) 
 

Definition at line 1330 of file g_main.c.

References client, level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, clientSession_t::duelTeam, DUELTEAM_DOUBLE, DUELTEAM_FREE, DUELTEAM_LONE, g_entities, G_PowerDuelCount(), gclient_t, level, level_locals_t::maxclients, NULL, level_locals_t::numPlayingClients, gclient_s::pers, qfalse, qtrue, gclient_s::sess, clientSession_t::sessionTeam, SetTeam(), SPECTATOR_SCOREBOARD, clientSession_t::spectatorClient, clientSession_t::spectatorState, clientSession_t::spectatorTime, TEAM_SPECTATOR, and level_locals_t::warmupTime.

Referenced by CheckIntermissionExit(), and CheckTournament().

01331 {
01332         int                     i;
01333         int                     loners = 0;
01334         int                     doubles = 0;
01335         int                     nonspecLoners = 0;
01336         int                     nonspecDoubles = 0;
01337         gclient_t       *client;
01338         gclient_t       *nextInLine;
01339 
01340         if ( level.numPlayingClients >= 3 )
01341         {
01342                 return;
01343         }
01344 
01345         nextInLine = NULL;
01346 
01347         G_PowerDuelCount(&nonspecLoners, &nonspecDoubles, qfalse);
01348         if (nonspecLoners >= 1 && nonspecDoubles >= 2)
01349         { //we have enough people, stop
01350                 return;
01351         }
01352 
01353         //Could be written faster, but it's not enough to care I suppose.
01354         G_PowerDuelCount(&loners, &doubles, qtrue);
01355 
01356         if (loners < 1 || doubles < 2)
01357         { //don't bother trying to spawn anyone yet if the balance is not even set up between spectators
01358                 return;
01359         }
01360 
01361         //Count again, with only in-game clients in mind.
01362         loners = nonspecLoners;
01363         doubles = nonspecDoubles;
01364 //      G_PowerDuelCount(&loners, &doubles, qfalse);
01365 
01366         for ( i = 0 ; i < level.maxclients ; i++ ) {
01367                 client = &level.clients[i];
01368                 if ( client->pers.connected != CON_CONNECTED ) {
01369                         continue;
01370                 }
01371                 if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
01372                         continue;
01373                 }
01374                 if (client->sess.duelTeam == DUELTEAM_FREE)
01375                 {
01376                         continue;
01377                 }
01378                 if (client->sess.duelTeam == DUELTEAM_LONE && loners >= 1)
01379                 {
01380                         continue;
01381                 }
01382                 if (client->sess.duelTeam == DUELTEAM_DOUBLE && doubles >= 2)
01383                 {
01384                         continue;
01385                 }
01386 
01387                 // never select the dedicated follow or scoreboard clients
01388                 if ( client->sess.spectatorState == SPECTATOR_SCOREBOARD || 
01389                         client->sess.spectatorClient < 0  ) {
01390                         continue;
01391                 }
01392 
01393                 if ( !nextInLine || client->sess.spectatorTime < nextInLine->sess.spectatorTime ) {
01394                         nextInLine = client;
01395                 }
01396         }
01397 
01398         if ( !nextInLine ) {
01399                 return;
01400         }
01401 
01402         level.warmupTime = -1;
01403 
01404         // set them to free-for-all team
01405         SetTeam( &g_entities[ nextInLine - level.clients ], "f" );
01406 
01407         //Call recursively until everyone is in
01408         AddPowerDuelPlayers();
01409 }

void AddTournamentPlayer void   ) 
 

Definition at line 1232 of file g_main.c.

References client, level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, g_allowHighPingDuelist, g_entities, gclient_t, vmCvar_t::integer, level, level_locals_t::maxclients, NULL, level_locals_t::numPlayingClients, gclient_s::pers, playerState_s::ping, gclient_s::ps, gclient_s::sess, clientSession_t::sessionTeam, SetTeam(), SPECTATOR_SCOREBOARD, clientSession_t::spectatorClient, clientSession_t::spectatorState, clientSession_t::spectatorTime, TEAM_SPECTATOR, and level_locals_t::warmupTime.

Referenced by CheckIntermissionExit(), and CheckTournament().

01232                                  {
01233         int                     i;
01234         gclient_t       *client;
01235         gclient_t       *nextInLine;
01236 
01237         if ( level.numPlayingClients >= 2 ) {
01238                 return;
01239         }
01240 
01241         // never change during intermission
01242 //      if ( level.intermissiontime ) {
01243 //              return;
01244 //      }
01245 
01246         nextInLine = NULL;
01247 
01248         for ( i = 0 ; i < level.maxclients ; i++ ) {
01249                 client = &level.clients[i];
01250                 if ( client->pers.connected != CON_CONNECTED ) {
01251                         continue;
01252                 }
01253                 if (!g_allowHighPingDuelist.integer && client->ps.ping >= 999)
01254                 { //don't add people who are lagging out if cvar is not set to allow it.
01255                         continue;
01256                 }
01257                 if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
01258                         continue;
01259                 }
01260                 // never select the dedicated follow or scoreboard clients
01261                 if ( client->sess.spectatorState == SPECTATOR_SCOREBOARD || 
01262                         client->sess.spectatorClient < 0  ) {
01263                         continue;
01264                 }
01265 
01266                 if ( !nextInLine || client->sess.spectatorTime < nextInLine->sess.spectatorTime ) {
01267                         nextInLine = client;
01268                 }
01269         }
01270 
01271         if ( !nextInLine ) {
01272                 return;
01273         }
01274 
01275         level.warmupTime = -1;
01276 
01277         // set them to free-for-all team
01278         SetTeam( &g_entities[ nextInLine - level.clients ], "f" );
01279 }

void AdjustTournamentScores void   ) 
 

Definition at line 1525 of file g_main.c.

References level_locals_t::clients, ClientUserinfoChanged(), CON_CONNECTED, clientPersistant_t::connected, CS_CLIENT_DUELWINNER, level, clientSession_t::losses, gclient_s::pers, PERS_SCORE, gclient_s::sess, level_locals_t::sortedClients, STAT_ARMOR, STAT_HEALTH, trap_SetConfigstring(), va(), and clientSession_t::wins.

Referenced by BeginIntermission().

01525                                     {
01526         int                     clientNum;
01527 
01528         if (level.clients[level.sortedClients[0]].ps.persistant[PERS_SCORE] ==
01529                 level.clients[level.sortedClients[1]].ps.persistant[PERS_SCORE] &&
01530                 level.clients[level.sortedClients[0]].pers.connected == CON_CONNECTED &&
01531                 level.clients[level.sortedClients[1]].pers.connected == CON_CONNECTED)
01532         {
01533                 int clFirst = level.clients[ level.sortedClients[0] ].ps.stats[STAT_HEALTH] + level.clients[ level.sortedClients[0] ].ps.stats[STAT_ARMOR];
01534                 int clSec = level.clients[ level.sortedClients[1] ].ps.stats[STAT_HEALTH] + level.clients[ level.sortedClients[1] ].ps.stats[STAT_ARMOR];
01535                 int clFailure = 0;
01536                 int clSuccess = 0;
01537 
01538                 if (clFirst > clSec)
01539                 {
01540                         clFailure = 1;
01541                         clSuccess = 0;
01542                 }
01543                 else if (clSec > clFirst)
01544                 {
01545                         clFailure = 0;
01546                         clSuccess = 1;
01547                 }
01548                 else
01549                 {
01550                         clFailure = 2;
01551                         clSuccess = 2;
01552                 }
01553 
01554                 if (clFailure != 2)
01555                 {
01556                         clientNum = level.sortedClients[clSuccess];
01557 
01558                         level.clients[ clientNum ].sess.wins++;
01559                         ClientUserinfoChanged( clientNum );
01560                         trap_SetConfigstring ( CS_CLIENT_DUELWINNER, va("%i", clientNum ) );
01561 
01562                         clientNum = level.sortedClients[clFailure];
01563 
01564                         level.clients[ clientNum ].sess.losses++;
01565                         ClientUserinfoChanged( clientNum );
01566                 }
01567                 else
01568                 {
01569                         clSuccess = 0;
01570                         clFailure = 1;
01571 
01572                         clientNum = level.sortedClients[clSuccess];
01573 
01574                         level.clients[ clientNum ].sess.wins++;
01575                         ClientUserinfoChanged( clientNum );
01576                         trap_SetConfigstring ( CS_CLIENT_DUELWINNER, va("%i", clientNum ) );
01577 
01578                         clientNum = level.sortedClients[clFailure];
01579 
01580                         level.clients[ clientNum ].sess.losses++;
01581                         ClientUserinfoChanged( clientNum );
01582                 }
01583         }
01584         else
01585         {
01586                 clientNum = level.sortedClients[0];
01587                 if ( level.clients[ clientNum ].pers.connected == CON_CONNECTED ) {
01588                         level.clients[ clientNum ].sess.wins++;
01589                         ClientUserinfoChanged( clientNum );
01590 
01591                         trap_SetConfigstring ( CS_CLIENT_DUELWINNER, va("%i", clientNum ) );
01592                 }
01593 
01594                 clientNum = level.sortedClients[1];
01595                 if ( level.clients[ clientNum ].pers.connected == CON_CONNECTED ) {
01596                         level.clients[ clientNum ].sess.losses++;
01597                         ClientUserinfoChanged( clientNum );
01598                 }
01599         }
01600 }

void AI_UpdateGroups void   ) 
 

Definition at line 964 of file NPC_AI_Utils.c.

References AI_RefreshGroup(), d_noGroupAI, level_locals_t::groups, vmCvar_t::integer, level, MAX_FRAME_GROUPS, memset(), AIGroupInfo_s::numGroup, and qfalse.

Referenced by G_RunFrame().

00965 {
00966         int i;
00967 
00968         if ( d_noGroupAI.integer )
00969         {
00970                 return;
00971         }
00972         //Clear all Groups
00973         for ( i = 0; i < MAX_FRAME_GROUPS; i++ ) 
00974         {
00975                 if ( !level.groups[i].numGroup || AI_RefreshGroup( &level.groups[i] ) == qfalse )//level.groups[i].enemy == NULL || 
00976                 {
00977                         memset( &level.groups[i], 0, sizeof( level.groups[i] ) );
00978                 }
00979         }
00980 }

void BeginIntermission void   ) 
 

Definition at line 2019 of file g_main.c.

References AdjustTournamentScores(), client, CS_CLIENT_DUELWINNER, DuelLimitHit(), FindIntermissionPoint(), g_entities, g_gametype, gDuelExit, gentity_t, GT_DUEL, GT_POWERDUEL, vmCvar_t::integer, level_locals_t::intermissiontime, level, level_locals_t::maxclients, MoveClientToIntermission(), qfalse, qtrue, respawn(), SendScoreboardMessageToAllClients(), gclient_s::sess, clientSession_t::sessionTeam, TEAM_SPECTATOR, level_locals_t::time, and trap_SetConfigstring().

Referenced by CheckExitRules(), and Cmd_LevelShot_f().

02019                                {
02020         int                     i;
02021         gentity_t       *client;
02022 
02023         if ( level.intermissiontime ) {
02024                 return;         // already active
02025         }
02026 
02027         // if in tournement mode, change the wins / losses
02028         if ( g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL ) {
02029                 trap_SetConfigstring ( CS_CLIENT_DUELWINNER, "-1" );
02030 
02031                 if (g_gametype.integer != GT_POWERDUEL)
02032                 {
02033                         AdjustTournamentScores();
02034                 }
02035                 if (DuelLimitHit())
02036                 {
02037                         gDuelExit = qtrue;
02038                 }
02039                 else
02040                 {
02041                         gDuelExit = qfalse;
02042                 }
02043         }
02044 
02045         level.intermissiontime = level.time;
02046         FindIntermissionPoint();
02047 
02048         /*
02049         if (g_singlePlayer.integer) {
02050                 trap_Cvar_Set("ui_singlePlayerActive", "0");
02051                 UpdateTournamentInfo();
02052         }
02053         */
02054         //what the? Well, I don't want this to happen.
02055 
02056         // move all clients to the intermission point
02057         for (i=0 ; i< level.maxclients ; i++) {
02058                 client = g_entities + i;
02059                 if (!client->inuse)
02060                         continue;
02061                 // respawn if dead
02062                 if (client->health <= 0) {
02063                         if (g_gametype.integer != GT_POWERDUEL ||
02064                                 !client->client ||
02065                                 client->client->sess.sessionTeam != TEAM_SPECTATOR)
02066                         { //don't respawn spectators in powerduel or it will mess the line order all up
02067                                 respawn(client);
02068                         }
02069                 }
02070                 MoveClientToIntermission( client );
02071         }
02072 
02073         // send the current scoring to all clients
02074         SendScoreboardMessageToAllClients();
02075 
02076 }

void BG_ClearVehicleParseParms void   ) 
 

Definition at line 79 of file bg_vehicleLoad.c.

References VehicleParms, and VehWeaponParms.

Referenced by G_InitGame().

00080 {
00081         //You can't strcat to these forever without clearing them!
00082         VehWeaponParms[0] = 0;
00083         VehicleParms[0] = 0;
00084 }

int BG_GetTime void   ) 
 

Definition at line 3543 of file g_main.c.

References level, and level_locals_t::time.

03544 {
03545         return level.time;
03546 }

void BG_VehicleLoadParms void   ) 
 

void CalculateRanks void   ) 
 

Definition at line 1735 of file g_main.c.

References CheckExitRules(), level_locals_t::clients, CON_CONNECTED, CON_DISCONNECTED, clientPersistant_t::connected, CS_CLIENT_DUELWINNER, CS_SCORES1, CS_SCORES2, level_locals_t::follow1, level_locals_t::follow2, g_entities, g_gametype, gclient_t, gQueueScoreMessage, gQueueScoreMessageTime, GT_DUEL, GT_POWERDUEL, GT_SINGLE_PLAYER, GT_TEAM, gclient_s::iAmALoser, vmCvar_t::integer, level_locals_t::intermissiontime, level, level_locals_t::maxclients, level_locals_t::numConnectedClients, level_locals_t::numNonSpectatorClients, level_locals_t::numPlayingClients, level_locals_t::numteamVotingClients, level_locals_t::numVotingClients, gclient_s::pers, PERS_RANK, PERS_SCORE, playerState_s::persistant, gclient_s::ps, qsort(), qtrue, gentity_s::r, RANK_TIED_FLAG, SCORE_NOT_PRESENT, gclient_s::sess, clientSession_t::sessionTeam, level_locals_t::sortedClients, SortRanks(), SVF_BOT, entityShared_t::svFlags, TEAM_BLUE, TEAM_NUM_TEAMS, TEAM_RED, TEAM_SPECTATOR, level_locals_t::teamScores, level_locals_t::time, trap_SetConfigstring(), va(), and level_locals_t::warmupTime.

Referenced by AddScore(), ClientBegin(), ClientConnect(), ClientDisconnect(), RemovePowerDuelLosers(), Team_TouchOurFlag(), and UpdateTournamentInfo().

01735                             {
01736         int             i;
01737         int             rank;
01738         int             score;
01739         int             newScore;
01740         int             preNumSpec = 0;
01741         //int           nonSpecIndex = -1;
01742         gclient_t       *cl;
01743 
01744         preNumSpec = level.numNonSpectatorClients;
01745 
01746         level.follow1 = -1;
01747         level.follow2 = -1;
01748         level.numConnectedClients = 0;
01749         level.numNonSpectatorClients = 0;
01750         level.numPlayingClients = 0;
01751         level.numVotingClients = 0;             // don't count bots
01752         for ( i = 0; i < TEAM_NUM_TEAMS; i++ ) {
01753                 level.numteamVotingClients[i] = 0;
01754         }
01755         for ( i = 0 ; i < level.maxclients ; i++ ) {
01756                 if ( level.clients[i].pers.connected != CON_DISCONNECTED ) {
01757                         level.sortedClients[level.numConnectedClients] = i;
01758                         level.numConnectedClients++;
01759 
01760                         if ( level.clients[i].sess.sessionTeam != TEAM_SPECTATOR || g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL )
01761                         {
01762                                 if (level.clients[i].sess.sessionTeam != TEAM_SPECTATOR)
01763                                 {
01764                                         level.numNonSpectatorClients++;
01765                                         //nonSpecIndex = i;
01766                                 }
01767                         
01768                                 // decide if this should be auto-followed
01769                                 if ( level.clients[i].pers.connected == CON_CONNECTED )
01770                                 {
01771                                         if (level.clients[i].sess.sessionTeam != TEAM_SPECTATOR || level.clients[i].iAmALoser)
01772                                         {
01773                                                 level.numPlayingClients++;
01774                                         }
01775                                         if ( !(g_entities[i].r.svFlags & SVF_BOT) )
01776                                         {
01777                                                 level.numVotingClients++;
01778                                                 if ( level.clients[i].sess.sessionTeam == TEAM_RED )
01779                                                         level.numteamVotingClients[0]++;
01780                                                 else if ( level.clients[i].sess.sessionTeam == TEAM_BLUE )
01781                                                         level.numteamVotingClients[1]++;
01782                                         }
01783                                         if ( level.follow1 == -1 ) {
01784                                                 level.follow1 = i;
01785                                         } else if ( level.follow2 == -1 ) {
01786                                                 level.follow2 = i;
01787                                         }
01788                                 }
01789                         }
01790                 }
01791         }
01792 
01793         //if (!g_warmup.integer)
01794         if (1)
01795         {
01796                 level.warmupTime = 0;
01797         }
01798 
01799         /*
01800         if (level.numNonSpectatorClients == 2 && preNumSpec < 2 && nonSpecIndex != -1 && g_gametype.integer == GT_DUEL && !level.warmupTime)
01801         {
01802                 gentity_t *currentWinner = G_GetDuelWinner(&level.clients[nonSpecIndex]);
01803 
01804                 if (currentWinner && currentWinner->client)
01805                 {
01806                         trap_SendServerCommand( -1, va("cp \"%s" S_COLOR_WHITE " %s %s\n\"",
01807                         currentWinner->client->pers.netname, G_GetStringEdString("MP_SVGAME", "VERSUS"), level.clients[nonSpecIndex].pers.netname));
01808                 }
01809         }
01810         */
01811         //NOTE: for now not doing this either. May use later if appropriate.
01812 
01813         qsort( level.sortedClients, level.numConnectedClients, 
01814                 sizeof(level.sortedClients[0]), SortRanks );
01815 
01816         // set the rank value for all clients that are connected and not spectators
01817         if ( g_gametype.integer >= GT_TEAM ) {
01818                 // in team games, rank is just the order of the teams, 0=red, 1=blue, 2=tied
01819                 for ( i = 0;  i < level.numConnectedClients; i++ ) {
01820                         cl = &level.clients[ level.sortedClients[i] ];
01821                         if ( level.teamScores[TEAM_RED] == level.teamScores[TEAM_BLUE] ) {
01822                                 cl->ps.persistant[PERS_RANK] = 2;
01823                         } else if ( level.teamScores[TEAM_RED] > level.teamScores[TEAM_BLUE] ) {
01824                                 cl->ps.persistant[PERS_RANK] = 0;
01825                         } else {
01826                                 cl->ps.persistant[PERS_RANK] = 1;
01827                         }
01828                 }
01829         } else {        
01830                 rank = -1;
01831                 score = 0;
01832                 for ( i = 0;  i < level.numPlayingClients; i++ ) {
01833                         cl = &level.clients[ level.sortedClients[i] ];
01834                         newScore = cl->ps.persistant[PERS_SCORE];
01835                         if ( i == 0 || newScore != score ) {
01836                                 rank = i;
01837                                 // assume we aren't tied until the next client is checked
01838                                 level.clients[ level.sortedClients[i] ].ps.persistant[PERS_RANK] = rank;
01839                         } else {
01840                                 // we are tied with the previous client
01841                                 level.clients[ level.sortedClients[i-1] ].ps.persistant[PERS_RANK] = rank | RANK_TIED_FLAG;
01842                                 level.clients[ level.sortedClients[i] ].ps.persistant[PERS_RANK] = rank | RANK_TIED_FLAG;
01843                         }
01844                         score = newScore;
01845                         if ( g_gametype.integer == GT_SINGLE_PLAYER && level.numPlayingClients == 1 ) {
01846                                 level.clients[ level.sortedClients[i] ].ps.persistant[PERS_RANK] = rank | RANK_TIED_FLAG;
01847                         }
01848                 }
01849         }
01850 
01851         // set the CS_SCORES1/2 configstrings, which will be visible to everyone
01852         if ( g_gametype.integer >= GT_TEAM ) {
01853                 trap_SetConfigstring( CS_SCORES1, va("%i", level.teamScores[TEAM_RED] ) );
01854                 trap_SetConfigstring( CS_SCORES2, va("%i", level.teamScores[TEAM_BLUE] ) );
01855         } else {
01856                 if ( level.numConnectedClients == 0 ) {
01857                         trap_SetConfigstring( CS_SCORES1, va("%i", SCORE_NOT_PRESENT) );
01858                         trap_SetConfigstring( CS_SCORES2, va("%i", SCORE_NOT_PRESENT) );
01859                 } else if ( level.numConnectedClients == 1 ) {
01860                         trap_SetConfigstring( CS_SCORES1, va("%i", level.clients[ level.sortedClients[0] ].ps.persistant[PERS_SCORE] ) );
01861                         trap_SetConfigstring( CS_SCORES2, va("%i", SCORE_NOT_PRESENT) );
01862                 } else {
01863                         trap_SetConfigstring( CS_SCORES1, va("%i", level.clients[ level.sortedClients[0] ].ps.persistant[PERS_SCORE] ) );
01864                         trap_SetConfigstring( CS_SCORES2, va("%i", level.clients[ level.sortedClients[1] ].ps.persistant[PERS_SCORE] ) );
01865                 }
01866 
01867                 if (g_gametype.integer != GT_DUEL || g_gametype.integer != GT_POWERDUEL)
01868                 { //when not in duel, use this configstring to pass the index of the player currently in first place
01869                         if ( level.numConnectedClients >= 1 )
01870                         {
01871                                 trap_SetConfigstring ( CS_CLIENT_DUELWINNER, va("%i", level.sortedClients[0] ) );
01872                         }
01873                         else
01874                         {
01875                                 trap_SetConfigstring ( CS_CLIENT_DUELWINNER, "-1" );
01876                         }
01877                 }
01878         }
01879 
01880         // see if it is time to end the level
01881         CheckExitRules();
01882 
01883         // if we are at the intermission or in multi-frag Duel game mode, send the new info to everyone
01884         if ( level.intermissiontime || g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL ) {
01885                 gQueueScoreMessage = qtrue;
01886                 gQueueScoreMessageTime = level.time + 500;
01887                 //SendScoreboardMessageToAllClients();
01888                 //rww - Made this operate on a "queue" system because it was causing large overflows
01889         }
01890 }

void CheckCvars void   ) 
 

Definition at line 3439 of file g_main.c.

References g_password, MAX_INFO_STRING, vmCvar_t::modificationCount, Q_stricmp(), strcpy(), vmCvar_t::string, and trap_Cvar_Set().

Referenced by G_RunFrame().

03439                         {
03440         static int lastMod = -1;
03441         
03442         if ( g_password.modificationCount != lastMod ) {
03443                 char password[MAX_INFO_STRING];
03444                 char *c = password;
03445                 lastMod = g_password.modificationCount;
03446                 
03447                 strcpy( password, g_password.string );
03448                 while( *c )
03449                 {
03450                         if ( *c == '%' )
03451                         {
03452                                 *c = '.';
03453                         }
03454                         c++;
03455                 }
03456                 trap_Cvar_Set("g_password", password );
03457 
03458                 if ( *g_password.string && Q_stricmp( g_password.string, "none" ) ) {
03459                         trap_Cvar_Set( "g_needpass", "1" );
03460                 } else {
03461                         trap_Cvar_Set( "g_needpass", "0" );
03462                 }
03463         }
03464 }

void CheckExitRules void   ) 
 

void CheckIntermissionExit void   ) 
 

Definition at line 2301 of file g_main.c.

References AddPowerDuelPlayers(), AddTournamentPlayer(), playerState_s::clientNum, level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, CS_CLIENT_DUELISTS, CS_CLIENT_DUELWINNER, d_noIntermissionWait, DuelLimitHit(), ExitLevel(), level_locals_t::exitTime, g_austrian, g_entities, g_fraglimit, g_gametype, G_LogPrintf(), g_maxclients, gclient_t, gDidDuelStuff, gDuelExit, GT_DUEL, GT_POWERDUEL, vmCvar_t::integer, level_locals_t::intermissiontime, level, level_locals_t::numNonSpectatorClients, level_locals_t::numPlayingClients, gclient_s::pers, PERS_SCORE, gclient_s::ps, qfalse, qtrue, level_locals_t::readyToExit, gclient_s::readyToExit, RemoveDuelDrawLoser(), RemovePowerDuelLosers(), RemoveTournamentLoser(), level_locals_t::sortedClients, STAT_CLIENTS_READY, playerState_s::stats, SVF_BOT, level_locals_t::time, trap_SetConfigstring(), and va().

Referenced by CheckExitRules().

02301                                    {
02302         int                     ready, notReady;
02303         int                     i;
02304         gclient_t       *cl;
02305         int                     readyMask;
02306 
02307         // see which players are ready
02308         ready = 0;
02309         notReady = 0;
02310         readyMask = 0;
02311         for (i=0 ; i< g_maxclients.integer ; i++) {
02312                 cl = level.clients + i;
02313                 if ( cl->pers.connected != CON_CONNECTED ) {
02314                         continue;
02315                 }
02316                 if ( g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT ) {
02317                         continue;
02318                 }
02319 
02320                 if ( cl->readyToExit ) {
02321                         ready++;
02322                         if ( i < 16 ) {
02323                                 readyMask |= 1 << i;
02324                         }
02325                 } else {
02326                         notReady++;
02327                 }
02328         }
02329 
02330         if ( (g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL) && !gDidDuelStuff &&
02331                 (level.time > level.intermissiontime + 2000) )
02332         {
02333                 gDidDuelStuff = qtrue;
02334 
02335                 if ( g_austrian.integer && g_gametype.integer != GT_POWERDUEL )
02336                 {
02337                         G_LogPrintf("Duel Results:\n");
02338                         //G_LogPrintf("Duel Time: %d\n", level.time );
02339                         G_LogPrintf("winner: %s, score: %d, wins/losses: %d/%d\n", 
02340                                 level.clients[level.sortedClients[0]].pers.netname,
02341                                 level.clients[level.sortedClients[0]].ps.persistant[PERS_SCORE],
02342                                 level.clients[level.sortedClients[0]].sess.wins,
02343                                 level.clients[level.sortedClients[0]].sess.losses );
02344                         G_LogPrintf("loser: %s, score: %d, wins/losses: %d/%d\n", 
02345                                 level.clients[level.sortedClients[1]].pers.netname,
02346                                 level.clients[level.sortedClients[1]].ps.persistant[PERS_SCORE],
02347                                 level.clients[level.sortedClients[1]].sess.wins,
02348                                 level.clients[level.sortedClients[1]].sess.losses );
02349                 }
02350                 // if we are running a tournement map, kick the loser to spectator status,
02351                 // which will automatically grab the next spectator and restart
02352                 if (!DuelLimitHit())
02353                 {
02354                         if (g_gametype.integer == GT_POWERDUEL)
02355                         {
02356                                 RemovePowerDuelLosers();
02357                                 AddPowerDuelPlayers();
02358                         }
02359                         else
02360                         {
02361                                 if (level.clients[level.sortedClients[0]].ps.persistant[PERS_SCORE] ==
02362                                         level.clients[level.sortedClients[1]].ps.persistant[PERS_SCORE] &&
02363                                         level.clients[level.sortedClients[0]].pers.connected == CON_CONNECTED &&
02364                                         level.clients[level.sortedClients[1]].pers.connected == CON_CONNECTED)
02365                                 {
02366                                         RemoveDuelDrawLoser();
02367                                 }
02368                                 else
02369                                 {
02370                                         RemoveTournamentLoser();
02371                                 }
02372                                 AddTournamentPlayer();
02373                         }
02374 
02375                         if ( g_austrian.integer )
02376                         {
02377                                 if (g_gametype.integer == GT_POWERDUEL)
02378                                 {
02379                                         G_LogPrintf("Power Duel Initiated: %s %d/%d vs %s %d/%d and %s %d/%d, kill limit: %d\n", 
02380                                                 level.clients[level.sortedClients[0]].pers.netname,
02381                                                 level.clients[level.sortedClients[0]].sess.wins,
02382                                                 level.clients[level.sortedClients[0]].sess.losses,
02383                                                 level.clients[level.sortedClients[1]].pers.netname,
02384                                                 level.clients[level.sortedClients[1]].sess.wins,
02385                                                 level.clients[level.sortedClients[1]].sess.losses,
02386                                                 level.clients[level.sortedClients[2]].pers.netname,
02387                                                 level.clients[level.sortedClients[2]].sess.wins,
02388                                                 level.clients[level.sortedClients[2]].sess.losses,
02389                                                 g_fraglimit.integer );
02390                                 }
02391                                 else
02392                                 {
02393                                         G_LogPrintf("Duel Initiated: %s %d/%d vs %s %d/%d, kill limit: %d\n", 
02394                                                 level.clients[level.sortedClients[0]].pers.netname,
02395                                                 level.clients[level.sortedClients[0]].sess.wins,
02396                                                 level.clients[level.sortedClients[0]].sess.losses,
02397                                                 level.clients[level.sortedClients[1]].pers.netname,
02398                                                 level.clients[level.sortedClients[1]].sess.wins,
02399                                                 level.clients[level.sortedClients[1]].sess.losses,
02400                                                 g_fraglimit.integer );
02401                                 }
02402                         }
02403                         
02404                         if (g_gametype.integer == GT_POWERDUEL)
02405                         {
02406                                 if (level.numPlayingClients >= 3 && level.numNonSpectatorClients >= 3)
02407                                 {
02408                                         trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("%i|%i|%i", level.sortedClients[0], level.sortedClients[1], level.sortedClients[2] ) );
02409                                         trap_SetConfigstring ( CS_CLIENT_DUELWINNER, "-1" );
02410                                 }                       
02411                         }
02412                         else
02413                         {
02414                                 if (level.numPlayingClients >= 2)
02415                                 {
02416                                         trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("%i|%i", level.sortedClients[0], level.sortedClients[1] ) );
02417                                         trap_SetConfigstring ( CS_CLIENT_DUELWINNER, "-1" );
02418                                 }
02419                         }
02420 
02421                         return; 
02422                 }
02423 
02424                 if ( g_austrian.integer && g_gametype.integer != GT_POWERDUEL )
02425                 {
02426                         G_LogPrintf("Duel Tournament Winner: %s wins/losses: %d/%d\n", 
02427                                 level.clients[level.sortedClients[0]].pers.netname,
02428                                 level.clients[level.sortedClients[0]].sess.wins,
02429                                 level.clients[level.sortedClients[0]].sess.losses );
02430                 }
02431 
02432                 if (g_gametype.integer == GT_POWERDUEL)
02433                 {
02434                         RemovePowerDuelLosers();
02435                         AddPowerDuelPlayers();
02436 
02437                         if (level.numPlayingClients >= 3 && level.numNonSpectatorClients >= 3)
02438                         {
02439                                 trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("%i|%i|%i", level.sortedClients[0], level.sortedClients[1], level.sortedClients[2] ) );
02440                                 trap_SetConfigstring ( CS_CLIENT_DUELWINNER, "-1" );
02441                         }
02442                 }
02443                 else
02444                 {
02445                         //this means we hit the duel limit so reset the wins/losses
02446                         //but still push the loser to the back of the line, and retain the order for
02447                         //the map change
02448                         if (level.clients[level.sortedClients[0]].ps.persistant[PERS_SCORE] ==
02449                                 level.clients[level.sortedClients[1]].ps.persistant[PERS_SCORE] &&
02450                                 level.clients[level.sortedClients[0]].pers.connected == CON_CONNECTED &&
02451                                 level.clients[level.sortedClients[1]].pers.connected == CON_CONNECTED)
02452                         {
02453                                 RemoveDuelDrawLoser();
02454                         }
02455                         else
02456                         {
02457                                 RemoveTournamentLoser();
02458                         }
02459 
02460                         AddTournamentPlayer();
02461 
02462                         if (level.numPlayingClients >= 2)
02463                         {
02464                                 trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("%i|%i", level.sortedClients[0], level.sortedClients[1] ) );
02465                                 trap_SetConfigstring ( CS_CLIENT_DUELWINNER, "-1" );
02466                         }
02467                 }
02468         }
02469 
02470         if ((g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL) && !gDuelExit)
02471         { //in duel, we have different behaviour for between-round intermissions
02472                 if ( level.time > level.intermissiontime + 4000 )
02473                 { //automatically go to next after 4 seconds
02474                         ExitLevel();
02475                         return;
02476                 }
02477 
02478                 for (i=0 ; i< g_maxclients.integer ; i++)
02479                 { //being in a "ready" state is not necessary here, so clear it for everyone
02480                   //yes, I also thinking holding this in a ps value uniquely for each player
02481                   //is bad and wrong, but it wasn't my idea.
02482                         cl = level.clients + i;
02483                         if ( cl->pers.connected != CON_CONNECTED )
02484                         {
02485                                 continue;
02486                         }
02487                         cl->ps.stats[STAT_CLIENTS_READY] = 0;
02488                 }
02489                 return;
02490         }
02491 
02492         // copy the readyMask to each player's stats so
02493         // it can be displayed on the scoreboard
02494         for (i=0 ; i< g_maxclients.integer ; i++) {
02495                 cl = level.clients + i;
02496                 if ( cl->pers.connected != CON_CONNECTED ) {
02497                         continue;
02498                 }
02499                 cl->ps.stats[STAT_CLIENTS_READY] = readyMask;
02500         }
02501 
02502         // never exit in less than five seconds
02503         if ( level.time < level.intermissiontime + 5000 ) {
02504                 return;
02505         }
02506 
02507         if (d_noIntermissionWait.integer)
02508         { //don't care who wants to go, just go.
02509                 ExitLevel();
02510                 return;
02511         }
02512 
02513         // if nobody wants to go, clear timer
02514         if ( !ready ) {
02515                 level.readyToExit = qfalse;
02516                 return;
02517         }
02518 
02519         // if everyone wants to go, go now
02520         if ( !notReady ) {
02521                 ExitLevel();
02522                 return;
02523         }
02524 
02525         // the first person to ready starts the ten second timeout
02526         if ( !level.readyToExit ) {
02527                 level.readyToExit = qtrue;
02528                 level.exitTime = level.time;
02529         }
02530 
02531         // if we have waited ten seconds since at least one player
02532         // wanted to exit, go ahead
02533         if ( level.time < level.exitTime + 10000 ) {
02534                 return;
02535         }
02536 
02537         ExitLevel();
02538 }

void CheckTeamLeader int  team  ) 
 

Definition at line 3361 of file g_main.c.

References level_locals_t::clients, g_entities, level, level_locals_t::maxclients, qtrue, gentity_s::r, gclient_s::sess, clientSession_t::sessionTeam, SVF_BOT, entityShared_t::svFlags, and clientSession_t::teamLeader.

Referenced by SetTeam().

03361                                  {
03362         int i;
03363 
03364         for ( i = 0 ; i < level.maxclients ; i++ ) {
03365                 if (level.clients[i].sess.sessionTeam != team)
03366                         continue;
03367                 if (level.clients[i].sess.teamLeader)
03368                         break;
03369         }
03370         if (i >= level.maxclients) {
03371                 for ( i = 0 ; i < level.maxclients ; i++ ) {
03372                         if (level.clients[i].sess.sessionTeam != team)
03373                                 continue;
03374                         if (!(g_entities[i].r.svFlags & SVF_BOT)) {
03375                                 level.clients[i].sess.teamLeader = qtrue;
03376                                 break;
03377                         }
03378                 }
03379                 for ( i = 0 ; i < level.maxclients ; i++ ) {
03380                         if (level.clients[i].sess.sessionTeam != team)
03381                                 continue;
03382                         level.clients[i].sess.teamLeader = qtrue;
03383                         break;
03384                 }
03385         }
03386 }

void CheckTeamVote int  team  ) 
 

Definition at line 3393 of file g_main.c.

References CS_TEAMVOTE_TIME, EXEC_APPEND, G_GetStringEdString(), level, level_locals_t::numteamVotingClients, Q_strncmp(), TEAM_BLUE, TEAM_RED, level_locals_t::teamVoteNo, level_locals_t::teamVoteString, level_locals_t::teamVoteTime, level_locals_t::teamVoteYes, level_locals_t::time, trap_SendConsoleCommand(), trap_SendServerCommand(), trap_SetConfigstring(), va(), and VOTE_TIME.

Referenced by G_RunFrame().

03393                                {
03394         int cs_offset;
03395 
03396         if ( team == TEAM_RED )
03397                 cs_offset = 0;
03398         else if ( team == TEAM_BLUE )
03399                 cs_offset = 1;
03400         else
03401                 return;
03402 
03403         if ( !level.teamVoteTime[cs_offset] ) {
03404                 return;
03405         }
03406         if ( level.time - level.teamVoteTime[cs_offset] >= VOTE_TIME ) {
03407                 trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "TEAMVOTEFAILED")) );
03408         } else {
03409                 if ( level.teamVoteYes[cs_offset] > level.numteamVotingClients[cs_offset]/2 ) {
03410                         // execute the command, then remove the vote
03411                         trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "TEAMVOTEPASSED")) );
03412                         //
03413                         if ( !Q_strncmp( "leader", level.teamVoteString[cs_offset], 6) ) {
03414                                 //set the team leader
03415                                 //SetLeader(team, atoi(level.teamVoteString[cs_offset] + 7));
03416                         }
03417                         else {
03418                                 trap_SendConsoleCommand( EXEC_APPEND, va("%s\n", level.teamVoteString[cs_offset] ) );
03419                         }
03420                 } else if ( level.teamVoteNo[cs_offset] >= level.numteamVotingClients[cs_offset]/2 ) {
03421                         // same behavior as a timeout
03422                         trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "TEAMVOTEFAILED")) );
03423                 } else {
03424                         // still waiting for a majority
03425                         return;
03426                 }
03427         }
03428         level.teamVoteTime[cs_offset] = 0;
03429         trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, "" );
03430 
03431 }

void CheckTournament void   ) 
 

Definition at line 2932 of file g_main.c.

References AddPowerDuelPlayers(), AddTournamentPlayer(), level_locals_t::clients, CS_CLIENT_DUELHEALTHS, CS_CLIENT_DUELISTS, CS_WARMUP, DUELTEAM_DOUBLE, DUELTEAM_LONE, EV_GLOBAL_DUEL, EXEC_APPEND, g_austrian, G_CanResetDuelists(), g_dontFrickinCheck, g_duelPrintTimer, g_fraglimit, g_gametype, G_GetStringEdString(), G_LogPrintf(), G_PowerDuelCount(), G_RemoveDuelist(), G_ResetDuelists(), g_showDuelHealths, G_TempEntity(), g_warmup, gentity_t, entityState_s::groundEntityNum, GT_DUEL, GT_POWERDUEL, GT_TEAM, vmCvar_t::integer, level_locals_t::intermissionQueued, level_locals_t::intermissiontime, level, vmCvar_t::modificationCount, level_locals_t::numConnectedClients, level_locals_t::numNonSpectatorClients, level_locals_t::numPlayingClients, entityState_s::otherEntityNum, entityState_s::otherEntityNum2, playerState_t, qboolean, qfalse, qtrue, gentity_s::r, level_locals_t::restarted, gentity_s::s, level_locals_t::sortedClients, STAT_HEALTH, playerState_s::stats, SVF_BROADCAST, entityShared_t::svFlags, TEAM_BLUE, TEAM_NUM_TEAMS, TEAM_RED, TeamCount(), level_locals_t::time, trap_Cvar_Set(), trap_SendConsoleCommand(), trap_SendServerCommand(), trap_SetConfigstring(), va(), vec3_origin, level_locals_t::warmupModificationCount, and level_locals_t::warmupTime.

Referenced by G_RunFrame().

02932                              {
02933         // check because we run 3 game frames before calling Connect and/or ClientBegin
02934         // for clients on a map_restart
02935 //      if ( level.numPlayingClients == 0 && (g_gametype.integer != GT_POWERDUEL) ) {
02936 //              return;
02937 //      }
02938 
02939         if (g_gametype.integer == GT_POWERDUEL)
02940         {
02941                 if (level.numPlayingClients >= 3 && level.numNonSpectatorClients >= 3)
02942                 {
02943                         trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("%i|%i|%i", level.sortedClients[0], level.sortedClients[1], level.sortedClients[2] ) );
02944                 }
02945         }
02946         else
02947         {
02948                 if (level.numPlayingClients >= 2)
02949                 {
02950                         trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("%i|%i", level.sortedClients[0], level.sortedClients[1] ) );
02951                 }
02952         }
02953 
02954         if ( g_gametype.integer == GT_DUEL )
02955         {
02956                 // pull in a spectator if needed
02957                 if ( level.numPlayingClients < 2 && !level.intermissiontime && !level.intermissionQueued ) {
02958                         AddTournamentPlayer();
02959 
02960                         if (level.numPlayingClients >= 2)
02961                         {
02962                                 trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("%i|%i", level.sortedClients[0], level.sortedClients[1] ) );
02963                         }
02964                 }
02965 
02966                 if (level.numPlayingClients >= 2)
02967                 {
02968 // nmckenzie: DUEL_HEALTH
02969                         if ( g_showDuelHealths.integer >= 1 )
02970                         {
02971                                 playerState_t *ps1, *ps2;
02972                                 ps1 = &level.clients[level.sortedClients[0]].ps;
02973                                 ps2 = &level.clients[level.sortedClients[1]].ps;
02974                                 trap_SetConfigstring ( CS_CLIENT_DUELHEALTHS, va("%i|%i|!", 
02975                                         ps1->stats[STAT_HEALTH], ps2->stats[STAT_HEALTH]));
02976                         }
02977                 }
02978 
02979                 //rww - It seems we have decided there will be no warmup in duel.
02980                 //if (!g_warmup.integer)
02981                 { //don't care about any of this stuff then, just add people and leave me alone
02982                         level.warmupTime = 0;
02983                         return;
02984                 }
02985 #if 0
02986                 // if we don't have two players, go back to "waiting for players"
02987                 if ( level.numPlayingClients != 2 ) {
02988                         if ( level.warmupTime != -1 ) {
02989                                 level.warmupTime = -1;
02990                                 trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) );
02991                                 G_LogPrintf( "Warmup:\n" );
02992                         }
02993                         return;
02994                 }
02995 
02996                 if ( level.warmupTime == 0 ) {
02997                         return;
02998                 }
02999 
03000                 // if the warmup is changed at the console, restart it
03001                 if ( g_warmup.modificationCount != level.warmupModificationCount ) {
03002                         level.warmupModificationCount = g_warmup.modificationCount;
03003                         level.warmupTime = -1;
03004                 }
03005 
03006                 // if all players have arrived, start the countdown
03007                 if ( level.warmupTime < 0 ) {
03008                         if ( level.numPlayingClients == 2 ) {
03009                                 // fudge by -1 to account for extra delays
03010                                 level.warmupTime = level.time + ( g_warmup.integer - 1 ) * 1000;
03011 
03012                                 if (level.warmupTime < (level.time + 3000))
03013                                 { //rww - this is an unpleasent hack to keep the level from resetting completely on the client (this happens when two map_restarts are issued rapidly)
03014                                         level.warmupTime = level.time + 3000;
03015                                 }
03016                                 trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) );
03017                         }
03018                         return;
03019                 }
03020 
03021                 // if the warmup time has counted down, restart
03022                 if ( level.time > level.warmupTime ) {
03023                         level.warmupTime += 10000;
03024                         trap_Cvar_Set( "g_restarted", "1" );
03025                         trap_SendConsoleCommand( EXEC_APPEND, "map_restart 0\n" );
03026                         level.restarted = qtrue;
03027                         return;
03028                 }
03029 #endif
03030         }
03031         else if (g_gametype.integer == GT_POWERDUEL)
03032         {
03033                 if (level.numPlayingClients < 2)
03034                 { //hmm, ok, pull more in.
03035                         g_dontFrickinCheck = qfalse;
03036                 }
03037 
03038                 if (level.numPlayingClients > 3)
03039                 { //umm..yes..lets take care of that then.
03040                         int lone = 0, dbl = 0;
03041 
03042                         G_PowerDuelCount(&lone, &dbl, qfalse);
03043                         if (lone > 1)
03044                         {
03045                                 G_RemoveDuelist(DUELTEAM_LONE);
03046                         }
03047                         else if (dbl > 2)
03048                         {
03049                                 G_RemoveDuelist(DUELTEAM_DOUBLE);
03050                         }
03051                 }
03052                 else if (level.numPlayingClients < 3)
03053                 { //hmm, someone disconnected or something and we need em
03054                         int lone = 0, dbl = 0;
03055 
03056                         G_PowerDuelCount(&lone, &dbl, qfalse);
03057                         if (lone < 1)
03058                         {
03059                                 g_dontFrickinCheck = qfalse;
03060                         }
03061                         else if (dbl < 1)
03062                         {
03063                                 g_dontFrickinCheck = qfalse;
03064                         }
03065                 }
03066 
03067                 // pull in a spectator if needed
03068                 if (level.numPlayingClients < 3 && !g_dontFrickinCheck)
03069                 {
03070                         AddPowerDuelPlayers();
03071 
03072                         if (level.numPlayingClients >= 3 &&
03073                                 G_CanResetDuelists())
03074                         {
03075                                 gentity_t *te = G_TempEntity(vec3_origin, EV_GLOBAL_DUEL);
03076                                 te->r.svFlags |= SVF_BROADCAST;
03077                                 //this is really pretty nasty, but..
03078                                 te->s.otherEntityNum = level.sortedClients[0];
03079                                 te->s.otherEntityNum2 = level.sortedClients[1];
03080                                 te->s.groundEntityNum = level.sortedClients[2];
03081 
03082                                 trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("%i|%i|%i", level.sortedClients[0], level.sortedClients[1], level.sortedClients[2] ) );
03083                                 G_ResetDuelists();
03084 
03085                                 g_dontFrickinCheck = qtrue;
03086                         }
03087                         else if (level.numPlayingClients > 0 ||
03088                                 level.numConnectedClients > 0)
03089                         {
03090                                 if (g_duelPrintTimer < level.time)
03091                                 { //print once every 10 seconds
03092                                         int lone = 0, dbl = 0;
03093 
03094                                         G_PowerDuelCount(&lone, &dbl, qtrue);
03095                                         if (lone < 1)
03096                                         {
03097                                                 trap_SendServerCommand( -1, va("cp \"%s\n\"", G_GetStringEdString("MP_SVGAME", "DUELMORESINGLE")) );
03098                                         }
03099                                         else
03100                                         {
03101                                                 trap_SendServerCommand( -1, va("cp \"%s\n\"", G_GetStringEdString("MP_SVGAME", "DUELMOREPAIRED")) );
03102                                         }
03103                                         g_duelPrintTimer = level.time + 10000;
03104                                 }
03105                         }
03106 
03107                         if (level.numPlayingClients >= 3 && level.numNonSpectatorClients >= 3)
03108                         { //pulled in a needed person
03109                                 if (G_CanResetDuelists())
03110                                 {
03111                                         gentity_t *te = G_TempEntity(vec3_origin, EV_GLOBAL_DUEL);
03112                                         te->r.svFlags |= SVF_BROADCAST;
03113                                         //this is really pretty nasty, but..
03114                                         te->s.otherEntityNum = level.sortedClients[0];
03115                                         te->s.otherEntityNum2 = level.sortedClients[1];
03116                                         te->s.groundEntityNum = level.sortedClients[2];
03117 
03118                                         trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("%i|%i|%i", level.sortedClients[0], level.sortedClients[1], level.sortedClients[2] ) );
03119 
03120                                         if ( g_austrian.integer )
03121                                         {
03122                                                 G_LogPrintf("Duel Initiated: %s %d/%d vs %s %d/%d and %s %d/%d, kill limit: %d\n", 
03123                                                         level.clients[level.sortedClients[0]].pers.netname,
03124                                                         level.clients[level.sortedClients[0]].sess.wins,
03125                                                         level.clients[level.sortedClients[0]].sess.losses,
03126                                                         level.clients[level.sortedClients[1]].pers.netname,
03127                                                         level.clients[level.sortedClients[1]].sess.wins,
03128                                                         level.clients[level.sortedClients[1]].sess.losses,
03129                                                         level.clients[level.sortedClients[2]].pers.netname,
03130                                                         level.clients[level.sortedClients[2]].sess.wins,
03131                                                         level.clients[level.sortedClients[2]].sess.losses,
03132                                                         g_fraglimit.integer );
03133                                         }
03134                                         //trap_SendConsoleCommand( EXEC_APPEND, "map_restart 0\n" );
03135                                         //FIXME: This seems to cause problems. But we'd like to reset things whenever a new opponent is set.
03136                                 }
03137                         }
03138                 }
03139                 else
03140                 { //if you have proper num of players then don't try to add again
03141                         g_dontFrickinCheck = qtrue;
03142                 }
03143 
03144                 level.warmupTime = 0;
03145                 return;
03146         }
03147         else if ( level.warmupTime != 0 ) {
03148                 int             counts[TEAM_NUM_TEAMS];
03149                 qboolean        notEnough = qfalse;
03150 
03151                 if ( g_gametype.integer > GT_TEAM ) {
03152                         counts[TEAM_BLUE] = TeamCount( -1, TEAM_BLUE );
03153                         counts[TEAM_RED] = TeamCount( -1, TEAM_RED );
03154 
03155                         if (counts[TEAM_RED] < 1 || counts[TEAM_BLUE] < 1) {
03156                                 notEnough = qtrue;
03157                         }
03158                 } else if ( level.numPlayingClients < 2 ) {
03159                         notEnough = qtrue;
03160                 }
03161 
03162                 if ( notEnough ) {
03163                         if ( level.warmupTime != -1 ) {
03164                                 level.warmupTime = -1;
03165                                 trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) );
03166                                 G_LogPrintf( "Warmup:\n" );
03167                         }
03168                         return; // still waiting for team members
03169                 }
03170 
03171                 if ( level.warmupTime == 0 ) {
03172                         return;
03173                 }
03174 
03175                 // if the warmup is changed at the console, restart it
03176                 /*
03177                 if ( g_warmup.modificationCount != level.warmupModificationCount ) {
03178                         level.warmupModificationCount = g_warmup.modificationCount;
03179                         level.warmupTime = -1;
03180                 }
03181                 */
03182 
03183                 // if all players have arrived, start the countdown
03184                 if ( level.warmupTime < 0 ) {
03185                         // fudge by -1 to account for extra delays
03186                         level.warmupTime = level.time + ( g_warmup.integer - 1 ) * 1000;
03187                         trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) );
03188                         return;
03189                 }
03190 
03191                 // if the warmup time has counted down, restart
03192                 if ( level.time > level.warmupTime ) {
03193                         level.warmupTime += 10000;
03194                         trap_Cvar_Set( "g_restarted", "1" );
03195                         trap_SendConsoleCommand( EXEC_APPEND, "map_restart 0\n" );
03196                         level.restarted = qtrue;
03197                         return;
03198                 }
03199         }
03200 }

void CheckVote void   ) 
 

Definition at line 3230 of file g_main.c.

References CS_VOTE_TIME, EXEC_APPEND, g_fraglimitVoteCorrection, G_GetStringEdString(), G_KickAllBots(), G_RefreshNextMap(), GT_DUEL, GT_POWERDUEL, GT_SIEGE, vmCvar_t::integer, level, level_locals_t::numVotingClients, qfalse, qtrue, level_locals_t::time, trap_Cvar_VariableIntegerValue(), trap_SendConsoleCommand(), trap_SendServerCommand(), trap_SetConfigstring(), va(), VOTE_TIME, level_locals_t::voteExecuteTime, level_locals_t::voteNo, level_locals_t::voteString, level_locals_t::voteTime, level_locals_t::voteYes, level_locals_t::votingGametype, and level_locals_t::votingGametypeTo.

Referenced by G_RunFrame().

03230                        {
03231         if ( level.voteExecuteTime && level.voteExecuteTime < level.time ) {
03232                 level.voteExecuteTime = 0;
03233                 trap_SendConsoleCommand( EXEC_APPEND, va("%s\n", level.voteString ) );
03234 
03235                 if (level.votingGametype)
03236                 {
03237                         if (trap_Cvar_VariableIntegerValue("g_gametype") != level.votingGametypeTo)
03238                         { //If we're voting to a different game type, be sure to refresh all the map stuff
03239                                 const char *nextMap = G_RefreshNextMap(level.votingGametypeTo, qtrue);
03240 
03241                                 if (level.votingGametypeTo == GT_SIEGE)
03242                                 { //ok, kick all the bots, cause the aren't supported!
03243                     G_KickAllBots();
03244                                         //just in case, set this to 0 too... I guess...maybe?
03245                                         //trap_Cvar_Set("bot_minplayers", "0");
03246                                 }
03247 
03248                                 if (nextMap && nextMap[0])
03249                                 {
03250                                         trap_SendConsoleCommand( EXEC_APPEND, va("map %s\n", nextMap ) );
03251                                 }
03252                         }
03253                         else
03254                         { //otherwise, just leave the map until a restart
03255                                 G_RefreshNextMap(level.votingGametypeTo, qfalse);
03256                         }
03257 
03258                         if (g_fraglimitVoteCorrection.integer)
03259                         { //This means to auto-correct fraglimit when voting to and from duel.
03260                                 const int currentGT = trap_Cvar_VariableIntegerValue("g_gametype");
03261                                 const int currentFL = trap_Cvar_VariableIntegerValue("fraglimit");
03262                                 const int currentTL = trap_Cvar_VariableIntegerValue("timelimit");
03263 
03264                                 if ((level.votingGametypeTo == GT_DUEL || level.votingGametypeTo == GT_POWERDUEL) && currentGT != GT_DUEL && currentGT != GT_POWERDUEL)
03265                                 {
03266                                         if (currentFL > 3 || !currentFL)
03267                                         { //if voting to duel, and fraglimit is more than 3 (or unlimited), then set it down to 3
03268                                                 trap_SendConsoleCommand(EXEC_APPEND, "fraglimit 3\n");
03269                                         }
03270                                         if (currentTL)
03271                                         { //if voting to duel, and timelimit is set, make it unlimited
03272                                                 trap_SendConsoleCommand(EXEC_APPEND, "timelimit 0\n");
03273                                         }
03274                                 }
03275                                 else if ((level.votingGametypeTo != GT_DUEL && level.votingGametypeTo != GT_POWERDUEL) &&
03276                                         (currentGT == GT_DUEL || currentGT == GT_POWERDUEL))
03277                                 {
03278                                         if (currentFL && currentFL < 20)
03279                                         { //if voting from duel, an fraglimit is less than 20, then set it up to 20
03280                                                 trap_SendConsoleCommand(EXEC_APPEND, "fraglimit 20\n");
03281                                         }
03282                                 }
03283                         }
03284 
03285                         level.votingGametype = qfalse;
03286                         level.votingGametypeTo = 0;
03287                 }
03288         }
03289         if ( !level.voteTime ) {
03290                 return;
03291         }
03292         if ( level.time - level.voteTime >= VOTE_TIME ) {
03293                 trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "VOTEFAILED")) );
03294         } else {
03295                 if ( level.voteYes > level.numVotingClients/2 ) {
03296                         // execute the command, then remove the vote
03297                         trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "VOTEPASSED")) );
03298                         level.voteExecuteTime = level.time + 3000;
03299                 } else if ( level.voteNo >= level.numVotingClients/2 ) {
03300                         // same behavior as a timeout
03301                         trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "VOTEFAILED")) );
03302                 } else {
03303                         // still waiting for a majority
03304                         return;
03305                 }
03306         }
03307         level.voteTime = 0;
03308         trap_SetConfigstring( CS_VOTE_TIME, "" );
03309 
03310 }

void ClearNPCGlobals void   ) 
 

Definition at line 647 of file NPC.c.

References client, NPC, NPCInfo, and NULL.

Referenced by G_RunFrame().

00648 {
00649         NPC = NULL;
00650         NPCInfo = NULL;
00651         client = NULL;
00652 }

void ClearPlayerAlertEvents void   ) 
 

Definition at line 660 of file NPC_senses.c.

References ALERT_CLEAR_TIME, alertEvent_t, level_locals_t::alertEvents, eventClearTime, level, MAX_ALERT_EVENTS, memmove(), memset(), level_locals_t::numAlertEvents, level_locals_t::time, and alertEvent_s::timestamp.

00661 {
00662         int curNumAlerts = level.numAlertEvents;
00663         int i;
00664         //loop through them all (max 32)
00665         for ( i = 0; i < curNumAlerts; i++ )
00666         {
00667                 //see if the event is old enough to delete
00668                 if ( level.alertEvents[i].timestamp && level.alertEvents[i].timestamp + ALERT_CLEAR_TIME < level.time )
00669                 {//this event has timed out
00670                         //drop the count
00671                         level.numAlertEvents--;
00672                         //shift the rest down
00673                         if ( level.numAlertEvents > 0 )
00674                         {//still have more in the array
00675                                 if ( (i+1) < MAX_ALERT_EVENTS )
00676                                 {
00677                                         memmove( &level.alertEvents[i], &level.alertEvents[i+1], sizeof(alertEvent_t)*(MAX_ALERT_EVENTS-(i+1) ) );
00678                                 }
00679                         }
00680                         else
00681                         {//just clear this one... or should we clear the whole array?
00682                                 memset( &level.alertEvents[i], 0, sizeof( alertEvent_t ) );
00683                         }
00684                 }
00685         }
00686         //make sure this never drops below zero... if it does, something very very bad happened
00687         assert( level.numAlertEvents >= 0 );
00688 
00689         if ( eventClearTime < level.time )
00690         {//this is just a 200ms debouncer so things that generate constant alerts (like corpses and missiles) add an alert every 200 ms
00691                 eventClearTime = level.time + ALERT_CLEAR_TIME;
00692         }
00693 }

void QDECL Com_Error int  level,
const char *  error,
... 
 

Definition at line 1192 of file g_main.c.

References G_Error(), QDECL, va_end, va_list, va_start, and vsprintf().

01192                                                            {
01193         va_list         argptr;
01194         char            text[1024];
01195 
01196         va_start (argptr, error);
01197         vsprintf (text, error, argptr);
01198         va_end (argptr);
01199 
01200         G_Error( "%s", text);
01201 }

void QDECL Com_Printf const char *  msg,
... 
 

Definition at line 1203 of file g_main.c.

References G_Printf(), QDECL, va_end, va_list, va_start, and vsprintf().

01203                                               {
01204         va_list         argptr;
01205         char            text[1024];
01206 
01207         va_start (argptr, msg);
01208         vsprintf (text, msg, argptr);
01209         va_end (argptr);
01210 
01211         G_Printf ("%s", text);
01212 }

void CP_FindCombatPointWaypoints void   ) 
 

Definition at line 2548 of file NPC_combat.c.

References Com_Printf(), level_locals_t::combatPoints, level, NAV_FindClosestWaypointForPoint2(), level_locals_t::numCombatPoints, combatPoint_t::origin, S_COLOR_RED, vtos(), combatPoint_t::waypoint, and WAYPOINT_NONE.

Referenced by G_InitGame(), and vmMain().

02549 {
02550         int i;
02551 
02552         for ( i = 0; i < level.numCombatPoints; i++ )
02553         {
02554                 level.combatPoints[i].waypoint = NAV_FindClosestWaypointForPoint2( level.combatPoints[i].origin );
02555 #ifndef FINAL_BUILD
02556                 if ( level.combatPoints[i].waypoint == WAYPOINT_NONE )
02557                 {
02558                         Com_Printf( S_COLOR_RED"ERROR: Combat Point at %s has no waypoint!\n", vtos(level.combatPoints[i].origin) );
02559                 }
02560 #endif
02561         }
02562 }

qboolean DuelLimitHit void   ) 
 

Definition at line 2078 of file g_main.c.

References level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, g_duel_fraglimit, g_maxclients, gclient_t, vmCvar_t::integer, level, gclient_s::pers, qboolean, qfalse, qtrue, gclient_s::sess, and clientSession_t::wins.

Referenced by BeginIntermission(), CheckIntermissionExit(), and ExitLevel().

02079 {
02080         int i;
02081         gclient_t *cl;
02082 
02083         for ( i=0 ; i< g_maxclients.integer ; i++ ) {
02084                 cl = level.clients + i;
02085                 if ( cl->pers.connected != CON_CONNECTED ) {
02086                         continue;
02087                 }
02088 
02089                 if ( g_duel_fraglimit.integer && cl->sess.wins >= g_duel_fraglimit.integer )
02090                 {
02091                         return qtrue;
02092                 }
02093         }
02094 
02095         return qfalse;
02096 }

void DuelResetWinsLosses void   ) 
 

Definition at line 2098 of file g_main.c.

References level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, g_maxclients, gclient_t, vmCvar_t::integer, level, clientSession_t::losses, gclient_s::pers, gclient_s::sess, and clientSession_t::wins.

Referenced by ExitLevel().

02099 {
02100         int i;
02101         gclient_t *cl;
02102 
02103         for ( i=0 ; i< g_maxclients.integer ; i++ ) {
02104                 cl = level.clients + i;
02105                 if ( cl->pers.connected != CON_CONNECTED ) {
02106                         continue;
02107                 }
02108 
02109                 cl->sess.wins = 0;
02110                 cl->sess.losses = 0;
02111         }
02112 }

void ExitLevel void   ) 
 

Definition at line 2125 of file g_main.c.

References siegePers_s::beatingTime, level_locals_t::changemap, level_locals_t::clients, CON_CONNECTED, CON_CONNECTING, clientPersistant_t::connected, DuelLimitHit(), DuelResetWinsLosses(), EXEC_APPEND, g_gametype, g_maxclients, g_siegePersistant, g_siegeTeamSwitch, G_WriteSessionData(), gclient_t, GT_DUEL, GT_POWERDUEL, GT_SIEGE, vmCvar_t::integer, level_locals_t::intermissiontime, level, NULL, gclient_s::pers, PERS_SCORE, playerState_s::persistant, gclient_s::ps, qtrue, level_locals_t::restarted, SiegeDoTeamAssign(), TEAM_BLUE, TEAM_RED, level_locals_t::teamScores, and trap_SendConsoleCommand().

Referenced by CheckIntermissionExit().

02125                       {
02126         int             i;
02127         gclient_t *cl;
02128 
02129         // if we are running a tournement map, kick the loser to spectator status,
02130         // which will automatically grab the next spectator and restart
02131         if ( g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL ) {
02132                 if (!DuelLimitHit())
02133                 {
02134                         if ( !level.restarted ) {
02135                                 trap_SendConsoleCommand( EXEC_APPEND, "map_restart 0\n" );
02136                                 level.restarted = qtrue;
02137                                 level.changemap = NULL;
02138                                 level.intermissiontime = 0;
02139                         }
02140                         return; 
02141                 }
02142 
02143                 DuelResetWinsLosses();
02144         }
02145 
02146 
02147         if (g_gametype.integer == GT_SIEGE &&
02148                 g_siegeTeamSwitch.integer &&
02149                 g_siegePersistant.beatingTime)
02150         { //restart same map...
02151                 trap_SendConsoleCommand( EXEC_APPEND, "map_restart 0\n" );
02152         }
02153         else
02154         {
02155                 trap_SendConsoleCommand( EXEC_APPEND, "vstr nextmap\n" );
02156         }
02157         level.changemap = NULL;
02158         level.intermissiontime = 0;
02159 
02160         if (g_gametype.integer == GT_SIEGE &&
02161                 g_siegeTeamSwitch.integer)
02162         { //switch out now
02163                 SiegeDoTeamAssign();
02164         }
02165 
02166         // reset all the scores so we don't enter the intermission again
02167         level.teamScores[TEAM_RED] = 0;
02168         level.teamScores[TEAM_BLUE] = 0;
02169         for ( i=0 ; i< g_maxclients.integer ; i++ ) {
02170                 cl = level.clients + i;
02171                 if ( cl->pers.connected != CON_CONNECTED ) {
02172                         continue;
02173                 }
02174                 cl->ps.persistant[PERS_SCORE] = 0;
02175         }
02176 
02177         // we need to do this here before chaning to CON_CONNECTING
02178         G_WriteSessionData();
02179 
02180         // change all client states to connecting, so the early players into the
02181         // next level will know the others aren't done reconnecting
02182         for (i=0 ; i< g_maxclients.integer ; i++) {
02183                 if ( level.clients[i].pers.connected == CON_CONNECTED ) {
02184                         level.clients[i].pers.connected = CON_CONNECTING;
02185                 }
02186         }
02187 
02188 }

void FindIntermissionPoint void   ) 
 

Definition at line 1963 of file g_main.c.

References entityState_s::angles, FOFS, G_Find(), g_gametype, G_PickTarget(), G_UseTargets2(), gentity_t, gSiegeRoundEnded, gSiegeRoundWinningTeam, GT_SIEGE, vmCvar_t::integer, level_locals_t::intermission_angle, level_locals_t::intermission_origin, level_locals_t::intermissiontime, level, NULL, entityState_s::origin, gentity_s::s, SelectSpawnPoint(), SIEGETEAM_TEAM1, SIEGETEAM_TEAM2, gentity_s::target, gentity_s::target2, TEAM_SPECTATOR, level_locals_t::time, vec3_origin, vec3_t, vectoangles(), VectorCopy, and VectorSubtract.

Referenced by BeginIntermission(), and SelectSpectatorSpawnPoint().

01963                                    {
01964         gentity_t       *ent = NULL;
01965         gentity_t       *target;
01966         vec3_t          dir;
01967 
01968         // find the intermission spot
01969         if ( g_gametype.integer == GT_SIEGE
01970                 && level.intermissiontime
01971                 && level.intermissiontime <= level.time
01972                 && gSiegeRoundEnded )
01973         {
01974                 if (gSiegeRoundWinningTeam == SIEGETEAM_TEAM1)
01975                 {
01976                         ent = G_Find (NULL, FOFS(classname), "info_player_intermission_red");
01977                         if ( ent && ent->target2 ) 
01978                         {
01979                                 G_UseTargets2( ent, ent, ent->target2 );
01980                         }
01981                 }
01982                 else if (gSiegeRoundWinningTeam == SIEGETEAM_TEAM2)
01983                 {
01984                         ent = G_Find (NULL, FOFS(classname), "info_player_intermission_blue");
01985                         if ( ent && ent->target2 ) 
01986                         {
01987                                 G_UseTargets2( ent, ent, ent->target2 );
01988                         }
01989                 }
01990         }
01991         if ( !ent )
01992         {
01993                 ent = G_Find (NULL, FOFS(classname), "info_player_intermission");
01994         }
01995         if ( !ent ) {   // the map creator forgot to put in an intermission point...
01996                 SelectSpawnPoint ( vec3_origin, level.intermission_origin, level.intermission_angle, TEAM_SPECTATOR );
01997         } else {
01998                 VectorCopy (ent->s.origin, level.intermission_origin);
01999                 VectorCopy (ent->s.angles, level.intermission_angle);
02000                 // if it has a target, look towards it
02001                 if ( ent->target ) {
02002                         target = G_PickTarget( ent->target );
02003                         if ( target ) {
02004                                 VectorSubtract( target->s.origin, level.intermission_origin, dir );
02005                                 vectoangles( dir, level.intermission_angle );
02006                         }
02007                 }
02008         }
02009 
02010 }

qboolean G_CanResetDuelists void   ) 
 

Definition at line 1679 of file g_main.c.

References gentity_s::client, clientSession_t::duelTeam, DUELTEAM_FREE, g_entities, gentity_t, gentity_s::health, gentity_s::inuse, level, qboolean, qfalse, qtrue, gclient_s::sess, clientSession_t::sessionTeam, level_locals_t::sortedClients, and TEAM_SPECTATOR.

Referenced by CheckTournament().

01680 {
01681         int i;
01682         gentity_t *ent;
01683 
01684         i = 0;
01685         while (i < 3)
01686         { //precheck to make sure they are all respawnable
01687                 ent = &g_entities[level.sortedClients[i]];
01688 
01689                 if (!ent->inuse || !ent->client || ent->health <= 0 ||
01690                         ent->client->sess.sessionTeam == TEAM_SPECTATOR ||
01691                         ent->client->sess.duelTeam <= DUELTEAM_FREE)
01692                 {
01693                         return qfalse;
01694                 }
01695                 i++;
01696         }
01697 
01698         return qtrue;
01699 }

qboolean G_EntIsBreakable int  entityNum  ) 
 

Definition at line 2817 of file g_mover.c.

02818 {
02819         gentity_t *ent;
02820 
02821         if ( entityNum < 0 || entityNum >= ENTITYNUM_WORLD )
02822         {
02823                 return qfalse;
02824         }
02825 
02826         ent = &g_entities[entityNum];
02827         if ( (ent->r.svFlags & SVF_GLASS_BRUSH) )
02828         {
02829                 return qtrue;
02830         }
02831         /*
02832         if ( (ent->svFlags&SVF_BBRUSH) )
02833         {
02834                 return qtrue;
02835         }
02836         */
02837         if ( !Q_stricmp( "func_breakable", ent->classname ) )
02838         {
02839                 return qtrue;
02840         }
02841 
02842         if ( !Q_stricmp( "misc_model_breakable", ent->classname ) )
02843         {
02844                 return qtrue;
02845         }
02846         if ( !Q_stricmp( "misc_maglock", ent->classname ) )
02847         {
02848                 return qtrue;
02849         }
02850 
02851         return qfalse;
02852 }

qboolean G_EntIsDoor int  entityNum  ) 
 

Definition at line 1212 of file g_mover.c.

01213 {
01214         gentity_t *ent;
01215 
01216         if ( entityNum < 0 || entityNum >= ENTITYNUM_WORLD )
01217         {
01218                 return qfalse;
01219         }
01220 
01221         ent = &g_entities[entityNum];
01222         if ( ent && !Q_stricmp( "func_door", ent->classname ) )
01223         {//blocked by a door
01224                 return qtrue;
01225         }
01226         return qfalse;
01227 }

qboolean G_EntIsRemovableUsable int  entNum  ) 
 

Definition at line 3023 of file g_mover.c.

03024 {
03025         gentity_t *ent = &g_entities[entNum];
03026         if ( ent->classname && !Q_stricmp( "func_usable", ent->classname ) )
03027         {
03028                 if ( !(ent->s.eFlags&EF_SHADER_ANIM) && !(ent->spawnflags&8) && ent->targetname )
03029                 {//not just a shader-animator and not ALWAYS_ON, so it must be removable somehow
03030                         return qtrue;
03031                 }
03032         }
03033         return qfalse;
03034 }

qboolean G_EntIsUnlockedDoor int  entityNum  ) 
 

Definition at line 1272 of file g_mover.c.

01273 {
01274         if ( entityNum < 0 || entityNum >= ENTITYNUM_WORLD )
01275         {
01276                 return qfalse;
01277         }
01278 
01279         if ( G_EntIsDoor( entityNum ) )
01280         {
01281                 gentity_t *ent = &g_entities[entityNum];
01282                 gentity_t *owner = NULL;
01283                 if ( ent->flags & FL_TEAMSLAVE )
01284                 {//not the master door, get the master door
01285                         while ( ent->teammaster && (ent->flags&FL_TEAMSLAVE))
01286                         {
01287                                 ent = ent->teammaster;
01288                         }
01289                 }
01290                 if ( ent->targetname )
01291                 {//find out what is targetting it
01292                         owner = NULL;
01293                         //FIXME: if ent->targetname, check what kind of trigger/ent is targetting it?  If a normal trigger (active, etc), then it's okay?
01294                         while ( (owner = G_Find( owner, FOFS( target ), ent->targetname )) != NULL )
01295                         {
01296                                 if ( !Q_stricmp( "trigger_multiple", owner->classname ) )//FIXME: other triggers okay too?
01297                                 {
01298                                         if ( !(owner->flags & FL_INACTIVE) )
01299                                         {
01300                                                 return qtrue;
01301                                         }
01302                                 }
01303                         }
01304                         owner = NULL;
01305                         while ( (owner = G_Find( owner, FOFS( target2 ), ent->targetname )) != NULL )
01306                         {
01307                                 if ( !Q_stricmp( "trigger_multiple", owner->classname ) )//FIXME: other triggers okay too?
01308                                 {
01309                                         if ( !(owner->flags & FL_INACTIVE) )
01310                                         {
01311                                                 return qtrue;
01312                                         }
01313                                 }
01314                         }
01315                         return qfalse;
01316                 }
01317                 else
01318                 {//check the door's auto-created trigger instead
01319                         owner = G_FindDoorTrigger( ent );
01320                         if ( owner && (owner->flags&FL_INACTIVE) )
01321                         {//owning auto-created trigger is inactive
01322                                 return qfalse;
01323                         }
01324                 }
01325                 if ( !(ent->flags & FL_INACTIVE) && //assumes that the reactivate trigger isn't right next to the door!
01326                         !ent->health &&
01327                         !(ent->spawnflags & MOVER_PLAYER_USE) &&
01328                         !(ent->spawnflags & MOVER_FORCE_ACTIVATE) &&
01329                         !(ent->spawnflags & MOVER_LOCKED))
01330                         //FIXME: what about MOVER_GOODIE?
01331                 {
01332                         return qtrue;
01333                 }
01334         }
01335         return qfalse;
01336 }

void QDECL G_Error const char *  fmt,
... 
 

Definition at line 702 of file g_main.c.

References QDECL, trap_Error(), va_end, va_list, va_start, and vsprintf().

Referenced by Cmd_FollowCycle_f(), Com_Error(), G_AddSpawnVarToken(), G_Alloc(), G_ParseSpawnVars(), G_Spawn(), G_SpawnEntitiesFromString(), G_TryPushingEntity(), hyperspace_touch(), InitSiegeMode(), NPC_LoadParms(), Reached_BinaryMover(), RegisterItem(), RespawnItem(), SelectDuelSpawnPoint(), SelectRandomFurthestSpawnPoint(), shipboundary_touch(), SP_func_breakable(), SP_misc_siege_item(), SP_target_level_change(), SP_target_play_music(), SP_target_speaker(), SP_trigger_hyperspace(), SP_trigger_shipboundary(), and SP_worldspawn().

00702                                            {
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 }

void G_FindTeams void   ) 
 

Definition at line 724 of file g_main.c.

References CONTENTS_TRIGGER, FL_TEAMSLAVE, gentity_s::flags, g_entities, gentity_t, gentity_s::inuse, level, NULL, level_locals_t::num_entities, strcmp(), gentity_s::targetname, gentity_s::team, gentity_s::teamchain, and gentity_s::teammaster.

Referenced by G_InitGame().

00724                          {
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 }

const char* G_GetStringEdString char *  refSection,
char *  refName
 

Definition at line 4088 of file g_main.c.

References Com_sprintf().

Referenced by BroadcastTeamChange(), CheatsOk(), CheckExitRules(), CheckTeamVote(), CheckTournament(), CheckVote(), ClientBegin(), ClientCommand(), ClientConnect(), ClientThink_real(), ClientUserinfoChanged(), Cmd_CallTeamVote_f(), Cmd_CallVote_f(), Cmd_DuelTeam_f(), Cmd_EngageDuel_f(), Cmd_ForceChanged_f(), Cmd_Kill_f(), Cmd_SetViewpos_f(), Cmd_SiegeClass_f(), Cmd_Team_f(), Cmd_TeamVote_f(), Cmd_Vote_f(), JMSaberTouch(), SetLeader(), and SetTeam().

04089 {
04090         /*
04091         static char text[1024]={0};
04092         trap_SP_GetStringTextString(va("%s_%s", refSection, refName), text, sizeof(text));
04093         return text;
04094         */
04095 
04096         //Well, it would've been lovely doing it the above way, but it would mean mixing
04097         //languages for the client depending on what the server is. So we'll mark this as
04098         //a stringed reference with @@@ and send the refname to the client, and when it goes
04099         //to print it will get scanned for the stringed reference indication and dealt with
04100         //properly.
04101         static char text[1024]={0};
04102         Com_sprintf(text, sizeof(text), "@@@%s", refName);
04103         return text;
04104 }

void G_InitGame int  levelTime,
int  randomSeed,
int  restart
 

Definition at line 884 of file g_main.c.

References B_InitAlloc(), BG_ClearVehicleParseParms(), bg_customSiegeSoundNames, BG_InitAnimsets(), BG_VehicleLoadParms(), BotAILoadMap(), BotAISetup(), ClearRegisteredItems(), gentity_s::client, level_locals_t::clients, CP_FindCombatPointWaypoints(), CS_CLIENT_DUELHEALTHS, CS_CLIENT_DUELISTS, CS_CLIENT_DUELWINNER, CS_CLIENT_JEDIMASTER, CVAR_ROM, CVAR_SERVERINFO, FS_APPEND, FS_APPEND_SYNC, G_CheckTeamItems(), g_clients, g_duel_fraglimit, g_entities, G_FindTeams(), g_fraglimit, g_gametype, G_InitBots(), G_InitMemory(), G_InitWorldSession(), g_log, G_LogPrintf(), g_logSync, G_LogWeaponInit(), g_maxclients, G_ModelIndex(), G_Printf(), G_ProcessIPBans(), G_RegisterCvars(), G_RemapTeamShaders(), g_RMG, G_SoundIndex(), G_SpawnEntitiesFromString(), GAMEVERSION, level_locals_t::gentities, gentity_t, gSharedBuffer, GT_DUEL, GT_JEDIMASTER, GT_POWERDUEL, GT_SIEGE, GT_SINGLE_PLAYER, GT_TEAM, InitBodyQue(), InitSiegeMode(), vmCvar_t::integer, level, level_locals_t::logFile, MAX_CLIENTS, MAX_CUSTOM_SIEGE_SOUNDS, MAX_GENTITIES, MAX_INFO_STRING, level_locals_t::maxclients, memset(), navCalculatePaths, NPC_InitGame(), level_locals_t::num_entities, gclient_s::ps, qfalse, qtrue, RemoveAllWP(), SaveRegisteredItems(), level_locals_t::snd_fry, level_locals_t::snd_hack, level_locals_t::snd_medHealed, level_locals_t::snd_medSupplied, SP_PODIUM_MODEL, srand(), START_TIME_NAV_CALC, level_locals_t::startTime, vmCvar_t::string, level_locals_t::time, TIMER_Clear(), trap_Cvar_Register(), trap_Cvar_Set(), trap_Cvar_VariableIntegerValue(), trap_FS_FOpenFile(), trap_G2API_CleanEntAttachments(), trap_GetServerinfo(), trap_ICARUS_Init(), trap_LocateGameData(), trap_Nav_Load(), trap_Nav_SetPathsCalculated(), trap_SetConfigstring(), trap_SV_RegisterSharedMemory(), va(), and WP_SaberLoadParms().

Referenced by vmMain().

00884                                                               {
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 / slime
00930 
00931         level.snd_hack = G_SoundIndex("sound/player/hacking.wav");
00932         level.snd_medHealed = G_SoundIndex("sound/player/supp_healed.wav");
00933         level.snd_medSupplied = G_SoundIndex("sound/player/supp_supplied.wav");
00934 
00935         //trap_SP_RegisterServer("mp_svgame");
00936 
00937 #ifndef _XBOX
00938         if ( g_log.string[0] ) {
00939                 if ( g_logSync.integer ) {
00940                         trap_FS_FOpenFile( g_log.string, &level.logFile, FS_APPEND_SYNC );
00941                 } else {
00942                         trap_FS_FOpenFile( g_log.string, &level.logFile, FS_APPEND );
00943                 }
00944                 if ( !level.logFile ) {
00945                         G_Printf( "WARNING: Couldn't open logfile: %s\n", g_log.string );
00946                 } else {
00947                         char    serverinfo[MAX_INFO_STRING];
00948 
00949                         trap_GetServerinfo( serverinfo, sizeof( serverinfo ) );
00950 
00951                         G_LogPrintf("------------------------------------------------------------\n" );
00952                         G_LogPrintf("InitGame: %s\n", serverinfo );
00953                 }
00954         } else {
00955                 G_Printf( "Not logging to disk.\n" );
00956         }
00957 #endif
00958 
00959         G_LogWeaponInit();
00960 
00961         G_InitWorldSession();
00962 
00963         // initialize all entities for this game
00964         memset( g_entities, 0, MAX_GENTITIES * sizeof(g_entities[0]) );
00965         level.gentities = g_entities;
00966 
00967         // initialize all clients for this game
00968         level.maxclients = g_maxclients.integer;
00969         memset( g_clients, 0, MAX_CLIENTS * sizeof(g_clients[0]) );
00970         level.clients = g_clients;
00971 
00972         // set client fields on player ents
00973         for ( i=0 ; i<level.maxclients ; i++ ) {
00974                 g_entities[i].client = level.clients + i;
00975         }
00976 
00977         // always leave room for the max number of clients,
00978         // even if they aren't all used, so numbers inside that
00979         // range are NEVER anything but clients
00980         level.num_entities = MAX_CLIENTS;
00981 
00982         // let the server system know where the entites are
00983         trap_LocateGameData( level.gentities, level.num_entities, sizeof( gentity_t ), 
00984                 &level.clients[0].ps, sizeof( level.clients[0] ) );
00985 
00986         //Load sabers.cfg data
00987         WP_SaberLoadParms();
00988 
00989         NPC_InitGame();
00990         
00991         TIMER_Clear();
00992         //
00993         //ICARUS INIT START
00994 
00995 //      Com_Printf("------ ICARUS Initialization ------\n");
00996 
00997         trap_ICARUS_Init();
00998 
00999 //      Com_Printf ("-----------------------------------\n");
01000 
01001         //ICARUS INIT END
01002         //
01003 
01004         // reserve some spots for dead player bodies
01005         InitBodyQue();
01006 
01007         ClearRegisteredItems();
01008 
01009         //make sure saber data is loaded before this! (so we can precache the appropriate hilts)
01010         InitSiegeMode();
01011 
01012         trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM );
01013         trap_Cvar_Register( &ckSum, "sv_mapChecksum", "", CVAR_ROM );
01014 
01015         navCalculatePaths       = ( trap_Nav_Load( mapname.string, ckSum.integer ) == qfalse );
01016 
01017         // parse the key/value pairs and spawn gentities
01018         G_SpawnEntitiesFromString(qfalse);
01019 
01020         // general initialization
01021         G_FindTeams();
01022 
01023         // make sure we have flags for CTF, etc
01024         if( g_gametype.integer >= GT_TEAM ) {
01025                 G_CheckTeamItems();
01026         }
01027         else if ( g_gametype.integer == GT_JEDIMASTER )
01028         {
01029                 trap_SetConfigstring ( CS_CLIENT_JEDIMASTER, "-1" );
01030         }
01031 
01032         if (g_gametype.integer == GT_POWERDUEL)
01033         {
01034                 trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("-1|-1|-1") );
01035         }
01036         else
01037         {
01038                 trap_SetConfigstring ( CS_CLIENT_DUELISTS, va("-1|-1") );
01039         }
01040 // nmckenzie: DUEL_HEALTH: Default.
01041         trap_SetConfigstring ( CS_CLIENT_DUELHEALTHS, va("-1|-1|!") );
01042         trap_SetConfigstring ( CS_CLIENT_DUELWINNER, va("-1") );
01043 
01044         SaveRegisteredItems();
01045 
01046         //G_Printf ("-----------------------------------\n");
01047 
01048         if( g_gametype.integer == GT_SINGLE_PLAYER || trap_Cvar_VariableIntegerValue( "com_buildScript" ) ) {
01049                 G_ModelIndex( SP_PODIUM_MODEL );
01050                 G_SoundIndex( "sound/player/gurp1.wav" );
01051                 G_SoundIndex( "sound/player/gurp2.wav" );
01052         }
01053 
01054         if ( trap_Cvar_VariableIntegerValue( "bot_enable" ) ) {
01055                 BotAISetup( restart );
01056                 BotAILoadMap( restart );
01057                 G_InitBots( restart );
01058         }
01059 
01060         G_RemapTeamShaders();
01061 
01062         if ( g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL )
01063         {
01064                 G_LogPrintf("Duel Tournament Begun: kill limit %d, win limit: %d\n", g_fraglimit.integer, g_duel_fraglimit.integer );
01065         }
01066 
01067         if ( navCalculatePaths )
01068         {//not loaded - need to calc paths
01069                 navCalcPathTime = level.time + START_TIME_NAV_CALC;//make sure all ents are in and linked
01070         }
01071         else
01072         {//loaded
01073                 //FIXME: if this is from a loadgame, it needs to be sure to write this 
01074                 //out whenever you do a savegame since the edges and routes are dynamic...
01075                 //OR: always do a navigator.CheckBlockedEdges() on map startup after nav-load/calc-paths
01076                 //navigator.pathsCalculated = qtrue;//just to be safe?  Does this get saved out?  No... assumed
01077                 trap_Nav_SetPathsCalculated(qtrue);
01078                 //need to do this, because combatpoint waypoints aren't saved out...?
01079                 CP_FindCombatPointWaypoints();
01080                 navCalcPathTime = 0;
01081 
01082                 /*
01083                 if ( g_eSavedGameJustLoaded == eNO )
01084                 {//clear all the failed edges unless we just loaded the game (which would include failed edges)
01085                         trap_Nav_ClearAllFailedEdges();
01086                 }
01087                 */
01088                 //No loading games in MP.
01089         }
01090 
01091         if (g_gametype.integer == GT_SIEGE)
01092         { //just get these configstrings registered now...
01093                 int i = 0;
01094                 while (i < MAX_CUSTOM_SIEGE_SOUNDS)
01095                 {
01096                         if (!bg_customSiegeSoundNames[i])
01097                         {
01098                                 break;
01099                         }
01100                         G_SoundIndex((char *)bg_customSiegeSoundNames[i]);
01101                         i++;
01102                 }
01103         }
01104 }

void G_KickAllBots void   ) 
 

Definition at line 3202 of file g_main.c.

References playerState_s::clientNum, level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, EXEC_INSERT, g_entities, g_maxclients, gclient_t, vmCvar_t::integer, level, clientPersistant_t::netname, gclient_s::pers, gclient_s::ps, Q_CleanStr(), strcpy(), SVF_BOT, trap_SendConsoleCommand(), and va().

Referenced by CheckVote().

03203 {
03204         int i;
03205         char netname[36];
03206         gclient_t       *cl;
03207 
03208         for ( i=0 ; i< g_maxclients.integer ; i++ )
03209         {
03210                 cl = level.clients + i;
03211                 if ( cl->pers.connected != CON_CONNECTED )
03212                 {
03213                         continue;
03214                 }
03215                 if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) )
03216                 {
03217                         continue;
03218                 }
03219                 strcpy(netname, cl->pers.netname);
03220                 Q_CleanStr(netname);
03221                 trap_SendConsoleCommand( EXEC_INSERT, va("kick \"%s\"\n", netname) );
03222         }
03223 }

void QDECL G_LogPrintf const char *  fmt,
... 
 

Definition at line 2197 of file g_main.c.

References Com_sprintf(), g_dedicated, G_Printf(), vmCvar_t::integer, level, level_locals_t::logFile, min, QDECL, strlen(), level_locals_t::time, trap_FS_Write(), va_end, va_list, va_start, and vsprintf().

Referenced by BroadcastTeamChange(), CheckIntermissionExit(), CheckTournament(), ClientBegin(), ClientConnect(), ClientDisconnect(), ClientUserinfoChanged(), G_CheckForDismemberment(), G_InitGame(), G_LogWeaponOutput(), G_Say(), G_ShutdownGame(), LogExit(), player_die(), and Touch_Item().

02197                                                {
02198         va_list         argptr;
02199         char            string[1024];
02200         int                     min, tens, sec;
02201 
02202         sec = level.time / 1000;
02203 
02204         min = sec / 60;
02205         sec -= min * 60;
02206         tens = sec / 10;
02207         sec -= tens * 10;
02208 
02209         Com_sprintf( string, sizeof(string), "%3i:%i%i ", min, tens, sec );
02210 
02211         va_start( argptr, fmt );
02212         vsprintf( string +7 , fmt,argptr );
02213         va_end( argptr );
02214 
02215         if ( g_dedicated.integer ) {
02216                 G_Printf( "%s", string + 7 );
02217         }
02218 
02219         if ( !level.logFile ) {
02220                 return;
02221         }
02222 
02223         trap_FS_Write( string, strlen( string ), level.logFile );
02224 }

qboolean G_ParseSpawnVars qboolean  inSubBSP  ) 
 

Definition at line 1018 of file g_spawn.c.

References G_AddSpawnVarToken(), G_Error(), level, MAX_SPAWN_VARS, MAX_TOKEN_CHARS, level_locals_t::numSpawnVarChars, level_locals_t::numSpawnVars, qboolean, qfalse, qtrue, level_locals_t::spawnVars, and trap_GetEntityToken().

Referenced by G_SpawnEntitiesFromString(), and vmMain().

01018                                                {
01019         char            keyname[MAX_TOKEN_CHARS];
01020         char            com_token[MAX_TOKEN_CHARS];
01021 
01022         level.numSpawnVars = 0;
01023         level.numSpawnVarChars = 0;
01024 
01025         // parse the opening brace
01026         if ( !trap_GetEntityToken( com_token, sizeof( com_token ) ) ) {
01027                 // end of spawn string
01028                 return qfalse;
01029         }
01030         if ( com_token[0] != '{' ) {
01031                 G_Error( "G_ParseSpawnVars: found %s when expecting {",com_token );
01032         }
01033 
01034         // go through all the key / value pairs
01035         while ( 1 ) {   
01036                 // parse key
01037                 if ( !trap_GetEntityToken( keyname, sizeof( keyname ) ) ) {
01038                         G_Error( "G_ParseSpawnVars: EOF without closing brace" );
01039                 }
01040 
01041                 if ( keyname[0] == '}' ) {
01042                         break;
01043                 }
01044                 
01045                 // parse value  
01046                 if ( !trap_GetEntityToken( com_token, sizeof( com_token ) ) ) {
01047                         G_Error( "G_ParseSpawnVars: EOF without closing brace" );
01048                 }
01049 
01050                 if ( com_token[0] == '}' ) {
01051                         G_Error( "G_ParseSpawnVars: closing brace without data" );
01052                 }
01053                 if ( level.numSpawnVars == MAX_SPAWN_VARS ) {
01054                         G_Error( "G_ParseSpawnVars: MAX_SPAWN_VARS" );
01055                 }
01056                 level.spawnVars[ level.numSpawnVars ][0] = G_AddSpawnVarToken( keyname );
01057                 level.spawnVars[ level.numSpawnVars ][1] = G_AddSpawnVarToken( com_token );
01058                 level.numSpawnVars++;
01059         }
01060 
01061         if (inSubBSP)
01062         {
01063                 HandleEntityAdjustment();
01064         }
01065 
01066         return qtrue;
01067 }

qboolean G_PointInBounds vec3_t  point,
vec3_t  mins,
vec3_t  maxs
 

Definition at line 1877 of file g_utils.c.

01878 {
01879         int i;
01880 
01881         for(i = 0; i < 3; i++ )
01882         {
01883                 if ( point[i] < mins[i] )
01884                 {
01885                         return qfalse;
01886                 }
01887                 if ( point[i] > maxs[i] )
01888                 {
01889                         return qfalse;
01890                 }
01891         }
01892 
01893         return qtrue;
01894 }

void G_PowerDuelCount int *  loners,
int *  doubles,
qboolean  countSpec
 

Definition at line 1305 of file g_main.c.

References gentity_s::client, clientSession_t::duelTeam, DUELTEAM_DOUBLE, DUELTEAM_LONE, g_entities, gclient_t, gentity_s::inuse, MAX_CLIENTS, gclient_s::sess, clientSession_t::sessionTeam, and TEAM_SPECTATOR.

Referenced by AddPowerDuelPlayers(), CheckTournament(), G_InitSessionData(), and G_PowerDuelCheckFail().

01306 {
01307         int i = 0;
01308         gclient_t *cl;
01309 
01310         while (i < MAX_CLIENTS)
01311         {
01312                 cl = g_entities[i].client;
01313 
01314                 if (g_entities[i].inuse && cl && (countSpec || cl->sess.sessionTeam != TEAM_SPECTATOR))
01315                 {
01316                         if (cl->sess.duelTeam == DUELTEAM_LONE)
01317                         {
01318                                 (*loners)++;
01319                         }
01320                         else if (cl->sess.duelTeam == DUELTEAM_DOUBLE)
01321                         {
01322                                 (*doubles)++;
01323                         }
01324                 }
01325                 i++;
01326         }
01327 }

void QDECL G_Printf const char *  fmt,
... 
 

Definition at line 691 of file g_main.c.

References QDECL, trap_Printf(), va_end, va_list, va_start, and vsprintf().

Referenced by AcceptBotCommand(), B_Alloc(), B_Free(), BotUtilizePersonality(), BotWaypointRender(), ClientForString(), Com_Printf(), ConnectTrail(), CreateNewWP(), CreateNewWP_FromObject(), CreateNewWP_InsertUnder(), CreateNewWP_InTrail(), CTFTakesPriority(), FinishSpawningItem(), G_AddEvent(), G_Alloc(), G_CallSpawn(), G_CheckTeamItems(), G_Damage(), G_InitGame(), G_InitWorldSession(), G_LogPrintf(), G_PickTarget(), G_RegisterCvars(), G_RMGPathing(), G_RunFrame(), G_Say(), G_UseTargets2(), LoadPathData(), locateCamera(), ReadChatGroups(), RemoveWP_InTrail(), SavePathData(), SP_func_timer(), SP_func_train(), SP_info_siege_decomplete(), SP_info_siege_objective(), SP_misc_ammo_floor_unit(), SP_misc_holocron(), SP_misc_shield_floor_unit(), SP_path_corner(), SP_target_teleporter(), Svcmd_AddIP_f(), Svcmd_EntityList_f(), Svcmd_GameMem_f(), Svcmd_RemoveIP_f(), target_laser_start(), target_teleporter_use(), Team_CaptureFlagSound(), Team_ReturnFlagSound(), Team_TakeFlagSound(), TeleportToWP(), TransferWPData(), trigger_teleporter_touch(), UseSiegeTarget(), and WPFlagsModify().

00691                                             {
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 }

void G_RegisterCvars void   ) 
 

Definition at line 791 of file g_main.c.

References g_gametype, G_Printf(), G_RemapTeamShaders(), g_warmup, GT_CTY, GT_HOLOCRON, GT_JEDIMASTER, GT_MAX_GAME_TYPE, vmCvar_t::integer, level, vmCvar_t::modificationCount, qboolean, qfalse, qtrue, trap_Cvar_Register(), trap_Cvar_Set(), and level_locals_t::warmupModificationCount.

Referenced by G_InitGame().

00791                              {
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 }

void G_RemapTeamShaders void   ) 
 

Definition at line 771 of file g_main.c.

References AddRemap(), BuildShaderStateConfig(), Com_sprintf(), CS_SHADERSTATE, level, level_locals_t::time, and trap_SetConfigstring().

Referenced by G_InitGame(), G_RegisterCvars(), and G_UpdateCvars().

00771                                 {
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 }

void G_RemoveDuelist int  team  ) 
 

Definition at line 2907 of file g_main.c.

References gentity_s::client, clientSession_t::duelTeam, g_entities, gentity_t, gentity_s::inuse, MAX_CLIENTS, gclient_s::sess, clientSession_t::sessionTeam, SetTeam(), and TEAM_SPECTATOR.

Referenced by CheckTournament().

02908 {
02909         int i = 0;
02910         gentity_t *ent;
02911         while (i < MAX_CLIENTS)
02912         {
02913                 ent = &g_entities[i];
02914 
02915                 if (ent->inuse && ent->client && ent->client->sess.sessionTeam != TEAM_SPECTATOR &&
02916                         ent->client->sess.duelTeam == team)
02917                 {
02918                         SetTeam(ent, "s");
02919                 }
02920         i++;
02921         }
02922 }

void G_ResetDuelists void   ) 
 

Definition at line 1702 of file g_main.c.

References gentity_s::client, entityState_s::clientNum, ClientSpawn(), EV_PLAYER_TELEPORT_IN, g_entities, g_noPDuelCheck, G_TempEntity(), gentity_t, level, MOD_SUICIDE, playerState_s::origin, player_die(), gclient_s::ps, qfalse, qtrue, gentity_s::s, level_locals_t::sortedClients, and trap_UnlinkEntity().

Referenced by CheckTournament().

01703 {
01704         int i;
01705         gentity_t *ent;
01706         gentity_t *tent;
01707 
01708         i = 0;
01709         while (i < 3)
01710         {
01711                 ent = &g_entities[level.sortedClients[i]];
01712 
01713                 g_noPDuelCheck = qtrue;
01714                 player_die(ent, ent, ent, 999, MOD_SUICIDE);
01715                 g_noPDuelCheck = qfalse;
01716                 trap_UnlinkEntity (ent);
01717                 ClientSpawn(ent);
01718 
01719                 // add a teleportation effect
01720                 tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN );
01721                 tent->s.clientNum = ent->s.clientNum;
01722                 i++;
01723         }
01724 }

void G_ROFF_NotetrackCallback gentity_t cent,
const char *  notetrack
 

Definition at line 2039 of file g_utils.c.

References entityState_s::angles2, entityState_s::apos, entityShared_t::currentAngles, entityShared_t::currentOrigin, gentity_t, entityState_s::number, entityState_s::origin2, entityState_s::pos, qfalse, gentity_s::r, gentity_s::roffid, gentity_s::s, strcmp(), trap_ROFF_Play(), trajectory_t::trBase, and VectorCopy.

Referenced by vmMain().

02040 {
02041         char type[256];
02042         int i = 0;
02043         int addlArg = 0;
02044 
02045         if (!cent || !notetrack)
02046         {
02047                 return;
02048         }
02049 
02050         while (notetrack[i] && notetrack[i] != ' ')
02051         {
02052                 type[i] = notetrack[i];
02053                 i++;
02054         }
02055 
02056         type[i] = '\0';
02057 
02058         if (!i || !type[0])
02059         {
02060                 return;
02061         }
02062 
02063         if (notetrack[i] == ' ')
02064         {
02065                 addlArg = 1;
02066         }
02067 
02068         if (strcmp(type, "loop") == 0)
02069         {
02070                 if (addlArg) //including an additional argument means reset to original position before loop
02071                 {
02072                         VectorCopy(cent->s.origin2, cent->s.pos.trBase);
02073                         VectorCopy(cent->s.origin2, cent->r.currentOrigin);
02074                         VectorCopy(cent->s.angles2, cent->s.apos.trBase);
02075                         VectorCopy(cent->s.angles2, cent->r.currentAngles);
02076                 }
02077 
02078                 trap_ROFF_Play(cent->s.number, cent->roffid, qfalse);
02079         }
02080 }

void G_RunFrame int  levelTime  ) 
 

Definition at line 3566 of file g_main.c.

References entityShared_t::absmax, entityShared_t::absmin, AI_UpdateGroups(), atof(), bgSiegeClasses, BOTH_CONSOLE1, BUTTON_USE, usercmd_s::buttons, CFL_STATVIEWER, CHAN_VOICE, CheckCvars(), CheckExitRules(), CheckTeamStatus(), CheckTeamVote(), CheckTournament(), CheckVote(), ClearNPCGlobals(), ClearPlayerAlertEvents(), gentity_s::client, ClientEndFrame(), CLOAK_DEFUEL_RATE, CLOAK_REFUEL_RATE, gclient_s::cloakDebRecharge, gclient_s::cloakDebReduce, playerState_s::cloakFuel, clientPersistant_t::cmd, Com_Printf(), d_altRoutes, DAMAGE_NO_ARMOR, EF_SOUNDTRACKER, entityState_s::eFlags, ENTITYNUM_NONE, ET_BODY, ET_ITEM, ET_MISSILE, ET_MOVER, ET_NPC, entityState_s::eType, entityState_s::event, EVENT_VALID_MSEC, entityState_s::eventParm, gentity_s::eventTime, playerState_s::externalEvent, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, level_locals_t::framenum, gentity_s::freeAfterEvent, g_allowNPC, G_CheckClientTimeouts(), G_Damage(), g_entities, G_EntitySound(), G_FreeEntity(), g_gametype, g_LastFrameTime, g_listEntity, G_PointInBounds(), G_Printf(), G_RunClient(), G_RunExPhys(), G_RunItem(), G_RunMissile(), G_RunMover(), G_RunThink(), G_SendG2KillQueue(), G_SetAnim(), G_SiegeClientExData(), g_siegeRespawn, g_siegeRespawnCheck, G_SoundIndex(), g_TimeSinceLastFrame, G_UpdateCvars(), gDoSlowMoDuel, gentity_t, gQueueScoreMessage, gQueueScoreMessageTime, gSlowMoDuelTime, GT_SIEGE, gclient_s::hackingAngles, playerState_s::hackingTime, HANDEXTEND_CHOKE, gentity_s::health, gclient_s::inSpaceIndex, gclient_s::inSpaceSuffocation, vmCvar_t::integer, level_locals_t::intermissiontime, gentity_s::inuse, gclient_s::isHacking, Jedi_Decloak(), JETPACK_DEFUEL_RATE, Jetpack_Off(), JETPACK_REFUEL_RATE, gclient_s::jetPackDebRecharge, gclient_s::jetPackDebReduce, playerState_s::jetpackFuel, gclient_s::jetPackOn, gentity_s::lastWaypoint, level, entityShared_t::linked, MAX_CLIENTS, MAX_GENTITIES, MAX_POWERUPS, level_locals_t::maxclients, MOD_SUICIDE, NAV_CheckCalcPaths(), NAV_FindPlayerWaypoint(), gentity_s::neverFree, gentity_s::noWaypointTime, NULL, level_locals_t::num_entities, entityState_s::number, playerState_s::origin, gclient_s::pers, gentity_s::physicsObject, playerState_s::pm_flags, PMF_FOLLOW, playerState_s::powerups, level_locals_t::previousTime, gclient_s::ps, PW_CLOAKED, Q_irand(), qfalse, gentity_s::r, respawn(), level_locals_t::restarted, gentity_s::s, SendScoreboardMessageToAllClients(), gclient_s::sess, clientSession_t::sessionTeam, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, SETANIM_TORSO, SiegeCheckTimers(), gclient_s::siegeClass, gclient_s::siegeEDataSend, gentity_s::takedamage, TEAM_BLUE, TEAM_RED, TEAM_SPECTATOR, gclient_s::tempSpectate, level_locals_t::time, playerState_s::torsoAnim, playerState_s::torsoTimer, trap_Cvar_Set(), trap_Cvar_VariableStringBuffer(), trap_ICARUS_MaintainTaskManager(), trap_Nav_CheckAllFailedEdges(), trap_Nav_CheckFailedNodes(), trap_Nav_ClearCheckedNodes(), trap_PrecisionTimer_End(), trap_PrecisionTimer_Start(), trap_ROFF_UpdateEntities(), trap_UnlinkEntity(), gentity_s::unlinkAfterEvent, usercmd_s::upmove, va(), vec3_t, VectorSubtract, playerState_s::viewangles, gentity_s::waypoint, WAYPOINT_NONE, playerState_s::weaponTime, WP_ForcePowersUpdate(), WP_SaberPositionUpdate(), and WP_SaberStartMissileBlockCheck().

Referenced by vmMain().

03566                                  {
03567         int                     i;
03568         gentity_t       *ent;
03569         int                     msec;
03570 #ifdef _G_FRAME_PERFANAL
03571         int                     iTimer_ItemRun = 0;
03572         int                     iTimer_ROFF = 0;
03573         int                     iTimer_ClientEndframe = 0;
03574         int                     iTimer_GameChecks = 0;
03575         int                     iTimer_Queues = 0;
03576         void            *timer_ItemRun;
03577         void            *timer_ROFF;
03578         void            *timer_ClientEndframe;
03579         void            *timer_GameChecks;
03580         void            *timer_Queues;
03581 #endif
03582 
03583         if (g_gametype.integer == GT_SIEGE &&
03584                 g_siegeRespawn.integer &&
03585                 g_siegeRespawnCheck < level.time)
03586         { //check for a respawn wave
03587                 int i = 0;
03588                 gentity_t *clEnt;
03589                 while (i < MAX_CLIENTS)
03590                 {
03591                         clEnt = &g_entities[i];
03592 
03593                         if (clEnt->inuse && clEnt->client &&
03594                                 clEnt->client->tempSpectate > level.time &&
03595                                 clEnt->client->sess.sessionTeam != TEAM_SPECTATOR)
03596                         {
03597                                 respawn(clEnt);
03598                                 clEnt->client->tempSpectate = 0;
03599                         }
03600                         i++;
03601                 }
03602 
03603                 g_siegeRespawnCheck = level.time + g_siegeRespawn.integer * 1000;
03604         }
03605 
03606         if (gDoSlowMoDuel)
03607         {
03608                 if (level.restarted)
03609                 {
03610                         char buf[128];
03611                         float tFVal = 0;
03612 
03613                         trap_Cvar_VariableStringBuffer("timescale", buf, sizeof(buf));
03614 
03615                         tFVal = atof(buf);
03616 
03617                         trap_Cvar_Set("timescale", "1");
03618                         if (tFVal == 1.0f)
03619                         {
03620                                 gDoSlowMoDuel = qfalse;
03621                         }
03622                 }
03623                 else
03624                 {
03625                         float timeDif = (level.time - gSlowMoDuelTime); //difference in time between when the slow motion was initiated and now
03626                         float useDif = 0; //the difference to use when actually setting the timescale
03627 
03628                         if (timeDif < 150)
03629                         {
03630                                 trap_Cvar_Set("timescale", "0.1f");
03631                         }
03632                         else if (timeDif < 1150)
03633                         {
03634                                 useDif = (timeDif/1000); //scale from 0.1 up to 1
03635                                 if (useDif < 0.1)
03636                                 {
03637                                         useDif = 0.1;
03638                                 }
03639                                 if (useDif > 1.0)
03640                                 {
03641                                         useDif = 1.0;
03642                                 }
03643                                 trap_Cvar_Set("timescale", va("%f", useDif));
03644                         }
03645                         else
03646                         {
03647                                 char buf[128];
03648                                 float tFVal = 0;
03649 
03650                                 trap_Cvar_VariableStringBuffer("timescale", buf, sizeof(buf));
03651 
03652                                 tFVal = atof(buf);
03653 
03654                                 trap_Cvar_Set("timescale", "1");
03655                                 if (timeDif > 1500 && tFVal == 1.0f)
03656                                 {
03657                                         gDoSlowMoDuel = qfalse;
03658                                 }
03659                         }
03660                 }
03661         }
03662 
03663         // if we are waiting for the level to restart, do nothing
03664         if ( level.restarted ) {
03665                 return;
03666         }
03667 
03668         level.framenum++;
03669         level.previousTime = level.time;
03670         level.time = levelTime;
03671         msec = level.time - level.previousTime;
03672 
03673         if (g_allowNPC.integer)
03674         {
03675                 NAV_CheckCalcPaths();
03676         }
03677 
03678         AI_UpdateGroups();
03679 
03680         if (g_allowNPC.integer)
03681         {
03682                 if ( d_altRoutes.integer )
03683                 {
03684                         trap_Nav_CheckAllFailedEdges();
03685                 }
03686                 trap_Nav_ClearCheckedNodes();
03687 
03688                 //remember last waypoint, clear current one
03689                 for ( i = 0; i < level.num_entities ; i++) 
03690                 {
03691                         ent = &g_entities[i];
03692 
03693                         if ( !ent->inuse )
03694                                 continue;
03695 
03696                         if ( ent->waypoint != WAYPOINT_NONE 
03697                                 && ent->noWaypointTime < level.time )
03698                         {
03699                                 ent->lastWaypoint = ent->waypoint;
03700                                 ent->waypoint = WAYPOINT_NONE;
03701                         }
03702                         if ( d_altRoutes.integer )
03703                         {
03704                                 trap_Nav_CheckFailedNodes( ent );
03705                         }
03706                 }
03707 
03708                 //Look to clear out old events
03709                 ClearPlayerAlertEvents();
03710         }
03711 
03712         g_TimeSinceLastFrame = (level.time - g_LastFrameTime);
03713 
03714         // get any cvar changes
03715         G_UpdateCvars();
03716 
03717 
03718 
03719 #ifdef _G_FRAME_PERFANAL
03720         trap_PrecisionTimer_Start(&timer_ItemRun);
03721 #endif
03722         //
03723         // go through all allocated objects
03724         //
03725         ent = &g_entities[0];
03726         for (i=0 ; i<level.num_entities ; i++, ent++) {
03727                 if ( !ent->inuse ) {
03728                         continue;
03729                 }
03730 
03731                 // clear events that are too old
03732                 if ( level.time - ent->eventTime > EVENT_VALID_MSEC ) {
03733                         if ( ent->s.event ) {
03734                                 ent->s.event = 0;       // &= EV_EVENT_BITS;
03735                                 if ( ent->client ) {
03736                                         ent->client->ps.externalEvent = 0;
03737                                         // predicted events should never be set to zero
03738                                         //ent->client->ps.events[0] = 0;
03739                                         //ent->client->ps.events[1] = 0;
03740                                 }
03741                         }
03742                         if ( ent->freeAfterEvent ) {
03743                                 // tempEntities or dropped items completely go away after their event
03744                                 if (ent->s.eFlags & EF_SOUNDTRACKER)
03745                                 { //don't trigger the event again..
03746                                         ent->s.event = 0;
03747                                         ent->s.eventParm = 0;
03748                                         ent->s.eType = 0;
03749                                         ent->eventTime = 0;
03750                                 }
03751                                 else
03752                                 {
03753                                         G_FreeEntity( ent );
03754                                         continue;
03755                                 }
03756                         } else if ( ent->unlinkAfterEvent ) {
03757                                 // items that will respawn will hide themselves after their pickup event
03758                                 ent->unlinkAfterEvent = qfalse;
03759                                 trap_UnlinkEntity( ent );
03760                         }
03761                 }
03762 
03763                 // temporary entities don't think
03764                 if ( ent->freeAfterEvent ) {
03765                         continue;
03766                 }
03767 
03768                 if ( !ent->r.linked && ent->neverFree ) {
03769                         continue;
03770                 }
03771 
03772                 if ( ent->s.eType == ET_MISSILE ) {
03773                         G_RunMissile( ent );
03774                         continue;
03775                 }
03776 
03777                 if ( ent->s.eType == ET_ITEM || ent->physicsObject ) {
03778 #if 0 //use if body dragging enabled?
03779                         if (ent->s.eType == ET_BODY)
03780                         { //special case for bodies
03781                                 float grav = 3.0f;
03782                                 float mass = 0.14f;
03783                                 float bounce = 1.15f;
03784 
03785                                 G_RunExPhys(ent, grav, mass, bounce, qfalse, NULL, 0);
03786                         }
03787                         else
03788                         {
03789                                 G_RunItem( ent );
03790                         }
03791 #else
03792                         G_RunItem( ent );
03793 #endif
03794                         continue;
03795                 }
03796 
03797                 if ( ent->s.eType == ET_MOVER ) {
03798                         G_RunMover( ent );
03799                         continue;
03800                 }
03801 
03802                 if ( i < MAX_CLIENTS ) 
03803                 {
03804                         G_CheckClientTimeouts ( ent );
03805                         
03806                         if (ent->client->inSpaceIndex && ent->client->inSpaceIndex != ENTITYNUM_NONE)
03807                         { //we're in space, check for suffocating and for exiting
03808                 gentity_t *spacetrigger = &g_entities[ent->client->inSpaceIndex];
03809 
03810                                 if (!spacetrigger->inuse ||
03811                                         !G_PointInBounds(ent->client->ps.origin, spacetrigger->r.absmin, spacetrigger->r.absmax))
03812                                 { //no longer in space then I suppose
03813                     ent->client->inSpaceIndex = 0;                                      
03814                                 }
03815                                 else
03816                                 { //check for suffocation
03817                     if (ent->client->inSpaceSuffocation < level.time)
03818                                         { //suffocate!
03819                                                 if (ent->health > 0 && ent->takedamage)
03820                                                 { //if they're still alive..
03821                                                         G_Damage(ent, spacetrigger, spacetrigger, NULL, ent->client->ps.origin, Q_irand(50, 70), DAMAGE_NO_ARMOR, MOD_SUICIDE);
03822 
03823                                                         if (ent->health > 0)
03824                                                         { //did that last one kill them?
03825                                                                 //play the choking sound
03826                                                                 G_EntitySound(ent, CHAN_VOICE, G_SoundIndex(va( "*choke%d.wav", Q_irand( 1, 3 ) )));
03827 
03828                                                                 //make them grasp their throat
03829                                                                 ent->client->ps.forceHandExtend = HANDEXTEND_CHOKE;
03830                                                                 ent->client->ps.forceHandExtendTime = level.time + 2000;
03831                                                         }
03832                                                 }
03833 
03834                                                 ent->client->inSpaceSuffocation = level.time + Q_irand(100, 200);
03835                                         }
03836                                 }
03837                         }
03838 
03839                         if (ent->client->isHacking)
03840                         { //hacking checks
03841                                 gentity_t *hacked = &g_entities[ent->client->isHacking];
03842                                 vec3_t angDif;
03843 
03844                                 VectorSubtract(ent->client->ps.viewangles, ent->client->hackingAngles, angDif);
03845 
03846                                 //keep him in the "use" anim
03847                                 if (ent->client->ps.torsoAnim != BOTH_CONSOLE1)
03848                                 {
03849                                         G_SetAnim( ent, NULL, SETANIM_TORSO, BOTH_CONSOLE1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 );
03850                                 }
03851                                 else
03852                                 {
03853                                         ent->client->ps.torsoTimer = 500;
03854                                 }
03855                                 ent->client->ps.weaponTime = ent->client->ps.torsoTimer;
03856 
03857                                 if (!(ent->client->pers.cmd.buttons & BUTTON_USE))
03858                                 { //have to keep holding use
03859                                         ent->client->isHacking = 0;
03860                                         ent->client->ps.hackingTime = 0;
03861                                 }
03862                                 else if (!hacked || !hacked->inuse)
03863                                 { //shouldn't happen, but safety first
03864                                         ent->client->isHacking = 0;
03865                                         ent->client->ps.hackingTime = 0;
03866                                 }
03867                                 else if (!G_PointInBounds( ent->client->ps.origin, hacked->r.absmin, hacked->r.absmax ))
03868                                 { //they stepped outside the thing they're hacking, so reset hacking time
03869                                         ent->client->isHacking = 0;
03870                                         ent->client->ps.hackingTime = 0;
03871                                 }
03872                                 else if (VectorLength(angDif) > 10.0f)
03873                                 { //must remain facing generally the same angle as when we start
03874                                         ent->client->isHacking = 0;
03875                                         ent->client->ps.hackingTime = 0;
03876                                 }
03877                         }
03878 
03879 #define JETPACK_DEFUEL_RATE             200 //approx. 20 seconds of idle use from a fully charged fuel amt
03880 #define JETPACK_REFUEL_RATE             150 //seems fair
03881                         if (ent->client->jetPackOn)
03882                         { //using jetpack, drain fuel
03883                                 if (ent->client->jetPackDebReduce < level.time)
03884                                 {
03885                                         if (ent->client->pers.cmd.upmove > 0)
03886                                         { //take more if they're thrusting
03887                                                 ent->client->ps.jetpackFuel -= 2;
03888                                         }
03889                                         else
03890                                         {
03891                                                 ent->client->ps.jetpackFuel--;
03892                                         }
03893                                         
03894                                         if (ent->client->ps.jetpackFuel <= 0)
03895                                         { //turn it off
03896                                                 ent->client->ps.jetpackFuel = 0;
03897                                                 Jetpack_Off(ent);
03898                                         }
03899                                         ent->client->jetPackDebReduce = level.time + JETPACK_DEFUEL_RATE;
03900                                 }
03901                         }
03902                         else if (ent->client->ps.jetpackFuel < 100)
03903                         { //recharge jetpack
03904                                 if (ent->client->jetPackDebRecharge < level.time)
03905                                 {
03906                                         ent->client->ps.jetpackFuel++;
03907                                         ent->client->jetPackDebRecharge = level.time + JETPACK_REFUEL_RATE;
03908                                 }
03909                         }
03910 
03911 #define CLOAK_DEFUEL_RATE               200 //approx. 20 seconds of idle use from a fully charged fuel amt
03912 #define CLOAK_REFUEL_RATE               150 //seems fair
03913                         if (ent->client->ps.powerups[PW_CLOAKED])
03914                         { //using cloak, drain battery
03915                                 if (ent->client->cloakDebReduce < level.time)
03916                                 {
03917                                         ent->client->ps.cloakFuel--;
03918                                         
03919                                         if (ent->client->ps.cloakFuel <= 0)
03920                                         { //turn it off
03921                                                 ent->client->ps.cloakFuel = 0;
03922                                                 Jedi_Decloak(ent);
03923                                         }
03924                                         ent->client->cloakDebReduce = level.time + CLOAK_DEFUEL_RATE;
03925                                 }
03926                         }
03927                         else if (ent->client->ps.cloakFuel < 100)
03928                         { //recharge cloak
03929                                 if (ent->client->cloakDebRecharge < level.time)
03930                                 {
03931                                         ent->client->ps.cloakFuel++;
03932                                         ent->client->cloakDebRecharge = level.time + CLOAK_REFUEL_RATE;
03933                                 }
03934                         }
03935 
03936                         if (g_gametype.integer == GT_SIEGE &&
03937                                 ent->client->siegeClass != -1 &&
03938                                 (bgSiegeClasses[ent->client->siegeClass].classflags & (1<<CFL_STATVIEWER)))
03939                         { //see if it's time to send this guy an update of extended info
03940                                 if (ent->client->siegeEDataSend < level.time)
03941                                 {
03942                     G_SiegeClientExData(ent);
03943                                         ent->client->siegeEDataSend = level.time + 1000; //once every sec seems ok
03944                                 }
03945                         }
03946 
03947                         if((!level.intermissiontime)&&!(ent->client->ps.pm_flags&PMF_FOLLOW) && ent->client->sess.sessionTeam != TEAM_SPECTATOR)
03948                         {
03949                                 WP_ForcePowersUpdate(ent, &ent->client->pers.cmd );
03950                                 WP_SaberPositionUpdate(ent, &ent->client->pers.cmd);
03951                                 WP_SaberStartMissileBlockCheck(ent, &ent->client->pers.cmd);
03952                         }
03953 
03954                         if (g_allowNPC.integer)
03955                         {
03956                                 //This was originally intended to only be done for client 0.
03957                                 //Make sure it doesn't slow things down too much with lots of clients in game.
03958                                 NAV_FindPlayerWaypoint(i);
03959                         }
03960 
03961                         trap_ICARUS_MaintainTaskManager(ent->s.number);
03962 
03963                         G_RunClient( ent );
03964                         continue;
03965                 }
03966                 else if (ent->s.eType == ET_NPC)
03967                 {
03968                         int j;
03969                         // turn off any expired powerups
03970                         for ( j = 0 ; j < MAX_POWERUPS ; j++ ) {
03971                                 if ( ent->client->ps.powerups[ j ] < level.time ) {
03972                                         ent->client->ps.powerups[ j ] = 0;
03973                                 }
03974                         }
03975 
03976                         WP_ForcePowersUpdate(ent, &ent->client->pers.cmd );
03977                         WP_SaberPositionUpdate(ent, &ent->client->pers.cmd);
03978                         WP_SaberStartMissileBlockCheck(ent, &ent->client->pers.cmd);
03979                 }
03980 
03981                 G_RunThink( ent );
03982 
03983                 if (g_allowNPC.integer)
03984                 {
03985                         ClearNPCGlobals();
03986                 }
03987         }
03988 #ifdef _G_FRAME_PERFANAL
03989         iTimer_ItemRun = trap_PrecisionTimer_End(timer_ItemRun);
03990 #endif
03991 
03992         SiegeCheckTimers();
03993 
03994 #ifdef _G_FRAME_PERFANAL
03995         trap_PrecisionTimer_Start(&timer_ROFF);
03996 #endif
03997         trap_ROFF_UpdateEntities();
03998 #ifdef _G_FRAME_PERFANAL
03999         iTimer_ROFF = trap_PrecisionTimer_End(timer_ROFF);
04000 #endif
04001 
04002 
04003 
04004 #ifdef _G_FRAME_PERFANAL
04005         trap_PrecisionTimer_Start(&timer_ClientEndframe);
04006 #endif
04007         // perform final fixups on the players
04008         ent = &g_entities[0];
04009         for (i=0 ; i < level.maxclients ; i++, ent++ ) {
04010                 if ( ent->inuse ) {
04011                         ClientEndFrame( ent );
04012                 }
04013         }
04014 #ifdef _G_FRAME_PERFANAL
04015         iTimer_ClientEndframe = trap_PrecisionTimer_End(timer_ClientEndframe);
04016 #endif
04017 
04018 
04019 
04020 #ifdef _G_FRAME_PERFANAL
04021         trap_PrecisionTimer_Start(&timer_GameChecks);
04022 #endif
04023         // see if it is time to do a tournement restart
04024         CheckTournament();
04025 
04026         // see if it is time to end the level
04027         CheckExitRules();
04028 
04029         // update to team status?
04030         CheckTeamStatus();
04031 
04032         // cancel vote if timed out
04033         CheckVote();
04034 
04035         // check team votes
04036         CheckTeamVote( TEAM_RED );
04037         CheckTeamVote( TEAM_BLUE );
04038 
04039         // for tracking changes
04040         CheckCvars();
04041 
04042         if (g_listEntity.integer) {
04043                 for (i = 0; i < MAX_GENTITIES; i++) {
04044                         G_Printf("%4i: %s\n", i, g_entities[i].classname);
04045                 }
04046                 trap_Cvar_Set("g_listEntity", "0");
04047         }
04048 #ifdef _G_FRAME_PERFANAL
04049         iTimer_GameChecks = trap_PrecisionTimer_End(timer_GameChecks);
04050 #endif
04051 
04052 
04053 
04054 #ifdef _G_FRAME_PERFANAL
04055         trap_PrecisionTimer_Start(&timer_Queues);
04056 #endif
04057         //At the end of the frame, send out the ghoul2 kill queue, if there is one
04058         G_SendG2KillQueue();
04059 
04060         if (gQueueScoreMessage)
04061         {
04062                 if (gQueueScoreMessageTime < level.time)
04063                 {
04064                         SendScoreboardMessageToAllClients();
04065 
04066                         gQueueScoreMessageTime = 0;
04067                         gQueueScoreMessage = 0;
04068                 }
04069         }
04070 #ifdef _G_FRAME_PERFANAL
04071         iTimer_Queues = trap_PrecisionTimer_End(timer_Queues);
04072 #endif
04073 
04074 
04075 
04076 #ifdef _G_FRAME_PERFANAL
04077         Com_Printf("---------------\nItemRun: %i\nROFF: %i\nClientEndframe: %i\nGameChecks: %i\nQueues: %i\n---------------\n",
04078                 iTimer_ItemRun,
04079                 iTimer_ROFF,
04080                 iTimer_ClientEndframe,
04081                 iTimer_GameChecks,
04082                 iTimer_Queues);
04083 #endif
04084 
04085         g_LastFrameTime = level.time;
04086 }

void G_RunThink gentity_t ent  ) 
 

Definition at line 3473 of file g_main.c.

References gentity_t, gentity_s::inuse, level, gentity_s::nextthink, entityState_s::number, gentity_s::s, gentity_s::think, level_locals_t::time, and trap_ICARUS_MaintainTaskManager().

Referenced by G_RunFrame(), G_RunItem(), G_RunMissile(), G_RunMover(), and G_RunStuckMissile().

03473                                  {
03474         float   thinktime;
03475 
03476         thinktime = ent->nextthink;
03477         if (thinktime <= 0) {
03478                 goto runicarus;
03479         }
03480         if (thinktime > level.time) {
03481                 goto runicarus;
03482         }
03483         
03484         ent->nextthink = 0;
03485         if (!ent->think) {
03486                 //G_Error ( "NULL ent->think");
03487                 goto runicarus;
03488         }
03489         ent->think (ent);
03490 
03491 runicarus:
03492         if ( ent->inuse )
03493         {
03494                 trap_ICARUS_MaintainTaskManager(ent->s.number);
03495         }
03496 }

void G_ShutdownGame int  restart  ) 
 

Definition at line 1113 of file g_main.c.

References B_CleanupAlloc(), BG_ClearAnimsets(), BotAIShutdown(), gentity_s::client, g2SaberInstance, G_CleanAllFakeClients(), g_entities, G_LogPrintf(), G_LogWeaponOutput(), G_WriteSessionData(), gentity_t, gentity_s::ghoul2, level, level_locals_t::logFile, MAX_GENTITIES, MAX_SABERS, NULL, precachedKyle, TAG_Init(), trap_Cvar_VariableIntegerValue(), trap_FS_FCloseFile(), trap_G2_HaveWeGhoul2Models(), trap_G2API_CleanGhoul2Models(), trap_ICARUS_Shutdown(), trap_ROFF_Clean(), and gclient_s::weaponGhoul2.

Referenced by vmMain().

01113                                    {
01114         int i = 0;
01115         gentity_t *ent;
01116 
01117 //      G_Printf ("==== ShutdownGame ====\n");
01118 
01119         G_CleanAllFakeClients(); //get rid of dynamically allocated fake client structs.
01120 
01121         BG_ClearAnimsets(); //free all dynamic allocations made through the engine
01122 
01123 //      Com_Printf("... Gameside GHOUL2 Cleanup\n");
01124         while (i < MAX_GENTITIES)
01125         { //clean up all the ghoul2 instances
01126                 ent = &g_entities[i];
01127 
01128                 if (ent->ghoul2 && trap_G2_HaveWeGhoul2Models(ent->ghoul2))
01129                 {
01130                         trap_G2API_CleanGhoul2Models(&ent->ghoul2);
01131                         ent->ghoul2 = NULL;
01132                 }
01133                 if (ent->client)
01134                 {
01135                         int j = 0;
01136 
01137                         while (j < MAX_SABERS)
01138                         {
01139                                 if (ent->client->weaponGhoul2[j] && trap_G2_HaveWeGhoul2Models(ent->client->weaponGhoul2[j]))
01140                                 {
01141                                         trap_G2API_CleanGhoul2Models(&ent->client->weaponGhoul2[j]);
01142                                 }
01143                                 j++;
01144                         }
01145                 }
01146                 i++;
01147         }
01148         if (g2SaberInstance && trap_G2_HaveWeGhoul2Models(g2SaberInstance))
01149         {
01150                 trap_G2API_CleanGhoul2Models(&g2SaberInstance);
01151                 g2SaberInstance = NULL;
01152         }
01153         if (precachedKyle && trap_G2_HaveWeGhoul2Models(precachedKyle))
01154         {
01155                 trap_G2API_CleanGhoul2Models(&precachedKyle);
01156                 precachedKyle = NULL;
01157         }
01158 
01159 //      Com_Printf ("... ICARUS_Shutdown\n");
01160         trap_ICARUS_Shutdown ();        //Shut ICARUS down
01161 
01162 //      Com_Printf ("... Reference Tags Cleared\n");
01163         TAG_Init();     //Clear the reference tags
01164 
01165         G_LogWeaponOutput();
01166 
01167         if ( level.logFile ) {
01168                 G_LogPrintf("ShutdownGame:\n" );
01169                 G_LogPrintf("------------------------------------------------------------\n" );
01170                 trap_FS_FCloseFile( level.logFile );
01171         }
01172 
01173         // write all the client session data so we can get it back
01174         G_WriteSessionData();
01175 
01176         trap_ROFF_Clean();
01177 
01178         if ( trap_Cvar_VariableIntegerValue( "bot_enable" ) ) {
01179                 BotAIShutdown( restart );
01180         }
01181 
01182         B_CleanupAlloc(); //clean up all allocations made with B_Alloc
01183 }

void G_SpawnGEntityFromSpawnVars qboolean  inSubBSP  ) 
 

Definition at line 766 of file g_spawn.c.

References BG_ParseField(), BSET_SPAWN, byte, gentity_s::classname, entityShared_t::currentOrigin, fields, G_ActivateBehavior(), G_CallSpawn(), G_FreeEntity(), g_gametype, G_Spawn(), G_SpawnInt(), G_SpawnString(), gentity_t, GT_FFA, GT_MAX_GAME_TYPE, GT_SINGLE_PLAYER, GT_TEAM, vmCvar_t::integer, level, NULL, level_locals_t::numSpawnVars, entityState_s::origin, entityState_s::pos, Q_strncmp(), gentity_s::r, gentity_s::s, level_locals_t::spawnVars, strstr(), trap_ICARUS_InitEnt(), trap_ICARUS_ValidEnt(), trajectory_t::trBase, and VectorCopy.

Referenced by G_SpawnEntitiesFromString(), and vmMain().

00766                                                       {
00767         int                     i;
00768         gentity_t       *ent;
00769         char            *s, *value, *gametypeName;
00770         static char *gametypeNames[] = {"ffa", "holocron", "jedimaster", "duel", "powerduel", "single", "team", "siege", "ctf", "cty"};
00771 
00772         // get the next free entity
00773         ent = G_Spawn();
00774 
00775         for ( i = 0 ; i < level.numSpawnVars ; i++ ) {
00776                 BG_ParseField( fields, level.spawnVars[i][0], level.spawnVars[i][1], (byte *)ent );
00777         }
00778 
00779         // check for "notsingle" flag
00780         if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
00781                 G_SpawnInt( "notsingle", "0", &i );
00782                 if ( i ) {
00783                         G_FreeEntity( ent );
00784                         return;
00785                 }
00786         }
00787         // check for "notteam" flag (GT_FFA, GT_DUEL, GT_SINGLE_PLAYER)
00788         if ( g_gametype.integer >= GT_TEAM ) {
00789                 G_SpawnInt( "notteam", "0", &i );
00790                 if ( i ) {
00791                         G_FreeEntity( ent );
00792                         return;
00793                 }
00794         } else {
00795                 G_SpawnInt( "notfree", "0", &i );
00796                 if ( i ) {
00797                         G_FreeEntity( ent );
00798                         return;
00799                 }
00800         }
00801 
00802         G_SpawnInt( "notta", "0", &i );
00803         if ( i ) {
00804                 G_FreeEntity( ent );
00805                 return;
00806         }
00807 
00808         if( G_SpawnString( "gametype", NULL, &value ) ) {
00809                 if( g_gametype.integer >= GT_FFA && g_gametype.integer < GT_MAX_GAME_TYPE ) {
00810                         gametypeName = gametypeNames[g_gametype.integer];
00811 
00812                         s = strstr( value, gametypeName );
00813                         if( !s ) {
00814                                 G_FreeEntity( ent );
00815                                 return;
00816                         }
00817                 }
00818         }
00819 
00820         // move editor origin to pos
00821         VectorCopy( ent->s.origin, ent->s.pos.trBase );
00822         VectorCopy( ent->s.origin, ent->r.currentOrigin );
00823 
00824         // if we didn't get a classname, don't bother spawning anything
00825         if ( !G_CallSpawn( ent ) ) {
00826                 G_FreeEntity( ent );
00827         }
00828 
00829         //Tag on the ICARUS scripting information only to valid recipients
00830         if ( trap_ICARUS_ValidEnt( ent ) )
00831         {
00832                 trap_ICARUS_InitEnt( ent );
00833 
00834                 if ( ent->classname && ent->classname[0] )
00835                 {
00836                         if ( Q_strncmp( "NPC_", ent->classname, 4 ) != 0 )
00837                         {//Not an NPC_spawner (rww - probably don't even care for MP, but whatever)
00838                                 G_ActivateBehavior( ent, BSET_SPAWN );
00839                         }
00840                 }
00841         }
00842 }

void G_UpdateCvars void   ) 
 

Definition at line 840 of file g_main.c.

References G_RemapTeamShaders(), qboolean, qfalse, qtrue, trap_Cvar_Update(), trap_SendServerCommand(), and va().

Referenced by G_RunFrame().

00840                            {
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 }

void Jedi_Decloak gentity_t self  ) 
 

Definition at line 818 of file NPC_AI_Jedi.c.

00819 {
00820         if ( self )
00821         {
00822                 self->flags &= ~FL_NOTARGET;
00823                 if ( self->client )
00824                 {
00825                         if ( self->client->ps.powerups[PW_CLOAKED] )
00826                         {//Uncloak
00827                                 self->client->ps.powerups[PW_CLOAKED] = 0;
00828 
00829                                 G_Sound( self, CHAN_ITEM, G_SoundIndex("sound/chars/shadowtrooper/decloak.wav") );
00830                         }
00831                 }
00832         }
00833 }

void LogExit const char *  string  ) 
 

Definition at line 2233 of file g_main.c.

References level_locals_t::clients, CON_CONNECTING, clientPersistant_t::connected, CS_INTERMISSION, g_gametype, G_LogPrintf(), gclient_t, GT_TEAM, vmCvar_t::integer, level_locals_t::intermissionQueued, level, clientPersistant_t::netname, level_locals_t::numConnectedClients, gclient_s::pers, PERS_SCORE, playerState_s::persistant, playerState_s::ping, gclient_s::ps, gclient_s::sess, clientSession_t::sessionTeam, level_locals_t::sortedClients, TEAM_BLUE, TEAM_RED, TEAM_SPECTATOR, level_locals_t::teamScores, level_locals_t::time, and trap_SetConfigstring().

Referenced by CheckExitRules(), siegeEndUse(), SiegeRoundComplete(), and Use_Target_Escapetrig().

02233                                    {
02234         int                             i, numSorted;
02235         gclient_t               *cl;
02236 //      qboolean                won = qtrue;
02237         G_LogPrintf( "Exit: %s\n", string );
02238 
02239         level.intermissionQueued = level.time;
02240 
02241         // this will keep the clients from playing any voice sounds
02242         // that will get cut off when the queued intermission starts
02243         trap_SetConfigstring( CS_INTERMISSION, "1" );
02244 
02245         // don't send more than 32 scores (FIXME?)
02246         numSorted = level.numConnectedClients;
02247         if ( numSorted > 32 ) {
02248                 numSorted = 32;
02249         }
02250 
02251         if ( g_gametype.integer >= GT_TEAM ) {
02252                 G_LogPrintf( "red:%i  blue:%i\n",
02253                         level.teamScores[TEAM_RED], level.teamScores[TEAM_BLUE] );
02254         }
02255 
02256         for (i=0 ; i < numSorted ; i++) {
02257                 int             ping;
02258 
02259                 cl = &level.clients[level.sortedClients[i]];
02260 
02261                 if ( cl->sess.sessionTeam == TEAM_SPECTATOR ) {
02262                         continue;
02263                 }
02264                 if ( cl->pers.connected == CON_CONNECTING ) {
02265                         continue;
02266                 }
02267 
02268                 ping = cl->ps.ping < 999 ? cl->ps.ping : 999;
02269 
02270                 G_LogPrintf( "score: %i  ping: %i  client: %i %s\n", cl->ps.persistant[PERS_SCORE], ping, level.sortedClients[i],       cl->pers.netname );
02271 //              if (g_singlePlayer.integer && (g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL)) {
02272 //                      if (g_entities[cl - level.clients].r.svFlags & SVF_BOT && cl->ps.persistant[PERS_RANK] == 0) {
02273 //                              won = qfalse;
02274 //                      }
02275 //              }
02276         }
02277 
02278         //yeah.. how about not.
02279         /*
02280         if (g_singlePlayer.integer) {
02281                 if (g_gametype.integer >= GT_CTF) {
02282                         won = level.teamScores[TEAM_RED] > level.teamScores[TEAM_BLUE];
02283                 }
02284                 trap_SendConsoleCommand( EXEC_APPEND, (won) ? "spWin\n" : "spLose\n" );
02285         }
02286         */
02287 }

void MoveClientToIntermission gentity_t ent  ) 
 

Definition at line 1927 of file g_main.c.

References gentity_s::client, entityShared_t::contents, entityState_s::eFlags, playerState_s::eFlags, ET_GENERAL, entityState_s::eType, entityState_s::event, gentity_t, level_locals_t::intermission_angle, level_locals_t::intermission_origin, level, entityState_s::loopIsSoundset, entityState_s::loopSound, memset(), entityState_s::modelindex, playerState_s::origin, entityState_s::origin, PM_INTERMISSION, playerState_s::pm_type, playerState_s::powerups, gclient_s::ps, qfalse, gentity_s::r, gentity_s::s, gclient_s::sess, SPECTATOR_FOLLOW, clientSession_t::spectatorState, StopFollowing(), VectorCopy, and playerState_s::viewangles.

Referenced by BeginIntermission(), and ClientSpawn().

01927                                                 {
01928         // take out of follow mode if needed
01929         if ( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) {
01930                 StopFollowing( ent );
01931         }
01932 
01933 
01934         // move to the spot
01935         VectorCopy( level.intermission_origin, ent->s.origin );
01936         VectorCopy( level.intermission_origin, ent->client->ps.origin );
01937         VectorCopy (level.intermission_angle, ent->client->ps.viewangles);
01938         ent->client->ps.pm_type = PM_INTERMISSION;
01939 
01940         // clean up powerup info
01941         memset( ent->client->ps.powerups, 0, sizeof(ent->client->ps.powerups) );
01942 
01943         ent->client->ps.eFlags = 0;
01944         ent->s.eFlags = 0;
01945         ent->s.eType = ET_GENERAL;
01946         ent->