reaction/code/game/g_session.c
2013-01-04 13:27:22 +00:00

296 lines
7.7 KiB
C

//-----------------------------------------------------------------------------
//
// $Id$
//
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.23 2002/10/26 22:03:43 jbravo
// Made TeamDM work RQ3 style.
//
// Revision 1.22 2002/10/21 21:00:39 slicer
// New MM features and bug fixes
//
// Revision 1.21 2002/09/29 16:06:45 jbravo
// Work done at the HPWorld expo
//
// Revision 1.20 2002/08/23 14:25:05 slicer
// Added a new Referee System with multiple ref support
//
// Revision 1.19 2002/08/21 07:00:07 jbravo
// Added CTB respawn queue and fixed game <-> cgame synch problem in CTB
//
// Revision 1.18 2002/07/20 05:06:01 niceass
// scoreboard remembering your team in CTB but lying is fixed
//
// Revision 1.17 2002/07/11 04:29:41 niceass
// removed auto-joining teams for things like ctb
//
// Revision 1.16 2002/06/16 20:06:14 jbravo
// Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap"
//
// Revision 1.15 2002/05/11 15:00:04 jbravo
// Fix for autojoin and a very minir for for Obits
//
// Revision 1.14 2002/05/05 15:51:16 slicer
// Captain and subs get saved on map_restarts ( moved to "sess" )
//
// Revision 1.13 2002/03/30 21:51:42 jbravo
// Removed all those ifdefs for zcam.
//
// Revision 1.12 2002/03/26 11:32:05 jbravo
// Remember specstate between rounds.
//
// Revision 1.11 2002/03/18 17:52:36 slicer
// Saved sess.savedTeam throught map changes for matchmode
//
// Revision 1.10 2002/03/11 18:02:33 slicer
// Fixed team changes and scoreboard bugs
//
// Revision 1.9 2002/02/25 19:41:53 jbravo
// Fixed the use ESC and join menu to join teams when dead players are
// spectating in TP mode.
// Tuned the autorespawn system a bit. Now dead ppl. are dead for a very
// small time before they are made into spectators.
//
// Revision 1.8 2002/02/09 00:10:12 jbravo
// Fixed spectator follow and free and updated zcam to 1.04 and added the
// missing zcam files.
//
// Revision 1.7 2002/02/03 21:23:51 slicer
// More Matchmode code and fixed 2 bugs in TP
//
// Revision 1.5 2002/01/11 19:48:30 jbravo
// Formatted the source in non DOS format.
//
// Revision 1.4 2001/12/31 16:28:42 jbravo
// I made a Booboo with the Log tag.
//
//
//-----------------------------------------------------------------------------
// Copyright (C) 1999-2000 Id Software, Inc.
//
#include "g_local.h"
#include "zcam.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;
//Slicer how about savedTeam ?!
if (!g_RQ3_matchmode.integer && g_gametype.integer >= GT_TEAM) {
//Reset teams on map changes / map_restarts, except on matchmode
client->sess.savedTeam = TEAM_SPECTATOR;
}
s = va("%i %i %i %i %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,
//Adding saved Team
client->sess.savedTeam, client->sess.captain, client->sess.sub,client->sess.referee
//Captain and sub
);
var = va( "session%i", (int)(client - level.clients) );
trap_Cvar_Set(var, s);
camera_state_save(client);
}
/*
================
G_ReadSessionData
Called on a reconnect
================
*/
void G_ReadSessionData(gclient_t * client)
{
char s[MAX_STRING_CHARS];
const char *var;
// bk001205 - format
int teamLeader;
int spectatorState;
int sessionTeam;
//Slicer
int savedTeam;
int captain;
int sub;
int ref;
var = va("session%i", (int)(client - level.clients));
trap_Cvar_VariableStringBuffer(var, s, sizeof(s));
//Slicer: Reading savedTeam also.
sscanf(s, "%i %i %i %i %i %i %i %i %i %i %i", &sessionTeam, // bk010221 - format
&client->sess.spectatorTime, &spectatorState, // bk010221 - format
&client->sess.spectatorClient, &client->sess.wins, &client->sess.losses, &teamLeader, // bk010221 - format
&savedTeam, &captain, &sub, &ref);
// bk001205 - format issues
// Only noticable on non-roundbased games like CTB.
client->sess.sessionTeam = (team_t) sessionTeam;
client->sess.spectatorState = (spectatorState_t) spectatorState;
client->sess.teamLeader = (qboolean) teamLeader;
client->sess.savedTeam = (team_t) savedTeam;
client->sess.captain = (team_t) captain;
client->sess.sub = (team_t) sub;
client->sess.referee = ref;
if (g_gametype.integer == GT_CTF) {
client->sess.sessionTeam = TEAM_SPECTATOR;
client->sess.savedTeam = TEAM_SPECTATOR;
client->sess.captain = TEAM_FREE;
client->sess.sub = TEAM_FREE;
}
camera_state_load(client);
}
/*
================
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;
//Slicer: init savedTeam also
sess->savedTeam = TEAM_SPECTATOR;
//Slicer: init Matchmode stuff
sess->captain = TEAM_FREE;
sess->sub = TEAM_FREE;
sess->referee = 0;
sess->refHear = qfalse;
sess->refReady = 0;
// JBravo: adding PERS_SAVEDTEAM
client->ps.persistant[PERS_SAVEDTEAM] = TEAM_SPECTATOR;
// initial team determination
if (g_gametype.integer >= GT_TEAM) {
if ( g_teamAutoJoin.integer && !(g_entities[ client - level.clients ].r.svFlags & SVF_BOT) ) {
if (g_gametype.integer == GT_TEAMPLAY) {
sess->savedTeam = PickTeam(-1);
client->ps.persistant[PERS_SAVEDTEAM] = sess->savedTeam;
} else if (g_gametype.integer == GT_CTF || g_gametype.integer == GT_TEAM) {
sess->savedTeam = PickTeam(-1);
client->ps.persistant[PERS_SAVEDTEAM] = sess->savedTeam;
sess->sessionTeam = sess->savedTeam;
} else
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;
client->specMode = 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]);
}
}
}