doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MultiplayerGame.h
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 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 Doom 3 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 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 Doom 3 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 #ifndef __MULTIPLAYERGAME_H__
30 #define __MULTIPLAYERGAME_H__
31 
32 /*
33 ===============================================================================
34 
35  Basic DOOM multiplayer
36 
37 ===============================================================================
38 */
39 
40 class idPlayer;
41 
42 #ifdef CTF
43 class idItemTeam;
44 #endif
45 
46 
47 typedef enum {
48  GAME_SP = 0,
53 #ifdef CTF
54  GAME_CTF,
55  GAME_COUNT,
56 #endif
57 } gameType_t;
58 
59 #ifdef CTF
60 
61 // Used by the UI
62 typedef enum {
63  FLAGSTATUS_INBASE = 0,
64  FLAGSTATUS_TAKEN = 1,
65  FLAGSTATUS_STRAY = 2,
66  FLAGSTATUS_NONE = 3
67 } flagStatus_t;
68 
69 #endif
70 
71 
72 typedef enum {
76  PLAYER_VOTE_WAIT // mark a player allowed to vote
77 } playerVote_t;
78 
79 typedef struct mpPlayerState_s {
80  int ping; // player ping
81  int fragCount; // kills
82  int teamFragCount; // team kills
83  int wins; // wins
84  playerVote_t vote; // player's vote
85  bool scoreBoardUp; // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui
86  bool ingame;
88 
89 const int NUM_CHAT_NOTIFY = 5;
90 const int CHAT_FADE_TIME = 400;
91 const int FRAGLIMIT_DELAY = 2000;
92 
93 const int MP_PLAYER_MINFRAGS = -100;
94 #ifdef CTF
95 const int MP_PLAYER_MAXFRAGS = 400; // in CTF frags are player points
96 #else
97 const int MP_PLAYER_MAXFRAGS = 100;
98 #endif
99 const int MP_PLAYER_MAXWINS = 100;
100 const int MP_PLAYER_MAXPING = 999;
101 
102 #ifdef CTF
103 const int MP_CTF_MAXPOINTS = 25;
104 #endif
105 
106 typedef struct mpChatLine_s {
108  short fade; // starts high and decreases, line is removed once reached 0
109 } mpChatLine_t;
110 
111 typedef enum {
122 #ifdef CTF
123  SND_FLAG_CAPTURED_YOURS,
124  SND_FLAG_CAPTURED_THEIRS,
125  SND_FLAG_RETURN,
126  SND_FLAG_TAKEN_YOURS,
127  SND_FLAG_TAKEN_THEIRS,
128  SND_FLAG_DROPPED_YOURS,
129  SND_FLAG_DROPPED_THEIRS,
130 #endif
132 } snd_evt_t;
133 
135 public:
136 
138 
139  void Shutdown( void );
140 
141  // resets everything and prepares for a match
142  void Reset( void );
143 
144  // setup local data for a new player
145  void SpawnPlayer( int clientNum );
146 
147  // checks rules and updates state of the mp game
148  void Run( void );
149 
150  // draws mp hud, scoredboard, etc..
151  bool Draw( int clientNum );
152 
153  // updates a player vote
154  void PlayerVote( int clientNum, playerVote_t vote );
155 
156  // updates frag counts and potentially ends the match in sudden death
157  void PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag );
158 
159  void AddChatLine( const char *fmt, ... ) id_attribute((format(printf,2,3)));
160 
161  void UpdateMainGui( void );
162  idUserInterface*StartMenu( void );
163  const char* HandleGuiCommands( const char *menuCommand );
164  void SetMenuSkin( void );
165 
166  void WriteToSnapshot( idBitMsgDelta &msg ) const;
167  void ReadFromSnapshot( const idBitMsgDelta &msg );
168 
169  // game state
170  typedef enum {
171  INACTIVE = 0, // not running
172  WARMUP, // warming up
173  COUNTDOWN, // post warmup pre-game
174  GAMEON, // game is on
175  SUDDENDEATH, // game is on but in sudden death, first frag wins
176  GAMEREVIEW, // game is over, scoreboard is up. we wait si_gameReviewPause seconds (which has a min value)
179  } gameState_t;
180  static const char *GameStateStrings[ STATE_COUNT ];
182 
183  static const char *GlobalSoundStrings[ SND_COUNT ];
184  void PlayGlobalSound( int to, snd_evt_t evt, const char *shader = NULL );
185 #ifdef CTF
186  void PlayTeamSound( int toTeam, snd_evt_t evt, const char *shader = NULL ); // sound that's sent only to member of toTeam team
187 #endif
188 
189  // more compact than a chat line
190  typedef enum {
206 #ifdef CTF
207  MSG_POINTLIMIT,
208 
209  MSG_FLAGTAKEN,
210  MSG_FLAGDROP,
211  MSG_FLAGRETURN,
212  MSG_FLAGCAPTURE,
213  MSG_SCOREUPDATE,
214 
215 #endif
217  } msg_evt_t;
218  void PrintMessageEvent( int to, msg_evt_t evt, int parm1 = -1, int parm2 = -1 );
219 
220  void DisconnectClient( int clientNum );
221  static void ForceReady_f( const idCmdArgs &args );
222  static void DropWeapon_f( const idCmdArgs &args );
223  static void MessageMode_f( const idCmdArgs &args );
224  static void VoiceChat_f( const idCmdArgs &args );
225  static void VoiceChatTeam_f( const idCmdArgs &args );
226 
227  typedef enum {
238  } vote_flags_t;
239 
240  typedef enum {
243  VOTE_PASSED, // passed, but no reset yet
245  VOTE_RESET // tell clients to reset vote state
246  } vote_result_t;
247 
248  static void Vote_f( const idCmdArgs &args );
249  static void CallVote_f( const idCmdArgs &args );
250  void ClientCallVote( vote_flags_t voteIndex, const char *voteValue );
251  void ServerCallVote( int clientNum, const idBitMsg &msg );
252  void ClientStartVote( int clientNum, const char *voteString );
253  void ServerStartVote( int clientNum, vote_flags_t voteIndex, const char *voteValue );
254  void ClientUpdateVote( vote_result_t result, int yesCount, int noCount );
255  void CastVote( int clientNum, bool vote );
256  void ExecuteVote( void );
257 
258  void WantKilled( int clientNum );
259  int NumActualClients( bool countSpectators, int *teamcount = NULL );
260  void DropWeapon( int clientNum );
261  void MapRestart( void );
262  // called by idPlayer whenever it detects a team change (init or switch)
263  void SwitchToTeam( int clientNum, int oldteam, int newteam );
264  bool IsPureReady( void ) const;
265  void ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound );
266  void ProcessVoiceChat( int clientNum, bool team, int index );
267 
268  void Precache( void );
269 
270  // throttle UI switch rates
271  void ThrottleUserInfo( void );
272  void ToggleSpectate( void );
273  void ToggleReady( void );
274  void ToggleTeam( void );
275 
276  void ClearFrags( int clientNum );
277 
278  void EnterGame( int clientNum );
279  bool CanPlay( idPlayer *p );
280  bool IsInGame( int clientNum );
281  bool WantRespawn( idPlayer *p );
282 
283  void ServerWriteInitialReliableMessages( int clientNum );
284  void ClientReadStartState( const idBitMsg &msg );
285  void ClientReadWarmupTime( const idBitMsg &msg );
286 
287  void ServerClientConnect( int clientNum );
288 #ifdef CTF
289  void ClearHUDStatus( void );
290  int GetFlagPoints( int team ); // Team points in CTF
291  void SetFlagMsg( bool b ); // allow flag event messages to be sent
292  bool IsFlagMsgOn( void ); // should flag event messages go through?
293  void ClearGuis( void );
294 
295  int player_red_flag; // Ent num of red flag carrier for HUD
296  int player_blue_flag; // Ent num of blue flag carrier for HUD
297 
298 #endif
299  void PlayerStats( int clientNum, char *data, const int len );
300 
301 private:
302  static const char *MPGuis[];
303  static const char *ThrottleVars[];
304  static const char *ThrottleVarsInEnglish[];
305  static const int ThrottleDelay[];
306 
307  // state vars
308  gameState_t gameState; // what state the current game is in
309  gameState_t nextState; // state to switch to when nextStateSwitch is hit
310  int pingUpdateTime; // time to update ping
311 
313 
314  // keep track of clients which are willingly in spectator mode
315 
316  // vote vars
317  vote_flags_t vote; // active vote or VOTE_NONE
318  int voteTimeOut; // when the current vote expires
319  int voteExecTime; // delay between vote passed msg and execute
320  float yesVotes; // counter for yes votes
321  float noVotes; // and for no votes
322  idStr voteValue; // the data voted upon ( server )
323  idStr voteString; // the vote string ( client )
324  bool voted; // hide vote box ( client )
326 
327  // time related
328  int nextStateSwitch; // time next state switch
329  int warmupEndTime; // warmup till..
330  int matchStartedTime; // time current match started
331 
332  // tourney
333  int currentTourneyPlayer[2];// our current set of players
334  int lastWinner; // plays again
335 
336  // warmup
337  idStr warmupText; // text shown in warmup area of screen
338  bool one, two, three; // keeps count down voice from repeating
339 
340  // guis
341  idUserInterface *scoreBoard; // scoreboard
342  idUserInterface *spectateGui; // spectate info
343  idUserInterface *guiChat; // chat text
344  idUserInterface *mainGui; // ready / nick / votes etc.
346  idUserInterface *msgmodeGui; // message mode
347  int currentMenu; // 0 - none, 1 - mainGui, 2 - msgmodeGui
348  int nextMenu; // if 0, will do mainGui
349  bool bCurrentMenuMsg; // send menu state updates to server
350 
351  // chat data
354  int chatHistorySize; // 0 <= x < NUM_CHAT_NOTIFY
357 
358  // rankings are used by UpdateScoreboard and UpdateHud
359  int numRankedPlayers; // ranked players, others may be empty slots or spectators
361 
362  bool pureReady; // defaults to false, set to true once server game is running with pure checksums
364 
365  int switchThrottle[ 3 ];
367 
368  gameType_t lastGameType; // for restarts
369  int startFragLimit; // synchronize to clients in initial state, set on -> GAMEON
370 
371 #ifdef CTF
372  idItemTeam * teamFlags[ 2 ];
373  int teamPoints[ 2 ];
374 
375  bool flagMsgOn;
376 
377  const char * gameTypeVoteMap[ GAME_COUNT ];
378 #endif
379 
380 private:
381  void UpdatePlayerRanks();
382 
383  // updates the passed gui with current score information
384  void UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec );
386 #ifdef CTF
387  void UpdateCTFScoreboard( idUserInterface *scoreBoard, idPlayer *player );
388 #endif
389 
390 #ifndef CTF
391  // We declare this publically above so we can call it during a map restart.
392  void ClearGuis( void );
393 #endif
394 
395  void DrawScoreBoard( idPlayer *player );
396  void UpdateHud( idPlayer *player, idUserInterface *hud );
397  bool Warmup( void );
398  void CheckVote( void );
399  bool AllPlayersReady( void );
400  idPlayer * FragLimitHit( void );
401  idPlayer * FragLeader( void );
402  bool TimeLimitHit( void );
403 #ifdef CTF
404  bool PointLimitHit( void );
405  // return team with most points
406  int WinningTeam( void );
407 #endif
408  void NewState( gameState_t news, idPlayer *player = NULL );
409  void UpdateWinsLosses( idPlayer *winner );
410  // fill any empty tourney slots based on the current tourney ranks
411  void FillTourneySlots( void );
412  void CycleTourneyPlayers( void );
413  // walk through the tourneyRank to build a wait list for the clients
414  void UpdateTourneyLine( void );
415  const char * GameTime( void );
416  void Clear( void );
417  bool EnoughClientsToPlay( void );
418  void ClearChatData( void );
419  void DrawChat( void );
420  // go through the clients, and see if they want to be respawned, and if the game allows it
421  // called during normal gameplay for death -> respawn cycles
422  // and for a spectator who want back in the game (see param)
423  void CheckRespawns( idPlayer *spectator = NULL );
424  void ForceReady();
425  // when clients disconnect or join spectate during game, check if we need to end the game
426  void CheckAbortGame( void );
427  void MessageMode( const idCmdArgs &args );
428  void DisableMenu( void );
429  void SetMapShot( void );
430  // scores in TDM
431  void TeamScore( int entityNumber, int team, int delta );
432  void VoiceChat( const idCmdArgs &args, bool team );
433  void DumpTourneyLine( void );
434  void SuddenRespawn( void );
435 
436 #ifdef CTF
437  void FindTeamFlags( void );
438 #endif
439 
440 public:
441 
442 #ifdef CTF
443  idItemTeam * GetTeamFlag( int team );
444  flagStatus_t GetFlagStatus( int team );
445  void TeamScoreCTF( int team, int delta );
446  void PlayerScoreCTF( int playerIdx, int delta );
447  // returns entityNum to team flag carrier, -1 if no flag carrier
448  int GetFlagCarrier( int team );
449  void UpdateScoreboardFlagStatus( void );
450 
451  void SetBestGametype( const char * map );
452  void ReloadScoreboard();
453 #endif
454 
455 #ifdef _D3XP
456  idStr GetBestGametype( const char* map, const char* gametype );
457 #endif
458 
459 /* #ifdef CTF ... merge the below IsGametypeFlagBased */
460 bool IsGametypeFlagBased( void );
461 bool IsGametypeTeamBased( void );
462 /* #endif CTF */
463 
464 };
465 
467  return gameState;
468 }
469 
470 ID_INLINE bool idMultiplayerGame::IsPureReady( void ) const {
471  return pureReady;
472 }
473 
474 ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) {
475  playerState[ clientNum ].fragCount = 0;
476 }
477 
478 ID_INLINE bool idMultiplayerGame::IsInGame( int clientNum ) {
479  return playerState[ clientNum ].ingame;
480 }
481 
482 #endif /* !__MULTIPLAYERGAME_H__ */
483 
void DrawScoreBoard(idPlayer *player)
void VoiceChat(const idCmdArgs &args, bool team)
gameType_t
bool IsGametypeTeamBased(void)
void ClientReadWarmupTime(const idBitMsg &msg)
void ProcessVoiceChat(int clientNum, bool team, int index)
idUserInterface * scoreBoard
idUserInterface * mainGui
const char * HandleGuiCommands(const char *menuCommand)
idPlayer * FragLimitHit(void)
void PlayerStats(int clientNum, char *data, const int len)
GLenum GLint GLuint mask
Definition: glext.h:5864
GLenum GLsizei GLenum format
Definition: glext.h:2846
static void MessageMode_f(const idCmdArgs &args)
const int MP_PLAYER_MINFRAGS
void UpdateScoreboard(idUserInterface *scoreBoard, idPlayer *player)
void PlayGlobalSound(int to, snd_evt_t evt, const char *shader=NULL)
const int NUM_CHAT_NOTIFY
void ClientCallVote(vote_flags_t voteIndex, const char *voteValue)
void UpdateRankColor(idUserInterface *gui, const char *mask, int i, const idVec3 &vec)
void SwitchToTeam(int clientNum, int oldteam, int newteam)
void EnterGame(int clientNum)
void SpawnPlayer(int clientNum)
void WantKilled(int clientNum)
static const char * MPGuis[]
void PrintMessageEvent(int to, msg_evt_t evt, int parm1=-1, int parm2=-1)
static const char * GameStateStrings[STATE_COUNT]
gameState_t gameState
Definition: Vector.h:316
bool EnoughClientsToPlay(void)
void CheckRespawns(idPlayer *spectator=NULL)
const int MP_PLAYER_MAXPING
snd_evt_t
GLenum GLsizei len
Definition: glext.h:3472
void ClientUpdateVote(vote_result_t result, int yesCount, int noCount)
void ServerStartVote(int clientNum, vote_flags_t voteIndex, const char *voteValue)
int i
Definition: process.py:33
struct mpChatLine_s mpChatLine_t
Boolean result
idMultiplayerGame::gameState_t GetGameState(void) const
void PlayerDeath(idPlayer *dead, idPlayer *killer, bool telefrag)
void UpdateTourneyLine(void)
void NewState(gameState_t news, idPlayer *player=NULL)
void ClientReadStartState(const idBitMsg &msg)
idPlayer * FragLeader(void)
static const char * ThrottleVarsInEnglish[]
mpPlayerState_t playerState[MAX_CLIENTS]
bool IsInGame(int clientNum)
GLuint index
Definition: glext.h:3476
void AddChatLine(const char *fmt,...) id_attribute((format(printf
static void CallVote_f(const idCmdArgs &args)
void CastVote(int clientNum, bool vote)
bool IsPureReady(void) const
mpChatLine_t chatHistory[NUM_CHAT_NOTIFY]
#define MAX_CLIENTS
Definition: Game_local.h:81
#define NULL
Definition: Lib.h:88
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
void void UpdateMainGui(void)
static void VoiceChatTeam_f(const idCmdArgs &args)
bool CanPlay(idPlayer *p)
idUserInterface * StartMenu(void)
idPlayer * rankedPlayers[MAX_CLIENTS]
void PlayerVote(int clientNum, playerVote_t vote)
idUserInterface * guiChat
void TeamScore(int entityNumber, int team, int delta)
gameType_t lastGameType
static const int ThrottleDelay[]
void ServerWriteInitialReliableMessages(int clientNum)
bool WantRespawn(idPlayer *p)
void ClientStartVote(int clientNum, const char *voteString)
const int MP_PLAYER_MAXFRAGS
void MessageMode(const idCmdArgs &args)
idUserInterface * msgmodeGui
void WriteToSnapshot(idBitMsgDelta &msg) const
GLubyte GLubyte b
Definition: glext.h:4662
playerVote_t
static const char * ThrottleVars[]
const char * GameTime(void)
#define id_attribute(x)
Definition: sys_public.h:139
void ProcessChatMessage(int clientNum, bool team, const char *name, const char *text, const char *sound)
static const char * GlobalSoundStrings[SND_COUNT]
gameState_t nextState
idUserInterface * spectateGui
bool IsGametypeFlagBased(void)
const GLcharARB * name
Definition: glext.h:3629
static void Vote_f(const idCmdArgs &args)
const int CHAT_FADE_TIME
Definition: Str.h:116
const int MP_PLAYER_MAXWINS
static void ForceReady_f(const idCmdArgs &args)
static void DropWeapon_f(const idCmdArgs &args)
bool AllPlayersReady(void)
void DropWeapon(int clientNum)
void ReadFromSnapshot(const idBitMsgDelta &msg)
void UpdateWinsLosses(idPlayer *winner)
playerVote_t vote
int NumActualClients(bool countSpectators, int *teamcount=NULL)
GLfloat GLfloat p
Definition: glext.h:4674
bool Draw(int clientNum)
struct mpPlayerState_s mpPlayerState_t
void ClearFrags(int clientNum)
void ServerClientConnect(int clientNum)
void ServerCallVote(int clientNum, const idBitMsg &msg)
void CycleTourneyPlayers(void)
const int FRAGLIMIT_DELAY
void UpdateHud(idPlayer *player, idUserInterface *hud)
void DisconnectClient(int clientNum)
static void VoiceChat_f(const idCmdArgs &args)
int kickVoteMap[MAX_CLIENTS]