mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2024-11-13 00:24:29 +00:00
303 lines
7.8 KiB
C
303 lines
7.8 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 ?!
|
|
|
|
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;
|
|
if (!(g_entities[(int)(client-level.clients)].r.svFlags & SVF_BOT)) {
|
|
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;
|
|
|
|
// check for team preference, mainly for bots
|
|
value = Info_ValueForKey( userinfo, "teampref" );
|
|
|
|
// check for human's team preference set by start server menu
|
|
if ( !value[0] && g_localTeamPref.string[0] && client->pers.localClient ) {
|
|
value = g_localTeamPref.string;
|
|
|
|
// clear team so it's only used once
|
|
trap_Cvar_Set( "g_localTeamPref", "" );
|
|
}
|
|
|
|
// initial team determination
|
|
if (g_gametype.integer >= GT_TEAM) {
|
|
// always spawn as spectator in team games
|
|
sess->sessionTeam = TEAM_SPECTATOR;
|
|
sess->spectatorState = SPECTATOR_FREE;
|
|
client->specMode = SPECTATOR_FREE;
|
|
sess->spectatorTime = level.time;
|
|
|
|
if (value[0] || g_teamAutoJoin.integer) {
|
|
SetTeam(&g_entities[client - level.clients], value[0] ? value : "auto");
|
|
}
|
|
} else {
|
|
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) {
|
|
if (!g_RQ3_matchmode.integer && g_gametype.integer >= GT_TEAM && !(g_entities[i].r.svFlags & SVF_BOT)) {
|
|
//Slicer: reset teams on map changes / map_restarts, except on matchmode
|
|
level.clients[i].sess.savedTeam = TEAM_SPECTATOR;
|
|
}
|
|
|
|
G_WriteClientSessionData(&level.clients[i]);
|
|
}
|
|
}
|
|
}
|