aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/ai_waypoint.h
blob: cc899b5ed2132ea6546d92784ab9d22fade28520 (plain) (blame)
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