OpenMoHAA 0.82.0
Loading...
Searching...
No Matches
navigate.h
1/*
2===========================================================================
3Copyright (C) 2024 the OpenMoHAA team
4
5This file is part of OpenMoHAA source code.
6
7OpenMoHAA source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12OpenMoHAA source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OpenMoHAA source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20===========================================================================
21*/
22
23// navigate.h:
24// Potentially could be an C++ implementation of the A* search algorithm, but
25// is currently unfinished.
26//
27
28#pragma once
29
30#include "g_local.h"
31#include "class.h"
32#include "entity.h"
33#include "stack.h"
34#include "container.h"
35#include "doors.h"
36#include "sentient.h"
37#include "../qcommon/qfiles.h"
38
39extern Event EV_AI_SavePaths;
40extern Event EV_AI_SaveNodes;
41extern Event EV_AI_LoadNodes;
42extern Event EV_AI_ClearNodes;
43extern Event EV_AI_RecalcPaths;
44extern Event EV_AI_CalcPath;
45extern Event EV_AI_DisconnectPath;
46
47extern cvar_t *ai_showroutes;
48extern cvar_t *ai_showroutes_distance;
49extern cvar_t *ai_shownodenums;
50extern cvar_t *ai_shownode;
51extern cvar_t *ai_showallnode;
52extern cvar_t *ai_showpath;
53extern cvar_t *ai_fallheight;
54extern cvar_t *ai_debugpath;
55extern cvar_t *ai_pathchecktime;
56extern cvar_t *ai_pathcheckdist;
57
58extern int ai_maxnode;
59
60#define MAX_PATHCHECKSPERFRAME 4
61
62extern int path_checksthisframe;
63
64#define MAX_PATH_LENGTH 128 // should be more than plenty
65#define NUM_PATHSPERNODE 48
66
67class Path;
68class PathNode;
69class SimpleActor;
70
71#define NUM_WIDTH_VALUES 16
72#define WIDTH_STEP 8
73#define MAX_WIDTH (WIDTH_STEP * NUM_WIDTH_VALUES)
74#define MAX_HEIGHT 128
75
76#define CHECK_PATH(path, width, height) \
77 ((((width) >= MAX_WIDTH) || ((width) < 0)) ? false \
78 : ((int)(path)->maxheight[((width) / WIDTH_STEP) - 1] < (int)(height)))
79
81{
82public:
83 short int from;
84 short int to;
85};
86
87typedef struct {
88 byte numBlockers;
89 byte badPlaceTeam[2];
90 short int node;
91 short int fallheight;
92 float dist;
93 vec2_t dir;
94 vec3_t pos1;
95 vec3_t pos2;
96} pathway_t;
97
98class PathInfo
99{
100public:
101 bool bAccurate;
102 vec3_t point;
103 float dist;
104 vec2_t dir;
105
106public:
107 PathInfo();
108
109 void Archive(Archiver& arc);
110};
111
112inline PathInfo::PathInfo()
113 : bAccurate(false)
114 , point {0, 0, 0}
115 , dist(0)
116 , dir {0, 0}
117{}
118
119inline void PathInfo::Archive(Archiver& arc)
120{
121 arc.ArchiveBool(&bAccurate);
122 arc.ArchiveVec3(point);
123 arc.ArchiveFloat(&dist);
124 arc.ArchiveVec2(dir);
125}
126
127typedef enum {
128 NOT_IN_LIST,
129 IN_OPEN,
130 IN_CLOSED
131} pathlist_t;
132
133#define PATH_DONT_LINK 1
134#define AI_DUCK 2
135#define AI_COVER 4
136#define AI_CONCEALMENT 8
137#define AI_CORNER_LEFT 16
138#define AI_CORNER_RIGHT 32
139#define AI_SNIPER 64
140#define AI_CRATE 128
141// Added in 2.0
142#define AI_LOW_WALL_ARC 256
143
144#define AI_MOVE_MASK \
145 (AI_COVER | AI_CONCEALMENT | AI_CORNER_LEFT | AI_CORNER_RIGHT | AI_SNIPER | AI_CRATE | AI_LOW_WALL_ARC)
146#define AI_COVER_MASK (AI_COVER | AI_CONCEALMENT | AI_CORNER_LEFT | AI_CORNER_RIGHT | AI_CRATE | AI_LOW_WALL_ARC)
147#define AI_CONCEALMENT_MASK (AI_CORNER_LEFT | AI_CORNER_RIGHT | AI_CRATE | AI_LOW_WALL_ARC)
148
149void DrawNode(int iNodeCount);
150void DrawAllConnections(void);
151
152class PathNode : public SimpleEntity
153{
154public:
155 int findCount;
156 pathway_t *Child;
157 int numChildren;
158 int virtualNumChildren;
159 float f;
160 float h;
161 float g;
162 class PathNode *Parent;
163 bool inopen;
164 PathNode *PrevNode;
165 PathNode *NextNode;
166 short int pathway;
167 const vec_t *m_PathPos;
168 float dist;
169 vec2_t dir;
170 int nodeflags;
171 SafePtr<Entity> pLastClaimer;
172 int iAvailableTime;
173 int nodenum;
174 short int m_Depth;
175 float m_fLowWallArc;
176
177 friend class PathSearch;
178 friend void DrawAllConnections(void);
179
180private:
181 void ConnectTo(PathNode *node);
182 void SetNodeFlags(Event *ev);
183 void SetLowWallArc(Event *ev); // Added in 2.0
184 void Remove(Event *ev);
185
186public:
187 CLASS_PROTOTYPE(PathNode);
188
189 PathNode();
190 virtual ~PathNode();
191
192 void *operator new(size_t size);
193 void operator delete(void *ptr);
194
195 void Archive(Archiver& arc) override;
196 void ArchiveDynamic(Archiver& arc);
197 void ArchiveStatic(Archiver& arc);
198
199 bool CheckPathTo(PathNode *node);
200 void CheckPathToDefault(PathNode *node, pathway_t *pathway);
201 qboolean LadderTo(PathNode *node, pathway_t *pathway);
202
203 void DrawConnections(void);
204 void Claim(Entity *pClaimer);
205 void Relinquish(void);
206 Entity *GetClaimHolder(void) const;
207 bool IsClaimedByOther(Entity *pPossibleClaimer) const;
208 void MarkTemporarilyBad(void);
209 void ConnectChild(int i);
210 void DisconnectChild(int i);
211 const_str GetSpecialAttack(class Actor *pActor);
212 void IsTouching(Event *ev);
213 qboolean IsTouching(Entity *e1);
214 void setOriginEvent(Vector org) override;
215};
216
217typedef SafePtr<PathNode> PathNodePtr;
218
219#define PATHMAP_CELLSIZE 256
220#define PATHMAP_GRIDSIZE (MAX_MAP_BOUNDS * 2 / PATHMAP_CELLSIZE)
221
222#define PATHMAP_NODES 128 // 128 - sizeof( int ) / sizeof( short )
223
224#define MAX_PATHNODES 4096
225
226class MapCell : public Class
227{
228private:
229 int numnodes;
230 short *nodes;
231
232 friend class PathSearch;
233
234public:
235 MapCell();
236 ~MapCell();
237
238 void AddNode(PathNode *node);
239 int NumNodes(void);
240};
241
242class PathSearch : public Listener
243{
244 friend class PathNode;
245
246private:
247 static MapCell PathMap[PATHMAP_GRIDSIZE][PATHMAP_GRIDSIZE];
248 static PathNode *open;
249 static int findFrame;
250 static qboolean m_bNodesloaded;
251 static qboolean m_NodeCheckFailed;
252 static int m_LoadIndex;
253
254public:
255 static PathNode *pathnodes[MAX_PATHNODES];
256 static int nodecount;
257 static float total_dist;
258 static const char *last_error;
259
260private:
261 static void LoadAddToGrid(int x, int y);
262 static void LoadAddToGrid2(PathNode *node, int x, int y);
263 static void AddToGrid(PathNode *node, int x, int y);
264 static bool Connect(PathNode *node, int x, int y);
265 static int NodeCoordinate(float coord);
266 static int GridCoordinate(float coord);
267 static qboolean ArchiveSaveNodes(void);
268 static void ArchiveLoadNodes(void);
269 static void Init(void);
270
271public:
272 CLASS_PROTOTYPE(PathSearch);
273
274 PathSearch();
275 virtual ~PathSearch();
276
277 static void ArchiveStaticLoad(Archiver& arc);
278 static void ArchiveStaticSave(Archiver& arc);
279 static bool ArchiveDynamic(Archiver& arc);
280
281 static void AddNode(PathNode *node);
282 static void Connect(PathNode *node);
283 static void UpdateNode(PathNode *node);
284
285 static MapCell *GetNodesInCell(int x, int y);
286 static MapCell *GetNodesInCell(const vec3_t pos);
287
288 static class PathNode *DebugNearestStartNode(const vec3_t pos, Entity *ent = NULL);
289 static class PathNode *NearestStartNode(const vec3_t pos, SimpleActor *ent);
290 static class PathNode *NearestEndNode(const vec3_t pos);
291 static int DebugNearestNodeList(const vec3_t pos, PathNode **nodelist, int iMaxNodes);
292 static int DebugNearestNodeList2(const vec3_t pos, PathNode **nodelist, int iMaxNodes);
293
294 static void ShowNodes(void);
295 static void LoadNodes(void);
296 static void CreatePaths(void);
297 static void *AllocPathNode(void);
298 static void FreePathNode(void *);
299 static void ResetNodes(void);
300 static void ClearNodes(void); // Added in OPM
301
302 static void UpdatePathwaysForBadPlace(const Vector& origin, float radius, int dir, int team);
303 static PathInfo *GeneratePath(PathInfo *path);
304 static PathInfo *GeneratePathNear(PathInfo *path);
305 static PathInfo *GeneratePathAway(PathInfo *path);
306
307 static class PathNode *GetSpawnNode(ClassDef *cls);
308
309 static int FindPath(
310 const vec3_t start,
311 const vec3_t end,
312 Entity *ent,
313 float maxPath,
314 const vec3_t vLeashHome,
315 float fLeashDistSquared,
316 int fallheight
317 );
318 static int FindPathAway(
319 const vec3_t start,
320 const vec3_t avoid,
321 const vec3_t vPreferredDir,
322 Entity *ent,
323 float fMinSafeDist,
324 const vec3_t vLeashHome,
325 float fLeashDistSquared,
326 int fallheight
327 );
328 static int FindPathNear(
329 const vec3_t start,
330 const vec3_t end,
331 Entity *ent,
332 float maxPath,
333 float fRadiusSquared,
334 const vec3_t vLeashHome,
335 float fLeashDistSquared,
336 int fallheight
337 );
338
339 static class PathNode *
340 FindCornerNodeForWall(const vec3_t start, const vec3_t end, Entity *ent, float maxPath, const vec4_t plane);
341 static class PathNode *FindCornerNodeForExactPath(Entity *self, Sentient *enemy, float fMaxPath);
342 static int FindPotentialCover(Entity *pEnt, Vector& vPos, Entity *pEnemy, PathNode **ppFoundNodes, int iMaxFind);
343 static void PlayerCover(class Player *pPlayer);
344 static class PathNode *FindNearestCover(Entity *pEnt, Vector& vPos, Entity *pEnemy);
345 static class PathNode *FindNearestSniperNode(Entity *pEnt, Vector& vPos, Entity *pEnemy);
346
347private:
348 static int NearestNodeSetup(const vec3_t pos, MapCell *cell, int *nodes, vec3_t *deltas);
349};
350
351inline MapCell::~MapCell()
352{
353 numnodes = 0;
354 nodes = NULL;
355}
356
357extern PathSearch PathManager;
358
359//===============
360// Added in OPM
361//===============
362
363class NavMaster : public Listener
364{
365public:
366 CLASS_PROTOTYPE(NavMaster);
367
368 NavMaster();
369
370 void Init(void);
371
372 void CreatePaths(Event *ev);
373 void CreateNode(Event *ev);
374 void SetNodeFlags(Event *ev);
375 void SetNodeTargetName(Event *ev);
376 void SetNodeTarget(Event *ev);
377 void RemoveNode(Event *ev);
378 void Frame();
379
380private:
381 void CheckNodeSelected();
382 PathNode *DetermineCurrentNode() const;
383 bool FovCheck(const Vector& dir, const Vector& delta, float fov) const;
384
385private:
386 SafePtr<PathNode> selectedNode;
387};
388
389extern NavMaster navMaster;
390
391PathNode *AI_FindNode(const char *name);
392void AI_AddNode(PathNode *node);
393void AI_RemoveNode(PathNode *node);
394void AI_ResetNodes(void);
395
396class AttractiveNode : public SimpleArchivedEntity
397{
398public:
399 int m_iPriority;
400 bool m_bUse;
401 float m_fMaxStayTime;
402 float m_fMaxDistance;
403 float m_fMaxDistanceSquared;
404 float m_fRespawnTime;
405 const_str m_csTeam;
406 int m_iTeam;
407
408private:
409 // Container< SafePtr< Sentient > > m_pSentList;
410
411public:
412 CLASS_PROTOTYPE(AttractiveNode);
413
414 AttractiveNode();
415 ~AttractiveNode();
416
417 bool CheckTeam(Sentient *sent);
418 void setMaxDist(float dist);
419
420 void GetPriority(Event *ev);
421 void SetPriority(Event *ev);
422 void GetDistance(Event *ev);
423 void SetDistance(Event *ev);
424 void GetStayTime(Event *ev);
425 void SetStayTime(Event *ev);
426 void GetRespawnTime(Event *ev);
427 void SetRespawnTime(Event *ev);
428 void GetTeam(Event *ev);
429 void SetTeam(Event *ev);
430 void SetUse(Event *ev);
431
432 void Archive(Archiver& arc) override;
433};
434
435typedef SafePtr<AttractiveNode> AttractiveNodePtr;
436
437inline void AttractiveNode::Archive(Archiver& arc)
438{
439 arc.ArchiveInteger(&m_iPriority);
440 arc.ArchiveBool(&m_bUse);
441 arc.ArchiveFloat(&m_fMaxStayTime);
442 arc.ArchiveFloat(&m_fMaxDistanceSquared);
443}
444
445extern Container<AttractiveNode *> attractiveNodes;
Definition actor.h:585
Definition archive.h:86
Definition class.h:175
Definition container.h:85
Definition entity.h:203
Definition listener.h:246
Definition navigate.h:227
Definition navigate.h:364
Definition navigate.h:99
Definition navigate.h:153
Definition navigate.h:243
Definition player.h:127
Definition safeptr.h:160
Definition sentient.h:95
Definition simpleactor.h:80
Definition vector.h:61
Definition navigate.h:81
Definition navigate.h:87