hl2_src-leak-2017/src/game/server/ai_movetypes.h

384 lines
12 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef AI_MOVETYPES_H
#define AI_MOVETYPES_H
#if defined( _WIN32 )
#pragma once
#endif
#include "ai_navtype.h"
class CAI_Path;
//-----------------------------------------------------------------------------
// Debugging code
//
// Use this function to set breakpoints to find out where movement is failing
//
#ifdef DEBUG
extern void DebugNoteMovementFailure();
#define DebugNoteMovementFailureIfBlocked( moveResult ) if ( !IsMoveBlocked( moveResult ) ) ((void)0); else DebugNoteMovementFailure()
#else
#define DebugNoteMovementFailure() ((void)0)
#define DebugNoteMovementFailureIfBlocked( moveResult ) ((void)0)
#endif
enum AIMoveResult_t
{
AIMR_BLOCKED_ENTITY = -1, // Move was blocked by an entity
AIMR_BLOCKED_WORLD = -2, // Move was blocked by the world
AIMR_BLOCKED_NPC = -3, // Move was blocked by an NPC
AIMR_ILLEGAL = -4, // Move is illegal for some reason
AIMR_OK = 0,
AIMR_CHANGE_TYPE, // Locomotion method has changed
};
#ifdef DEBUG
extern AIMoveResult_t DbgResult( AIMoveResult_t result );
#else
inline AIMoveResult_t DbgResult( AIMoveResult_t result ) { return result; } // inline not macro for compiler typing
#endif
//-----------------------------------------------------------------------------
// Movement related constants and base types
//-----------------------------------------------------------------------------
#ifdef PHYSICS_NPC_SHADOW_DISCREPENCY
const float AI_EPS_CASTS = 0.3; // The amount physics and hull cast can disagree
#endif
inline bool IsMoveBlocked( AIMoveResult_t moveResult )
{
return (moveResult < AIMR_OK );
}
//-------------------------------------
enum StepGroundTest_t
{
STEP_DONT_CHECK_GROUND = 0,
STEP_ON_VALID_GROUND,
STEP_ON_INVALID_GROUND,
};
//-------------------------------------
struct AIMoveTrace_t
{
AIMoveTrace_t()
{
memset( this, 0, sizeof(*this) );
}
AIMoveResult_t fStatus; // See AIMoveResult_t
Vector vEndPosition; // The last point that could be moved to
Vector vHitNormal; // The normal of a hit, if any. vec3_origin if none. Can be none even if "hit"
CBaseEntity* pObstruction; // The obstruction I bumped into (if any)
float flTotalDist;
float flDistObstructed; // FIXME: This is a strange number. In the case
// of calling MoveLimit with navtype NAV_GROUND,
// it represents a 2D distance to the obstruction.
// In the case of other navtypes, it represents a
// 3D distance to the obstruction
Vector vJumpVelocity; // FIXME: Remove this; it's bogus
// It's only returned by JumpMoveLimit
// which seems to be a bogus concept to begin with
float flStepUpDistance;
};
inline bool IsMoveBlocked( const AIMoveTrace_t &moveTrace )
{
return (moveTrace.fStatus < AIMR_OK );
}
// Categorizes the blocker and sets the appropriate bits
AIMoveResult_t AIComputeBlockerMoveResult( CBaseEntity *pBlocker );
//-------------------------------------
// Purpose: Specifies an immediate, localized, straight line movement goal
//-------------------------------------
enum AILocalMoveGoalFlags_t
{
AILMG_NONE,
AILMG_TARGET_IS_GOAL = 0x01,
AILMG_CONSUME_INTERVAL = 0x02,
AILMG_TARGET_IS_TRANSITION = 0x04,
AILMG_NO_STEER = 0x08,
AILMG_NO_AVOIDANCE_PATHS = 0x10,
};
struct AILocalMoveGoal_t
{
AILocalMoveGoal_t()
{
memset( this, 0, sizeof(*this) );
}
// Object of the goal
Vector target;
// The actual move. Note these need not always agree with "target"
Vector dir;
Vector facing;
float speed;
// The distance maximum distance intended to travel in path length
float maxDist;
// The distance expected to move this think
float curExpectedDist;
Navigation_t navType;
CBaseEntity * pMoveTarget;
unsigned flags;
// The path from which this goal was derived
CAI_Path * pPath;
// The result if a forward probing trace has been done
bool bHasTraced;
AIMoveTrace_t directTrace;
AIMoveTrace_t thinkTrace;
#ifdef DEBUG
int solveCookie;
#endif
};
//-------------------------------------
enum AIMotorMoveResult_t
{
AIM_FAILED,
AIM_SUCCESS,
// Partial successes
AIM_PARTIAL_HIT_NPC,
AIM_PARTIAL_HIT_WORLD,
AIM_PARTIAL_HIT_TARGET,
AIM_NUM_RESULTS
};
//-----------------------------------------------------------------------------
// Purpose: The set of callbacks used by lower-level movement classes to
// notify and receive guidance from higher level-classes
//-----------------------------------------------------------------------------
abstract_class IAI_MovementSink
{
public:
//---------------------------------
//
// Queries
//
virtual float CalcYawSpeed( void ) = 0;
//---------------------------------
//
// Local navigation notifications, each allows services provider to overridde default result
//
virtual bool OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult ) = 0;
virtual bool OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult ) = 0;
virtual bool OnFailedSteer( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult ) = 0;
virtual bool OnFailedLocalNavigation( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult ) = 0;
virtual bool OnInsufficientStopDist( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult ) = 0;
virtual bool OnMoveBlocked( AIMoveResult_t *pResult ) = 0;
//---------------------------------
//
// Motor notifications, each allows services provider to overridde default result
//
virtual bool OnMoveStalled( const AILocalMoveGoal_t &move ) = 0;
virtual bool OnMoveExecuteFailed( const AILocalMoveGoal_t &move,
const AIMoveTrace_t &trace,
AIMotorMoveResult_t fMotorResult,
AIMoveResult_t *pResult ) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Default implementations of IAI_MovementSink
//-----------------------------------------------------------------------------
class CAI_DefMovementSink : public IAI_MovementSink
{
public:
//---------------------------------
//
// Queries
//
virtual float CalcYawSpeed( void ) { return -1.0; }
//---------------------------------
//
// Local navigation notifications, each allows services provider to overridde default result
//
virtual bool OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ) { return false; }
virtual bool OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ) { return false; }
virtual bool OnFailedSteer( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ) { return false; }
virtual bool OnFailedLocalNavigation( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ) { return false; }
virtual bool OnInsufficientStopDist( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ) { return false; }
virtual bool OnMoveBlocked( AIMoveResult_t *pResult ) { return false; }
//---------------------------------
//
// Motor notifications, each allows services provider to overridde default result
//
virtual bool OnMoveStalled( const AILocalMoveGoal_t &move ) { return false; }
virtual bool OnMoveExecuteFailed( const AILocalMoveGoal_t &move, const AIMoveTrace_t &trace, AIMotorMoveResult_t fMotorResult, AIMoveResult_t *pResult ) { return false; }
};
//-------------------------------------
class CAI_ProxyMovementSink : public CAI_DefMovementSink
{
public:
CAI_ProxyMovementSink()
: m_pProxied( NULL )
{
}
//---------------------------------
void Init( IAI_MovementSink *pMovementServices ) { m_pProxied = pMovementServices; }
//---------------------------------
//
// Queries
//
virtual float CalcYawSpeed( void );
//---------------------------------
//
// Local navigation notifications, each allows services provider to overridde default result
//
virtual bool OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult );
virtual bool OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult );
virtual bool OnFailedSteer( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult );
virtual bool OnFailedLocalNavigation( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult );
virtual bool OnInsufficientStopDist( AILocalMoveGoal_t *pMoveGoal,
float distClear,
AIMoveResult_t *pResult );
virtual bool OnMoveBlocked( AIMoveResult_t *pResult );
//---------------------------------
//
// Motor notifications, each allows services provider to overridde default result
//
virtual bool OnMoveStalled( const AILocalMoveGoal_t &move );
virtual bool OnMoveExecuteFailed( const AILocalMoveGoal_t &move, const AIMoveTrace_t &trace, AIMotorMoveResult_t fMotorResult, AIMoveResult_t *pResult );
IAI_MovementSink *m_pProxied;
};
// ----------------------------------------------------------------------------
inline float CAI_ProxyMovementSink::CalcYawSpeed( void )
{
float result;
if ( m_pProxied && ( result = m_pProxied->CalcYawSpeed() ) != -1.0 )
return result;
return CAI_DefMovementSink::CalcYawSpeed();
}
inline bool CAI_ProxyMovementSink::OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult )
{
if ( m_pProxied && m_pProxied->OnCalcBaseMove( pMoveGoal, distClear, pResult ) )
return true;
return CAI_DefMovementSink::OnCalcBaseMove( pMoveGoal, distClear, pResult );
}
inline bool CAI_ProxyMovementSink::OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult )
{
if ( m_pProxied && m_pProxied->OnObstructionPreSteer( pMoveGoal, distClear, pResult ) )
return true;
return CAI_DefMovementSink::OnObstructionPreSteer( pMoveGoal, distClear, pResult );
}
inline bool CAI_ProxyMovementSink::OnFailedSteer( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult )
{
if ( m_pProxied && m_pProxied->OnFailedSteer( pMoveGoal, distClear, pResult ) )
return true;
return CAI_DefMovementSink::OnFailedSteer( pMoveGoal, distClear, pResult );
}
inline bool CAI_ProxyMovementSink::OnFailedLocalNavigation( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult )
{
if ( m_pProxied && m_pProxied->OnFailedLocalNavigation( pMoveGoal, distClear, pResult ) )
return true;
return CAI_DefMovementSink::OnFailedLocalNavigation( pMoveGoal, distClear, pResult );
}
inline bool CAI_ProxyMovementSink::OnInsufficientStopDist( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult )
{
if ( m_pProxied && m_pProxied->OnInsufficientStopDist( pMoveGoal, distClear, pResult ) )
return true;
return CAI_DefMovementSink::OnInsufficientStopDist( pMoveGoal, distClear, pResult );
}
inline bool CAI_ProxyMovementSink::OnMoveStalled( const AILocalMoveGoal_t &move )
{
if ( m_pProxied && m_pProxied->OnMoveStalled( move ) )
return true;
return CAI_DefMovementSink::OnMoveStalled( move );
}
inline bool CAI_ProxyMovementSink::OnMoveExecuteFailed( const AILocalMoveGoal_t &move, const AIMoveTrace_t &trace, AIMotorMoveResult_t fMotorResult, AIMoveResult_t *pResult )
{
if ( m_pProxied && m_pProxied->OnMoveExecuteFailed( move, trace, fMotorResult, pResult ) )
return true;
return CAI_DefMovementSink::OnMoveExecuteFailed( move, trace, fMotorResult, pResult );
}
inline bool CAI_ProxyMovementSink::OnMoveBlocked( AIMoveResult_t *pResult )
{
if ( m_pProxied && m_pProxied->OnMoveBlocked( pResult ) )
return true;
return CAI_DefMovementSink::OnMoveBlocked( pResult );
}
//=============================================================================
#endif // AI_MOVETYPES_H