//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #ifndef TF_GAMESTATS_H #define TF_GAMESTATS_H #ifdef _WIN32 #pragma once #endif #include "gamestats.h" #include "tf_obj.h" #include "tf_gamestats_shared.h" #include "GameEventListener.h" class CTFPlayer; //============================================================================= // // TF Game Stats Class // class CTFGameStats : public CBaseGameStats, public CGameEventListener, public CAutoGameSystem { public: // Constructor/Destructor. CTFGameStats( void ); ~CTFGameStats( void ); virtual void Clear( void ); virtual bool UseOldFormat() { return false; } virtual bool AddDataForSend( KeyValues *pKV, StatSendType_t sendType ); void AddMapData( KeyValues *pKV, TF_Gamestats_LevelStats_t *pCurrentMap ); virtual bool Init(); virtual void LevelInitPreEntity(); virtual void LevelShutdownPreClearSteamAPIContext(); // Events. virtual void Event_LevelInit( void ); virtual void Event_LevelShutdown( float flElapsed ); virtual void Event_PlayerKilled( CBasePlayer *pPlayer, const CTakeDamageInfo &info ); void Event_RoundStart(); void Event_RoundEnd( int iWinningTeam, bool bFullRound, float flRoundTime, bool bWasSuddenDeathWin ); void Event_GameEnd(); void Event_PlayerConnected( CBasePlayer *pPlayer ); void Event_PlayerDisconnected( CTFPlayer *pPlayer ) {} void Event_PlayerDisconnectedTF( CTFPlayer *pPlayer ); void Event_PlayerChangedClass( CTFPlayer *pPlayer, int iOldClass, int iNewClass ); void Event_PlayerSpawned( CTFPlayer *pPlayer ); void Event_PlayerForceRespawn( CTFPlayer *pPlayer ); void Event_PlayerLeachedHealth( CTFPlayer *pPlayer, bool bDispenserHeal, float amount ); void Event_PlayerHealedOther( CTFPlayer *pPlayer, float amount ); void Event_PlayerHealedOtherAssist( CTFPlayer *pPlayer, float amount ); void Event_PlayerBlockedDamage( CTFPlayer *pPlayer, int nAmount ); void Event_AssistKill( CTFPlayer *pPlayer, CBaseEntity *pVictim ); void Event_PlayerInvulnerable( CTFPlayer *pPlayer ); void Event_PlayerCreatedBuilding( CTFPlayer *pPlayer, CBaseObject *pBuilding ); void Event_PlayerDestroyedBuilding( CTFPlayer *pPlayer, CBaseObject *pBuilding ); void Event_AssistDestroyBuilding( CTFPlayer *pPlayer, CBaseObject *pBuilding ); void Event_Headshot( CTFPlayer *pKiller, bool bBowShot=false ); void Event_Backstab( CTFPlayer *pKiller ); void Event_PlayerUsedTeleport( CTFPlayer *pTeleportOwner, CTFPlayer *pTeleportingPlayer ); void Event_PlayerFiredWeapon( CTFPlayer *pPlayer, bool bCritical ); void Event_PlayerDamage( CBasePlayer *pPlayer, const CTakeDamageInfo &info, int iDamageTaken ); void Event_PlayerDamageAssist( CBasePlayer *pProvider, int iBonusDamage ); void Event_BossDamage( CBasePlayer *pAttacker, int iDamage ); void Event_PlayerKilledOther( CBasePlayer *pAttacker, CBaseEntity *pVictim, const CTakeDamageInfo &info ); void Event_PlayerCapturedPoint( CTFPlayer *pPlayer ); void Event_PlayerReturnedFlag( CTFPlayer *pPlayer ); void Event_PlayerScoresEscortPoints( CTFPlayer *pPlayer, int iPoints ); void Event_PlayerDefendedPoint( CTFPlayer *pPlayer ); void Event_PlayerDominatedOther( CTFPlayer *pAttacker ); void Event_PlayerRevenge( CTFPlayer *pAttacker ); void Event_PlayerStunBall( CTFPlayer *pAttacker, bool bSpecial ); void Event_PlayerAwardBonusPoints( CTFPlayer *pPlayer, CBaseEntity *pSource, int nCount ); void Event_PlayerHealthkitPickup( CTFPlayer *pTFPlayer ); void Event_PlayerAmmokitPickup( CTFPlayer *pTFPlayer ); void Event_PlayerSuicide( CBasePlayer *pPlayer ); void Event_KillDetail( CTFPlayer* pKiller, CTFPlayer* pVictim, CTFPlayer* pAssister, IGameEvent* event /*player_death*/, const CTakeDamageInfo &info ); void Event_TeamChange( CTFPlayer* pPlayer, int oldTeam, int newTeam ); void Event_PlayerCollectedCurrency( CBasePlayer *pPlayer, int nAmount ); void Event_PlayerLoadoutChanged( CTFPlayer *pPlayer, bool bForceReport ); void Event_PlayerRevived( CTFPlayer *pPlayer ); void Event_PlayerThrowableHit( CTFPlayer *pPlayer ); void Event_PlayerThrowableKill( CTFPlayer *pPlayer ); void Event_PlayerEarnedKillStreak( CTFPlayer *pPlayer ); void Event_HalloweenBossEvent( uint8 unBossType, uint16 unBossLevel, uint8 unEventType, uint8 unPlayersInvolved, float fElapsedTime ); virtual void FireGameEvent( IGameEvent * event ); bool IsRealGameplay( TF_Gamestats_LevelStats_t *game ); void AccumulateGameData(); void AccumulateVoteData( void ); bool GetVoteData( const char *szIssueName, int nNumOptions, CUtlVector &vecNames ); void ClearCurrentGameData(); // SteamWorks GameStats void SW_GameStats_WriteMap(); void SW_GameStats_WriteRound( int iWinningTeam, bool bFullRound, int iEndReason ); void SW_GameStats_WritePlayer( CTFPlayer *pPlayer, bool bDisconnected=false ); void SW_GameStats_WriteKill( CTFPlayer* pKiller, CTFPlayer* pVictim, CTFPlayer* pAssister, IGameEvent* event /*player_death*/, const CTakeDamageInfo &info ); void SW_ClassChange( CTFPlayer* pPlayer, int oldClass, int newClass ); void SW_GameEvent( CTFPlayer* pPlayer, const char* pszScoreType, int iPoints ); void SW_FlagEvent( int iPlayer, int iCarrier, int iEventType ); void SW_CapEvent( int iPoint, int iPlayer, const char* pszEventID, int iPoints ); void SW_WriteHostsRow(); // Passtime void SW_PasstimeRoundEnded(); // PowerUp Mode void Event_PowerUpModeDeath( CTFPlayer *pKiller, CTFPlayer *pVictim ); void Event_PowerUpRuneDuration( CTFPlayer *pKiller, int iDuration, int nRune ); // Utilities. TF_Gamestats_LevelStats_t *GetCurrentMap( void ) { return m_reportedStats.m_pCurrentGame; } TF_Gamestats_RoundStats_t* GetRoundStatsForTeam( int iTeamNumber ); void StoreGameEndReason( const char* reason ); struct PlayerStats_t * FindPlayerStats( CBasePlayer *pPlayer ); void ResetPlayerStats( CTFPlayer *pPlayer ); void ResetKillHistory( CTFPlayer *pPlayer ); void ResetRoundStats(); protected: void IncrementStat( CTFPlayer *pPlayer, TFStatType_t statType, int iValue ); void SendStatsToPlayer( CTFPlayer *pPlayer, bool bIsAlive ); void AccumulateAndResetPerLifeStats( CTFPlayer *pPlayer ); void TrackKillStats( CBasePlayer *pAttacker, CBasePlayer *pVictim ); public: TFReportedStats_t m_reportedStats; // Stats which are uploaded from TF server to Steam PlayerStats_t m_aPlayerStats[MAX_PLAYERS+1]; // List of stats for each player for current life - reset after each death or class change // Stats structs used for the new steamworks reporting. TF_Gamestats_RoundStats_t m_currentRoundRed; TF_Gamestats_RoundStats_t m_currentRoundBlue; TF_Gamestats_KillStats_t m_currentKill; TF_Gamestats_LevelStats_t m_currentMap; bool m_bRoundActive; int m_iRoundsPlayed; bool m_bServerShutdown; int m_iGameEndReason; // Unique Column Keys int m_iEvents; int m_iKillCount; int m_iPlayerUpdates; int m_iLoadoutChangesCount; // Robot Destruction Struct RobotDestructionStats_t m_rdStats; // Passtime PasstimeStats_t m_passtimeStats; private: CUtlMap< CUtlConstString, int > m_MapsPlaytime; char m_szNextMap[32]; }; extern CTFGameStats CTF_GameStats; #endif // TF_GAMESTATS_H