sqwarmed/sdk_src/game/server/ai_planesolver.h

184 lines
5.9 KiB
C++

//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef AI_PLANE_SOLVER_H
#define AI_PLANE_SOLVER_H
#ifdef _WIN32
#pragma once
#endif
#include "utlvector.h"
#include "ai_movesolver.h"
#include "ehandle.h"
#include "mathlib/vector.h"
#include "simtimer.h"
#include "ai_navtype.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class Vector2D;
class CBaseEntity;
struct edict_t;
class CAI_BaseNPC;
class CAI_Motor;
class CAI_Navigator;
struct AILocalMoveGoal_t;
struct AIMoveTrace_t;
//-------------------------------------
enum AI_SuggestorResult_t
{
SR_NONE,
SR_OK,
SR_FAIL
};
DECLARE_POINTER_HANDLE( Obstacle_t );
#define OBSTACLE_INVALID ( (Obstacle_t)0 )
class CAI_PlaneSolver
{
public:
// constructor
CAI_PlaneSolver( CAI_BaseNPC *pNpc );
// Attempt to find a valid move direction for the specifed goal
bool Solve( const AILocalMoveGoal_t &goal, float distClear, Vector *pSolution );
float CalcProbeDist( float speed );
// Flush any cached results (e.g., hull changed, results not valid)
void Reset();
void AddObstacle( const Vector &pos, float radius, CBaseEntity *pEntity = NULL, AI_MoveSuggType_t type = AIMST_AVOID_OBJECT );
bool HaveObstacles() { return ( m_Obstacles.Count() != 0 ) || ( s_GlobalObstacles.Count() != 0 ); }
static Obstacle_t AddGlobalObstacle( const Vector &pos, float radius, CBaseEntity *pEntity = NULL, AI_MoveSuggType_t type = AIMST_AVOID_OBJECT );
static void RemoveGlobalObstacle( Obstacle_t hObstacle );
static void RemoveGlobalObstacles( void );
static bool IsSegmentBlockedByGlobalObstacles( const Vector &vecStart, const Vector &vecEnd );
private:
enum
{
DEGREES_POSITIVE_ARC = 270,
DEGREES_POSITIVE_ARC_CLOSE_OBSTRUCTION = 340,
NUM_PROBES = 5
};
struct CircleObstacles_t
{
CircleObstacles_t( const Vector &center, float radius, CBaseEntity *pEntity, AI_MoveSuggType_t type )
: center(center),
radius(radius),
hEntity(pEntity),
type(type)
{
}
Vector center;
float radius;
AI_MoveSuggType_t type;
EHANDLE hEntity;
};
// How far ahead does the ground solver look (seconds)
float GetLookaheadTime() { return 1.0; }
// --------------------------------
// For debugging purposes
void VisualizeRegulations();
void VisualizeSolution( const Vector &vecGoal, const Vector& vecActual );
// --------------------------------
bool MoveLimit( Navigation_t navType, const Vector &target, bool ignoreTransients, bool fCheckStep, AIMoveTrace_t *pMoveTrace );
bool MoveLimit( Navigation_t navType, const Vector &target, bool ignoreTransients, bool fCheckStep, int contents, AIMoveTrace_t *pMoveTrace );
//-----------------------------------------------------------------------------
// Adjust the solution for fliers
//-----------------------------------------------------------------------------
void AdjustSolutionForFliers( const AILocalMoveGoal_t &goal, float flSolutionYaw, Vector *pSolution );
// --------------------------------
// Convenience accessors
CAI_BaseNPC * GetNpc();
CAI_Motor * GetMotor();
const Vector & GetLocalOrigin();
// --------------------------------
void GenerateObstacleNpcs( const AILocalMoveGoal_t &goal, float probeDist );
AI_SuggestorResult_t GenerateObstacleSuggestions( const AILocalMoveGoal_t &goal, const AIMoveTrace_t &directTrace, float distClear, float probeDist, float degreesToProbe, int nProbes );
AI_SuggestorResult_t GenerateObstacleSuggestion( const AILocalMoveGoal_t &goal, float yawScanCenter, float probeDist, float spanPerProbe, int probeOffset );
void GenerateSuggestionFromTrace( const AILocalMoveGoal_t &goal,
const AIMoveTrace_t &moveTrace, float probeDist,
float arcCenter, float arcSpan, int probeOffset );
bool GenerateCircleObstacleSuggestions( const AILocalMoveGoal_t &moveGoal, float probeDist );
void CalcYawsFromOffset( float yawScanCenter, float spanPerProbe, int probeOffset,
float *pYawTest, float *pYawCenter );
float CalculateRegulationWeight( const AIMoveTrace_t &moveTrace, float pctBlockedt );
float AdjustRegulationWeight( CBaseEntity *pEntity, float weight );
unsigned ComputeTurnBiasFlags( const AILocalMoveGoal_t &goal, const AIMoveTrace_t &directTrace );
bool RunMoveSolver( const AILocalMoveGoal_t &goal, const AIMoveTrace_t &directTrace,
float degreesPositiveArc, bool fDeterOscillation,
Vector *pResult );
bool DetectUnsolvable( const AILocalMoveGoal_t &goal );
bool GenerateCircleObstacleSuggestion( const CircleObstacles_t &obstacle, const AILocalMoveGoal_t &moveGoal, float probeDist, const Vector& npcLoc, float radiusNpc );
// --------------------------------
CAI_BaseNPC * m_pNpc;
Vector m_PrevTarget;
bool m_fSolvedPrev;
float m_PrevSolution;
Vector m_PrevSolutionVector;
float m_ClosestHaveBeenToCurrent;
float m_TimeLastProgress;
bool m_fCannotSolveCurrent;
CSimTimer m_RefreshSamplesTimer;
// --------------------------------
CUtlVector<CircleObstacles_t> m_Obstacles;
static CUtlFixedLinkedList<CircleObstacles_t> s_GlobalObstacles;
// --------------------------------
CAI_MoveSolver m_Solver;
};
//-------------------------------------
inline void CAI_PlaneSolver::Reset()
{
m_RefreshSamplesTimer.Force();
m_fSolvedPrev = false;
m_PrevTarget.Init( FLT_MAX, FLT_MAX, FLT_MAX ),
m_PrevSolution = 0;
m_ClosestHaveBeenToCurrent = FLT_MAX;
m_TimeLastProgress = FLT_MAX;
m_fCannotSolveCurrent = false;
}
//=============================================================================
#endif // AI_PLANE_SOLVER_H