//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef AI_PATHFINDER_H #define AI_PATHFINDER_H #include "ai_component.h" #include "ai_navtype.h" #if defined(_WIN32) #pragma once #endif struct AIMoveTrace_t; struct OverlayLine_t; struct AI_Waypoint_t; class CAI_Link; class CAI_Network; class CAI_Node; //----------------------------------------------------------------------------- // The type of route to build enum RouteBuildFlags_e { bits_BUILD_GROUND = 0x00000001, // bits_BUILD_JUMP = 0x00000002, // bits_BUILD_FLY = 0x00000004, // bits_BUILD_CLIMB = 0x00000008, // bits_BUILD_GIVEWAY = 0x00000010, // bits_BUILD_TRIANG = 0x00000020, // bits_BUILD_IGNORE_NPCS = 0x00000040, // Ignore collisions with NPCs bits_BUILD_COLLIDE_NPCS = 0x00000080, // Use collisions with NPCs // (redundant for argument clarity) bits_BUILD_GET_CLOSE = 0x00000100, // the route will be built even if it // can't reach the destination }; //----------------------------------------------------------------------------- // CAI_Pathfinder // // Purpose: Executes pathfinds through an associated network. // //----------------------------------------------------------------------------- class CAI_Pathfinder : public CAI_Component { public: CAI_Pathfinder(CAI_BaseNPC *pOuter) : CAI_Component(pOuter), m_flLastStaleLinkCheckTime(0), m_pNetwork(NULL) {} void Init(CAI_Network *pNetwork); //--------------------------------- int NearestNodeToNPC(); int NearestNodeToPoint(const Vector &vecOrigin); AI_Waypoint_t *FindBestPath(int startID, int endID); AI_Waypoint_t *FindShortRandomPath(int startID, float minPathLength, const Vector &vDirection = vec3_origin); // -------------------------------- bool IsLinkUsable(CAI_Link *pLink, int startID); // -------------------------------- AI_Waypoint_t *BuildRoute(const Vector &vStart, const Vector &vEnd, CBaseEntity *pTarget, float goalTolerance, Navigation_t curNavType = NAV_NONE, bool bLocalSucceedOnWithinTolerance = false); void UnlockRouteNodes(AI_Waypoint_t *); // -------------------------------- void SetIgnoreBadLinks() { m_bIgnoreStaleLinks = true; } // lasts only for the next pathfind // -------------------------------- virtual AI_Waypoint_t *BuildNodeRoute(const Vector &vStart, const Vector &vEnd, int buildFlags, float goalTolerance); virtual AI_Waypoint_t *BuildLocalRoute(const Vector &vStart, const Vector &vEnd, CBaseEntity const *pTarget, int endFlags, int nodeID, int buildFlags, float goalTolerance); virtual AI_Waypoint_t *BuildRadialRoute( const Vector &vStartPos, const Vector &vCenterPos, const Vector &vGoalPos, float flRadius, float flArc, float flStepDist, bool bClockwise, float goalTolerance, bool bAirRoute); virtual AI_Waypoint_t *BuildTriangulationRoute( const Vector &vStart, const Vector &vEnd, CBaseEntity const *pTarget, int endFlags, int nodeID, float flYaw, float flDistToBlocker, Navigation_t navType); virtual AI_Waypoint_t *BuildOBBAvoidanceRoute( const Vector &vStart, const Vector &vEnd, const CBaseEntity *pObstruction, const CBaseEntity *pTarget, Navigation_t navType); // -------------------------------- bool Triangulate(Navigation_t navType, const Vector &vecStart, const Vector &vecEnd, float flDistToBlocker, CBaseEntity const *pTargetEnt, Vector *pApex); // -------------------------------- void DrawDebugGeometryOverlays(int m_debugOverlays); protected: virtual bool CanUseLocalNavigation() { return true; } private: friend class CPathfindNearestNodeFilter; //--------------------------------- AI_Waypoint_t *RouteToNode(const Vector &vecOrigin, int buildFlags, int nodeID, float goalTolerance); AI_Waypoint_t *RouteFromNode(const Vector &vecOrigin, int buildFlags, int nodeID, float goalTolerance); AI_Waypoint_t *BuildNearestNodeRoute(const Vector &vGoal, bool bToNode, int buildFlags, float goalTolerance, int *pNearestNode); //--------------------------------- AI_Waypoint_t *MakeRouteFromParents(int *parentArray, int endID); AI_Waypoint_t *CreateNodeWaypoint(Hull_t hullType, int nodeID, int nodeFlags = 0); AI_Waypoint_t *BuildRouteThroughPoints(Vector *vecPoints, int nNumPoints, int nDirection, int nStartIndex, int nEndIndex, Navigation_t navType, CBaseEntity *pTarget); bool IsLinkStillStale(int moveType, CAI_Link *nodeLink); // -------------------------------- // Builds a simple route (no triangulation, no making way) AI_Waypoint_t *BuildSimpleRoute(Navigation_t navType, const Vector &vStart, const Vector &vEnd, const CBaseEntity *pTarget, int endFlags, int nodeID, int nodeTargetType, float flYaw); // Builds a complex route (triangulation, making way) AI_Waypoint_t *BuildComplexRoute(Navigation_t navType, const Vector &vStart, const Vector &vEnd, const CBaseEntity *pTarget, int endFlags, int nodeID, int buildFlags, float flYaw, float goalTolerance, float maxLocalNavDistance); AI_Waypoint_t *BuildGroundRoute(const Vector &vStart, const Vector &vEnd, CBaseEntity const *pTarget, int endFlags, int nodeID, int buildFlags, float flYaw, float goalTolerance); AI_Waypoint_t *BuildFlyRoute(const Vector &vStart, const Vector &vEnd, CBaseEntity const *pTarget, int endFlags, int nodeID, int buildFlags, float flYaw, float goalTolerance); AI_Waypoint_t *BuildJumpRoute(const Vector &vStart, const Vector &vEnd, CBaseEntity const *pTarget, int endFlags, int nodeID, int buildFlags, float flYaw); AI_Waypoint_t *BuildClimbRoute(const Vector &vStart, const Vector &vEnd, CBaseEntity const *pTarget, int endFlags, int nodeID, int buildFlags, float flYaw); // Computes the link type Navigation_t ComputeWaypointType(CAI_Node **ppNodes, int parentID, int destID); // -------------------------------- bool TestTriangulationRoute(Navigation_t navType, const Vector &vecStart, const Vector &vecApex, const Vector &vecEnd, const CBaseEntity *pTargetEnt, AIMoveTrace_t *pStartTrace); // -------------------------------- bool CheckStaleRoute(const Vector &vStart, const Vector &vEnd, int moveTypes); bool CheckStaleNavTypeRoute(Navigation_t navType, const Vector &vStart, const Vector &vEnd); // -------------------------------- bool CanGiveWay(const Vector &vStart, const Vector &vEnd, CBaseEntity *pNPCBlocker); // -------------------------------- bool UseStrongOptimizations(); // -------------------------------- // Debugging fields and functions class CTriDebugOverlay { public: CTriDebugOverlay() : m_debugTriOverlayLine(NULL) {} void AddTriOverlayLines(const Vector &vecStart, const Vector &vecApex, const Vector &vecEnd, const AIMoveTrace_t &startTrace, const AIMoveTrace_t &endTrace, bool bPathClear); void ClearTriOverlayLines(void); void FadeTriOverlayLines(void); void Draw(int npcDebugOverlays); private: void AddTriOverlayLine(const Vector &origin, const Vector &dest, int r, int g, int b, bool noDepthTest); OverlayLine_t **m_debugTriOverlayLine; }; CTriDebugOverlay m_TriDebugOverlay; //--------------------------------- float m_flLastStaleLinkCheckTime; // Last time I check for a stale link bool m_bIgnoreStaleLinks; //--------------------------------- CAI_Network *GetNetwork() { return m_pNetwork; } const CAI_Network *GetNetwork() const { return m_pNetwork; } CAI_Network *m_pNetwork; public: DECLARE_SIMPLE_DATADESC(); }; //----------------------------------------------------------------------------- #endif // AI_PATHFINDER_H