2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
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.
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.
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/>.
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.
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.
26 ===========================================================================
29 #ifndef __MULTIPLAYERGAME_H__
30 #define __MULTIPLAYERGAME_H__
33 ===============================================================================
35 Basic DOOM multiplayer
37 ===============================================================================
63 FLAGSTATUS_INBASE = 0,
76 PLAYER_VOTE_WAIT // mark a player allowed to vote
79 typedef struct mpPlayerState_s {
80 int ping; // player ping
81 int fragCount; // kills
82 int teamFragCount; // team kills
84 playerVote_t vote; // player's vote
85 bool scoreBoardUp; // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui
89 const int NUM_CHAT_NOTIFY = 5;
90 const int CHAT_FADE_TIME = 400;
91 const int FRAGLIMIT_DELAY = 2000;
93 const int MP_PLAYER_MINFRAGS = -100;
95 const int MP_PLAYER_MAXFRAGS = 400; // in CTF frags are player points
97 const int MP_PLAYER_MAXFRAGS = 100;
99 const int MP_PLAYER_MAXWINS = 100;
100 const int MP_PLAYER_MAXPING = 999;
103 const int MP_CTF_MAXPOINTS = 25;
106 typedef struct mpChatLine_s {
108 short fade; // starts high and decreases, line is removed once reached 0
123 SND_FLAG_CAPTURED_YOURS,
124 SND_FLAG_CAPTURED_THEIRS,
126 SND_FLAG_TAKEN_YOURS,
127 SND_FLAG_TAKEN_THEIRS,
128 SND_FLAG_DROPPED_YOURS,
129 SND_FLAG_DROPPED_THEIRS,
134 class idMultiplayerGame {
139 void Shutdown( void );
141 // resets everything and prepares for a match
144 // setup local data for a new player
145 void SpawnPlayer( int clientNum );
147 // checks rules and updates state of the mp game
150 // draws mp hud, scoredboard, etc..
151 bool Draw( int clientNum );
153 // updates a player vote
154 void PlayerVote( int clientNum, playerVote_t vote );
156 // updates frag counts and potentially ends the match in sudden death
157 void PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag );
159 void AddChatLine( const char *fmt, ... ) id_attribute((format(printf,2,3)));
161 void UpdateMainGui( void );
162 idUserInterface*StartMenu( void );
163 const char* HandleGuiCommands( const char *menuCommand );
164 void SetMenuSkin( void );
166 void WriteToSnapshot( idBitMsgDelta &msg ) const;
167 void ReadFromSnapshot( const idBitMsgDelta &msg );
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)
180 static const char *GameStateStrings[ STATE_COUNT ];
181 idMultiplayerGame::gameState_t GetGameState( void ) const;
183 static const char *GlobalSoundStrings[ SND_COUNT ];
184 void PlayGlobalSound( int to, snd_evt_t evt, const char *shader = NULL );
186 void PlayTeamSound( int toTeam, snd_evt_t evt, const char *shader = NULL ); // sound that's sent only to member of toTeam team
189 // more compact than a chat line
218 void PrintMessageEvent( int to, msg_evt_t evt, int parm1 = -1, int parm2 = -1 );
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 );
243 VOTE_PASSED, // passed, but no reset yet
245 VOTE_RESET // tell clients to reset vote state
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 );
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 );
268 void Precache( void );
270 // throttle UI switch rates
271 void ThrottleUserInfo( void );
272 void ToggleSpectate( void );
273 void ToggleReady( void );
274 void ToggleTeam( void );
276 void ClearFrags( int clientNum );
278 void EnterGame( int clientNum );
279 bool CanPlay( idPlayer *p );
280 bool IsInGame( int clientNum );
281 bool WantRespawn( idPlayer *p );
283 void ServerWriteInitialReliableMessages( int clientNum );
284 void ClientReadStartState( const idBitMsg &msg );
285 void ClientReadWarmupTime( const idBitMsg &msg );
287 void ServerClientConnect( int clientNum );
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 );
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
299 void PlayerStats( int clientNum, char *data, const int len );
302 static const char *MPGuis[];
303 static const char *ThrottleVars[];
304 static const char *ThrottleVarsInEnglish[];
305 static const int ThrottleDelay[];
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
312 mpPlayerState_t playerState[ MAX_CLIENTS ];
314 // keep track of clients which are willingly in spectator mode
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 )
325 int kickVoteMap[ MAX_CLIENTS ];
328 int nextStateSwitch; // time next state switch
329 int warmupEndTime; // warmup till..
330 int matchStartedTime; // time current match started
333 int currentTourneyPlayer[2];// our current set of players
334 int lastWinner; // plays again
337 idStr warmupText; // text shown in warmup area of screen
338 bool one, two, three; // keeps count down voice from repeating
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
352 mpChatLine_t chatHistory[ NUM_CHAT_NOTIFY ];
353 int chatHistoryIndex;
354 int chatHistorySize; // 0 <= x < NUM_CHAT_NOTIFY
355 bool chatDataUpdated;
356 int lastChatLineTime;
358 // rankings are used by UpdateScoreboard and UpdateHud
359 int numRankedPlayers; // ranked players, others may be empty slots or spectators
360 idPlayer * rankedPlayers[MAX_CLIENTS];
362 bool pureReady; // defaults to false, set to true once server game is running with pure checksums
363 int fragLimitTimeout;
365 int switchThrottle[ 3 ];
366 int voiceChatThrottle;
368 gameType_t lastGameType; // for restarts
369 int startFragLimit; // synchronize to clients in initial state, set on -> GAMEON
372 idItemTeam * teamFlags[ 2 ];
377 const char * gameTypeVoteMap[ GAME_COUNT ];
381 void UpdatePlayerRanks();
383 // updates the passed gui with current score information
384 void UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec );
385 void UpdateScoreboard( idUserInterface *scoreBoard, idPlayer *player );
387 void UpdateCTFScoreboard( idUserInterface *scoreBoard, idPlayer *player );
391 // We declare this publically above so we can call it during a map restart.
392 void ClearGuis( void );
395 void DrawScoreBoard( idPlayer *player );
396 void UpdateHud( idPlayer *player, idUserInterface *hud );
398 void CheckVote( void );
399 bool AllPlayersReady( void );
400 idPlayer * FragLimitHit( void );
401 idPlayer * FragLeader( void );
402 bool TimeLimitHit( void );
404 bool PointLimitHit( void );
405 // return team with most points
406 int WinningTeam( void );
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 );
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 );
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 );
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 );
437 void FindTeamFlags( void );
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 );
451 void SetBestGametype( const char * map );
452 void ReloadScoreboard();
456 idStr GetBestGametype( const char* map, const char* gametype );
459 /* #ifdef CTF ... merge the below IsGametypeFlagBased */
460 bool IsGametypeFlagBased( void );
461 bool IsGametypeTeamBased( void );
466 ID_INLINE idMultiplayerGame::gameState_t idMultiplayerGame::GetGameState( void ) const {
470 ID_INLINE bool idMultiplayerGame::IsPureReady( void ) const {
474 ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) {
475 playerState[ clientNum ].fragCount = 0;
478 ID_INLINE bool idMultiplayerGame::IsInGame( int clientNum ) {
479 return playerState[ clientNum ].ingame;
482 #endif /* !__MULTIPLAYERGAME_H__ */