]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/game/MultiplayerGame.h
hello world
[icculus/iodoom3.git] / neo / game / MultiplayerGame.h
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 typedef enum {
43         GAME_SP,
44         GAME_DM,
45         GAME_TOURNEY,
46         GAME_TDM,
47         GAME_LASTMAN
48 } gameType_t;
49
50 typedef enum {
51                 PLAYER_VOTE_NONE,
52                 PLAYER_VOTE_NO,
53                 PLAYER_VOTE_YES,
54                 PLAYER_VOTE_WAIT        // mark a player allowed to vote
55 } playerVote_t;
56
57 typedef struct mpPlayerState_s {
58         int                             ping;                   // player ping
59         int                             fragCount;              // kills
60         int                             teamFragCount;  // team kills
61         int                             wins;                   // wins
62         playerVote_t    vote;                   // player's vote
63         bool                    scoreBoardUp;   // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui
64         bool                    ingame;
65 } mpPlayerState_t;
66
67 const int NUM_CHAT_NOTIFY       = 5;
68 const int CHAT_FADE_TIME        = 400;
69 const int FRAGLIMIT_DELAY       = 2000;
70
71 const int MP_PLAYER_MINFRAGS = -100;
72 const int MP_PLAYER_MAXFRAGS = 100;
73 const int MP_PLAYER_MAXWINS     = 100;
74 const int MP_PLAYER_MAXPING     = 999;
75
76 typedef struct mpChatLine_s {
77         idStr                   line;
78         short                   fade;                   // starts high and decreases, line is removed once reached 0
79 } mpChatLine_t;
80
81 typedef enum {
82         SND_YOUWIN = 0,
83         SND_YOULOSE,
84         SND_FIGHT,
85         SND_VOTE,
86         SND_VOTE_PASSED,
87         SND_VOTE_FAILED,
88         SND_THREE,
89         SND_TWO,
90         SND_ONE,
91         SND_SUDDENDEATH,
92         SND_COUNT
93 } snd_evt_t;
94
95 class idMultiplayerGame {
96 public:
97
98                                         idMultiplayerGame();
99
100         void                    Shutdown( void );
101
102         // resets everything and prepares for a match
103         void                    Reset( void );
104
105         // setup local data for a new player
106         void                    SpawnPlayer( int clientNum );
107
108         // checks rules and updates state of the mp game
109         void                    Run( void );
110
111         // draws mp hud, scoredboard, etc.. 
112         bool                    Draw( int clientNum );
113
114         // updates a player vote
115         void                    PlayerVote( int clientNum, playerVote_t vote );
116
117         // updates frag counts and potentially ends the match in sudden death
118         void                    PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag );
119
120         void                    AddChatLine( const char *fmt, ... ) id_attribute((format(printf,2,3)));
121
122         void                    UpdateMainGui( void );
123         idUserInterface*StartMenu( void );
124         const char*             HandleGuiCommands( const char *menuCommand );
125         void                    SetMenuSkin( void );
126
127         void                    WriteToSnapshot( idBitMsgDelta &msg ) const;
128         void                    ReadFromSnapshot( const idBitMsgDelta &msg );
129
130         // game state
131         typedef enum {
132                 INACTIVE = 0,                                           // not running
133                 WARMUP,                                                         // warming up
134                 COUNTDOWN,                                                      // post warmup pre-game
135                 GAMEON,                                                         // game is on
136                 SUDDENDEATH,                                            // game is on but in sudden death, first frag wins
137                 GAMEREVIEW,                                                     // game is over, scoreboard is up. we wait si_gameReviewPause seconds (which has a min value)
138                 NEXTGAME,
139                 STATE_COUNT
140         } gameState_t;
141         static const char *GameStateStrings[ STATE_COUNT ];
142         idMultiplayerGame::gameState_t          GetGameState( void ) const;
143
144         static const char *GlobalSoundStrings[ SND_COUNT ];
145         void                    PlayGlobalSound( int to, snd_evt_t evt, const char *shader = NULL );
146
147         // more compact than a chat line
148         typedef enum {
149                 MSG_SUICIDE = 0,
150                 MSG_KILLED,
151                 MSG_KILLEDTEAM,
152                 MSG_DIED,
153                 MSG_VOTE,
154                 MSG_VOTEPASSED,
155                 MSG_VOTEFAILED,
156                 MSG_SUDDENDEATH,
157                 MSG_FORCEREADY,
158                 MSG_JOINEDSPEC,
159                 MSG_TIMELIMIT,
160                 MSG_FRAGLIMIT,
161                 MSG_TELEFRAGGED,
162                 MSG_JOINTEAM,
163                 MSG_HOLYSHIT,
164                 MSG_COUNT
165         } msg_evt_t;
166         void                    PrintMessageEvent( int to, msg_evt_t evt, int parm1 = -1, int parm2 = -1 );
167
168         void                    DisconnectClient( int clientNum );
169         static void             ForceReady_f( const idCmdArgs &args );
170         static void             DropWeapon_f( const idCmdArgs &args );
171         static void             MessageMode_f( const idCmdArgs &args );
172         static void             VoiceChat_f( const idCmdArgs &args );
173         static void             VoiceChatTeam_f( const idCmdArgs &args );
174
175         typedef enum {
176                 VOTE_RESTART = 0,
177                 VOTE_TIMELIMIT,
178                 VOTE_FRAGLIMIT,
179                 VOTE_GAMETYPE,
180                 VOTE_KICK,
181                 VOTE_MAP,
182                 VOTE_SPECTATORS,
183                 VOTE_NEXTMAP,
184                 VOTE_COUNT,
185                 VOTE_NONE
186         } vote_flags_t;
187
188         typedef enum {
189                 VOTE_UPDATE,
190                 VOTE_FAILED,
191                 VOTE_PASSED,    // passed, but no reset yet
192                 VOTE_ABORTED,
193                 VOTE_RESET              // tell clients to reset vote state
194         } vote_result_t;
195
196         static void             Vote_f( const idCmdArgs &args );
197         static void             CallVote_f( const idCmdArgs &args );
198         void                    ClientCallVote( vote_flags_t voteIndex, const char *voteValue );
199         void                    ServerCallVote( int clientNum, const idBitMsg &msg );
200         void                    ClientStartVote( int clientNum, const char *voteString );
201         void                    ServerStartVote( int clientNum, vote_flags_t voteIndex, const char *voteValue );
202         void                    ClientUpdateVote( vote_result_t result, int yesCount, int noCount );
203         void                    CastVote( int clientNum, bool vote );
204         void                    ExecuteVote( void );
205
206         void                    WantKilled( int clientNum );
207         int                             NumActualClients( bool countSpectators, int *teamcount = NULL );
208         void                    DropWeapon( int clientNum );
209         void                    MapRestart( void );
210         // called by idPlayer whenever it detects a team change (init or switch)
211         void                    SwitchToTeam( int clientNum, int oldteam, int newteam );
212         bool                    IsPureReady( void ) const;
213         void                    ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound );
214         void                    ProcessVoiceChat( int clientNum, bool team, int index );
215
216         void                    Precache( void );
217         
218         // throttle UI switch rates
219         void                    ThrottleUserInfo( void );
220         void                    ToggleSpectate( void );
221         void                    ToggleReady( void );
222         void                    ToggleTeam( void );
223
224         void                    ClearFrags( int clientNum );
225
226         void                    EnterGame( int clientNum );
227         bool                    CanPlay( idPlayer *p );
228         bool                    IsInGame( int clientNum );
229         bool                    WantRespawn( idPlayer *p );
230
231         void                    ServerWriteInitialReliableMessages( int clientNum );
232         void                    ClientReadStartState( const idBitMsg &msg );
233         void                    ClientReadWarmupTime( const idBitMsg &msg );
234
235         void                    ServerClientConnect( int clientNum );
236
237         void                    PlayerStats( int clientNum, char *data, const int len );
238
239 private:
240         static const char       *MPGuis[];
241         static const char       *ThrottleVars[];
242         static const char       *ThrottleVarsInEnglish[];
243         static const int        ThrottleDelay[];
244
245         // state vars
246         gameState_t             gameState;                              // what state the current game is in
247         gameState_t             nextState;                              // state to switch to when nextStateSwitch is hit
248         int                             pingUpdateTime;                 // time to update ping
249
250         mpPlayerState_t playerState[ MAX_CLIENTS ];
251
252                                                                                         // keep track of clients which are willingly in spectator mode
253
254         // vote vars
255         vote_flags_t    vote;                                   // active vote or VOTE_NONE
256         int                             voteTimeOut;                    // when the current vote expires
257         int                             voteExecTime;                   // delay between vote passed msg and execute
258         float                   yesVotes;                               // counter for yes votes
259         float                   noVotes;                                // and for no votes
260         idStr                   voteValue;                              // the data voted upon ( server )
261         idStr                   voteString;                             // the vote string ( client )
262         bool                    voted;                                  // hide vote box ( client )
263         int                             kickVoteMap[ MAX_CLIENTS ];
264
265         // time related
266         int                             nextStateSwitch;                // time next state switch
267         int                             warmupEndTime;                  // warmup till..
268         int                             matchStartedTime;               // time current match started
269
270         // tourney
271         int                             currentTourneyPlayer[2];// our current set of players
272         int                             lastWinner;                             // plays again
273
274         // warmup
275         idStr                   warmupText;                             // text shown in warmup area of screen
276         bool                    one, two, three;                // keeps count down voice from repeating
277
278         // guis
279         idUserInterface *scoreBoard;                    // scoreboard
280         idUserInterface *spectateGui;                   // spectate info
281         idUserInterface *guiChat;                               // chat text
282         idUserInterface *mainGui;                               // ready / nick / votes etc.
283         idListGUI               *mapList;
284         idUserInterface *msgmodeGui;                    // message mode
285         int                             currentMenu;                    // 0 - none, 1 - mainGui, 2 - msgmodeGui
286         int                             nextMenu;                               // if 0, will do mainGui
287         bool                    bCurrentMenuMsg;                // send menu state updates to server
288
289         // chat data
290         mpChatLine_t    chatHistory[ NUM_CHAT_NOTIFY ];
291         int                             chatHistoryIndex;
292         int                             chatHistorySize;                // 0 <= x < NUM_CHAT_NOTIFY
293         bool                    chatDataUpdated;
294         int                             lastChatLineTime;
295
296         // rankings are used by UpdateScoreboard and UpdateHud
297         int                             numRankedPlayers;               // ranked players, others may be empty slots or spectators
298         idPlayer *              rankedPlayers[MAX_CLIENTS];
299
300         bool                    pureReady;                              // defaults to false, set to true once server game is running with pure checksums
301         int                             fragLimitTimeout;
302
303         int                             switchThrottle[ 3 ];
304         int                             voiceChatThrottle;
305
306         gameType_t              lastGameType;                   // for restarts
307         int                             startFragLimit;                 // synchronize to clients in initial state, set on -> GAMEON
308
309 private:
310         void                    UpdatePlayerRanks();
311
312         // updates the passed gui with current score information
313         void                    UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec );
314         void                    UpdateScoreboard( idUserInterface *scoreBoard, idPlayer *player );
315         
316         void                    ClearGuis( void );
317         void                    DrawScoreBoard( idPlayer *player );
318         void                    UpdateHud( idPlayer *player, idUserInterface *hud );
319         bool                    Warmup( void );
320         void                    CheckVote( void );
321         bool                    AllPlayersReady( void );
322         idPlayer *              FragLimitHit( void );
323         idPlayer *              FragLeader( void );
324         bool                    TimeLimitHit( void );
325         void                    NewState( gameState_t news, idPlayer *player = NULL );
326         void                    UpdateWinsLosses( idPlayer *winner );
327         // fill any empty tourney slots based on the current tourney ranks
328         void                    FillTourneySlots( void );
329         void                    CycleTourneyPlayers( void );
330         // walk through the tourneyRank to build a wait list for the clients
331         void                    UpdateTourneyLine( void );
332         const char *    GameTime( void );
333         void                    Clear( void );
334         bool                    EnoughClientsToPlay( void );
335         void                    ClearChatData( void );
336         void                    DrawChat( void );
337         // go through the clients, and see if they want to be respawned, and if the game allows it
338         // called during normal gameplay for death -> respawn cycles
339         // and for a spectator who want back in the game (see param)
340         void                    CheckRespawns( idPlayer *spectator = NULL );
341         void                    ForceReady();
342         // when clients disconnect or join spectate during game, check if we need to end the game
343         void                    CheckAbortGame( void );
344         void                    MessageMode( const idCmdArgs &args );
345         void                    DisableMenu( void );
346         void                    SetMapShot( void );
347         // scores in TDM
348         void                    TeamScore( int entityNumber, int team, int delta );
349         void                    VoiceChat( const idCmdArgs &args, bool team );
350         void                    DumpTourneyLine( void );
351         void                    SuddenRespawn( void );
352 };
353
354 ID_INLINE idMultiplayerGame::gameState_t idMultiplayerGame::GetGameState( void ) const {
355         return gameState;
356 }
357
358 ID_INLINE bool idMultiplayerGame::IsPureReady( void ) const {
359         return pureReady;
360 }
361
362 ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) {
363         playerState[ clientNum ].fragCount = 0;
364 }
365
366 ID_INLINE bool idMultiplayerGame::IsInGame( int clientNum ) {
367         return playerState[ clientNum ].ingame;
368 }
369
370 #endif  /* !__MULTIPLAYERGAME_H__ */
371