⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hl1_npc_apache.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include	"cbase.h"
#include	"AI_Default.h"
#include	"AI_Task.h"
#include	"AI_Schedule.h"
#include	"AI_Node.h"
#include	"AI_Hull.h"
#include	"AI_Hint.h"
#include	"AI_Route.h"
#include	"soundent.h"
#include	"game.h"
#include	"NPCEvent.h"
#include	"EntityList.h"
#include	"activitylist.h"
#include	"hl1_basegrenade.h"
#include	"animation.h"
#include	"IEffects.h"
#include	"vstdlib/random.h"
#include	"engine/IEngineSound.h"
#include	"ammodef.h"
#include	"soundenvelope.h"
#include	"hl1_cbasehelicopter.h"
#include	"ndebugoverlay.h"
#include	"smoke_trail.h"
#include	"beam_shared.h"
#include	"grenade_homer.h"

#define	 HOMER_TRAIL0_LIFE		0.1
#define	 HOMER_TRAIL1_LIFE		0.2
#define	 HOMER_TRAIL2_LIFE		3.0//	1.0

#define  SF_NOTRANSITION 128

class CNPC_Apache : public CBaseHelicopter
{
	DECLARE_CLASS( CNPC_Apache, CBaseHelicopter );
public:
	
	void Spawn( void );
	void Precache( void );

	int  BloodColor( void ) { return DONT_BLEED; }
	Class_T  Classify( void ) { return CLASS_HUMAN_MILITARY; };
	void InitializeRotorSound( void );
	void LaunchRocket( Vector &viewDir, int damage, int radius, Vector vecLaunchPoint );

	void Flight( void );

	void SetObjectCollisionBox( void )
	{
		SetAbsMins( GetAbsOrigin() + Vector( -300, -300, -172) );
		SetAbsMaxs( GetAbsOrigin() + Vector(300, 300, 8) );
	}

	bool FireGun( void );
	void AimRocketGun( void );
	void FireRocket( void );
	void DyingThink( void );

	int  ObjectCaps( void );
	
   /* int		Save( CSave &save );
	int		Restore( CRestore &restore );
	static	TYPEDESCRIPTION m_SaveData[];

	void Spawn( void );
	void Precache( void );

	
	void Killed( entvars_t *pevAttacker, int iGib );
	void GibMonster( void );

	void EXPORT HuntThink( void );
	void EXPORT FlyTouch( CBaseEntity *pOther );
	void EXPORT CrashTouch( CBaseEntity *pOther );
	void EXPORT DyingThink( void );
	void EXPORT StartupUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
	void EXPORT NullThink( void );

	void ShowDamage( void );
	void Flight( void );
	void FireRocket( void );
	BOOL FireGun( void );
	
	int  TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
	void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);*/

	int m_iRockets;
	float m_flForce;
	float m_flNextRocket;

	int m_iAmmoType;

	Vector m_vecTarget;
	Vector m_posTarget;

	Vector m_vecDesired;
	Vector m_posDesired;

	Vector m_vecGoal;

	Vector m_angGun;
	
	int m_iSoundState; // don't save this

	int m_iSpriteTexture;
	int m_iExplode;
	int m_iBodyGibs;
	int	m_nDebrisModel;

	float m_flGoalSpeed;

	int m_iDoSmokePuff;
	CBeam *m_pBeam;
};

void CNPC_Apache :: Spawn( void )
{
	Precache( );
	SetModel( "models/apache.mdl" );

	UTIL_SetSize( this, Vector( -256, -256, 0 ), Vector( 256, 256, 128 ) );
	UTIL_SetOrigin( this, GetAbsOrigin() );

	m_spawnflags &= ~SF_AWAITINPUT;
	BaseClass::Spawn();
	m_iHealth			= 100;

	m_flFieldOfView = -0.707; // 270 degrees

	m_fHelicopterFlags	= BITS_HELICOPTER_MISSILE_ON | BITS_HELICOPTER_GUN_ON;

	InitBoneControllers();

	SetRenderColor( 255, 255, 255, 255 );

	m_iRockets = 10;
}

LINK_ENTITY_TO_CLASS ( monster_apache, CNPC_Apache );

int CNPC_Apache::ObjectCaps( void ) 
{ 
	if ( GetSpawnFlags() & SF_NOTRANSITION )
	     return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; 
	else 
		 return BaseClass::ObjectCaps();
}

void CNPC_Apache::Precache( void )
{
	m_iAmmoType = GetAmmoDef()->Index("9mmRound"); 

	engine->PrecacheModel("models/apache.mdl");

	enginesound->PrecacheSound("apache/ap_rotor1.wav");
	enginesound->PrecacheSound("apache/ap_rotor2.wav");
	enginesound->PrecacheSound("apache/ap_rotor3.wav");
	enginesound->PrecacheSound("apache/ap_whine1.wav");

	enginesound->PrecacheSound("weapons/mortarhit.wav");

	//m_iSpriteTexture = PRECACHE_MODEL( "sprites/white.spr" );

	enginesound->PrecacheSound("turret/tu_fire1.wav");

	engine->PrecacheModel("sprites/lgtning.spr");

//	m_iExplode	= PRECACHE_MODEL( "sprites/fexplo.spr" );
//	m_iBodyGibs = PRECACHE_MODEL( "models/metalplategibs_green.mdl" );

//	UTIL_PrecacheOther( "hvr_rocket" );

	engine->PrecacheModel( "models/weapons/w_missile.mdl" );
	m_nDebrisModel = engine->PrecacheModel( "models/gibs/rock_gibs.mdl" );

	BaseClass::Precache();
}

void CNPC_Apache::InitializeRotorSound( void )
{
	CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();

	CPASAttenuationFilter filter( this );
	m_pRotorSound	= controller.SoundCreate( filter, entindex(), CHAN_STATIC, "apache/ap_rotor2.wav", 0.2 );

	BaseClass::InitializeRotorSound();
}

void CNPC_Apache::Flight( void )
{
	StudioFrameAdvance( );

	float flDistToDesiredPosition = (GetAbsOrigin() - m_vecDesiredPosition).Length();
	//NDebugOverlay::Line(GetAbsOrigin(), GetDesiredPosition(), 0,0,255, true, 0.1);

	if (m_flGoalSpeed < 800 )
		m_flGoalSpeed += GetAcceleration();


//	Vector vecGoalOrientation;
	if (flDistToDesiredPosition > 250) // 500
	{
		Vector v1 = (m_vecTargetPosition - GetAbsOrigin());
		Vector v2 = (m_vecDesiredPosition - GetAbsOrigin());

		VectorNormalize( v1 );
		VectorNormalize( v2 );

		if (m_flLastSeen + 90 > gpGlobals->curtime && DotProduct( v1, v2 ) > 0.25)
		{
			m_vecGoalOrientation = ( m_vecTargetPosition - GetAbsOrigin());
		}
		else
		{
			m_vecGoalOrientation = (m_vecDesiredPosition - GetAbsOrigin());
		}
		VectorNormalize( m_vecGoalOrientation );
	}
	else
	{
		AngleVectors( m_pGoalEnt->GetAbsAngles(), &m_vecGoalOrientation );
	}
//	SetGoalOrientation( vecGoalOrientation );
	

	if (m_pGoalEnt)
	{
		// ALERT( at_console, "%.0f\n", flLength );
		if ( HasReachedTarget() )
		{
			// If we get this close to the desired position, it's assumed that we've reached
			// the desired position, so move on.

			// Fire target that I've reached my goal
			m_AtTarget.FireOutput( m_pGoalEnt, this );

			OnReachedTarget( m_pGoalEnt );

			m_pGoalEnt = gEntList.FindEntityByName( NULL, m_pGoalEnt->m_target, NULL );

			if (m_pGoalEnt)
			{
				m_vecDesiredPosition = m_pGoalEnt->GetAbsOrigin();
				
//				Vector vecGoalOrientation;
				AngleVectors( m_pGoalEnt->GetAbsAngles(), &m_vecGoalOrientation );

//				SetGoalOrientation( vecGoalOrientation );

				flDistToDesiredPosition = (GetAbsOrigin() - m_vecDesiredPosition).Length();
			}
		}
	}
	else
	{
		// If we can't find a new target, just stay where we are.
		m_vecDesiredPosition = GetAbsOrigin();
	}

	// tilt model 5 degrees
	QAngle angAdj = QAngle( 5.0, 0, 0 );

	// estimate where I'll be facing in one seconds
	Vector forward, right, up;
	AngleVectors( GetAbsAngles() + GetLocalAngularVelocity() * 2 + angAdj, &forward, &right, &up );
	// Vector vecEst1 = GetAbsOrigin() + pev->velocity + gpGlobals->v_up * m_flForce - Vector( 0, 0, 384 );
	// float flSide = DotProduct( m_posDesired - vecEst1, gpGlobals->v_right );
	

	QAngle angVel = GetLocalAngularVelocity();
	float flSide = DotProduct( m_vecGoalOrientation, right );

	if (flSide < 0)
	{
		if ( angVel.y < 60)
		{
			 angVel.y += 8; // 9 * (3.0/2.0);
		}
	}
	else
	{
		if ( angVel.y > -60)
		{
			 angVel.y -= 8; // 9 * (3.0/2.0);
		}
	}
	angVel.y *= 0.98;
	SetLocalAngularVelocity( angVel );

	Vector vecVel = GetAbsVelocity();

	// estimate where I'll be in two seconds
	AngleVectors( GetAbsAngles() + GetLocalAngularVelocity() * 1 + angAdj, &forward, &right, &up );
	Vector vecEst = GetAbsOrigin() + vecVel * 2.0 + up * m_flForce * 20 - Vector( 0, 0, 384 * 2 );

	// add immediate force
	AngleVectors( GetAbsAngles() + angAdj, &forward, &right, &up );

	vecVel.x += up.x * m_flForce;
	vecVel.y += up.y * m_flForce;
	vecVel.z += up.z * m_flForce;
	// add gravity
	vecVel.z -= 38.4; // 32ft/sec

	float flSpeed = vecVel.Length();
	float flDir = DotProduct( Vector( forward.x, forward.y, 0 ), Vector( vecVel.x, vecVel.y, 0 ) );
	if (flDir < 0)
		flSpeed = -flSpeed;

	float flDist = DotProduct( m_vecDesiredPosition - vecEst, forward );

	// float flSlip = DotProduct( pev->velocity, gpGlobals->v_right );
	float flSlip = -DotProduct( m_vecDesiredPosition - vecEst, right );

	angVel = GetLocalAngularVelocity();
	// fly sideways
	if (flSlip > 0)
	{
		if (GetAbsAngles().z > -30 && angVel.z > -15)
			angVel.z -= 4;
		else
			angVel.z += 2;
	}
	else
	{

		if (GetAbsAngles().z < 30 && angVel.z < 15)
			angVel.z += 4;
		else
			angVel.z -= 2;
	}
	SetLocalAngularVelocity( angVel );

	// sideways drag
	vecVel.x = vecVel.x * (1.0 - fabs( right.x ) * 0.05);
    vecVel.y = vecVel.y * (1.0 - fabs( right.y ) * 0.05);
	vecVel.z = vecVel.z * (1.0 - fabs( right.z ) * 0.05);

	// general drag
	vecVel = vecVel * 0.995;

	// Set final computed velocity
	SetAbsVelocity( vecVel );
	
	// apply power to stay correct height
	if (m_flForce < 80 && vecEst.z < m_vecDesiredPosition.z) 
	{
		m_flForce += 12;
	}
	else if (m_flForce > 30)
	{
		if (vecEst.z > m_vecDesiredPosition.z) 
			m_flForce -= 8;
	}


	angVel = GetLocalAngularVelocity();
	// pitch forward or back to get to target
	if (flDist > 0 && flSpeed < m_flGoalSpeed && GetAbsAngles().x + angVel.x < 40)
	{
		// ALERT( at_console, "F " );
		// lean forward
		angVel.x += 12.0;
	}
	else if (flDist < 0 && flSpeed > -50 && GetAbsAngles().x + angVel.x  > -20)
	{
		// ALERT( at_console, "B " );
		// lean backward
		angVel.x -= 12.0;
	}
	else if (GetAbsAngles().x + angVel.x < 0)
	{
		// ALERT( at_console, "f " );
		angVel.x += 4.0;
	}
	else if (GetAbsAngles().x + angVel.x > 0)
	{
		// ALERT( at_console, "b " );
		angVel.x -= 4.0;
	}

	// Set final computed angular velocity
	SetLocalAngularVelocity( angVel );

	// ALERT( at_console, "%.0f %.0f : %.0f %.0f : %.0f %.0f : %.0f\n", GetAbsOrigin().x, pev->velocity.x, flDist, flSpeed, GetAbsAngles().x, pev->avelocity.x, m_flForce ); 
	// ALERT( at_console, "%.0f %.0f : %.0f %0.f : %.0f\n", GetAbsOrigin().z, pev->velocity.z, vecEst.z, m_posDesired.z, m_flForce ); 
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -