1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Teamplay game rules that manage a round based structure for you
//
//=============================================================================
#ifndef TEAMPLAYROUNDBASED_GAMERULES_H
#define TEAMPLAYROUNDBASED_GAMERULES_H
#ifdef _WIN32
#pragma once
#endif
#include "teamplay_gamerules.h"
#include "teamplay_round_timer.h"
#include "GameEventListener.h"
#ifdef GAME_DLL
#include "team_control_point.h"
extern ConVar mp_respawnwavetime;
extern ConVar mp_showroundtransitions;
extern ConVar mp_enableroundwaittime;
extern ConVar mp_showcleanedupents;
extern ConVar mp_bonusroundtime;
extern ConVar mp_restartround;
extern ConVar mp_winlimit;
extern ConVar mp_maxrounds;
extern ConVar mp_stalemate_timelimit;
extern ConVar mp_stalemate_enable;
#else
#define CTeamplayRoundBasedRules C_TeamplayRoundBasedRules
#define CTeamplayRoundBasedRulesProxy C_TeamplayRoundBasedRulesProxy
#endif
extern ConVar tf_arena_use_queue;
extern ConVar mp_stalemate_meleeonly;
extern ConVar mp_forceautoteam;
class CTeamplayRoundBasedRules;
//-----------------------------------------------------------------------------
// Round states
//-----------------------------------------------------------------------------
enum gamerules_roundstate_t
{
// initialize the game, create teams
GR_STATE_INIT = 0,
//Before players have joined the game. Periodically checks to see if enough players are ready
//to start a game. Also reverts to this when there are no active players
GR_STATE_PREGAME,
//The game is about to start, wait a bit and spawn everyone
GR_STATE_STARTGAME,
//All players are respawned, frozen in place
GR_STATE_PREROUND,
//Round is on, playing normally
GR_STATE_RND_RUNNING,
//Someone has won the round
GR_STATE_TEAM_WIN,
//Noone has won, manually restart the game, reset scores
GR_STATE_RESTART,
//Noone has won, restart the game
GR_STATE_STALEMATE,
//Game is over, showing the scoreboard etc
GR_STATE_GAME_OVER,
//Game is in a bonus state, transitioned to after a round ends
GR_STATE_BONUS,
//Game is awaiting the next wave/round of a multi round experience
GR_STATE_BETWEEN_RNDS,
GR_NUM_ROUND_STATES
};
enum {
WINREASON_NONE =0,
WINREASON_ALL_POINTS_CAPTURED,
WINREASON_OPPONENTS_DEAD,
WINREASON_FLAG_CAPTURE_LIMIT,
WINREASON_DEFEND_UNTIL_TIME_LIMIT,
WINREASON_STALEMATE,
WINREASON_TIMELIMIT,
WINREASON_WINLIMIT,
WINREASON_WINDIFFLIMIT,
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
WINREASON_RD_REACTOR_CAPTURED,
WINREASON_RD_CORES_COLLECTED,
WINREASON_RD_REACTOR_RETURNED,
#endif
};
enum stalemate_reasons_t
{
STALEMATE_JOIN_MID,
STALEMATE_TIMER,
STALEMATE_SERVER_TIMELIMIT,
NUM_STALEMATE_REASONS,
};
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
/// Info about a player in a PVE game or any other mode that we
/// might eventually decide to use the lobby system for.
struct LobbyPlayerInfo_t
{
int m_nEntNum; //< Index of player (1...MAX_PLAYERS), or 0 if the guy is in the lobby but not yet known to us
CUtlString m_sPlayerName; //< Player display name
CSteamID m_steamID; //< Steam ID of the player
int m_iTeam; //< Team selection.
bool m_bInLobby; //< Is this guy in the lobby?
bool m_bConnected; //< Is this a bot?
bool m_bBot; //< Is this a bot?
bool m_bSquadSurplus; //< Did he present a voucher to get surplus for his squad
};
#endif
//-----------------------------------------------------------------------------
// Purpose: Per-state data
//-----------------------------------------------------------------------------
class CGameRulesRoundStateInfo
{
public:
gamerules_roundstate_t m_iRoundState;
const char *m_pStateName;
void (CTeamplayRoundBasedRules::*pfnEnterState)(); // Init and deinit the state.
void (CTeamplayRoundBasedRules::*pfnLeaveState)();
void (CTeamplayRoundBasedRules::*pfnThink)(); // Do a PreThink() in this state.
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CTeamplayRoundBasedRulesProxy : public CGameRulesProxy
{
public:
DECLARE_CLASS( CTeamplayRoundBasedRulesProxy, CGameRulesProxy );
DECLARE_NETWORKCLASS();
#ifdef GAME_DLL
DECLARE_DATADESC();
void InputSetStalemateOnTimelimit( inputdata_t &inputdata );
#endif
//----------------------------------------------------------------------------------
// Client specific
#ifdef CLIENT_DLL
void OnPreDataChanged( DataUpdateType_t updateType );
void OnDataChanged( DataUpdateType_t updateType );
#endif // CLIENT_DLL
};
//-----------------------------------------------------------------------------
// Purpose: Teamplay game rules that manage a round based structure for you
//-----------------------------------------------------------------------------
class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListener
{
DECLARE_CLASS( CTeamplayRoundBasedRules, CTeamplayRules );
public:
CTeamplayRoundBasedRules();
#ifdef CLIENT_DLL
DECLARE_CLIENTCLASS_NOBASE(); // This makes datatables able to access our private vars.
void SetRoundState( int iRoundState );
#else
DECLARE_SERVERCLASS_NOBASE(); // This makes datatables able to access our private vars.
#endif
float GetLastRoundStateChangeTime( void ) const { return m_flLastRoundStateChangeTime; }
float m_flLastRoundStateChangeTime;
// Data accessors
inline gamerules_roundstate_t State_Get( void ) { return m_iRoundState; }
bool IsInWaitingForPlayers( void ) { return m_bInWaitingForPlayers; }
virtual bool InRoundRestart( void ) { return State_Get() == GR_STATE_PREROUND; }
bool InStalemate( void ) { return State_Get() == GR_STATE_STALEMATE; }
bool RoundHasBeenWon( void ) { return State_Get() == GR_STATE_TEAM_WIN; }
virtual float GetNextRespawnWave( int iTeam, CBasePlayer *pPlayer );
virtual bool HasPassedMinRespawnTime( CBasePlayer *pPlayer );
virtual void LevelInitPostEntity( void );
virtual float GetRespawnTimeScalar( int iTeam );
virtual float GetRespawnWaveMaxLength( int iTeam, bool bScaleWithNumPlayers = true );
virtual bool ShouldRespawnQuickly( CBasePlayer *pPlayer ) { return false; }
float GetMinTimeWhenPlayerMaySpawn( CBasePlayer *pPlayer );
// Return false if players aren't allowed to cap points at this time (i.e. in WaitingForPlayers)
virtual bool PointsMayBeCaptured( void ) { return ((State_Get() == GR_STATE_RND_RUNNING || State_Get() == GR_STATE_STALEMATE) && !IsInWaitingForPlayers()); }
virtual void SetLastCapPointChanged( int iIndex ) { m_iLastCapPointChanged = iIndex; }
int GetLastCapPointChanged( void ) { return m_iLastCapPointChanged; }
virtual int GetWinningTeam( void ){ return m_iWinningTeam; }
int GetWinReason() { return m_iWinReason; }
bool InOvertime( void ){ return m_bInOvertime; }
void SetOvertime( bool bOvertime );
bool InSetup( void ){ return m_bInSetup; }
void BalanceTeams( bool bRequireSwitcheesToBeDead );
bool SwitchedTeamsThisRound( void ) { return m_bSwitchedTeamsThisRound; }
virtual bool ShouldBalanceTeams( void );
bool IsInTournamentMode( void );
bool IsInHighlanderMode( void );
bool IsInPreMatch( void ) { return (IsInTournamentMode() && IsInWaitingForPlayers()); }
bool IsWaitingForTeams( void ) { return m_bAwaitingReadyRestart; }
bool IsInStopWatch( void ) { return m_bStopWatch; }
void SetInStopWatch( bool bState ) { m_bStopWatch = bState; }
virtual void StopWatchModeThink( void ) { };
bool IsTeamReady( int iTeamNumber )
{
return m_bTeamReady[iTeamNumber];
}
bool IsPlayerReady( int iIndex )
{
return m_bPlayerReady[iIndex];
}
virtual void HandleTeamScoreModify( int iTeam, int iScore) { };
float GetRoundRestartTime( void ) { return m_flRestartRoundTime; }
//Arena Mode
virtual bool IsInArenaMode( void ) { return false; }
//Koth Mode
virtual bool IsInKothMode( void ) { return false; }
//Training Mode
virtual bool IsInTraining( void ) { return false; }
virtual bool IsInItemTestingMode( void ) { return false; }
void SetMultipleTrains( bool bMultipleTrains ){ m_bMultipleTrains = bMultipleTrains; }
bool HasMultipleTrains( void ){ return m_bMultipleTrains; }
virtual int GetBonusRoundTime( bool bFinal = false );
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
// Get list of all the players, including those in the lobby but who have
// not yet joined.
void GetAllPlayersLobbyInfo( CUtlVector<LobbyPlayerInfo_t> &vecPlayers, bool bIncludeBots = false );
// Get list of players who are on the defending team now, or are likely
// to end up on the defending team (not yet connected or assigned a team)
void GetPotentialPlayersLobbyPlayerInfo( CUtlVector<LobbyPlayerInfo_t> &vecLobbyPlayers, bool bIncludeBots = false );
#endif
void SetAllowBetweenRounds( bool bValue ) { m_bAllowBetweenRounds = bValue; }
public: // IGameEventListener Interface
virtual void FireGameEvent( IGameEvent * event );
//----------------------------------------------------------------------------------
// Server specific
#ifdef GAME_DLL
// Derived game rules class should override these
public:
// Override this to prevent removal of game specific entities that need to persist
virtual bool RoundCleanupShouldIgnore( CBaseEntity *pEnt );
virtual bool ShouldCreateEntity( const char *pszClassName );
// Called when a new round is being initialized
virtual void SetupOnRoundStart( void ) { return; }
// Called when a new round is off and running
virtual void SetupOnRoundRunning( void ) { return; }
// Called before a new round is started (so the previous round can end)
virtual void PreviousRoundEnd( void ) { return; }
// Send the team scores down to the client
virtual void SendTeamScoresEvent( void ) { return; }
// Send the end of round info displayed in the win panel
virtual void SendWinPanelInfo( void ) { return; }
// Setup spawn points for the current round before it starts
virtual void SetupSpawnPointsForRound( void ) { return; }
// Called when a round has entered stalemate mode (timer has run out)
virtual void SetupOnStalemateStart( void ) { return; }
virtual void SetupOnStalemateEnd( void ) { return; }
virtual void SetSetup( bool bSetup );
virtual bool ShouldGoToBonusRound( void ) { return false; }
virtual void SetupOnBonusStart( void ) { return; }
virtual void SetupOnBonusEnd( void ) { return; }
virtual void BonusStateThink( void ) { return; }
virtual void BetweenRounds_Start( void ) { return; }
virtual void BetweenRounds_End( void ) { return; }
virtual void BetweenRounds_Think( void ) { return; }
virtual void PreRound_End( void ) { return; }
bool PrevRoundWasWaitingForPlayers() { return m_bPrevRoundWasWaitingForPlayers; }
virtual bool ShouldScorePerRound( void ){ return true; }
bool CheckNextLevelCvar( bool bAllowEnd = true );
virtual bool TimerMayExpire( void );
virtual bool IsValveMap( void ){ return false; }
virtual void RestartTournament( void );
virtual bool TournamentModeCanEndWithTimelimit( void ){ return true; }
public:
void State_Transition( gamerules_roundstate_t newState );
void RespawnPlayers( bool bForceRespawn, bool bTeam = false, int iTeam = TEAM_UNASSIGNED );
void SetForceMapReset( bool reset );
void SetRoundToPlayNext( string_t strName ){ m_iszRoundToPlayNext = strName; }
string_t GetRoundToPlayNext( void ){ return m_iszRoundToPlayNext; }
void AddPlayedRound( string_t strName );
bool IsPreviouslyPlayedRound ( string_t strName );
string_t GetLastPlayedRound( void );
virtual void SetWinningTeam( int team, int iWinReason, bool bForceMapReset = true, bool bSwitchTeams = false, bool bDontAddScore = false, bool bFinal = false ) OVERRIDE;
virtual void SetStalemate( int iReason, bool bForceMapReset = true, bool bSwitchTeams = false );
virtual void SetRoundOverlayDetails( void ){ return; }
virtual float GetWaitingForPlayersTime( void ) { return mp_waitingforplayers_time.GetFloat(); }
void ShouldResetScores( bool bResetTeam, bool bResetPlayer ){ m_bResetTeamScores = bResetTeam; m_bResetPlayerScores = bResetPlayer; }
void ShouldResetRoundsPlayed( bool bResetRoundsPlayed ){ m_bResetRoundsPlayed = bResetRoundsPlayed; }
void SetFirstRoundPlayed( string_t strName ){ m_iszFirstRoundPlayed = strName ; }
string_t GetFirstRoundPlayed(){ return m_iszFirstRoundPlayed; }
void SetTeamRespawnWaveTime( int iTeam, float flValue );
void AddTeamRespawnWaveTime( int iTeam, float flValue );
virtual void FillOutTeamplayRoundWinEvent( IGameEvent *event ) {} // derived classes may implement to add fields to this event
void SetStalemateOnTimelimit( bool bStalemate ) { m_bAllowStalemateAtTimelimit = bStalemate; }
bool IsGameUnderTimeLimit( void );
CTeamRoundTimer *GetActiveRoundTimer( void );
void HandleTimeLimitChange( void );
void SetTeamReadyState( bool bState, int iTeam )
{
m_bTeamReady.Set( iTeam, bState );
}
void SetPlayerReadyState( int iIndex, bool bState )
{
m_bPlayerReady.Set( iIndex, bState );
}
void ResetPlayerAndTeamReadyState( void );
virtual void PlayTrainCaptureAlert( CTeamControlPoint *pPoint, bool bFinalPointInMap ){ return; }
virtual void PlaySpecialCapSounds( int iCappingTeam, CTeamControlPoint *pPoint ){ return; }
bool PlayThrottledAlert( int iTeam, const char *sound, float fDelayBeforeNext );
void BroadcastSound( int iTeam, const char *sound, int iAdditionalSoundFlags = 0 );
int GetRoundsPlayed( void ) { return m_nRoundsPlayed; }
virtual void RecalculateControlPointState( void ){ return; }
virtual bool ShouldSkipAutoScramble( void ){ return false; }
virtual bool ShouldWaitToStartRecording( void ){ return IsInWaitingForPlayers(); }
protected:
virtual void Think( void );
virtual void CheckChatText( CBasePlayer *pPlayer, char *pText );
void CheckChatForReadySignal( CBasePlayer *pPlayer, const char *chatmsg );
// Game beginning / end handling
virtual void GoToIntermission( void );
void SetInWaitingForPlayers( bool bWaitingForPlayers );
void CheckWaitingForPlayers( void );
virtual bool AllowWaitingForPlayers( void ) { return true; }
void CheckRestartRound( void );
bool CheckTimeLimit( bool bAllowEnd = true );
int GetTimeLeft( void );
virtual bool CheckWinLimit( bool bAllowEnd = true );
bool CheckMaxRounds( bool bAllowEnd = true );
void CheckReadyRestart( void );
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
bool AreLobbyPlayersOnTeamReady( int iTeam );
bool AreLobbyPlayersConnected( void );
#endif
virtual bool CanChangelevelBecauseOfTimeLimit( void ) { return true; }
virtual bool CanGoToStalemate( void ) { return true; }
// State machine handling
void State_Enter( gamerules_roundstate_t newState ); // Initialize the new state.
void State_Leave(); // Cleanup the previous state.
void State_Think(); // Update the current state.
static CGameRulesRoundStateInfo* State_LookupInfo( gamerules_roundstate_t state ); // Find the state info for the specified state.
// State Functions
void State_Enter_INIT( void );
void State_Think_INIT( void );
void State_Enter_PREGAME( void );
void State_Think_PREGAME( void );
void State_Enter_STARTGAME( void );
void State_Think_STARTGAME( void );
void State_Enter_PREROUND( void );
void State_Leave_PREROUND( void );
void State_Think_PREROUND( void );
void State_Enter_RND_RUNNING( void );
void State_Think_RND_RUNNING( void );
void State_Enter_TEAM_WIN( void );
void State_Think_TEAM_WIN( void );
void State_Enter_RESTART( void );
void State_Think_RESTART( void );
void State_Enter_STALEMATE( void );
void State_Think_STALEMATE( void );
void State_Leave_STALEMATE( void );
void State_Enter_BONUS( void );
void State_Think_BONUS( void );
void State_Leave_BONUS( void );
void State_Enter_BETWEEN_RNDS( void );
void State_Leave_BETWEEN_RNDS( void );
void State_Think_BETWEEN_RNDS( void );
// mp_scrambleteams_auto
void ResetTeamsRoundWinTracking( void );
protected:
virtual void InitTeams( void );
virtual int CountActivePlayers( void );
virtual void RoundRespawn( void );
virtual void CleanUpMap( void );
virtual void CheckRespawnWaves( void );
void ResetScores( void );
void ResetMapTime( void );
void PlayStartRoundVoice( void );
void PlayWinSong( int team );
void PlayStalemateSong( void );
void PlaySuddenDeathSong( void );
virtual const char* GetStalemateSong( int nTeam ) { return "Game.Stalemate"; }
virtual const char* WinSongName( int nTeam ) { return "Game.YourTeamWon"; }
virtual const char* LoseSongName( int nTeam ) { return "Game.YourTeamLost"; }
virtual void RespawnTeam( int iTeam ) { RespawnPlayers( false, true, iTeam ); }
void HideActiveTimer( void );
virtual void RestoreActiveTimer( void );
virtual void InternalHandleTeamWin( int iWinningTeam ){ return; }
bool MapHasActiveTimer( void );
void CreateTimeLimitTimer( void );
virtual float GetLastMajorEventTime( void ) OVERRIDE { return m_flLastTeamWin; }
protected:
CGameRulesRoundStateInfo *m_pCurStateInfo; // Per-state data
float m_flStateTransitionTime; // Timer for round states
float m_flWaitingForPlayersTimeEnds;
CHandle<CTeamRoundTimer> m_hWaitingForPlayersTimer;
float m_flNextPeriodicThink;
bool m_bChangeLevelOnRoundEnd;
bool m_bResetTeamScores;
bool m_bResetPlayerScores;
bool m_bResetRoundsPlayed;
// Stalemate
EHANDLE m_hPreviousActiveTimer;
CHandle<CTeamRoundTimer> m_hStalemateTimer;
float m_flStalemateStartTime;
CHandle<CTeamRoundTimer> m_hTimeLimitTimer;
bool m_bForceMapReset; // should the map be reset when a team wins and the round is restarted?
bool m_bPrevRoundWasWaitingForPlayers; // was the previous map reset after a waiting for players period
bool m_bInitialSpawn;
string_t m_iszRoundToPlayNext;
CUtlVector<string_t> m_iszPreviousRounds; // we'll store the two previous rounds so we won't play them again right away if there are other rounds that can be played first
string_t m_iszFirstRoundPlayed; // store the first round played after a full restart so we can pick a different one next time if we have other options
float m_flOriginalTeamRespawnWaveTime[ MAX_TEAMS ];
bool m_bAllowStalemateAtTimelimit;
bool m_bChangelevelAfterStalemate;
float m_flRoundStartTime; // time the current round started
float m_flNewThrottledAlertTime; // time that we can play another throttled alert
int m_nRoundsPlayed;
bool m_bUseAddScoreAnim;
gamerules_roundstate_t m_prevState;
bool m_bPlayerReadyBefore[MAX_PLAYERS+1]; // Test to see if a player has hit ready before
float m_flLastTeamWin;
private:
CUtlMap < int, int > m_GameTeams; // Team index, Score
#endif
// End server specific
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
// Client specific
#ifdef CLIENT_DLL
public:
virtual void OnPreDataChanged( DataUpdateType_t updateType );
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void HandleOvertimeBegin(){}
virtual void GetTeamGlowColor( int nTeam, float &r, float &g, float &b ){ r = 0.76f; g = 0.76f; b = 0.76f; }
private:
bool m_bOldInWaitingForPlayers;
bool m_bOldInOvertime;
bool m_bOldInSetup;
#endif // CLIENT_DLL
public:
bool WouldChangeUnbalanceTeams( int iNewTeam, int iCurrentTeam );
bool AreTeamsUnbalanced( int &iHeaviestTeam, int &iLightestTeam );
virtual bool HaveCheatsBeenEnabledDuringLevel( void ) { return m_bCheatsEnabledDuringLevel; }
protected:
CNetworkVar( gamerules_roundstate_t, m_iRoundState );
CNetworkVar( bool, m_bInOvertime ); // Are we currently in overtime?
CNetworkVar( bool, m_bInSetup ); // Are we currently in setup?
CNetworkVar( bool, m_bSwitchedTeamsThisRound );
protected:
CNetworkVar( int, m_iWinningTeam ); // Set before entering GR_STATE_TEAM_WIN
CNetworkVar( int, m_iWinReason );
CNetworkVar( bool, m_bInWaitingForPlayers );
CNetworkVar( bool, m_bAwaitingReadyRestart );
CNetworkVar( float, m_flRestartRoundTime );
CNetworkVar( float, m_flMapResetTime ); // Time that the map was reset
CNetworkArray( float, m_flNextRespawnWave, MAX_TEAMS ); // Minor waste, but cleaner code
CNetworkArray( bool, m_bTeamReady, MAX_TEAMS );
CNetworkVar( bool, m_bStopWatch );
CNetworkVar( bool, m_bMultipleTrains ); // two trains in this map?
CNetworkArray( bool, m_bPlayerReady, MAX_PLAYERS );
CNetworkVar( bool, m_bCheatsEnabledDuringLevel );
public:
CNetworkArray( float, m_TeamRespawnWaveTimes, MAX_TEAMS ); // Time between each team's respawn wave
private:
float m_flStartBalancingTeamsAt;
float m_flNextBalanceTeamsTime;
bool m_bPrintedUnbalanceWarning;
float m_flFoundUnbalancedTeamsTime;
float m_flAutoBalanceQueueTimeEnd;
int m_nAutoBalanceQueuePlayerIndex;
int m_nAutoBalanceQueuePlayerScore;
protected:
bool m_bAllowBetweenRounds;
public:
float m_flStopWatchTotalTime;
int m_iLastCapPointChanged;
};
// Utility function
bool FindInList( const char **pStrings, const char *pToFind );
inline CTeamplayRoundBasedRules* TeamplayRoundBasedRules()
{
return static_cast<CTeamplayRoundBasedRules*>(g_pGameRules);
}
#endif // TEAMPLAYROUNDBASED_GAMERULES_H
|