680 lines
23 KiB
C++
680 lines
23 KiB
C++
//========= 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 "GameEventListener.h"
|
|
#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,
|
|
#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
|