//========= 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< washentity_t > 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< AvoidSphereHandle_t > 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< AvoidBoxHandle_t > s_AvoidBoxes; }; #endif // CBASEHELICOPTER_H