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.
287 lines
9.4 KiB
287 lines
9.4 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
// tf_populator.h
|
||
|
// KeyValues driven procedural population system
|
||
|
// Michael Booth, April 2011
|
||
|
|
||
|
#ifndef TF_POPULATOR_H
|
||
|
#define TF_POPULATOR_H
|
||
|
|
||
|
|
||
|
#include "bot/tf_bot.h"
|
||
|
#include "tf_mann_vs_machine_stats.h"
|
||
|
#include "tf_populator_spawners.h"
|
||
|
#include "tf_populators.h"
|
||
|
|
||
|
class CMannVsMachineStats;
|
||
|
class KeyValues;
|
||
|
class IPopulator;
|
||
|
class CPopulationManager;
|
||
|
class CWave;
|
||
|
|
||
|
#define MVM_POP_FILE_PATH "scripts/population"
|
||
|
|
||
|
//-----------------------------------------------------------------------
|
||
|
class CPopulationManager : public CPointEntity, public CGameEventListener
|
||
|
{
|
||
|
public:
|
||
|
DECLARE_CLASS( CPopulationManager, CPointEntity );
|
||
|
DECLARE_DATADESC();
|
||
|
|
||
|
CPopulationManager( void );
|
||
|
virtual ~CPopulationManager();
|
||
|
|
||
|
// CPointEntity
|
||
|
virtual void Spawn( void ); // entity spawn
|
||
|
|
||
|
// CGameEventListener
|
||
|
virtual void FireGameEvent( IGameEvent *gameEvent );
|
||
|
|
||
|
virtual void Reset( void );
|
||
|
virtual bool Initialize( void );
|
||
|
virtual void Precache( void );
|
||
|
|
||
|
const char *GetPopulationFilename( void );
|
||
|
const char *GetPopulationFilenameShort( void );
|
||
|
void SetPopulationFilename( const char *populationFile );
|
||
|
|
||
|
// Resolve a pop file shortname to a full name
|
||
|
bool FindPopulationFileByShortName( const char *pShortName, CUtlString &outFullName );
|
||
|
|
||
|
// Enumerate possible population files for this map, searching e.g. mapname_*.pop, //BSP/.../*.pop
|
||
|
// This is separate from the explicit popfile lists for tours.
|
||
|
static void FindDefaultPopulationFileShortNames( CUtlVector< CUtlString > &outVecShortNames );
|
||
|
|
||
|
void SetupOnRoundStart( void );
|
||
|
|
||
|
void Update( void ); // continuously invoked to modify population over time
|
||
|
|
||
|
// Triggered by GameRules for any mode specific logic that isn't suitable for the entity think (e.g. not simulating)
|
||
|
void GameRulesThink();
|
||
|
|
||
|
void UpdateObjectiveResource( void );
|
||
|
void ResetMap( void );
|
||
|
|
||
|
void CycleMission ( void );
|
||
|
bool LoadMissionCycleFile ( void );
|
||
|
bool IsValidMvMMap( const char *pszMapName );
|
||
|
|
||
|
// Waves
|
||
|
void ShowNextWaveDescription( void );
|
||
|
void StartCurrentWave( void );
|
||
|
void JumpToWave( uint32 waveNumber, float fCleanMoneyPercent = -1.0f );
|
||
|
void WaveEnd ( bool bSuccess );
|
||
|
|
||
|
CWave *GetCurrentWave( void );
|
||
|
|
||
|
int GetWaveNumber( void ) { return m_iCurrentWaveIndex; }
|
||
|
int GetTotalWaveCount( void ) { return m_waveVector.Count(); }
|
||
|
|
||
|
// Check Points
|
||
|
void ClearCheckpoint( void );
|
||
|
void SetCheckpoint( int waveNumber );
|
||
|
void RestoreCheckpoint( void );
|
||
|
void RestoreItemToCheckpointState( CTFPlayer *player, CEconItemView *item );
|
||
|
void ForgetOtherBottleUpgrades ( CTFPlayer *player, CEconItemView *pItem, int upgradeToKeep );
|
||
|
void RestorePlayerCurrency ();
|
||
|
|
||
|
CUtlVector< CUpgradeInfo > *GetPlayerUpgradeHistory ( CTFPlayer *player ); // Returns the Upgrade vector for a given player
|
||
|
int GetPlayerCurrencySpent ( CTFPlayer *player );
|
||
|
void AddPlayerCurrencySpent ( CTFPlayer *player, int cost );
|
||
|
void SendUpgradesToPlayer ( CTFPlayer *player );
|
||
|
|
||
|
void OnPlayerKilled( CTFPlayer *corpse );
|
||
|
void OnCurrencyPackFade( void );
|
||
|
void OnCurrencyCollected( int nAmount, bool bCountAsDropped, bool bIsBonus );
|
||
|
int GetTotalPopFileCurrency( void );
|
||
|
|
||
|
void AdjustMinPlayerSpawnTime( void );
|
||
|
|
||
|
void MarkAllCurrentPlayersSafeToLeave();
|
||
|
void MvMVictory( void );
|
||
|
void PlayerDoneViewingLoot( const CTFPlayer* pPlayer );
|
||
|
|
||
|
void GetSentryBusterDamageAndKillThreshold( int &nDamage, int &nKills ) const;
|
||
|
|
||
|
bool IsInEndlessWaves ( void );
|
||
|
|
||
|
// Endless
|
||
|
float GetHealthMultiplier ( bool bIsTank = false );
|
||
|
float GetDamageMultiplier ( void );
|
||
|
void EndlessParseBotUpgrades( void );
|
||
|
void EndlessRollEscalation ( void );
|
||
|
void EndlessSetAttributesForBot( CTFBot *pBot );
|
||
|
bool EndlessShouldResetFlag ();
|
||
|
void EndlessFlagHasReset ();
|
||
|
|
||
|
// inlined
|
||
|
bool IsRestoringCheckpoint( void ) const; // return true if we are in the process of restoring players to their checkpointed state
|
||
|
float GetElapsedTime( void ) const; // return elapsed time since scenario started
|
||
|
int GetStartingCurrency( void ) const;
|
||
|
int GetRespawnWaveTime( void ) const;
|
||
|
bool CanBotsAttackWhileInSpawnRoom( void ) const;
|
||
|
KeyValues *GetTemplate( const char *pszName ) const;
|
||
|
|
||
|
bool IsAdvancedPopFile( void ) { return m_bAdvancedPopFile; }
|
||
|
void SetMapRestartTime( float flTime ) { m_flMapRestartTime = flTime; }
|
||
|
bool IsPopFileEventType( int fileType ) { return m_nMvMEventPopfileType == fileType; }
|
||
|
|
||
|
void DebugWaveStats();
|
||
|
|
||
|
void AllocateBots();
|
||
|
|
||
|
void PauseSpawning();
|
||
|
void UnpauseSpawning();
|
||
|
bool IsSpawningPaused() const { return m_bSpawningPaused; }
|
||
|
|
||
|
bool IsBonusRound() const { return m_bBonusRound; }
|
||
|
CBaseCombatCharacter* GetBonusBoss() const { return m_hBonusBoss; }
|
||
|
|
||
|
enum { MVM_INVADERS_TEAM_SIZE = 22 };
|
||
|
|
||
|
static bool GetWavesUseReadyBetween() { return true; }
|
||
|
|
||
|
void SetDefaultEventChangeAttributesName( const char* pszDefaultEventChangeAttributesName ) { m_defaultEventChangeAttributesName = pszDefaultEventChangeAttributesName; }
|
||
|
const char* GetDefaultEventChangeAttributesName() const { return m_defaultEventChangeAttributesName.String(); }
|
||
|
bool HasEventChangeAttributes( const char* pszEventName ) const;
|
||
|
|
||
|
static int CollectMvMBots ( CUtlVector< CTFPlayer *> *pBots );
|
||
|
|
||
|
// Respec
|
||
|
void RemovePlayerAndItemUpgradesFromHistory( CTFPlayer *pPlayer );
|
||
|
void AddRespecToPlayer( CTFPlayer *pPlayer );
|
||
|
void RemoveRespecFromPlayer( CTFPlayer *pPlayer );
|
||
|
void SetNumRespecsForPlayer( CTFPlayer *pPlayer, int nCount );
|
||
|
int GetNumRespecsAvailableForPlayer( CTFPlayer *pPlayer );
|
||
|
int GetNumRespecsEarnedInWave( void ) { return m_nRespecsAwardedInWave; }
|
||
|
int GetNumRespecsEarned( void ) { return m_nRespecsAwarded; }
|
||
|
void ResetRespecPoints( void );
|
||
|
|
||
|
// Buyback
|
||
|
void SetBuybackCreditsForPlayer( CTFPlayer *pPlayer, int nCount );
|
||
|
void RemoveBuybackCreditFromPlayer( CTFPlayer *pPlayer );
|
||
|
int GetNumBuybackCreditsForPlayer( CTFPlayer *pPlayer );
|
||
|
bool IsPlayerBeingTrackedForBuybacks( CTFPlayer *pPlayer );
|
||
|
|
||
|
|
||
|
private:
|
||
|
struct CheckpointSnapshotInfo
|
||
|
{
|
||
|
CSteamID m_steamId; // which player this snapshot is for
|
||
|
int m_currencySpent; // how much money they had spent up to this check point
|
||
|
CUtlVector< CUpgradeInfo > m_upgradeVector; // the upgrades the player had as this checkpoint
|
||
|
};
|
||
|
|
||
|
struct PlayerUpgradeHistory
|
||
|
{
|
||
|
CSteamID m_steamId; // which player this snapshot is for
|
||
|
CUtlVector< CUpgradeInfo > m_upgradeVector;
|
||
|
int m_currencySpent;
|
||
|
};
|
||
|
|
||
|
void PostInitialize( void );
|
||
|
bool Parse( void ); // read in population from file from m_filename
|
||
|
|
||
|
CheckpointSnapshotInfo *FindCheckpointSnapshot( CTFPlayer *player ) const;
|
||
|
CheckpointSnapshotInfo *FindCheckpointSnapshot( CSteamID id ) const;
|
||
|
PlayerUpgradeHistory *FindOrAddPlayerUpgradeHistory ( CTFPlayer *player );
|
||
|
PlayerUpgradeHistory *FindOrAddPlayerUpgradeHistory ( CSteamID steamId );
|
||
|
|
||
|
void LoadLastKnownMission();
|
||
|
bool LoadMvMMission( KeyValues *pNextMission );
|
||
|
|
||
|
CUtlVector< IPopulator * > m_populatorVector;
|
||
|
char m_popfileFull[ MAX_PATH ];
|
||
|
char m_popfileShort[ MAX_PATH ];
|
||
|
|
||
|
KeyValues *m_pTemplates;
|
||
|
|
||
|
bool m_bIsInitialized;
|
||
|
bool m_bAllocatedBots;
|
||
|
|
||
|
bool m_bBonusRound;
|
||
|
CHandle< CBaseCombatCharacter > m_hBonusBoss;
|
||
|
|
||
|
int m_nStartingCurrency;
|
||
|
int m_nLobbyBonusCurrency;
|
||
|
int m_nMvMEventPopfileType;
|
||
|
int m_nRespawnWaveTime;
|
||
|
bool m_bFixedRespawnWaveTime;
|
||
|
bool m_canBotsAttackWhileInSpawnRoom;
|
||
|
int m_sentryBusterDamageDealtThreshold;
|
||
|
int m_sentryBusterKillThreshold;
|
||
|
|
||
|
uint32 m_iCurrentWaveIndex;
|
||
|
CUtlVector< CWave * > m_waveVector; // pointers to waves within m_populationVector
|
||
|
|
||
|
float m_flMapRestartTime; // Restart the Map if gameover and this time elapses
|
||
|
|
||
|
CUtlVector< PlayerUpgradeHistory * > m_playerUpgrades; // list of all players and their upgrades who have played on this MVM rotation
|
||
|
|
||
|
bool m_isRestoringCheckpoint;
|
||
|
|
||
|
// checkpoint data must be static because the population manager entity is destroyed and recreated each round
|
||
|
static CUtlVector< CheckpointSnapshotInfo * > m_checkpointSnapshot; // snapshot of player state at the saved checkpoint
|
||
|
|
||
|
static int m_checkpointWaveIndex; // wave to restart at if scenario lost
|
||
|
static int m_nNumConsecutiveWipes;
|
||
|
|
||
|
bool m_bAdvancedPopFile;
|
||
|
bool m_bCheckForCurrencyAchievement;
|
||
|
|
||
|
CMannVsMachineStats *m_pMVMStats;
|
||
|
KeyValues *m_pKvpMvMMapCycle;
|
||
|
|
||
|
bool m_bSpawningPaused;
|
||
|
bool m_bIsWaveJumping;
|
||
|
bool m_bEndlessOn;
|
||
|
CUtlVector< CMvMBotUpgrade > m_BotUpgradesList;
|
||
|
CUtlVector< CMvMBotUpgrade > m_EndlessActiveBotUpgrades;
|
||
|
CUniformRandomStream m_randomizer;
|
||
|
CUtlVector< int > m_EndlessSeeds;
|
||
|
bool m_bShouldResetFlag;
|
||
|
CUtlVector< const CTFPlayer* > m_donePlayers;
|
||
|
|
||
|
CUtlString m_defaultEventChangeAttributesName;
|
||
|
|
||
|
// Respec
|
||
|
CUtlMap< uint64, int > m_PlayerRespecPoints; // The number of upgrade respecs players (steamID) have
|
||
|
int m_nRespecsAwarded;
|
||
|
int m_nRespecsAwardedInWave;
|
||
|
int m_nCurrencyCollectedForRespec;
|
||
|
|
||
|
// Buyback
|
||
|
CUtlMap< uint64, int > m_PlayerBuybackPoints; // The number of times a player can buyback
|
||
|
|
||
|
};
|
||
|
|
||
|
inline bool CPopulationManager::IsRestoringCheckpoint( void ) const
|
||
|
{
|
||
|
return m_isRestoringCheckpoint;
|
||
|
}
|
||
|
|
||
|
inline int CPopulationManager::GetStartingCurrency( void ) const
|
||
|
{
|
||
|
return m_nStartingCurrency + m_nLobbyBonusCurrency;
|
||
|
}
|
||
|
|
||
|
inline int CPopulationManager::GetRespawnWaveTime( void ) const
|
||
|
{
|
||
|
return m_nRespawnWaveTime;
|
||
|
}
|
||
|
|
||
|
inline bool CPopulationManager::CanBotsAttackWhileInSpawnRoom( void ) const
|
||
|
{
|
||
|
return m_canBotsAttackWhileInSpawnRoom;
|
||
|
}
|
||
|
|
||
|
inline KeyValues *CPopulationManager::GetTemplate( const char *pszName ) const
|
||
|
{
|
||
|
return m_pTemplates->FindKey( pszName );
|
||
|
}
|
||
|
|
||
|
// singleton accessor
|
||
|
extern CPopulationManager *g_pPopulationManager;
|
||
|
|
||
|
|
||
|
#endif // TF_POPULATOR_H
|