//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef AI_BASENPC_PHYSICSFLYER_H #define AI_BASENPC_PHYSICSFLYER_H #ifdef _WIN32 #pragma once #endif #include "ai_basenpc.h" #include "ai_navigator.h" //----------------------------------------------------------------------------- // The combot. //----------------------------------------------------------------------------- abstract_class CAI_BasePhysicsFlyingBot : public CAI_BaseNPC, public IMotionEvent { DECLARE_CLASS(CAI_BasePhysicsFlyingBot, CAI_BaseNPC); public: DECLARE_DATADESC(); void StartTask(const Task_t *pTask); void GetVelocity(Vector * vVelocity, AngularImpulse * vAngVelocity); virtual QAngle BodyAngles(); virtual bool ShouldSavePhysics() { return true; } protected: CAI_BasePhysicsFlyingBot(); ~CAI_BasePhysicsFlyingBot(); Vector VelocityToAvoidObstacles(float flInterval); virtual float MinGroundDist(void); virtual void TurnHeadToTarget(float flInterval, const Vector &moveTarget); void MoveInDirection(float flInterval, const Vector &targetDir, float accelXY, float accelZ, float decay) { decay = ExponentialDecay(decay, 1.0, flInterval); accelXY *= flInterval; accelZ *= flInterval; m_vCurrentVelocity.x = (decay * m_vCurrentVelocity.x + accelXY * targetDir.x); m_vCurrentVelocity.y = (decay * m_vCurrentVelocity.y + accelXY * targetDir.y); m_vCurrentVelocity.z = (decay * m_vCurrentVelocity.z + accelZ * targetDir.z); } void MoveToLocation(float flInterval, const Vector &target, float accelXY, float accelZ, float decay) { Vector targetDir = target - GetLocalOrigin(); VectorNormalize(targetDir); MoveInDirection(flInterval, targetDir, accelXY, accelZ, decay); } void Decelerate(float flInterval, float decay) { decay *= flInterval; m_vCurrentVelocity.x = (decay * m_vCurrentVelocity.x); m_vCurrentVelocity.y = (decay * m_vCurrentVelocity.y); m_vCurrentVelocity.z = (decay * m_vCurrentVelocity.z); } void AddNoiseToVelocity(float noiseScale = 1.0) { if (m_vNoiseMod.x) { m_vCurrentVelocity.x += noiseScale * sin(m_vNoiseMod.x * gpGlobals->curtime + m_vNoiseMod.x); } if (m_vNoiseMod.y) { m_vCurrentVelocity.y += noiseScale * cos(m_vNoiseMod.y * gpGlobals->curtime + m_vNoiseMod.y); } if (m_vNoiseMod.z) { m_vCurrentVelocity.z -= noiseScale * cos(m_vNoiseMod.z * gpGlobals->curtime + m_vNoiseMod.z); } } void LimitSpeed(float zLimit, float maxSpeed = -1) { if (maxSpeed == -1) maxSpeed = m_flSpeed; if (m_vCurrentVelocity.Length() > maxSpeed) { VectorNormalize(m_vCurrentVelocity); m_vCurrentVelocity *= maxSpeed; } // Limit fall speed if (zLimit > 0 && m_vCurrentVelocity.z < -zLimit) { m_vCurrentVelocity.z = -zLimit; } } AI_NavPathProgress_t ProgressFlyPath( float flInterval, const CBaseEntity *pNewTarget, unsigned collisionMask, bool bNewTrySimplify = true, float strictPointTolerance = 32.0); const Vector &GetCurrentVelocity() const { return m_vCurrentVelocity; } void SetCurrentVelocity(const Vector &vNewVel) { m_vCurrentVelocity = vNewVel; } const Vector &GetNoiseMod() const { return m_vNoiseMod; } void SetNoiseMod(float x, float y, float z) { m_vNoiseMod.Init(x, y, z); } void SetNoiseMod(const Vector &noise) { m_vNoiseMod = noise; } void TranslateNavGoal(CBaseEntity * pTarget, Vector & chasePosition); virtual void MoveToTarget(float flInterval, const Vector &MoveTarget) = 0; virtual float GetHeadTurnRate(void) { return 15.0f; } // Degrees per second bool CreateVPhysics(void); IMotionEvent::simresult_e Simulate( IPhysicsMotionController * pController, IPhysicsObject * pObject, float deltaTime, Vector &linear, AngularImpulse &angular); virtual void ClampMotorForces(Vector & linear, AngularImpulse & angular) { // limit reaction forces linear.x = clamp(linear.x, -3000.f, 3000.f); linear.y = clamp(linear.y, -3000.f, 3000.f); linear.z = clamp(linear.z, -3000.f, 3000.f); // add in weightlessness linear.z += 800.f; } // ------------------------------- // Movement vars // ------------------------------- Vector m_vCurrentVelocity; Vector m_vCurrentBanking; Vector m_vNoiseMod; float m_fHeadYaw; Vector m_vLastPatrolDir; IPhysicsMotionController *m_pMotionController; }; #endif // AI_BASENPC_PHYSICSFLYER_H