summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cgame/cg_draw.c16
-rw-r--r--src/cgame/cg_drawtools.c30
-rw-r--r--src/cgame/cg_local.h1
-rw-r--r--src/cgame/cg_servercmds.c22
-rw-r--r--src/game/bg_misc.c81
-rw-r--r--src/game/bg_public.h19
-rw-r--r--src/game/g_active.c17
-rw-r--r--src/game/g_admin.c73
-rw-r--r--src/game/g_admin.h1
-rw-r--r--src/game/g_buildable.c20
-rw-r--r--src/game/g_client.c11
-rw-r--r--src/game/g_cmds.c453
-rw-r--r--src/game/g_local.h5
-rw-r--r--src/game/g_main.c23
-rw-r--r--src/game/g_session.c15
-rw-r--r--src/game/g_svcmds.c47
-rw-r--r--src/ui/ui_gameinfo.c29
-rw-r--r--src/ui/ui_local.h6
-rw-r--r--src/ui/ui_main.c165
-rw-r--r--src/ui/ui_shared.c23
20 files changed, 880 insertions, 177 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index 1a96e75f..89740c7c 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -3048,6 +3048,7 @@ static void CG_DrawVote( void )
char *s;
int sec;
vec4_t white = { 1.0f, 1.0f, 1.0f, 1.0f };
+ char yeskey[ 32 ], nokey[ 32 ];
if( !cgs.voteTime )
return;
@@ -3063,8 +3064,10 @@ static void CG_DrawVote( void )
if( sec < 0 )
sec = 0;
-
- s = va( "VOTE(%i): \"%s\" Yes:%i No:%i", sec, cgs.voteString, cgs.voteYes, cgs.voteNo );
+ 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 );
CG_Text_Paint( 8, 340, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
}
@@ -3078,6 +3081,7 @@ 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_PTEAM ] == PTE_HUMANS )
cs_offset = 0;
@@ -3101,8 +3105,12 @@ static void CG_DrawTeamVote( void )
if( sec < 0 )
sec = 0;
- s = va( "TEAMVOTE(%i): \"%s\" Yes:%i No:%i", sec, cgs.teamVoteString[ cs_offset ],
- cgs.teamVoteYes[cs_offset], cgs.teamVoteNo[ cs_offset ] );
+ 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 ] );
CG_Text_Paint( 8, 360, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
}
diff --git a/src/cgame/cg_drawtools.c b/src/cgame/cg_drawtools.c
index 3151f66f..06ae0713 100644
--- a/src/cgame/cg_drawtools.c
+++ b/src/cgame/cg_drawtools.c
@@ -346,3 +346,33 @@ qboolean CG_WorldToScreen( vec3_t point, float *x, float *y )
return qtrue;
}
+
+/*
+================
+CG_KeyBinding
+================
+*/
+char *CG_KeyBinding( const char *bind )
+{
+ static char key[ 32 ];
+ char bindbuff[ MAX_CVAR_VALUE_STRING ];
+ int i;
+
+ key[ 0 ] = '\0';
+ // NOTE: change K_LAST_KEY to MAX_KEYS for full key support (eventually)
+ for( i = 0; i < K_LAST_KEY; i++ )
+ {
+ trap_Key_GetBindingBuf( i, bindbuff, sizeof( bindbuff ) );
+ if( !Q_stricmp( bindbuff, bind ) )
+ {
+ trap_Key_KeynumToStringBuf( i, key, sizeof( key ) );
+ break;
+ }
+ }
+ if( !key[ 0 ] )
+ {
+ Q_strncpyz( key, "\\", sizeof( key ) );
+ Q_strcat( key, sizeof( key ), bind );
+ }
+ return key;
+}
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 5bebfaf0..1f0fa005 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -1595,6 +1595,7 @@ void CG_DrawRect( float x, float y, float width, float height, float size
void CG_DrawSides(float x, float y, float w, float h, float size);
void CG_DrawTopBottom(float x, float y, float w, float h, float size);
qboolean CG_WorldToScreen( vec3_t point, float *x, float *y );
+char *CG_KeyBinding( const char *bind );
//
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index 2665df16..6fcae7eb 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -377,8 +377,9 @@ static void CG_ConfigStringModified( void )
CG_NewClientInfo( num - CS_PLAYERS );
CG_BuildSpectatorString( );
}
- else if( num == CS_FLAGSTATUS )
+ else if( num == CS_WINNER )
{
+ trap_Cvar_Set( "ui_winner", str );
}
else if( num == CS_SHADERSTATE )
{
@@ -806,8 +807,9 @@ static void CG_ServerCommand( void )
{
if( !cg_teamChatsOnly.integer )
{
- trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
+ if( Q_stricmpn( text, "[skipnotify]", 12 ) )
+ trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
CG_RemoveChatEscapeChar( text );
CG_Printf( "%s\n", text );
}
@@ -817,14 +819,16 @@ static void CG_ServerCommand( void )
if( !strcmp( cmd, "tchat" ) )
{
- if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
- trap_S_StartLocalSound( cgs.media.alienTalkSound, CHAN_LOCAL_SOUND );
- else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
- trap_S_StartLocalSound( cgs.media.humanTalkSound, CHAN_LOCAL_SOUND );
- else
- trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
-
Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
+ if( Q_stricmpn( text, "[skipnotify]", 12 ) )
+ {
+ if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
+ trap_S_StartLocalSound( cgs.media.alienTalkSound, CHAN_LOCAL_SOUND );
+ else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
+ trap_S_StartLocalSound( cgs.media.humanTalkSound, CHAN_LOCAL_SOUND );
+ else
+ trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
+ }
CG_RemoveChatEscapeChar( text );
CG_Printf( "%s\n", text );
return;
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index fd8b87d7..fd79c380 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -5529,3 +5529,84 @@ qboolean BG_BuildableIsAllowed( buildable_t buildable )
return qtrue;
}
+
+/*
+============
+BG_ClientListTest
+============
+*/
+qboolean BG_ClientListTest( clientList_t *list, int clientNum )
+{
+ if( clientNum < 0 || clientNum >= MAX_CLIENTS || !list )
+ return qfalse;
+ if( clientNum < 32 )
+ return ( ( list->lo & ( 1 << clientNum ) ) != 0 );
+ else
+ return ( ( list->hi & ( 1 << ( clientNum - 32 ) ) ) != 0 );
+}
+
+/*
+============
+BG_ClientListAdd
+============
+*/
+void BG_ClientListAdd( clientList_t *list, int clientNum )
+{
+ if( clientNum < 0 || clientNum >= MAX_CLIENTS || !list )
+ return;
+ if( clientNum < 32 )
+ list->lo |= ( 1 << clientNum );
+ else
+ list->hi |= ( 1 << ( clientNum - 32 ) );
+}
+
+/*
+============
+BG_ClientListRemove
+============
+*/
+void BG_ClientListRemove( clientList_t *list, int clientNum )
+{
+ if( clientNum < 0 || clientNum >= MAX_CLIENTS || !list )
+ return;
+ if( clientNum < 32 )
+ list->lo &= ~( 1 << clientNum );
+ else
+ list->hi &= ~( 1 << ( clientNum - 32 ) );
+}
+
+/*
+============
+BG_ClientListString
+============
+*/
+char *BG_ClientListString( clientList_t *list )
+{
+ static char s[ 17 ];
+
+ s[ 0 ] = '\0';
+ if( !list )
+ return s;
+ Com_sprintf( s, sizeof( s ), "%08x%08x", list->hi, list->lo );
+ return s;
+}
+
+/*
+============
+BG_ClientListParse
+============
+*/
+void BG_ClientListParse( clientList_t *list, const char *s )
+{
+ if( !list )
+ return;
+ list->lo = 0;
+ list->hi = 0;
+ if( !s )
+ return;
+ if( strlen( s ) != 16 )
+ return;
+ sscanf( s, "%x%x", &list->hi, &list->lo );
+}
+
+
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 877b8b8c..722aca47 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -64,7 +64,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define CS_GAME_VERSION 20
#define CS_LEVEL_START_TIME 21 // so the timer only shows the current level
#define CS_INTERMISSION 22 // when 1, fraglimit/timelimit has been hit and intermission will start in a second or two
-#define CS_FLAGSTATUS 23 // string indicating flag status in CTF
+#define CS_WINNER 23 // string indicating round winner
#define CS_SHADERSTATE 24
#define CS_BOTINFO 25
#define CS_CLIENTS_READY 26 //TA: following suggestion in STAT_ enum STAT_CLIENTS_READY becomes a configstring
@@ -1294,3 +1294,20 @@ qboolean BG_UpgradeIsAllowed( upgrade_t upgrade );
qboolean BG_ClassIsAllowed( pClass_t class );
qboolean BG_BuildableIsAllowed( buildable_t buildable );
qboolean BG_UpgradeClassAvailable( playerState_t *ps );
+
+typedef struct
+{
+ unsigned int hi;
+ unsigned int lo;
+} clientList_t;
+qboolean BG_ClientListTest( clientList_t *list, int clientNum );
+void BG_ClientListAdd( clientList_t *list, int clientNum );
+void BG_ClientListRemove( clientList_t *list, int clientNum );
+char *BG_ClientListString( clientList_t *list );
+void BG_ClientListParse( clientList_t *list, const char *s );
+
+// Friendly Fire Flags
+#define FFF_HUMANS 1
+#define FFF_ALIENS 2
+#define FFF_BUILDABLES 4
+
diff --git a/src/game/g_active.c b/src/game/g_active.c
index d7776991..b3e8f2b9 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -762,7 +762,8 @@ void ClientTimerActions( gentity_t *ent, int msec )
}
//replenish alien health
- if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
+ if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS &&
+ level.surrenderTeam != PTE_ALIENS )
{
int entityList[ MAX_GENTITIES ];
vec3_t range = { LEVEL4_REGEN_RANGE, LEVEL4_REGEN_RANGE, LEVEL4_REGEN_RANGE };
@@ -801,6 +802,20 @@ void ClientTimerActions( gentity_t *ent, int msec )
if( ent->health > client->ps.stats[ STAT_MAX_HEALTH ] )
ent->health = client->ps.stats[ STAT_MAX_HEALTH ];
}
+
+ // turn off life support when a team admits defeat
+ if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS &&
+ level.surrenderTeam == PTE_ALIENS )
+ {
+ G_Damage( ent, NULL, NULL, NULL, NULL,
+ BG_FindRegenRateForClass( client->ps.stats[ STAT_PCLASS ] ),
+ DAMAGE_NO_ARMOR, MOD_SUICIDE );
+ }
+ else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS &&
+ level.surrenderTeam == PTE_HUMANS )
+ {
+ G_Damage( ent, NULL, NULL, NULL, NULL, 5, DAMAGE_NO_ARMOR, MOD_SUICIDE );
+ }
}
while( client->time10000 >= 10000 )
diff --git a/src/game/g_admin.c b/src/game/g_admin.c
index 8cf374d3..73fe3060 100644
--- a/src/game/g_admin.c
+++ b/src/game/g_admin.c
@@ -42,6 +42,11 @@ g_admin_cmd_t g_admin_cmds[ ] =
"display your current admin level",
""
},
+
+ {"allowbuild", G_admin_denybuild, "d",
+ "restore a player's ablity to build",
+ "[^3name|slot#^7]"
+ },
{"allready", G_admin_allready, "y",
"makes everyone ready in intermission",
@@ -60,6 +65,11 @@ g_admin_cmd_t g_admin_cmds[ ] =
""
},
+ {"denybuild", G_admin_denybuild, "d",
+ "take away a player's ablity to build",
+ "[^3name|slot#^7]"
+ },
+
{"help", G_admin_help, "h",
"display commands available to you or help on a specific command",
"(^5command^7)"
@@ -2042,6 +2052,68 @@ qboolean G_admin_mute( gentity_t *ent, int skiparg )
return qtrue;
}
+qboolean G_admin_denybuild( gentity_t *ent, int skiparg )
+{
+ int pids[ MAX_CLIENTS ];
+ char name[ MAX_NAME_LENGTH ], err[ MAX_STRING_CHARS ];
+ char command[ MAX_ADMIN_CMD_LEN ], *cmd;
+ gentity_t *vic;
+
+ G_SayArgv( skiparg, command, sizeof( command ) );
+ cmd = command;
+ if( cmd && *cmd == '!' )
+ cmd++;
+ if( G_SayArgc() < 2 + skiparg )
+ {
+ ADMP( va( "^3!%s: ^7usage: !%s [name|slot#]\n", cmd, cmd ) );
+ return qfalse;
+ }
+ G_SayArgv( 1 + skiparg, name, sizeof( name ) );
+ if( G_ClientNumbersFromString( name, pids ) != 1 )
+ {
+ G_MatchOnePlayer( pids, err, sizeof( err ) );
+ ADMP( va( "^3!%s: ^7%s\n", cmd, err ) );
+ return qfalse;
+ }
+ if( !admin_higher( ent, &g_entities[ pids[ 0 ] ] ) )
+ {
+ ADMP( va( "^3!%s: ^7sorry, but your intended victim has a higher admin"
+ " level than you\n", cmd ) );
+ return qfalse;
+ }
+ vic = &g_entities[ pids[ 0 ] ];
+ if( vic->client->pers.denyBuild )
+ {
+ if( !Q_stricmp( cmd, "denybuild" ) )
+ {
+ ADMP( "^3!denybuild: ^7player already has no building rights\n" );
+ return qtrue;
+ }
+ vic->client->pers.denyBuild = qfalse;
+ CPx( pids[ 0 ], "cp \"^1You've regained your building rights\"" );
+ AP( va(
+ "print \"^3!allowbuild: ^7building rights for ^7%s^7 restored by %s\n\"",
+ vic->client->pers.netname,
+ ( ent ) ? ent->client->pers.netname : "console" ) );
+ }
+ else
+ {
+ if( !Q_stricmp( cmd, "allowbuild" ) )
+ {
+ ADMP( "^3!allowbuild: ^7player already has building rights\n" );
+ return qtrue;
+ }
+ vic->client->pers.denyBuild = qtrue;
+ CPx( pids[ 0 ], "cp \"^1You've lost your building rights\"" );
+ AP( va(
+ "print \"^3!denybuild: ^7building rights for ^7%s^7 revoked by ^7%s\n\"",
+ vic->client->pers.netname,
+ ( ent ) ? ent->client->pers.netname : "console" ) );
+ }
+ ClientUserinfoChanged( pids[ 0 ] );
+ return qtrue;
+}
+
qboolean G_admin_listadmins( gentity_t *ent, int skiparg )
{
int i, found = 0;
@@ -2724,6 +2796,7 @@ qboolean G_admin_nextmap( gentity_t *ent, int skiparg )
AP( va( "print \"^3!nextmap: ^7%s^7 decided to load the next map\n\"",
( ent ) ? ent->client->pers.netname : "console" ) );
level.lastWin = PTE_NONE;
+ trap_SetConfigstring( CS_WINNER, "Evacuation" );
LogExit( va( "nextmap was run by %s",
( ent ) ? ent->client->pers.netname : "console" ) );
return qtrue;
diff --git a/src/game/g_admin.h b/src/game/g_admin.h
index 21e63fa1..c4bf3928 100644
--- a/src/game/g_admin.h
+++ b/src/game/g_admin.h
@@ -153,6 +153,7 @@ qboolean G_admin_listlayouts( gentity_t *ent, int skiparg );
qboolean G_admin_listplayers( gentity_t *ent, int skiparg );
qboolean G_admin_map( gentity_t *ent, int skiparg );
qboolean G_admin_mute( gentity_t *ent, int skiparg );
+qboolean G_admin_denybuild( gentity_t *ent, int skiparg );
qboolean G_admin_showbans( gentity_t *ent, int skiparg );
qboolean G_admin_help( gentity_t *ent, int skiparg );
qboolean G_admin_admintest( gentity_t *ent, int skiparg );
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 5aba0ece..aeac1be6 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -3691,3 +3691,23 @@ void G_LayoutLoad( void )
}
}
+void G_BaseSelfDestruct( pTeam_t team )
+{
+ int i;
+ gentity_t *ent;
+
+ for( i = MAX_CLIENTS; i < level.num_entities; i++ )
+ {
+ ent = &level.gentities[ i ];
+ if( ent->health <= 0 )
+ continue;
+ if( ent->s.eType != ET_BUILDABLE )
+ continue;
+ if( team == PTE_HUMANS && ent->biteam != BIT_HUMANS )
+ continue;
+ if( team == PTE_ALIENS && ent->biteam != BIT_ALIENS )
+ continue;
+ G_Damage( ent, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
+ }
+}
+
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 6184bad0..a2607cdf 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1141,10 +1141,12 @@ void ClientUserinfoChanged( int clientNum )
// print scoreboards, display models, and play custom sounds
Com_sprintf( userinfo, sizeof( userinfo ),
- "n\\%s\\t\\%i\\model\\%s\\hmodel\\%s"
- "\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d",
+ "n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\"
+ "hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\"
+ "tl\\%d\\ig\\%16s",
client->pers.netname, team, model, model, c1, c2,
- client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader );
+ client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask,
+ teamLeader, BG_ClientListString( &client->sess.ignoreList ) );
trap_SetConfigstring( CS_PLAYERS + clientNum, userinfo );
@@ -1663,6 +1665,9 @@ void ClientDisconnect( int clientNum )
// stop any following clients
for( i = 0; i < level.maxclients; i++ )
{
+ // remove any /ignore settings for this clientNum
+ BG_ClientListRemove( &level.clients[ i ].sess.ignoreList, clientNum );
+
if( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR &&
level.clients[ i ].sess.spectatorState == SPECTATOR_FOLLOW &&
level.clients[ i ].sess.spectatorClient == clientNum )
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index cc8e0a5e..4ffd1144 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -777,6 +777,8 @@ G_Say
*/
static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *name, const char *message )
{
+ qboolean ignore = qfalse;
+
if( !other )
return;
@@ -800,8 +802,12 @@ static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, cons
// specs with ADMF_SPEC_ALLCHAT flag can see team chat
}
- trap_SendServerCommand( other-g_entities, va( "%s \"%s%c%c%s\"",
+ if( BG_ClientListTest( &other->client->sess.ignoreList, ent-g_entities ) )
+ ignore = qtrue;
+
+ trap_SendServerCommand( other-g_entities, va( "%s \"%s%s%c%c%s\"",
mode == SAY_TEAM ? "tchat" : "chat",
+ ( ignore ) ? "[skipnotify]" : "",
name, Q_COLOR_ESCAPE, color, message ) );
}
@@ -994,6 +1000,8 @@ void Cmd_CallVote_f( gentity_t *ent )
int i;
char arg1[ MAX_STRING_TOKENS ];
char arg2[ MAX_STRING_TOKENS ];
+ int clientNum = -1;
+ char name[ MAX_NETNAME ];
if( !g_allowVote.integer )
{
@@ -1017,12 +1025,6 @@ void Cmd_CallVote_f( gentity_t *ent )
return;
}
- if( ent->client->pers.teamSelection == PTE_NONE )
- {
- trap_SendServerCommand( ent-g_entities, "print \"Not allowed to call a vote as spectator\n\"" );
- return;
- }
-
// make sure it is a valid command to vote on
trap_Argv( 1, arg1, sizeof( arg1 ) );
trap_Argv( 2, arg2, sizeof( arg2 ) );
@@ -1040,74 +1042,108 @@ void Cmd_CallVote_f( gentity_t *ent )
trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.voteString ) );
}
- if( !Q_stricmp( arg1, "kick" ) )
+ // detect clientNum for partial name match votes
+ if( !Q_stricmp( arg1, "kick" ) ||
+ !Q_stricmp( arg1, "mute" ) ||
+ !Q_stricmp( arg1, "unmute" ) )
{
- int clientNum;
int clientNums[ MAX_CLIENTS ] = { -1 };
if( G_ClientNumbersFromString( arg2, clientNums ) == 1 )
{
- // there was one partial name match name was clientNum
+ // there was only one partial name match
clientNum = clientNums[ 0 ];
}
else
{
- // look for an exact name match before bailing out
+ // look for an exact name match (sets clientNum to -1 if it fails)
clientNum = G_ClientNumberFromString( ent, arg2 );
- if( clientNum == -1 )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"callvote: invalid player\n\"" );
- return;
- }
}
- Q_strncpyz( arg1, "clientkick", sizeof( arg1 ) );
- Q_strncpyz( arg2, va( "%d", clientNum ), sizeof( arg2 ) );
- }
- if( !Q_stricmp( arg1, "clientkick" ) )
+ if( clientNum != -1 &&
+ level.clients[ clientNum ].pers.connected == CON_DISCONNECTED )
+ {
+ clientNum = -1;
+ }
+
+ if( clientNum != -1 )
+ {
+ Q_strncpyz( name, level.clients[ clientNum ].pers.netname,
+ sizeof( name ) );
+ Q_CleanStr( name );
+ }
+ }
+
+ if( !Q_stricmp( arg1, "kick" ) )
{
- char kickee[ MAX_NETNAME ];
- int clientNum = 0;
+ if( clientNum == -1 )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: invalid player\n\"" );
+ return;
+ }
- //check arg2 is a number
- for( i = 0; arg2[ i ]; i++ )
+ if( G_admin_permission( &g_entities[ clientNum ], ADMF_IMMUNITY ) )
{
- if( arg2[ i ] < '0' || arg2[ i ] > '9' )
- {
- clientNum = -1;
- break;
- }
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: admin is immune from vote kick\n\"" );
+ return;
}
- if( clientNum > -1 )
- clientNum = atoi( arg2 );
- if( clientNum >= 0 && clientNum < level.maxclients )
+ // use ip in case this player disconnects before the vote ends
+ Com_sprintf( level.voteString, sizeof( level.voteString ),
+ "!ban %s %d vote kick", level.clients[ clientNum ].pers.ip,
+ g_adminTempBan.integer + 1 );
+ Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
+ "Kick player \'%s\'", name );
+ }
+ else if( !Q_stricmp( arg1, "mute" ) )
+ {
+
+ if( clientNum == -1 )
{
- if( G_admin_permission( &g_entities[ clientNum ], ADMF_IMMUNITY ) )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"callvote: admin is immune from vote kick\n\"" );
- return;
- }
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: invalid player\n\"" );
+ return;
+ }
+
+ if( level.clients[ clientNum ].pers.muted )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: player is already muted\n\"" );
+ return;
+ }
- if( level.clients[ clientNum ].pers.connected != CON_DISCONNECTED )
- {
- Q_strncpyz( kickee, level.clients[ clientNum ].pers.netname,
- sizeof( kickee ) );
- Q_CleanStr( kickee );
- // use ip in case this player disconnects before the vote ends
- Com_sprintf( level.voteString, sizeof( level.voteString ),
- "!ban %s %d vote kick", level.clients[ clientNum ].pers.ip,
- g_adminTempBan.integer + 1 );
- Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
- "Kick player \'%s\'", kickee );
- }
- else
- 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;
}
- else
+ 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( clientNum == -1 )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: invalid player\n\"" );
+ return;
+ }
+ if( !level.clients[ clientNum ].pers.muted )
+ {
+ 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" ) )
{
@@ -1126,19 +1162,19 @@ void Cmd_CallVote_f( gentity_t *ent )
Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 );
Com_sprintf( level.voteDisplayString,
- sizeof( level.voteDisplayString ), "Change to map \'%s\'", arg2 );
+ sizeof( level.voteDisplayString ), "Change to map '%s'", arg2 );
}
- else if( !Q_stricmp( arg1, "nextmap" ) )
+ else if( !Q_stricmp( arg1, "draw" ) )
{
- Com_sprintf( level.voteString, sizeof( level.voteString ), "advanceMapRotation" );
+ Com_sprintf( level.voteString, sizeof( level.voteString ), "evacuation" );
Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
- "Skip to next map in rotation" );
+ "End match in a draw" );
}
else
{
trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string\n\"" );
- trap_SendServerCommand( ent-g_entities, "print \"Valid vote commands are: map_restart, nextmap, "
- "map <mapname>, kick <player>, clientkick <clientnum>\n\"" );
+ trap_SendServerCommand( ent-g_entities, "print \"Valid vote commands are: "
+ "map_restart, draw, kick, mute and unmute\n" );
return;
}
@@ -1184,12 +1220,6 @@ void Cmd_Vote_f( gentity_t *ent )
return;
}
- if( ent->client->pers.teamSelection == PTE_NONE )
- {
- trap_SendServerCommand( ent-g_entities, "print \"Not allowed to vote as spectator\n\"" );
- return;
- }
-
trap_SendServerCommand( ent-g_entities, "print \"Vote cast\n\"" );
ent->client->ps.eFlags |= EF_VOTED;
@@ -1221,6 +1251,15 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
int i, team, cs_offset;
char arg1[ MAX_STRING_TOKENS ];
char arg2[ MAX_STRING_TOKENS ];
+ int clientNum = -1;
+ char name[ MAX_NETNAME ];
+
+ if( ent->client->pers.teamSelection == PTE_NONE )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"Not allowed to call a team vote as a spectator\n\"" );
+ return;
+ }
team = ent->client->ps.stats[ STAT_PTEAM ];
@@ -1253,12 +1292,6 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
return;
}
- if( ent->client->pers.teamSelection == PTE_NONE )
- {
- trap_SendServerCommand( ent-g_entities, "print \"Not allowed to call a vote as spectator\n\"" );
- return;
- }
-
// make sure it is a valid command to vote on
trap_Argv( 1, arg1, sizeof( arg1 ) );
trap_Argv( 2, arg2, sizeof( arg2 ) );
@@ -1268,61 +1301,52 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
trap_SendServerCommand( ent-g_entities, "print \"Invalid team vote string\n\"" );
return;
}
-
- if( !Q_stricmp( arg1, "teamkick" ) )
+
+ // detect clientNum for partial name match votes
+ if( !Q_stricmp( arg1, "kick" ) ||
+ !Q_stricmp( arg1, "denybuild" ) ||
+ !Q_stricmp( arg1, "allowbuild" ) )
{
- int clientNum;
int clientNums[ MAX_CLIENTS ] = { -1 };
if( G_ClientNumbersFromString( arg2, clientNums ) == 1 )
{
- // there was one partial name match or name was clientNum
+ // there was only one partial name match
clientNum = clientNums[ 0 ];
}
else
{
- // look for an exact name match before bailing out
+ // look for an exact name match (sets clientNum to -1 if it fails)
clientNum = G_ClientNumberFromString( ent, arg2 );
- if( clientNum == -1 )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"callvote: invalid player\n\"" );
- return;
- }
}
- Q_strncpyz( arg1, "teamclientkick", sizeof( arg1 ) );
- Q_strncpyz( arg2, va( "%d", clientNum ), sizeof( arg2 ) );
- }
-
- if( !Q_stricmp( arg1, "teamclientkick" ) )
- {
- int clientNum = 0;
- char kickee[ MAX_NETNAME ];
- //check arg2 is a number
- for( i = 0; arg2[ i ]; i++ )
+ // make sure this player is on the same team
+ if( clientNum != -1 && level.clients[ clientNum ].pers.teamSelection !=
+ ent->client->pers.teamSelection )
{
- if( arg2[ i ] < '0' || arg2[ i ] > '9' )
- {
- clientNum = -1;
- break;
- }
+ clientNum = -1;
+ }
+
+ if( clientNum != -1 &&
+ level.clients[ clientNum ].pers.connected == CON_DISCONNECTED )
+ {
+ clientNum = -1;
}
- if( clientNum > -1 )
- clientNum = atoi( arg2 );
- if( clientNum >= 0 && clientNum < level.maxclients )
+ if( clientNum != -1 )
{
- if( level.clients[ clientNum ].pers.connected == CON_DISCONNECTED )
- clientNum = -1;
- else if( level.clients[ clientNum ].pers.teamSelection != team )
- clientNum = -1;
+ Q_strncpyz( name, level.clients[ clientNum ].pers.netname,
+ sizeof( name ) );
+ Q_CleanStr( name );
}
+ }
- if( clientNum < 0 )
+ if( !Q_stricmp( arg1, "kick" ) )
+ {
+ if( clientNum == -1 )
{
- trap_SendServerCommand( ent-g_entities, va( "print \"client %s "
- S_COLOR_WHITE "is not a valid player on your team\n\"", arg2 ) );
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: invalid player\n\"" );
return;
}
@@ -1333,9 +1357,6 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
return;
}
- Q_strncpyz( kickee, level.clients[ clientNum ].pers.netname,
- sizeof( kickee ) );
- Q_CleanStr( kickee );
// use ip in case this player disconnects before the vote ends
Com_sprintf( level.teamVoteString[ cs_offset ],
@@ -1344,13 +1365,73 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
g_adminTempBan.integer + 1 );
Com_sprintf( level.teamVoteDisplayString[ cs_offset ],
sizeof( level.teamVoteDisplayString[ cs_offset ] ),
- "Kick player \'%s\'", kickee );
+ "Kick player '%s'", name );
+ }
+ else if( !Q_stricmp( arg1, "denybuild" ) )
+ {
+ if( clientNum == -1 )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: invalid player\n\"" );
+ return;
+ }
+
+ if( level.clients[ clientNum ].pers.denyBuild )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: 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\"" );
+ 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 );
+ }
+ else if( !Q_stricmp( arg1, "allowbuild" ) )
+ {
+ if( clientNum == -1 )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: invalid player\n\"" );
+ return;
+ }
+
+ if( !level.clients[ clientNum ].pers.denyBuild )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"callvote: player already has building rights\n\"" );
+ 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 );
+ }
+ else if( !Q_stricmp( arg1, "admitdefeat" ) )
+ {
+ 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" );
}
else
{
trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string\n\"" );
- trap_SendServerCommand( ent-g_entities, "print \"Valid team vote commands are: teamkick <player>, "
- "teamclientkick <client>\n\"" );
+ trap_SendServerCommand( ent-g_entities,
+ "print \"Valid team vote commands are: "
+ "kick, denybuild, allowbuild and surrender\n\"" );
return;
}
ent->client->pers.voteCount++;
@@ -1714,6 +1795,13 @@ void Cmd_Destroy_f( gentity_t *ent, qboolean deconstruct )
trace_t tr;
gentity_t *traceEnt;
+ if( ent->client->pers.denyBuild )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"Your building rights have been revoked\n\"" );
+ return;
+ }
+
if( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING )
G_Damage( ent->client->hovel, ent, ent, forward, ent->s.origin, 10000, 0, MOD_SUICIDE );
@@ -2293,6 +2381,13 @@ void Cmd_Build_f( gentity_t *ent )
vec3_t origin;
pTeam_t team;
+ if( ent->client->pers.denyBuild )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"Your building rights have been revoked\n\"" );
+ return;
+ }
+
trap_Argv( 1, s, sizeof( s ) );
buildable = BG_FindBuildNumForName( s );
@@ -2670,6 +2765,70 @@ void Cmd_Test_f( gentity_t *ent )
ent->client->lastPoisonClient = ent;*/
}
+static void Cmd_Ignore_f( gentity_t *ent, qboolean ignore )
+{
+ int pids[ MAX_CLIENTS ];
+ char name[ MAX_NAME_LENGTH ];
+ const char *cmd;
+ int matches = 0;
+ int i;
+
+ cmd = ( ignore ) ? "ignore" : "unignore";
+
+ if( trap_Argc() < 2 )
+ {
+ trap_SendServerCommand( ent-g_entities, va( "print \"[skipnotify]"
+ "%s: usage \\%s [clientNum | partial name match]\n\"", cmd, cmd ) );
+ return;
+ }
+
+ Q_strncpyz( name, ConcatArgs( 1 ), sizeof( name ) );
+ matches = G_ClientNumbersFromString( name, pids );
+ if( matches < 1 )
+ {
+ trap_SendServerCommand( ent-g_entities, va( "print \"[skipnotify]"
+ "%s: no clients match the name '%s'\n\"", cmd, name ) );
+ return;
+ }
+
+ for( i = 0; i < matches; i++ )
+ {
+ if( ignore )
+ {
+ if( !BG_ClientListTest( &ent->client->sess.ignoreList, pids[ i ] ) )
+ {
+ BG_ClientListAdd( &ent->client->sess.ignoreList, pids[ i ] );
+ ClientUserinfoChanged( ent->client->ps.clientNum );
+ trap_SendServerCommand( ent-g_entities, va( "print \"[skipnotify]"
+ "ignore: added %s^7 to your ignore list\n\"",
+ level.clients[ pids[ i ] ].pers.netname ) );
+ }
+ else
+ {
+ trap_SendServerCommand( ent-g_entities, va( "print \"[skipnotify]"
+ "ignore: %s^7 is already on your ignore list\n\"",
+ level.clients[ pids[ i ] ].pers.netname ) );
+ }
+ }
+ else
+ {
+ if( BG_ClientListTest( &ent->client->sess.ignoreList, pids[ i ] ) )
+ {
+ BG_ClientListRemove( &ent->client->sess.ignoreList, pids[ i ] );
+ ClientUserinfoChanged( ent->client->ps.clientNum );
+ trap_SendServerCommand( ent-g_entities, va( "print \"[skipnotify]"
+ "unignore: removed %s^7 from your ignore list\n\"",
+ level.clients[ pids[ i ] ].pers.netname ) );
+ }
+ else
+ {
+ trap_SendServerCommand( ent-g_entities, va( "print \"[skipnotify]"
+ "unignore: %s^7 is not on your ignore list\n\"",
+ level.clients[ pids[ i ] ].pers.netname ) );
+ }
+ }
+ }
+}
/*
=================
@@ -2717,6 +2876,18 @@ void ClientCommand( int clientNum )
return;
}
+ if( !Q_stricmp( cmd, "ignore" ) )
+ {
+ Cmd_Ignore_f( ent, qtrue );
+ return;
+ }
+
+ if( !Q_stricmp( cmd, "unignore" ) )
+ {
+ Cmd_Ignore_f( ent, qfalse );
+ return;
+ }
+
if( G_admin_cmd_check( ent, qfalse ) )
return;
@@ -2906,12 +3077,13 @@ void G_DecolorString( char *in, char *out )
void G_PrivateMessage( gentity_t *ent )
{
int pids[ MAX_CLIENTS ];
+ int ignoreids[ MAX_CLIENTS ];
char name[ MAX_NAME_LENGTH ];
char cmd[ 12 ];
char str[ MAX_STRING_CHARS ];
char *msg;
char color;
- int pcount, count = 0;
+ int pcount, matches, ignored = 0;
int i;
int skipargs = 0;
qboolean teamonly = qfalse;
@@ -2941,27 +3113,40 @@ void G_PrivateMessage( gentity_t *ent )
if( ent )
{
- if( teamonly )
+ int count = 0;
+
+ for( i=0; i < pcount; i++ )
{
- for( i=0; i < pcount; i++ )
+ tmpent = &g_entities[ pids[ i ] ];
+
+ if( teamonly && !OnSameTeam( ent, tmpent ) )
+ continue;
+
+ if( BG_ClientListTest( &tmpent->client->sess.ignoreList,
+ ent-g_entities ) )
{
- if( !OnSameTeam( ent, &g_entities[ pids[ i ] ] ) )
- continue;
- pids[ count ] = pids[ i ];
- count++;
+ ignoreids[ ignored++ ] = pids[ i ];
+ continue;
}
- pcount = count;
+
+ pids[ count ] = pids[ i ];
+ count++;
}
+ matches = count;
+ }
+ else
+ {
+ matches = pcount;
}
color = teamonly ? COLOR_CYAN : COLOR_YELLOW;
Q_strncpyz( str,
- va( "^%csent to %i player%s: ^7", color, pcount,
- ( pcount == 1 ) ? "" : "s" ),
+ va( "^%csent to %i player%s: ^7", color, matches,
+ ( matches == 1 ) ? "" : "s" ),
sizeof( str ) );
- for( i=0; i < pcount; i++ )
+ for( i=0; i < matches; i++ )
{
tmpent = &g_entities[ pids[ i ] ];
@@ -2973,7 +3158,7 @@ void G_PrivateMessage( gentity_t *ent )
( ent ) ? ent->client->pers.netname : "console",
color,
name,
- pcount,
+ matches,
color,
msg,
ent ? ent-g_entities : -1 ) );
@@ -2988,7 +3173,7 @@ void G_PrivateMessage( gentity_t *ent )
( ent ) ? ent->client->pers.netname : "console" ) );
}
- if( !pcount )
+ if( !matches )
ADMP( va( "^3No player matching ^7\'%s^7\' ^3to send message to.\n",
name ) );
else
@@ -3001,5 +3186,19 @@ void G_PrivateMessage( gentity_t *ent )
( ent ) ? ent->client->pers.netname : "console",
name, msg );
}
+
+ if( ignored )
+ {
+ Q_strncpyz( str, va( "^%cignored by %i player%s: ^7", color, ignored,
+ ( ignored == 1 ) ? "" : "s" ), sizeof( str ) );
+ for( i=0; i < ignored; i++ )
+ {
+ tmpent = &g_entities[ ignoreids[ i ] ];
+ if( i > 0 )
+ Q_strcat( str, sizeof( str ), "^7, " );
+ Q_strcat( str, sizeof( str ), tmpent->client->pers.netname );
+ }
+ ADMP( va( "%s\n", str ) );
+ }
}
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 3b423dab..8536cc64 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -299,6 +299,7 @@ typedef struct
int spectatorClient; // for chasecam and follow mode
int wins, losses; // tournament stats
qboolean teamLeader; // true when this client is a team leader
+ clientList_t ignoreList;
} clientSession_t;
#define MAX_NETNAME 36
@@ -350,6 +351,7 @@ typedef struct
char guid[ 33 ];
char ip[ 16 ];
qboolean muted;
+ qboolean denyBuild;
int adminLevel;
} clientPersistant_t;
@@ -653,6 +655,8 @@ typedef struct
int unlaggedTimes[ MAX_UNLAGGED_MARKERS ];
char layout[ MAX_QPATH ];
+
+ pTeam_t surrenderTeam;
} level_locals_t;
//
@@ -741,6 +745,7 @@ void G_LayoutSave( char *name );
int G_LayoutList( const char *map, char *list, int len );
void G_LayoutSelect( void );
void G_LayoutLoad( void );
+void G_BaseSelfDestruct( pTeam_t team );
//
// g_utils.c
diff --git a/src/game/g_main.c b/src/game/g_main.c
index a1525a9a..4f4423d4 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -144,6 +144,7 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_restarted, "g_restarted", "0", CVAR_ROM, 0, qfalse },
{ NULL, "sv_mapname", "", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse },
{ NULL, "P", "", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse },
+ { NULL, "ff", "0", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse },
// latched vars
@@ -469,8 +470,12 @@ void G_UpdateCvars( void )
cv->modificationCount = cv->vmCvar->modificationCount;
if( cv->trackChange )
+ {
trap_SendServerCommand( -1, va( "print \"Server: %s changed to %s\n\"",
cv->cvarName, cv->vmCvar->string ) );
+ // update serverinfo in case this cvar is passed to clients indirectly
+ CalculateRanks( );
+ }
if( cv->teamShader )
remapped = qtrue;
@@ -595,6 +600,7 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
&level.clients[ 0 ].ps, sizeof( level.clients[ 0 ] ) );
trap_SetConfigstring( CS_INTERMISSION, "0" );
+ trap_SetConfigstring( CS_WINNER, "" );
// test to see if a custom buildable layout will be loaded
G_LayoutSelect( );
@@ -681,6 +687,7 @@ void G_ShutdownGame( int restart )
G_admin_namelog_cleanup( );
level.restarted = qfalse;
+ level.surrenderTeam = PTE_NONE;
}
@@ -1271,7 +1278,8 @@ void CalculateRanks( void )
int score;
int newScore;
gclient_t *cl;
- char P[ MAX_CLIENTS + 1 ] = {""};
+ char P[ MAX_CLIENTS + 1 ] = {""};
+ int ff = 0;
level.follow1 = -1;
level.follow2 = -1;
@@ -1342,6 +1350,16 @@ void CalculateRanks( void )
P[ i + 1 ] = '\0';
trap_Cvar_Set( "P", P );
+ if( g_friendlyFire.integer )
+ ff |= ( FFF_HUMANS | FFF_ALIENS );
+ if( g_friendlyFireHumans.integer )
+ ff |= FFF_HUMANS;
+ if( g_friendlyFireAliens.integer )
+ ff |= FFF_ALIENS;
+ if( g_friendlyBuildableFire.integer )
+ ff |= FFF_BUILDABLES;
+ trap_Cvar_Set( "ff", va( "%i", ff ) );
+
qsort( level.sortedClients, level.numConnectedClients,
sizeof( level.sortedClients[ 0 ] ), SortRanks );
@@ -1885,6 +1903,7 @@ void CheckExitRules( void )
{
level.lastWin = PTE_NONE;
trap_SendServerCommand( -1, "print \"Timelimit hit\n\"" );
+ trap_SetConfigstring( CS_WINNER, "Stalemate" );
LogExit( "Timelimit hit." );
return;
}
@@ -1910,6 +1929,7 @@ void CheckExitRules( void )
//humans win
level.lastWin = PTE_HUMANS;
trap_SendServerCommand( -1, "print \"Humans win\n\"");
+ trap_SetConfigstring( CS_WINNER, "Humans Win" );
LogExit( "Humans win." );
}
else if( level.uncondAlienWin ||
@@ -1920,6 +1940,7 @@ void CheckExitRules( void )
//aliens win
level.lastWin = PTE_ALIENS;
trap_SendServerCommand( -1, "print \"Aliens win\n\"");
+ trap_SetConfigstring( CS_WINNER, "Aliens Win" );
LogExit( "Aliens win." );
}
}
diff --git a/src/game/g_session.c b/src/game/g_session.c
index ad9addc1..81eed74f 100644
--- a/src/game/g_session.c
+++ b/src/game/g_session.c
@@ -46,14 +46,15 @@ void G_WriteClientSessionData( gclient_t *client )
const char *s;
const char *var;
- s = va( "%i %i %i %i %i %i %i",
+ s = va( "%i %i %i %i %i %i %i %s",
client->sess.sessionTeam,
client->sess.spectatorTime,
client->sess.spectatorState,
client->sess.spectatorClient,
client->sess.wins,
client->sess.losses,
- client->sess.teamLeader
+ client->sess.teamLeader,
+ BG_ClientListString( &client->sess.ignoreList )
);
var = va( "session%i", client - level.clients );
@@ -81,16 +82,19 @@ void G_ReadSessionData( gclient_t *client )
var = va( "session%i", client - level.clients );
trap_Cvar_VariableStringBuffer( var, s, sizeof(s) );
- sscanf( s, "%i %i %i %i %i %i %i",
+ // FIXME: should be using BG_ClientListParse() for ignoreList, but
+ // bg_lib.c's sscanf() currently lacks %s
+ sscanf( s, "%i %i %i %i %i %i %i %x%x",
&sessionTeam,
&client->sess.spectatorTime,
&spectatorState,
&client->sess.spectatorClient,
&client->sess.wins,
&client->sess.losses,
- &teamLeader
+ &teamLeader,
+ &client->sess.ignoreList.hi,
+ &client->sess.ignoreList.lo
);
-
// bk001205 - format issues
client->sess.sessionTeam = (team_t)sessionTeam;
client->sess.spectatorState = (spectatorState_t)spectatorState;
@@ -131,6 +135,7 @@ void G_InitSessionData( gclient_t *client, char *userinfo )
sess->spectatorState = SPECTATOR_FREE;
sess->spectatorTime = level.time;
sess->spectatorClient = -1;
+ memset( &sess->ignoreList, 0, sizeof( sess->ignoreList ) );
G_WriteClientSessionData( client );
}
diff --git a/src/game/g_svcmds.c b/src/game/g_svcmds.c
index df656446..e65015af 100644
--- a/src/game/g_svcmds.c
+++ b/src/game/g_svcmds.c
@@ -544,6 +544,38 @@ void Svcmd_LayoutLoad_f( void )
level.restarted = qtrue;
}
+static void Svcmd_AdmitDefeat_f( void )
+{
+ int team;
+ char teamNum[ 2 ];
+
+ if( trap_Argc( ) != 2 )
+ {
+ G_Printf("admitdefeat: must provide a team\n");
+ return;
+ }
+ trap_Argv( 1, teamNum, sizeof( teamNum ) );
+ team = atoi( teamNum );
+ if( team == PTE_ALIENS || teamNum[ 0 ] == 'a' )
+ {
+ level.surrenderTeam = PTE_ALIENS;
+ G_BaseSelfDestruct( PTE_ALIENS );
+ G_TeamCommand( PTE_ALIENS, "cp \"Hivemind Link Broken\" 1");
+ trap_SendServerCommand( -1, "print \"Alien team has admitted defeat\n\"" );
+ }
+ else if( team == PTE_HUMANS || teamNum[ 0 ] == 'h' )
+ {
+ level.surrenderTeam = PTE_HUMANS;
+ G_BaseSelfDestruct( PTE_HUMANS );
+ G_TeamCommand( PTE_HUMANS, "cp \"Life Support Terminated\" 1");
+ trap_SendServerCommand( -1, "print \"Human team has admitted defeat\n\"" );
+ }
+ else
+ {
+ G_Printf("admitdefeat: invalid team\n");
+ }
+}
+
/*
=================
ConsoleCommand
@@ -656,6 +688,21 @@ qboolean ConsoleCommand( void )
return qtrue;
}
+ if( !Q_stricmp( cmd, "admitdefeat" ) )
+ {
+ Svcmd_AdmitDefeat_f( );
+ return qtrue;
+ }
+
+ if( !Q_stricmp( cmd, "evacuation" ) )
+ {
+ trap_SendServerCommand( -1, "print \"Evacuation ordered\n\"" );
+ level.lastWin = PTE_NONE;
+ trap_SetConfigstring( CS_WINNER, "Evacuation" );
+ LogExit( "Evacuation." );
+ return qtrue;
+ }
+
// see if this is a a admin command
if( G_admin_cmd_check( NULL, qfalse ) )
return qtrue;
diff --git a/src/ui/ui_gameinfo.c b/src/ui/ui_gameinfo.c
index ab3ce6da..90047b9d 100644
--- a/src/ui/ui_gameinfo.c
+++ b/src/ui/ui_gameinfo.c
@@ -162,7 +162,7 @@ void UI_LoadArenas( void ) {
strcat(filename, dirptr);
UI_LoadArenasFromFile(filename);
}
- trap_Print( va( "%i arenas parsed\n", ui_numArenas ) );
+ trap_Print( va( "[skipnotify]%i arenas parsed\n", ui_numArenas ) );
if (UI_OutOfMemory()) {
trap_Print(S_COLOR_YELLOW"WARNING: not anough memory in pool to load all arenas\n");
}
@@ -305,3 +305,30 @@ char *UI_GetBotNameByNumber( int num ) {
}
return "Sarge";
}
+
+void UI_ServerInfo( void )
+{
+ char info[ MAX_INFO_VALUE ];
+ int i;
+
+ info[0] = '\0';
+ if( trap_GetConfigString( CS_SERVERINFO, info, sizeof( info ) ) )
+ {
+ trap_Cvar_Set( "ui_serverinfo_mapname",
+ Info_ValueForKey( info, "mapname" ) );
+ trap_Cvar_Set( "ui_serverinfo_timelimit",
+ Info_ValueForKey( info, "timelimit" ) );
+ trap_Cvar_Set( "ui_serverinfo_sd",
+ Info_ValueForKey( info, "g_suddenDeathTime" ) );
+ trap_Cvar_Set( "ui_serverinfo_hostname",
+ Info_ValueForKey( info, "sv_hostname" ) );
+ trap_Cvar_Set( "ui_serverinfo_maxclients",
+ Info_ValueForKey( info, "sv_maxclients" ) );
+ trap_Cvar_Set( "ui_serverinfo_version",
+ Info_ValueForKey( info, "version" ) );
+ trap_Cvar_Set( "ui_serverinfo_unlagged",
+ Info_ValueForKey( info, "g_unlagged" ) );
+ trap_Cvar_Set( "ui_serverinfo_ff",
+ Info_ValueForKey( info, "ff" ) );
+ }
+}
diff --git a/src/ui/ui_local.h b/src/ui/ui_local.h
index def61dc3..7afdf653 100644
--- a/src/ui/ui_local.h
+++ b/src/ui/ui_local.h
@@ -360,6 +360,7 @@ int UI_AdjustTimeByGame(int time);
void UI_ShowPostGame(qboolean newHigh);
void UI_ClearScores( void );
void UI_LoadArenas(void);
+void UI_ServerInfo(void);
//
// ui_menu.c
@@ -818,11 +819,16 @@ typedef struct {
int playerRefresh;
int playerIndex;
int playerNumber;
+ int myPlayerIndex;
+ int ignoreIndex;
qboolean teamLeader;
char playerNames[MAX_CLIENTS][MAX_NAME_LENGTH];
+ char rawPlayerNames[MAX_CLIENTS][MAX_NAME_LENGTH];
char teamNames[MAX_CLIENTS][MAX_NAME_LENGTH];
+ char rawTeamNames[MAX_CLIENTS][MAX_NAME_LENGTH];
int clientNums[MAX_CLIENTS];
int teamClientNums[MAX_CLIENTS];
+ clientList_t ignoreList[MAX_CLIENTS];
int mapCount;
mapInfo mapList[MAX_MAPS];
diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c
index f3a81f5a..ea7f84f4 100644
--- a/src/ui/ui_main.c
+++ b/src/ui/ui_main.c
@@ -1964,6 +1964,28 @@ static void UI_DrawAllMapsSelection(rectDef_t *rect, float scale, vec4_t color,
}
}
+static void UI_DrawPlayerListSelection( rectDef_t *rect, float scale,
+ vec4_t color, int textStyle )
+{
+ if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount )
+ {
+ Text_Paint(rect->x, rect->y, scale, color,
+ uiInfo.rawPlayerNames[ uiInfo.playerIndex ],
+ 0, 0, textStyle);
+ }
+}
+
+static void UI_DrawTeamListSelection( rectDef_t *rect, float scale,
+ vec4_t color, int textStyle )
+{
+ if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount )
+ {
+ Text_Paint(rect->x, rect->y, scale, color,
+ uiInfo.rawTeamNames[ uiInfo.teamIndex ],
+ 0, 0, textStyle);
+ }
+}
+
static void UI_DrawOpponentName(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_opponentName"), 0, 0, textStyle);
}
@@ -2064,6 +2086,10 @@ static int UI_OwnerDrawWidth(int ownerDraw, float scale) {
break;
case UI_ALLMAPS_SELECTION:
break;
+ case UI_PLAYERLIST_SELECTION:
+ break;
+ case UI_TEAMLIST_SELECTION:
+ break;
case UI_OPPONENT_NAME:
break;
case UI_KEYBINDSTATUS:
@@ -2127,18 +2153,29 @@ static void UI_BuildPlayerList( void ) {
count = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
uiInfo.playerCount = 0;
uiInfo.myTeamCount = 0;
+ uiInfo.myPlayerIndex = 0;
playerTeamNumber = 0;
for( n = 0; n < count; n++ ) {
trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING );
if (info[0]) {
- Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount], Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
+ BG_ClientListParse( &uiInfo.ignoreList[ uiInfo.playerCount ],
+ Info_ValueForKey( info, "ig" ) );
+ Q_strncpyz( uiInfo.rawPlayerNames[uiInfo.playerCount],
+ Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
+ Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount],
+ Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
Q_CleanStr( uiInfo.playerNames[uiInfo.playerCount] );
uiInfo.clientNums[uiInfo.playerCount] = n;
+ if( n == uiInfo.playerNumber )
+ uiInfo.myPlayerIndex = uiInfo.playerCount;
uiInfo.playerCount++;
team2 = atoi(Info_ValueForKey(info, "t"));
if (team2 == team) {
- Q_strncpyz( uiInfo.teamNames[uiInfo.myTeamCount], Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
+ Q_strncpyz( uiInfo.rawTeamNames[uiInfo.myTeamCount],
+ Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
+ Q_strncpyz( uiInfo.teamNames[uiInfo.myTeamCount],
+ Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
Q_CleanStr( uiInfo.teamNames[uiInfo.myTeamCount] );
uiInfo.teamClientNums[uiInfo.myTeamCount] = n;
if (uiInfo.playerNumber == n) {
@@ -2164,11 +2201,19 @@ static void UI_BuildPlayerList( void ) {
static void UI_DrawSelectedPlayer(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
+ char name[ MAX_NAME_LENGTH ];
+ char *s;
+
if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) {
uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
UI_BuildPlayerList();
}
- Text_Paint(rect->x, rect->y, scale, color, (uiInfo.teamLeader) ? UI_Cvar_VariableString("cg_selectedPlayerName") : UI_Cvar_VariableString("name") , 0, 0, textStyle);
+ if( uiInfo.teamLeader )
+ s = UI_Cvar_VariableString("cg_selectedPlayerName");
+ else
+ s = UI_Cvar_VariableString("name");
+ Q_strncpyz( name, s, sizeof( name ) );
+ Text_Paint(rect->x, rect->y, scale, color, name, 0, 0, textStyle);
}
static void UI_DrawServerRefreshDate(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
@@ -2478,6 +2523,12 @@ static void UI_OwnerDraw( float x, float y, float w, float h,
case UI_MAPS_SELECTION:
UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qfalse);
break;
+ case UI_PLAYERLIST_SELECTION:
+ UI_DrawPlayerListSelection(&rect, scale, color, textStyle);
+ break;
+ case UI_TEAMLIST_SELECTION:
+ UI_DrawTeamListSelection(&rect, scale, color, textStyle);
+ break;
case UI_OPPONENT_NAME:
UI_DrawOpponentName(&rect, scale, color, textStyle);
break;
@@ -3904,6 +3955,8 @@ static void UI_RunMenuScript(char **args) {
UI_LoadArenas();
UI_MapCountByGameType(qfalse);
Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, "createserver");
+ } else if (Q_stricmp(name, "loadServerInfo") == 0) {
+ UI_ServerInfo();
} else if (Q_stricmp(name, "saveControls") == 0) {
Controls_SetConfig(qtrue);
} else if (Q_stricmp(name, "loadControls") == 0) {
@@ -4142,15 +4195,47 @@ static void UI_RunMenuScript(char **args) {
{
if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount )
{
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote clientkick %d\n",
+ trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote kick %d\n",
+ uiInfo.clientNums[ uiInfo.playerIndex ] ) );
+ }
+ }
+ else if( Q_stricmp( name, "voteMute" ) == 0 )
+ {
+ if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount )
+ {
+ trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote mute %d\n",
+ uiInfo.clientNums[ uiInfo.playerIndex ] ) );
+ }
+ }
+ else if( Q_stricmp( name, "voteUnMute" ) == 0 )
+ {
+ if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount )
+ {
+ trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote unmute %d\n",
uiInfo.clientNums[ uiInfo.playerIndex ] ) );
}
}
else if( Q_stricmp( name, "voteTeamKick" ) == 0 )
{
- if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.playerCount )
+ if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount )
{
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote teamclientkick %d\n",
+ trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote kick %d\n",
+ uiInfo.teamClientNums[ uiInfo.teamIndex ] ) );
+ }
+ }
+ else if( Q_stricmp( name, "voteTeamDenyBuild" ) == 0 )
+ {
+ if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount )
+ {
+ trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote denybuild %d\n",
+ uiInfo.teamClientNums[ uiInfo.teamIndex ] ) );
+ }
+ }
+ else if( Q_stricmp( name, "voteTeamAllowBuild" ) == 0 )
+ {
+ if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount )
+ {
+ trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote allowbuild %d\n",
uiInfo.teamClientNums[ uiInfo.teamIndex ] ) );
}
}
@@ -4271,6 +4356,51 @@ static void UI_RunMenuScript(char **args) {
} else if (Q_stricmp(name, "update") == 0) {
if (String_Parse(args, &name2))
UI_Update(name2);
+ } else if (Q_stricmp(name, "InitIgnoreList") == 0) {
+ UI_BuildPlayerList();
+ } else if (Q_stricmp(name, "ToggleIgnore") == 0) {
+ if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount )
+ {
+ if( BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] ) )
+ {
+ BG_ClientListRemove( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] );
+ trap_Cmd_ExecuteText( EXEC_NOW, va( "unignore %i\n",
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] ) );
+ }
+ else
+ {
+ BG_ClientListAdd( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] );
+ trap_Cmd_ExecuteText( EXEC_NOW, va( "ignore %i\n",
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] ) );
+ }
+ }
+ } else if (Q_stricmp(name, "IgnorePlayer") == 0) {
+ if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount )
+ {
+ if( !BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] ) )
+ {
+ BG_ClientListAdd( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] );
+ trap_Cmd_ExecuteText( EXEC_NOW, va( "ignore %i\n",
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] ) );
+ }
+ }
+ } else if (Q_stricmp(name, "UnIgnorePlayer") == 0) {
+ if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount )
+ {
+ if( BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] ) )
+ {
+ BG_ClientListRemove( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] );
+ trap_Cmd_ExecuteText( EXEC_NOW, va( "unignore %i\n",
+ uiInfo.clientNums[ uiInfo.ignoreIndex ] ) );
+ }
+ }
} else if (Q_stricmp(name, "setPbClStatus") == 0) {
int stat;
if ( Int_Parse( args, &stat ) )
@@ -4917,6 +5047,7 @@ UI_FeederCount
==================
*/
static int UI_FeederCount(float feederID) {
+
if (feederID == FEEDER_HEADS) {
return UI_HeadCountByTeam();
} else if (feederID == FEEDER_Q3HEADS) {
@@ -4943,6 +5074,8 @@ static int UI_FeederCount(float feederID) {
UI_BuildPlayerList();
}
return uiInfo.myTeamCount;
+ } else if (feederID == FEEDER_IGNORE_LIST) {
+ return uiInfo.playerCount;
} else if (feederID == FEEDER_MODS) {
return uiInfo.modCount;
} else if (feederID == FEEDER_DEMOS) {
@@ -5114,6 +5247,22 @@ static const char *UI_FeederItemText(float feederID, int index, int column, qhan
if (index >= 0 && index < uiInfo.myTeamCount) {
return uiInfo.teamNames[index];
}
+ } else if (feederID == FEEDER_IGNORE_LIST) {
+ if (index >= 0 && index < uiInfo.playerCount) {
+ switch( column )
+ {
+ case 1:
+ // am I ignoring him
+ return ( BG_ClientListTest(&uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
+ uiInfo.clientNums[ index ] ) ) ? "X" : "";
+ case 2:
+ // is he ignoring me
+ return ( BG_ClientListTest( &uiInfo.ignoreList[ index ],
+ uiInfo.playerNumber ) ) ? "X" : "";
+ default:
+ return uiInfo.playerNames[index];
+ }
+ }
} else if (feederID == FEEDER_MODS) {
if (index >= 0 && index < uiInfo.modCount) {
if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr) {
@@ -5277,6 +5426,8 @@ static void UI_FeederSelection(float feederID, int index) {
uiInfo.playerIndex = index;
} else if (feederID == FEEDER_TEAM_LIST) {
uiInfo.teamIndex = index;
+ } else if (feederID == FEEDER_IGNORE_LIST) {
+ uiInfo.ignoreIndex = index;
} else if (feederID == FEEDER_MODS) {
uiInfo.modIndex = index;
} else if (feederID == FEEDER_CINEMATICS) {
@@ -6055,6 +6206,7 @@ vmCvar_t ui_serverStatusTimeOut;
//TA: bank values
vmCvar_t ui_bank;
+vmCvar_t ui_winner;
// bk001129 - made static to avoid aliasing
@@ -6085,6 +6237,7 @@ static cvarTable_t cvarTable[] = {
{ &ui_spSkill, "g_spSkill", "2", CVAR_ARCHIVE },
{ &ui_spSelection, "ui_spSelection", "", CVAR_ROM },
+ { &ui_winner, "ui_winner", "", CVAR_ROM },
{ &ui_browserMaster, "ui_browserMaster", "0", CVAR_ARCHIVE },
{ &ui_browserGameType, "ui_browserGameType", "0", CVAR_ARCHIVE },
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c
index f3132378..2ca88cb6 100644
--- a/src/ui/ui_shared.c
+++ b/src/ui/ui_shared.c
@@ -3436,25 +3436,10 @@ static bind_t g_bindings[] =
{ "weapnext", ']', -1, -1, -1 },
{ "+button3", K_MOUSE3, -1, -1, -1 },
{ "+button4", K_MOUSE4, -1, -1, -1 },
- { "prevTeamMember", 'w', -1, -1, -1 },
- { "nextTeamMember", 'r', -1, -1, -1 },
- { "nextOrder", 't', -1, -1, -1 },
- { "confirmOrder", 'y', -1, -1, -1 },
- { "denyOrder", 'n', -1, -1, -1 },
- { "taskOffense", 'o', -1, -1, -1 },
- { "taskDefense", 'd', -1, -1, -1 },
- { "taskPatrol", 'p', -1, -1, -1 },
- { "taskCamp", 'c', -1, -1, -1 },
- { "taskFollow", 'f', -1, -1, -1 },
- { "taskRetrieve", 'v', -1, -1, -1 },
- { "taskEscort", 'l', -1, -1, -1 },
- { "taskOwnFlag", 'i', -1, -1, -1 },
- { "taskSuicide", 'k', -1, -1, -1 },
- { "tauntKillInsult", K_F1, -1, -1, -1 },
- { "tauntPraise", K_F2, -1, -1, -1 },
- { "tauntTaunt", K_F3, -1, -1, -1 },
- { "tauntDeathInsult", K_F4, -1, -1, -1 },
- { "tauntGauntlet", K_F5, -1, -1, -1 },
+ { "vote yes", K_F1, -1, -1, -1 },
+ { "vote no", K_F2, -1, -1, -1 },
+ { "teamvote yes", K_F3, -1, -1, -1 },
+ { "teamvote no", K_F4, -1, -1, -1 },
{ "scoresUp", K_KP_PGUP, -1, -1, -1 },
{ "scoresDown", K_KP_PGDN, -1, -1, -1 },
// bk001205 - this one below was: '-1'