You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
6.5 KiB
279 lines
6.5 KiB
//========= 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
|