codemp/game/g_session.c

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 Id Software, Inc.
00002 //
00003 #include "g_local.h"
00004 
00005 
00006 /*
00007 =======================================================================
00008 
00009   SESSION DATA
00010 
00011 Session data is the only data that stays persistant across level loads
00012 and tournament restarts.
00013 =======================================================================
00014 */
00015 
00016 /*
00017 ================
00018 G_WriteClientSessionData
00019 
00020 Called on game shutdown
00021 ================
00022 */
00023 void G_WriteClientSessionData( gclient_t *client ) {
00024         const char      *s;
00025         const char      *var;
00026         int                     i = 0;
00027         char            siegeClass[64];
00028         char            saberType[64];
00029         char            saber2Type[64];
00030 
00031         strcpy(siegeClass, client->sess.siegeClass);
00032 
00033         while (siegeClass[i])
00034         { //sort of a hack.. we don't want spaces by siege class names have spaces so convert them all to unused chars
00035                 if (siegeClass[i] == ' ')
00036                 {
00037                         siegeClass[i] = 1;
00038                 }
00039 
00040                 i++;
00041         }
00042 
00043         if (!siegeClass[0])
00044         { //make sure there's at least something
00045                 strcpy(siegeClass, "none");
00046         }
00047 
00048         //Do the same for the saber
00049         strcpy(saberType, client->sess.saberType);
00050 
00051         i = 0;
00052         while (saberType[i])
00053         {
00054                 if (saberType[i] == ' ')
00055                 {
00056                         saberType[i] = 1;
00057                 }
00058 
00059                 i++;
00060         }
00061 
00062         strcpy(saber2Type, client->sess.saber2Type);
00063 
00064         i = 0;
00065         while (saber2Type[i])
00066         {
00067                 if (saber2Type[i] == ' ')
00068                 {
00069                         saber2Type[i] = 1;
00070                 }
00071 
00072                 i++;
00073         }
00074 
00075         s = va("%i %i %i %i %i %i %i %i %i %i %i %i %s %s %s", 
00076                 client->sess.sessionTeam,
00077                 client->sess.spectatorTime,
00078                 client->sess.spectatorState,
00079                 client->sess.spectatorClient,
00080                 client->sess.wins,
00081                 client->sess.losses,
00082                 client->sess.teamLeader,
00083                 client->sess.setForce,
00084                 client->sess.saberLevel,
00085                 client->sess.selectedFP,
00086                 client->sess.duelTeam,
00087                 client->sess.siegeDesiredTeam,
00088                 siegeClass,
00089                 saberType,
00090                 saber2Type
00091                 );
00092 
00093         var = va( "session%i", client - level.clients );
00094 
00095         trap_Cvar_Set( var, s );
00096 }
00097 
00098 /*
00099 ================
00100 G_ReadSessionData
00101 
00102 Called on a reconnect
00103 ================
00104 */
00105 void G_ReadSessionData( gclient_t *client ) {
00106         char    s[MAX_STRING_CHARS];
00107         const char      *var;
00108         int                     i = 0;
00109 
00110         // bk001205 - format
00111         int teamLeader;
00112         int spectatorState;
00113         int sessionTeam;
00114 
00115         var = va( "session%i", client - level.clients );
00116         trap_Cvar_VariableStringBuffer( var, s, sizeof(s) );
00117 
00118         sscanf( s, "%i %i %i %i %i %i %i %i %i %i %i %i %s %s %s",
00119                 &sessionTeam,                 // bk010221 - format
00120                 &client->sess.spectatorTime,
00121                 &spectatorState,              // bk010221 - format
00122                 &client->sess.spectatorClient,
00123                 &client->sess.wins,
00124                 &client->sess.losses,
00125                 &teamLeader,                   // bk010221 - format
00126                 &client->sess.setForce,
00127                 &client->sess.saberLevel,
00128                 &client->sess.selectedFP,
00129                 &client->sess.duelTeam,
00130                 &client->sess.siegeDesiredTeam,
00131                 &client->sess.siegeClass,
00132                 &client->sess.saberType,
00133                 &client->sess.saber2Type
00134                 );
00135 
00136         while (client->sess.siegeClass[i])
00137         { //convert back to spaces from unused chars, as session data is written that way.
00138                 if (client->sess.siegeClass[i] == 1)
00139                 {
00140                         client->sess.siegeClass[i] = ' ';
00141                 }
00142 
00143                 i++;
00144         }
00145 
00146         i = 0;
00147         //And do the same for the saber type
00148         while (client->sess.saberType[i])
00149         {
00150                 if (client->sess.saberType[i] == 1)
00151                 {
00152                         client->sess.saberType[i] = ' ';
00153                 }
00154 
00155                 i++;
00156         }
00157 
00158         i = 0;
00159         while (client->sess.saber2Type[i])
00160         {
00161                 if (client->sess.saber2Type[i] == 1)
00162                 {
00163                         client->sess.saber2Type[i] = ' ';
00164                 }
00165 
00166                 i++;
00167         }
00168 
00169         // bk001205 - format issues
00170         client->sess.sessionTeam = (team_t)sessionTeam;
00171         client->sess.spectatorState = (spectatorState_t)spectatorState;
00172         client->sess.teamLeader = (qboolean)teamLeader;
00173 
00174         client->ps.fd.saberAnimLevel = client->sess.saberLevel;
00175         client->ps.fd.saberDrawAnimLevel = client->sess.saberLevel;
00176         client->ps.fd.forcePowerSelected = client->sess.selectedFP;
00177 }
00178 
00179 
00180 /*
00181 ================
00182 G_InitSessionData
00183 
00184 Called on a first-time connect
00185 ================
00186 */
00187 void G_InitSessionData( gclient_t *client, char *userinfo, qboolean isBot ) {
00188         clientSession_t *sess;
00189         const char              *value;
00190 
00191         sess = &client->sess;
00192 
00193         client->sess.siegeDesiredTeam = TEAM_FREE;
00194 
00195         // initial team determination
00196         if ( g_gametype.integer >= GT_TEAM ) {
00197                 if ( g_teamAutoJoin.integer ) {
00198                         sess->sessionTeam = PickTeam( -1 );
00199                         BroadcastTeamChange( client, -1 );
00200                 } else {
00201                         // always spawn as spectator in team games
00202                         if (!isBot)
00203                         {
00204                                 sess->sessionTeam = TEAM_SPECTATOR;     
00205                         }
00206                         else
00207                         { //Bots choose their team on creation
00208                                 value = Info_ValueForKey( userinfo, "team" );
00209                                 if (value[0] == 'r' || value[0] == 'R')
00210                                 {
00211                                         sess->sessionTeam = TEAM_RED;
00212                                 }
00213                                 else if (value[0] == 'b' || value[0] == 'B')
00214                                 {
00215                                         sess->sessionTeam = TEAM_BLUE;
00216                                 }
00217                                 else
00218                                 {
00219                                         sess->sessionTeam = PickTeam( -1 );
00220                                 }
00221                                 BroadcastTeamChange( client, -1 );
00222                         }
00223                 }
00224         } else {
00225                 value = Info_ValueForKey( userinfo, "team" );
00226                 if ( value[0] == 's' ) {
00227                         // a willing spectator, not a waiting-in-line
00228                         sess->sessionTeam = TEAM_SPECTATOR;
00229                 } else {
00230                         switch ( g_gametype.integer ) {
00231                         default:
00232                         case GT_FFA:
00233                         case GT_HOLOCRON:
00234                         case GT_JEDIMASTER:
00235                         case GT_SINGLE_PLAYER:
00236                                 if ( g_maxGameClients.integer > 0 && 
00237                                         level.numNonSpectatorClients >= g_maxGameClients.integer ) {
00238                                         sess->sessionTeam = TEAM_SPECTATOR;
00239                                 } else {
00240                                         sess->sessionTeam = TEAM_FREE;
00241                                 }
00242                                 break;
00243                         case GT_DUEL:
00244                                 // if the game is full, go into a waiting mode
00245                                 if ( level.numNonSpectatorClients >= 2 ) {
00246                                         sess->sessionTeam = TEAM_SPECTATOR;
00247                                 } else {
00248                                         sess->sessionTeam = TEAM_FREE;
00249                                 }
00250                                 break;
00251                         case GT_POWERDUEL:
00252                                 //sess->duelTeam = DUELTEAM_LONE; //default
00253                                 {
00254                                         int loners = 0;
00255                                         int doubles = 0;
00256 
00257                                         G_PowerDuelCount(&loners, &doubles, qtrue);
00258 
00259                                         if (!doubles || loners > (doubles/2))
00260                                         {
00261                                                 sess->duelTeam = DUELTEAM_DOUBLE;
00262                                         }
00263                                         else
00264                                         {
00265                                                 sess->duelTeam = DUELTEAM_LONE;
00266                                         }
00267                                 }
00268                                 sess->sessionTeam = TEAM_SPECTATOR;
00269                                 break;
00270                         }
00271                 }
00272         }
00273 
00274         sess->spectatorState = SPECTATOR_FREE;
00275         sess->spectatorTime = level.time;
00276 
00277         sess->siegeClass[0] = 0;
00278         sess->saberType[0] = 0;
00279         sess->saber2Type[0] = 0;
00280 
00281         G_WriteClientSessionData( client );
00282 }
00283 
00284 
00285 /*
00286 ==================
00287 G_InitWorldSession
00288 
00289 ==================
00290 */
00291 void G_InitWorldSession( void ) {
00292         char    s[MAX_STRING_CHARS];
00293         int                     gt;
00294 
00295         trap_Cvar_VariableStringBuffer( "session", s, sizeof(s) );
00296         gt = atoi( s );
00297         
00298         // if the gametype changed since the last session, don't use any
00299         // client sessions
00300         if ( g_gametype.integer != gt ) {
00301                 level.newSession = qtrue;
00302                 G_Printf( "Gametype changed, clearing session data.\n" );
00303         }
00304 }
00305 
00306 /*
00307 ==================
00308 G_WriteSessionData
00309 
00310 ==================
00311 */
00312 void G_WriteSessionData( void ) {
00313         int             i;
00314 
00315         trap_Cvar_Set( "session", va("%i", g_gametype.integer) );
00316 
00317         for ( i = 0 ; i < level.maxclients ; i++ ) {
00318                 if ( level.clients[i].pers.connected == CON_CONNECTED ) {
00319                         G_WriteClientSessionData( &level.clients[i] );
00320                 }
00321         }
00322 }