summaryrefslogtreecommitdiff
path: root/src/game/g_session.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/g_session.c')
-rw-r--r--src/game/g_session.c188
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] );
+ }
+ }
+}