summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cgame/cg_draw.c73
-rw-r--r--src/cgame/cg_local.h16
-rw-r--r--src/cgame/cg_main.c13
-rw-r--r--src/cgame/cg_servercmds.c76
-rw-r--r--src/game/bg_public.h13
-rw-r--r--src/game/g_active.c6
-rw-r--r--src/game/g_admin.c31
-rw-r--r--src/game/g_buildable.c2
-rw-r--r--src/game/g_client.c5
-rw-r--r--src/game/g_cmds.c637
-rw-r--r--src/game/g_local.h37
-rw-r--r--src/game/g_main.c323
-rw-r--r--src/game/g_svcmds.c16
-rw-r--r--src/game/g_team.c2
14 files changed, 383 insertions, 867 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index 4ae6792d..ba8aaacf 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -2756,76 +2756,39 @@ static void CG_DrawCenterString( void )
CG_DrawVote
=================
*/
-static void CG_DrawVote( void )
+static void CG_DrawVote( team_t team )
{
char *s;
int sec;
vec4_t white = { 1.0f, 1.0f, 1.0f, 1.0f };
char yeskey[ 32 ], nokey[ 32 ];
- if( !cgs.voteTime )
+ if( !cgs.voteTime[ team ] )
return;
// play a talk beep whenever it is modified
- if( cgs.voteModified )
+ if( cgs.voteModified[ team ] )
{
- cgs.voteModified = qfalse;
+ cgs.voteModified[ team ] = qfalse;
trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
}
- sec = ( VOTE_TIME - ( cg.time - cgs.voteTime ) ) / 1000;
+ sec = ( VOTE_TIME - ( cg.time - cgs.voteTime[ team ] ) ) / 1000;
if( sec < 0 )
sec = 0;
- Q_strncpyz( yeskey, CG_KeyBinding( "vote yes" ), sizeof( yeskey ) );
- Q_strncpyz( nokey, CG_KeyBinding( "vote no" ), sizeof( nokey ) );
- s = va( "VOTE(%i): \"%s\" [%s]Yes:%i [%s]No:%i", sec, cgs.voteString,
- yeskey, cgs.voteYes, nokey, cgs.voteNo );
- UI_Text_Paint( 8, 340, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
-}
-
-/*
-=================
-CG_DrawTeamVote
-=================
-*/
-static void CG_DrawTeamVote( void )
-{
- char *s;
- int sec, cs_offset;
- vec4_t white = { 1.0f, 1.0f, 1.0f, 1.0f };
- char yeskey[ 32 ], nokey[ 32 ];
-
- if( cg.predictedPlayerState.stats[ STAT_TEAM ] == TEAM_HUMANS )
- cs_offset = 0;
- else if( cg.predictedPlayerState.stats[ STAT_TEAM ] == TEAM_ALIENS )
- cs_offset = 1;
- else
- return;
-
- if( !cgs.teamVoteTime[ cs_offset ] )
- return;
-
- // play a talk beep whenever it is modified
- if ( cgs.teamVoteModified[ cs_offset ] )
- {
- cgs.teamVoteModified[ cs_offset ] = qfalse;
- trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
- }
-
- sec = ( VOTE_TIME - ( cg.time - cgs.teamVoteTime[ cs_offset ] ) ) / 1000;
-
- if( sec < 0 )
- sec = 0;
-
- Q_strncpyz( yeskey, CG_KeyBinding( "teamvote yes" ), sizeof( yeskey ) );
- Q_strncpyz( nokey, CG_KeyBinding( "teamvote no" ), sizeof( nokey ) );
- s = va( "TEAMVOTE(%i): \"%s\" [%s]Yes:%i [%s]No:%i", sec,
- cgs.teamVoteString[ cs_offset ],
- yeskey, cgs.teamVoteYes[cs_offset],
- nokey, cgs.teamVoteNo[ cs_offset ] );
- UI_Text_Paint( 8, 360, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
+ Q_strncpyz( yeskey,
+ CG_KeyBinding( va( "%svote yes", team == TEAM_NONE ? "" : "team" ) ),
+ sizeof( yeskey ) );
+ Q_strncpyz( nokey,
+ CG_KeyBinding( va( "%svote no", team == TEAM_NONE ? "" : "team" ) ),
+ sizeof( nokey ) );
+ s = va( "%sVOTE(%i): \"%s\" [%s]Yes:%i [%s]No:%i",
+ team == TEAM_NONE ? "" : "TEAM", sec, cgs.voteString[ team ],
+ yeskey, cgs.voteYes[ team ], nokey, cgs.voteNo[ team ] );
+ UI_Text_Paint( 8, team == TEAM_NONE ? 340 : 360, 0.3f, white, s, 0, 0,
+ ITEM_TEXTSTYLE_NORMAL );
}
@@ -2999,8 +2962,8 @@ static void CG_Draw2D( void )
Menu_Paint( menu, qtrue );
- CG_DrawVote( );
- CG_DrawTeamVote( );
+ CG_DrawVote( TEAM_NONE );
+ CG_DrawVote( cg.predictedPlayerState.stats[ STAT_TEAM ] );
CG_DrawQueue( );
// don't draw center string if scoreboard is up
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 17328819..f7dda861 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -1356,17 +1356,11 @@ typedef struct
char mapname[ MAX_QPATH ];
qboolean markDeconstruct; // Whether or not buildables are marked
- int voteTime;
- int voteYes;
- int voteNo;
- qboolean voteModified; // beep whenever changed
- char voteString[ MAX_STRING_TOKENS ];
-
- int teamVoteTime[ 2 ];
- int teamVoteYes[ 2 ];
- int teamVoteNo[ 2 ];
- qboolean teamVoteModified[ 2 ]; // beep whenever changed
- char teamVoteString[ 2 ][ MAX_STRING_TOKENS ];
+ int voteTime[ NUM_TEAMS ];
+ int voteYes[ NUM_TEAMS ];
+ int voteNo[ NUM_TEAMS ];
+ qboolean voteModified[ NUM_TEAMS ];// beep whenever changed
+ char voteString[ NUM_TEAMS ][ MAX_STRING_TOKENS ];
int levelStartTime;
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index 68a34159..01c24579 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -1763,12 +1763,15 @@ void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
// copy vote display strings so they don't show up blank if we see
// the same one directly after connecting
- Q_strncpyz( cgs.voteString, CG_ConfigString( CS_VOTE_STRING ),
+ Q_strncpyz( cgs.voteString[ TEAM_NONE ],
+ CG_ConfigString( CS_VOTE_STRING + TEAM_NONE ),
sizeof( cgs.voteString ) );
- Q_strncpyz( cgs.teamVoteString[ 0 ], CG_ConfigString( CS_TEAMVOTE_STRING + 0 ),
- sizeof( cgs.teamVoteString[ 0 ] ) );
- Q_strncpyz( cgs.teamVoteString[ 1 ], CG_ConfigString( CS_TEAMVOTE_STRING + 1 ),
- sizeof( cgs.teamVoteString[ 1 ] ) );
+ Q_strncpyz( cgs.voteString[ TEAM_ALIENS ],
+ CG_ConfigString( CS_VOTE_STRING + TEAM_ALIENS ),
+ sizeof( cgs.voteString[ TEAM_ALIENS ] ) );
+ Q_strncpyz( cgs.voteString[ TEAM_HUMANS ],
+ CG_ConfigString( CS_VOTE_STRING + TEAM_ALIENS ),
+ sizeof( cgs.voteString[ TEAM_HUMANS ] ) );
// check version
s = CG_ConfigString( CS_GAME_VERSION );
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index 2d9b7038..8e18fd9c 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -291,65 +291,33 @@ static void CG_ConfigStringModified( void )
}
else if( num == CS_LEVEL_START_TIME )
cgs.levelStartTime = atoi( str );
- else if( num == CS_VOTE_TIME )
+ else if( num >= CS_VOTE_TIME && num < CS_VOTE_TIME + NUM_TEAMS )
{
- cgs.voteTime = atoi( str );
- cgs.voteModified = qtrue;
-
- if( cgs.voteTime )
- trap_Cvar_Set( "ui_voteActive", "1" );
- else
- trap_Cvar_Set( "ui_voteActive", "0" );
- }
- else if( num == CS_VOTE_YES )
- {
- cgs.voteYes = atoi( str );
- cgs.voteModified = qtrue;
- }
- else if( num == CS_VOTE_NO )
- {
- cgs.voteNo = atoi( str );
- cgs.voteModified = qtrue;
- }
- else if( num == CS_VOTE_STRING )
- Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
- else if( num >= CS_TEAMVOTE_TIME && num <= CS_TEAMVOTE_TIME + 1 )
- {
- int cs_offset = num - CS_TEAMVOTE_TIME;
-
- cgs.teamVoteTime[ cs_offset ] = atoi( str );
- cgs.teamVoteModified[ cs_offset ] = qtrue;
-
- if( cs_offset == 0 )
- {
- if( cgs.teamVoteTime[ cs_offset ] )
- trap_Cvar_Set( "ui_humanTeamVoteActive", "1" );
- else
- trap_Cvar_Set( "ui_humanTeamVoteActive", "0" );
- }
- else if( cs_offset == 1 )
- {
- if( cgs.teamVoteTime[ cs_offset ] )
- trap_Cvar_Set( "ui_alienTeamVoteActive", "1" );
- else
- trap_Cvar_Set( "ui_alienTeamVoteActive", "0" );
- }
- }
- else if( num >= CS_TEAMVOTE_YES && num <= CS_TEAMVOTE_YES + 1 )
- {
- cgs.teamVoteYes[ num - CS_TEAMVOTE_YES ] = atoi( str );
- cgs.teamVoteModified[ num - CS_TEAMVOTE_YES ] = qtrue;
+ cgs.voteTime[ num - CS_VOTE_TIME ] = atoi( str );
+ cgs.voteModified[ num - CS_VOTE_TIME ] = qtrue;
+
+ if( num - CS_VOTE_TIME == TEAM_NONE )
+ trap_Cvar_Set( "ui_voteActive", cgs.voteTime[ TEAM_NONE ] ? "1" : "0" );
+ else if( num - CS_VOTE_TIME == TEAM_ALIENS )
+ trap_Cvar_Set( "ui_alienTeamVoteActive",
+ cgs.voteTime[ TEAM_ALIENS ] ? "1" : "0" );
+ else if( num - CS_VOTE_TIME == TEAM_HUMANS )
+ trap_Cvar_Set( "ui_humanTeamVoteActive",
+ cgs.voteTime[ TEAM_HUMANS ] ? "1" : "0" );
}
- else if( num >= CS_TEAMVOTE_NO && num <= CS_TEAMVOTE_NO + 1 )
+ else if( num >= CS_VOTE_YES && num < CS_VOTE_YES + NUM_TEAMS )
{
- cgs.teamVoteNo[ num - CS_TEAMVOTE_NO ] = atoi( str );
- cgs.teamVoteModified[ num - CS_TEAMVOTE_NO ] = qtrue;
+ cgs.voteYes[ num - CS_VOTE_YES ] = atoi( str );
+ cgs.voteModified[ num - CS_VOTE_YES ] = qtrue;
}
- else if( num >= CS_TEAMVOTE_STRING && num <= CS_TEAMVOTE_STRING + 1 )
+ else if( num >= CS_VOTE_NO && num < CS_VOTE_NO + NUM_TEAMS )
{
- Q_strncpyz( cgs.teamVoteString[ num - CS_TEAMVOTE_STRING ], str,
- sizeof( cgs.teamVoteString[ num - CS_TEAMVOTE_STRING ] ) );
+ cgs.voteNo[ num - CS_VOTE_NO ] = atoi( str );
+ cgs.voteModified[ num - CS_VOTE_NO ] = qtrue;
}
+ else if( num >= CS_VOTE_STRING && num < CS_VOTE_STRING + NUM_TEAMS )
+ Q_strncpyz( cgs.voteString[ num - CS_VOTE_STRING ], str,
+ sizeof( cgs.voteString[ num - CS_VOTE_STRING ] ) );
else if( num == CS_INTERMISSION )
cg.intermissionStarted = atoi( str );
else if( num >= CS_MODELS && num < CS_MODELS+MAX_MODELS )
@@ -406,7 +374,7 @@ static void CG_MapRestart( void )
cg.intermissionStarted = qfalse;
- cgs.voteTime = 0;
+ cgs.voteTime[ TEAM_NONE ] = 0;
cg.mapRestart = qtrue;
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index a42fb735..480139cf 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -52,14 +52,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// 6 UNUSED
// 7 UNUSED
#define CS_VOTE_TIME 8
-#define CS_VOTE_STRING 9
-#define CS_VOTE_YES 10
-#define CS_VOTE_NO 11
-
-#define CS_TEAMVOTE_TIME 12
-#define CS_TEAMVOTE_STRING 14
-#define CS_TEAMVOTE_YES 16
-#define CS_TEAMVOTE_NO 18
+#define CS_VOTE_STRING (CS_VOTE_TIME + NUM_TEAMS)
+#define CS_VOTE_YES (CS_VOTE_STRING + NUM_TEAMS)
+#define CS_VOTE_NO (CS_VOTE_YES + NUM_TEAMS)
#define CS_GAME_VERSION 20
#define CS_LEVEL_START_TIME 21 // so the timer only shows the current level
@@ -296,8 +291,6 @@ typedef enum
#define EF_MOVER_STOP 0x00001000 // will push otherwise
#define EF_POISONCLOUDED 0x00002000 // player hit with basilisk gas
#define EF_CONNECTION 0x00004000 // draw a connection trouble sprite
-#define EF_VOTED 0x00008000 // already cast a vote
-#define EF_TEAMVOTED 0x00010000 // already cast a vote
#define EF_BLOBLOCKED 0x00020000 // caught by a trapper
#define EF_WARN_CHARGE 0x00040000 // Lucifer Cannon is about to overcharge
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 5eb5d3d1..236bc708 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -1812,7 +1812,7 @@ SpectatorClientEndFrame
void SpectatorClientEndFrame( gentity_t *ent )
{
gclient_t *cl;
- int clientNum, flags;
+ int clientNum;
int score, ping;
// if we are doing a chase cam or a remote view, grab the latest info
@@ -1824,9 +1824,6 @@ void SpectatorClientEndFrame( gentity_t *ent )
cl = &level.clients[ clientNum ];
if( cl->pers.connected == CON_CONNECTED )
{
- // Save
- flags = ( cl->ps.eFlags & ~( EF_VOTED | EF_TEAMVOTED ) ) |
- ( ent->client->ps.eFlags & ( EF_VOTED | EF_TEAMVOTED ) );
score = ent->client->ps.persistant[ PERS_SCORE ];
ping = ent->client->ps.ping;
@@ -1834,7 +1831,6 @@ void SpectatorClientEndFrame( gentity_t *ent )
ent->client->ps = cl->ps;
// Restore
- ent->client->ps.eFlags = flags;
ent->client->ps.persistant[ PERS_SCORE ] = score;
ent->client->ps.ping = ping;
diff --git a/src/game/g_admin.c b/src/game/g_admin.c
index 167c134a..dc41e700 100644
--- a/src/game/g_admin.c
+++ b/src/game/g_admin.c
@@ -2669,33 +2669,18 @@ qboolean G_admin_endvote( gentity_t *ent, int skiparg )
msg = va( "print \"^3!%s: ^7%s^7 decided that everyone voted %s\n\"",
cmd, ( ent ) ? ent->client->pers.netname : "console",
cancel ? "No" : "Yes" );
- if( team == TEAM_NONE )
+ if( !level.voteTime[ team ] )
{
- if( !level.voteTime )
- {
- ADMP( va( "^3!%s: ^7no vote in progress\n", cmd ) );
- return qfalse;
- }
- level.voteNo = cancel ? MAX_CLIENTS : 0;
- level.voteYes = cancel ? 0 : MAX_CLIENTS;
- CheckVote();
- AP( msg );
+ ADMP( va( "^3!%s: ^7no vote in progress\n", cmd ) );
+ return qfalse;
}
+ level.voteNo[ team ] = cancel ? level.numVotingClients[ team ] : 0;
+ level.voteYes[ team ] = cancel ? 0 : level.numVotingClients[ team ];
+ CheckVote( team );
+ if( team == TEAM_NONE )
+ AP( msg );
else
- {
- int offset = 0;
- if( team == TEAM_ALIENS )
- offset++;
- if( !level.teamVoteTime[ offset ] )
- {
- ADMP( va( "^3!%s: ^7no vote in progress\n", cmd ) );
- return qfalse;
- }
- level.teamVoteNo[ offset ] = cancel ? MAX_CLIENTS : 0;
- level.teamVoteYes[ offset ] = cancel ? 0 : MAX_CLIENTS;
- CheckTeamVote( team );
G_TeamCommand( team, msg );
- }
return qtrue;
}
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 3fb7296f..25edb023 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -346,7 +346,7 @@ Get the number of build points from a position
*/
int G_GetBuildPoints( const vec3_t pos, team_t team, int extraDistance )
{
- if( level.suddenDeath )
+ if( G_TimeTilSuddenDeath( ) <= 0 )
{
return 0;
}
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 78440563..8fe6ae96 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1436,8 +1436,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
}
// toggle the teleport bit so the client knows to not lerp
- flags = ent->client->ps.eFlags & ( EF_TELEPORT_BIT | EF_VOTED | EF_TEAMVOTED );
- flags ^= EF_TELEPORT_BIT;
+ flags = ( ent->client->ps.eFlags & EF_TELEPORT_BIT ) ^ EF_TELEPORT_BIT;
G_UnlaggedClear( ent );
// clear everything but the persistant data
@@ -1689,7 +1688,7 @@ void ClientDisconnect( int clientNum )
G_admin_namelog_update( ent->client, qtrue );
G_LeaveTeam( ent );
- G_Vote( ent, qfalse );
+ G_Vote( ent, TEAM_NONE, qfalse );
// stop any following clients
for( i = 0; i < level.maxclients; i++ )
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 6d9fc217..9cda473e 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -998,487 +998,267 @@ Cmd_CallVote_f
*/
void Cmd_CallVote_f( gentity_t *ent )
{
- int i;
- char arg1[ MAX_STRING_TOKENS ];
- char arg2[ MAX_NAME_LENGTH ];
- int clientNum = -1;
- char name[ MAX_NAME_LENGTH ];
+ char cmd[ MAX_TOKEN_CHARS ],
+ vote[ MAX_TOKEN_CHARS ],
+ arg[ MAX_TOKEN_CHARS ];
+ char name[ MAX_NAME_LENGTH ] = "";
+ int clientNum = -1;
+ team_t team;
+
+ trap_Argv( 0, cmd, sizeof( cmd ) );
+ trap_Argv( 1, vote, sizeof( vote ) );
+ trap_Argv( 2, arg, sizeof( arg ) );
+
+ if( !Q_stricmp( cmd, "callteamvote" ) )
+ team = ent->client->pers.teamSelection;
+ else
+ team = TEAM_NONE;
if( !g_allowVote.integer )
{
- trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here\n\"" );
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: voting not allowed here\n\"", cmd ) );
return;
}
- if( level.voteTime )
+ if( level.voteTime[ team ] )
{
- trap_SendServerCommand( ent-g_entities, "print \"A vote is already in progress\n\"" );
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: a vote is already in progress\n\"", cmd ) );
return;
}
+ level.voteThreshold[ team ] = 50;
+
if( g_voteLimit.integer > 0 &&
ent->client->pers.voteCount >= g_voteLimit.integer &&
!G_admin_permission( ent, ADMF_NO_VOTE_LIMIT ) )
{
trap_SendServerCommand( ent-g_entities, va(
- "print \"You have already called the maximum number of votes (%d)\n\"",
- g_voteLimit.integer ) );
- return;
- }
-
- // make sure it is a valid command to vote on
- trap_Argv( 1, arg1, sizeof( arg1 ) );
- trap_Argv( 2, arg2, sizeof( arg2 ) );
-
- if( strchr( arg1, ';' ) || strchr( arg2, ';' ) )
- {
- trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string\n\"" );
+ "print \"%s: you have already called the maximum number of votes (%d)\n\"",
+ cmd, g_voteLimit.integer ) );
return;
}
- // if there is still a vote to be executed
- if( level.voteExecuteTime )
+ trap_Argv( 1, vote, sizeof( vote ) );
+ // kick, mute, unmute, denybuild, allowbuild
+ if( !Q_stricmp( vote, "kick" ) ||
+ !Q_stricmp( vote, "mute" ) || !Q_stricmp( vote, "unmute" ) ||
+ !Q_stricmp( vote, "denybuild" ) || !Q_stricmp( vote, "allowbuild" ) )
{
- level.voteExecuteTime = 0;
- trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.voteString ) );
- }
+ int clientNums[ MAX_CLIENTS ];
+ int matches;
+ char err[ MAX_STRING_CHARS ];
- level.votePassThreshold = 50;
-
- // detect clientNum for partial name match votes
- if( !Q_stricmp( arg1, "kick" ) ||
- !Q_stricmp( arg1, "mute" ) ||
- !Q_stricmp( arg1, "unmute" ) )
- {
- int clientNums[ MAX_CLIENTS ];
- int matches = 0;
- char err[ MAX_STRING_CHARS ] = "";
-
- if( !arg2[ 0 ] )
+ if( !arg[ 0 ] )
{
trap_SendServerCommand( ent-g_entities,
- "print \"callvote: no target\n\"" );
+ va( "print \"%s: no target\n\"", cmd ) );
return;
}
- matches = G_ClientNumbersFromString( arg2, clientNums, MAX_CLIENTS );
+ // with a little extra work only players from the right team are considered
+ matches = G_ClientNumbersFromString( arg, clientNums, MAX_CLIENTS );
if( matches == 1 )
- {
- // there was only one partial name match
clientNum = clientNums[ 0 ];
- }
else
- {
- // look for an exact name match (sets clientNum to -1 if it fails)
- clientNum = G_ClientNumberFromString( arg2 );
- }
+ clientNum = G_ClientNumberFromString( arg );
if( clientNum != -1 )
{
- Q_strncpyz( name, level.clients[ clientNum ].pers.netname,
- sizeof( name ) );
- Q_CleanStr( name );
+ G_SanitiseString( level.clients[ clientNum ].pers.netname, name, sizeof( name ) );
}
else if( matches > 1 )
{
G_MatchOnePlayer( clientNums, matches, err, sizeof( err ) );
- ADMP( va( "^3callvote: ^7%s\n", err ) );
+ ADMP( va( "%s: %s\n", cmd, err ) );
return;
}
else
{
trap_SendServerCommand( ent-g_entities,
- "print \"callvote: invalid player\n\"" );
+ va( "print \"%s: invalid player\n\"", cmd ) );
return;
}
- }
- if( !Q_stricmp( arg1, "kick" ) )
- {
- if( G_admin_permission( &g_entities[ clientNum ], ADMF_IMMUNITY ) )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"callvote: admin is immune from vote kick\n\"" );
- return;
- }
- if( level.clients[ clientNum ].pers.localClient )
+ if( !Q_stricmp( vote, "kick" ) || !Q_stricmp( vote, "mute" ) ||
+ !Q_stricmp( vote, "denybuild" ) )
{
- trap_SendServerCommand( ent-g_entities,
- "print \"callvote: host is immune from vote kick\n\"" );
- return;
+ if( G_admin_permission( g_entities + clientNum, ADMF_IMMUNITY ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: admin is immune\n\"", cmd ) );
+ return;
+ }
}
-
- // use ip in case this player disconnects before the vote ends
- Com_sprintf( level.voteString, sizeof( level.voteString ),
- "!ban %s \"1s%s\" vote kick", level.clients[ clientNum ].pers.ip,
- g_adminTempBan.string );
- Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
- "Kick player \'%s\'", name );
}
- else if( !Q_stricmp( arg1, "mute" ) )
- {
- if( level.clients[ clientNum ].pers.muted )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"callvote: player is already muted\n\"" );
- return;
- }
- if( G_admin_permission( &g_entities[ clientNum ], ADMF_IMMUNITY ) )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"callvote: admin is immune from vote mute\n\"" );
- return;
- }
- Com_sprintf( level.voteString, sizeof( level.voteString ),
- "!mute %i", clientNum );
- Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
- "Mute player \'%s\'", name );
- }
- else if( !Q_stricmp( arg1, "unmute" ) )
+ if( !Q_stricmp( vote, "kick" ) )
{
- if( !level.clients[ clientNum ].pers.muted )
+ if( level.clients[ clientNum ].pers.localClient )
{
trap_SendServerCommand( ent-g_entities,
- "print \"callvote: player is not currently muted\n\"" );
- return;
- }
- Com_sprintf( level.voteString, sizeof( level.voteString ),
- "!unmute %i", clientNum );
- Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
- "Un-Mute player \'%s\'", name );
- }
- else if( !Q_stricmp( arg1, "map_restart" ) )
- {
- Com_sprintf( level.voteString, sizeof( level.voteString ), "%s", arg1 );
- Com_sprintf( level.voteDisplayString,
- sizeof( level.voteDisplayString ), "Restart current map" );
- }
- else if( !Q_stricmp( arg1, "map" ) )
- {
- if( !G_MapExists( arg2 ) )
- {
- trap_SendServerCommand( ent - g_entities, va( "print \"callvote: "
- "'maps/%s.bsp' could not be found on the server\n\"", arg2 ) );
+ va( "print \"%s: admin is immune\n\"", cmd ) );
return;
}
- Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 );
- Com_sprintf( level.voteDisplayString,
- sizeof( level.voteDisplayString ), "Change to map '%s'", arg2 );
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
+ "ban %s \"1s%s\" vote kick", level.clients[ clientNum ].pers.ip,
+ g_adminTempBan.string );
+ Com_sprintf( level.voteDisplayString[ team ],
+ sizeof( level.voteDisplayString[ team ] ),
+ "Kick player '%s'", name );
}
- else if( !Q_stricmp( arg1, "nextmap" ) )
+ else if( team == TEAM_NONE )
{
- if( G_MapExists( g_nextMap.string ) )
+ if( !Q_stricmp( vote, "mute" ) )
{
- trap_SendServerCommand( ent - g_entities, va( "print \"callvote: "
- "the next map is already set to '%s^7'\n\"", g_nextMap.string ) );
- return;
- }
+ if( level.clients[ clientNum ].pers.muted )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: player is already muted\n\"", cmd ) );
+ return;
+ }
- if( !G_MapExists( arg2 ) )
- {
- trap_SendServerCommand( ent - g_entities, va( "print \"callvote: "
- "'maps/%s^7.bsp' could not be found on the server\n\"", arg2 ) );
- return;
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
+ "mute %d", clientNum );
+ Com_sprintf( level.voteDisplayString[ team ],
+ sizeof( level.voteDisplayString[ team ] ),
+ "Mute player '%s'", name );
}
-
- Com_sprintf( level.voteString, sizeof( level.voteString ),
- "set g_nextMap %s", arg2 );
-
- Com_sprintf( level.voteDisplayString,
- sizeof( level.voteDisplayString ), "Set the next map to '%s^7'", arg2 );
- }
- else if( !Q_stricmp( arg1, "draw" ) )
- {
- Com_sprintf( level.voteString, sizeof( level.voteString ), "evacuation" );
- Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
- "End match in a draw" );
- }
- else if( !Q_stricmp( arg1, "sudden_death" ) ||
- !Q_stricmp( arg1, "suddendeath" ) )
- {
- if(!g_suddenDeathVotePercent.integer)
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"Sudden Death votes have been disabled\n\"" );
- return;
- }
- else if( g_suddenDeath.integer )
+ else if( !Q_stricmp( vote, "unmute" ) )
{
- trap_SendServerCommand( ent - g_entities,
- va( "print \"callvote: Sudden Death has already begun\n\"") );
- return;
+ if( !level.clients[ clientNum ].pers.muted )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: player is not currently muted\n\"", cmd ) );
+ return;
+ }
+
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
+ "unmute %d", clientNum );
+ Com_sprintf( level.voteDisplayString[ team ],
+ sizeof( level.voteDisplayString[ team ] ),
+ "Unmute player '%s'", name );
}
- else if( G_TimeTilSuddenDeath() <= g_suddenDeathVoteDelay.integer * 1000 )
+ else if( !Q_stricmp( vote, "map_restart" ) )
{
- trap_SendServerCommand( ent - g_entities,
- va( "print \"callvote: Sudden Death is already immenent\n\"") );
- return;
+ strcpy( level.voteString[ team ], vote );
+ strcpy( level.voteDisplayString[ team ], "Restart current map" );
}
- else
+ else if( !Q_stricmp( vote, "map" ) )
{
- level.votePassThreshold = g_suddenDeathVotePercent.integer;
- Com_sprintf( level.voteString, sizeof( level.voteString ), "suddendeath" );
- Com_sprintf( level.voteDisplayString,
- sizeof( level.voteDisplayString ), "Begin sudden death" );
-
- if( g_suddenDeathVoteDelay.integer )
- Q_strcat( level.voteDisplayString, sizeof( level.voteDisplayString ),
- va( " in %d seconds", g_suddenDeathVoteDelay.integer ) );
+ if( !G_MapExists( arg ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: 'maps/%s.bsp' could not be found on the server\n\"",
+ cmd, arg ) );
+ return;
+ }
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString ),
+ "%s \"%s\"", vote, arg );
+ Com_sprintf( level.voteDisplayString[ team ],
+ sizeof( level.voteDisplayString[ team ] ),
+ "Change to map '%s'", arg );
}
- }
- else
- {
- trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string\n\"" );
- trap_SendServerCommand( ent-g_entities, "print \"Valid vote commands are: "
- "map, nextmap, map_restart, sudden_death, draw, kick, mute and unmute\n" );
- return;
- }
-
- if( level.votePassThreshold != 50 )
- {
- Q_strcat( level.voteDisplayString, sizeof( level.voteDisplayString ),
- va( " (Needs > %d percent)", level.votePassThreshold ) );
- }
-
- trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE
- " called a vote: %s^7\n\"", ent->client->pers.netname,
- level.voteDisplayString ) );
-
- G_LogPrintf( "CallVote: %d \"%s" S_COLOR_WHITE "\": %s\n",
- ent - g_entities, ent->client->pers.netname, level.voteString );
-
- ent->client->pers.voteCount++;
-
- // start the voting, the caller autoamtically votes yes
- level.voteTime = level.time;
- level.voteYes = 1;
- level.voteNo = 0;
- ent->client->pers.vote = qtrue;
-
- for( i = 0; i < level.maxclients; i++ )
- level.clients[i].ps.eFlags &= ~EF_VOTED;
-
- ent->client->ps.eFlags |= EF_VOTED;
-
- trap_SetConfigstring( CS_VOTE_TIME, va( "%i", level.voteTime ) );
- trap_SetConfigstring( CS_VOTE_STRING, level.voteDisplayString );
- trap_SetConfigstring( CS_VOTE_YES, "1" );
- trap_SetConfigstring( CS_VOTE_NO, "0" );
-}
-
-/*
-==================
-Cmd_Vote_f
-==================
-*/
-void Cmd_Vote_f( gentity_t *ent )
-{
- char msg[ 64 ];
-
- if( !level.voteTime )
- {
- trap_SendServerCommand( ent-g_entities, "print \"No vote in progress\n\"" );
- return;
- }
-
- if( ent->client->ps.eFlags & EF_VOTED )
- {
- trap_SendServerCommand( ent-g_entities, "print \"Vote already cast\n\"" );
- return;
- }
-
- trap_SendServerCommand( ent-g_entities, "print \"Vote cast\n\"" );
-
- trap_Argv( 1, msg, sizeof( msg ) );
- ent->client->pers.vote = ( tolower( msg[ 0 ] ) == 'y' || msg[ 0 ] == '1' );
- G_Vote( ent, qtrue );
-
- // a majority will be determined in CheckVote, which will also account
- // for players entering or leaving
-}
-
-/*
-==================
-Cmd_CallTeamVote_f
-==================
-*/
-void Cmd_CallTeamVote_f( gentity_t *ent )
-{
- int i, team, cs_offset = 0;
- char arg1[ MAX_STRING_TOKENS ];
- char arg2[ MAX_NAME_LENGTH ];
- int clientNum = -1;
- char name[ MAX_NAME_LENGTH ];
-
- team = ent->client->pers.teamSelection;
-
- if( team == TEAM_ALIENS )
- cs_offset = 1;
-
- if( !g_allowVote.integer )
- {
- trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here\n\"" );
- return;
- }
-
- if( level.teamVoteTime[ cs_offset ] )
- {
- trap_SendServerCommand( ent-g_entities, "print \"A team vote is already in progress\n\"" );
- return;
- }
-
- if( g_voteLimit.integer > 0 &&
- ent->client->pers.voteCount >= g_voteLimit.integer &&
- !G_admin_permission( ent, ADMF_NO_VOTE_LIMIT ) )
- {
- trap_SendServerCommand( ent-g_entities, va(
- "print \"You have already called the maximum number of votes (%d)\n\"",
- g_voteLimit.integer ) );
- return;
- }
-
- // make sure it is a valid command to vote on
- trap_Argv( 1, arg1, sizeof( arg1 ) );
- trap_Argv( 2, arg2, sizeof( arg2 ) );
-
- if( strchr( arg1, ';' ) || strchr( arg2, ';' ) )
- {
- trap_SendServerCommand( ent-g_entities, "print \"Invalid team vote string\n\"" );
- return;
- }
-
- // detect clientNum for partial name match votes
- if( !Q_stricmp( arg1, "kick" ) ||
- !Q_stricmp( arg1, "denybuild" ) ||
- !Q_stricmp( arg1, "allowbuild" ) )
- {
- int clientNums[ MAX_CLIENTS ];
- int matches = 0;
- char err[ MAX_STRING_CHARS ] = "";
-
- if( !arg2[ 0 ] )
+ else if( !Q_stricmp( vote, "nextmap" ) )
{
- trap_SendServerCommand( ent-g_entities,
- "print \"callteamvote: no target\n\"" );
- return;
- }
+ if( G_MapExists( g_nextMap.string ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: the next map is already set to '%s'\n\"",
+ cmd, g_nextMap.string ) );
+ return;
+ }
- matches = G_ClientNumbersFromString( arg2, clientNums, MAX_CLIENTS ) ;
- if( matches == 1 )
- {
- // there was only one partial name match
- clientNum = clientNums[ 0 ];
- }
- else
- {
- // look for an exact name match (sets clientNum to -1 if it fails)
- clientNum = G_ClientNumberFromString( arg2 );
- }
+ if( !G_MapExists( arg ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: 'maps/%s.bsp' could not be found on the server\n\"",
+ cmd, arg ) );
+ return;
+ }
- // make sure this player is on the same team
- if( clientNum != -1 && level.clients[ clientNum ].pers.teamSelection !=
- team )
- {
- clientNum = -1;
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
+ "set g_nextMap \"%s\"", arg );
+ Com_sprintf( level.voteDisplayString[ team ],
+ sizeof( level.voteDisplayString[ team ] ),
+ "Set the next map go '%s'", arg );
}
-
- if( clientNum != -1 )
+ else if( !Q_stricmp( vote, "draw" ) )
{
- Q_strncpyz( name, level.clients[ clientNum ].pers.netname,
- sizeof( name ) );
- Q_CleanStr( name );
+ strcpy( level.voteString[ team ], "evacuation" );
+ strcpy( level.voteDisplayString[ team ], "End match in a draw" );
}
- else if( matches > 1 )
+ else if( !Q_stricmp( vote, "sudden_death" ) )
{
- G_MatchOnePlayer( clientNums, matches, err, sizeof( err ) );
- ADMP( va( "^3callteamvote: ^7%s\n", err ) );
- return;
+ if(!g_suddenDeathVotePercent.integer)
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"Sudden Death votes have been disabled\n\"" );
+ return;
+ }
+ if( G_TimeTilSuddenDeath( ) <= 0 )
+ {
+ trap_SendServerCommand( ent - g_entities,
+ va( "print \"callvote: Sudden Death has already begun\n\"") );
+ return;
+ }
+ if( G_TimeTilSuddenDeath() <= g_suddenDeathVoteDelay.integer * 1000 )
+ {
+ trap_SendServerCommand( ent - g_entities,
+ va( "print \"callvote: Sudden Death is already immenent\n\"") );
+ return;
+ }
+ level.voteThreshold[ team ] = g_suddenDeathVotePercent.integer;
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
+ "suddendeath %d", g_suddenDeathVoteDelay.integer );
+ strcpy( level.voteDisplayString[ team ], "Begin sudden death" );
}
else
{
- trap_SendServerCommand( ent-g_entities,
- "print \"callteamvote: invalid player\n\"" );
+ trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string\n\"" );
+ trap_SendServerCommand( ent-g_entities, "print \"Valid vote commands are: "
+ "map, nextmap, map_restart, draw, kick, mute and unmute\n" );
return;
}
}
-
- if( !Q_stricmp( arg1, "kick" ) )
- {
- if( G_admin_permission( &g_entities[ clientNum ], ADMF_IMMUNITY ) )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"callteamvote: admin is immune from vote kick\n\"" );
- return;
- }
- if( level.clients[ clientNum ].pers.localClient )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"callteamvote: host is immune from vote kick\n\"" );
- return;
- }
-
- // use ip in case this player disconnects before the vote ends
- Com_sprintf( level.teamVoteString[ cs_offset ],
- sizeof( level.teamVoteString[ cs_offset ] ),
- "!ban %s \"1s%s\" team vote kick", level.clients[ clientNum ].pers.ip,
- g_adminTempBan.string );
- Com_sprintf( level.teamVoteDisplayString[ cs_offset ],
- sizeof( level.teamVoteDisplayString[ cs_offset ] ),
- "Kick player '%s'", name );
- }
- else if( !Q_stricmp( arg1, "denybuild" ) )
+ else if( !Q_stricmp( vote, "denybuild" ) )
{
if( level.clients[ clientNum ].pers.denyBuild )
{
trap_SendServerCommand( ent-g_entities,
- "print \"callteamvote: player already lost building rights\n\"" );
- return;
- }
-
- if( G_admin_permission( &g_entities[ clientNum ], ADMF_IMMUNITY ) )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"callteamvote: admin is immune from denybuild\n\"" );
+ va( "print \"%s: player already lost building rights\n\"", cmd ) );
return;
}
- Com_sprintf( level.teamVoteString[ cs_offset ],
- sizeof( level.teamVoteString[ cs_offset ] ), "!denybuild %i", clientNum );
- Com_sprintf( level.teamVoteDisplayString[ cs_offset ],
- sizeof( level.teamVoteDisplayString[ cs_offset ] ),
- "Take away building rights from '%s'", name );
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
+ "denybuild %d", clientNum );
+ Com_sprintf( level.voteDisplayString[ team ],
+ sizeof( level.voteDisplayString[ team ] ),
+ "Take away building rights from '%s'", name );
}
- else if( !Q_stricmp( arg1, "allowbuild" ) )
+ else if( !Q_stricmp( vote, "allowbuild" ) )
{
if( !level.clients[ clientNum ].pers.denyBuild )
{
trap_SendServerCommand( ent-g_entities,
- "print \"callteamvote: player already has building rights\n\"" );
+ va( "print \"%s: player already has building rights\n\"", cmd ) );
return;
}
- Com_sprintf( level.teamVoteString[ cs_offset ],
- sizeof( level.teamVoteString[ cs_offset ] ), "!allowbuild %i", clientNum );
- Com_sprintf( level.teamVoteDisplayString[ cs_offset ],
- sizeof( level.teamVoteDisplayString[ cs_offset ] ),
- "Allow '%s' to build", name );
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
+ "allowbuild %d", clientNum );
+ Com_sprintf( level.voteDisplayString[ team ],
+ sizeof( level.voteDisplayString[ team ] ),
+ "Allow '%s' to build", name );
}
- else if( !Q_stricmp( arg1, "admitdefeat" ) )
+ else if( !Q_stricmp( vote, "admitdefeat" ) )
{
- if( team == level.surrenderTeam )
- {
- trap_SendServerCommand( ent-g_entities, "print \"You have already surrendered\n\"");
- return;
- }
-
- Com_sprintf( level.teamVoteString[ cs_offset ],
- sizeof( level.teamVoteString[ cs_offset ] ), "admitdefeat %i", team );
- Com_sprintf( level.teamVoteDisplayString[ cs_offset ],
- sizeof( level.teamVoteDisplayString[ cs_offset ] ),
- "Admit Defeat" );
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
+ "admitdefeat %d", team );
+ strcpy( level.voteDisplayString[ team ], "Admit Defeat" );
}
else
{
@@ -1488,71 +1268,70 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
"kick, denybuild, allowbuild and admitdefeat\n\"" );
return;
}
- ent->client->pers.voteCount++;
-
- G_TeamCommand( team, va( "print \"%s " S_COLOR_WHITE "called a team vote: %s\n\"",
- ent->client->pers.netname, level.teamVoteDisplayString[ cs_offset ] ) );
- G_LogPrintf( "CallTeamVote: %d \"%s" S_COLOR_WHITE "\": %s\n",
- ent - g_entities, ent->client->pers.netname,
- level.teamVoteDisplayString[ cs_offset ] );
+ G_LogPrintf( "%s: %d \"%s" S_COLOR_WHITE "\": %s\n",
+ team == TEAM_NONE ? "CallVote" : "CallTeamVote",
+ ent - g_entities, ent->client->pers.netname, level.voteString[ team ] );
- // start the voting, the caller autoamtically votes yes
- level.teamVoteTime[ cs_offset ] = level.time;
- level.teamVoteYes[ cs_offset ] = 1;
- level.teamVoteNo[ cs_offset ] = 0;
- ent->client->pers.teamVote = qtrue;
-
- for( i = 0; i < level.maxclients; i++ )
+ if( team == TEAM_NONE )
{
- if( level.clients[ i ].ps.stats[ STAT_TEAM ] == team )
- level.clients[ i ].ps.eFlags &= ~EF_TEAMVOTED;
+ trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE
+ " called a vote: %s\n\"", ent->client->pers.netname,
+ level.voteDisplayString[ team ] ) );
+ }
+ else
+ {
+ G_TeamCommand( team, va( "print \"%s" S_COLOR_WHITE
+ " called a team vote: %s\n\"", ent->client->pers.netname,
+ level.voteDisplayString[ team ] ) );
}
- ent->client->ps.eFlags |= EF_TEAMVOTED;
+ level.voteTime[ team ] = level.time;
+ trap_SetConfigstring( CS_VOTE_TIME + team,
+ va( "%d", level.voteTime[ team ] ) );
+ trap_SetConfigstring( CS_VOTE_STRING + team,
+ level.voteDisplayString[ team ] );
- trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset,
- va( "%i", level.teamVoteTime[ cs_offset ] ) );
- trap_SetConfigstring( CS_TEAMVOTE_STRING + cs_offset,
- level.teamVoteDisplayString[ cs_offset ] );
- trap_SetConfigstring( CS_TEAMVOTE_YES + cs_offset, "1" );
- trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset, "0" );
+ ent->client->pers.voteCount++;
+ ent->client->pers.vote[ team ] = qtrue;
+ G_Vote( ent, team, qtrue );
}
-
/*
==================
-Cmd_TeamVote_f
+Cmd_Vote_f
==================
*/
-void Cmd_TeamVote_f( gentity_t *ent )
+void Cmd_Vote_f( gentity_t *ent )
{
- int cs_offset = 0;
- char msg[ 64 ];
+ char cmd[ MAX_TOKEN_CHARS ], vote[ MAX_TOKEN_CHARS ];
+ team_t team = ent->client->pers.teamSelection;
- if( ent->client->pers.teamSelection == TEAM_ALIENS )
- cs_offset = 1;
+ trap_Argv( 0, cmd, sizeof( cmd ) );
+ if( Q_stricmp( cmd, "teamvote" ) )
+ team = TEAM_NONE;
- if( !level.teamVoteTime[ cs_offset ] )
+ if( !level.voteTime[ team ] )
{
- trap_SendServerCommand( ent-g_entities, "print \"No team vote in progress\n\"" );
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: no vote in progress\n\"", cmd ) );
return;
}
- if( ent->client->ps.eFlags & EF_TEAMVOTED )
+ if( ent->client->pers.voted[ team ] )
{
- trap_SendServerCommand( ent-g_entities, "print \"Team vote already cast\n\"" );
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: vote already cast\n\"", cmd ) );
return;
}
- trap_SendServerCommand( ent-g_entities, "print \"Team vote cast\n\"" );
-
- trap_Argv( 1, msg, sizeof( msg ) );
- ent->client->pers.teamVote = ( tolower( msg[ 0 ] ) == 'y' || msg[ 0 ] == '1' );
- G_TeamVote( ent, qtrue );
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: vote cast\n\"", cmd ) );
- // a majority will be determined in CheckTeamVote, which will also account
- // for players entering or leaving
+ trap_Argv( 1, vote, sizeof( vote ) );
+ ent->client->pers.vote[ team ] =
+ ( tolower( vote[ 0 ] ) == 'y' || vote[ 0 ] == '1' );
+ G_Vote( ent, team, qtrue );
}
@@ -3100,7 +2879,7 @@ commands_t cmds[ ] = {
// communication commands
{ "callvote", CMD_MESSAGE, Cmd_CallVote_f },
- { "callteamvote", CMD_MESSAGE|CMD_TEAM, Cmd_CallTeamVote_f },
+ { "callteamvote", CMD_MESSAGE|CMD_TEAM, Cmd_CallVote_f },
{ "say_area", CMD_MESSAGE|CMD_TEAM, Cmd_SayArea_f },
// can be used even during intermission
{ "say", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f },
@@ -3134,7 +2913,7 @@ commands_t cmds[ ] = {
{ "follownext", CMD_SPEC, Cmd_FollowCycle_f },
{ "followprev", CMD_SPEC, Cmd_FollowCycle_f },
- { "teamvote", CMD_TEAM, Cmd_TeamVote_f },
+ { "teamvote", CMD_TEAM, Cmd_Vote_f },
{ "class", CMD_TEAM, Cmd_Class_f },
{ "kill", CMD_TEAM|CMD_LIVING, Cmd_Kill_f },
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 48451f12..afafe587 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -324,9 +324,8 @@ typedef struct
// used to save persistant[] values while in SPECTATOR_FOLLOW mode
int credit;
- // votes
- qboolean vote;
- qboolean teamVote;
+ qboolean voted[ NUM_TEAMS ];
+ qboolean vote[ NUM_TEAMS ];
// flood protection
int floodDemerits;
@@ -542,22 +541,14 @@ typedef struct
int warmupModificationCount; // for detecting if g_warmup is changed
// voting state
- char voteString[MAX_STRING_CHARS];
- char voteDisplayString[MAX_STRING_CHARS];
- int voteTime; // level.time vote was called
- int votePassThreshold; // need at least this percent to pass
- int voteExecuteTime; // time the vote is executed
- int voteYes;
- int voteNo;
- int numVotingClients; // set by CalculateRanks
-
- // team voting state
- char teamVoteString[ 2 ][ MAX_STRING_CHARS ];
- char teamVoteDisplayString[ 2 ][ MAX_STRING_CHARS ];
- int teamVoteTime[ 2 ]; // level.time vote was called
- int teamVoteYes[ 2 ];
- int teamVoteNo[ 2 ];
- int numteamVotingClients[ 2 ]; // set by CalculateRanks
+ int voteThreshold[ NUM_TEAMS ]; // need at least this percent to pass
+ char voteString[ NUM_TEAMS ][ MAX_STRING_CHARS ];
+ char voteDisplayString[ NUM_TEAMS ][ MAX_STRING_CHARS ];
+ int voteTime[ NUM_TEAMS ]; // level.time vote was called
+ int voteExecuteTime[ NUM_TEAMS ]; // time the vote is executed
+ int voteYes[ NUM_TEAMS ];
+ int voteNo[ NUM_TEAMS ];
+ int numVotingClients[ NUM_TEAMS ];// set by CalculateRanks
// spawn variables
qboolean spawning; // the G_Spawn*() functions are valid
@@ -617,7 +608,6 @@ typedef struct
team_t lastWin;
- qboolean suddenDeath;
int suddenDeathBeginTime;
timeWarning_t suddenDeathWarning;
timeWarning_t timelimitWarning;
@@ -966,10 +956,8 @@ void QDECL G_LogPrintf( const char *fmt, ... );
void SendScoreboardMessageToAllClients( void );
void QDECL G_Printf( const char *fmt, ... );
void QDECL G_Error( const char *fmt, ... );
-void G_Vote( gentity_t *ent, qboolean voting );
-void G_TeamVote( gentity_t *ent, qboolean voting );
-void CheckVote( void );
-void CheckTeamVote( team_t teamnum );
+void G_Vote( gentity_t *ent, team_t team, qboolean voting );
+void CheckVote( team_t teamnum );
void LogExit( const char *string );
int G_TimeTilSuddenDeath( void );
@@ -1056,7 +1044,6 @@ extern vmCvar_t g_maxNameChanges;
extern vmCvar_t g_timelimit;
extern vmCvar_t g_suddenDeathTime;
-extern vmCvar_t g_suddenDeath;
extern vmCvar_t g_friendlyFire;
extern vmCvar_t g_friendlyBuildableFire;
extern vmCvar_t g_dretchPunt;
diff --git a/src/game/g_main.c b/src/game/g_main.c
index da521eb3..0343353e 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -41,7 +41,6 @@ gclient_t g_clients[ MAX_CLIENTS ];
vmCvar_t g_fraglimit;
vmCvar_t g_timelimit;
vmCvar_t g_suddenDeathTime;
-vmCvar_t g_suddenDeath;
vmCvar_t g_capturelimit;
vmCvar_t g_friendlyFire;
vmCvar_t g_friendlyBuildableFire;
@@ -164,7 +163,6 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_timelimit, "timelimit", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
{ &g_suddenDeathTime, "g_suddenDeathTime", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
- { &g_suddenDeath, "g_suddenDeath", "0", CVAR_SERVERINFO | CVAR_NORESTART, 0, qtrue },
{ &g_synchronousClients, "g_synchronousClients", "0", CVAR_SYSTEMINFO, 0, qfalse },
@@ -634,7 +632,6 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
trap_Cvar_Set( "g_humanStage", va( "%d", S1 ) );
trap_Cvar_Set( "g_alienCredits", 0 );
trap_Cvar_Set( "g_humanCredits", 0 );
- trap_Cvar_Set( "g_suddenDeath", 0 );
level.suddenDeathBeginTime = g_suddenDeathTime.integer * 60000;
G_Printf( "-----------------------------------\n" );
@@ -654,15 +651,13 @@ remove all currently active votes
*/
static void G_ClearVotes( void )
{
- level.voteTime = 0;
- trap_SetConfigstring( CS_VOTE_TIME, "" );
- trap_SetConfigstring( CS_VOTE_STRING, "" );
- level.teamVoteTime[ 0 ] = 0;
- trap_SetConfigstring( CS_TEAMVOTE_TIME, "" );
- trap_SetConfigstring( CS_TEAMVOTE_STRING, "" );
- level.teamVoteTime[ 1 ] = 0;
- trap_SetConfigstring( CS_TEAMVOTE_TIME + 1, "" );
- trap_SetConfigstring( CS_TEAMVOTE_STRING + 1, "" );
+ int i;
+ memset( level.voteTime, 0, sizeof( level.voteTime ) );
+ for( i = 0; i < NUM_TEAMS; i++ )
+ {
+ trap_SetConfigstring( CS_VOTE_TIME + i, "" );
+ trap_SetConfigstring( CS_VOTE_STRING + i, "" );
+ }
}
/*
@@ -1053,11 +1048,12 @@ void G_CountSpawns( void )
G_TimeTilSuddenDeath
============
*/
+#define SUDDENDEATHWARNING 60000
int G_TimeTilSuddenDeath( void )
{
if( ( !g_suddenDeathTime.integer && level.suddenDeathBeginTime==0 ) ||
( level.suddenDeathBeginTime < 0 ) )
- return 1; // Always some time away
+ return SUDDENDEATHWARNING + 1; // Always some time away
return ( ( level.suddenDeathBeginTime ) - ( level.time - level.startTime ) );
}
@@ -1098,54 +1094,18 @@ void G_CalculateBuildPoints( void )
}
// Sudden Death checks
-
- // Note: g_suddenDeath sets what is going on and level.suddenDeath
- // trails it to run stuff here. They're only inconsistent for as long
- // as it takes this function to run once and update
-
- // reset if SD was on, but now it's off
- if( !g_suddenDeath.integer && level.suddenDeath )
+ if( G_TimeTilSuddenDeath( ) <= 0 && level.suddenDeathWarning < TW_PASSED )
{
- level.suddenDeath = qfalse;
- level.suddenDeathWarning = 0;
- level.suddenDeathBeginTime = -1;
- if( ( level.time - level.startTime ) < ( g_suddenDeathTime.integer * 60000 ) )
- level.suddenDeathBeginTime = g_suddenDeathTime.integer * 60000;
- else
- level.suddenDeathBeginTime = -1;
+ G_LogPrintf( "Beginning Sudden Death\n" );
+ trap_SendServerCommand( -1, "cp \"Sudden Death!\"" );
+ level.suddenDeathWarning = TW_PASSED;
}
-
- // SD checks and warnings
- if( !level.suddenDeath )
+ else if( G_TimeTilSuddenDeath( ) <= SUDDENDEATHWARNING &&
+ level.suddenDeathWarning < TW_IMMINENT )
{
- // check conditions to enter sudden death
- if( !level.warmupTime &&
- ( g_suddenDeath.integer || G_TimeTilSuddenDeath( ) <= 0 ) )
- {
- // begin sudden death
- if( level.suddenDeathWarning < TW_PASSED )
- {
- G_LogPrintf( "Beginning Sudden Death\n" );
- trap_SendServerCommand( -1, "cp \"Sudden Death!\"" );
-
- level.suddenDeathBeginTime = level.time;
- level.suddenDeath=qtrue;
- trap_Cvar_Set( "g_suddenDeath", "1" );
-
- level.suddenDeathWarning = TW_PASSED;
- }
- }
- else
- {
- // warn about sudden death
- if( G_TimeTilSuddenDeath( ) <= 60000 &&
- level.suddenDeathWarning < TW_IMMINENT )
- {
- trap_SendServerCommand( -1, va( "cp \"Sudden Death in %d seconds!\"",
- (int)(G_TimeTilSuddenDeath() / 1000 ) ) );
- level.suddenDeathWarning = TW_IMMINENT;
- }
- }
+ trap_SendServerCommand( -1, va( "cp \"Sudden Death in %d seconds!\"",
+ (int)(G_TimeTilSuddenDeath() / 1000 ) ) );
+ level.suddenDeathWarning = TW_IMMINENT;
}
level.humanBuildPoints = g_humanBuildPoints.integer - level.humanBuildPointQueue;
@@ -1221,7 +1181,7 @@ void G_CalculateBuildPoints( void )
{
zone = &level.buildPointZones[ ent->buildPointZone ];
- if( !level.suddenDeath )
+ if( G_TimeTilSuddenDeath( ) > 0 )
{
// BP queue updates
while( zone->queuedBuildPoints > 0 &&
@@ -1412,7 +1372,7 @@ void CalculateRanks( void )
level.numConnectedClients = 0;
level.numPlayingClients = 0;
- level.numVotingClients = 0; // don't count bots
+ memset( level.numVotingClients, 0, sizeof( level.numVotingClients ) );
level.numAlienClients = 0;
level.numHumanClients = 0;
level.numLiveAlienClients = 0;
@@ -1430,7 +1390,7 @@ void CalculateRanks( void )
if( level.clients[ i ].pers.connected != CON_CONNECTED )
continue;
- level.numVotingClients++;
+ level.numVotingClients[ TEAM_NONE ]++;
if( level.clients[ i ].pers.teamSelection != TEAM_NONE )
{
level.numPlayingClients++;
@@ -1451,8 +1411,8 @@ void CalculateRanks( void )
}
level.numNonSpectatorClients = level.numLiveAlienClients +
level.numLiveHumanClients;
- level.numteamVotingClients[ 0 ] = level.numHumanClients;
- level.numteamVotingClients[ 1 ] = level.numAlienClients;
+ level.numVotingClients[ TEAM_ALIENS ] = level.numAlienClients;
+ level.numVotingClients[ TEAM_HUMANS ] = level.numHumanClients;
P[ i ] = '\0';
trap_Cvar_Set( "P", P );
@@ -2063,91 +2023,34 @@ void CheckExitRules( void )
G_Vote
==================
*/
-void G_Vote( gentity_t *ent, qboolean voting )
+void G_Vote( gentity_t *ent, team_t team, qboolean voting )
{
- if( !level.voteTime )
+ if( !level.voteTime[ team ] )
return;
- if( voting )
- {
- if( ent->client->ps.eFlags & EF_VOTED )
- return;
- ent->client->ps.eFlags |= EF_VOTED;
- }
- else
- {
- if( !( ent->client->ps.eFlags & EF_VOTED ) )
- return;
- ent->client->ps.eFlags &= ~EF_VOTED;
- }
-
- if( ent->client->pers.vote )
- {
- if( voting )
- level.voteYes++;
- else
- level.voteYes--;
- trap_SetConfigstring( CS_VOTE_YES, va( "%d", level.voteYes ) );
- }
- else
- {
- if( voting )
- level.voteNo++;
- else
- level.voteNo--;
- trap_SetConfigstring( CS_VOTE_NO, va( "%d", level.voteNo ) );
- }
-}
-
-/*
-==================
-G_TeamVote
-==================
-*/
-void G_TeamVote( gentity_t *ent, qboolean voting )
-{
- int cs_offset;
-
- if( ent->client->pers.teamSelection == TEAM_HUMANS )
- cs_offset = 0;
- else if( ent->client->pers.teamSelection == TEAM_ALIENS )
- cs_offset = 1;
- else
+ if( voting && ent->client->pers.voted[ team ] )
return;
-
- if( !level.teamVoteTime[ cs_offset ] )
+ if( !voting && !ent->client->pers.voted[ team ] )
return;
+ ent->client->pers.voted[ team ] = voting;
- if( voting )
- {
- if( ent->client->ps.eFlags & EF_TEAMVOTED )
- return;
- ent->client->ps.eFlags |= EF_TEAMVOTED;
- }
- else
- {
- if( !( ent->client->ps.eFlags & EF_TEAMVOTED ) )
- return;
- ent->client->ps.eFlags &= ~EF_TEAMVOTED;
- }
-
- if( ent->client->pers.teamVote )
+ if( ent->client->pers.vote[ team ] )
{
if( voting )
- level.teamVoteYes[ cs_offset ]++;
+ level.voteYes[ team ]++;
else
- level.teamVoteYes[ cs_offset ]--;
- trap_SetConfigstring( CS_TEAMVOTE_YES + cs_offset,
- va( "%d", level.teamVoteYes[ cs_offset ] ) );
+ level.voteYes[ team ]--;
+ trap_SetConfigstring( CS_VOTE_YES + team,
+ va( "%d", level.voteYes[ team ] ) );
}
else
{
if( voting )
- level.teamVoteNo[ cs_offset ]++;
+ level.voteNo[ team ]++;
else
- level.teamVoteNo[ cs_offset ]--;
- trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset,
- va( "%d", level.teamVoteNo[ cs_offset ] ) );
+ level.voteNo[ team ]--;
+ trap_SetConfigstring( CS_VOTE_NO + team,
+ va( "%d", level.voteNo[ team ] ) );
}
}
@@ -2166,138 +2069,72 @@ FUNCTIONS CALLED EVERY FRAME
CheckVote
==================
*/
-void CheckVote( void )
+void CheckVote( team_t team )
{
- int votePassThreshold = level.votePassThreshold;
- int voteYesPercent;
+ float votePassThreshold = (float)level.voteThreshold[ team ] / 100.0f;
+ qboolean pass = qfalse;
+ char *msg;
+ int i;
- if( level.voteExecuteTime && level.voteExecuteTime < level.time )
+ if( level.voteExecuteTime[ team ] &&
+ level.voteExecuteTime[ team ] < level.time )
{
- level.voteExecuteTime = 0;
+ level.voteExecuteTime[ team ] = 0;
- trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.voteString ) );
- if( !Q_stricmp( level.voteString, "map_restart" ) ||
- !Q_stricmpn( level.voteString, "map", 3 ) )
+ trap_SendConsoleCommand( EXEC_APPEND,
+ va( "%s\n", level.voteString[ team ] ) );
+ if( !Q_stricmp( level.voteString[ team ], "map_restart" ) ||
+ !Q_stricmpn( level.voteString[ team ], "map", 3 ) )
{
level.restarted = qtrue;
}
-
- if( !Q_stricmp( level.voteString, "suddendeath" ) )
- {
- level.suddenDeathBeginTime = level.time +
- ( 1000 * g_suddenDeathVoteDelay.integer ) - level.startTime;
- level.voteString[0] = '\0';
-
- if( g_suddenDeathVoteDelay.integer )
- trap_SendServerCommand( -1, va("cp \"Sudden Death will begin in %d seconds\n\"", g_suddenDeathVoteDelay.integer ) );
- }
}
- if( !level.voteTime )
+ if( !level.voteTime[ team ] )
return;
-
- if( level.voteYes + level.voteNo > 0 )
- voteYesPercent = (int)( 100 * ( level.voteYes ) / ( level.voteYes + level.voteNo ) );
- else
- voteYesPercent = 0;
- if( ( level.time - level.voteTime >= VOTE_TIME ) ||
- ( level.voteYes + level.voteNo == level.numConnectedClients ) )
+ if( ( level.time - level.voteTime[ team ] >= VOTE_TIME ) ||
+ ( level.voteYes[ team ] + level.voteNo[ team ] == level.numVotingClients[ team ] ) )
{
- if( voteYesPercent> votePassThreshold || level.voteNo == 0 )
- {
- // execute the command, then remove the vote
- trap_SendServerCommand( -1, va("print \"Vote passed (%d - %d)\n\"",
- level.voteYes, level.voteNo ) );
- G_LogPrintf( "Vote: Vote passed (%d-%d)\n", level.voteYes, level.voteNo );
- level.voteExecuteTime = level.time + 3000;
- }
- else
- {
- // same behavior as a timeout
- trap_SendServerCommand( -1, va("print \"Vote failed (%d - %d)\n\"",
- level.voteYes, level.voteNo ) );
- G_LogPrintf( "Vote: Vote failed (%d - %d)\n", level.voteYes, level.voteNo );
- }
+ pass = (float)level.voteYes[ team ] / 100.0f > votePassThreshold ||
+ level.voteNo[ team ] == 0;
}
else
{
- if( level.voteYes > (int)( (double) level.numConnectedClients *
- ( (double) votePassThreshold/100.0 ) ) )
+ if( (float)level.voteYes[ team ] / 100.0f >
+ (float)level.numVotingClients[ team ] * votePassThreshold )
{
- // execute the command, then remove the vote
- trap_SendServerCommand( -1, va("print \"Vote passed (%d - %d)\n\"",
- level.voteYes, level.voteNo ) );
- G_LogPrintf( "Vote: Vote passed (%d - %d)\n", level.voteYes, level.voteNo );
- level.voteExecuteTime = level.time + 3000;
+ pass = qtrue;
}
- else if( level.voteNo > (int)( (double) level.numConnectedClients *
- ( (double) ( 100.0-votePassThreshold )/ 100.0 ) ) )
+ else if( (float)level.voteNo[ team ] <=
+ (float)level.numVotingClients[ team ] * 1.0f - votePassThreshold )
{
- // same behavior as a timeout
- trap_SendServerCommand( -1, va("print \"Vote failed (%d - %d)\n\"",
- level.voteYes, level.voteNo ) );
- G_LogPrintf("Vote failed\n");
- }
- else
- {
- // still waiting for a majority
return;
}
}
- level.voteTime = 0;
- trap_SetConfigstring( CS_VOTE_TIME, "" );
- trap_SetConfigstring( CS_VOTE_STRING, "" );
-}
-
+ if( pass )
+ level.voteExecuteTime[ team ] = level.time + 3000;
-/*
-==================
-CheckTeamVote
-==================
-*/
-void CheckTeamVote( team_t team )
-{
- int cs_offset;
-
- if ( team == TEAM_HUMANS )
- cs_offset = 0;
- else if ( team == TEAM_ALIENS )
- cs_offset = 1;
+ msg = va( "print \"%sote %sed (%d - %d)\n\"",
+ team == TEAM_NONE ? "V" : "Team v", pass ? "pass" : "fail",
+ level.voteYes[ team ], level.voteNo[ team ] );
+ if( team == TEAM_NONE )
+ trap_SendServerCommand( -1, msg );
else
- return;
+ G_TeamCommand( team, msg );
- if( !level.teamVoteTime[ cs_offset ] )
- return;
+ level.voteTime[ team ] = 0;
+ level.voteYes[ team ] = 0;
+ level.voteNo[ team ] = 0;
- if( level.time - level.teamVoteTime[ cs_offset ] >= VOTE_TIME )
- {
- G_TeamCommand( team, "print \"Team vote failed\n\"" );
- }
- else
- {
- if( level.teamVoteYes[ cs_offset ] > level.numteamVotingClients[ cs_offset ] / 2 )
- {
- // execute the command, then remove the vote
- G_TeamCommand( team, "print \"Team vote passed\n\"" );
- trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.teamVoteString[ cs_offset ] ) );
- }
- else if( level.teamVoteNo[ cs_offset ] >= level.numteamVotingClients[ cs_offset ] / 2 )
- {
- // same behavior as a timeout
- G_TeamCommand( team, "print \"Team vote failed\n\"" );
- }
- else
- {
- // still waiting for a majority
- return;
- }
- }
+ for( i = 0; i < level.maxclients; i++ )
+ level.clients[ i ].pers.voted[ team ] = qfalse;
- level.teamVoteTime[ cs_offset ] = 0;
- trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, "" );
- trap_SetConfigstring( CS_TEAMVOTE_STRING + cs_offset, "" );
+ trap_SetConfigstring( CS_VOTE_TIME + team, "" );
+ trap_SetConfigstring( CS_VOTE_STRING + team, "" );
+ trap_SetConfigstring( CS_VOTE_YES + team, "0" );
+ trap_SetConfigstring( CS_VOTE_NO + team, "0" );
}
@@ -2555,11 +2392,9 @@ void G_RunFrame( int levelTime )
CheckTeamStatus( );
// cancel vote if timed out
- CheckVote( );
-
- // check team votes
- CheckTeamVote( TEAM_HUMANS );
- CheckTeamVote( TEAM_ALIENS );
+ CheckVote( TEAM_NONE );
+ CheckVote( TEAM_ALIENS );
+ CheckVote( TEAM_HUMANS );
level.frameMsec = trap_Milliseconds();
}
diff --git a/src/game/g_svcmds.c b/src/game/g_svcmds.c
index c81ffca1..75d757d1 100644
--- a/src/game/g_svcmds.c
+++ b/src/game/g_svcmds.c
@@ -509,6 +509,19 @@ static void Svcmd_MessageWrapper( void )
G_Say( NULL, SAY_ALL, ConcatArgs( 1 ) );
}
+static void Svcmd_SuddenDeath_f( void )
+{
+ char secs[ 5 ];
+ int offset;
+ trap_Argv( 0, secs, sizeof( secs ) );
+ offset = atoi( secs );
+
+ level.suddenDeathBeginTime = level.time - level.startTime + offset * 1000;
+ trap_SendServerCommand( -1,
+ va( "cp \"Sudden Death will begin in %d second%s\"",
+ offset, offset == 1 ? "" : "s" ) );
+}
+
struct
{
char *cmd;
@@ -536,7 +549,8 @@ struct
{ "say", qtrue, Svcmd_MessageWrapper },
{ "chat", qtrue, Svcmd_Chat_f },
{ "m", qtrue, Svcmd_MessageWrapper },
- { "a", qtrue, Svcmd_MessageWrapper }
+ { "a", qtrue, Svcmd_MessageWrapper },
+ { "suddendeath", qfalse, Svcmd_SuddenDeath_f }
};
/*
diff --git a/src/game/g_team.c b/src/game/g_team.c
index 96e7e39e..7384b4b1 100644
--- a/src/game/g_team.c
+++ b/src/game/g_team.c
@@ -103,7 +103,7 @@ void G_LeaveTeam( gentity_t *self )
// stop any following clients
G_StopFromFollowing( self );
- G_TeamVote( self, qfalse );
+ G_Vote( self, team, qfalse );
self->suicideTime = 0;
for( i = 0; i < level.num_entities; i++ )