]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/d3xp/MultiplayerGame.h
hello world
[icculus/iodoom3.git] / neo / d3xp / 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 #ifdef CTF
43 class idItemTeam;
44 #endif
45
46
47 typedef enum {
48         GAME_SP = 0,
49         GAME_DM,
50         GAME_TOURNEY,
51         GAME_TDM,
52         GAME_LASTMAN,
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 {
73                 PLAYER_VOTE_NONE,
74                 PLAYER_VOTE_NO,
75                 PLAYER_VOTE_YES,
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;
87 } mpPlayerState_t;
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 {
107         idStr                   line;
108         short                   fade;                   // starts high and decreases, line is removed once reached 0
109 } mpChatLine_t;
110
111 typedef enum {
112         SND_YOUWIN = 0,
113         SND_YOULOSE,
114         SND_FIGHT,
115         SND_VOTE,
116         SND_VOTE_PASSED,
117         SND_VOTE_FAILED,
118         SND_THREE,
119         SND_TWO,
120         SND_ONE,
121         SND_SUDDENDEATH,
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
131         SND_COUNT
132 } snd_evt_t;
133
134 class idMultiplayerGame {
135 public:
136
137                                         idMultiplayerGame();
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)
177                 NEXTGAME,
178                 STATE_COUNT
179         } gameState_t;
180         static const char *GameStateStrings[ STATE_COUNT ];
181         idMultiplayerGame::gameState_t          GetGameState( void ) const;
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 {
191                 MSG_SUICIDE = 0,
192                 MSG_KILLED,
193                 MSG_KILLEDTEAM,
194                 MSG_DIED,
195                 MSG_VOTE,
196                 MSG_VOTEPASSED,
197                 MSG_VOTEFAILED,
198                 MSG_SUDDENDEATH,
199                 MSG_FORCEREADY,
200                 MSG_JOINEDSPEC,
201                 MSG_TIMELIMIT,
202                 MSG_FRAGLIMIT,
203                 MSG_TELEFRAGGED,
204                 MSG_JOINTEAM,
205                 MSG_HOLYSHIT,
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
216                 MSG_COUNT
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 {
228                 VOTE_RESTART = 0,
229                 VOTE_TIMELIMIT,
230                 VOTE_FRAGLIMIT,
231                 VOTE_GAMETYPE,
232                 VOTE_KICK,
233                 VOTE_MAP,
234                 VOTE_SPECTATORS,
235                 VOTE_NEXTMAP,
236                 VOTE_COUNT,
237                 VOTE_NONE
238         } vote_flags_t;
239
240         typedef enum {
241                 VOTE_UPDATE,
242                 VOTE_FAILED,
243                 VOTE_PASSED,    // passed, but no reset yet
244                 VOTE_ABORTED,
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
312         mpPlayerState_t playerState[ MAX_CLIENTS ];
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 )
325         int                             kickVoteMap[ MAX_CLIENTS ];
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.
345         idListGUI               *mapList;
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
352         mpChatLine_t    chatHistory[ NUM_CHAT_NOTIFY ];
353         int                             chatHistoryIndex;
354         int                             chatHistorySize;                // 0 <= x < NUM_CHAT_NOTIFY
355         bool                    chatDataUpdated;
356         int                             lastChatLineTime;
357
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];
361
362         bool                    pureReady;                              // defaults to false, set to true once server game is running with pure checksums
363         int                             fragLimitTimeout;
364
365         int                             switchThrottle[ 3 ];
366         int                             voiceChatThrottle;
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 );
385         void                    UpdateScoreboard( idUserInterface *scoreBoard, idPlayer *player );
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
466 ID_INLINE idMultiplayerGame::gameState_t idMultiplayerGame::GetGameState( void ) const {
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