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.
177 lines
4.0 KiB
177 lines
4.0 KiB
3 years ago
|
//========= 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 ROCKET_TURRET_LASER_ATTACHMENT 2
|
||
|
#define ROCKET_TURRET_LASER_RANGE 8192
|
||
|
|
||
|
#define ROCKET_TURRET_END_POINT_PULSE_SCALE 5.0f
|
||
|
|
||
|
|
||
|
class C_NPC_RocketTurret : public C_AI_BaseNPC
|
||
|
{
|
||
|
public:
|
||
|
DECLARE_CLASS( C_NPC_RocketTurret, C_AI_BaseNPC );
|
||
|
DECLARE_CLIENTCLASS();
|
||
|
|
||
|
C_NPC_RocketTurret( void );
|
||
|
virtual ~C_NPC_RocketTurret( void );
|
||
|
|
||
|
virtual void Spawn( void );
|
||
|
virtual void ClientThink( void );
|
||
|
|
||
|
virtual ITraceFilter* GetBeamTraceFilter( void );
|
||
|
|
||
|
void LaserOff( void );
|
||
|
void LaserOn( void );
|
||
|
float LaserEndPointSize( void );
|
||
|
|
||
|
private:
|
||
|
CBeam *m_pBeam;
|
||
|
|
||
|
int m_iLaserState;
|
||
|
|
||
|
int m_nSiteHalo;
|
||
|
float m_fPulseOffset;
|
||
|
QAngle m_vecCurrentAngles;
|
||
|
|
||
|
CTraceFilterSkipTwoEntities m_filterBeams;
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
IMPLEMENT_CLIENTCLASS_DT( C_NPC_RocketTurret, DT_NPC_RocketTurret, CNPC_RocketTurret )
|
||
|
|
||
|
RecvPropInt( RECVINFO( m_iLaserState ) ),
|
||
|
RecvPropInt( RECVINFO( m_nSiteHalo ) ),
|
||
|
RecvPropVector( RECVINFO( m_vecCurrentAngles ) ),
|
||
|
|
||
|
END_RECV_TABLE()
|
||
|
|
||
|
|
||
|
C_NPC_RocketTurret::C_NPC_RocketTurret( void )
|
||
|
: m_filterBeams( NULL, NULL, COLLISION_GROUP_DEBRIS )
|
||
|
{
|
||
|
m_filterBeams.SetPassEntity( this );
|
||
|
m_filterBeams.SetPassEntity2( UTIL_PlayerByIndex( 1 ) );
|
||
|
}
|
||
|
|
||
|
C_NPC_RocketTurret::~C_NPC_RocketTurret( void )
|
||
|
{
|
||
|
LaserOff();
|
||
|
if( m_pBeam )
|
||
|
m_pBeam->Remove();
|
||
|
}
|
||
|
|
||
|
|
||
|
void C_NPC_RocketTurret::Spawn( void )
|
||
|
{
|
||
|
SetThink( &C_NPC_RocketTurret::ClientThink );
|
||
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||
|
|
||
|
m_pBeam = NULL;
|
||
|
m_fPulseOffset = RandomFloat( 0.0f, 2.0f * M_PI );
|
||
|
|
||
|
BaseClass::Spawn();
|
||
|
}
|
||
|
|
||
|
void C_NPC_RocketTurret::ClientThink( void )
|
||
|
{
|
||
|
if ( m_iLaserState == 0 )
|
||
|
LaserOff();
|
||
|
else
|
||
|
LaserOn();
|
||
|
}
|
||
|
|
||
|
ITraceFilter* C_NPC_RocketTurret::GetBeamTraceFilter( void )
|
||
|
{
|
||
|
return &m_filterBeams;
|
||
|
}
|
||
|
|
||
|
void C_NPC_RocketTurret::LaserOff( void )
|
||
|
{
|
||
|
if( m_pBeam )
|
||
|
m_pBeam->AddEffects( EF_NODRAW );
|
||
|
}
|
||
|
|
||
|
void C_NPC_RocketTurret::LaserOn( void )
|
||
|
{
|
||
|
if ( !IsBoneAccessAllowed() )
|
||
|
{
|
||
|
LaserOff();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Vector vecMuzzle;
|
||
|
QAngle angMuzzleDir;
|
||
|
GetAttachment( ROCKET_TURRET_LASER_ATTACHMENT, vecMuzzle, angMuzzleDir );
|
||
|
|
||
|
QAngle angAimDir = m_vecCurrentAngles;
|
||
|
Vector vecAimDir;
|
||
|
AngleVectors ( angAimDir, &vecAimDir );
|
||
|
|
||
|
if (!m_pBeam)
|
||
|
{
|
||
|
m_pBeam = CBeam::BeamCreate( "effects/bluelaser1.vmt", 0.1 );
|
||
|
m_pBeam->SetHaloTexture( m_nSiteHalo );
|
||
|
m_pBeam->SetColor( 100, 100, 255 );
|
||
|
m_pBeam->SetBrightness( 100 );
|
||
|
m_pBeam->SetNoise( 0 );
|
||
|
m_pBeam->SetWidth( 1 );
|
||
|
m_pBeam->SetEndWidth( 0 );
|
||
|
m_pBeam->SetScrollRate( 0 );
|
||
|
m_pBeam->SetFadeLength( 0 );
|
||
|
m_pBeam->SetHaloScale( 16.0f );
|
||
|
m_pBeam->SetCollisionGroup( COLLISION_GROUP_NONE );
|
||
|
m_pBeam->SetBeamFlag( FBEAM_REVERSED );
|
||
|
m_pBeam->PointsInit( vecMuzzle + vecAimDir, vecMuzzle );
|
||
|
m_pBeam->SetStartEntity( this );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pBeam->RemoveEffects( EF_NODRAW );
|
||
|
}
|
||
|
|
||
|
if ( m_iLaserState == 2 )
|
||
|
{
|
||
|
// Beam is freaking out
|
||
|
float fSize = RandomFloat( 0.5f, 5.0f );
|
||
|
int iRate = RandomInt( 4, 20 );
|
||
|
m_pBeam->SetWidth( fSize );
|
||
|
m_pBeam->SetScrollRate( iRate );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pBeam->SetWidth( 1 );
|
||
|
m_pBeam->SetScrollRate( 0 );
|
||
|
}
|
||
|
|
||
|
// Trace to find an endpoint (so the beam draws through portals)
|
||
|
Vector vEndPoint;
|
||
|
float fEndFraction;
|
||
|
Ray_t rayPath;
|
||
|
rayPath.Init( vecMuzzle, vecMuzzle + vecAimDir * ROCKET_TURRET_LASER_RANGE );
|
||
|
|
||
|
if ( UTIL_Portal_TraceRay_Beam( rayPath, MASK_SHOT, &m_filterBeams, &fEndFraction ) )
|
||
|
vEndPoint = vecMuzzle + vecAimDir * ROCKET_TURRET_LASER_RANGE; // Trace went through portal and endpoint is unknown
|
||
|
else
|
||
|
vEndPoint = vecMuzzle + vecAimDir * ROCKET_TURRET_LASER_RANGE * fEndFraction; // Trace hit a wall
|
||
|
|
||
|
m_pBeam->PointsInit( vEndPoint, vecMuzzle );
|
||
|
|
||
|
m_pBeam->SetHaloScale( LaserEndPointSize() );
|
||
|
}
|
||
|
|
||
|
float C_NPC_RocketTurret::LaserEndPointSize( void )
|
||
|
{
|
||
|
return ( MAX( 0.0f, sinf( gpGlobals->curtime * M_PI + m_fPulseOffset ) ) ) * ROCKET_TURRET_END_POINT_PULSE_SCALE + 1.0f;
|
||
|
}
|