This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

235 lines
6.5 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef AI_WAYPOINT_H
#define AI_WAYPOINT_H
#if defined(_WIN32)
#pragma once
#endif
#include <mempool.h>
// ----------------------------------------------------------------------------
// Forward declarations
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Flags used in the flags field in AI_Waypoint_T
// ----------------------------------------------------------------------------
enum WaypointFlags_t {
// The type of waypoint
bits_WP_TO_DETOUR = 0x01, // move to detour point.
bits_WP_TO_PATHCORNER = 0x02, // move to a path corner
bits_WP_TO_NODE = 0x04, // move to a node
bits_WP_TO_GOAL = 0x08, // move to an arbitrary point
bits_WP_TO_DOOR = 0x10, // move to position to open a door
// Other flags for waypoint
bits_WP_DONT_SIMPLIFY =
0x20, // Don't let the route code simplify this waypoint
};
// ----------------------------------------------------------------------------
// Purpose: Waypoints that make up an NPC's route.
// ----------------------------------------------------------------------------
struct AI_Waypoint_t {
public:
AI_Waypoint_t();
AI_Waypoint_t(const Vector &vecPosition, float flYaw, Navigation_t navType,
int fWaypointFlags, int nNodeID);
AI_Waypoint_t(const AI_Waypoint_t &from) {
memcpy(this, &from, sizeof(*this));
flPathDistGoal = -1;
pNext = pPrev = NULL;
}
AI_Waypoint_t &operator=(const AI_Waypoint_t &from) {
memcpy(this, &from, sizeof(*this));
flPathDistGoal = -1;
pNext = pPrev = NULL;
return *this;
}
~AI_Waypoint_t() {
AssertValid();
if (pNext) {
pNext->AssertValid();
pNext->pPrev = pPrev;
}
if (pPrev) {
pPrev->AssertValid();
pPrev->pNext = pNext;
}
}
//---------------------------------
void AssertValid() const {
#ifdef DEBUG
Assert(!pNext || pNext->pPrev == this);
Assert(!pPrev || pPrev->pNext == this);
#endif
}
//---------------------------------
int Flags() const;
Navigation_t NavType() const;
// Flag modification method
void ModifyFlags(int fFlags, bool bEnable);
bool IsReducible() {
return (pNext && m_iWPType == pNext->m_iWPType &&
!(m_fWaypointFlags & (bits_WP_TO_GOAL | bits_WP_TO_PATHCORNER |
bits_WP_DONT_SIMPLIFY)));
}
//---------------------------------
void SetNext(AI_Waypoint_t *p);
AI_Waypoint_t *GetNext() { return pNext; }
const AI_Waypoint_t *GetNext() const { return pNext; }
AI_Waypoint_t *GetPrev() { return pPrev; }
const AI_Waypoint_t *GetPrev() const { return pPrev; }
AI_Waypoint_t *GetLast();
//---------------------------------
const Vector &GetPos() const { return vecLocation; }
void SetPos(const Vector &newPos) { vecLocation = newPos; }
EHANDLE GetEHandleData() { return m_hData; }
//---------------------------------
//
// Basic info
//
Vector vecLocation;
float flYaw; // Waypoint facing dir
int iNodeID; // If waypoint is a node, which one
//---------------------------------
//
// Precalculated distances
//
float flPathDistGoal;
//---------------------------------
//
// If following a designer laid path, the path-corner entity (if any)
//
EHANDLE hPathCorner;
// Data specific to the waypoint type:
//
// PATHCORNER: The path corner entity.
// DOOR: If moving to position to open a door, the handle of the door to
// open.
EHANDLE m_hData;
private:
int m_fWaypointFlags; // See WaypointFlags_t
Navigation_t m_iWPType; // The type of waypoint
AI_Waypoint_t *pNext;
AI_Waypoint_t *pPrev;
DECLARE_FIXEDSIZE_ALLOCATOR(AI_Waypoint_t);
public:
DECLARE_SIMPLE_DATADESC();
};
// ----------------------------------------------------------------------------
// Inline methods associated with AI_Waypoint_t
// ----------------------------------------------------------------------------
inline int AI_Waypoint_t::Flags() const { return m_fWaypointFlags; }
inline Navigation_t AI_Waypoint_t::NavType() const { return m_iWPType; }
inline void AI_Waypoint_t::ModifyFlags(int fFlags, bool bEnable) {
if (bEnable)
m_fWaypointFlags |= fFlags;
else
m_fWaypointFlags &= ~fFlags;
}
inline void AI_Waypoint_t::SetNext(AI_Waypoint_t *p) {
if (pNext) {
pNext->pPrev = NULL;
}
pNext = p;
if (pNext) {
if (pNext->pPrev) pNext->pPrev->pNext = NULL;
pNext->pPrev = this;
}
}
// ----------------------------------------------------------------------------
// Purpose: Holds an maintains a chain of waypoints
class CAI_WaypointList {
public:
CAI_WaypointList() : m_pFirstWaypoint(NULL) {}
CAI_WaypointList(AI_Waypoint_t *pFirstWaypoint)
: m_pFirstWaypoint(pFirstWaypoint) {}
void Set(AI_Waypoint_t *route);
void PrependWaypoints(AI_Waypoint_t *pWaypoints);
void PrependWaypoint(const Vector &newPoint, Navigation_t navType,
unsigned waypointFlags, float flYaw = 0);
bool IsEmpty() const { return (m_pFirstWaypoint == NULL); }
AI_Waypoint_t *GetFirst() { return m_pFirstWaypoint; }
const AI_Waypoint_t *GetFirst() const { return m_pFirstWaypoint; }
AI_Waypoint_t *GetLast();
const AI_Waypoint_t *GetLast() const;
void RemoveAll();
private:
AI_Waypoint_t *m_pFirstWaypoint; // Linked list of waypoints
};
// ----------------------------------------------------------------------------
#ifdef DEBUG
void AssertRouteValid(AI_Waypoint_t *route);
#else
#define AssertRouteValid(route) ((void)0)
#endif
// ----------------------------------------------------------------------------
// Utilities
void DeleteAll(AI_Waypoint_t *pWaypointList);
// ------------------------------------
inline void DeleteAll(AI_Waypoint_t **ppWaypointList) {
DeleteAll(*ppWaypointList);
*ppWaypointList = NULL;
}
// ------------------------------------
void AddWaypointLists(AI_Waypoint_t *pLeft, AI_Waypoint_t *pRight);
// ----------------------------------------------------------------------------
#endif // AI_WAYPOINT_H