diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/server/env_entity_maker.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/server/env_entity_maker.cpp')
| -rw-r--r-- | mp/src/game/server/env_entity_maker.cpp | 732 |
1 files changed, 366 insertions, 366 deletions
diff --git a/mp/src/game/server/env_entity_maker.cpp b/mp/src/game/server/env_entity_maker.cpp index ff0fbcfd..d8ad528e 100644 --- a/mp/src/game/server/env_entity_maker.cpp +++ b/mp/src/game/server/env_entity_maker.cpp @@ -1,366 +1,366 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "entityoutput.h"
-#include "TemplateEntities.h"
-#include "point_template.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define SF_ENTMAKER_AUTOSPAWN 0x0001
-#define SF_ENTMAKER_WAITFORDESTRUCTION 0x0002
-#define SF_ENTMAKER_IGNOREFACING 0x0004
-#define SF_ENTMAKER_CHECK_FOR_SPACE 0x0008
-#define SF_ENTMAKER_CHECK_PLAYER_LOOKING 0x0010
-
-
-//-----------------------------------------------------------------------------
-// Purpose: An entity that mapmakers can use to ensure there's a required entity never runs out.
-// i.e. physics cannisters that need to be used.
-//-----------------------------------------------------------------------------
-class CEnvEntityMaker : public CPointEntity
-{
- DECLARE_CLASS( CEnvEntityMaker, CPointEntity );
-public:
- DECLARE_DATADESC();
-
- virtual void Spawn( void );
- virtual void Activate( void );
-
- void SpawnEntity( Vector vecAlternateOrigin = vec3_invalid, QAngle vecAlternateAngles = vec3_angle );
- void CheckSpawnThink( void );
- void InputForceSpawn( inputdata_t &inputdata );
- void InputForceSpawnAtEntityOrigin( inputdata_t &inputdata );
-
-private:
-
- CPointTemplate *FindTemplate();
-
- bool HasRoomToSpawn();
- bool IsPlayerLooking();
-
- Vector m_vecEntityMins;
- Vector m_vecEntityMaxs;
- EHANDLE m_hCurrentInstance;
- EHANDLE m_hCurrentBlocker; // Last entity that blocked us spawning something
- Vector m_vecBlockerOrigin;
-
- // Movement after spawn
- QAngle m_angPostSpawnDirection;
- float m_flPostSpawnDirectionVariance;
- float m_flPostSpawnSpeed;
- bool m_bPostSpawnUseAngles;
-
- string_t m_iszTemplate;
-
- COutputEvent m_pOutputOnSpawned;
- COutputEvent m_pOutputOnFailedSpawn;
-};
-
-BEGIN_DATADESC( CEnvEntityMaker )
- // DEFINE_FIELD( m_vecEntityMins, FIELD_VECTOR ),
- // DEFINE_FIELD( m_vecEntityMaxs, FIELD_VECTOR ),
- DEFINE_FIELD( m_hCurrentInstance, FIELD_EHANDLE ),
- DEFINE_FIELD( m_hCurrentBlocker, FIELD_EHANDLE ),
- DEFINE_FIELD( m_vecBlockerOrigin, FIELD_VECTOR ),
- DEFINE_KEYFIELD( m_iszTemplate, FIELD_STRING, "EntityTemplate" ),
- DEFINE_KEYFIELD( m_angPostSpawnDirection, FIELD_VECTOR, "PostSpawnDirection" ),
- DEFINE_KEYFIELD( m_flPostSpawnDirectionVariance, FIELD_FLOAT, "PostSpawnDirectionVariance" ),
- DEFINE_KEYFIELD( m_flPostSpawnSpeed, FIELD_FLOAT, "PostSpawnSpeed" ),
- DEFINE_KEYFIELD( m_bPostSpawnUseAngles, FIELD_BOOLEAN, "PostSpawnInheritAngles" ),
-
- // Outputs
- DEFINE_OUTPUT( m_pOutputOnSpawned, "OnEntitySpawned" ),
- DEFINE_OUTPUT( m_pOutputOnFailedSpawn, "OnEntityFailedSpawn" ),
-
- // Inputs
- DEFINE_INPUTFUNC( FIELD_VOID, "ForceSpawn", InputForceSpawn ),
- DEFINE_INPUTFUNC( FIELD_STRING, "ForceSpawnAtEntityOrigin", InputForceSpawnAtEntityOrigin ),
-
- // Functions
- DEFINE_THINKFUNC( CheckSpawnThink ),
-END_DATADESC()
-
-LINK_ENTITY_TO_CLASS( env_entity_maker, CEnvEntityMaker );
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CEnvEntityMaker::Spawn( void )
-{
- m_vecEntityMins = vec3_origin;
- m_vecEntityMaxs = vec3_origin;
- m_hCurrentInstance = NULL;
- m_hCurrentBlocker = NULL;
- m_vecBlockerOrigin = vec3_origin;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CEnvEntityMaker::Activate( void )
-{
- BaseClass::Activate();
-
- // check for valid template
- if ( m_iszTemplate == NULL_STRING )
- {
- Warning( "env_entity_maker %s has no template entity!\n", GetEntityName().ToCStr() );
- UTIL_Remove( this );
- return;
- }
-
- // Spawn an instance
- if ( m_spawnflags & SF_ENTMAKER_AUTOSPAWN )
- {
- SpawnEntity();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CPointTemplate *CEnvEntityMaker::FindTemplate()
-{
- // Find our point_template
- CPointTemplate *pTemplate = dynamic_cast<CPointTemplate *>(gEntList.FindEntityByName( NULL, STRING(m_iszTemplate) ));
- if ( !pTemplate )
- {
- Warning( "env_entity_maker %s failed to find template %s.\n", GetEntityName().ToCStr(), STRING(m_iszTemplate) );
- }
-
- return pTemplate;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Spawn an instance of the entity
-//-----------------------------------------------------------------------------
-void CEnvEntityMaker::SpawnEntity( Vector vecAlternateOrigin, QAngle vecAlternateAngles )
-{
- CPointTemplate *pTemplate = FindTemplate();
- if (!pTemplate)
- return;
-
- // Spawn our template
- Vector vecSpawnOrigin = GetAbsOrigin();
- QAngle vecSpawnAngles = GetAbsAngles();
-
- if( vecAlternateOrigin != vec3_invalid )
- {
- // We have a valid alternate origin and angles. Use those instead
- // of spawning the items at my own origin and angles.
- vecSpawnOrigin = vecAlternateOrigin;
- vecSpawnAngles = vecAlternateAngles;
- }
-
- CUtlVector<CBaseEntity*> hNewEntities;
- if ( !pTemplate->CreateInstance( vecSpawnOrigin, vecSpawnAngles, &hNewEntities ) )
- return;
-
- //Adrian: oops we couldn't spawn the entity (or entities) for some reason!
- if ( hNewEntities.Count() == 0 )
- return;
-
- m_hCurrentInstance = hNewEntities[0];
-
- // Assume it'll block us
- m_hCurrentBlocker = m_hCurrentInstance;
- m_vecBlockerOrigin = m_hCurrentBlocker->GetAbsOrigin();
-
- // Store off the mins & maxs the first time we spawn
- if ( m_vecEntityMins == vec3_origin )
- {
- m_hCurrentInstance->CollisionProp()->WorldSpaceAABB( &m_vecEntityMins, &m_vecEntityMaxs );
- m_vecEntityMins -= m_hCurrentInstance->GetAbsOrigin();
- m_vecEntityMaxs -= m_hCurrentInstance->GetAbsOrigin();
- }
-
- // Fire our output
- m_pOutputOnSpawned.FireOutput( this, this );
-
- // Start thinking
- if ( m_spawnflags & SF_ENTMAKER_AUTOSPAWN )
- {
- SetThink( &CEnvEntityMaker::CheckSpawnThink );
- SetNextThink( gpGlobals->curtime + 0.5f );
- }
-
- // If we have a specified post spawn speed, apply it to all spawned entities
- if ( m_flPostSpawnSpeed )
- {
- for ( int i = 0; i < hNewEntities.Count(); i++ )
- {
- CBaseEntity *pEntity = hNewEntities[i];
- if ( pEntity->GetMoveType() == MOVETYPE_NONE )
- continue;
-
- // Calculate a velocity for this entity
- Vector vForward,vRight,vUp;
- QAngle angSpawnDir( m_angPostSpawnDirection );
- if ( m_bPostSpawnUseAngles )
- {
- if ( GetParent() )
- {
- angSpawnDir += GetParent()->GetAbsAngles();
- }
- else
- {
- angSpawnDir += GetAbsAngles();
- }
- }
- AngleVectors( angSpawnDir, &vForward, &vRight, &vUp );
- Vector vecShootDir = vForward;
- vecShootDir += vRight * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance;
- vecShootDir += vForward * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance;
- vecShootDir += vUp * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance;
- VectorNormalize( vecShootDir );
- vecShootDir *= m_flPostSpawnSpeed;
-
- // Apply it to the entity
- IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject();
- if ( pPhysicsObject )
- {
- pPhysicsObject->AddVelocity(&vecShootDir, NULL);
- }
- else
- {
- pEntity->SetAbsVelocity( vecShootDir );
- }
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns whether or not the template entities can fit if spawned.
-// Input : pBlocker - Returns blocker unless NULL.
-//-----------------------------------------------------------------------------
-bool CEnvEntityMaker::HasRoomToSpawn()
-{
- // Do we have a blocker from last time?
- if ( m_hCurrentBlocker )
- {
- // If it hasn't moved, abort immediately
- if ( m_vecBlockerOrigin == m_hCurrentBlocker->GetAbsOrigin() )
- {
- return false;
- }
- }
-
- // Check to see if there's enough room to spawn
- trace_t tr;
- UTIL_TraceHull( GetAbsOrigin(), GetAbsOrigin(), m_vecEntityMins, m_vecEntityMaxs, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
- if ( tr.m_pEnt || tr.startsolid )
- {
- // Store off our blocker to check later
- m_hCurrentBlocker = tr.m_pEnt;
- if ( m_hCurrentBlocker )
- {
- m_vecBlockerOrigin = m_hCurrentBlocker->GetAbsOrigin();
- }
-
- return false;
- }
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns true if the player is looking towards us.
-//-----------------------------------------------------------------------------
-bool CEnvEntityMaker::IsPlayerLooking()
-{
- for ( int i = 1; i <= gpGlobals->maxClients; i++ )
- {
- CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
- if ( pPlayer )
- {
- // Only spawn if the player's looking away from me
- Vector vLookDir = pPlayer->EyeDirection3D();
- Vector vTargetDir = GetAbsOrigin() - pPlayer->EyePosition();
- VectorNormalize( vTargetDir );
-
- float fDotPr = DotProduct( vLookDir,vTargetDir );
- if ( fDotPr > 0 )
- return true;
- }
- }
-
- return false;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Check to see if we should spawn another instance
-//-----------------------------------------------------------------------------
-void CEnvEntityMaker::CheckSpawnThink( void )
-{
- SetNextThink( gpGlobals->curtime + 0.5f );
-
- // Do we have an instance?
- if ( m_hCurrentInstance )
- {
- // If Wait-For-Destruction is set, abort immediately
- if ( m_spawnflags & SF_ENTMAKER_WAITFORDESTRUCTION )
- return;
- }
-
- // Check to see if there's enough room to spawn
- if ( !HasRoomToSpawn() )
- return;
-
- // We're clear, now check to see if the player's looking
- if ( !( HasSpawnFlags( SF_ENTMAKER_IGNOREFACING ) ) && IsPlayerLooking() )
- return;
-
- // Clear, no player watching, so spawn!
- SpawnEntity();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Spawns the entities, checking for space if flagged to do so.
-//-----------------------------------------------------------------------------
-void CEnvEntityMaker::InputForceSpawn( inputdata_t &inputdata )
-{
- CPointTemplate *pTemplate = FindTemplate();
- if (!pTemplate)
- return;
-
- if ( HasSpawnFlags( SF_ENTMAKER_CHECK_FOR_SPACE ) && !HasRoomToSpawn() )
- {
- m_pOutputOnFailedSpawn.FireOutput( this, this );
- return;
- }
-
- if ( HasSpawnFlags( SF_ENTMAKER_CHECK_PLAYER_LOOKING ) && IsPlayerLooking() )
- {
- m_pOutputOnFailedSpawn.FireOutput( this, this );
- return;
- }
-
- SpawnEntity();
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CEnvEntityMaker::InputForceSpawnAtEntityOrigin( inputdata_t &inputdata )
-{
- CBaseEntity *pTargetEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller );
-
- if( pTargetEntity )
- {
- SpawnEntity( pTargetEntity->GetAbsOrigin(), pTargetEntity->GetAbsAngles() );
- }
-}
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "cbase.h" +#include "entityoutput.h" +#include "TemplateEntities.h" +#include "point_template.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define SF_ENTMAKER_AUTOSPAWN 0x0001 +#define SF_ENTMAKER_WAITFORDESTRUCTION 0x0002 +#define SF_ENTMAKER_IGNOREFACING 0x0004 +#define SF_ENTMAKER_CHECK_FOR_SPACE 0x0008 +#define SF_ENTMAKER_CHECK_PLAYER_LOOKING 0x0010 + + +//----------------------------------------------------------------------------- +// Purpose: An entity that mapmakers can use to ensure there's a required entity never runs out. +// i.e. physics cannisters that need to be used. +//----------------------------------------------------------------------------- +class CEnvEntityMaker : public CPointEntity +{ + DECLARE_CLASS( CEnvEntityMaker, CPointEntity ); +public: + DECLARE_DATADESC(); + + virtual void Spawn( void ); + virtual void Activate( void ); + + void SpawnEntity( Vector vecAlternateOrigin = vec3_invalid, QAngle vecAlternateAngles = vec3_angle ); + void CheckSpawnThink( void ); + void InputForceSpawn( inputdata_t &inputdata ); + void InputForceSpawnAtEntityOrigin( inputdata_t &inputdata ); + +private: + + CPointTemplate *FindTemplate(); + + bool HasRoomToSpawn(); + bool IsPlayerLooking(); + + Vector m_vecEntityMins; + Vector m_vecEntityMaxs; + EHANDLE m_hCurrentInstance; + EHANDLE m_hCurrentBlocker; // Last entity that blocked us spawning something + Vector m_vecBlockerOrigin; + + // Movement after spawn + QAngle m_angPostSpawnDirection; + float m_flPostSpawnDirectionVariance; + float m_flPostSpawnSpeed; + bool m_bPostSpawnUseAngles; + + string_t m_iszTemplate; + + COutputEvent m_pOutputOnSpawned; + COutputEvent m_pOutputOnFailedSpawn; +}; + +BEGIN_DATADESC( CEnvEntityMaker ) + // DEFINE_FIELD( m_vecEntityMins, FIELD_VECTOR ), + // DEFINE_FIELD( m_vecEntityMaxs, FIELD_VECTOR ), + DEFINE_FIELD( m_hCurrentInstance, FIELD_EHANDLE ), + DEFINE_FIELD( m_hCurrentBlocker, FIELD_EHANDLE ), + DEFINE_FIELD( m_vecBlockerOrigin, FIELD_VECTOR ), + DEFINE_KEYFIELD( m_iszTemplate, FIELD_STRING, "EntityTemplate" ), + DEFINE_KEYFIELD( m_angPostSpawnDirection, FIELD_VECTOR, "PostSpawnDirection" ), + DEFINE_KEYFIELD( m_flPostSpawnDirectionVariance, FIELD_FLOAT, "PostSpawnDirectionVariance" ), + DEFINE_KEYFIELD( m_flPostSpawnSpeed, FIELD_FLOAT, "PostSpawnSpeed" ), + DEFINE_KEYFIELD( m_bPostSpawnUseAngles, FIELD_BOOLEAN, "PostSpawnInheritAngles" ), + + // Outputs + DEFINE_OUTPUT( m_pOutputOnSpawned, "OnEntitySpawned" ), + DEFINE_OUTPUT( m_pOutputOnFailedSpawn, "OnEntityFailedSpawn" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "ForceSpawn", InputForceSpawn ), + DEFINE_INPUTFUNC( FIELD_STRING, "ForceSpawnAtEntityOrigin", InputForceSpawnAtEntityOrigin ), + + // Functions + DEFINE_THINKFUNC( CheckSpawnThink ), +END_DATADESC() + +LINK_ENTITY_TO_CLASS( env_entity_maker, CEnvEntityMaker ); + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEnvEntityMaker::Spawn( void ) +{ + m_vecEntityMins = vec3_origin; + m_vecEntityMaxs = vec3_origin; + m_hCurrentInstance = NULL; + m_hCurrentBlocker = NULL; + m_vecBlockerOrigin = vec3_origin; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEnvEntityMaker::Activate( void ) +{ + BaseClass::Activate(); + + // check for valid template + if ( m_iszTemplate == NULL_STRING ) + { + Warning( "env_entity_maker %s has no template entity!\n", GetEntityName().ToCStr() ); + UTIL_Remove( this ); + return; + } + + // Spawn an instance + if ( m_spawnflags & SF_ENTMAKER_AUTOSPAWN ) + { + SpawnEntity(); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CPointTemplate *CEnvEntityMaker::FindTemplate() +{ + // Find our point_template + CPointTemplate *pTemplate = dynamic_cast<CPointTemplate *>(gEntList.FindEntityByName( NULL, STRING(m_iszTemplate) )); + if ( !pTemplate ) + { + Warning( "env_entity_maker %s failed to find template %s.\n", GetEntityName().ToCStr(), STRING(m_iszTemplate) ); + } + + return pTemplate; +} + + +//----------------------------------------------------------------------------- +// Purpose: Spawn an instance of the entity +//----------------------------------------------------------------------------- +void CEnvEntityMaker::SpawnEntity( Vector vecAlternateOrigin, QAngle vecAlternateAngles ) +{ + CPointTemplate *pTemplate = FindTemplate(); + if (!pTemplate) + return; + + // Spawn our template + Vector vecSpawnOrigin = GetAbsOrigin(); + QAngle vecSpawnAngles = GetAbsAngles(); + + if( vecAlternateOrigin != vec3_invalid ) + { + // We have a valid alternate origin and angles. Use those instead + // of spawning the items at my own origin and angles. + vecSpawnOrigin = vecAlternateOrigin; + vecSpawnAngles = vecAlternateAngles; + } + + CUtlVector<CBaseEntity*> hNewEntities; + if ( !pTemplate->CreateInstance( vecSpawnOrigin, vecSpawnAngles, &hNewEntities ) ) + return; + + //Adrian: oops we couldn't spawn the entity (or entities) for some reason! + if ( hNewEntities.Count() == 0 ) + return; + + m_hCurrentInstance = hNewEntities[0]; + + // Assume it'll block us + m_hCurrentBlocker = m_hCurrentInstance; + m_vecBlockerOrigin = m_hCurrentBlocker->GetAbsOrigin(); + + // Store off the mins & maxs the first time we spawn + if ( m_vecEntityMins == vec3_origin ) + { + m_hCurrentInstance->CollisionProp()->WorldSpaceAABB( &m_vecEntityMins, &m_vecEntityMaxs ); + m_vecEntityMins -= m_hCurrentInstance->GetAbsOrigin(); + m_vecEntityMaxs -= m_hCurrentInstance->GetAbsOrigin(); + } + + // Fire our output + m_pOutputOnSpawned.FireOutput( this, this ); + + // Start thinking + if ( m_spawnflags & SF_ENTMAKER_AUTOSPAWN ) + { + SetThink( &CEnvEntityMaker::CheckSpawnThink ); + SetNextThink( gpGlobals->curtime + 0.5f ); + } + + // If we have a specified post spawn speed, apply it to all spawned entities + if ( m_flPostSpawnSpeed ) + { + for ( int i = 0; i < hNewEntities.Count(); i++ ) + { + CBaseEntity *pEntity = hNewEntities[i]; + if ( pEntity->GetMoveType() == MOVETYPE_NONE ) + continue; + + // Calculate a velocity for this entity + Vector vForward,vRight,vUp; + QAngle angSpawnDir( m_angPostSpawnDirection ); + if ( m_bPostSpawnUseAngles ) + { + if ( GetParent() ) + { + angSpawnDir += GetParent()->GetAbsAngles(); + } + else + { + angSpawnDir += GetAbsAngles(); + } + } + AngleVectors( angSpawnDir, &vForward, &vRight, &vUp ); + Vector vecShootDir = vForward; + vecShootDir += vRight * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance; + vecShootDir += vForward * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance; + vecShootDir += vUp * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance; + VectorNormalize( vecShootDir ); + vecShootDir *= m_flPostSpawnSpeed; + + // Apply it to the entity + IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject(); + if ( pPhysicsObject ) + { + pPhysicsObject->AddVelocity(&vecShootDir, NULL); + } + else + { + pEntity->SetAbsVelocity( vecShootDir ); + } + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns whether or not the template entities can fit if spawned. +// Input : pBlocker - Returns blocker unless NULL. +//----------------------------------------------------------------------------- +bool CEnvEntityMaker::HasRoomToSpawn() +{ + // Do we have a blocker from last time? + if ( m_hCurrentBlocker ) + { + // If it hasn't moved, abort immediately + if ( m_vecBlockerOrigin == m_hCurrentBlocker->GetAbsOrigin() ) + { + return false; + } + } + + // Check to see if there's enough room to spawn + trace_t tr; + UTIL_TraceHull( GetAbsOrigin(), GetAbsOrigin(), m_vecEntityMins, m_vecEntityMaxs, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); + if ( tr.m_pEnt || tr.startsolid ) + { + // Store off our blocker to check later + m_hCurrentBlocker = tr.m_pEnt; + if ( m_hCurrentBlocker ) + { + m_vecBlockerOrigin = m_hCurrentBlocker->GetAbsOrigin(); + } + + return false; + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns true if the player is looking towards us. +//----------------------------------------------------------------------------- +bool CEnvEntityMaker::IsPlayerLooking() +{ + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); + if ( pPlayer ) + { + // Only spawn if the player's looking away from me + Vector vLookDir = pPlayer->EyeDirection3D(); + Vector vTargetDir = GetAbsOrigin() - pPlayer->EyePosition(); + VectorNormalize( vTargetDir ); + + float fDotPr = DotProduct( vLookDir,vTargetDir ); + if ( fDotPr > 0 ) + return true; + } + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: Check to see if we should spawn another instance +//----------------------------------------------------------------------------- +void CEnvEntityMaker::CheckSpawnThink( void ) +{ + SetNextThink( gpGlobals->curtime + 0.5f ); + + // Do we have an instance? + if ( m_hCurrentInstance ) + { + // If Wait-For-Destruction is set, abort immediately + if ( m_spawnflags & SF_ENTMAKER_WAITFORDESTRUCTION ) + return; + } + + // Check to see if there's enough room to spawn + if ( !HasRoomToSpawn() ) + return; + + // We're clear, now check to see if the player's looking + if ( !( HasSpawnFlags( SF_ENTMAKER_IGNOREFACING ) ) && IsPlayerLooking() ) + return; + + // Clear, no player watching, so spawn! + SpawnEntity(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Spawns the entities, checking for space if flagged to do so. +//----------------------------------------------------------------------------- +void CEnvEntityMaker::InputForceSpawn( inputdata_t &inputdata ) +{ + CPointTemplate *pTemplate = FindTemplate(); + if (!pTemplate) + return; + + if ( HasSpawnFlags( SF_ENTMAKER_CHECK_FOR_SPACE ) && !HasRoomToSpawn() ) + { + m_pOutputOnFailedSpawn.FireOutput( this, this ); + return; + } + + if ( HasSpawnFlags( SF_ENTMAKER_CHECK_PLAYER_LOOKING ) && IsPlayerLooking() ) + { + m_pOutputOnFailedSpawn.FireOutput( this, this ); + return; + } + + SpawnEntity(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CEnvEntityMaker::InputForceSpawnAtEntityOrigin( inputdata_t &inputdata ) +{ + CBaseEntity *pTargetEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller ); + + if( pTargetEntity ) + { + SpawnEntity( pTargetEntity->GetAbsOrigin(), pTargetEntity->GetAbsAngles() ); + } +} |