You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
12 KiB
336 lines
12 KiB
5 years ago
|
// NextBotLocomotionInterface.h
|
||
|
// NextBot interface for movement through the environment
|
||
|
// Author: Michael Booth, April 2005
|
||
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
|
||
|
#ifndef _NEXT_BOT_LOCOMOTION_INTERFACE_H_
|
||
|
#define _NEXT_BOT_LOCOMOTION_INTERFACE_H_
|
||
|
|
||
|
#include "NextBotComponentInterface.h"
|
||
|
|
||
|
class Path;
|
||
|
class INextBot;
|
||
|
class CNavLadder;
|
||
|
|
||
|
//----------------------------------------------------------------------------------------------------------------
|
||
|
/**
|
||
|
* The interface encapsulating *how* a bot moves through the world (walking? flying? etc)
|
||
|
*/
|
||
|
class ILocomotion : public INextBotComponent
|
||
|
{
|
||
|
public:
|
||
|
ILocomotion( INextBot *bot );
|
||
|
virtual ~ILocomotion();
|
||
|
|
||
|
virtual void Reset( void ); // (EXTEND) reset to initial state
|
||
|
virtual void Update( void ); // (EXTEND) update internal state
|
||
|
|
||
|
//
|
||
|
// The primary locomotive method
|
||
|
// Depending on the physics of the bot's motion, it may not actually
|
||
|
// reach the given position precisely.
|
||
|
// The 'weight' can be used to combine multiple Approach() calls within
|
||
|
// a single frame into a single goal (ie: weighted average)
|
||
|
//
|
||
|
virtual void Approach( const Vector &goalPos, float goalWeight = 1.0f ); // (EXTEND) move directly towards the given position
|
||
|
|
||
|
//
|
||
|
// Move the bot to the precise given position immediately,
|
||
|
// updating internal state as needed
|
||
|
// Collision resolution is done to prevent interpenetration, which may prevent
|
||
|
// the bot from reaching the given position. If no collisions occur, the
|
||
|
// bot will be at the given position when this method returns.
|
||
|
//
|
||
|
virtual void DriveTo( const Vector &pos ); // (EXTEND) Move the bot to the precise given position immediately,
|
||
|
|
||
|
//
|
||
|
// Locomotion modifiers
|
||
|
//
|
||
|
virtual bool ClimbUpToLedge( const Vector &landingGoal, const Vector &landingForward, const CBaseEntity *obstacle ) { return true; } // initiate a jump to an adjacent high ledge, return false if climb can't start
|
||
|
virtual void JumpAcrossGap( const Vector &landingGoal, const Vector &landingForward ) { } // initiate a jump across an empty volume of space to far side
|
||
|
virtual void Jump( void ) { } // initiate a simple undirected jump in the air
|
||
|
virtual bool IsClimbingOrJumping( void ) const; // is jumping in any form
|
||
|
virtual bool IsClimbingUpToLedge( void ) const; // is climbing up to a high ledge
|
||
|
virtual bool IsJumpingAcrossGap( void ) const; // is jumping across a gap to the far side
|
||
|
virtual bool IsScrambling( void ) const; // is in the middle of a complex action (climbing a ladder, climbing a ledge, jumping, etc) that shouldn't be interrupted
|
||
|
|
||
|
virtual void Run( void ) { } // set desired movement speed to running
|
||
|
virtual void Walk( void ) { } // set desired movement speed to walking
|
||
|
virtual void Stop( void ) { } // set desired movement speed to stopped
|
||
|
virtual bool IsRunning( void ) const;
|
||
|
virtual void SetDesiredSpeed( float speed ) { } // set desired speed for locomotor movement
|
||
|
virtual float GetDesiredSpeed( void ) const; // returns the current desired speed
|
||
|
|
||
|
virtual void SetSpeedLimit( float speed ) { } // set maximum speed bot can reach, regardless of desired speed
|
||
|
virtual float GetSpeedLimit( void ) const { return 1000.0f; } // get maximum speed bot can reach, regardless of desired speed
|
||
|
|
||
|
virtual bool IsOnGround( void ) const; // return true if standing on something
|
||
|
virtual void OnLeaveGround( CBaseEntity *ground ) { } // invoked when bot leaves ground for any reason
|
||
|
virtual void OnLandOnGround( CBaseEntity *ground ) { } // invoked when bot lands on the ground after being in the air
|
||
|
virtual CBaseEntity *GetGround( void ) const; // return the current ground entity or NULL if not on the ground
|
||
|
virtual const Vector &GetGroundNormal( void ) const; // surface normal of the ground we are in contact with
|
||
|
virtual float GetGroundSpeed( void ) const; // return current world space speed in XY plane
|
||
|
virtual const Vector &GetGroundMotionVector( void ) const; // return unit vector in XY plane describing our direction of motion - even if we are currently not moving
|
||
|
|
||
|
virtual void ClimbLadder( const CNavLadder *ladder, const CNavArea *dismountGoal ) { } // climb the given ladder to the top and dismount
|
||
|
virtual void DescendLadder( const CNavLadder *ladder, const CNavArea *dismountGoal ) { } // descend the given ladder to the bottom and dismount
|
||
|
virtual bool IsUsingLadder( void ) const; // we are moving to get on, ascending/descending, and/or dismounting a ladder
|
||
|
virtual bool IsAscendingOrDescendingLadder( void ) const; // we are actually on the ladder right now, either climbing up or down
|
||
|
virtual bool IsAbleToAutoCenterOnLadder( void ) const { return false; }
|
||
|
|
||
|
virtual void FaceTowards( const Vector &target ) { } // rotate body to face towards "target"
|
||
|
|
||
|
virtual void SetDesiredLean( const QAngle &lean ) { }
|
||
|
virtual const QAngle &GetDesiredLean( void ) const;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Locomotion information
|
||
|
//
|
||
|
virtual bool IsAbleToJumpAcrossGaps( void ) const; // return true if this bot can jump across gaps in its path
|
||
|
virtual bool IsAbleToClimb( void ) const; // return true if this bot can climb arbitrary geometry it encounters
|
||
|
|
||
|
virtual const Vector &GetFeet( void ) const; // return position of "feet" - the driving point where the bot contacts the ground
|
||
|
|
||
|
virtual float GetStepHeight( void ) const; // if delta Z is greater than this, we have to jump to get up
|
||
|
virtual float GetMaxJumpHeight( void ) const; // return maximum height of a jump
|
||
|
virtual float GetDeathDropHeight( void ) const; // distance at which we will die if we fall
|
||
|
|
||
|
virtual float GetRunSpeed( void ) const; // get maximum running speed
|
||
|
virtual float GetWalkSpeed( void ) const; // get maximum walking speed
|
||
|
|
||
|
virtual float GetMaxAcceleration( void ) const; // return maximum acceleration of locomotor
|
||
|
virtual float GetMaxDeceleration( void ) const; // return maximum deceleration of locomotor
|
||
|
|
||
|
virtual const Vector &GetVelocity( void ) const; // return current world space velocity
|
||
|
virtual float GetSpeed( void ) const; // return current world space speed (magnitude of velocity)
|
||
|
virtual const Vector &GetMotionVector( void ) const; // return unit vector describing our direction of motion - even if we are currently not moving
|
||
|
|
||
|
virtual bool IsAreaTraversable( const CNavArea *baseArea ) const; // return true if given area can be used for navigation
|
||
|
|
||
|
virtual float GetTraversableSlopeLimit( void ) const; // return Z component of unit normal of steepest traversable slope
|
||
|
|
||
|
// return true if the given entity can be ignored during locomotion
|
||
|
enum TraverseWhenType
|
||
|
{
|
||
|
IMMEDIATELY, // the entity will not block our motion - we'll carry right through
|
||
|
EVENTUALLY // the entity will block us until we spend effort to open/destroy it
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return true if this locomotor could potentially move along the line given.
|
||
|
* If false is returned, fraction of walkable ray is returned in 'fraction'
|
||
|
*/
|
||
|
virtual bool IsPotentiallyTraversable( const Vector &from, const Vector &to, TraverseWhenType when = EVENTUALLY, float *fraction = NULL ) const;
|
||
|
|
||
|
/**
|
||
|
* Return true if there is a possible "gap" that will need to be jumped over
|
||
|
* If true is returned, fraction of ray before gap is returned in 'fraction'
|
||
|
*/
|
||
|
virtual bool HasPotentialGap( const Vector &from, const Vector &to, float *fraction = NULL ) const;
|
||
|
|
||
|
// return true if there is a "gap" here when moving in the given direction
|
||
|
virtual bool IsGap( const Vector &pos, const Vector &forward ) const;
|
||
|
|
||
|
virtual bool IsEntityTraversable( CBaseEntity *obstacle, TraverseWhenType when = EVENTUALLY ) const;
|
||
|
|
||
|
//
|
||
|
// Stuck state. If the locomotor cannot make progress, it becomes "stuck" and can only leave
|
||
|
// this stuck state by successfully moving and becoming un-stuck.
|
||
|
//
|
||
|
virtual bool IsStuck( void ) const; // return true if bot is stuck
|
||
|
virtual float GetStuckDuration( void ) const; // return how long we've been stuck
|
||
|
virtual void ClearStuckStatus( const char *reason = "" ); // reset stuck status to un-stuck
|
||
|
|
||
|
virtual bool IsAttemptingToMove( void ) const; // return true if we have tried to Approach() or DriveTo() very recently
|
||
|
|
||
|
void TraceHull( const Vector& start, const Vector& end, const Vector &mins, const Vector &maxs, unsigned int fMask, ITraceFilter *pFilter, trace_t *pTrace ) const;
|
||
|
|
||
|
/**
|
||
|
* Should we collide with this entity?
|
||
|
*/
|
||
|
virtual bool ShouldCollideWith( const CBaseEntity *object ) const { return true; }
|
||
|
|
||
|
|
||
|
protected:
|
||
|
virtual void AdjustPosture( const Vector &moveGoal );
|
||
|
virtual void StuckMonitor( void );
|
||
|
|
||
|
private:
|
||
|
Vector m_motionVector;
|
||
|
Vector m_groundMotionVector;
|
||
|
float m_speed;
|
||
|
float m_groundSpeed;
|
||
|
|
||
|
// stuck monitoring
|
||
|
bool m_isStuck; // if true, we are stuck
|
||
|
IntervalTimer m_stuckTimer; // how long we've been stuck
|
||
|
CountdownTimer m_stillStuckTimer; // for resending stuck events
|
||
|
Vector m_stuckPos; // where we got stuck
|
||
|
IntervalTimer m_moveRequestTimer;
|
||
|
};
|
||
|
|
||
|
|
||
|
inline bool ILocomotion::IsAbleToJumpAcrossGaps( void ) const
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsAbleToClimb( void ) const
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsAttemptingToMove( void ) const
|
||
|
{
|
||
|
return m_moveRequestTimer.HasStarted() && m_moveRequestTimer.GetElapsedTime() < 0.25f;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsScrambling( void ) const
|
||
|
{
|
||
|
return !IsOnGround() || IsClimbingOrJumping() || IsAscendingOrDescendingLadder();
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsClimbingOrJumping( void ) const
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsClimbingUpToLedge( void ) const
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsJumpingAcrossGap( void ) const
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsRunning( void ) const
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetDesiredSpeed( void ) const
|
||
|
{
|
||
|
return 0.0f;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsOnGround( void ) const
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
inline CBaseEntity *ILocomotion::GetGround( void ) const
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
inline const Vector &ILocomotion::GetGroundNormal( void ) const
|
||
|
{
|
||
|
return vec3_origin;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetGroundSpeed( void ) const
|
||
|
{
|
||
|
return m_groundSpeed;
|
||
|
}
|
||
|
|
||
|
inline const Vector & ILocomotion::GetGroundMotionVector( void ) const
|
||
|
{
|
||
|
return m_groundMotionVector;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsUsingLadder( void ) const
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsAscendingOrDescendingLadder( void ) const
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
inline const QAngle &ILocomotion::GetDesiredLean( void ) const
|
||
|
{
|
||
|
return vec3_angle;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetStepHeight( void ) const
|
||
|
{
|
||
|
return 0.0f;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetMaxJumpHeight( void ) const
|
||
|
{
|
||
|
return 0.0f;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetDeathDropHeight( void ) const
|
||
|
{
|
||
|
return 0.0f;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetRunSpeed( void ) const
|
||
|
{
|
||
|
return 0.0f;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetWalkSpeed( void ) const
|
||
|
{
|
||
|
return 0.0f;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetMaxAcceleration( void ) const
|
||
|
{
|
||
|
return 0.0f;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetMaxDeceleration( void ) const
|
||
|
{
|
||
|
return 0.0f;
|
||
|
}
|
||
|
|
||
|
inline const Vector &ILocomotion::GetVelocity( void ) const
|
||
|
{
|
||
|
return vec3_origin;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetSpeed( void ) const
|
||
|
{
|
||
|
return m_speed;
|
||
|
}
|
||
|
|
||
|
inline const Vector & ILocomotion::GetMotionVector( void ) const
|
||
|
{
|
||
|
return m_motionVector;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetTraversableSlopeLimit( void ) const
|
||
|
{
|
||
|
return 0.6;
|
||
|
}
|
||
|
|
||
|
inline bool ILocomotion::IsStuck( void ) const
|
||
|
{
|
||
|
return m_isStuck;
|
||
|
}
|
||
|
|
||
|
inline float ILocomotion::GetStuckDuration( void ) const
|
||
|
{
|
||
|
return ( IsStuck() ) ? m_stuckTimer.GetElapsedTime() : 0.0f;
|
||
|
}
|
||
|
|
||
|
inline void ILocomotion::TraceHull( const Vector& start, const Vector& end, const Vector &mins, const Vector &maxs, unsigned int fMask, ITraceFilter *pFilter, trace_t *pTrace ) const
|
||
|
{
|
||
|
// VPROF_BUDGET( "ILocomotion::TraceHull", "TraceHull" );
|
||
|
Ray_t ray;
|
||
|
ray.Init( start, end, mins, maxs );
|
||
|
enginetrace->TraceRay( ray, fMask, pFilter, pTrace );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#endif // _NEXT_BOT_LOCOMOTION_INTERFACE_H_
|
||
|
|