From c4c6f67a49e33d14e24d56d0082f153797cd30f8 Mon Sep 17 00:00:00 2001 From: Christopher Schwarz Date: Sun, 18 Oct 2009 17:42:10 +0000 Subject: * (bug 4309) Add options to !restart that allow for keeping/switching player teams, and optionally also to lock them. --- src/game/g_admin.c | 78 ++++++++++++++++++++++++++++++++++++++++++++-------- src/game/g_client.c | 10 +++++++ src/game/g_local.h | 2 ++ src/game/g_main.c | 9 ++++++ src/game/g_session.c | 15 ++++++---- 5 files changed, 97 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/game/g_admin.c b/src/game/g_admin.c index 749b616c..c917e412 100644 --- a/src/game/g_admin.c +++ b/src/game/g_admin.c @@ -151,8 +151,8 @@ g_admin_cmd_t g_admin_cmds[ ] = }, {"restart", G_admin_restart, "restart", - "restart the current map (optionally using named layout)", - "(^5layout^7)" + "restart the current map (optionally using named layout or keeping/switching teams)", + "(^5layout^7) (^5keepteams|switchteams|keepteamslock|switchteamslock^7)" }, {"setlevel", G_admin_setlevel, "setlevel", @@ -2668,7 +2668,10 @@ qboolean G_admin_rename( gentity_t *ent, int skiparg ) qboolean G_admin_restart( gentity_t *ent, int skiparg ) { - char layout[ MAX_CVAR_VALUE_STRING ] = { "" }; + char layout[ MAX_CVAR_VALUE_STRING ] = { "" }; + char teampref[ MAX_STRING_CHARS ] = { "" }; + int i; + gclient_t *cl; if( G_SayArgc( ) > 1 + skiparg ) { @@ -2677,23 +2680,74 @@ qboolean G_admin_restart( gentity_t *ent, int skiparg ) trap_Cvar_VariableStringBuffer( "mapname", map, sizeof( map ) ); G_SayArgv( skiparg + 1, layout, sizeof( layout ) ); - if( !Q_stricmp( layout, "*BUILTIN*" ) || - trap_FS_FOpenFile( va( "layouts/%s/%s.dat", map, layout ), - NULL, FS_READ ) > 0 ) + // Figure out which argument is which + if( Q_stricmp( layout, "keepteams" ) && + Q_stricmp( layout, "keepteamslock" ) && + Q_stricmp( layout, "switchteams" ) && + Q_stricmp( layout, "switchteamslock" ) ) { - trap_Cvar_Set( "g_layouts", layout ); + if( !Q_stricmp( layout, "*BUILTIN*" ) || + trap_FS_FOpenFile( va( "layouts/%s/%s.dat", map, layout ), + NULL, FS_READ ) > 0 ) + { + trap_Cvar_Set( "g_layouts", layout ); + } + else + { + ADMP( va( "^3!restart: ^7layout '%s' does not exist\n", layout ) ); + return qfalse; + } } - else + else { - ADMP( va( "^3!restart: ^7layout '%s' does not exist\n", layout ) ); - return qfalse; + layout[ 0 ] = '\0'; + G_SayArgv( skiparg + 1, teampref, sizeof( teampref ) ); } } + + if( G_SayArgc( ) > 2 + skiparg ) + G_SayArgv( skiparg + 2, teampref, sizeof( teampref ) ); + + if( !Q_stricmpn( teampref, "keepteams", 9 ) ) + { + for( i = 0; i < g_maxclients.integer; i++ ) + { + cl = level.clients + i; + if( cl->pers.connected != CON_CONNECTED ) + continue; + + if( cl->pers.teamSelection == TEAM_NONE ) + continue; + + cl->sess.restartTeam = cl->pers.teamSelection; + } + } + else if( !Q_stricmpn( teampref, "switchteams", 11 ) ) + { + for( i = 0; i < g_maxclients.integer; i++ ) + { + cl = level.clients + i; + + if( cl->pers.connected != CON_CONNECTED ) + continue; + + if( cl->pers.teamSelection == TEAM_HUMANS ) + cl->sess.restartTeam = TEAM_ALIENS; + else if(cl->pers.teamSelection == TEAM_ALIENS ) + cl->sess.restartTeam = TEAM_HUMANS; + } + } + + if( !Q_stricmp( teampref, "switchteamslock" ) || + !Q_stricmp( teampref, "keepteamslock" ) ) + trap_Cvar_Set( "g_lockTeamsAtStart", "1" ); trap_SendConsoleCommand( EXEC_APPEND, "map_restart" ); - AP( va( "print \"^3!restart: ^7map restarted by %s %s\n\"", + + AP( va( "print \"^3!restart: ^7map restarted by %s %s %s\n\"", ( ent ) ? ent->client->pers.netname : "console", - ( layout[ 0 ] ) ? va( "(forcing layout '%s')", layout ) : "" ) ); + ( layout[ 0 ] ) ? va( "^7(forcing layout '%s^7')", layout ) : "", + ( teampref[ 0 ] ) ? va( "^7(with teams option: '%s^7')", teampref ) : "" ) ); return qtrue; } diff --git a/src/game/g_client.c b/src/game/g_client.c index 071a8441..ca002506 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -1285,6 +1285,16 @@ char *ClientConnect( int clientNum, qboolean firstTime ) // count current clients and rank for scoreboard CalculateRanks( ); G_admin_namelog_update( client, qfalse ); + + + // if this is after !restart keepteams or !restart switchteams, apply said selection + if ( client->sess.restartTeam != TEAM_NONE ) + { + G_ChangeTeam( ent, client->sess.restartTeam ); + client->sess.restartTeam = TEAM_NONE; + } + + return NULL; } diff --git a/src/game/g_local.h b/src/game/g_local.h index 3bd703fc..81f45505 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -275,6 +275,7 @@ typedef struct int spectatorTime; // for determining next-in-line to play spectatorState_t spectatorState; int spectatorClient; // for chasecam and follow mode + team_t restartTeam; //for !restart keepteams and !restart switchteams clientList_t ignoreList; } clientSession_t; @@ -1040,6 +1041,7 @@ extern vmCvar_t g_cheats; extern vmCvar_t g_maxclients; // allow this many total, including spectators extern vmCvar_t g_maxGameClients; // allow this many active extern vmCvar_t g_restarted; +extern vmCvar_t g_lockTeamsAtStart; extern vmCvar_t g_minCommandPeriod; extern vmCvar_t g_minNameChangePeriod; extern vmCvar_t g_maxNameChanges; diff --git a/src/game/g_main.c b/src/game/g_main.c index df13a957..01df75d6 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -62,6 +62,7 @@ vmCvar_t g_synchronousClients; vmCvar_t g_warmup; vmCvar_t g_doWarmup; vmCvar_t g_restarted; +vmCvar_t g_lockTeamsAtStart; vmCvar_t g_logFile; vmCvar_t g_logFileSync; vmCvar_t g_blood; @@ -151,6 +152,7 @@ static cvarTable_t gameCvarTable[ ] = { NULL, "gamename", GAME_VERSION , CVAR_SERVERINFO | CVAR_ROM, 0, qfalse }, { NULL, "gamedate", __DATE__ , CVAR_ROM, 0, qfalse }, { &g_restarted, "g_restarted", "0", CVAR_ROM, 0, qfalse }, + { &g_lockTeamsAtStart, "g_lockTeamsAtStart", "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 }, @@ -641,6 +643,13 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) G_UpdateTeamConfigStrings( ); G_ResetPTRConnections( ); + + if( g_lockTeamsAtStart.integer ) + { + level.alienTeamLocked = qtrue; + level.humanTeamLocked = qtrue; + trap_Cvar_Set( "g_lockTeamsAtStart", "0" ); + } } /* diff --git a/src/game/g_session.c b/src/game/g_session.c index cce6c792..2133f8a4 100644 --- a/src/game/g_session.c +++ b/src/game/g_session.c @@ -46,10 +46,11 @@ void G_WriteClientSessionData( gclient_t *client ) const char *s; const char *var; - s = va( "%i %i %i %s", + s = va( "%i %i %i %i %s", client->sess.spectatorTime, client->sess.spectatorState, client->sess.spectatorClient, + client->sess.restartTeam, Com_ClientListString( &client->sess.ignoreList ) ); @@ -67,22 +68,25 @@ Called on a reconnect */ void G_ReadSessionData( gclient_t *client ) { - char s[ MAX_STRING_CHARS ]; + char s[ MAX_STRING_CHARS ]; const char *var; - int spectatorState; - char ignorelist[ 17 ]; + int spectatorState; + int restartTeam; + char ignorelist[ 17 ]; var = va( "session%i", client - level.clients ); trap_Cvar_VariableStringBuffer( var, s, sizeof(s) ); - sscanf( s, "%i %i %i %16s", + sscanf( s, "%i %i %i %i %16s", &client->sess.spectatorTime, &spectatorState, &client->sess.spectatorClient, + &restartTeam, ignorelist ); client->sess.spectatorState = (spectatorState_t)spectatorState; + client->sess.restartTeam = (team_t)restartTeam; Com_ClientListParse( &client->sess.ignoreList, ignorelist ); } @@ -117,6 +121,7 @@ void G_InitSessionData( gclient_t *client, char *userinfo ) sess->spectatorState = SPECTATOR_NOT; } + sess->restartTeam = TEAM_NONE; sess->spectatorState = SPECTATOR_FREE; sess->spectatorTime = level.time; sess->spectatorClient = -1; -- cgit