1 /*
2 ===========================================================================
3
4 Return to Castle Wolfenstein single player GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6
7 This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
8
9 RTCW SP Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 RTCW SP Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code. If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "g_local.h"
30
31
32 /*
33 =======================================================================
34
35 SESSION DATA
36
37 Session data is the only data that stays persistant across level loads
38 and tournament restarts.
39 =======================================================================
40 */
41
42 /*
43 ================
44 G_WriteClientSessionData
45
46 Called on game shutdown
47 ================
48 */
G_WriteClientSessionData(gclient_t * client)49 void G_WriteClientSessionData( gclient_t *client ) {
50 const char *s;
51 const char *var;
52
53 s = va( "%i %i %i %i %i %i %i %i %i %i %i", // DHM - Nerve
54 client->sess.sessionTeam,
55 client->sess.spectatorNum,
56 client->sess.spectatorState,
57 client->sess.spectatorClient,
58 client->sess.wins,
59 client->sess.losses,
60 client->sess.playerType, // DHM - Nerve
61 client->sess.playerWeapon, // DHM - Nerve
62 client->sess.playerPistol, // DHM - Nerve
63 client->sess.playerItem, // DHM - Nerve
64 client->sess.playerSkin // DHM - Nerve
65 );
66
67 var = va( "session%i", (int)(client - level.clients) );
68
69 trap_Cvar_Set( var, s );
70 }
71
72 /*
73 ================
74 G_ReadSessionData
75
76 Called on a reconnect
77 ================
78 */
G_ReadSessionData(gclient_t * client)79 void G_ReadSessionData( gclient_t *client ) {
80 char s[MAX_STRING_CHARS];
81 const char *var;
82
83 var = va( "session%i", (int)(client - level.clients) );
84 trap_Cvar_VariableStringBuffer( var, s, sizeof( s ) );
85
86 sscanf( s, "%i %i %i %i %i %i %i %i %i %i %i", // DHM - Nerve
87 (int *)&client->sess.sessionTeam,
88 &client->sess.spectatorNum,
89 (int *)&client->sess.spectatorState,
90 &client->sess.spectatorClient,
91 &client->sess.wins,
92 &client->sess.losses,
93 &client->sess.playerType, // DHM - Nerve
94 &client->sess.playerWeapon, // DHM - Nerve
95 &client->sess.playerPistol, // DHM - Nerve
96 &client->sess.playerItem, // DHM - Nerve
97 &client->sess.playerSkin // DHM - Nerve
98 );
99 }
100
101
102 /*
103 ================
104 G_InitSessionData
105
106 Called on a first-time connect
107 ================
108 */
G_InitSessionData(gclient_t * client,char * userinfo)109 void G_InitSessionData( gclient_t *client, char *userinfo ) {
110 clientSession_t *sess;
111 const char *value;
112
113 sess = &client->sess;
114
115 // check for team preference, mainly for bots
116 value = Info_ValueForKey( userinfo, "teampref" );
117
118 // check for human's team preference set by start server menu
119 if ( !value[0] && g_localTeamPref.string[0] /*&& client->pers.localClient*/ ) {
120 value = g_localTeamPref.string;
121
122 // clear team so it's only used once
123 trap_Cvar_Set( "g_localTeamPref", "" );
124 }
125
126 // initial team determination
127 if ( g_gametype.integer >= GT_TEAM ) {
128 // always spawn as spectator in team games
129 sess->sessionTeam = TEAM_SPECTATOR;
130 sess->spectatorState = SPECTATOR_FREE;
131
132 if ( value[0] || g_teamAutoJoin.integer ) {
133 SetTeam( &g_entities[client - level.clients], value );
134 }
135 } else {
136 if ( value[0] == 's' ) {
137 // a willing spectator, not a waiting-in-line
138 sess->sessionTeam = TEAM_SPECTATOR;
139 } else {
140 switch ( g_gametype.integer ) {
141 default:
142 case GT_FFA:
143 case GT_SINGLE_PLAYER:
144 if ( g_maxGameClients.integer > 0 &&
145 level.numNonSpectatorClients >= g_maxGameClients.integer ) {
146 sess->sessionTeam = TEAM_SPECTATOR;
147 } else {
148 sess->sessionTeam = TEAM_FREE;
149 }
150 break;
151 case GT_TOURNAMENT:
152 // if the game is full, go into a waiting mode
153 if ( level.numNonSpectatorClients >= 2 ) {
154 sess->sessionTeam = TEAM_SPECTATOR;
155 } else {
156 sess->sessionTeam = TEAM_FREE;
157 }
158 break;
159 }
160 }
161
162 sess->spectatorState = SPECTATOR_FREE;
163 }
164
165 AddTournamentQueue(client);
166
167 // DHM - Nerve
168 sess->playerType = 0;
169 sess->playerWeapon = 0;
170 sess->playerPistol = 0;
171 sess->playerItem = 0;
172 sess->playerSkin = 0;
173 // dhm - end
174
175 G_WriteClientSessionData( client );
176 }
177
178
179 /*
180 ==================
181 G_InitWorldSession
182
183 ==================
184 */
G_InitWorldSession(void)185 void G_InitWorldSession( void ) {
186 char s[MAX_STRING_CHARS];
187 int gt;
188
189 trap_Cvar_VariableStringBuffer( "session", s, sizeof( s ) );
190 gt = atoi( s );
191
192 // if the gametype changed since the last session, don't use any
193 // client sessions
194 if ( g_gametype.integer != gt ) {
195 level.newSession = qtrue;
196 G_Printf( "Gametype changed, clearing session data.\n" );
197 }
198 }
199
200 /*
201 ==================
202 G_WriteSessionData
203
204 ==================
205 */
G_WriteSessionData(void)206 void G_WriteSessionData( void ) {
207 int i;
208
209 trap_Cvar_Set( "session", va( "%i", g_gametype.integer ) );
210
211 for ( i = 0 ; i < level.maxclients ; i++ ) {
212 if ( level.clients[i].pers.connected == CON_CONNECTED ) {
213 G_WriteClientSessionData( &level.clients[i] );
214 }
215 }
216 }
217