1
This commit is contained in:
762
game/server/EnvBeam.cpp
Normal file
762
game/server/EnvBeam.cpp
Normal file
@ -0,0 +1,762 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implements visual effects entities: sprites, beams, bubbles, etc.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "beam_shared.h"
|
||||
#include "ndebugoverlay.h"
|
||||
#include "filters.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// Keeps us from doing strcmps in the tracefilter.
|
||||
string_t g_iszPhysicsPropClassname;
|
||||
|
||||
enum Touch_t
|
||||
{
|
||||
touch_none = 0,
|
||||
touch_player_only,
|
||||
touch_npc_only,
|
||||
touch_player_or_npc,
|
||||
touch_player_or_npc_or_physicsprop,
|
||||
};
|
||||
|
||||
class CEnvBeam : public CBeam
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CEnvBeam, CBeam );
|
||||
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void Activate( void );
|
||||
|
||||
void StrikeThink( void );
|
||||
void UpdateThink( void );
|
||||
void RandomArea( void );
|
||||
void RandomPoint( const Vector &vecSrc );
|
||||
void Zap( const Vector &vecSrc, const Vector &vecDest );
|
||||
|
||||
void Strike( void );
|
||||
|
||||
bool PassesTouchFilters(CBaseEntity *pOther);
|
||||
|
||||
void InputTurnOn( inputdata_t &inputdata );
|
||||
void InputTurnOff( inputdata_t &inputdata );
|
||||
void InputToggle( inputdata_t &inputdata );
|
||||
void InputStrikeOnce( inputdata_t &inputdata );
|
||||
|
||||
void TurnOn( void );
|
||||
void TurnOff( void );
|
||||
void Toggle( void );
|
||||
|
||||
const char *GetDecalName( void ){ return STRING( m_iszDecal );}
|
||||
|
||||
inline bool ServerSide( void )
|
||||
{
|
||||
if ( m_life == 0 && !HasSpawnFlags(SF_BEAM_RING) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
void BeamUpdateVars( void );
|
||||
|
||||
int m_active;
|
||||
int m_spriteTexture;
|
||||
|
||||
string_t m_iszStartEntity;
|
||||
string_t m_iszEndEntity;
|
||||
float m_life;
|
||||
float m_boltWidth;
|
||||
float m_noiseAmplitude;
|
||||
int m_speed;
|
||||
float m_restrike;
|
||||
string_t m_iszSpriteName;
|
||||
int m_frameStart;
|
||||
|
||||
float m_radius;
|
||||
|
||||
Touch_t m_TouchType;
|
||||
string_t m_iFilterName;
|
||||
EHANDLE m_hFilter;
|
||||
|
||||
string_t m_iszDecal;
|
||||
|
||||
COutputEvent m_OnTouchedByEntity;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( env_beam, CEnvBeam );
|
||||
|
||||
BEGIN_DATADESC( CEnvBeam )
|
||||
|
||||
DEFINE_FIELD( m_active, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( m_spriteTexture, FIELD_INTEGER ),
|
||||
|
||||
DEFINE_KEYFIELD( m_iszStartEntity, FIELD_STRING, "LightningStart" ),
|
||||
DEFINE_KEYFIELD( m_iszEndEntity, FIELD_STRING, "LightningEnd" ),
|
||||
DEFINE_KEYFIELD( m_life, FIELD_FLOAT, "life" ),
|
||||
DEFINE_KEYFIELD( m_boltWidth, FIELD_FLOAT, "BoltWidth" ),
|
||||
DEFINE_KEYFIELD( m_noiseAmplitude, FIELD_FLOAT, "NoiseAmplitude" ),
|
||||
DEFINE_KEYFIELD( m_speed, FIELD_INTEGER, "TextureScroll" ),
|
||||
DEFINE_KEYFIELD( m_restrike, FIELD_FLOAT, "StrikeTime" ),
|
||||
DEFINE_KEYFIELD( m_iszSpriteName, FIELD_STRING, "texture" ),
|
||||
DEFINE_KEYFIELD( m_frameStart, FIELD_INTEGER, "framestart" ),
|
||||
DEFINE_KEYFIELD( m_radius, FIELD_FLOAT, "Radius" ),
|
||||
DEFINE_KEYFIELD( m_TouchType, FIELD_INTEGER, "TouchType" ),
|
||||
DEFINE_KEYFIELD( m_iFilterName, FIELD_STRING, "filtername" ),
|
||||
DEFINE_KEYFIELD( m_iszDecal, FIELD_STRING, "decalname" ),
|
||||
|
||||
DEFINE_FIELD( m_hFilter, FIELD_EHANDLE ),
|
||||
|
||||
// Function Pointers
|
||||
DEFINE_FUNCTION( StrikeThink ),
|
||||
DEFINE_FUNCTION( UpdateThink ),
|
||||
|
||||
// Input functions
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "StrikeOnce", InputStrikeOnce ),
|
||||
|
||||
DEFINE_OUTPUT( m_OnTouchedByEntity, "OnTouchedByEntity" ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::Spawn( void )
|
||||
{
|
||||
if ( !m_iszSpriteName )
|
||||
{
|
||||
SetThink( &CEnvBeam::SUB_Remove );
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::Spawn();
|
||||
|
||||
m_noiseAmplitude = MIN(MAX_BEAM_NOISEAMPLITUDE, m_noiseAmplitude);
|
||||
|
||||
// Check for tapering
|
||||
if ( HasSpawnFlags( SF_BEAM_TAPEROUT ) )
|
||||
{
|
||||
SetWidth( m_boltWidth );
|
||||
SetEndWidth( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWidth( m_boltWidth );
|
||||
SetEndWidth( GetWidth() ); // Note: EndWidth is not scaled
|
||||
}
|
||||
|
||||
if ( ServerSide() )
|
||||
{
|
||||
SetThink( &CEnvBeam::UpdateThink );
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
SetFireTime( gpGlobals->curtime );
|
||||
|
||||
if ( GetEntityName() != NULL_STRING )
|
||||
{
|
||||
if ( !(m_spawnflags & SF_BEAM_STARTON) )
|
||||
{
|
||||
AddEffects( EF_NODRAW );
|
||||
m_active = 0;
|
||||
SetNextThink( TICK_NEVER_THINK );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_active = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_active = 0;
|
||||
if ( !GetEntityName() || FBitSet(m_spawnflags, SF_BEAM_STARTON) )
|
||||
{
|
||||
SetThink( &CEnvBeam::StrikeThink );
|
||||
SetNextThink( gpGlobals->curtime + 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::Precache( void )
|
||||
{
|
||||
if ( !Q_stristr( STRING(m_iszSpriteName), ".vmt" ) )
|
||||
{
|
||||
// HACK/YWB: This was almost always the laserbeam.spr, so alloc'ing the name a second time with the proper extension isn't going to
|
||||
// kill us on memrory.
|
||||
//Warning( "Level Design Error: %s (%i:%s) Sprite name (%s) missing .vmt extension!\n",
|
||||
// STRING( m_iClassname ), entindex(), GetEntityName(), STRING(m_iszSpriteName) );
|
||||
|
||||
char fixedname[ 512 ];
|
||||
Q_strncpy( fixedname, STRING( m_iszSpriteName ), sizeof( fixedname ) );
|
||||
|
||||
Q_SetExtension( fixedname, ".vmt", sizeof( fixedname ) );
|
||||
|
||||
m_iszSpriteName = AllocPooledString( fixedname );
|
||||
}
|
||||
|
||||
g_iszPhysicsPropClassname = AllocPooledString( "prop_physics" );
|
||||
|
||||
m_spriteTexture = PrecacheModel( STRING(m_iszSpriteName) );
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::Activate( void )
|
||||
{
|
||||
// Get a handle to my filter entity if there is one
|
||||
if (m_iFilterName != NULL_STRING)
|
||||
{
|
||||
m_hFilter = dynamic_cast<CBaseFilter *>(gEntList.FindEntityByName( NULL, m_iFilterName ));
|
||||
}
|
||||
|
||||
BaseClass::Activate();
|
||||
|
||||
if ( ServerSide() )
|
||||
BeamUpdateVars();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Input handler to turn the lightning on either continually or for
|
||||
// interval refiring.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::InputTurnOn( inputdata_t &inputdata )
|
||||
{
|
||||
if ( !m_active )
|
||||
{
|
||||
TurnOn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Input handler to turn the lightning off.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::InputTurnOff( inputdata_t &inputdata )
|
||||
{
|
||||
if ( m_active )
|
||||
{
|
||||
TurnOff();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Input handler to toggle the lightning on/off.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::InputToggle( inputdata_t &inputdata )
|
||||
{
|
||||
if ( m_active )
|
||||
{
|
||||
TurnOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
TurnOn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Input handler for making the beam strike once. This will not affect
|
||||
// any interval refiring that might be going on. If the lifetime is set
|
||||
// to zero (infinite) it will turn on and stay on.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::InputStrikeOnce( inputdata_t &inputdata )
|
||||
{
|
||||
Strike();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Turns the lightning on. If it is set for interval refiring, it will
|
||||
// begin doing so. If it is set to be continually on, it will do so.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::TurnOn( void )
|
||||
{
|
||||
m_active = 1;
|
||||
|
||||
if ( ServerSide() )
|
||||
{
|
||||
RemoveEffects( EF_NODRAW );
|
||||
DoSparks( GetAbsStartPos(), GetAbsEndPos() );
|
||||
|
||||
SetThink( &CEnvBeam::UpdateThink );
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
SetFireTime( gpGlobals->curtime );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThink( &CEnvBeam::StrikeThink );
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::TurnOff( void )
|
||||
{
|
||||
m_active = 0;
|
||||
|
||||
if ( ServerSide() )
|
||||
{
|
||||
AddEffects( EF_NODRAW );
|
||||
}
|
||||
|
||||
SetNextThink( TICK_NEVER_THINK );
|
||||
SetThink( NULL );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Think function for striking at intervals.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::StrikeThink( void )
|
||||
{
|
||||
if ( m_life != 0 )
|
||||
{
|
||||
if ( m_spawnflags & SF_BEAM_RANDOM )
|
||||
SetNextThink( gpGlobals->curtime + m_life + random->RandomFloat( 0, m_restrike ) );
|
||||
else
|
||||
SetNextThink( gpGlobals->curtime + m_life + m_restrike );
|
||||
}
|
||||
m_active = 1;
|
||||
|
||||
if (!m_iszEndEntity)
|
||||
{
|
||||
if (!m_iszStartEntity)
|
||||
{
|
||||
RandomArea( );
|
||||
}
|
||||
else
|
||||
{
|
||||
CBaseEntity *pStart = RandomTargetname( STRING(m_iszStartEntity) );
|
||||
if (pStart != NULL)
|
||||
{
|
||||
RandomPoint( pStart->GetAbsOrigin() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg( "env_beam: unknown entity \"%s\"\n", STRING(m_iszStartEntity) );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Strike();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Strikes once for its configured lifetime.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::Strike( void )
|
||||
{
|
||||
CBroadcastRecipientFilter filter;
|
||||
|
||||
CBaseEntity *pStart = RandomTargetname( STRING(m_iszStartEntity) );
|
||||
CBaseEntity *pEnd = RandomTargetname( STRING(m_iszEndEntity) );
|
||||
|
||||
if ( pStart == NULL || pEnd == NULL )
|
||||
return;
|
||||
|
||||
m_speed = clamp( (int) m_speed, 0, (int) MAX_BEAM_SCROLLSPEED );
|
||||
|
||||
int pointStart = IsStaticPointEntity( pStart );
|
||||
int pointEnd = IsStaticPointEntity( pEnd );
|
||||
|
||||
if ( pointStart || pointEnd )
|
||||
{
|
||||
if ( m_spawnflags & SF_BEAM_RING )
|
||||
{
|
||||
// don't work
|
||||
return;
|
||||
}
|
||||
|
||||
te->BeamEntPoint( filter, 0.0,
|
||||
pointStart ? 0 : pStart->entindex(),
|
||||
pointStart ? &pStart->GetAbsOrigin() : NULL,
|
||||
pointEnd ? 0 : pEnd->entindex(),
|
||||
pointEnd ? &pEnd->GetAbsOrigin() : NULL,
|
||||
m_spriteTexture,
|
||||
0, // No halo
|
||||
m_frameStart,
|
||||
(int)m_flFrameRate,
|
||||
m_life,
|
||||
m_boltWidth,
|
||||
m_boltWidth, // End width
|
||||
0, // No fade
|
||||
m_noiseAmplitude,
|
||||
m_clrRender->r, m_clrRender->g, m_clrRender->b, m_clrRender->a,
|
||||
m_speed );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_spawnflags & SF_BEAM_RING)
|
||||
{
|
||||
te->BeamRing( filter, 0.0,
|
||||
pStart->entindex(),
|
||||
pEnd->entindex(),
|
||||
m_spriteTexture,
|
||||
0, // No halo
|
||||
m_frameStart,
|
||||
(int)m_flFrameRate,
|
||||
m_life,
|
||||
m_boltWidth,
|
||||
0, // No spread
|
||||
m_noiseAmplitude,
|
||||
m_clrRender->r,
|
||||
m_clrRender->g,
|
||||
m_clrRender->b,
|
||||
m_clrRender->a,
|
||||
m_speed );
|
||||
}
|
||||
else
|
||||
{
|
||||
te->BeamEnts( filter, 0.0,
|
||||
pStart->entindex(),
|
||||
pEnd->entindex(),
|
||||
m_spriteTexture,
|
||||
0, // No halo
|
||||
m_frameStart,
|
||||
(int)m_flFrameRate,
|
||||
m_life,
|
||||
m_boltWidth,
|
||||
m_boltWidth, // End width
|
||||
0, // No fade
|
||||
m_noiseAmplitude,
|
||||
m_clrRender->r,
|
||||
m_clrRender->g,
|
||||
m_clrRender->b,
|
||||
m_clrRender->a,
|
||||
m_speed );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DoSparks( pStart->GetAbsOrigin(), pEnd->GetAbsOrigin() );
|
||||
if ( m_flDamage > 0 )
|
||||
{
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( pStart->GetAbsOrigin(), pEnd->GetAbsOrigin(), MASK_SOLID, NULL, COLLISION_GROUP_NONE, &tr );
|
||||
BeamDamageInstant( &tr, m_flDamage );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class CTraceFilterPlayersNPCs : public ITraceFilter
|
||||
{
|
||||
public:
|
||||
bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
|
||||
{
|
||||
CBaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
|
||||
if ( pEntity )
|
||||
{
|
||||
if ( pEntity->IsPlayer() || pEntity->MyNPCPointer() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
virtual TraceType_t GetTraceType() const
|
||||
{
|
||||
return TRACE_ENTITIES_ONLY;
|
||||
}
|
||||
};
|
||||
|
||||
class CTraceFilterPlayersNPCsPhysicsProps : public ITraceFilter
|
||||
{
|
||||
public:
|
||||
bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
|
||||
{
|
||||
CBaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
|
||||
if ( pEntity )
|
||||
{
|
||||
if ( pEntity->IsPlayer() || pEntity->MyNPCPointer() || pEntity->m_iClassname == g_iszPhysicsPropClassname )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
virtual TraceType_t GetTraceType() const
|
||||
{
|
||||
return TRACE_ENTITIES_ONLY;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CEnvBeam::PassesTouchFilters(CBaseEntity *pOther)
|
||||
{
|
||||
bool fPassedSoFar = false;
|
||||
|
||||
// Touched some player or NPC!
|
||||
if( m_TouchType != touch_npc_only )
|
||||
{
|
||||
if( pOther->IsPlayer() )
|
||||
{
|
||||
fPassedSoFar = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_TouchType != touch_player_only )
|
||||
{
|
||||
if( pOther->IsNPC() )
|
||||
{
|
||||
fPassedSoFar = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_TouchType == touch_player_or_npc_or_physicsprop )
|
||||
{
|
||||
if( pOther->m_iClassname == g_iszPhysicsPropClassname )
|
||||
{
|
||||
fPassedSoFar = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( fPassedSoFar )
|
||||
{
|
||||
CBaseFilter* pFilter = (CBaseFilter*)(m_hFilter.Get());
|
||||
return (!pFilter) ? true : pFilter->PassesFilter( this, pOther );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::UpdateThink( void )
|
||||
{
|
||||
// Apply damage every 1/10th of a second.
|
||||
if ( ( m_flDamage > 0 ) && ( gpGlobals->curtime >= m_flFireTime + 0.1 ) )
|
||||
{
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( GetAbsStartPos(), GetAbsEndPos(), MASK_SOLID, NULL, COLLISION_GROUP_NONE, &tr );
|
||||
BeamDamage( &tr );
|
||||
// BeamDamage calls RelinkBeam, so no need to call it again.
|
||||
}
|
||||
else
|
||||
{
|
||||
RelinkBeam();
|
||||
}
|
||||
|
||||
if( m_TouchType != touch_none )
|
||||
{
|
||||
trace_t tr;
|
||||
Ray_t ray;
|
||||
ray.Init( GetAbsStartPos(), GetAbsEndPos() );
|
||||
|
||||
if( m_TouchType == touch_player_or_npc_or_physicsprop )
|
||||
{
|
||||
CTraceFilterPlayersNPCsPhysicsProps traceFilter;
|
||||
enginetrace->TraceRay( ray, MASK_SHOT, &traceFilter, &tr );
|
||||
}
|
||||
else
|
||||
{
|
||||
CTraceFilterPlayersNPCs traceFilter;
|
||||
enginetrace->TraceRay( ray, MASK_SHOT, &traceFilter, &tr );
|
||||
}
|
||||
|
||||
if( tr.fraction != 1.0 && PassesTouchFilters( tr.m_pEnt ) )
|
||||
{
|
||||
m_OnTouchedByEntity.FireOutput( tr.m_pEnt, this, 0 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &vecSrc -
|
||||
// &vecDest -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::Zap( const Vector &vecSrc, const Vector &vecDest )
|
||||
{
|
||||
CBroadcastRecipientFilter filter;
|
||||
|
||||
te->BeamPoints( filter, 0.0,
|
||||
&vecSrc,
|
||||
&vecDest,
|
||||
m_spriteTexture,
|
||||
0, // No halo
|
||||
m_frameStart,
|
||||
(int)m_flFrameRate,
|
||||
m_life,
|
||||
m_boltWidth,
|
||||
m_boltWidth, // End width
|
||||
0, // No fade
|
||||
m_noiseAmplitude,
|
||||
m_clrRender->r,
|
||||
m_clrRender->g,
|
||||
m_clrRender->b,
|
||||
m_clrRender->a,
|
||||
m_speed );
|
||||
|
||||
DoSparks( vecSrc, vecDest );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::RandomArea( void )
|
||||
{
|
||||
int iLoops = 0;
|
||||
|
||||
for (iLoops = 0; iLoops < 10; iLoops++)
|
||||
{
|
||||
Vector vecSrc = GetAbsOrigin();
|
||||
|
||||
Vector vecDir1 = Vector( random->RandomFloat( -1.0, 1.0 ), random->RandomFloat( -1.0, 1.0 ),random->RandomFloat( -1.0, 1.0 ) );
|
||||
VectorNormalize( vecDir1 );
|
||||
trace_t tr1;
|
||||
UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr1 );
|
||||
|
||||
if (tr1.fraction == 1.0)
|
||||
continue;
|
||||
|
||||
Vector vecDir2;
|
||||
do {
|
||||
vecDir2 = Vector( random->RandomFloat( -1.0, 1.0 ), random->RandomFloat( -1.0, 1.0 ),random->RandomFloat( -1.0, 1.0 ) );
|
||||
} while (DotProduct(vecDir1, vecDir2 ) > 0);
|
||||
VectorNormalize( vecDir2 );
|
||||
trace_t tr2;
|
||||
UTIL_TraceLine( vecSrc, vecSrc + vecDir2 * m_radius, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr2 );
|
||||
|
||||
if (tr2.fraction == 1.0)
|
||||
continue;
|
||||
|
||||
if ((tr1.endpos - tr2.endpos).Length() < m_radius * 0.1)
|
||||
continue;
|
||||
|
||||
UTIL_TraceLine( tr1.endpos, tr2.endpos, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr2 );
|
||||
|
||||
if (tr2.fraction != 1.0)
|
||||
continue;
|
||||
|
||||
Zap( tr1.endpos, tr2.endpos );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : vecSrc -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::RandomPoint( const Vector &vecSrc )
|
||||
{
|
||||
int iLoops = 0;
|
||||
|
||||
for (iLoops = 0; iLoops < 10; iLoops++)
|
||||
{
|
||||
Vector vecDir1 = Vector( random->RandomFloat( -1.0, 1.0 ), random->RandomFloat( -1.0, 1.0 ),random->RandomFloat( -1.0, 1.0 ) );
|
||||
VectorNormalize( vecDir1 );
|
||||
trace_t tr1;
|
||||
UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr1 );
|
||||
|
||||
if ((tr1.endpos - vecSrc).Length() < m_radius * 0.1)
|
||||
continue;
|
||||
|
||||
if (tr1.fraction == 1.0)
|
||||
continue;
|
||||
|
||||
Zap( vecSrc, tr1.endpos );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvBeam::BeamUpdateVars( void )
|
||||
{
|
||||
CBaseEntity *pStart = gEntList.FindEntityByName( NULL, m_iszStartEntity );
|
||||
CBaseEntity *pEnd = gEntList.FindEntityByName( NULL, m_iszEndEntity );
|
||||
|
||||
if (( pStart == NULL ) || ( pEnd == NULL ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_nNumBeamEnts = 2;
|
||||
|
||||
m_speed = clamp( (int) m_speed, 0, (int) MAX_BEAM_SCROLLSPEED );
|
||||
|
||||
// NOTE: If the end entity is the beam itself (and the start entity
|
||||
// isn't *also* the beam itself, we've got problems. This is a problem
|
||||
// because SetAbsStartPos actually sets the entity's origin.
|
||||
if ( ( pEnd == this ) && ( pStart != this ) )
|
||||
{
|
||||
DevMsg("env_beams cannot have the end entity be the beam itself\n"
|
||||
"unless the start entity is also the beam itself!\n" );
|
||||
Assert(0);
|
||||
}
|
||||
|
||||
SetModelName( m_iszSpriteName );
|
||||
SetTexture( m_spriteTexture );
|
||||
|
||||
SetType( BEAM_ENTPOINT );
|
||||
|
||||
if ( IsStaticPointEntity( pStart ) )
|
||||
{
|
||||
SetAbsStartPos( pStart->GetAbsOrigin() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStartEntity( pStart );
|
||||
}
|
||||
|
||||
if ( IsStaticPointEntity( pEnd ) )
|
||||
{
|
||||
SetAbsEndPos( pEnd->GetAbsOrigin() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetEndEntity( pEnd );
|
||||
}
|
||||
|
||||
RelinkBeam();
|
||||
|
||||
SetWidth( MIN(MAX_BEAM_WIDTH, m_boltWidth) );
|
||||
SetNoise( MIN(MAX_BEAM_NOISEAMPLITUDE, m_noiseAmplitude) );
|
||||
SetFrame( m_frameStart );
|
||||
SetScrollRate( m_speed );
|
||||
if ( m_spawnflags & SF_BEAM_SHADEIN )
|
||||
{
|
||||
SetBeamFlags( FBEAM_SHADEIN );
|
||||
}
|
||||
else if ( m_spawnflags & SF_BEAM_SHADEOUT )
|
||||
{
|
||||
SetBeamFlags( FBEAM_SHADEOUT );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user