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.
467 lines
11 KiB
467 lines
11 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: tf_populator_spawners |
|
// Implementations of NPC Spawning Code for PvE related game modes (MvM) |
|
//=============================================================================// |
|
#ifndef TF_POPULATORS_H |
|
#define TF_POPULATORS_H |
|
|
|
#include "tf_population_manager.h" |
|
|
|
class KeyValues; |
|
class IPopulator; |
|
class IPopulationSpawner; |
|
class CPopulationManager; |
|
class CWave; |
|
class CSpawnLocation; |
|
|
|
//----------------------------------------------------------------------- |
|
class CSpawnLocation |
|
{ |
|
public: |
|
CSpawnLocation(); |
|
|
|
bool Parse( KeyValues *data ); |
|
|
|
bool IsValid( void ) const; |
|
|
|
SpawnLocationResult FindSpawnLocation( Vector& vSpawnPosition ); |
|
|
|
private: |
|
CTFNavArea *SelectSpawnArea( void ) const; |
|
|
|
RelativePositionType m_relative; |
|
TFTeamSpawnVector_t m_teamSpawnVector; |
|
|
|
int m_nSpawnCount; |
|
int m_nRandomSeed; |
|
bool m_bClosestPointOnNav; |
|
}; |
|
|
|
inline bool CSpawnLocation::IsValid( void ) const |
|
{ |
|
return m_relative != UNDEFINED || m_teamSpawnVector.Count() > 0; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------- |
|
// For spawning bots/players at a specific position |
|
class CPopulatorInternalSpawnPoint : public CPointEntity |
|
{ |
|
DECLARE_CLASS( CPopulatorInternalSpawnPoint, CPointEntity ); |
|
}; |
|
|
|
extern CHandle< CPopulatorInternalSpawnPoint > g_internalSpawnPoint; |
|
|
|
//----------------------------------------------------------------------- |
|
// A Populator manages the populating of entities in the environment. |
|
class IPopulator |
|
{ |
|
public: |
|
IPopulator( CPopulationManager *manager ) |
|
{ |
|
m_manager = manager; |
|
m_spawner = NULL; |
|
} |
|
|
|
virtual ~IPopulator() |
|
{ |
|
if ( m_spawner ) |
|
{ |
|
delete m_spawner; |
|
} |
|
m_spawner = NULL; |
|
} |
|
|
|
virtual bool Parse( KeyValues *data ) = 0; |
|
|
|
virtual void PostInitialize( void ) { } // create initial population at start of scenario |
|
virtual void Update( void ) { } // continuously invoked to modify population over time |
|
virtual void UnpauseSpawning() {} |
|
|
|
virtual void OnPlayerKilled( CTFPlayer *corpse ) { } |
|
|
|
CPopulationManager *GetManager( void ) const { return m_manager; } |
|
|
|
virtual bool HasEventChangeAttributes( const char* pszEventName ) const |
|
{ |
|
if ( m_spawner ) |
|
{ |
|
return m_spawner->HasEventChangeAttributes( pszEventName ); |
|
} |
|
|
|
return false; |
|
} |
|
|
|
IPopulationSpawner *m_spawner; |
|
|
|
private: |
|
CPopulationManager *m_manager; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------- |
|
// Invokes its spawner when mission conditions are met |
|
class CMissionPopulator : public IPopulator |
|
{ |
|
public: |
|
CMissionPopulator( CPopulationManager *manager ); |
|
virtual ~CMissionPopulator() { } |
|
|
|
virtual bool Parse( KeyValues *data ); |
|
|
|
virtual void Update( void ); // continuously invoked to modify population over time |
|
virtual void UnpauseSpawning( void ); |
|
|
|
int BeginAtWave( void ) { return m_beginAtWaveIndex; } |
|
int StopAtWave( void ) { return m_stopAtWaveIndex; } |
|
|
|
CTFBot::MissionType GetMissionType( void ){ return m_mission; } |
|
|
|
private: |
|
CTFBot::MissionType m_mission; |
|
CSpawnLocation m_where; |
|
|
|
bool UpdateMissionDestroySentries( void ); |
|
bool UpdateMission( CTFBot::MissionType mission ); |
|
|
|
enum StateType |
|
{ |
|
NOT_STARTED, |
|
INITIAL_COOLDOWN, |
|
RUNNING |
|
}; |
|
|
|
StateType m_state; |
|
|
|
float m_initialCooldown; |
|
float m_cooldownDuration; |
|
CountdownTimer m_cooldownTimer; |
|
CountdownTimer m_checkForDangerousSentriesTimer; |
|
int m_desiredCount; |
|
int m_beginAtWaveIndex; // this mission becomes active at this wave number |
|
int m_stopAtWaveIndex; // stop when this wave becomes active |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------- |
|
// Invokes its spawner at random positions scattered throughout |
|
// the environment at PostInitialize() |
|
class CRandomPlacementPopulator : public IPopulator |
|
{ |
|
public: |
|
CRandomPlacementPopulator( CPopulationManager *manager ); |
|
virtual ~CRandomPlacementPopulator() { } |
|
|
|
virtual bool Parse( KeyValues *data ); |
|
|
|
virtual void PostInitialize( void ); // create initial population at start of scenario |
|
|
|
int m_count; |
|
float m_minSeparation; |
|
unsigned int m_navAreaFilter; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------- |
|
// Invokes its spawner periodically |
|
class CPeriodicSpawnPopulator : public IPopulator |
|
{ |
|
public: |
|
CPeriodicSpawnPopulator( CPopulationManager *manager ); |
|
virtual ~CPeriodicSpawnPopulator() { } |
|
|
|
virtual bool Parse( KeyValues *data ); |
|
|
|
virtual void PostInitialize( void ); // create initial population at start of scenario |
|
virtual void Update( void ); // continuously invoked to modify population over time |
|
virtual void UnpauseSpawning( void ); |
|
|
|
CSpawnLocation m_where; |
|
float m_minInterval; |
|
float m_maxInterval; |
|
|
|
private: |
|
CountdownTimer m_timer; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------- |
|
// Spawns a group of entities within a Wave |
|
class CWaveSpawnPopulator : public IPopulator |
|
{ |
|
public: |
|
CWaveSpawnPopulator( CPopulationManager *manager ); |
|
virtual ~CWaveSpawnPopulator(); |
|
|
|
virtual bool Parse( KeyValues *data ); |
|
|
|
virtual void Update( void ); // continuously invoked to modify population over time |
|
|
|
virtual void OnPlayerKilled( CTFPlayer *corpse ); |
|
|
|
CSpawnLocation m_where; |
|
int m_totalCount; |
|
int m_remainingCount; |
|
int m_nClassCounts; |
|
int m_maxActive; // the maximum number of entities active at one time |
|
int m_spawnCount; // the number of entities to spawn at once |
|
float m_waitBeforeStarting; |
|
float m_waitBetweenSpawns; // between spawns of mobs |
|
bool m_bWaitBetweenSpawnAfterDeath; |
|
|
|
CFmtStr m_startWaveWarningSound; |
|
EventInfo *m_startWaveOutput; |
|
|
|
CFmtStr m_firstSpawnWarningSound; |
|
EventInfo *m_firstSpawnOutput; |
|
|
|
CFmtStr m_lastSpawnWarningSound; |
|
EventInfo *m_lastSpawnOutput; |
|
|
|
CFmtStr m_doneWarningSound; |
|
EventInfo *m_doneOutput; |
|
|
|
int m_totalCurrency; |
|
int m_unallocatedCurrency; |
|
|
|
CUtlString m_name; |
|
CUtlString m_waitForAllSpawned; |
|
CUtlString m_waitForAllDead; |
|
|
|
bool IsDone( void ) const |
|
{ |
|
return m_state == DONE; |
|
} |
|
|
|
bool IsDoneSpawningBots( void ) const |
|
{ |
|
return m_state > SPAWNING; |
|
} |
|
|
|
// Invoked by td_setnextwave to finish off a wave |
|
void ForceFinish( void ); |
|
void ForceReset( void ) |
|
{ |
|
m_unallocatedCurrency = m_totalCurrency; |
|
m_remainingCount = m_totalCount; |
|
m_state = PENDING; |
|
} |
|
|
|
bool IsSupportWave( void ) const { return m_bSupportWave; } |
|
bool IsLimitedSupportWave( void ) const { return m_bLimitedSupport; } |
|
void SetParent( CWave *pParent ) { m_pParent = pParent; } |
|
int GetCurrencyAmountPerDeath( void ); |
|
void OnNonSupportWavesDone( void ); |
|
|
|
private: |
|
bool IsFinishedSpawning( void ); |
|
|
|
CountdownTimer m_timer; |
|
EntityHandleVector_t m_activeVector; |
|
int m_countSpawnedSoFar; |
|
int m_myReservedSlotCount; |
|
|
|
bool m_bSupportWave; |
|
bool m_bLimitedSupport; |
|
CWave *m_pParent; |
|
|
|
enum InternalStateType |
|
{ |
|
PENDING, |
|
PRE_SPAWN_DELAY, |
|
SPAWNING, |
|
WAIT_FOR_ALL_DEAD, |
|
DONE |
|
}; |
|
InternalStateType m_state; |
|
void SetState( InternalStateType eState ); |
|
|
|
int ReservePlayerSlots( int count ); // reserve 'count' player slots so other WaveSpawns don't take them |
|
void ReleasePlayerSlots( int count ); // release 'count' player slots that have been previously reserved |
|
static int m_reservedPlayerSlotCount; |
|
|
|
bool m_bRandomSpawn; |
|
SpawnLocationResult m_spawnLocationResult; |
|
Vector m_vSpawnPosition; |
|
}; |
|
|
|
|
|
struct WaveClassCount_t |
|
{ |
|
int nClassCount; |
|
string_t iszClassIconName; |
|
unsigned int iFlags; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------- |
|
// Spawns sequential "waves" of entities over time. |
|
// A wave consists of one or more WaveSpawns that all run concurrently. |
|
// The wave is done when all contained WaveSpawns are done. |
|
class CWave : public IPopulator |
|
{ |
|
public: |
|
CWave( CPopulationManager *manager ); |
|
virtual ~CWave(); |
|
|
|
virtual bool Parse( KeyValues *data ); |
|
virtual void Update( void ); |
|
|
|
virtual void OnPlayerKilled( CTFPlayer *corpse ); |
|
|
|
virtual bool HasEventChangeAttributes( const char* pszEventName ) const OVERRIDE; |
|
|
|
void ForceFinish(); // used when forcing a wave to finish |
|
void ForceReset(); // used when forcing a wave to start |
|
|
|
CWaveSpawnPopulator *FindWaveSpawnPopulator( const char *name ); // find a CWaveSpawnPopulator by name |
|
|
|
void AddClassType( string_t iszClassIconName, int nCount, unsigned int iFlags ); |
|
|
|
int GetNumClassTypes( void ) const { return m_nWaveClassCounts.Count(); } |
|
void StartUpgradesAlertTimer ( float flTime ) { m_GetUpgradesAlertTimer.Start( flTime ); } |
|
void SetStartTime (float flTime) { m_flStartTime = flTime; } |
|
|
|
// inline |
|
bool IsCheckpoint( void ) const; |
|
CWave *GetNextWave( void ) const; |
|
void SetNextWave( CWave *wave ); |
|
const char *GetDescription( void ) const; |
|
int GetTotalCurrency( void ) const; |
|
int GetEnemyCount( void ) const; |
|
int GetClassCount( int nIndex ) const; |
|
string_t GetClassIconName( int nIndex ) const; |
|
unsigned int GetClassFlags( int nIndex ) const; |
|
|
|
int NumTanksSpawned( void ) const; |
|
void IncrementTanksSpawned( void ); |
|
|
|
int NumSentryBustersSpawned( void ) const; |
|
void IncrementSentryBustersSpawned( void ); |
|
int NumSentryBustersKilled( void ) const; |
|
void IncrementSentryBustersKilled( void ); |
|
void ResetSentryBustersKilled( void ); |
|
|
|
int NumEngineersTeleportSpawned( void ) const; |
|
void IncrementEngineerTeleportSpawned( void ); |
|
|
|
private: |
|
bool IsDoneWithNonSupportWaves( void ); |
|
|
|
void ActiveWaveUpdate(); |
|
void WaveCompleteUpdate(); |
|
void WaveIntermissionUpdate(); |
|
|
|
CUtlVector< CWaveSpawnPopulator * > m_waveSpawnVector; |
|
|
|
bool m_isStarted; |
|
bool m_bFiredInitWaveOutput; |
|
int m_iEnemyCount; |
|
int m_nTanksSpawned; |
|
int m_nSentryBustersSpawned; |
|
int m_nNumEngineersTeleportSpawned; |
|
|
|
int m_nNumSentryBustersKilled; |
|
|
|
CUtlVector< WaveClassCount_t > m_nWaveClassCounts; |
|
int m_totalCurrency; |
|
|
|
EventInfo *m_startOutput; |
|
EventInfo *m_doneOutput; |
|
EventInfo *m_initOutput; |
|
|
|
CFmtStr m_description; |
|
CFmtStr m_soundName; |
|
|
|
float m_waitWhenDone; |
|
CountdownTimer m_doneTimer; |
|
|
|
bool m_bCheckBonusCreditsMin; |
|
bool m_bCheckBonusCreditsMax; |
|
float m_flBonusCreditsTime; |
|
|
|
bool m_bPlayedUpgradeAlert; |
|
CountdownTimer m_GetUpgradesAlertTimer; |
|
|
|
bool m_isEveryContainedWaveSpawnDone; |
|
float m_flStartTime; |
|
}; |
|
|
|
inline const char *CWave::GetDescription( void ) const |
|
{ |
|
return m_description; |
|
} |
|
|
|
inline int CWave::GetTotalCurrency( void ) const |
|
{ |
|
return m_totalCurrency; |
|
} |
|
|
|
inline int CWave::GetEnemyCount( void ) const |
|
{ |
|
return m_iEnemyCount; |
|
} |
|
|
|
inline int CWave::GetClassCount( int nIndex ) const |
|
{ |
|
return m_nWaveClassCounts[ nIndex ].nClassCount; |
|
} |
|
|
|
inline string_t CWave::GetClassIconName( int nIndex ) const |
|
{ |
|
return m_nWaveClassCounts[ nIndex ].iszClassIconName; |
|
} |
|
|
|
inline unsigned int CWave::GetClassFlags( int nIndex ) const |
|
{ |
|
return m_nWaveClassCounts[ nIndex ].iFlags; |
|
} |
|
|
|
inline int CWave::NumTanksSpawned( void ) const |
|
{ |
|
return m_nTanksSpawned; |
|
} |
|
|
|
inline void CWave::IncrementTanksSpawned( void ) |
|
{ |
|
m_nTanksSpawned++; |
|
} |
|
|
|
|
|
inline int CWave::NumSentryBustersSpawned( void ) const |
|
{ |
|
return m_nSentryBustersSpawned; |
|
} |
|
|
|
inline void CWave::IncrementSentryBustersSpawned( void ) |
|
{ |
|
m_nSentryBustersSpawned++; |
|
} |
|
|
|
inline int CWave::NumSentryBustersKilled( void ) const |
|
{ |
|
return m_nNumSentryBustersKilled; |
|
} |
|
|
|
inline void CWave::IncrementSentryBustersKilled( void ) |
|
{ |
|
m_nNumSentryBustersKilled++; |
|
} |
|
|
|
inline void CWave::ResetSentryBustersKilled( void ) |
|
{ |
|
m_nNumSentryBustersKilled = 0; |
|
} |
|
|
|
inline int CWave::NumEngineersTeleportSpawned( void ) const |
|
{ |
|
return m_nNumEngineersTeleportSpawned; |
|
} |
|
|
|
inline void CWave::IncrementEngineerTeleportSpawned( void ) |
|
{ |
|
m_nNumEngineersTeleportSpawned++; |
|
} |
|
|
|
#endif // TF_POPULATORS_H
|
|
|