1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
//========= 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
|