MultiplayerGame.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition 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 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. 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.
  18. ===========================================================================
  19. */
  20. #ifndef __MULTIPLAYERGAME_H__
  21. #define __MULTIPLAYERGAME_H__
  22. /*
  23. ===============================================================================
  24. Basic DOOM multiplayer
  25. ===============================================================================
  26. */
  27. class idPlayer;
  28. class idMenuHandler_HUD;
  29. class idMenuHandler_Scoreboard;
  30. class idItemTeam;
  31. enum gameType_t {
  32. GAME_SP = -2,
  33. GAME_RANDOM = -1,
  34. GAME_DM = 0,
  35. GAME_TOURNEY,
  36. GAME_TDM,
  37. GAME_LASTMAN,
  38. GAME_CTF,
  39. GAME_COUNT,
  40. };
  41. // Used by the UI
  42. typedef enum {
  43. FLAGSTATUS_INBASE = 0,
  44. FLAGSTATUS_TAKEN = 1,
  45. FLAGSTATUS_STRAY = 2,
  46. FLAGSTATUS_NONE = 3
  47. } flagStatus_t;
  48. typedef struct mpPlayerState_s {
  49. int ping; // player ping
  50. int fragCount; // kills
  51. int teamFragCount; // team kills
  52. int wins; // wins
  53. bool scoreBoardUp; // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui
  54. int deaths;
  55. } mpPlayerState_t;
  56. const int NUM_CHAT_NOTIFY = 5;
  57. const int CHAT_FADE_TIME = 400;
  58. const int FRAGLIMIT_DELAY = 2000;
  59. const int MP_PLAYER_MINFRAGS = -100;
  60. const int MP_PLAYER_MAXFRAGS = 400; // in CTF frags are player points
  61. const int MP_PLAYER_MAXWINS = 100;
  62. const int MP_PLAYER_MAXPING = 999;
  63. const int MP_CTF_MAXPOINTS = 400;
  64. typedef struct mpChatLine_s {
  65. idStr line;
  66. short fade; // starts high and decreases, line is removed once reached 0
  67. } mpChatLine_t;
  68. typedef enum {
  69. SND_YOUWIN = 0,
  70. SND_YOULOSE,
  71. SND_FIGHT,
  72. SND_THREE,
  73. SND_TWO,
  74. SND_ONE,
  75. SND_SUDDENDEATH,
  76. SND_FLAG_CAPTURED_YOURS,
  77. SND_FLAG_CAPTURED_THEIRS,
  78. SND_FLAG_RETURN,
  79. SND_FLAG_TAKEN_YOURS,
  80. SND_FLAG_TAKEN_THEIRS,
  81. SND_FLAG_DROPPED_YOURS,
  82. SND_FLAG_DROPPED_THEIRS,
  83. SND_COUNT
  84. } snd_evt_t;
  85. class idMultiplayerGame {
  86. public:
  87. idMultiplayerGame();
  88. void Shutdown();
  89. // resets everything and prepares for a match
  90. void Reset();
  91. // setup local data for a new player
  92. void SpawnPlayer( int clientNum );
  93. // checks rules and updates state of the mp game
  94. void Run();
  95. // draws mp hud, scoredboard, etc..
  96. bool Draw( int clientNum );
  97. // updates frag counts and potentially ends the match in sudden death
  98. void PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag );
  99. void AddChatLine( VERIFY_FORMAT_STRING const char *fmt, ... );
  100. void WriteToSnapshot( idBitMsg &msg ) const;
  101. void ReadFromSnapshot( const idBitMsg &msg );
  102. // game state
  103. typedef enum {
  104. INACTIVE = 0, // not running
  105. WARMUP, // warming up
  106. COUNTDOWN, // post warmup pre-game
  107. GAMEON, // game is on
  108. SUDDENDEATH, // game is on but in sudden death, first frag wins
  109. GAMEREVIEW, // game is over, scoreboard is up. we wait si_gameReviewPause seconds (which has a min value)
  110. NEXTGAME,
  111. STATE_COUNT
  112. } gameState_t;
  113. static const char *GameStateStrings[ STATE_COUNT ];
  114. idMultiplayerGame::gameState_t GetGameState() const;
  115. static const char *GlobalSoundStrings[ SND_COUNT ];
  116. void PlayGlobalSound( int toPlayerNum, snd_evt_t evt, const char *shader = NULL );
  117. void PlayTeamSound( int toTeam, snd_evt_t evt, const char *shader = NULL ); // sound that's sent only to member of toTeam team
  118. // more compact than a chat line
  119. typedef enum {
  120. MSG_SUICIDE = 0,
  121. MSG_KILLED,
  122. MSG_KILLEDTEAM,
  123. MSG_DIED,
  124. MSG_SUDDENDEATH,
  125. MSG_JOINEDSPEC,
  126. MSG_TIMELIMIT,
  127. MSG_FRAGLIMIT,
  128. MSG_TELEFRAGGED,
  129. MSG_JOINTEAM,
  130. MSG_HOLYSHIT,
  131. MSG_POINTLIMIT,
  132. MSG_FLAGTAKEN,
  133. MSG_FLAGDROP,
  134. MSG_FLAGRETURN,
  135. MSG_FLAGCAPTURE,
  136. MSG_SCOREUPDATE,
  137. MSG_LEFTGAME,
  138. MSG_COUNT
  139. } msg_evt_t;
  140. void PrintMessageEvent( msg_evt_t evt, int parm1 = -1, int parm2 = -1 );
  141. void DisconnectClient( int clientNum );
  142. static void DropWeapon_f( const idCmdArgs &args );
  143. static void MessageMode_f( const idCmdArgs &args );
  144. static void VoiceChat_f( const idCmdArgs &args );
  145. static void VoiceChatTeam_f( const idCmdArgs &args );
  146. int NumActualClients( bool countSpectators, int *teamcount = NULL );
  147. void DropWeapon( int clientNum );
  148. void MapRestart();
  149. void BalanceTeams();
  150. void SwitchToTeam( int clientNum, int oldteam, int newteam );
  151. bool IsPureReady() const;
  152. void ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound );
  153. void ProcessVoiceChat( int clientNum, bool team, int index );
  154. bool HandleGuiEvent( const sysEvent_t * sev );
  155. bool IsScoreboardActive();
  156. void SetScoreboardActive( bool active );
  157. void CleanupScoreboard();
  158. void Precache();
  159. void ToggleSpectate();
  160. void GetSpectateText( idPlayer * player, idStr spectatetext[ 2 ], bool scoreboard );
  161. void ClearFrags( int clientNum );
  162. bool CanPlay( idPlayer *p );
  163. bool WantRespawn( idPlayer *p );
  164. void ServerWriteInitialReliableMessages( int clientNum, lobbyUserID_t lobbyUserID );
  165. void ClientReadStartState( const idBitMsg &msg );
  166. void ClientReadWarmupTime( const idBitMsg &msg );
  167. void ClientReadMatchStartedTime( const idBitMsg & msg );
  168. void ClientReadAchievementUnlock( const idBitMsg & msg );
  169. void ServerClientConnect( int clientNum );
  170. int GetFlagPoints( int team ); // Team points in CTF
  171. void SetFlagMsg( bool b ); // allow flag event messages to be sent
  172. bool IsFlagMsgOn(); // should flag event messages go through?
  173. int player_red_flag; // Ent num of red flag carrier for HUD
  174. int player_blue_flag; // Ent num of blue flag carrier for HUD
  175. void PlayerStats( int clientNum, char *data, const int len );
  176. private:
  177. static const char * teamNames[];
  178. static const char * skinNames[];
  179. static const idVec3 skinColors[];
  180. static const int numSkins;
  181. // state vars
  182. gameState_t gameState; // what state the current game is in
  183. gameState_t nextState; // state to switch to when nextStateSwitch is hit
  184. mpPlayerState_t playerState[ MAX_CLIENTS ];
  185. // keep track of clients which are willingly in spectator mode
  186. // time related
  187. int nextStateSwitch; // time next state switch
  188. int warmupEndTime; // warmup till..
  189. int matchStartedTime; // time current match started
  190. // tourney
  191. int currentTourneyPlayer[2];// our current set of players
  192. int lastWinner; // plays again
  193. // warmup
  194. bool one, two, three; // keeps count down voice from repeating
  195. // guis
  196. idMenuHandler_Scoreboard * scoreboardManager;
  197. // chat data
  198. mpChatLine_t chatHistory[ NUM_CHAT_NOTIFY ];
  199. int chatHistoryIndex;
  200. int chatHistorySize; // 0 <= x < NUM_CHAT_NOTIFY
  201. bool chatDataUpdated;
  202. int lastChatLineTime;
  203. // rankings are used by UpdateScoreboard and UpdateHud
  204. int numRankedPlayers; // ranked players, others may be empty slots or spectators
  205. idPlayer * rankedPlayers[MAX_CLIENTS];
  206. bool pureReady; // defaults to false, set to true once server game is running with pure checksums
  207. int fragLimitTimeout;
  208. int voiceChatThrottle;
  209. int startFragLimit; // synchronize to clients in initial state, set on -> GAMEON
  210. idItemTeam * teamFlags[ 2 ];
  211. int teamPoints[ 2 ];
  212. bool flagMsgOn;
  213. private:
  214. void UpdatePlayerRanks();
  215. void GameHasBeenWon();
  216. // updates the passed gui with current score information
  217. void UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec );
  218. void UpdateScoreboard( idMenuHandler_Scoreboard * scoreboard, idPlayer *owner );
  219. void DrawScoreBoard( idPlayer *player );
  220. void UpdateHud( idPlayer *player, idMenuHandler_HUD * hudManager );
  221. bool Warmup();
  222. idPlayer * FragLimitHit();
  223. idPlayer * FragLeader();
  224. bool TimeLimitHit();
  225. bool PointLimitHit();
  226. // return team with most points
  227. int WinningTeam();
  228. void NewState( gameState_t news, idPlayer *player = NULL );
  229. void UpdateWinsLosses( idPlayer *winner );
  230. // fill any empty tourney slots based on the current tourney ranks
  231. void FillTourneySlots();
  232. void CycleTourneyPlayers();
  233. // walk through the tourneyRank to build a wait list for the clients
  234. void UpdateTourneyLine();
  235. const char * GameTime();
  236. void Clear();
  237. bool EnoughClientsToPlay();
  238. void ClearChatData();
  239. void DrawChat( idPlayer * player );
  240. // go through the clients, and see if they want to be respawned, and if the game allows it
  241. // called during normal gameplay for death -> respawn cycles
  242. // and for a spectator who want back in the game (see param)
  243. void CheckRespawns( idPlayer *spectator = NULL );
  244. // when clients disconnect or join spectate during game, check if we need to end the game
  245. void CheckAbortGame();
  246. void MessageMode( const idCmdArgs &args );
  247. // scores in TDM
  248. void TeamScore( int entityNumber, int team, int delta );
  249. void VoiceChat( const idCmdArgs &args, bool team );
  250. void DumpTourneyLine();
  251. void SuddenRespawn();
  252. void FindTeamFlags();
  253. void NewState_Warmup_ServerAndClient();
  254. void NewState_Countdown_ServerAndClient();
  255. void NewState_GameOn_ServerAndClient();
  256. void NewState_GameReview_ServerAndClient();
  257. public:
  258. const char * GetTeamName( int team ) const;
  259. const char * GetSkinName( int skin ) const;
  260. const idVec3 & GetSkinColor( int skin ) const;
  261. idItemTeam * GetTeamFlag( int team );
  262. flagStatus_t GetFlagStatus( int team );
  263. void TeamScoreCTF( int team, int delta );
  264. void PlayerScoreCTF( int playerIdx, int delta );
  265. // returns entityNum to team flag carrier, -1 if no flag carrier
  266. int GetFlagCarrier( int team );
  267. void UpdateScoreboardFlagStatus();
  268. void ReloadScoreboard();
  269. int GetGameModes( const char *** gameModes, const char *** gameModesDisplay );
  270. bool IsGametypeFlagBased();
  271. bool IsGametypeTeamBased();
  272. };
  273. ID_INLINE idMultiplayerGame::gameState_t idMultiplayerGame::GetGameState() const {
  274. return gameState;
  275. }
  276. ID_INLINE bool idMultiplayerGame::IsPureReady() const {
  277. return pureReady;
  278. }
  279. ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) {
  280. playerState[ clientNum ].fragCount = 0;
  281. }
  282. #endif /* !__MULTIPLAYERGAME_H__ */