|
|
|
|
//========= Copyright <EFBFBD> 1996-2005, 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, 3000 );
|
|
|
|
|
linear.y = clamp( linear.y, -3000, 3000 );
|
|
|
|
|
linear.z = clamp( linear.z, -3000, 3000 );
|
|
|
|
|
|
|
|
|
|
// add in weightlessness
|
|
|
|
|
linear.z += 800;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -------------------------------
|
|
|
|
|
// 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
|