diff options
Diffstat (limited to 'src/game/g_session.c')
-rw-r--r-- | src/game/g_session.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/src/game/g_session.c b/src/game/g_session.c new file mode 100644 index 00000000..06f2b1ba --- /dev/null +++ b/src/game/g_session.c @@ -0,0 +1,188 @@ +// Copyright (C) 1999-2000 Id Software, Inc. +// + +/* + * Portions Copyright (C) 2000-2001 Tim Angus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* To assertain which portions are licensed under the GPL and which are + * licensed by Id Software, Inc. please run a diff between the equivalent + * versions of the "Tremulous" modification and the unmodified "Quake3" + * game source code. + */ + +#include "g_local.h" + + +/* +======================================================================= + + SESSION DATA + +Session data is the only data that stays persistant across level loads +and tournament restarts. +======================================================================= +*/ + +/* +================ +G_WriteClientSessionData + +Called on game shutdown +================ +*/ +void G_WriteClientSessionData( gclient_t *client ) { + const char *s; + const char *var; + + s = va("%i %i %i %i %i %i %i", + client->sess.sessionTeam, + client->sess.spectatorTime, + client->sess.spectatorState, + client->sess.spectatorClient, + client->sess.wins, + client->sess.losses, + client->sess.teamLeader + ); + + var = va( "session%i", client - level.clients ); + + trap_Cvar_Set( var, s ); +} + +/* +================ +G_ReadSessionData + +Called on a reconnect +================ +*/ +void G_ReadSessionData( gclient_t *client ) { + char s[MAX_STRING_CHARS]; + const char *var; + + var = va( "session%i", client - level.clients ); + trap_Cvar_VariableStringBuffer( var, s, sizeof(s) ); + + sscanf( s, "%i %i %i %i %i %i %i", + &client->sess.sessionTeam, + &client->sess.spectatorTime, + &client->sess.spectatorState, + &client->sess.spectatorClient, + &client->sess.wins, + &client->sess.losses, + &client->sess.teamLeader + ); +} + + +/* +================ +G_InitSessionData + +Called on a first-time connect +================ +*/ +void G_InitSessionData( gclient_t *client, char *userinfo ) { + clientSession_t *sess; + const char *value; + + sess = &client->sess; + + // initial team determination + if ( g_gametype.integer >= GT_TEAM ) { + if ( g_teamAutoJoin.integer ) { + sess->sessionTeam = PickTeam( -1 ); + BroadcastTeamChange( client, -1 ); + } else { + // always spawn as spectator in team games + sess->sessionTeam = TEAM_SPECTATOR; + } + } else { + value = Info_ValueForKey( userinfo, "team" ); + if ( value[0] == 's' ) { + // a willing spectator, not a waiting-in-line + sess->sessionTeam = TEAM_SPECTATOR; + } else { + switch ( g_gametype.integer ) { + default: + case GT_FFA: + case GT_SINGLE_PLAYER: + if ( g_maxGameClients.integer > 0 && + level.numNonSpectatorClients >= g_maxGameClients.integer ) { + sess->sessionTeam = TEAM_SPECTATOR; + } else { + sess->sessionTeam = TEAM_FREE; + } + break; + case GT_TOURNAMENT: + // if the game is full, go into a waiting mode + if ( level.numNonSpectatorClients >= 2 ) { + sess->sessionTeam = TEAM_SPECTATOR; + } else { + sess->sessionTeam = TEAM_FREE; + } + break; + } + } + } + + sess->spectatorState = SPECTATOR_FREE; + sess->spectatorTime = level.time; + + G_WriteClientSessionData( client ); +} + + +/* +================== +G_InitWorldSession + +================== +*/ +void G_InitWorldSession( void ) { + char s[MAX_STRING_CHARS]; + int gt; + + trap_Cvar_VariableStringBuffer( "session", s, sizeof(s) ); + gt = atoi( s ); + + // if the gametype changed since the last session, don't use any + // client sessions + if ( g_gametype.integer != gt ) { + level.newSession = qtrue; + G_Printf( "Gametype changed, clearing session data.\n" ); + } +} + +/* +================== +G_WriteSessionData + +================== +*/ +void G_WriteSessionData( void ) { + int i; + + trap_Cvar_Set( "session", va("%i", g_gametype.integer) ); + + for ( i = 0 ; i < level.maxclients ; i++ ) { + if ( level.clients[i].pers.connected == CON_CONNECTED ) { + G_WriteClientSessionData( &level.clients[i] ); + } + } +} |