📄 hl1_npc_apache.cpp
字号:
// Purpose :
// Input :
// Output :
//------------------------------------------------------------------------------
#define CHOPPER_AP_GUN_TIP 0
#define CHOPPER_AP_GUN_BASE 1
#define CHOPPER_BC_GUN_YAW 0
#define CHOPPER_BC_GUN_PITCH 1
#define CHOPPER_BC_POD_PITCH 2
bool CNPC_Apache::FireGun( )
{
Vector vForward, vRight, vUp;
AngleVectors( GetAbsAngles(), &vForward, &vUp, &vRight );
Vector posGun;
QAngle angGun;
GetAttachment( 1, posGun, angGun );
Vector vecTarget = (m_vecTargetPosition - posGun);
VectorNormalize( vecTarget );
Vector vecOut;
vecOut.x = DotProduct( vForward, vecTarget );
vecOut.y = -DotProduct( vUp, vecTarget );
vecOut.z = DotProduct( vRight, vecTarget );
QAngle angles;
VectorAngles( vecOut, angles );
angles.x = -angles.x;
if (angles.y > 180)
angles.y = angles.y - 360;
if (angles.y < -180)
angles.y = angles.y + 360;
if (angles.x > 180)
angles.x = angles.x - 360;
if (angles.x < -180)
angles.x = angles.x + 360;
if (angles.x > m_angGun.x)
m_angGun.x = min( angles.x, m_angGun.x + 12 );
if (angles.x < m_angGun.x)
m_angGun.x = max( angles.x, m_angGun.x - 12 );
if (angles.y > m_angGun.y)
m_angGun.y = min( angles.y, m_angGun.y + 12 );
if (angles.y < m_angGun.y)
m_angGun.y = max( angles.y, m_angGun.y - 12 );
m_angGun.y = SetBoneController( 0, m_angGun.y );
m_angGun.x = SetBoneController( 1, -m_angGun.x );
Vector posBarrel;
QAngle angBarrel;
GetAttachment( 2, posBarrel, angBarrel );
Vector vecGun = (posGun - posBarrel);
VectorNormalize( vecGun );
// NDebugOverlay::Line( posBarrel, posBarrel + vecGun * 4098, 0,255,0, false, 0.1);
if ( DotProduct( vecGun, vecTarget ) > 0.98 )
{
CPASAttenuationFilter filter( this, 0.2f );
enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, "turret/tu_fire1.wav", 1.0, 0.2 );//<<TEMP>>temp sound
FireBullets( 1, posBarrel, vecGun, VECTOR_CONE_2DEGREES, 8192, m_iAmmoType, 2 );
return true;
}
return false;
}
void CNPC_Apache::FireRocket( void )
{
static float side = 1.0;
static int count;
Vector vForward, vRight, vUp;
AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp );
Vector vecSrc = GetAbsOrigin() + 1.5 * ( vForward * 21 + vRight * 70 * side + vUp * -79 );
// pick firing pod to launch from
switch( m_iRockets % 5)
{
case 0: vecSrc = vecSrc + vRight * 10; break;
case 1: vecSrc = vecSrc - vRight * 10; break;
case 2: vecSrc = vecSrc + vUp * 10; break;
case 3: vecSrc = vecSrc - vUp * 10; break;
case 4: break;
}
Vector vTargetDir = m_vecTargetPosition - GetAbsOrigin();
VectorNormalize ( vTargetDir );
LaunchRocket( vTargetDir, 100, 150, vecSrc);
m_iRockets--;
side = - side;
}
void CNPC_Apache::AimRocketGun( void )
{
Vector vForward, vRight, vUp;
if (m_iRockets <= 0)
return;
Vector vTargetDir = m_vecTargetPosition - GetAbsOrigin();
VectorNormalize ( vTargetDir );
AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp );
Vector vecEst = ( vForward * 800 + GetAbsVelocity());
VectorNormalize ( vecEst );
trace_t tr1;
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vecEst * 4096, MASK_ALL, this, COLLISION_GROUP_NONE, &tr1);
// NDebugOverlay::Line(GetAbsOrigin(), tr1.endpos, 255,255,0, false, 0.1);
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vTargetDir * 4096, MASK_ALL, this, COLLISION_GROUP_NONE, &tr1);
// NDebugOverlay::Line(GetAbsOrigin(), tr1.endpos, 0,255,0, false, 0.1);
// ALERT( at_console, "%d %d %d %4.2f\n", GetAbsAngles().x < 0, DotProduct( pev->velocity, gpGlobals->v_forward ) > -100, m_flNextRocket < gpGlobals->curtime, DotProduct( m_vecTarget, vecEst ) );
if ((m_iRockets % 2) == 1)
{
FireRocket( );
m_flNextRocket = gpGlobals->curtime + 0.5;
if (m_iRockets <= 0)
{
m_flNextRocket = gpGlobals->curtime + 10;
m_iRockets = 10;
}
}
else if (DotProduct( GetAbsVelocity(), vForward ) > -100 && m_flNextRocket < gpGlobals->curtime)
{
if (m_flLastSeen + 60 > gpGlobals->curtime)
{
if (GetEnemy() != NULL)
{
// make sure it's a good shot
//if (DotProduct( vTargetDir, vecEst) > 0.5)
{
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vecEst * 4096, MASK_ALL, this, COLLISION_GROUP_NONE, &tr);
// NDebugOverlay::Line(GetAbsOrigin(), tr.endpos, 255,0,255, false, 5);
// if ((tr.endpos - m_vecTargetPosition).Length() < 512)
if ((tr.endpos - m_vecTargetPosition).Length() < 1024)
FireRocket( );
}
}
else
{
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vecEst * 4096, MASK_ALL, this, COLLISION_GROUP_NONE, &tr);
// just fire when close
if ((tr.endpos - m_vecTargetPosition).Length() < 512)
FireRocket( );
}
}
}
}
#define MISSILE_HOMING_STRENGTH 0.3
#define MISSILE_HOMING_DELAY 5.0
#define MISSILE_HOMING_RAMP_UP 0.5
#define MISSILE_HOMING_DURATION 1.0
#define MISSILE_HOMING_RAMP_DOWN 0.5
void CNPC_Apache::LaunchRocket( Vector &viewDir, int damage, int radius, Vector vecLaunchPoint )
{
CGrenadeHomer *pGrenade = CGrenadeHomer::CreateGrenadeHomer( MAKE_STRING("models/weapons/w_missile.mdl"), MAKE_STRING("weapons/stinger_fire1.wav"), vecLaunchPoint, vec3_angle, edict() );
pGrenade->Spawn( );
pGrenade->SetHoming(MISSILE_HOMING_STRENGTH, MISSILE_HOMING_DELAY,
MISSILE_HOMING_RAMP_UP, MISSILE_HOMING_DURATION,
MISSILE_HOMING_RAMP_DOWN);
pGrenade->SetDamage( damage );
pGrenade->m_DmgRadius = radius;
pGrenade->Launch( this, GetEnemy(), viewDir * 1500, 500, 0, HOMER_SMOKE_TRAIL_ON );
}
//-----------------------------------------------------------------------------
// Purpose: Lame, temporary death
//-----------------------------------------------------------------------------
void CNPC_Apache::DyingThink( void )
{
StudioFrameAdvance( );
SetNextThink( gpGlobals->curtime + 0.1f );
if( random->RandomInt( 0, 50 ) == 1 )
{
Vector vecSize = Vector( 60, 60, 30 );
CPVSFilter filter( GetAbsOrigin() );
te->BreakModel( filter, 0.0, &GetAbsOrigin(), &vecSize, &vec3_origin, m_nDebrisModel, 100, 0, 2.5, BREAK_METAL );
}
QAngle angVel = GetLocalAngularVelocity();
if( angVel.y < 400 )
{
angVel.y *= 1.1;
SetLocalAngularVelocity( angVel );
}
Vector vecImpulse( 0, 0, 0 );
// add gravity
vecImpulse.z -= 38.4; // 32ft/sec
ApplyAbsVelocityImpulse( vecImpulse );
}
//**************************************************************************************
class CApacheHVR : public CHL1BaseGrenade
{
DECLARE_CLASS( CApacheHVR, CHL1BaseGrenade );
void Spawn( void );
void Precache( void );
void IgniteThink( void );
void AccelerateThink( void );
void StartRocketTrail( void );
void Detonate( CBaseEntity *pOther );
DECLARE_DATADESC();
int m_iTrail;
Vector m_vecForward;
float m_flDamage;
EHANDLE m_hSmokeTrail[2];
};
LINK_ENTITY_TO_CLASS( hvr_rocket, CApacheHVR );
BEGIN_DATADESC( CApacheHVR )
// DEFINE_FIELD( CApacheHVR, m_iTrail, FIELD_INTEGER ), // Dont' save, precache
DEFINE_FIELD( CApacheHVR, m_vecForward, FIELD_VECTOR ),
DEFINE_FUNCTION( CApacheHVR, IgniteThink ),
DEFINE_FUNCTION( CApacheHVR, AccelerateThink ),
DEFINE_FUNCTION( CApacheHVR, Detonate ),
END_DATADESC()
void CApacheHVR::StartRocketTrail( void )
{
SmokeTrail *pSmokeTrail = SmokeTrail::CreateSmokeTrail();
if( pSmokeTrail )
{
pSmokeTrail->m_SpawnRate = 500;
pSmokeTrail->m_ParticleLifetime = HOMER_TRAIL0_LIFE;
pSmokeTrail->m_StartColor.Init(0.7, 0.7, 0.7);
pSmokeTrail->m_EndColor.Init(0.5,0.5,0.5);
pSmokeTrail->m_StartSize = 10;
pSmokeTrail->m_EndSize = 10;
pSmokeTrail->m_SpawnRadius = 1;
pSmokeTrail->m_MinSpeed = 15;
pSmokeTrail->m_MaxSpeed = 25;
pSmokeTrail->SetLifetime(12);
pSmokeTrail->FollowEntity(ENTINDEX(pev));
m_hSmokeTrail[0] = pSmokeTrail;
}
pSmokeTrail = SmokeTrail::CreateSmokeTrail();
if( pSmokeTrail )
{
pSmokeTrail->m_SpawnRate = 150;
pSmokeTrail->m_ParticleLifetime = HOMER_TRAIL2_LIFE;
pSmokeTrail->m_StartColor.Init(0.7, 0.7, 0.7);
pSmokeTrail->m_EndColor.Init(0.5,0.5,0.5);
pSmokeTrail->m_StartSize = 12;
pSmokeTrail->m_EndSize = 20;
pSmokeTrail->m_SpawnRadius = 1;
pSmokeTrail->m_MinSpeed = 15;
pSmokeTrail->m_MaxSpeed = 25;
pSmokeTrail->SetLifetime(12);
pSmokeTrail->FollowEntity(ENTINDEX(pev));
m_hSmokeTrail[1] = pSmokeTrail;
}
}
void CApacheHVR :: Detonate ( CBaseEntity *pOther )
{
for ( int i = 0; i < 2; i++ )
{
if( m_hSmokeTrail[i] )
((SmokeTrail*)(CBaseEntity*)m_hSmokeTrail[i])->SetEmit(false);
}
ExplodeTouch( pOther );
}
void CApacheHVR :: Spawn( void )
{
Precache( );
// motor
SetSolid( SOLID_BBOX );
SetMoveType( MOVETYPE_FLY );
SetModel( "models/HVR.mdl" );
UTIL_SetSize(this, Vector( 0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin( this, GetAbsOrigin() );
SetThink( IgniteThink );
SetTouch( Detonate );
AngleVectors( GetAbsAngles(), &m_vecForward );
SetGravity( 0.5 );
SetNextThink( gpGlobals->curtime + 0.1f );
m_flDamage = 150;
}
void CApacheHVR :: Precache( void )
{
engine->PrecacheModel( "models/HVR.mdl" );
m_iTrail = engine->PrecacheModel( "sprites/smoke.spr" );
enginesound->PrecacheSound ( "weapons/rocket1.wav" );
}
void TE_BeamFollow( int msg_dest, float delay, const Vector *origin, const edict_t *recipient, int iEntIndex,
int modelIndex, int haloIndex, float haloScale, float life, float width, float endWidth,
float fadeLength,float r, float g, float b, float a, float brightness );
void CApacheHVR :: IgniteThink( void )
{
// make rocket sound
CPASAttenuationFilter filter( this, 0.5f );
enginesound->EmitSound( filter, entindex(), CHAN_VOICE, "weapons/rocket1.wav", 1, 0.5 );
StartRocketTrail();
// set to accelerate
SetThink( AccelerateThink );
SetNextThink( gpGlobals->curtime + 0.1f );
}
void CApacheHVR :: AccelerateThink( void )
{
// check world boundaries
if ( GetAbsOrigin().x < -4096 || GetAbsOrigin().x > 4096 || GetAbsOrigin().y < -4096 || GetAbsOrigin().y > 4096 || GetAbsOrigin().z < -4096 || GetAbsOrigin().z > 4096 )
{
UTIL_Remove( this );
return;
}
// accelerate
float flSpeed = GetAbsVelocity().Length();
if ( flSpeed < 1800 )
{
SetAbsVelocity( GetAbsVelocity() + m_vecForward * 200 );
}
Vector vVel = GetAbsVelocity();
VectorNormalize ( vVel );
QAngle angTmp;
VectorAngles( vVel, angTmp );
SetAbsAngles( angTmp );
SetNextThink( gpGlobals->curtime + 0.1f );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -