Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.
 
 
 
 
 
 

283 lines
8.2 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: tf_populator_spawners
// Implementations of NPC Spawning Code for PvE related game modes (MvM)
//=============================================================================//
#ifndef TF_POPULATOR_SPAWNERS_H
#define TF_POPULATOR_SPAWNERS_H
#include "bot/tf_bot.h"
#include "tf_mann_vs_machine_stats.h"
class CMannVsMachineStats;
class KeyValues;
class IPopulator;
class CPopulationManager;
class CWave;
enum RelativePositionType
{
UNDEFINED = 0,
AHEAD,
BEHIND,
ANYWHERE
};
struct EventInfo
{
CFmtStr m_target;
CFmtStr m_action;
};
enum SpawnLocationResult
{
SPAWN_LOCATION_NOT_FOUND = 0,
SPAWN_LOCATION_NAV,
SPAWN_LOCATION_TELEPORTER
};
typedef CUtlVector< CHandle< CBaseEntity > > EntityHandleVector_t;
typedef CUtlVector< CHandle< CTFTeamSpawn > > TFTeamSpawnVector_t;
//--------------------------------------------------------------------------------------------------------
//
// Return a random value with a distribution like so:
// 1| /
// | /
// |/
// /----
// 0 1
inline float SkewedRandomValue( void )
{
float x = RandomFloat( 0, 1.0f );
float y = RandomFloat( 0, 1.0f );
return x < y ? y : x;
}
//-----------------------------------------------------------------------
class CMvMBotUpgrade
{
public:
char szAttrib[ MAX_ATTRIBUTE_DESCRIPTION_LENGTH ]; // Debug
int iAttribIndex;
float flValue;
float flMax;
int nCost;
bool bIsBotAttr;
bool bIsSkillAttr; // Probably want to make these an enum or flag later
};
//-----------------------------------------------------------------------
class CTFNavAreaIncursionLess
{
public:
bool Less( const CTFNavArea *a, const CTFNavArea *b, void *pCtx )
{
return a->GetIncursionDistance( TF_TEAM_BLUE ) < b->GetIncursionDistance( TF_TEAM_BLUE );
}
};
//-----------------------------------------------------------------------
// A Spawner is responsible for actually spawning a particular
// instance of an entity into the environment.
// If 'result' is non-NULL, spawned entities are added to this vector.
class IPopulationSpawner
{
public:
// We need a virtual destructor or else the derived-class destructors won't be called,
// leading to memory leaks. Found via clang warning.
virtual ~IPopulationSpawner()
{
}
IPopulationSpawner( IPopulator *populator )
{
m_populator = populator;
}
IPopulator *GetPopulator( void ) const
{
return m_populator;
}
virtual bool Parse( KeyValues *data ) = 0;
virtual bool Spawn( const Vector &here, EntityHandleVector_t *result = NULL ) = 0;
virtual bool IsWhereRequired( void ) const // does this spawner need a valid Where parameter?
{
return true;
}
virtual bool IsVarious( void ) { return false; }
virtual int GetClass( int nSpawnNum = -1 ) { return TF_CLASS_UNDEFINED; }
virtual string_t GetClassIcon( int nSpawnNum = -1 ) { return NULL_STRING; }
virtual int GetHealth( int nSpawnNum = -1 ){ return 0; }
virtual bool IsMiniBoss( int nSpawnNum = -1 ) { return false; }
virtual bool HasAttribute( CTFBot::AttributeType type, int nSpawnNum = -1 ) { return false; }
virtual bool HasEventChangeAttributes( const char* pszEventName ) const = 0;
static IPopulationSpawner *ParseSpawner( IPopulator *populator, KeyValues *data );
protected:
IPopulator *m_populator;
};
//-----------------------------------------------------------------------
// A RandomChoice spawner picks one of the Spawners in its
// vector at random and invokes it to spawn entities.
class CRandomChoiceSpawner : public IPopulationSpawner
{
public:
CRandomChoiceSpawner( IPopulator *populator );
virtual ~CRandomChoiceSpawner();
virtual bool Parse( KeyValues *data );
virtual bool Spawn( const Vector &here, CUtlVector< CHandle< CBaseEntity > > *result = NULL );
virtual bool IsVarious( void ) { return true; }
virtual int GetClass( int nSpawnNum = -1 );
virtual string_t GetClassIcon( int nSpawnNum = -1 );
virtual int GetHealth( int nSpawnNum = -1 );
virtual bool IsMiniBoss( int nSpawnNum = -1 ) OVERRIDE;
virtual bool HasAttribute( CTFBot::AttributeType type, int nSpawnNum = -1 );
virtual bool HasEventChangeAttributes( const char* pszEventName ) const OVERRIDE;
CUtlVector< IPopulationSpawner * > m_spawnerVector;
CUtlVector< int > m_nRandomPickDecision;
int m_nNumSpawned;
};
//-----------------------------------------------------------------------
class CTFBotSpawner : public IPopulationSpawner
{
public:
CTFBotSpawner( IPopulator *populator );
virtual ~CTFBotSpawner() { }
virtual bool Parse( KeyValues *data );
bool ParseEventChangeAttributes( KeyValues *data );
virtual bool Spawn( const Vector &here, EntityHandleVector_t *result = NULL );
virtual int GetClass( int nSpawnNum = -1 );
virtual string_t GetClassIcon( int nSpawnNum = -1 );
virtual int GetHealth( int nSpawnNum = -1 );
virtual bool IsMiniBoss( int nSpawnNum = -1 ) OVERRIDE;
virtual bool HasAttribute( CTFBot::AttributeType type, int nSpawnNum = -1 );
virtual bool HasEventChangeAttributes( const char* pszEventName ) const OVERRIDE;
int m_class;
string_t m_iszClassIcon;
int m_health;
float m_scale;
float m_flAutoJumpMin;
float m_flAutoJumpMax;
CUtlString m_name;
CUtlStringList m_teleportWhereName;
CTFBot::EventChangeAttributes_t m_defaultAttributes;
CUtlVector< CTFBot::EventChangeAttributes_t > m_eventChangeAttributes;
};
//-----------------------------------------------------------------------
class CTankSpawner : public IPopulationSpawner
{
public:
CTankSpawner( IPopulator *populator );
virtual string_t GetClassIcon( int nSpawnNum = -1 ) { return MAKE_STRING( "tank" ); }
virtual int GetHealth( int nSpawnNum = -1 ){ return m_health; }
virtual bool Parse( KeyValues *data );
virtual bool Spawn( const Vector &here, EntityHandleVector_t *result = NULL );
virtual bool IsWhereRequired( void ) const // does this spawner need a valid Where parameter?
{
// the Tank spawns at a given path node
return false;
}
virtual bool IsMiniBoss( int nSpawnNum = -1 ) OVERRIDE { return true; }
virtual bool HasEventChangeAttributes( const char* pszEventName ) const OVERRIDE { return false; }
int m_health;
float m_speed;
CUtlString m_name;
CUtlString m_startingPathTrackNodeName; // which path_track we start at
int m_skin;
EventInfo *m_onKilledOutput;
EventInfo *m_onBombDroppedOutput;
};
//-----------------------------------------------------------------------
class CSentryGunSpawner : public IPopulationSpawner
{
public:
CSentryGunSpawner( IPopulator *populator );
virtual bool Parse( KeyValues *data );
virtual bool Spawn( const Vector &here, EntityHandleVector_t *result = NULL );
virtual bool HasEventChangeAttributes( const char* pszEventName ) const OVERRIDE { return false; }
int m_level;
};
//-----------------------------------------------------------------------
class CSquadSpawner : public IPopulationSpawner
{
public:
CSquadSpawner( IPopulator *populator );
virtual ~CSquadSpawner();
virtual bool Parse( KeyValues *data );
virtual bool Spawn( const Vector &here, EntityHandleVector_t *result = NULL );
virtual bool IsVarious( void ) { return true; }
virtual int GetClass( int nSpawnNum = -1 );
virtual string_t GetClassIcon( int nSpawnNum = -1 );
virtual int GetHealth( int nSpawnNum = -1 );
virtual bool IsMiniBoss( int nSpawnNum = -1 ) OVERRIDE;
virtual bool HasAttribute( CTFBot::AttributeType type, int nSpawnNum = -1 );
virtual bool HasEventChangeAttributes( const char* pszEventName ) const OVERRIDE;
CUtlVector< IPopulationSpawner * > m_memberSpawnerVector; // all of these are invoked to instantiate the squad
float m_formationSize;
bool m_bShouldPreserveSquad;
};
//-----------------------------------------------------------------------
class CMobSpawner : public IPopulationSpawner
{
public:
CMobSpawner( IPopulator *populator );
virtual ~CMobSpawner();
virtual bool Parse( KeyValues *data );
virtual bool Spawn( const Vector &here, EntityHandleVector_t *result = NULL );
virtual bool HasEventChangeAttributes( const char* pszEventName ) const OVERRIDE;
int m_count;
IPopulationSpawner *m_spawner;
private:
// TODO: Rethink this, since spawners are one-shot, and mobs need to spawn over time...
CountdownTimer m_mobSpawnTimer;
CountdownTimer m_mobLifetimeTimer;
CTFNavArea *m_mobArea;
int m_mobCountRemaining;
};
#endif // TF_POPULATOR_SPAWNERS_H