diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /sp/src/game/shared/teamplayroundbased_gamerules.h | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'sp/src/game/shared/teamplayroundbased_gamerules.h')
| -rw-r--r-- | sp/src/game/shared/teamplayroundbased_gamerules.h | 1172 |
1 files changed, 586 insertions, 586 deletions
diff --git a/sp/src/game/shared/teamplayroundbased_gamerules.h b/sp/src/game/shared/teamplayroundbased_gamerules.h index 4ce4911f..61567d49 100644 --- a/sp/src/game/shared/teamplayroundbased_gamerules.h +++ b/sp/src/game/shared/teamplayroundbased_gamerules.h @@ -1,586 +1,586 @@ -//========= 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"
-
-#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,
-};
-
-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
-{
- 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 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( void );
-
-#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 GetMvMPotentialDefendersLobbyPlayerInfo( CUtlVector<LobbyPlayerInfo_t> &vecMvmDefenders, bool bIncludeBots = false );
-
-#endif
-
- //----------------------------------------------------------------------------------
- // 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; }
-
- bool PrevRoundWasWaitingForPlayers() { return m_bPrevRoundWasWaitingForPlayers; }
-
- virtual bool ShouldScorePerRound( void ){ return true; }
-
- bool CheckNextLevelCvar( void );
-
- 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 );
- 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 );
- }
-
- virtual void PlayTrainCaptureAlert( CTeamControlPoint *pPoint, bool bFinalPointInMap ){ return; }
-
- virtual void PlaySpecialCapSounds( int iCappingTeam ){ 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( void );
- int GetTimeLeft( void );
- virtual bool CheckWinLimit( void );
- bool CheckMaxRounds( void );
-
- void CheckReadyRestart( void );
-#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
- bool AreDefendingPlayersReady();
-#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_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* LoseSongName( void ) { 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 );
-
-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;
-
-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 );
-
-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 );
-
-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;
-
-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
+//========= 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" + +#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, +}; + +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 +{ + 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 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( void ); + +#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 GetMvMPotentialDefendersLobbyPlayerInfo( CUtlVector<LobbyPlayerInfo_t> &vecMvmDefenders, bool bIncludeBots = false ); + +#endif + + //---------------------------------------------------------------------------------- + // 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; } + + bool PrevRoundWasWaitingForPlayers() { return m_bPrevRoundWasWaitingForPlayers; } + + virtual bool ShouldScorePerRound( void ){ return true; } + + bool CheckNextLevelCvar( void ); + + 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 ); + 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 ); + } + + virtual void PlayTrainCaptureAlert( CTeamControlPoint *pPoint, bool bFinalPointInMap ){ return; } + + virtual void PlaySpecialCapSounds( int iCappingTeam ){ 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( void ); + int GetTimeLeft( void ); + virtual bool CheckWinLimit( void ); + bool CheckMaxRounds( void ); + + void CheckReadyRestart( void ); +#if defined(TF_CLIENT_DLL) || defined(TF_DLL) + bool AreDefendingPlayersReady(); +#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_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* LoseSongName( void ) { 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 ); + +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; + +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 ); + +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 ); + +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; + +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 |