Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

g_main.c File Reference

#include "g_local.h"

Include dependency graph for g_main.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  cvarTable_t

Functions

void AddTournamentPlayer (void)
void AdjustTournamentScores (void)
void BeginIntermission (void)
void CalculateRanks (void)
void CheckCvars (void)
void CheckExitRules (void)
void CheckIntermissionExit (void)
void CheckTeamLeader (int team)
void CheckTeamVote (int team)
void CheckTournament (void)
void CheckVote (void)
void QDECL Com_Error (int level, const char *error,...)
void QDECL Com_Printf (const char *msg,...)
void ExitLevel (void)
void FindIntermissionPoint (void)
void QDECL G_Error (const char *fmt,...)
void G_FindTeams (void)
void G_InitGame (int levelTime, int randomSeed, int restart)
void QDECL G_LogPrintf (const char *fmt,...)
void QDECL G_Printf (const char *fmt,...)
void G_RegisterCvars (void)
void G_RemapTeamShaders ()
void G_RunFrame (int levelTime)
void G_RunThink (gentity_t *ent)
void G_ShutdownGame (int restart)
void G_UpdateCvars (void)
void LogExit (const char *string)
void MoveClientToIntermission (gentity_t *ent)
void PrintTeam (int team, char *message)
void RemoveTournamentLoser (void)
void RemoveTournamentWinner (void)
qboolean ScoreIsTied (void)
void SendScoreboardMessageToAllClients (void)
void SetLeader (int team, int client)
int QDECL SortRanks (const void *a, const void *b)
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)

Variables

vmCvar_t g_allowVote
vmCvar_t g_banIPs
vmCvar_t g_blood
vmCvar_t g_capturelimit
vmCvar_t g_cheats
gclient_t g_clients [MAX_CLIENTS]
vmCvar_t g_debugAlloc
vmCvar_t g_debugDamage
vmCvar_t g_debugMove
vmCvar_t g_dedicated
vmCvar_t g_dmflags
vmCvar_t g_doWarmup
gentity_t g_entities [MAX_GENTITIES]
vmCvar_t g_filterBan
vmCvar_t g_forcerespawn
vmCvar_t g_fraglimit
vmCvar_t g_friendlyFire
vmCvar_t g_gametype
vmCvar_t g_gravity
vmCvar_t g_inactivity
vmCvar_t g_knockback
vmCvar_t g_listEntity
vmCvar_t g_log
vmCvar_t g_logSync
vmCvar_t g_maxclients
vmCvar_t g_maxGameClients
vmCvar_t g_motd
vmCvar_t g_needpass
vmCvar_t g_password
vmCvar_t g_podiumDist
vmCvar_t g_podiumDrop
vmCvar_t g_quadfactor
vmCvar_t g_rankings
vmCvar_t g_restarted
vmCvar_t g_smoothClients
vmCvar_t g_speed
vmCvar_t g_synchronousClients
vmCvar_t g_teamAutoJoin
vmCvar_t g_teamForceBalance
vmCvar_t g_timelimit
vmCvar_t g_warmup
vmCvar_t g_weaponRespawn
vmCvar_t g_weaponTeamRespawn
cvarTable_t gameCvarTable []
int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[0] )
level_locals_t level
vmCvar_t pmove_fixed
vmCvar_t pmove_msec


Function Documentation

void AddTournamentPlayer void   ) 
 

Definition at line 582 of file g_main.c.

References level_locals_t::clients, clientPersistant_t::connected, g_entities, gclient_t, i, level_locals_t::intermissiontime, level, level_locals_t::maxclients, level_locals_t::numPlayingClients, gclient_s::pers, gclient_s::sess, clientSession_t::sessionTeam, SetTeam(), SPECTATOR_SCOREBOARD, clientSession_t::spectatorClient, clientSession_t::spectatorState, clientSession_t::spectatorTime, and level_locals_t::warmupTime.

Referenced by CheckTournament().

00582                                  {
00583     int         i;
00584     gclient_t   *client;
00585     gclient_t   *nextInLine;
00586 
00587     if ( level.numPlayingClients >= 2 ) {
00588         return;
00589     }
00590 
00591     // never change during intermission
00592     if ( level.intermissiontime ) {
00593         return;
00594     }
00595 
00596     nextInLine = NULL;
00597 
00598     for ( i = 0 ; i < level.maxclients ; i++ ) {
00599         client = &level.clients[i];
00600         if ( client->pers.connected != CON_CONNECTED ) {
00601             continue;
00602         }
00603         if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
00604             continue;
00605         }
00606         // never select the dedicated follow or scoreboard clients
00607         if ( client->sess.spectatorState == SPECTATOR_SCOREBOARD || 
00608             client->sess.spectatorClient < 0  ) {
00609             continue;
00610         }
00611 
00612         if ( !nextInLine || client->sess.spectatorTime < nextInLine->sess.spectatorTime ) {
00613             nextInLine = client;
00614         }
00615     }
00616 
00617     if ( !nextInLine ) {
00618         return;
00619     }
00620 
00621     level.warmupTime = -1;
00622 
00623     // set them to free-for-all team
00624     SetTeam( &g_entities[ nextInLine - level.clients ], "f" );
00625 }

Here is the call graph for this function:

void AdjustTournamentScores void   ) 
 

Definition at line 678 of file g_main.c.

References level_locals_t::clients, ClientUserinfoChanged(), clientPersistant_t::connected, level, clientSession_t::losses, gclient_s::pers, gclient_s::sess, level_locals_t::sortedClients, and clientSession_t::wins.

Referenced by BeginIntermission().

00678                                     {
00679     int         clientNum;
00680 
00681     clientNum = level.sortedClients[0];
00682     if ( level.clients[ clientNum ].pers.connected == CON_CONNECTED ) {
00683         level.clients[ clientNum ].sess.wins++;
00684         ClientUserinfoChanged( clientNum );
00685     }
00686 
00687     clientNum = level.sortedClients[1];
00688     if ( level.clients[ clientNum ].pers.connected == CON_CONNECTED ) {
00689         level.clients[ clientNum ].sess.losses++;
00690         ClientUserinfoChanged( clientNum );
00691     }
00692 
00693 }

Here is the call graph for this function:

void BeginIntermission void   ) 
 

Definition at line 965 of file g_main.c.

References AdjustTournamentScores(), FindIntermissionPoint(), g_entities, g_gametype, g_singlePlayer, gentity_t, gentity_s::health, i, vmCvar_t::integer, level_locals_t::intermissiontime, gentity_s::inuse, level, level_locals_t::maxclients, MoveClientToIntermission(), respawn(), SendScoreboardMessageToAllClients(), SpawnModelsOnVictoryPads(), level_locals_t::time, trap_Cvar_Set(), and UpdateTournamentInfo().

Referenced by CheckExitRules(), and Cmd_LevelShot_f().

00965                                {
00966     int         i;
00967     gentity_t   *client;
00968 
00969     if ( level.intermissiontime ) {
00970         return;     // already active
00971     }
00972 
00973     // if in tournement mode, change the wins / losses
00974     if ( g_gametype.integer == GT_TOURNAMENT ) {
00975         AdjustTournamentScores();
00976     }
00977 
00978     level.intermissiontime = level.time;
00979     FindIntermissionPoint();
00980 
00981 #ifdef MISSIONPACK
00982     if (g_singlePlayer.integer) {
00983         trap_Cvar_Set("ui_singlePlayerActive", "0");
00984         UpdateTournamentInfo();
00985     }
00986 #else
00987     // if single player game
00988     if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
00989         UpdateTournamentInfo();
00990         SpawnModelsOnVictoryPads();
00991     }
00992 #endif
00993 
00994     // move all clients to the intermission point
00995     for (i=0 ; i< level.maxclients ; i++) {
00996         client = g_entities + i;
00997         if (!client->inuse)
00998             continue;
00999         // respawn if dead
01000         if (client->health <= 0) {
01001             respawn(client);
01002         }
01003         MoveClientToIntermission( client );
01004     }
01005 
01006     // send the current scoring to all clients
01007     SendScoreboardMessageToAllClients();
01008 
01009 }

Here is the call graph for this function:

void CalculateRanks void   ) 
 

Definition at line 762 of file g_main.c.

References CheckExitRules(), cl, level_locals_t::clients, clientPersistant_t::connected, CS_SCORES1, CS_SCORES2, level_locals_t::follow1, level_locals_t::follow2, g_entities, g_gametype, gclient_t, GT_SINGLE_PLAYER, i, 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_SCORE, playerState_s::persistant, gclient_s::ps, qsort(), gentity_s::r, SCORE_NOT_PRESENT, SendScoreboardMessageToAllClients(), gclient_s::sess, clientSession_t::sessionTeam, level_locals_t::sortedClients, SortRanks(), entityShared_t::svFlags, TEAM_BLUE, TEAM_RED, level_locals_t::teamScores, trap_SetConfigstring(), and va().

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

00762                             {
00763     int     i;
00764     int     rank;
00765     int     score;
00766     int     newScore;
00767     gclient_t   *cl;
00768 
00769     level.follow1 = -1;
00770     level.follow2 = -1;
00771     level.numConnectedClients = 0;
00772     level.numNonSpectatorClients = 0;
00773     level.numPlayingClients = 0;
00774     level.numVotingClients = 0;     // don't count bots
00775     for ( i = 0; i < TEAM_NUM_TEAMS; i++ ) {
00776         level.numteamVotingClients[i] = 0;
00777     }
00778     for ( i = 0 ; i < level.maxclients ; i++ ) {
00779         if ( level.clients[i].pers.connected != CON_DISCONNECTED ) {
00780             level.sortedClients[level.numConnectedClients] = i;
00781             level.numConnectedClients++;
00782 
00783             if ( level.clients[i].sess.sessionTeam != TEAM_SPECTATOR ) {
00784                 level.numNonSpectatorClients++;
00785             
00786                 // decide if this should be auto-followed
00787                 if ( level.clients[i].pers.connected == CON_CONNECTED ) {
00788                     level.numPlayingClients++;
00789                     if ( !(g_entities[i].r.svFlags & SVF_BOT) ) {
00790                         level.numVotingClients++;
00791                         if ( level.clients[i].sess.sessionTeam == TEAM_RED )
00792                             level.numteamVotingClients[0]++;
00793                         else if ( level.clients[i].sess.sessionTeam == TEAM_BLUE )
00794                             level.numteamVotingClients[1]++;
00795                     }
00796                     if ( level.follow1 == -1 ) {
00797                         level.follow1 = i;
00798                     } else if ( level.follow2 == -1 ) {
00799                         level.follow2 = i;
00800                     }
00801                 }
00802             }
00803         }
00804     }
00805 
00806     qsort( level.sortedClients, level.numConnectedClients, 
00807         sizeof(level.sortedClients[0]), SortRanks );
00808 
00809     // set the rank value for all clients that are connected and not spectators
00810     if ( g_gametype.integer >= GT_TEAM ) {
00811         // in team games, rank is just the order of the teams, 0=red, 1=blue, 2=tied
00812         for ( i = 0;  i < level.numConnectedClients; i++ ) {
00813             cl = &level.clients[ level.sortedClients[i] ];
00814             if ( level.teamScores[TEAM_RED] == level.teamScores[TEAM_BLUE] ) {
00815                 cl->ps.persistant[PERS_RANK] = 2;
00816             } else if ( level.teamScores[TEAM_RED] > level.teamScores[TEAM_BLUE] ) {
00817                 cl->ps.persistant[PERS_RANK] = 0;
00818             } else {
00819                 cl->ps.persistant[PERS_RANK] = 1;
00820             }
00821         }
00822     } else {    
00823         rank = -1;
00824         score = 0;
00825         for ( i = 0;  i < level.numPlayingClients; i++ ) {
00826             cl = &level.clients[ level.sortedClients[i] ];
00827             newScore = cl->ps.persistant[PERS_SCORE];
00828             if ( i == 0 || newScore != score ) {
00829                 rank = i;
00830                 // assume we aren't tied until the next client is checked
00831                 level.clients[ level.sortedClients[i] ].ps.persistant[PERS_RANK] = rank;
00832             } else {
00833                 // we are tied with the previous client
00834                 level.clients[ level.sortedClients[i-1] ].ps.persistant[PERS_RANK] = rank | RANK_TIED_FLAG;
00835                 level.clients[ level.sortedClients[i] ].ps.persistant[PERS_RANK] = rank | RANK_TIED_FLAG;
00836             }
00837             score = newScore;
00838             if ( g_gametype.integer == GT_SINGLE_PLAYER && level.numPlayingClients == 1 ) {
00839                 level.clients[ level.sortedClients[i] ].ps.persistant[PERS_RANK] = rank | RANK_TIED_FLAG;
00840             }
00841         }
00842     }
00843 
00844     // set the CS_SCORES1/2 configstrings, which will be visible to everyone
00845     if ( g_gametype.integer >= GT_TEAM ) {
00846         trap_SetConfigstring( CS_SCORES1, va("%i", level.teamScores[TEAM_RED] ) );
00847         trap_SetConfigstring( CS_SCORES2, va("%i", level.teamScores[TEAM_BLUE] ) );
00848     } else {
00849         if ( level.numConnectedClients == 0 ) {
00850             trap_SetConfigstring( CS_SCORES1, va("%i", SCORE_NOT_PRESENT) );
00851             trap_SetConfigstring( CS_SCORES2, va("%i", SCORE_NOT_PRESENT) );
00852         } else if ( level.numConnectedClients == 1 ) {
00853             trap_SetConfigstring( CS_SCORES1, va("%i", level.clients[ level.sortedClients[0] ].ps.persistant[PERS_SCORE] ) );
00854             trap_SetConfigstring( CS_SCORES2, va("%i", SCORE_NOT_PRESENT) );
00855         } else {
00856             trap_SetConfigstring( CS_SCORES1, va("%i", level.clients[ level.sortedClients[0] ].ps.persistant[PERS_SCORE] ) );
00857             trap_SetConfigstring( CS_SCORES2, va("%i", level.clients[ level.sortedClients[1] ].ps.persistant[PERS_SCORE] ) );
00858         }
00859     }
00860 
00861     // see if it is time to end the level
00862     CheckExitRules();
00863 
00864     // if we are at the intermission, send the new info to everyone
00865     if ( level.intermissiontime ) {
00866         SendScoreboardMessageToAllClients();
00867     }
00868 }

Here is the call graph for this function:

void CheckCvars void   ) 
 

Definition at line 1668 of file g_main.c.

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

Referenced by G_RunFrame().

01668                         {
01669     static int lastMod = -1;
01670 
01671     if ( g_password.modificationCount != lastMod ) {
01672         lastMod = g_password.modificationCount;
01673         if ( *g_password.string && Q_stricmp( g_password.string, "none" ) ) {
01674             trap_Cvar_Set( "g_needpass", "1" );
01675         } else {
01676             trap_Cvar_Set( "g_needpass", "0" );
01677         }
01678     }
01679 }

Here is the call graph for this function:

void CheckExitRules void   ) 
 

Definition at line 1292 of file g_main.c.

References BeginIntermission(), CheckIntermissionExit(), cl, level_locals_t::clients, g_capturelimit, g_fraglimit, g_gametype, g_maxclients, g_singlePlayer, g_timelimit, gclient_t, GT_CTF, i, vmCvar_t::integer, level_locals_t::intermissionQueued, level_locals_t::intermissiontime, level, LogExit(), level_locals_t::numPlayingClients, S_COLOR_WHITE, ScoreIsTied(), SP_INTERMISSION_DELAY_TIME, level_locals_t::startTime, level_locals_t::teamScores, level_locals_t::time, time(), trap_SendServerCommand(), va(), and level_locals_t::warmupTime.

Referenced by CalculateRanks(), and G_RunFrame().

01292                             {
01293     int         i;
01294     gclient_t   *cl;
01295     // if at the intermission, wait for all non-bots to
01296     // signal ready, then go to next level
01297     if ( level.intermissiontime ) {
01298         CheckIntermissionExit ();
01299         return;
01300     }
01301 
01302     if ( level.intermissionQueued ) {
01303 #ifdef MISSIONPACK
01304         int time = (g_singlePlayer.integer) ? SP_INTERMISSION_DELAY_TIME : INTERMISSION_DELAY_TIME;
01305         if ( level.time - level.intermissionQueued >= time ) {
01306             level.intermissionQueued = 0;
01307             BeginIntermission();
01308         }
01309 #else
01310         if ( level.time - level.intermissionQueued >= INTERMISSION_DELAY_TIME ) {
01311             level.intermissionQueued = 0;
01312             BeginIntermission();
01313         }
01314 #endif
01315         return;
01316     }
01317 
01318     // check for sudden death
01319     if ( ScoreIsTied() ) {
01320         // always wait for sudden death
01321         return;
01322     }
01323 
01324     if ( g_timelimit.integer && !level.warmupTime ) {
01325         if ( level.time - level.startTime >= g_timelimit.integer*60000 ) {
01326             trap_SendServerCommand( -1, "print \"Timelimit hit.\n\"");
01327             LogExit( "Timelimit hit." );
01328             return;
01329         }
01330     }
01331 
01332     if ( level.numPlayingClients < 2 ) {
01333         return;
01334     }
01335 
01336     if ( g_gametype.integer < GT_CTF && g_fraglimit.integer ) {
01337         if ( level.teamScores[TEAM_RED] >= g_fraglimit.integer ) {
01338             trap_SendServerCommand( -1, "print \"Red hit the fraglimit.\n\"" );
01339             LogExit( "Fraglimit hit." );
01340             return;
01341         }
01342 
01343         if ( level.teamScores[TEAM_BLUE] >= g_fraglimit.integer ) {
01344             trap_SendServerCommand( -1, "print \"Blue hit the fraglimit.\n\"" );
01345             LogExit( "Fraglimit hit." );
01346             return;
01347         }
01348 
01349         for ( i=0 ; i< g_maxclients.integer ; i++ ) {
01350             cl = level.clients + i;
01351             if ( cl->pers.connected != CON_CONNECTED ) {
01352                 continue;
01353             }
01354             if ( cl->sess.sessionTeam != TEAM_FREE ) {
01355                 continue;
01356             }
01357 
01358             if ( cl->ps.persistant[PERS_SCORE] >= g_fraglimit.integer ) {
01359                 LogExit( "Fraglimit hit." );
01360                 trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " hit the fraglimit.\n\"",
01361                     cl->pers.netname ) );
01362                 return;
01363             }
01364         }
01365     }
01366 
01367     if ( g_gametype.integer >= GT_CTF && g_capturelimit.integer ) {
01368 
01369         if ( level.teamScores[TEAM_RED] >= g_capturelimit.integer ) {
01370             trap_SendServerCommand( -1, "print \"Red hit the capturelimit.\n\"" );
01371             LogExit( "Capturelimit hit." );
01372             return;
01373         }
01374 
01375         if ( level.teamScores[TEAM_BLUE] >= g_capturelimit.integer ) {
01376             trap_SendServerCommand( -1, "print \"Blue hit the capturelimit.\n\"" );
01377             LogExit( "Capturelimit hit." );
01378             return;
01379         }
01380     }
01381 }

Here is the call graph for this function:

void CheckIntermissionExit void   ) 
 

Definition at line 1186 of file g_main.c.

References cl, level_locals_t::clients, ExitLevel(), level_locals_t::exitTime, g_entities, g_gametype, g_maxclients, gclient_t, i, vmCvar_t::integer, level_locals_t::intermissiontime, level, gentity_s::r, level_locals_t::readyToExit, entityShared_t::svFlags, and level_locals_t::time.

Referenced by CheckExitRules().

01186                                    {
01187     int         ready, notReady;
01188     int         i;
01189     gclient_t   *cl;
01190     int         readyMask;
01191 
01192     if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
01193         return;
01194     }
01195 
01196     // see which players are ready
01197     ready = 0;
01198     notReady = 0;
01199     readyMask = 0;
01200     for (i=0 ; i< g_maxclients.integer ; i++) {
01201         cl = level.clients + i;
01202         if ( cl->pers.connected != CON_CONNECTED ) {
01203             continue;
01204         }
01205         if ( g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT ) {
01206             continue;
01207         }
01208 
01209         if ( cl->readyToExit ) {
01210             ready++;
01211             if ( i < 16 ) {
01212                 readyMask |= 1 << i;
01213             }
01214         } else {
01215             notReady++;
01216         }
01217     }
01218 
01219     // copy the readyMask to each player's stats so
01220     // it can be displayed on the scoreboard
01221     for (i=0 ; i< g_maxclients.integer ; i++) {
01222         cl = level.clients + i;
01223         if ( cl->pers.connected != CON_CONNECTED ) {
01224             continue;
01225         }
01226         cl->ps.stats[STAT_CLIENTS_READY] = readyMask;
01227     }
01228 
01229     // never exit in less than five seconds
01230     if ( level.time < level.intermissiontime + 5000 ) {
01231         return;
01232     }
01233 
01234     // if nobody wants to go, clear timer
01235     if ( !ready ) {
01236         level.readyToExit = qfalse;
01237         return;
01238     }
01239 
01240     // if everyone wants to go, go now
01241     if ( !notReady ) {
01242         ExitLevel();
01243         return;
01244     }
01245 
01246     // the first person to ready starts the ten second timeout
01247     if ( !level.readyToExit ) {
01248         level.readyToExit = qtrue;
01249         level.exitTime = level.time;
01250     }
01251 
01252     // if we have waited ten seconds since at least one player
01253     // wanted to exit, go ahead
01254     if ( level.time < level.exitTime + 10000 ) {
01255         return;
01256     }
01257 
01258     ExitLevel();
01259 }

Here is the call graph for this function:

void CheckTeamLeader int  team  ) 
 

Definition at line 1590 of file g_main.c.

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

Referenced by SetTeam().

01590                                  {
01591     int i;
01592 
01593     for ( i = 0 ; i < level.maxclients ; i++ ) {
01594         if (level.clients[i].sess.sessionTeam != team)
01595             continue;
01596         if (level.clients[i].sess.teamLeader)
01597             break;
01598     }
01599     if (i >= level.maxclients) {
01600         for ( i = 0 ; i < level.maxclients ; i++ ) {
01601             if (level.clients[i].sess.sessionTeam != team)
01602                 continue;
01603             if (!(g_entities[i].r.svFlags & SVF_BOT)) {
01604                 level.clients[i].sess.teamLeader = qtrue;
01605                 break;
01606             }
01607         }
01608         for ( i = 0 ; i < level.maxclients ; i++ ) {
01609             if (level.clients[i].sess.sessionTeam != team)
01610                 continue;
01611             level.clients[i].sess.teamLeader = qtrue;
01612             break;
01613         }
01614     }
01615 }

void CheckTeamVote int  team  ) 
 

Definition at line 1622 of file g_main.c.

References atoi, CS_TEAMVOTE_TIME, EXEC_APPEND, level, level_locals_t::numteamVotingClients, Q_strncmp(), SetLeader(), 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(), and va().

Referenced by G_RunFrame().

01622                                {
01623     int cs_offset;
01624 
01625     if ( team == TEAM_RED )
01626         cs_offset = 0;
01627     else if ( team == TEAM_BLUE )
01628         cs_offset = 1;
01629     else
01630         return;
01631 
01632     if ( !level.teamVoteTime[cs_offset] ) {
01633         return;
01634     }
01635     if ( level.time - level.teamVoteTime[cs_offset] >= VOTE_TIME ) {
01636         trap_SendServerCommand( -1, "print \"Team vote failed.\n\"" );
01637     } else {
01638         if ( level.teamVoteYes[cs_offset] > level.numteamVotingClients[cs_offset]/2 ) {
01639             // execute the command, then remove the vote
01640             trap_SendServerCommand( -1, "print \"Team vote passed.\n\"" );
01641             //
01642             if ( !Q_strncmp( "leader", level.teamVoteString[cs_offset], 6) ) {
01643                 //set the team leader
01644                 SetLeader(team, atoi(level.teamVoteString[cs_offset] + 7));
01645             }
01646             else {
01647                 trap_SendConsoleCommand( EXEC_APPEND, va("%s\n", level.teamVoteString[cs_offset] ) );
01648             }
01649         } else if ( level.teamVoteNo[cs_offset] >= level.numteamVotingClients[cs_offset]/2 ) {
01650             // same behavior as a timeout
01651             trap_SendServerCommand( -1, "print \"Team vote failed.\n\"" );
01652         } else {
01653             // still waiting for a majority
01654             return;
01655         }
01656     }
01657     level.teamVoteTime[cs_offset] = 0;
01658     trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, "" );
01659 
01660 }

Here is the call graph for this function:

void CheckTournament void   ) 
 

Definition at line 1401 of file g_main.c.

References AddTournamentPlayer(), CS_WARMUP, EXEC_APPEND, g_gametype, G_LogPrintf(), g_warmup, GT_SINGLE_PLAYER, vmCvar_t::integer, level, vmCvar_t::modificationCount, level_locals_t::numPlayingClients, qboolean, level_locals_t::restarted, TEAM_BLUE, TEAM_RED, TeamCount(), level_locals_t::time, trap_Cvar_Set(), trap_SendConsoleCommand(), trap_SetConfigstring(), va(), level_locals_t::warmupModificationCount, and level_locals_t::warmupTime.

Referenced by G_RunFrame().

01401                              {
01402     // check because we run 3 game frames before calling Connect and/or ClientBegin
01403     // for clients on a map_restart
01404     if ( level.numPlayingClients == 0 ) {
01405         return;
01406     }
01407 
01408     if ( g_gametype.integer == GT_TOURNAMENT ) {
01409 
01410         // pull in a spectator if needed
01411         if ( level.numPlayingClients < 2 ) {
01412             AddTournamentPlayer();
01413         }
01414 
01415         // if we don't have two players, go back to "waiting for players"
01416         if ( level.numPlayingClients != 2 ) {
01417             if ( level.warmupTime != -1 ) {
01418                 level.warmupTime = -1;
01419                 trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) );
01420                 G_LogPrintf( "Warmup:\n" );
01421             }
01422             return;
01423         }
01424 
01425         if ( level.warmupTime == 0 ) {
01426             return;
01427         }
01428 
01429         // if the warmup is changed at the console, restart it
01430         if ( g_warmup.modificationCount != level.warmupModificationCount ) {
01431             level.warmupModificationCount = g_warmup.modificationCount;
01432             level.warmupTime = -1;
01433         }
01434 
01435         // if all players have arrived, start the countdown
01436         if ( level.warmupTime < 0 ) {
01437             if ( level.numPlayingClients == 2 ) {
01438                 // fudge by -1 to account for extra delays
01439                 level.warmupTime = level.time + ( g_warmup.integer - 1 ) * 1000;
01440                 trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) );
01441             }
01442             return;
01443         }
01444 
01445         // if the warmup time has counted down, restart
01446         if ( level.time > level.warmupTime ) {
01447             level.warmupTime += 10000;
01448             trap_Cvar_Set( "g_restarted", "1" );
01449             trap_SendConsoleCommand( EXEC_APPEND, "map_restart 0\n" );
01450             level.restarted = qtrue;
01451             return;
01452         }
01453     } else if ( g_gametype.integer != GT_SINGLE_PLAYER && level.warmupTime != 0 ) {
01454         int     counts[TEAM_NUM_TEAMS];
01455         qboolean    notEnough = qfalse;
01456 
01457         if ( g_gametype.integer > GT_TEAM ) {
01458             counts[TEAM_BLUE] = TeamCount( -1, TEAM_BLUE );
01459             counts[TEAM_RED] = TeamCount( -1, TEAM_RED );
01460 
01461             if (counts[TEAM_RED] < 1 || counts[TEAM_BLUE] < 1) {
01462                 notEnough = qtrue;
01463             }
01464         } else if ( level.numPlayingClients < 2 ) {
01465             notEnough = qtrue;
01466         }
01467 
01468         if ( notEnough ) {
01469             if ( level.warmupTime != -1 ) {
01470                 level.warmupTime = -1;
01471                 trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) );
01472                 G_LogPrintf( "Warmup:\n" );
01473             }
01474             return; // still waiting for team members
01475         }
01476 
01477         if ( level.warmupTime == 0 ) {
01478             return;
01479         }
01480 
01481         // if the warmup is changed at the console, restart it
01482         if ( g_warmup.modificationCount != level.warmupModificationCount ) {
01483             level.warmupModificationCount = g_warmup.modificationCount;
01484             level.warmupTime = -1;
01485         }
01486 
01487         // if all players have arrived, start the countdown
01488         if ( level.warmupTime < 0 ) {
01489             // fudge by -1 to account for extra delays
01490             level.warmupTime = level.time + ( g_warmup.integer - 1 ) * 1000;
01491             trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) );
01492             return;
01493         }
01494 
01495         // if the warmup time has counted down, restart
01496         if ( level.time > level.warmupTime ) {
01497             level.warmupTime += 10000;
01498             trap_Cvar_Set( "g_restarted", "1" );
01499             trap_SendConsoleCommand( EXEC_APPEND, "map_restart 0\n" );
01500             level.restarted = qtrue;
01501             return;
01502         }
01503     }
01504 }

Here is the call graph for this function:

void CheckVote void   ) 
 

Definition at line 1512 of file g_main.c.

References CS_VOTE_TIME, EXEC_APPEND, level, level_locals_t::numVotingClients, level_locals_t::time, trap_SendConsoleCommand(), trap_SendServerCommand(), trap_SetConfigstring(), va(), level_locals_t::voteExecuteTime, level_locals_t::voteNo, level_locals_t::voteString, level_locals_t::voteTime, and level_locals_t::voteYes.

Referenced by G_RunFrame().

01512                        {
01513     if ( level.voteExecuteTime && level.voteExecuteTime < level.time ) {
01514         level.voteExecuteTime = 0;
01515         trap_SendConsoleCommand( EXEC_APPEND, va("%s\n", level.voteString ) );
01516     }
01517     if ( !level.voteTime ) {
01518         return;
01519     }
01520     if ( level.time - level.voteTime >= VOTE_TIME ) {
01521         trap_SendServerCommand( -1, "print \"Vote failed.\n\"" );
01522     } else {
01523         // ATVI Q3 1.32 Patch #9, WNF
01524         if ( level.voteYes > level.numVotingClients/2 ) {
01525             // execute the command, then remove the vote
01526             trap_SendServerCommand( -1, "print \"Vote passed.\n\"" );
01527             level.voteExecuteTime = level.time + 3000;
01528         } else if ( level.voteNo >= level.numVotingClients/2 ) {
01529             // same behavior as a timeout
01530             trap_SendServerCommand( -1, "print \"Vote failed.\n\"" );
01531         } else {
01532