diff options
Diffstat (limited to 'game/server/tf/bot/map_entities/tf_spawner.cpp')
| -rw-r--r-- | game/server/tf/bot/map_entities/tf_spawner.cpp | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/game/server/tf/bot/map_entities/tf_spawner.cpp b/game/server/tf/bot/map_entities/tf_spawner.cpp new file mode 100644 index 0000000..fa4f7c7 --- /dev/null +++ b/game/server/tf/bot/map_entities/tf_spawner.cpp @@ -0,0 +1,163 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// tf_spawner.cpp +// Entity to spawn one or more templatized entities +// Michael Booth, April 2011 + +#include "cbase.h" + +#include "tf_gamerules.h" +#include "bot/map_entities/tf_spawner.h" + + +//------------------------------------------------------------------------------ +BEGIN_DATADESC( CTFSpawner ) + DEFINE_KEYFIELD( m_spawnCount, FIELD_INTEGER, "count" ), + DEFINE_KEYFIELD( m_maxActiveCount, FIELD_INTEGER, "maxActive" ), + DEFINE_KEYFIELD( m_spawnInterval, FIELD_FLOAT, "interval" ), + DEFINE_KEYFIELD( m_templateName, FIELD_STRING, "template" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Reset", InputReset ), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + + DEFINE_OUTPUT( m_onExpended, "OnExpended" ), + DEFINE_OUTPUT( m_onSpawned, "OnSpawned" ), + DEFINE_OUTPUT( m_onKilled, "OnKilled" ), + + DEFINE_THINKFUNC( SpawnerThink ), +END_DATADESC() + +LINK_ENTITY_TO_CLASS( tf_spawner, CTFSpawner ); + + +//------------------------------------------------------------------------------ +CTFSpawner::CTFSpawner( void ) +{ + Reset(); +} + + +//------------------------------------------------------------------------------ +void CTFSpawner::Reset( void ) +{ + m_bExpended = false; + m_spawnCountRemaining = 0; + m_spawnedVector.RemoveAll(); + SetThink( NULL ); +} + + +//------------------------------------------------------------------------------ +void CTFSpawner::InputReset( inputdata_t &inputdata ) +{ + Reset(); +} + + +//------------------------------------------------------------------------------ +void CTFSpawner::InputEnable( inputdata_t &inputdata ) +{ + if ( m_bExpended ) + { + return; + } + + SetThink( &CTFSpawner::SpawnerThink ); + + if ( m_spawnCountRemaining ) + { + // already generating - don't restart count + return; + } + + SetNextThink( gpGlobals->curtime ); + m_spawnCountRemaining = m_spawnCount; + + m_template = dynamic_cast< CTFSpawnTemplate * >( gEntList.FindEntityByName( NULL, m_templateName ) ); + if ( m_template == NULL ) + { + Warning( "%s failed to find template named '%s'\n", GetClassname(), STRING( m_templateName ) ); + } +} + + +//------------------------------------------------------------------------------ +void CTFSpawner::InputDisable( inputdata_t &inputdata ) +{ + // just stop thinking + SetThink( NULL ); +} + + +//------------------------------------------------------------------------------ +void CTFSpawner::OnKilled( CBaseEntity *dead ) +{ + m_onKilled.FireOutput( dead, this ); +} + + +//------------------------------------------------------------------------------ +void CTFSpawner::SpawnerThink( void ) +{ + // still waiting for the real game to start? + gamerules_roundstate_t roundState = TFGameRules()->State_Get(); + if ( roundState >= GR_STATE_TEAM_WIN || roundState < GR_STATE_PREROUND || TFGameRules()->IsInWaitingForPlayers() ) + { + SetNextThink( gpGlobals->curtime + 1.0f ); + return; + } + + // clean up destroyed children + for ( int i = 0; i < m_spawnedVector.Count(); ) + { + CHandle< CBaseEntity > child = m_spawnedVector[i]; + + if ( child == NULL ) + { + m_spawnedVector.FastRemove(i); + m_onKilled.FireOutput( this, this ); + continue; + } + + ++i; + } + + if ( m_spawnedVector.Count() >= m_maxActiveCount ) + { + // reached max simultanous active count + SetNextThink( gpGlobals->curtime + 0.1f ); + return; + } + + if ( m_template == NULL ) + { + // nothing to spawn! + return; + } + + // spawn the entity + CBaseEntity *child = m_template->Instantiate(); + if ( child ) + { + m_spawnedVector.AddToTail( child ); + + child->SetAbsOrigin( GetAbsOrigin() ); + child->SetAbsAngles( GetAbsAngles() ); + child->SetOwnerEntity( this ); + + DispatchSpawn( child ); + m_onSpawned.FireOutput( child, this ); + + --m_spawnCountRemaining; + if ( m_spawnCountRemaining ) + { + SetNextThink( gpGlobals->curtime + m_spawnInterval ); + } + else + { + SetThink( NULL ); + m_onExpended.FireOutput( this, this ); + m_bExpended = true; + } + } +} |