Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1606 lines
58 KiB

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: The TF Game rules object
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#ifndef CS_GAMERULES_H
#define CS_GAMERULES_H
#ifdef _WIN32
#pragma once
#endif
#include "teamplay_gamerules.h"
#include "convar.h"
#include "cs_shareddefs.h"
#include "cs_weapon_parse.h"
#include "gamevars_shared.h"
#include "bot/bot_constants.h"
#include "../../../common/input_device.h"
#include "cstrike15_gcconstants.h"
#include "cstrike15_gcmessages.pb.h"
#include "usermessages.h"
#if defined( GAME_DLL )
#include "maprules.h"
#endif
//#define DEBUG_QUESTS_IN_CLIENT
#ifdef CLIENT_DLL
#include "networkstringtable_clientdll.h"
class C_CSPlayer;
#define CCSPlayer C_CSPlayer
#else
#include "funfactmgr_cs.h"
class CCSPlayer;
#endif
#define WINNER_NONE 0
#define WINNER_DRAW 1
#define WINNER_TER TEAM_TERRORIST
#define WINNER_CT TEAM_CT
#define CUSTOM_BOT_DIFFICULTY_NOBOTS 0
#define CUSTOM_BOT_DIFFICULTY_DUMB 1
#define CUSTOM_BOT_DIFFICULTY_EASY 2
#define CUSTOM_BOT_DIFFICULTY_MEDIUM 3
#define CUSTOM_BOT_DIFFICULTY_HARD 4
#define CUSTOM_BOT_DIFFICULTY_EXPERT 5
#define CUSTOM_BOT_MIN_DIFFICULTY_FOR_AWARDS_PROGRESS CUSTOM_BOT_DIFFICULTY_EASY
#define MAX_WEAPON_NAME_POPUP_RANGE 128.0
#define MAX_GIFT_GIVERS_FEATURED_COUNT 4
#define MAX_TOURNAMENT_ACTIVE_CASTER_COUNT 4
class CCSBot;
class CHostage;
class CCSWeaponInfo;
struct quest_data_t;
extern ConVar mp_startmoney;
extern ConVar mp_maxmoney;
extern ConVar mp_afterroundmoney;
extern ConVar mp_playercashawards;
extern ConVar mp_teamcashawards;
extern ConVar mp_tkpunish;
extern ConVar mp_c4timer;
extern ConVar mp_buytime;
extern ConVar mp_freezetime;
extern ConVar mp_playerid;
extern ConVar mp_defuser_allocation;
extern ConVar mp_death_drop_gun;
extern ConVar mp_death_drop_grenade;
extern ConVar mp_death_drop_defuser;
extern ConVar ammo_grenade_limit_total;
extern ConVar sv_competitive_official_5v5;
namespace DefuserAllocation
{
enum Type
{
None = 0,
Random = 1,
All = 2,
};
};
namespace TeamCashAward
{
enum Type
{
NONE = 0,
TERRORIST_WIN_BOMB,
ELIMINATION_HOSTAGE_MAP_T,
ELIMINATION_HOSTAGE_MAP_CT,
ELIMINATION_BOMB_MAP,
WIN_BY_TIME_RUNNING_OUT_HOSTAGE,
WIN_BY_TIME_RUNNING_OUT_BOMB,
WIN_BY_DEFUSING_BOMB,
WIN_BY_HOSTAGE_RESCUE,
LOSER_BONUS,
LOSER_BONUS_CONSECUTIVE_ROUNDS,
RESCUED_HOSTAGE,
HOSTAGE_ALIVE,
PLANTED_BOMB_BUT_DEFUSED,
HOSTAGE_INTERACTION,
LOSER_ZERO,
SURVIVE_GUARDIAN_WAVE,
CUSTOM_AWARD,
};
};
namespace RoundResult
{
enum Reason
{
UNDEFINED = 0,
CT_WIN_ELIMINATION,
CT_WIN_RESCUE,
CT_WIN_DEFUSE,
CT_WIN_TIME,
T_WIN_ELIMINATION,
T_WIN_BOMB,
T_WIN_TIME,
COUNT,
UNKNOWN
};
};
namespace PlayerCashAward
{
enum Type
{
NONE = 0,
KILL_TEAMMATE,
KILLED_ENEMY,
BOMB_PLANTED,
BOMB_DEFUSED,
RESCUED_HOSTAGE,
INTERACT_WITH_HOSTAGE,
DAMAGE_HOSTAGE,
KILL_HOSTAGE,
RESPAWN,
GET_KILLED,
};
};
namespace AutobalanceStatus
{
enum Type
{
NONE = 0,
NEXT_ROUND,
THIS_ROUND
};
};
//--------------------------------------------------------------------------------------------------------------
struct GGWeaponAliasName
{
CSWeaponID id;
const char *aliasName;
};
#define GGLIST_PISTOLS_TOTAL 9
#define GGLIST_RIFLES_TOTAL 7
#define GGLIST_MGS_TOTAL 2
#define GGLIST_SGS_TOTAL 4
#define GGLIST_SMGS_TOTAL 6
#define GGLIST_SNIPERS_TOTAL 3
#define GGLIST_PISTOLS_START 0
#define GGLIST_PISTOLS_LAST (GGLIST_PISTOLS_START+GGLIST_PISTOLS_TOTAL-1)
#define GGLIST_RIFLES_START GGLIST_PISTOLS_LAST+1
#define GGLIST_RIFLES_LAST (GGLIST_RIFLES_START+GGLIST_RIFLES_TOTAL-1)
#define GGLIST_MGS_START GGLIST_RIFLES_LAST+1
#define GGLIST_MGS_LAST (GGLIST_MGS_START+GGLIST_MGS_TOTAL-1)
#define GGLIST_SGS_START GGLIST_MGS_LAST+1
#define GGLIST_SGS_LAST (GGLIST_SGS_START+GGLIST_SGS_TOTAL-1)
#define GGLIST_SMGS_START GGLIST_SGS_LAST+1
#define GGLIST_SMGS_LAST (GGLIST_SMGS_START+GGLIST_SMGS_TOTAL-1)
#define GGLIST_SNIPERS_START GGLIST_SMGS_LAST+1
#define GGLIST_SNIPERS_LAST (GGLIST_SNIPERS_START+GGLIST_SNIPERS_TOTAL-1)
//--------------------------------------------------------------------------------------------------------------
// NOTE: Array must be NULL-terminated
static GGWeaponAliasName ggWeaponAliasNameList[] =
{
//pistols
{ WEAPON_DEAGLE, "deagle" },
{ WEAPON_DEAGLE, "revolver" },
{ WEAPON_ELITE, "elite" },
{ WEAPON_FIVESEVEN, "fiveseven" },
{ WEAPON_GLOCK, "glock" },
{ WEAPON_TEC9, "tec9" },
{ WEAPON_HKP2000, "hkp2000" },
{ WEAPON_HKP2000, "usp_silencer" },
{ WEAPON_P250, "p250" },
//rifles
{ WEAPON_AK47, "ak47" },
{ WEAPON_AUG, "aug" },
{ WEAPON_FAMAS, "famas" },
{ WEAPON_GALILAR, "galilar" },
{ WEAPON_M4A1, "m4a1" },
{ WEAPON_M4A1, "m4a1_silencer" },
{ WEAPON_SG556, "sg556" },
//mgs
{ WEAPON_M249, "m249" },
{ WEAPON_NEGEV, "negev" },
//shotguns
{ WEAPON_XM1014, "xm1014" },
{ WEAPON_MAG7, "mag7" },
{ WEAPON_SAWEDOFF, "sawedoff" },
{ WEAPON_NOVA, "nova" },
//smgs
{ WEAPON_MAC10, "mac10" },
{ WEAPON_P90, "p90" },
{ WEAPON_UMP45, "ump45" },
{ WEAPON_BIZON, "bizon" },
{ WEAPON_MP7, "mp7" },
{ WEAPON_MP9, "mp9" },
//snipers
// { WEAPON_SSG08, "ssg08" },
{ WEAPON_SCAR20, "scar20" },
{ WEAPON_G3SG1, "g3sg1" },
{ WEAPON_AWP, "awp" },
{ WEAPON_NONE, "" }
};
class CEconItemPreviewDataBlock; // forward declare item data
class CCSUsrMsg_PlayerDecalDigitalSignature; // forward declare proto message
#ifndef CLIENT_DLL
extern ConVar mp_autoteambalance;
#endif // !CLIENT_DLL
#ifdef CLIENT_DLL
#define CCSGameRules C_CSGameRules
#define CCSGameRulesProxy C_CSGameRulesProxy
#endif
#if !defined( CLIENT_DLL )
// forward declare GC message
class CMsgGCCStrike15_v2_MatchmakingServerRoundStats;
class CMsgGCCStrike15_v2_MatchmakingGC2ServerReserve;
int ScramblePlayersSort( CCSPlayer* const *p1, CCSPlayer* const *p2 );
class CCSMatch
{
public:
CCSMatch();
void Reset( void );
void SetPhase( GamePhase phase );
GamePhase GetPhase( void ) const { return m_phase; }
//These functions add to both the score and the number of rounds
void AddTerroristWins( int numWins );
void AddCTWins( int numWins);
void IncrementRound( int nNumRounds );
//These functions only adjust the score (without adding to the number of rounds played)
void AddTerroristBonusPoints( int numWins );
void AddCTBonusPoints( int numWins);
int GetTerroristScore( void ) const { return m_terroristScoreTotal; }
int GetCTScore( void ) const { return m_ctScoreTotal; }
int GetTeamScore( int nTeam ) const { switch( nTeam ) { case TEAM_TERRORIST: return GetTerroristScore(); case TEAM_CT: return GetCTScore(); default: Assert( !"unexpected value for nTeam" ); return 0; } }
int GetRoundsPlayed( void ) const { return m_actualRoundsPlayed; }
//Since the teams change in halftime modes and we want to retain their scores, we swap the scores
//between halves.
void SwapTeamScores( void );
int GetWinningTeam( void );
//These are the internal functions that actually mess with the scores, adjusting the appropriate phase-specific scores as well.
void AddTerroristScore( int score );
void AddCTScore( int score );
void GoToOvertime( int numOvertimesToAdd );
private:
//This is called anytime the match-internal scores are updated to reflect the changes in the team object (so the scores can be replicated)
void UpdateTeamScores( void );
// Called when we wish to change the full all-talk rules, based on entering a specific phase of the match
void EnableFullAlltalk( bool bEnable );
//This is the number of rounds that have been played, regardless of the actual score of the match (e.g. Demolition mode can give bonus points)
short m_actualRoundsPlayed;
// This is the index of the overtime that is being played, 0 when game has no overtime or is still in regulation time, 1 for first overtime, 2 for second, etc.
short m_nOvertimePlaying;
short m_ctScoreFirstHalf;
short m_ctScoreSecondHalf;
short m_ctScoreOvertime;
short m_ctScoreTotal;
short m_terroristScoreFirstHalf;
short m_terroristScoreSecondHalf;
short m_terroristScoreOvertime;
short m_terroristScoreTotal;
GamePhase m_phase;
};
class SpawnPoint : public CServerOnlyPointEntity
{
DECLARE_CLASS( SpawnPoint, CServerOnlyPointEntity );
DECLARE_DATADESC();
public:
SpawnPoint();
void Spawn( void );
bool IsEnabled() { return m_bEnabled; }
void InputSetEnabled( inputdata_t &inputdata );
void InputSetDisabled( inputdata_t &inputdata );
void InputToggleEnabled( inputdata_t &inputdata );
void SetSpawnEnabled( bool bEnabled );
int m_iPriority;
bool m_bEnabled;
int m_nType;
enum Type
{
Default = 0,
Deathmatch = 1,
ArmsRace = 2,
};
};
class SpawnPointCoopEnemy : public SpawnPoint
{
DECLARE_CLASS( SpawnPointCoopEnemy, SpawnPoint );
DECLARE_DATADESC();
public:
SpawnPointCoopEnemy();
void Spawn( void );
void Precache( void );
const char *GetWeaponsToGive( void ) { return STRING( m_szWeaponsToGive ); }
const char *GetPlayerModelToUse( void ) { return STRING( m_szPlayerModelToUse ); }
int GetArmorToSpawnWith( void ) { return m_nArmorToSpawnWith; }
bool ShouldStartAsleep( void ) { return m_bStartAsleep; }
int GetBotDifficulty( void ) { return m_nBotDifficulty; }
bool IsBotAgressive( void ) { return m_bIsAgressive; }
CNavArea *FindNearestArea( void );
float HideRadius() const { return m_flHideRadius; }
void HideRadius(bool val) { m_flHideRadius = val; }
enum BotDefaultBehavior_t
{
DEFEND_AREA = 0,
HUNT,
CHARGE_ENEMY,
DEFEND_INVESTIGATE,
};
BotDefaultBehavior_t GetDefaultBehavior() const { return m_nDefaultBehavior; }
void SetDefaultBehavior( BotDefaultBehavior_t val ) { m_nDefaultBehavior = val; }
protected:
string_t m_szWeaponsToGive;
string_t m_szPlayerModelToUse;
int m_nArmorToSpawnWith;
BotDefaultBehavior_t m_nDefaultBehavior;
int m_nBotDifficulty;
bool m_bIsAgressive;
bool m_bStartAsleep;
float m_flHideRadius;
CNavArea *m_pMyArea;
};
#endif //!CLIENT_DLL
class CCSGameRulesProxy : public CGameRulesProxy
{
public:
DECLARE_CLASS( CCSGameRulesProxy, CGameRulesProxy );
DECLARE_NETWORKCLASS();
};
class CCSGameRules : public CTeamplayRules
{
public:
DECLARE_CLASS( CCSGameRules, CTeamplayRules );
// Stuff that is shared between client and server.
bool IsFreezePeriod();
bool IsWarmupPeriod() const;
float GetWarmupPeriodEndTime() const;
bool IsWarmupPeriodPaused();
void SetWarmupPeriodStartTime( float fl ) { m_fWarmupPeriodStart = fl; }
float GetWarmupPeriodStartTime( void ) { return m_fWarmupPeriodStart; }
bool AllowTaunts( void );
bool IsTimeOutActive() const { return ( IsTerroristTimeOutActive() || IsCTTimeOutActive() ); }
bool IsTerroristTimeOutActive() const { return m_bTerroristTimeOutActive; }
bool IsCTTimeOutActive() const { return m_bCTTimeOutActive; }
void StartTerroristTimeOut( void );
void StartCTTimeOut( void );
void EndTerroristTimeOut( void );
void EndCTTimeOut( void );
float GetCTTimeOutRemaining() const { return m_flCTTimeOutRemaining; }
float GetTerroristTimeOutRemaining() const { return m_flTerroristTimeOutRemaining; }
int GetCTTimeOuts( ) const { return m_nCTTimeOuts; }
int GetTerroristTimeOuts( ) const { return m_nTerroristTimeOuts; }
#ifdef CLIENT_DLL
virtual bool AllowThirdPersonCamera();
bool IsGoodDownTime( void ); // this returns true when its a good time to do things like garbage collection
bool IsLoadoutAllowed( void );
void MarkClientStopRecordAtRoundEnd( bool bStop );
#endif
#ifndef CLIENT_DLL
void StartWarmup( void );
void EndWarmup( void );
virtual bool IsTeamChangeSilent( CBasePlayer *pPlayer, int iTeamNum, bool bAutoTeam, bool bSilent ) { return bSilent || m_bForceTeamChangeSilent; }
void CheckForGiftsLeaderboardUpdate();
#endif
bool IsConnectedUserInfoChangeAllowed( CBasePlayer *pPlayer );
virtual bool ShouldCollide( int collisionGroup0, int collisionGroup1 );
virtual float GetRoundRestartTime( void ) { return m_flRestartRoundTime; }
virtual bool IsGameRestarting( void ) { return m_bGameRestart; }
float GetMapRemainingTime(); // time till end of map, -1 if timelimit is disabled
float GetMapElapsedTime(); // How much time has elapsed since the map started.
float GetRoundRemainingTime() const; // time till end of round
float GetRoundStartTime(); // When this round started.
float GetRoundElapsedTime(); // How much time has elapsed since the round started.
float GetBuyTimeLength();
int GetRoundLength() const { return m_iRoundTime; }
int SelectDefaultTeam( bool ignoreBots = false );
int GetHumanTeam(); // TEAM_UNASSIGNED if no restrictions
void CalculateMaxGunGameProgressiveWeaponIndex( void );
int GetMaxGunGameProgressiveWeaponIndex( void ) { return m_iMaxGunGameProgressiveWeaponIndex; }
AcquireResult::Type IsWeaponAllowed( const CCSWeaponInfo *pWeaponInfo, int nTeamNumber ,CEconItemView *pItem = NULL );
bool IsBombDefuseMap() const;
bool IsHostageRescueMap() const;
bool MapHasBuyZone() const;
bool CanSpendMoneyInMap();
bool IsIntermission() const;
bool IsLogoMap() const;
bool IsSpawnPointValid( CBaseEntity *pSpot, CBasePlayer *pPlayer );
bool IsSpawnPointHiddenFromOtherPlayers( CBaseEntity *pSpot, CBasePlayer *pPlayer, int nHideFromTeam = 0 );
bool IsBuyTimeElapsed();
bool IsMatchWaitingForResume( void );
void SetMatchWaitingForResume( bool pause ) { m_bMatchWaitingForResume = pause; };
virtual int DefaultFOV();
// Get the view vectors for this mod.
virtual const CViewVectors* GetViewVectors() const;
bool IsCSGOBirthday( void );
int GetStartMoney( void );
int GetMaxMoney( void );
int GetBetweenRoundMoney( void );
bool PlayerCashAwardsEnabled( void );
bool TeamCashAwardsEnabled( void );
void AddHostageRescueTime( void );
bool IsPlayingCustomGametype( void ) const;
bool IsPlayingGunGameProgressive( void ) const;
bool IsPlayingGunGameDeathmatch( void ) const;
bool IsPlayingGunGameTRBomb( void ) const;
bool IsPlayingGunGame( void ) const;
bool IsPlayingClassic( void ) const;
bool IsPlayingOffline( void ) const;
bool IsPlayingTraining( void ) const;
bool IsPlayingCooperativeGametype( void ) const;
bool IsPlayingClassicCasual( void ) const;
bool IsPlayingAnyCompetitiveStrictRuleset( void ) const;
bool IsPlayingCoopGuardian( void ) const;
bool IsPlayingCoopMission( void ) const;
bool IsQueuedMatchmaking( void ) const;
bool IsValveDS( void ) const;
bool IsQuestEligible( void ) const;
bool ShouldRecordMatchStats( void ) const;
virtual bool IgnorePlayerKillCommand( void ) const { return IsQueuedMatchmaking() && !IsWarmupPeriod(); }
bool IsAwardsProgressAllowedForBotDifficulty() const; // returns false if the user is playing offline with trivial bots (no bots, harmless bots)
bool IsTeammateSolid( void ) const; // returns true if teammates are solid obstacles in the current game mode
bool IsArmorFree( void ) const;
bool HasHalfTime( void ) const;
bool IsRoundOver() const;
int GetCustomBotDifficulty( void ) const;
int GetCurrentGunGameWeapon ( int nCurrentWeaponIndex, int nTeamID );
int GetNextGunGameWeapon( int nCurrentWeaponIndex, int nTeamID );
int GetPreviousGunGameWeapon( int nCurrentWeaponIndex, int nTeamID );
bool IsFinalGunGameProgressiveWeapon( int nCurrentWeaponIndex, int nTeamID );
int GetGunGameNumKillsRequiredForWeapon( int nCurrentWeaponIndex, int nTeamID );
void AddGunGameWeapon( const char* pWeaponName, int nNumKillsToUpgrade, int nTeamID );
int GetNumProgressiveGunGameWeapons( int nTeamID ) const;
int GetProgressiveGunGameWeapon( int nWeaponIndex, int nTeamID ) const { return nTeamID == TEAM_CT ? m_GGProgressiveWeaponOrderCT[nWeaponIndex] : m_GGProgressiveWeaponOrderT[nWeaponIndex]; }
int GetProgressiveGunGameWeaponKillRequirement( int nWeaponIndex, int nTeamID ) const { return nTeamID == TEAM_CT ? m_GGProgressiveWeaponKillUpgradeOrderCT[nWeaponIndex] : m_GGProgressiveWeaponKillUpgradeOrderT[nWeaponIndex]; }
int GetGunGameTRBonusGrenade( CCSPlayer *pPlayer );
void IncrementGunGameTerroristWeapons( void );
void IncrementGunGameCTWeapons( void );
bool IsBotOnlyTeam( int nTeamNumber );
int TeamCashAwardValue( TeamCashAward::Type reason);
int PlayerCashAwardValue( PlayerCashAward::Type reason);
int GetMaxSpectatorSlots( void ) const;
float GetTimeUntilNextPhaseStarts( void ) { return m_timeUntilNextPhaseStarts; }
GamePhase GetGamePhase( void ) const { return ( GamePhase ) m_gamePhase.Get(); }
int GetTotalRoundsPlayed( void ) const { return m_totalRoundsPlayed; }
int GetOvertimePlaying( void ) const { return m_nOvertimePlaying; }
int GetNumWinsToClinch( void ) const;
bool IsLastRoundOfMatch() const;
bool IsMatchPoint() const;
// AreTeamsPlayingSwitchedSides() -- will return true when match is in second half, or in the half of overtime period where teams are switched.
// Overtime logic is as follows: TeamA plays CTs as first half of regulation, then Ts as second half of regulation,
// then if tied in regulation continues to play Ts as first half of 1st overtime, then switches to CTs for second half of 1st overtime,
// then if still tied after 1st OT they continue to play CTs as first half of 2nd overtime, then switch to Ts for second half of 2nd overtime,
// then if still tied after 2nd OT they continue to play Ts as first half of 3rd overtime, then switch to CTs for second half of 3rd overtime,
// and so on until the match determines a winner.
// So AreTeamsPlayingSwitchedSides will return true when TeamA is playing T-side and will return false when TeamA plays CT-side as they started match on CT
// in scenario outlined above.
bool AreTeamsPlayingSwitchedSides() const;
void SetIsWarmupPeriod( bool bIsWarmup ) { m_bWarmupPeriod = bIsWarmup; }
bool HasMatchStarted() { return m_bHasMatchStarted; }
int GetWeaponScoreForDeathmatch( int nPos );
float GetRestartRoundTime( void ) const;
#if !defined( CLIENT_DLL )
int GetCoopWaveNumber( void ) { return m_nGuardianModeWaveNumber; }
CGameCoopMissionManager *GetCoopMissionManager( void );
EHANDLE m_coopMissionManager;
void SetCoopMissionManager( CBaseEntity *pPoint ) { m_coopMissionManager = pPoint; }
void CoopSetBotQuotaAndRefreshSpawns( int nMaxEnemiesToSpawn );
void CoopMissionSetNextRespawnIn( float flSeconds, bool bIncrementWaveNumber );
void CoopMissionSpawnFirstEnemies( int nMaxEnemiesToSpawn );
void CoopMissionSpawnNextWave( int nMaxEnemiesToSpawn );
void CoopMissionRespawnDeadPlayers( void );
void CoopCollectBonusCoin( void );
virtual bool OnReplayPrompt( CBasePlayer *pVictim, CBasePlayer *pScorer ) OVERRIDE;
#endif
int GetGuardianRequiredKills( void ) const;
int GetGuardianKillsRemaining( void ) const;
int GetGuardianSpecialWeapon( void ) const;
private:
float GetExplosionDamageAdjustment(Vector & vecSrc, Vector & vecEnd, CBaseEntity *pEntityToIgnore); // returns multiplier between 0.0 and 1.0 that is the percentage of any damage done from vecSrc to vecEnd that actually makes it.
float GetAmountOfEntityVisible(Vector & src, CBaseEntity *player); // returns a value from 0 to 1 that is the percentage of player visible from src.
CNetworkVar( bool, m_bFreezePeriod ); // TRUE at beginning of round, set to FALSE when the period expires
CNetworkVar( bool, m_bWarmupPeriod ); //
CNetworkVar( float, m_fWarmupPeriodEnd ); // OBSOLETE. LEFT IN FOR DEMO COMPATIBILITY.
CNetworkVar( float, m_fWarmupPeriodStart );
CNetworkVar( bool, m_bTerroristTimeOutActive );
CNetworkVar( bool, m_bCTTimeOutActive );
CNetworkVar( float, m_flTerroristTimeOutRemaining );
CNetworkVar( float, m_flCTTimeOutRemaining );
CNetworkVar( int, m_nTerroristTimeOuts );
CNetworkVar( int, m_nCTTimeOuts );
CNetworkVar( bool, m_bMatchWaitingForResume ); // When mp_pause_match is called, this state becomes true and will prevent the next freezetime from ending.
CNetworkVar( int, m_iRoundTime ); // (From mp_roundtime) - How many seconds long this round is.
CNetworkVar( float, m_fMatchStartTime ); // time when match has started
CNetworkVar( float, m_fRoundStartTime ); // time round has started
CNetworkVar( float, m_flRestartRoundTime ); // the global time when the round is supposed to end, if this is not 0
CNetworkVar( bool, m_bGameRestart ); // True = mp_restartgame is being processed
CNetworkVar( float, m_flGameStartTime );
CNetworkVar( float, m_timeUntilNextPhaseStarts );
CNetworkVar( int, m_gamePhase );
CNetworkVar( int, m_totalRoundsPlayed);
CNetworkVar( int, m_nOvertimePlaying);
CNetworkVar( int, m_iHostagesRemaining );
CNetworkVar( bool, m_bAnyHostageReached );
CNetworkVar( bool, m_bMapHasBombTarget );
CNetworkVar( bool, m_bMapHasRescueZone );
CNetworkVar( bool, m_bMapHasBuyZone );
CNetworkVar( bool, m_bIsQueuedMatchmaking );
CNetworkVar( bool, m_bIsValveDS );
CNetworkVar( bool, m_bLogoMap ); // If there's an info_player_logo entity, then it's a logo map.
CNetworkVar( int, m_iNumGunGameProgressiveWeaponsCT ); // total number of CT gun game progressive weapons
CNetworkVar( int, m_iNumGunGameProgressiveWeaponsT ); // total number of T gun game progressive weapons
CNetworkVar( int, m_iSpectatorSlotCount ); // max spectator slots available
CNetworkArray( int, m_GGProgressiveWeaponOrderCT, 60 ); // CT gun game weapon order and # kills per weapon. Size is meant to be larger than the current number of different weapons defined in the CSWeaponID enum
CNetworkArray( int, m_GGProgressiveWeaponOrderT, 60 ); // T gun game weapon order and # kills per weapon. Size is meant to be larger than the current number of different weapons defined in the CSWeaponID enum
CNetworkArray( int, m_GGProgressiveWeaponKillUpgradeOrderCT, 60 ); // CT gun game number of kills per weapon. Size is meant to be larger than the current number of different weapons defined in the CSWeaponID enum
CNetworkArray( int, m_GGProgressiveWeaponKillUpgradeOrderT, 60 ); // T gun game number of kills per weapon. Size is meant to be larger than the current number of different weapons defined in the CSWeaponID enum
CNetworkVar( int, m_MatchDevice );
CNetworkVar( bool, m_bHasMatchStarted );
CNetworkVar( float, m_flDMBonusStartTime );
CNetworkVar( float, m_flDMBonusTimeLength );
CNetworkVar( uint16, m_unDMBonusWeaponLoadoutSlot );
CNetworkVar( bool, m_bDMBonusActive );
CNetworkVar( int, m_nNextMapInMapgroup );
CNetworkString( m_szTournamentEventName, MAX_PATH );
CNetworkString( m_szTournamentEventStage, MAX_PATH );
CNetworkString( m_szMatchStatTxt, MAX_PATH );
CNetworkString( m_szTournamentPredictionsTxt, MAX_PATH );
CNetworkVar( int, m_nTournamentPredictionsPct );
CNetworkVar( float, m_flCMMItemDropRevealStartTime );
CNetworkVar( float, m_flCMMItemDropRevealEndTime );
CNetworkVar( bool, m_bIsDroppingItems ); //
CNetworkVar( bool, m_bIsQuestEligible );
CNetworkVar( int, m_nGuardianModeWaveNumber );
CNetworkVar( int, m_nGuardianModeSpecialKillsRemaining );
CNetworkVar( int, m_nGuardianModeSpecialWeaponNeeded );
int m_nGuardianGrenadesToGiveBots;
public:
// HACK: Low on time, don't have a better place for this. Hang some global data guardian needs to bookkeep heavy spawns.
int m_nNumHeaviesToSpawn;
//
// Holiday gifts global presence
//
CNetworkVar( uint32, m_numGlobalGiftsGiven );
CNetworkVar( uint32, m_numGlobalGifters );
CNetworkVar( uint32, m_numGlobalGiftsPeriodSeconds );
CNetworkArray( uint32, m_arrFeaturedGiftersAccounts, MAX_GIFT_GIVERS_FEATURED_COUNT );
CNetworkArray( uint32, m_arrFeaturedGiftersGifts, MAX_GIFT_GIVERS_FEATURED_COUNT );
#define MAX_PROHIBITED_ITEMS 100
CNetworkArray( uint16, m_arrProhibitedItemIndices, MAX_PROHIBITED_ITEMS );
//
// Tournament Casters
//
CNetworkArray( uint32, m_arrTournamentActiveCasterAccounts, MAX_TOURNAMENT_ACTIVE_CASTER_COUNT );
// These three are part of a hack to move an expensive network call (ClientPrint) out of
// the death code and defer it by a short time. The level of network traffic is causing hitches on ps3.
// CCallQueue m_DeferredCallQueue;
// float m_flDeferredCallDispatchTime;
// Tournament best-of-N
CNetworkVar( int, m_numBestOfMaps );
// halloween mask seed
CNetworkVar( int, m_nHalloweenMaskListSeed );
CNetworkVar( bool, m_bBombDropped );
CNetworkVar( bool, m_bBombPlanted );
CNetworkVar( int, m_iRoundWinStatus ); // 1 == CT's won last round, 2 == Terrorists did, 3 == Draw, no winner
CNetworkVar( int, m_eRoundWinReason ); // see: e_RoundEndReason
CNetworkVar( bool, m_bTCantBuy ); // Who can and can't buy.
CNetworkVar( bool, m_bCTCantBuy );
CNetworkVar( float, m_flGuardianBuyUntilTime );
CNetworkArray( int, m_iMatchStats_RoundResults, MAX_MATCH_STATS_ROUNDS );
CNetworkArray( int, m_iMatchStats_PlayersAlive_CT, MAX_MATCH_STATS_ROUNDS );
CNetworkArray( int, m_iMatchStats_PlayersAlive_T, MAX_MATCH_STATS_ROUNDS );
CNetworkArray( float, m_TeamRespawnWaveTimes, MAX_TEAMS ); // Time between each team's respawn wave
CEconQuestDefinition* GetActiveAssassinationQuest( void ) const;
int GetActiveServerQuestID( void ) const { return m_iActiveAssassinationTargetMissionID; }
protected:
CNetworkArray( float, m_flNextRespawnWave, MAX_TEAMS ); // Minor waste, but cleaner code
CNetworkVar( int, m_iActiveAssassinationTargetMissionID ); // we cannot change the name of this field for networking compatibility, but in coopgametypes this means the server questid
bool m_bDontIncrementCoopWave;
public:
float GetCMMItemDropRevealDuration();
float GetCMMItemDropRevealEndTime() { return m_flCMMItemDropRevealEndTime; }
bool IsDroppingItems() { return m_bIsDroppingItems; }
loadout_positions_t GetDMBonusWeaponLoadoutSlot( void ) { return ( loadout_positions_t )m_unDMBonusWeaponLoadoutSlot.Get(); }
float GetDMBonusStartTime( void ) { return m_flDMBonusStartTime; }
float GetDMBonusTimeLength( void ) { return m_flDMBonusTimeLength; }
bool IsDMBonusActive( void ) { return m_bDMBonusActive; }
void SetNextMapInMapGroup( int nIndex ) { m_nNextMapInMapgroup = nIndex; }
int GetNextMapInMapGroup( void ) { return m_nNextMapInMapgroup; }
#if defined( GAME_DLL )
bool CheckGotGuardianModeSpecialKill( CWeaponCSBase* pAttackerWeapon );
#endif
int GetNumHostagesRemaining( void ) { return m_iHostagesRemaining; }
virtual CBaseCombatWeapon *GetNextBestWeapon( CBaseCombatCharacter *pPlayer, CBaseCombatWeapon *pCurrentWeapon );
virtual const unsigned char *GetEncryptionKey( void ) { return (unsigned char *)"d7NSuLq2"; } // both the client and server need this key
void CreateFriendlyMapNameToken( const char* szShortName, char* szOutBuffer, int nBuffSize );
// This is unlocalized and shouldn't be used for display
const char *GetDefaultTeamName( int nTeam );
void OpenBuyMenu( int nPlayerIndex );
void CloseBuyMenu( int nPlayerIndex );
// respawn
void SetNextTeamRespawnWaveDelay( int iTeam, float flDelay );
virtual float GetNextRespawnWave( int iTeam, CBasePlayer *pPlayer );
float GetMinTimeWhenPlayerMaySpawn( CBasePlayer *pPlayer );
float GetRespawnWaveMaxLength( int iTeam, bool bScaleWithNumPlayers = true );
float GetRespawnTimeScalar( int iTeam );
//float GetTimeUntilEndMatchNextMapVoteEnds( void );
bool IsEndMatchVotingForNextMap();
bool IsEndMatchVotingForNextMapEnabled();
// End Match Voting
CNetworkArray( int, m_nEndMatchMapGroupVoteOptions, MAX_ENDMATCH_VOTE_PANELS ); // For mapgroups >10 maps these will be vote options
// these functions cover recording and sending item drops for display in game modes where you don't allow drops during the match/round
CUtlVector< CEconItemPreviewDataBlock * > m_ItemsPtrDroppedDuringMatch;
const CUtlVector< CEconItemPreviewDataBlock * >& GetItemsDroppedDuringMatch( void ) const
{
return m_ItemsPtrDroppedDuringMatch;
}
void ClearItemsDroppedDuringMatch( void );
void RecordPlayerItemDrop( const CEconItemPreviewDataBlock &iteminfo );
static int GetMaxPlayers(); // always available
// COOP
void CoopResetRoundStartTime( void );
void CoopGiveC4sToCTs( int nC4sToGive );
#ifndef CLIENT_DLL
int m_coopBonusCoinsFound;
bool m_coopBonusPistolsOnly;
bool m_coopPlayersInDeploymentZone;
#endif
#ifdef CLIENT_DLL
DECLARE_CLIENTCLASS_NOBASE(); // This makes datatables able to access our private vars.
CCSGameRules();
~CCSGameRules();
// helper function - this will eventually support side car info (and will probably move)
const wchar_t* GetFriendlyMapName( const char* szShortName );
bool GetFriendlyMapNameToken( const char* szShortName, char* szOutBuffer, int nBuffSize );
char const * GetTournamentEventName() const;
char const * GetTournamentEventStage() const;
char const * GetTournamentPredictionsTxt() const { return m_szTournamentPredictionsTxt; }
int GetTournamentPredictionsPct() const { return m_nTournamentPredictionsPct; }
char const * GetMatchStatTeamsTxt() const { return m_szMatchStatTxt; }
CUserMessageBinder m_UMCMsgSendPlayerItemDrops;
CUserMessageBinder m_UMCMsgSendPlayerItemFound;
bool m_bMarkClientStopRecordAtRoundEnd;
static void RecvProxy_TournamentActiveCasterAccounts( const CRecvProxyData *pData, void *pStruct, void *pOut );
void ResetCasterConvars( void );
#else
DECLARE_SERVERCLASS_NOBASE(); // This makes datatables able to access our private vars.
CCSGameRules();
virtual ~CCSGameRules();
virtual void RefreshSkillData( bool forceUpdate );
void DumpTimers( void ) const; // debugging to help track down a stuck server (rare?)
CBaseEntity *GetPlayerSpawnSpot( CBasePlayer *pPlayer );
static void EndRound();
virtual void PlayerKilled( CBasePlayer *pVictim, const CTakeDamageInfo &info );
virtual void Think();
void SwitchTeamsAtRoundReset( void );
void ClearGunGameData( void );
void FreezePlayers( void );
// Called at the end of GameFrame (i.e. after all game logic has run this frame)
virtual void EndGameFrame( void );
// Called when game rules are destroyed by CWorld
virtual void LevelShutdown( void );
void UpdateTeamClanNames( int nTeam );
void UpdateTeamPredictions();
// vscript function
void SetPlayerCompletedTraining( bool bCompleted );
bool GetPlayerCompletedTraining( void );
void SetBestTrainingCourseTime( int nTime );
int GetBestTrainingCourseTime( void );
int GetValveTrainingCourseTime( void );
bool IsLocalPlayerUsingController( void );
void TrainingGivePlayerAmmo( void );
void TrainingSetRadarHidden( bool bHide );
void TrainingSetMiniScoreHidden( bool bHide );
void TrainingHighlightAmmoCounter( void );
void TrainingShowFinishMsgBox( void );
void TrainingShowExitDoorMsg( void );
virtual void RegisterScriptFunctions( void );
virtual bool ClientCommand( CBaseEntity *pEdict, const CCommand &args );
virtual void PlayerSpawn( CBasePlayer *pPlayer );
void ShowSpawnPoints( int duration );
virtual void SpawningLatePlayer( CCSPlayer* pLatePlayer );
bool IsPistolRound( void );
void HostageKilled( void ) { m_hostageWasKilled = true; }
void HostageInjured( void ) { m_hostageWasInjured = true; }
bool WasHostageKilled( void ) { return m_hostageWasKilled; }
bool WasHostageInjured( void ) { return m_hostageWasInjured; }
void PlayerTookDamage( CCSPlayer* player, const CTakeDamageInfo &damageInfo );
void SendKickBanToGC( CCSPlayer *pPlayer, EMsgGCCStrike15_v2_MatchmakingKickBanReason_t eReason );
void SendKickBanToGCforAccountId( uint32 uiAccountId, EMsgGCCStrike15_v2_MatchmakingKickBanReason_t eReason );
virtual bool PlayTextureSounds( void ) { return true; }
// Let the game rules specify if fall death should fade screen to black
virtual bool FlPlayerFallDeathDoesScreenFade( CBasePlayer *pl ) { return FALSE; }
virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore );
void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, bool bIgnoreWorld );
virtual void UpdateClientData( CBasePlayer *pl );
virtual CCSPlayer* CheckAndAwardAssists( CCSPlayer* pCSVictim, CCSPlayer* pKiller );
// Death notices
virtual void DeathNotice( CBasePlayer *pVictim, const CTakeDamageInfo &info );
IGameEvent * CreateWeaponKillGameEvent( char const *szEventName, const CTakeDamageInfo &info );
virtual void InitDefaultAIRelationships( void );
virtual const char *GetGameDescription( void ) { return "Counter-Strike: Global Offensive"; } // this is the game name that gets seen in the server browser
virtual const char *AIClassText(int classType);
virtual bool FShouldSwitchWeapon( CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon );
virtual const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer );
// Called before entities are created
virtual void LevelInitPreEntity();
// Called after the map has finished loading.
virtual void LevelInitPostEntity();
virtual float FlPlayerFallDamage( CBasePlayer *pPlayer );
virtual bool ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen );
virtual void ClientDisconnected( edict_t *pClient );
virtual void ClientCommandKeyValues( edict_t *pEntity, KeyValues *pKeyValues );
virtual int GetMaxHumanPlayers() const;
// Recreate all the map entities from the map data (preserving their indices),
// then remove everything else except the players.
// Also get rid of all world decals.
void CleanUpMap();
void CheckFreezePeriodExpired();
void CheckRoundTimeExpired();
// check if the scenario has been won/lost
// return true if the scenario is over, false if the scenario is still in progress
bool CheckWinConditions( void );
// this is used by entities like X and increments the round and ends it
void IncrementAndTerminateRound( float tmDelay, int reason );
void TerminateRound( float tmDelay, int reason );
void ProcessEndOfRoundAchievements( int iWinnerTeam, int iReason );
void SaveRoundDataInformation( char const *szFilenameOverride = NULL );
void LoadRoundDataInformation( char const *szFilename );
void ResetMasterSpawnPointsForCoop( void );
// The following round-related functions are called as follows:
//
// At Match Start:
// PreRestartRound() -> RestartRound() -> PostRestartRound()
//
// During Subsequent Round Gameplay:
// RoundWin() is called at the point when the winner of the round has been determined - prior to free-play commencing
// PreRestartRound() is called with 1 second remaining prior to the round officially ending (This is after a round
// winner has been chosen and players are allowed to continue playing)
// RoundEnd() is then called when the round has completely ended
// RestartRound() is then called immediately after RoundEnd()
// PostRestartRound() is called immediately after RestartRound() has completed
void PreRestartRound( void );
void RestartRound( void );
void PostRestartRound( void );
void RoundWin( void );
void RoundEnd( void );
int GetRoundsPlayed( void ) const { return m_match.GetRoundsPlayed(); }
void BalanceTeams( void );
void HandleScrambleTeams( void );
void HandleSwapTeams( void );
void MoveHumansToHumanTeam( void );
bool TeamFull( int team_id );
int MaxNumPlayersOnTerrTeam();
int MaxNumPlayersOnCTTeam();
bool WillTeamHaveRoomForPlayer( CCSPlayer* pPlayer, int newTeam );
bool TeamStacked( int newTeam_id, int curTeam_id );
bool FPlayerCanRespawn( CBasePlayer *pPlayer );
void UpdateTeamScores();
void CheckMapConditions();
void MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(int team);
// Check various conditions to end the map.
bool CheckGameOver();
bool CheckWinLimit();
bool CheckFragLimit();
void CheckLevelInitialized();
void CheckRestartRound();
virtual bool FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker );
virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled );
bool CanPlayerHearTalker( CBasePlayer* pListener, CBasePlayer *pSpeaker, bool bTeamOnly );
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget );
virtual bool PlayerCanHearChat( CBasePlayer *pListener, CBasePlayer *pSpeaker, bool bTeamOnly );
void GuardianUpdateBotAccountAndWeapons( CCSPlayer *pBot );
void GiveGuardianBotGrenades( CCSPlayer *pBot );
// repsawning
void SetTeamRespawnWaveTime( int iTeam, float flValue );
virtual bool HasPassedMinRespawnTime( CBasePlayer *pPlayer );
void CheckRespawnWaves( void );
// Checks if it still needs players to start a round, or if it has enough players to start rounds.
// Starts a round and returns true if there are enough players.
bool NeededPlayersCheck( bool &bNeededPlayers );
// Setup counts for m_iNumTerrorist, m_iNumCT, m_iNumSpawnableTerrorist, m_iNumSpawnableCT, etc.
void InitializePlayerCounts(
int &NumAliveTerrorist,
int &NumAliveCT,
int &NumDeadTerrorist,
int &NumDeadCT
);
// Check to see if the round is over for the various game types. Terminates the round
// and returns true if the round should end.
bool PrisonRoundEndCheck();
bool BombRoundEndCheck( bool bNeededPlayers );
bool HostageRescueRoundEndCheck( bool bNeededPlayers );
bool BombPlantedRoundEndCheck();
bool CTsReachedHostageRoundEndCheck();
bool GuardianAllKillsAchievedCheck();
bool m_bHasHostageBeenTouched;
CCSPlayer* CalculateEndOfRoundMVP();
// Check to see if the teams exterminated each other. Ends the round and returns true if so.
bool TeamExterminationCheck(
int NumAliveTerrorist,
int NumAliveCT,
int NumDeadTerrorist,
int NumDeadCT,
bool bNeededPlayers
);
void ReadMultiplayCvars();
void SwapAllPlayers();
void OnTeamsSwappedAtRoundReset();
void ResetForTradeshow( void ); // reset player scores, reset team scores, reset player controls, restart round; used for demos
void BroadcastSound( const char *sound, int team = -1 );
// GUN GAME PROGRESSIVE FUNCTION
bool GunGameProgressiveEndCheck( void );
// BOMB MAP FUNCTIONS
void GiveC4ToRandomPlayer();
void GiveDefuserToRandomPlayer();
CCSPlayer *IsThereABomber();
bool IsThereABomb();
// HOSTAGE MAP FUNCTIONS
void HostageTouched();
// Contribution score helpers
void ScorePlayerKill( CCSPlayer* pPlayer );
void ScorePlayerAssist( CCSPlayer* pPlayer, CCSPlayer* pCSVictim );
void ScorePlayerObjectiveKill( CCSPlayer* pPlayer );
void ScorePlayerSuicide( CCSPlayer* pPlayer );
void ScorePlayerTeamKill( CCSPlayer* pPlayer );
void ScorePlayerDamage( CCSPlayer* pPlayer, float fDamage );
void ScoreBombPlant( CCSPlayer* pPlayer );
void ScoreBombExploded( CCSPlayer* pPlayer );
void ScoreBombDefuse( CCSPlayer* pPlayer, bool bMajorEvent );
void ScoreHostageRescue( CCSPlayer* pPlayer, CHostage* pHostage, bool bMajorEvent );
void ScoreHostageKilled( CCSPlayer* pPlayer );
void ScoreHostageDamage( CCSPlayer* pPlayer, float fDamage );
void ScoreFriendlyFire( CCSPlayer* pPlayer, float fDamage );
void ScoreBlindEnemy( CCSPlayer* pPlayer );
void ScoreBlindFriendly( CCSPlayer* pPlayer );
// Sets up g_pPlayerResource.
virtual void CreateStandardEntities();
virtual const char *GetChatPrefix( bool bTeamOnly, CBasePlayer *pPlayer );
virtual const char *GetChatLocation( bool bTeamOnly, CBasePlayer *pPlayer );
virtual const char *GetChatFormat( bool bTeamOnly, CBasePlayer *pPlayer );
void ClientSettingsChanged( CBasePlayer *pPlayer );
virtual bool CanClientCustomizeOwnIdentity() OVERRIDE;
bool IsCareer( void ) const { return false; } // returns true if this is a CZ "career" game
virtual bool FAllowNPCs( void );
bool CheckSetVoteTime();
void GoToMatchRestartIntermission();
CCSMatch* GetMatch( void );
// Let's the match store recplicated vars in the game rules.
void SetGamePhase( GamePhase newPhase ) { m_gamePhase = newPhase; }
void SetTotalRoundsPlayed( int roundsPlayed ) { m_totalRoundsPlayed = roundsPlayed; }
void SetOvertimePlaying( int nOvertimePlaying ) { m_nOvertimePlaying = nOvertimePlaying; }
void SetScrambleTeamsOnRestart( bool scramble ) { m_bScrambleTeamsOnRestart = scramble; }
bool GetScrambleTeamsOnRestart( void ) { return m_bScrambleTeamsOnRestart; }
void SetSwapTeamsOnRestart( bool swapTeams ) { m_bSwapTeamsOnRestart = swapTeams; }
bool GetSwapTeamsOnRestart( void ) { return m_bSwapTeamsOnRestart; }
bool GameModeSupportsHealthBuffer( void );
protected:
// these functions cover recording and sending item drops for display in game modes where you don't allow drops during the match/round
void SendPlayerItemDropsToClient( void );
bool m_bPlayerItemsHaveBeenDisplayed;
void RewardMatchEndDrops( bool bAbortedMatch );
virtual void GoToIntermission( bool bAbortedMatch = false );
void UpdateMatchStats( CCSPlayer* pPlayer, int winnerIndex ) ;
static void SplitScoreAmongPlayersInZone( int iPoints, int iTeam, CCSPlayer* pExcludePlayer, uint iPlace );
static void SplitScoreAmongPlayersInRange( int iPoints, int iTeam, CCSPlayer* pExcludePlayer, const Vector& center, float fRangeInner, float fRangeOuter );
void GotoTRBombModeHalftime( void );
void EndTRBombModeHalftime( void );
float CalculateAveragePlayerContributionScore( void );
float CalculateAverageBotContributionScore( void );
public:
void ModifyRealtimeBotDifficulty( CCSPlayer* pOnlyBotToProcess = NULL );
public:
bool IsFriendlyFireOn() const;
bool IsLastRoundBeforeHalfTime( void );
virtual void SetAllowWeaponSwitch( bool allow );
virtual bool GetAllowWeaponSwitch( void );
bool ShouldGunGameSpawnBomb( void );
void SetGunGameSpawnBomb( bool allow );
bool IsClanTeam( CTeam *pTeam );
//int GetEndMatchCurrentMapVotes();
// VARIABLES FOR ALL TYPES OF MAPS
bool m_bLevelInitialized;
int m_iTotalRoundsPlayed;
int m_iUnBalancedRounds; // keeps track of the # of consecutive rounds that have gone by where one team outnumbers the other team by more than 2
bool m_endMatchOnRoundReset;
bool m_endMatchOnThink;
float m_flCoopRespawnAndHealTime;
// GAME TIMES
int m_iFreezeTime; // (From mp_freezetime) - How many seconds long the intro round (when players are frozen) is.
int m_iNumTerrorist; // The number of terrorists on the team (this is generated at the end of a round)
int m_iNumCT; // The number of CTs on the team (this is generated at the end of a round)
int m_iNumSpawnableTerrorist;
int m_iNumSpawnableCT;
CUtlVector< int > m_arrSelectedHostageSpawnIndices; // The indices of hostage spawn locations selected for the match
bool m_bFirstConnected;
bool m_bCompleteReset; // Set to TRUE to have the scores reset next time round restarts
bool m_bPickNewTeamsOnReset;
bool m_bScrambleTeamsOnRestart;
bool m_bSwapTeamsOnRestart;
enum EEndMatchMapVoteState_t
{
k_EEndMatchMapVoteState_MatchInProgress,
k_EEndMatchMapVoteState_VoteInProgress,
k_EEndMatchMapVoteState_VoteTimeEnded,
k_EEndMatchMapVoteState_AllPlayersVoted,
k_EEndMatchMapVoteState_SelectingWinner,
k_EEndMatchMapVoteState_SettingNextLevel,
k_EEndMatchMapVoteState_VoteAllDone,
};
#ifndef CLIENT_DLL
EEndMatchMapVoteState_t m_eEndMatchMapVoteState;
int m_nEndMatchMapVoteWinner;
CUtlVector<int> m_nEndMatchTiedVotes;
void CreateEndMatchMapGroupVoteOptions( void );
enum EQueuedMatchmakingRematchState_t
{
k_EQueuedMatchmakingRematchState_MatchInProgress,
k_EQueuedMatchmakingRematchState_VoteStarting,
k_EQueuedMatchmakingRematchState_VoteToRematchInProgress,
k_EQueuedMatchmakingRematchState_VoteToRematchSucceeded,
k_EQueuedMatchmakingRematchState_VoteToRematchFailed,
k_EQueuedMatchmakingRematchState_VoteToRematchFailed_Done,
k_EQueuedMatchmakingRematchState_VoteToRematch_Done,
k_EQueuedMatchmakingRematchState_VoteToRematch_T_Surrender,
k_EQueuedMatchmakingRematchState_VoteToRematch_CT_Surrender,
k_EQueuedMatchmakingRematchState_VoteToRematch_Aborted,
};
EQueuedMatchmakingRematchState_t m_eQueuedMatchmakingRematchState;
bool m_bNeedToAskPlayersForContinueVote;
uint32 m_numQueuedMatchmakingAccounts;
char *m_pQueuedMatchmakingReservationString;
uint32 m_numTotalTournamentDrops;
uint32 m_numSpectatorsCountMax;
uint32 m_numSpectatorsCountMaxTV;
uint32 m_numSpectatorsCountMaxLnk;
CMsgGCCStrike15_v2_MatchmakingServerRoundStats *m_pQueuedMatchmakingReportedRoundStats;
static CMsgGCCStrike15_v2_MatchmakingGC2ServerReserve sm_QueuedServerReservation;
void ReportRoundEndStatsToGC( CMsgGCCStrike15_v2_MatchmakingServerRoundStats **ppAllocateStats = NULL );
struct CQMMPlayerData_t
{
CQMMPlayerData_t()
{
Q_memset( this, 0, offsetof( CQMMPlayerData_t, m_uiCustomNonPodFields ) );
}
void Reset()
{ // Reset everything starting from m_numKills to the end
Q_memset( ( ( char * ) this ) + offsetof( CQMMPlayerData_t, m_numKills ), 0,
offsetof( CQMMPlayerData_t, m_uiCustomNonPodFields ) - offsetof( CQMMPlayerData_t, m_numKills ) );
}
uint32 m_uiPlayerAccountId; // QMM player account ID
int m_iDraftIndex; // Index of the player in the draft [0-4: team 1; 5-9: team 2]
uint32 m_msDisconnectionTimestamp; // Timestamp of player's disconnection if not 0
uint32 m_uiAbandonRecordedReason; // We recorded the fact that the player abandoned the match and this is the reason
bool m_bAbandonAllowsSurrender; // This player abandoning the match allows for his teammates to surrender
char m_chPlayerName[128]; // Last known player name
bool m_bEverFullyConnected; // Has this player ever connected to the server
bool m_bDisconnection1MinWarningPrinted; // Whether 1 minute warning has been printed
// RESETTABLE SECTION:
int m_numKills; // number of kills
int m_numAssists; // number of assists
int m_numDeaths; // number of deaths
int m_numScorePoints; // number of score points
int m_numMVPs; // number of MVP rounds
int m_cash; // player's cash
int m_numTeamKills; // number of team kills
int m_numTeamDamagePoints; // number of team damage points
int m_numHostageKills; // number of hostages killed
int m_numEnemyKills; // number of enemies killed
int m_numEnemyKillHeadshots; // number of enemies killed with headshot
int m_numEnemy3Ks; // number of 3Ks
int m_numEnemy4Ks; // number of 4Ks
int m_numEnemy5Ks; // number of 5Ks
int m_numEnemyKillsAgg; // number of enemies killed on aggregate
int m_numRoundsWon; // rounds won
int m_numFirstKills; // number of times this player got first kill of the round
int m_numClutchKills; // number of times this player got a kill with no teammates alive
int m_numPistolKills; // number of pistol kills this player got
int m_numSniperKills; // number of sniper kills this player got
int m_numHealthPointsRemovedTotal; // total number of health points removed (used for coop gameplay)
int m_numHealthPointsDealtTotal; // total number of health points dmg dealt to enemies (used for coop gameplay)
int m_numShotsFiredTotal; // total number of shots fired (incremented by one every time player pulls trigger, not per each shotgun pellet; used for coop gameplay)
int m_numShotsOnTargetTotal; // total number of shots on target (incremented by no moer than one per each time player pulls trigger, not per each shotgun pellet; used for coop gameplay)
bool m_bReceiveNoMoneyNextRound; // player is marked to not receive any money next round
// match stat data for the spectator graphs
int m_iMatchStats_Kills[MAX_MATCH_STATS_ROUNDS];
int m_iMatchStats_Damage[MAX_MATCH_STATS_ROUNDS];
int m_iMatchStats_EquipmentValue[MAX_MATCH_STATS_ROUNDS];
int m_iMatchStats_MoneySaved[MAX_MATCH_STATS_ROUNDS];
int m_iMatchStats_KillReward[MAX_MATCH_STATS_ROUNDS];
int m_iMatchStats_LiveTime[MAX_MATCH_STATS_ROUNDS];
int m_iMatchStats_Deaths[ MAX_MATCH_STATS_ROUNDS ];
int m_iMatchStats_Assists[ MAX_MATCH_STATS_ROUNDS ];
int m_iMatchStats_HeadShotKills[ MAX_MATCH_STATS_ROUNDS ];
int m_iMatchStats_Objective[ MAX_MATCH_STATS_ROUNDS ];
int m_iMatchStats_CashEarned[ MAX_MATCH_STATS_ROUNDS ];
int m_iMatchStats_UtilityDamage[ MAX_MATCH_STATS_ROUNDS ];
int m_iMatchStats_EnemiesFlashed[ MAX_MATCH_STATS_ROUNDS ];
// per weapon kills
uint32 m_uiCustomNonPodFields;
// END RESETTABLE SECTION
CUtlMap< uint32, uint32, int, CDefLess< uint32 > > m_mapQuestEventPoints;
// TODO: If we have more attributes we want to be processed with the timed rewards job, try to generify this
typedef CUtlMap< itemid_t, attrib_value_t, int, CDefLess< itemid_t > > StattrakMusicKitValues_t;
StattrakMusicKitValues_t m_mapMusicKitUpdates;
// once the player purchases an econ item, cache it and rebuy it from the cache.
typedef CUtlMap< uint16, item_definition_index_t, int16, CDefLess< uint16 > > LoadoutSlotToDefIndexMap_t;
LoadoutSlotToDefIndexMap_t m_mapLoadoutSlotToItem[ 2 ];
};
typedef CUtlMap< uint32, CQMMPlayerData_t *, int32, CDefLess< uint32 > > QueuedMatchmakingPlayersDataMap_t;
QueuedMatchmakingPlayersDataMap_t m_mapQueuedMatchmakingPlayersData;
CQMMPlayerData_t * QueuedMatchmakingPlayersDataFind( uint32 uiAccountID ) const
{
if ( !uiAccountID ) return NULL;
QueuedMatchmakingPlayersDataMap_t::IndexType_t idx = m_mapQueuedMatchmakingPlayersData.Find( uiAccountID );
return ( idx == m_mapQueuedMatchmakingPlayersData.InvalidIndex() ) ? NULL : m_mapQueuedMatchmakingPlayersData.Element( idx );
}
CQMMPlayerData_t * QueuedMatchmakingPlayersDataFindOrCreate( CCSPlayer *pPlayer );
struct CGcBanInformation_t
{
uint32 m_uiReason;
double m_dblExpiration;
};
typedef CUtlMap< uint32, CGcBanInformation_t > GcBanInformationMap_t;
static GcBanInformationMap_t sm_mapGcBanInformation;
bool m_bForceTeamChangeSilent;
bool m_bLoadingRoundBackupData;
class ICalculateEndOfRoundMVPHook_t
{
public:
virtual CCSPlayer* CalculateEndOfRoundMVP() = 0;
};
ICalculateEndOfRoundMVPHook_t *m_pfnCalculateEndOfRoundMVPHook;
typedef CUtlMap< int32, uint32, int32, CDefLess< int32 > > MapMatchInfoShownCounts;
MapMatchInfoShownCounts m_mapMatchInfoShownCounts; // tracks how many times each match info piece was shown
enum MapMatchInfoShownCountsSpecial_t
{
k_MapMatchInfoShownCounts_None = 0xF0000,
k_MapMatchInfoShownCounts_Predictions = 0xF0001,
k_MapMatchInfoShownCounts_MapDraft = 0xF0002,
};
int m_nMatchInfoShowType; // which match info is preferred to be shown
float m_flMatchInfoDecidedTime; // what curtime moment was when match info was decided
struct ServerPlayerDecalData_t
{
ServerPlayerDecalData_t() { V_memset( this, 0, sizeof(*this) ); }
bool operator == ( ServerPlayerDecalData_t const &x ) const { return !V_memcmp( this, &x, offsetof( ServerPlayerDecalData_t, m_rtGcTime ) ); }
AccountID_t m_unAccountID;
int m_nTraceID;
Vector m_vecOrigin;
Vector m_vecStart;
Vector m_vecRight;
Vector m_vecNormal;
int m_nEquipSlot;
int m_nPlayer;
int m_nEntity;
int m_nHitbox;
int m_nTintID;
float m_flCreationTime;
uint32 m_rtGcTime; // not participating in memcmp (set by GC, authoritative)
void CopyToMsg( CCSUsrMsg_PlayerDecalDigitalSignature &msg ) const;
void InitFromMsg( CCSUsrMsg_PlayerDecalDigitalSignature const &msg );
};
CUtlVector< ServerPlayerDecalData_t > m_arrServerPlayerDecalData;
#endif
int m_iAccountTerrorist;
int m_iAccountCT;
int m_iNumConsecutiveCTLoses; //SupraFiend: the number of rounds the CTs have lost in a row.
int m_iNumConsecutiveTerroristLoses;//SupraFiend: the number of rounds the Terrorists have lost in a row.
int m_iSpawnPointCount_Terrorist; // Number of Terrorist spawn points
int m_iSpawnPointCount_CT; // Number of CT spawn points
int m_iMaxNumTerrorists;
int m_iMaxNumCTs;
int m_iLoserBonus; // SupraFiend: the amount of money the losing team gets. This scales up as they lose more rounds in a row
float m_tmNextPeriodicThink;
bool m_bVoiceWonMatchBragFired;
float m_fWarmupNextChatNoticeTime;
CHandle<CCSPlayer> m_pMVP;
// HOSTAGE RESCUE VARIABLES
int m_iHostagesRescued;
int m_iHostagesTouched;
float m_flNextHostageAnnouncement;
// [tj] Accessor for weapons donation ability
bool GetCanDonateWeapon( void ) { return m_bCanDonateWeapons; }
// [tj] flawless and lossless round related flags
bool m_bNoTerroristsKilled;
bool m_bNoCTsKilled;
bool m_bNoTerroristsDamaged;
bool m_bNoCTsDamaged;
bool m_bNoEnemiesKilled;
// [tj] Find out if dropped weapons count as donations
bool m_bCanDonateWeapons;
// [tj] Keep track of first kill
CHandle<CCSPlayer> m_pFirstKill;
float m_firstKillTime;
// [menglish] Keep track of first blood
CHandle<CCSPlayer> m_pFirstBlood;
float m_firstBloodTime;
// [dwenger] Rescue-related achievement values
CUtlVector< CHandle<CCSPlayer> > m_arrRescuers;
bool m_hostageWasInjured;
bool m_hostageWasKilled;
// [menglish] Fun Fact Manager
CCSFunFactMgr *m_pFunFactManager;
// Automatic vote called near the end of a map
bool m_bVoteCalled;
bool m_bServerVoteOnReset;
float m_flVoteCheckThrottle;
// [tj] To avoid rewriting the same piece of code, we can get all the information
// we want from one call that fills in an array of structures.
struct TeamPlayerCounts
{
int totalPlayers;
int totalAlivePlayers;
int totalDeadPlayers; //sum of killedPlayers + suicidedPlayers + unenteredPlayers
int killedPlayers;
int suicidedPlayers;
int unenteredPlayers;
};
void GetPlayerCounts( TeamPlayerCounts teamCounts[TEAM_MAXCOUNT] );
bool m_bBuyTimeEnded;
int m_nLastFreezeEndBeep;
// PRISON ESCAPE VARIABLES
int m_iHaveEscaped;
bool m_bMapHasEscapeZone;
int m_iNumEscapers;
int m_iNumEscapeRounds; // keeps track of the # of consecutive rounds of escape played.. Teams will be swapped after 8 rounds
// BOMB MAP VARIABLES
bool m_bTargetBombed; // whether or not the bomb has been bombed
bool m_bBombDefused; // whether or not the bomb has been defused
bool m_bMapHasBombZone;
/* bool m_bBombPlanted;*/
bool m_bGunGameRespawnWithBomb; // Whether or not the next terrorist to spawn should have the bomb
float m_fGunGameBombRespawnTimer; // Time until the bomb can be respawned
void AddTeamAccount( int team, TeamCashAward::Type reason );
void AddTeamAccount( int team, TeamCashAward::Type reason, int amount, const char* szAwardText = NULL );
public:
CBaseEntity* GetNextSpawnpoint( int teamNumber );
void DoCoopSpawnAndNavInit( void );
void AddSpawnPointToMasterList( SpawnPoint* pSpawnPoint );
void GenerateSpawnPointListsFirstTime( void );
void RefreshCurrentSpawnPointLists( void );
CCSMatch m_match;
Vector m_vecMainCTSpawnPos;
void ShuffleSpawnPointLists( void );
void ShuffleMasterSpawnPointLists( void );
void SortSpawnPointLists( void );
void SortMasterSpawnPointLists( void );
void ShufflePlayerList( CUtlVector< CCSPlayer* > &playersList );
protected:
CUtlVector< SpawnPoint* > m_CTSpawnPointsMasterList; // The master list of CT spawn points (contains all points whether enabled or disabled)
CUtlVector< SpawnPoint* > m_TerroristSpawnPointsMasterList; // The master list of Terrorist spawn points (contains all points whether enabled or disabled)
int m_iNextCTSpawnPoint; // Used when picking the next CT spawn point to assign
int m_iNextTerroristSpawnPoint; // Used when picking the next Terrorist spawn point to assign
CUtlVector< SpawnPoint* > m_CTSpawnPoints; // List of CT spawn points sorted by their priorities
CUtlVector< SpawnPoint* > m_TerroristSpawnPoints; // List of Terrorist spawn points sorted by their priorities
private:
float m_fAutobalanceDisplayTime;
AutobalanceStatus::Type m_AutobalanceStatus;
CRecipientFilter m_AutoBalanceTraitors;
CRecipientFilter m_AutoBalanceLoyalists;
// Don't allow switching weapons while gaining new technologies
bool m_bAllowWeaponSwitch;
bool m_bRoundTimeWarningTriggered;
float m_phaseChangeAnnouncementTime;
float m_fNextUpdateTeamClanNamesTime;
float m_flLastThinkTime;
CRecipientFilter m_filterTerrorist;
CRecipientFilter m_filterCT;
#endif
// Methods & memeber variables on both client and server DLLs
public:
virtual bool ForceSplitScreenPlayersOnToSameTeam( void );
void UpdatePlayerEloBracket( CCSPlayer *pPlayer, int32 bracket );
bool IsSwitchingTeamsAtRoundReset( void ) { return m_bSwitchingTeamsAtRoundReset; }
float CheckTotalSmokedLength( float flRadius, Vector vecGrenadePos, Vector from, Vector to );
protected:
loadout_positions_t PickRandomWeaponForDMBonus( void );
void AssignStartingMoneyToAllPlayers( void );
void InitializeGameTypeAndMode( void );
bool m_bHasTriggeredRoundStartMusic;
bool m_bHasTriggeredCoopSpawnReset;
public:
BotProfileDevice_t GetMatchDevice( void ) const { return ( BotProfileDevice_t )( m_MatchDevice.Get() ); }
void AddDroppedWeaponToList( CWeaponCSBase *pWeapon );
void RemoveDroppedWeaponFromList( CWeaponCSBase *pWeapon );
int GetTotalDroppedWeaponsInWorld( void ) { return m_weaponsDroppedInWorld.Count(); }
protected:
void ProcessAutoBalance( void );
private:
void UnfreezeAllPlayers( void );
bool m_bSwitchingTeamsAtRoundReset;
int m_iMaxGunGameProgressiveWeaponIndex;
CUtlVector< CHandle<CWeaponCSBase> > m_weaponsDroppedInWorld;
};
bool EconEntity_OnOwnerKillEaterEvent( CEconItemView *pEconItemView, CCSPlayer *pOwner, CCSPlayer *pVictim, kill_eater_event_t eEventType, int iAmount = 1, uint32 *pNewValue = NULL );
//-----------------------------------------------------------------------------
// Gets us at the team fortress game rules
//-----------------------------------------------------------------------------
inline CCSGameRules* CSGameRules()
{
return static_cast<CCSGameRules*>(g_pGameRules);
}
#define IGNORE_SPECTATORS false
#define IGNORE_UNASSIGNED true
int UTIL_HumansInGame( bool ignoreSpectators = false, bool ignoreUnassigned = false );
int UTIL_SpectatorsInGame( void );
//-----------------------------------------------------------------------------
// Music Selection
//-----------------------------------------------------------------------------
enum CsMusicType_t
{
CSMUSIC_NONE = 0,
CSMUSIC_STARTGG,
CSMUSIC_START,
CSMUSIC_ACTION,
CSMUSIC_DEATHCAM,
CSMUSIC_BOMB,
CSMUSIC_BOMBTEN,
CSMUSIC_ROUNDTEN,
CSMUSIC_WONROUND,
CSMUSIC_LOSTROUND,
CSMUSIC_HOSTAGE,
CSMUSIC_MVP,
CSMUSIC_SELECTION,
CSMUSIC_HALFTIME
};
#define CSMUSIC_NOPACK 0
#ifdef CLIENT_DLL
void PlayMusicSelection( IRecipientFilter& filter, CsMusicType_t nMusicType , int nPlayerEntIndex = 0 , float flPreElapsedTime = 0.0 );
#endif
//-----------------------------------------------------------------------------
// Purpose: Useful utility functions
//-----------------------------------------------------------------------------
#ifdef CLIENT_DLL
#else
class CTFTeam;
CTFTeam *GetOpposingTeam( CTeam *pTeam );
bool EntityPlacementTest( CBaseEntity *pMainEnt, const Vector &vOrigin, Vector &outPos, bool bDropToGround, unsigned int mask = MASK_SOLID, ITraceFilter *pFilter = NULL );
#endif
// Assassination quest helper funcs
bool IsAssassinationQuest( const CEconQuestDefinition *pQuest );
bool IsAssassinationQuest( uint32 questID );
bool IsAssassinationQuestActive( const CEconQuestDefinition *pQuest );
extern const float g_flWarmupToFreezetimeDelay;
#endif // TF_GAMERULES_H