//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Base class for helicopters & helicopter-type vehicles // // $NoKeywords: $ //=============================================================================// #ifndef CBASEHELICOPTER_H #define CBASEHELICOPTER_H #ifdef _WIN32 #pragma once #endif #include "ai_basenpc.h" #include "ai_trackpather.h" //--------------------------------------------------------- // Helicopter flags //--------------------------------------------------------- enum HelicopterFlags_t { BITS_HELICOPTER_GUN_ON = 0x00000001, // Gun is on and aiming BITS_HELICOPTER_MISSILE_ON = 0x00000002, // Missile turrets are on and aiming }; //--------------------------------------------------------- //--------------------------------------------------------- #define SF_NOWRECKAGE 0x08 #define SF_NOROTORWASH 0x20 #define SF_AWAITINPUT 0x40 //--------------------------------------------------------- //--------------------------------------------------------- // Pathing data #define BASECHOPPER_LEAD_DISTANCE 800.0f #define BASECHOPPER_MIN_CHASE_DIST_DIFF \ 128.0f // Distance threshold used to determine when a target has moved // enough to update our navigation to it #define BASECHOPPER_AVOID_DIST 256.0f #define BASECHOPPER_MAX_SPEED 400.0f #define BASECHOPPER_MAX_FIRING_SPEED 250.0f #define BASECHOPPER_MIN_ROCKET_DIST 1000.0f #define BASECHOPPER_MAX_GUN_DIST 2000.0f //--------------------------------------------------------- // Physics rotor pushing #define BASECHOPPER_WASH_RADIUS 256 #define BASECHOPPER_WASH_PUSH_MIN \ 30 // Initial force * their mass applied to objects in the wash #define BASECHOPPER_WASH_PUSH_MAX \ 40 // Maximum force * their mass applied to objects in the wash #define BASECHOPPER_WASH_RAMP_TIME \ 1.0 // Time it takes to ramp from the initial to the max force on an object // in the wash (at the center of the wash) #define BASECHOPPER_WASH_MAX_MASS \ 300 // Don't attempt to push anything over this mass #define BASECHOPPER_WASH_MAX_OBJECTS \ 6 // Maximum number of objects the wash will push at once // Wash physics pushing struct washentity_t { DECLARE_DATADESC(); EHANDLE hEntity; float flWashStartTime; }; #define BASECHOPPER_WASH_ALTITUDE 1024.0f //========================================================= //========================================================= class CBaseHelicopter : public CAI_TrackPather { public: DECLARE_CLASS(CBaseHelicopter, CAI_TrackPather); DECLARE_DATADESC(); DECLARE_SERVERCLASS(); CBaseHelicopter(void); void Spawn(void); void Precache(void); virtual void UpdateOnRemove(); void Event_Killed(const CTakeDamageInfo &info); void StopLoopingSounds(); int BloodColor(void) { return DONT_BLEED; } void GibMonster(void); Class_T Classify(void) { return CLASS_COMBINE; } void CallDyingThink(void) { DyingThink(); } bool HasEnemy(void) { return GetEnemy() != NULL; } virtual void GatherEnemyConditions(CBaseEntity *pEnemy); virtual bool ChooseEnemy(void); virtual void HelicopterPostThink(void){}; virtual void FlyTouch(CBaseEntity *pOther); virtual void CrashTouch(CBaseEntity *pOther); virtual void HelicopterThink(void); virtual void DyingThink(void); virtual void NullThink(void); virtual void Startup(void); virtual void Flight(void); virtual void ShowDamage(void){}; void UpdatePlayerDopplerShift(void); virtual void Hunt(void); virtual bool IsCrashing(void) { return m_lifeState != LIFE_ALIVE; } virtual float GetAcceleration(void) { return 5; } virtual void ApplySidewaysDrag(const Vector &vecRight); virtual void ApplyGeneralDrag(void); void TraceAttack(const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator); virtual bool FireGun(void); virtual float GetRotorVolume(void); virtual void InitializeRotorSound(void); virtual void UpdateRotorSoundPitch(int iPitch); virtual void AimRocketGun(void){}; virtual void FireRocket(Vector vLaunchPos, Vector vLaunchDir){}; virtual bool GetTrackPatherTarget(Vector *pPos); virtual CBaseEntity *GetTrackPatherTargetEnt(); void DrawDebugGeometryOverlays(void); // Rotor washes virtual void DrawRotorWash(float flAltitude, const Vector &vecRotorOrigin); void DoRotorPhysicsPush(const Vector &vecRotorOrigin, float flAltitude); bool DoWashPush(washentity_t *pWash, const Vector &vecWashOrigin); void StopRotorWash(void); // Purpose: Marks the entity for deletion void InputKill(inputdata_t &inputdata); void DelayedKillThink(); virtual void SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways); // Helicopters never burn virtual void Ignite(float flFlameLifetime, bool bNPCOnly, float flSize, bool bCalledByLevelDesigner) { return; } protected: void HelicopterMove(); // Updates the enemy void UpdateEnemy(); // Override the desired position if your derived helicopter is doing // something special virtual void UpdateDesiredPosition(void); // Updates the facing direction virtual void UpdateFacingDirection(); // Fire weapons void FireWeapons(); // Computes the actual position to fly to void ComputeActualTargetPosition(float flSpeed, float flTime, float flPerpDist, Vector *pDest, bool bApplyNoise = true); // Gets the max speed of the helicopter virtual float GetMaxSpeed(); virtual float GetMaxSpeedFiring(); // Updates the enemy virtual float EnemySearchDistance(); // Rotor wash think void RotorWashThink(void); // Purpose: Push an airboat in our wash void DoWashPushOnAirboat(CBaseEntity *pAirboat, const Vector &vecWashToAirboat, float flWashAmount); // Updates the rotor wash volume virtual void UpdateRotorWashVolume(); // Rotor sound void InputEnableRotorSound(inputdata_t &inputdata); void InputDisableRotorSound(inputdata_t &inputdata); protected: CSoundPatch *m_pRotorSound; // Rotor loop played when the player can see // the helicopter CSoundPatch *m_pRotorBlast; // Sound played when the helicopter's pushing // around physics objects float m_flForce; int m_fHelicopterFlags; Vector m_vecDesiredFaceDir; float m_flLastSeen; float m_flPrevSeen; int m_iSoundState; // don't save this Vector m_vecTargetPosition; float m_flMaxSpeed; // Maximum speed of the helicopter. float m_flMaxSpeedFiring; // Maximum speed of the helicopter whilst firing // guns. float m_flGoalSpeed; // Goal speed float m_flInitialSpeed; float m_flRandomOffsetTime; Vector m_vecRandomOffset; float m_flRotorWashEntitySearchTime; bool m_bSuppressSound; EHANDLE m_hRotorWash; // Attached rotorwash entity // Inputs void InputActivate(inputdata_t &inputdata); // Inputs void InputGunOn(inputdata_t &inputdata); void InputGunOff(inputdata_t &inputdata); void InputMissileOn(inputdata_t &inputdata); void InputMissileOff(inputdata_t &inputdata); void InputEnableRotorWash(inputdata_t &inputdata); void InputDisableRotorWash(inputdata_t &inputdata); void InputMoveTopSpeed( inputdata_t &inputdata); // Causes the helicopter to immediately // accelerate to its desired velocity void InputMoveSpecifiedSpeed(inputdata_t &inputdata); void InputSetAngles( inputdata_t &inputdata); // Sets the angles of the helicopter protected: // Custom conservative collision volumes Vector m_cullBoxMins; Vector m_cullBoxMaxs; // Wash physics pushing CUtlVector m_hEntitiesPushedByWash; void SetStartupTime(float time) { m_flStartupTime = time; } private: CNetworkVar(float, m_flStartupTime); }; //----------------------------------------------------------------------------- // This entity is used to create little force spheres that the helicopter // should avoid. //----------------------------------------------------------------------------- class CAvoidSphere : public CBaseEntity { DECLARE_DATADESC(); public: DECLARE_CLASS(CAvoidSphere, CBaseEntity); void Init(float flRadius); virtual void Activate(); virtual void UpdateOnRemove(); static void ComputeAvoidanceForces(CBaseEntity *pEntity, float flEntityRadius, float flAvoidTime, Vector *pVecAvoidForce); private: typedef CHandle AvoidSphereHandle_t; float m_flRadius; static CUtlVector s_AvoidSpheres; }; //----------------------------------------------------------------------------- // This entity is used to create little force boxes that the helicopter // should avoid. //----------------------------------------------------------------------------- class CAvoidBox : public CBaseEntity { DECLARE_DATADESC(); public: DECLARE_CLASS(CAvoidBox, CBaseEntity); virtual void Spawn(); virtual void Activate(); virtual void UpdateOnRemove(); static void ComputeAvoidanceForces(CBaseEntity *pEntity, float flEntityRadius, float flAvoidTime, Vector *pVecAvoidForce); private: typedef CHandle AvoidBoxHandle_t; static CUtlVector s_AvoidBoxes; }; #endif // CBASEHELICOPTER_H