sqwarmed/sdk_src/game/server/ai_waypoint.h

280 lines
6.8 KiB
C++

//========= 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