|
|
//========= Copyright � 1996-2005, 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
bits_WP_PRECISE_MOVEMENT = 0x40, // Precise movement is necessary near 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; void SetNavType( Navigation_t type ) { m_iWPType = type; }
// 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; } void SetPrev( AI_Waypoint_t *p ); 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; } }
inline void AI_Waypoint_t::SetPrev( AI_Waypoint_t *p ) { if ( pPrev ) { pPrev->pNext = NULL; }
pPrev = p;
if ( pPrev ) { if ( pPrev->pNext ) pPrev->pNext->pPrev = NULL;
pPrev->pNext = 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
|