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.
168 lines
4.3 KiB
168 lines
4.3 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "c_ai_basenpc.h" |
|
#include "beam_shared.h" |
|
#include "prop_portal_shared.h" |
|
|
|
|
|
#define FLOOR_TURRET_PORTAL_EYE_ATTACHMENT 1 |
|
#define FLOOR_TURRET_PORTAL_LASER_ATTACHMENT 2 |
|
#define FLOOR_TURRET_PORTAL_LASER_RANGE 8192 |
|
|
|
#define FLOOR_TURRET_PORTAL_END_POINT_PULSE_SCALE 4.0f |
|
|
|
|
|
class C_NPC_Portal_FloorTurret : public C_AI_BaseNPC |
|
{ |
|
public: |
|
DECLARE_CLASS( C_NPC_Portal_FloorTurret, C_AI_BaseNPC ); |
|
DECLARE_CLIENTCLASS(); |
|
|
|
virtual ~C_NPC_Portal_FloorTurret( void ); |
|
|
|
virtual void Spawn( void ); |
|
virtual void ClientThink( void ); |
|
|
|
bool IsLaserOn( void ) { return m_pBeam != NULL; } |
|
void LaserOff( void ); |
|
void LaserOn( void ); |
|
float LaserEndPointSize( void ); |
|
|
|
private: |
|
CBeam *m_pBeam; |
|
|
|
bool m_bOutOfAmmo; |
|
bool m_bLaserOn; |
|
int m_sLaserHaloSprite; |
|
float m_fPulseOffset; |
|
|
|
float m_bBeamFlickerOff; |
|
float m_fBeamFlickerTime; |
|
|
|
}; |
|
|
|
|
|
IMPLEMENT_CLIENTCLASS_DT( C_NPC_Portal_FloorTurret, DT_NPC_Portal_FloorTurret, CNPC_Portal_FloorTurret ) |
|
|
|
RecvPropBool( RECVINFO( m_bOutOfAmmo ) ), |
|
RecvPropBool( RECVINFO( m_bLaserOn ) ), |
|
RecvPropInt( RECVINFO( m_sLaserHaloSprite ) ), |
|
|
|
END_RECV_TABLE() |
|
|
|
|
|
C_NPC_Portal_FloorTurret::~C_NPC_Portal_FloorTurret( void ) |
|
{ |
|
LaserOff(); |
|
if( m_pBeam ) |
|
m_pBeam->Remove(); |
|
} |
|
|
|
|
|
void C_NPC_Portal_FloorTurret::Spawn( void ) |
|
{ |
|
SetThink( &C_NPC_Portal_FloorTurret::ClientThink ); |
|
SetNextClientThink( CLIENT_THINK_ALWAYS ); |
|
|
|
m_pBeam = NULL; |
|
m_fPulseOffset = RandomFloat( 0.0f, 2.0f * M_PI ); |
|
|
|
m_bBeamFlickerOff = false; |
|
m_fBeamFlickerTime = 0.0f; |
|
|
|
BaseClass::Spawn(); |
|
} |
|
|
|
void C_NPC_Portal_FloorTurret::ClientThink( void ) |
|
{ |
|
if ( m_bOutOfAmmo && m_fBeamFlickerTime < gpGlobals->curtime ) |
|
{ |
|
m_fBeamFlickerTime = gpGlobals->curtime + RandomFloat( 0.05f, 0.3f ); |
|
m_bBeamFlickerOff = !m_bBeamFlickerOff; |
|
} |
|
|
|
if ( m_bLaserOn && !m_bBeamFlickerOff ) |
|
LaserOn(); |
|
else |
|
LaserOff(); |
|
} |
|
|
|
void C_NPC_Portal_FloorTurret::LaserOff( void ) |
|
{ |
|
if( m_pBeam ) |
|
{ |
|
m_pBeam->AddEffects( EF_NODRAW ); |
|
} |
|
} |
|
|
|
void C_NPC_Portal_FloorTurret::LaserOn( void ) |
|
{ |
|
if ( !IsBoneAccessAllowed() ) |
|
{ |
|
LaserOff(); |
|
return; |
|
} |
|
|
|
Vector vecMuzzle; |
|
QAngle angMuzzleDir; |
|
GetAttachment( FLOOR_TURRET_PORTAL_LASER_ATTACHMENT, vecMuzzle, angMuzzleDir ); |
|
|
|
Vector vecEye; |
|
QAngle angEyeDir; |
|
GetAttachment( FLOOR_TURRET_PORTAL_EYE_ATTACHMENT, vecEye, angEyeDir ); |
|
|
|
Vector vecMuzzleDir; |
|
AngleVectors( angEyeDir, &vecMuzzleDir ); |
|
|
|
if (!m_pBeam) |
|
{ |
|
m_pBeam = CBeam::BeamCreate( "effects/redlaser1.vmt", 0.2 ); |
|
m_pBeam->SetColor( 255, 32, 32 ); |
|
m_pBeam->SetBrightness( 255 ); |
|
m_pBeam->SetNoise( 0 ); |
|
m_pBeam->SetWidth( IsX360() ? ( 1.5f ) : ( 0.75f ) ); // On low end TVs these lasers are very hard to see at a distance |
|
m_pBeam->SetEndWidth( 0 ); |
|
m_pBeam->SetScrollRate( 0 ); |
|
m_pBeam->SetFadeLength( 0 ); |
|
m_pBeam->SetHaloTexture( m_sLaserHaloSprite ); |
|
m_pBeam->SetHaloScale( 4.0f ); |
|
m_pBeam->SetCollisionGroup( COLLISION_GROUP_NONE ); |
|
m_pBeam->PointsInit( vecMuzzle + vecMuzzleDir, vecMuzzle ); |
|
m_pBeam->SetBeamFlag( FBEAM_REVERSED ); |
|
m_pBeam->SetStartEntity( this ); |
|
} |
|
else |
|
{ |
|
m_pBeam->RemoveEffects( EF_NODRAW ); |
|
} |
|
|
|
// Trace to find an endpoint |
|
Vector vEndPoint; |
|
float fEndFraction; |
|
Ray_t rayPath; |
|
rayPath.Init( vecMuzzle, vecMuzzle + vecMuzzleDir * FLOOR_TURRET_PORTAL_LASER_RANGE ); |
|
|
|
CTraceFilterSkipClassname traceFilter( this, "prop_energy_ball", COLLISION_GROUP_NONE ); |
|
|
|
if ( UTIL_Portal_TraceRay_Beam( rayPath, MASK_SHOT, &traceFilter, &fEndFraction ) ) |
|
vEndPoint = vecMuzzle + vecMuzzleDir * FLOOR_TURRET_PORTAL_LASER_RANGE; // Trace went through portal and endpoint is unknown |
|
else |
|
vEndPoint = vecMuzzle + vecMuzzleDir * FLOOR_TURRET_PORTAL_LASER_RANGE * fEndFraction; // Trace hit a wall |
|
|
|
// The beam is backwards, sort of. The endpoint is the sniper. This is |
|
// so that the beam can be tapered to very thin where it emits from the turret. |
|
m_pBeam->PointsInit( vEndPoint, vecMuzzle ); |
|
|
|
m_pBeam->SetHaloScale( LaserEndPointSize() ); |
|
} |
|
|
|
float C_NPC_Portal_FloorTurret::LaserEndPointSize( void ) |
|
{ |
|
return ( ( MAX( 0.0f, sinf( gpGlobals->curtime * M_PI + m_fPulseOffset ) ) ) * FLOOR_TURRET_PORTAL_END_POINT_PULSE_SCALE + 3.0f ) * ( IsX360() ? ( 3.0f ) : ( 1.5f ) ); |
|
} |