Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
main.qc File Reference
Include dependency graph for main.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

bool buildpath_nodefilter_directional (vector n, vector c, vector p)
bool buildpath_nodefilter_moveskip (entity this, vector n, vector c, vector p)
bool buildpath_nodefilter_none (vector n, vector c, vector p)
float Cosine_Interpolate (float a, float b, float c)
void dumpnode (entity n)
entity path_build (entity next, vector where, entity prev, entity start)
entity pathlib_astar (entity this, vector from, vector to)
void pathlib_cleanup ()
void pathlib_close_node (entity node, vector goal)
void pathlib_deletepath (entity start)
entity pathlib_getbestopen ()
bool pathlib_makenode_adaptive (entity parent, vector start, vector to, vector goal, float cost)
entity pathlib_mknode (vector where, entity parent)

Variables

const float PATHLIB_NODEEXPIRE = 20

Function Documentation

◆ buildpath_nodefilter_directional()

bool buildpath_nodefilter_directional ( vector n,
vector c,
vector p )

Definition at line 296 of file main.qc.

297{
298 vector d2 = normalize(p - c);
299 vector d1 = normalize(c - n);
300
301 if(vdist(d1 - d2, <, 0.25))
302 {
303 //mark_error(c,30);
304 return true;
305 }
306 //mark_info(c,30);
307 return false;
308}
vector normalize(vector v)
vector
Definition self.qh:92
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8

References normalize(), vdist, and vector.

Referenced by pathlib_astar().

◆ buildpath_nodefilter_moveskip()

bool buildpath_nodefilter_moveskip ( entity this,
vector n,
vector c,
vector p )

Definition at line 310 of file main.qc.

311{
312 pathlib_walknode(this, p, n, 1);
314 return true;
315
316 return false;
317}
vector pathlib_walknode(entity this, vector start, vector end, float doedge)
Definition movenode.qc:88
bool pathlib_movenode_goodnode
Definition pathlib.qh:75

References entity(), pathlib_movenode_goodnode, pathlib_walknode(), and vector.

◆ buildpath_nodefilter_none()

bool buildpath_nodefilter_none ( vector n,
vector c,
vector p )

Definition at line 319 of file main.qc.

320{
321 return false;
322}

References vector.

Referenced by pathlib_waypointpath_step().

◆ Cosine_Interpolate()

float Cosine_Interpolate ( float a,
float b,
float c )

Definition at line 288 of file main.qc.

289{
290 float ft = c * M_PI;
291 float f = (1 - cos(ft)) * 0.5;
292
293 return a*(1-f) + b*f;
294}
#define M_PI
Definition mathlib.qh:108
float cos(float f)

References cos(), and M_PI.

◆ dumpnode()

void dumpnode ( entity n)

Definition at line 24 of file main.qc.

25{
26 if(n.is_path_node)
28 n.is_path_node = false;
30 n.nextthink = time;
31}
float time
void SUB_Remove(entity this)
Remove entity.
Definition defer.qh:13
ERASEABLE void IL_REMOVE(IntrusiveList this, entity it)
Remove any element, anywhere in the list.
IntrusiveList g_pathlib_nodes
Definition pathlib.qh:109
#define setthink(e, f)

References entity(), g_pathlib_nodes, IL_REMOVE(), setthink, SUB_Remove(), and time.

◆ path_build()

entity path_build ( entity next,
vector where,
entity prev,
entity start )

Definition at line 324 of file main.qc.

325{
326 if(prev && next)
328 if(buildpath_nodefilter(next.origin,where,prev.origin))
329 return next;
330
331
332 entity path = spawn();
333 path.owner = start;
334 path.path_next = next;
335
336 setorigin(path, where);
337
338 if(!next)
339 path.classname = "path_end";
340 else
341 {
342 if(!prev)
343 path.classname = "path_start";
344 else
345 path.classname = "path_node";
346 }
347
348 return path;
349}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define spawn
prev
Definition all.qh:73
next
Definition all.qh:95
var bool buildpath_nodefilter(vector n, vector c, vector p)

References buildpath_nodefilter(), entity(), next, prev, spawn, and vector.

Referenced by pathlib_astar(), and pathlib_waypointpath_step().

◆ pathlib_astar()

entity pathlib_astar ( entity this,
vector from,
vector to )

Definition at line 351 of file main.qc.

352{
353 entity open;
354 float ptime = gettime(GETTIME_REALTIME);
355 pathlib_starttime = ptime;
356
358
359 // Select water<->land capable node make/link
361
362 // Select XYZ cost estimate
363 //pathlib_heuristic = pathlib_h_diagonal3;
365
366 // Select distance + waterfactor cost
368
369 // Select star expander
371
372 // Select walk simulation movement test
374
375 // Filter final nodes by direction
377
378 // Filter tiles with cross pattern
380
381 // If the start is in water we need diffrent settings
382 if(inwater(from))
383 {
384 // Select volumetric node expaner
386
387 // Water movement test
389 }
390
391 if (!openlist)
392 openlist = spawn();
393
394 if (!closedlist)
395 closedlist = spawn();
396
405
406 pathlib_gridsize = 128;
411
412 movenode_boxmax = this.maxs * 1.1;
413 movenode_boxmin = this.mins * 1.1;
414
416
419 tile_check_up = '0 0 128';
421 tile_check_down = '0 0 256';
422
423 //movenode_stepup = '0 0 128';
424 movenode_stepup = '0 0 36';
425 movenode_maxdrop = '0 0 512';
426 //movenode_maxdrop = '0 0 512';
427 movenode_boxup = '0 0 72';
428
429 from.x = fsnap(from.x, pathlib_gridsize);
430 from.y = fsnap(from.y, pathlib_gridsize);
431 //from.z += 32;
432
433 to.x = fsnap(to.x, pathlib_gridsize);
434 to.y = fsnap(to.y, pathlib_gridsize);
435 //to.z += 32;
436
437 LOG_DEBUG("AStar init");
438 entity path = pathlib_mknode(from, NULL);
439 pathlib_close_node(path, to);
441 {
442 LOG_DEBUG("AStar: Goal found on first node!");
443
444 open = new(path_end);
445 open.owner = open;
446 setorigin(open, path.origin);
447
449
450 return open;
451 }
452
453 if(pathlib_expandnode(path, from, to) <= 0)
454 {
455 LOG_TRACE("AStar path fail.");
457
458 return NULL;
459 }
460
464 if(inwater(n.origin))
465 pathlib_expandnode_box(n, from, to);
466 else
467 pathlib_expandnode_star(n, from, to);
468
469 while(pathlib_open_cnt)
470 {
472 {
473 LOG_TRACE("Path took too long to compute!");
474 LOG_TRACE("Nodes - created: ", ftos(pathlib_made_cnt));
475 LOG_TRACE("Nodes - open: ", ftos(pathlib_open_cnt));
476 LOG_TRACE("Nodes - merged: ", ftos(pathlib_merge_cnt));
477 LOG_TRACE("Nodes - closed: ", ftos(pathlib_closed_cnt));
478
480 return NULL;
481 }
482
484 n = best_open_node;
486
487 if(inwater(n.origin))
488 pathlib_expandnode_box(n,from,to);
489 else
490 pathlib_expandnode(n,from,to);
491
493 {
494 LOG_DEBUG("Target found. Rebuilding and filtering path...");
495 float ftime = gettime(GETTIME_REALTIME);
496 ptime = ftime - ptime;
497
498 entity start = path_build(NULL,path.origin,NULL,NULL);
499 entity end = path_build(NULL,goal_node.origin,NULL,start);
500 entity ln = end;
501
502 open = goal_node;
503 for(open = goal_node; open.path_prev != path; open = open.path_prev)
504 {
505 n = path_build(ln,open.origin,open.path_prev,start);
506 ln.path_prev = n;
507 ln = n;
508 }
509 start.path_next = n;
510 n.path_prev = start;
511 ftime = gettime(GETTIME_REALTIME) - ftime;
512
513 float ctime = gettime(GETTIME_REALTIME);
515 ctime = gettime(GETTIME_REALTIME) - ctime;
516
517
518#if DEBUGPATHING
519 pathlib_showpath2(start);
520
521 LOG_TRACE("Time used - pathfinding: ", ftos(ptime));
522 LOG_TRACE("Time used - rebuild & filter: ", ftos(ftime));
523 LOG_TRACE("Time used - cleanup: ", ftos(ctime));
524 LOG_TRACE("Time used - total: ", ftos(ptime + ftime + ctime));
525 LOG_TRACE("Time used - # frames: ", ftos(ceil((ptime + ftime + ctime) / sys_frametime)));
526 LOG_TRACE("Nodes - created: ", ftos(pathlib_made_cnt));
527 LOG_TRACE("Nodes - open: ", ftos(pathlib_open_cnt));
528 LOG_TRACE("Nodes - merged: ", ftos(pathlib_merge_cnt));
529 LOG_TRACE("Nodes - closed: ", ftos(pathlib_closed_cnt));
530 LOG_TRACE("Nodes - searched: ", ftos(pathlib_searched_cnt));
531 LOG_TRACE("Nodes bestopen searched: ", ftos(pathlib_bestopen_searched));
532 LOG_TRACE("Nodes bestcash - hits: ", ftos(pathlib_bestcash_hits));
533 LOG_TRACE("Nodes bestcash - save: ", ftos(pathlib_bestcash_saved));
534 LOG_TRACE("AStar done.");
535#endif
536 return start;
537 }
538 }
539
540 LOG_TRACE("A* Faild to find a path! Try a smaller gridsize.");
541
543
544 return NULL;
545}
float pathlib_g_euclidean_water(entity parent, vector to, float static_cost)
Definition costs.qc:21
float pathlib_h_diagonal(vector a, vector b)
This heuristic consider both straight and diagonal moves to have the same cost.
Definition costs.qc:49
vector mins
vector maxs
float pathlib_expandnode_star(entity node, vector start, vector goal)
Definition expandnode.qc:95
float pathlib_expandnode_box(entity node, vector start, vector goal)
#define LOG_TRACE(...)
Definition log.qh:76
#define LOG_DEBUG(...)
Definition log.qh:80
ERASEABLE float fsnap(float val, float fsize)
Definition math.qh:54
float ceil(float f)
float gettime(void)
float vlen(vector v)
string ftos(float f)
vector pathlib_swimnode(entity this, vector start, vector end, float doedge)
Definition movenode.qc:45
#define inwater(point)
Definition pathlib.qh:11
float pathlib_movecost_diag
Definition pathlib.qh:52
vector movenode_boxup
Definition pathlib.qh:72
entity openlist
Definition pathlib.qh:18
const float pathlib_maxtime
Definition pathlib.qh:57
var bool tile_check(entity this, vector where)
float pathlib_foundgoal
Definition pathlib.qh:54
vector movenode_maxdrop
Definition pathlib.qh:71
float pathlib_merge_cnt
Definition pathlib.qh:45
var vector pathlib_movenode(entity this, vector start, vector end, float doedge)
float pathlib_searched_cnt
Definition pathlib.qh:46
var float pathlib_cost(entity parent, vector to, float static_cost)
vector tile_check_up
Definition pathlib.qh:61
var float pathlib_heuristic(vector from, vector to)
float pathlib_starttime
Definition pathlib.qh:56
var bool pathlib_makenode(entity parent, vector start, vector to, vector goal, float cost)
bool tile_check_cross(entity this, vector where)
Definition utility.qc:43
entity goal_node
Definition pathlib.qh:21
float pathlib_open_cnt
Definition pathlib.qh:42
var float pathlib_expandnode(entity node, vector start, vector goal)
entity closedlist
Definition pathlib.qh:19
float pathlib_movecost_waterfactor
Definition pathlib.qh:53
vector movenode_stepup
Definition pathlib.qh:70
float pathlib_bestcash_saved
Definition pathlib.qh:49
float pathlib_movecost
Definition pathlib.qh:51
float pathlib_bestopen_searched
Definition pathlib.qh:47
float pathlib_bestcash_hits
Definition pathlib.qh:48
float pathlib_gridsize
Definition pathlib.qh:50
vector movenode_boxmin
Definition pathlib.qh:74
entity best_open_node
Definition pathlib.qh:59
float pathlib_made_cnt
Definition pathlib.qh:44
float tile_check_size
Definition pathlib.qh:63
vector tile_check_down
Definition pathlib.qh:62
vector movenode_boxmax
Definition pathlib.qh:73
float movenode_stepsize
Definition pathlib.qh:69
float pathlib_closed_cnt
Definition pathlib.qh:43
#define NULL
Definition post.qh:14
float sys_frametime
Definition common.qh:57
bool buildpath_nodefilter_directional(vector n, vector c, vector p)
Definition main.qc:296
void pathlib_close_node(entity node, vector goal)
Definition main.qc:238
entity pathlib_mknode(vector where, entity parent)
Definition main.qc:38
void pathlib_cleanup()
Definition main.qc:265
entity pathlib_getbestopen()
Definition main.qc:216
bool pathlib_makenode_adaptive(entity parent, vector start, vector to, vector goal, float cost)
Definition main.qc:70
entity path_build(entity next, vector where, entity prev, entity start)
Definition main.qc:324
#define GETTIME_REALTIME
Definition static.qh:3

References best_open_node, buildpath_nodefilter(), buildpath_nodefilter_directional(), ceil(), closedlist, entity(), fsnap(), ftos(), gettime(), GETTIME_REALTIME, goal_node, inwater, LOG_DEBUG, LOG_TRACE, maxs, mins, movenode_boxmax, movenode_boxmin, movenode_boxup, movenode_maxdrop, movenode_stepsize, movenode_stepup, NULL, openlist, path_build(), pathlib_bestcash_hits, pathlib_bestcash_saved, pathlib_bestopen_searched, pathlib_cleanup(), pathlib_close_node(), pathlib_closed_cnt, pathlib_cost(), pathlib_expandnode(), pathlib_expandnode_box(), pathlib_expandnode_star(), pathlib_foundgoal, pathlib_g_euclidean_water(), pathlib_getbestopen(), pathlib_gridsize, pathlib_h_diagonal(), pathlib_heuristic(), pathlib_made_cnt, pathlib_makenode(), pathlib_makenode_adaptive(), pathlib_maxtime, pathlib_merge_cnt, pathlib_mknode(), pathlib_movecost, pathlib_movecost_diag, pathlib_movecost_waterfactor, pathlib_movenode(), pathlib_open_cnt, pathlib_searched_cnt, pathlib_starttime, pathlib_swimnode(), pathlib_walknode(), spawn, sys_frametime, tile_check(), tile_check_cross(), tile_check_down, tile_check_size, tile_check_up, vector, and vlen().

Referenced by ewheel_findtarget(), ewheel_move_path(), walker_findtarget(), and walker_move_path().

◆ pathlib_cleanup()

void pathlib_cleanup ( )

Definition at line 265 of file main.qc.

266{
268
269 //return;
270
271 IL_EACH(g_pathlib_nodes, it.is_path_node,
272 {
273 dumpnode(it);
274 });
275
277
278 if(openlist)
279 delete(openlist);
280
281 if(closedlist)
282 delete(closedlist);
283
284 openlist = NULL;
286}
#define IL_EACH(this, cond, body)
#define IL_CLEAR(this)
Remove all elements.

References best_open_node, closedlist, g_pathlib_nodes, IL_CLEAR, IL_EACH, NULL, and openlist.

Referenced by pathlib_astar().

◆ pathlib_close_node()

void pathlib_close_node ( entity node,
vector goal )

Definition at line 238 of file main.qc.

239{
240 if(node.owner == closedlist)
241 {
242 LOG_TRACE("Pathlib: Tried to close a closed node!");
243 return;
244 }
245
246 if(node == best_open_node)
248
251
252 node.owner = closedlist;
253
254 if(vdist(node.origin - goal, <=, pathlib_gridsize))
255 {
256 pathlib_walknode(node, node.origin, goal, 1);
258 {
259 goal_node = node;
260 pathlib_foundgoal = true;
261 }
262 }
263}

References best_open_node, closedlist, entity(), goal_node, LOG_TRACE, NULL, pathlib_closed_cnt, pathlib_foundgoal, pathlib_gridsize, pathlib_movenode_goodnode, pathlib_open_cnt, pathlib_walknode(), vdist, and vector.

Referenced by pathlib_astar().

◆ pathlib_deletepath()

void pathlib_deletepath ( entity start)

Definition at line 10 of file main.qc.

11{
12 if(!start)
13 return;
14
16 {
18 it.nextthink = time;
19 });
20}
entity owner
Definition main.qh:87
#define FOREACH_ENTITY_ENT(fld, match, body)
Definition iter.qh:179

References entity(), FOREACH_ENTITY_ENT, owner, setthink, SUB_Remove(), and time.

Referenced by ewheel_move_path(), and walker_move_path().

◆ pathlib_getbestopen()

entity pathlib_getbestopen ( )

Definition at line 216 of file main.qc.

217{
219 {
222
223 return best_open_node;
224 }
225
226 entity bestnode = NULL;
228 {
230
231 if(!bestnode || it.pathlib_node_f < bestnode.pathlib_node_f)
232 bestnode = it;
233 });
234
235 return bestnode;
236}

References best_open_node, entity(), FOREACH_ENTITY_ENT, NULL, openlist, owner, pathlib_bestcash_hits, pathlib_bestcash_saved, pathlib_bestopen_searched, and pathlib_open_cnt.

Referenced by pathlib_astar().

◆ pathlib_makenode_adaptive()

bool pathlib_makenode_adaptive ( entity parent,
vector start,
vector to,
vector goal,
float cost )

Definition at line 70 of file main.qc.

71{
72 bool dodge = false;
73 float f, h, g;
74
76
77 if(inwater(parent.origin))
78 {
79 LOG_DEBUG("FromWater");
82 }
83 else
84 {
85 if(inwater(to))
86 {
87 LOG_DEBUG("ToWater");
90 }
91 else
92 {
93 LOG_DEBUG("LandToLoand");
94 //if(edge_check(parent.origin))
95 // return 0;
96
99 dodge = true;
100 }
101 }
102
103 entity node = pathlib_nodeatpoint(to);
104 if(node)
105 {
106 LOG_DEBUG("NodeAtPoint");
108
109 if(node.owner == openlist)
110 {
111 h = pathlib_heuristic(node.origin,goal);
112 float g = pathlib_cost(parent,node.origin,cost);
113 f = g + h;
114
115 if(node.pathlib_node_g > g)
116 {
117 node.pathlib_node_h = h;
118 node.pathlib_node_g = g;
119 node.pathlib_node_f = f;
120
121 node.path_prev = parent;
122 }
123
124 if (!best_open_node)
125 best_open_node = node;
126 else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
127 best_open_node = node;
128 }
129
130 return true;
131 }
132
133 vector where = pathlib_movenode(parent, parent.origin, to, 0);
134
136 {
137 //pathlib_showsquare(where, 0 ,30);
138 //pathlib_showsquare(parent.origin, 1 ,30);
139 LOG_DEBUG("pathlib_movenode_goodnode = 0");
140 return false;
141 }
142
143 //pathlib_showsquare(where, 1 ,30);
144
145 if(pathlib_nodeatpoint(where))
146 {
147 LOG_DEBUG("NAP WHERE :",vtos(where));
148 LOG_DEBUG("not NAP TO:",vtos(to));
149 LOG_DEBUG("NAP-NNAP:",ftos(vlen(to-where)));
150 return false;
151 }
152
153
154 if(dodge)
155 if (!tile_check(parent, where))
156 {
157 LOG_DEBUG("tile_check fail");
158#if DEBUGPATHING
159 pathlib_showsquare(where, 0 ,30);
160#endif
161 return false;
162 }
163
164
165 h = pathlib_heuristic(where,goal);
166 g = pathlib_cost(parent,where,cost);
167 f = g + h;
168
169 /*
170 node = findradius(where,pathlib_gridsize * 0.5);
171 while(node)
172 {
173 if(node.is_path_node == true)
174 {
175 ++pathlib_merge_cnt;
176 if(node.owner == openlist)
177 {
178 if(node.pathlib_node_g > g)
179 {
180 //pathlib_movenode(node, where,node.origin,0);
181 //if(pathlib_movenode_goodnode)
182 //{
183 //mark_error(node.origin + '0 0 128',30);
184 node.pathlib_node_h = h;
185 node.pathlib_node_g = g;
186 node.pathlib_node_f = f;
187 node.path_prev = parent;
188 //}
189 }
190
191 if (!best_open_node)
192 best_open_node = node;
193 else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
194 best_open_node = node;
195 }
196
197 return 1;
198 }
199 node = node.chain;
200 }
201 */
202
203 node = pathlib_mknode(where, parent);
204 node.pathlib_node_h = h;
205 node.pathlib_node_g = g;
206 node.pathlib_node_f = f;
207
208 if (!best_open_node)
209 best_open_node = node;
210 else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
211 best_open_node = node;
212
213 return true;
214}
entity parent
Definition animhost.qc:7
string vtos(vector v)
entity pathlib_nodeatpoint(vector where)
Definition utility.qc:26

References best_open_node, entity(), ftos(), inwater, LOG_DEBUG, openlist, parent, pathlib_cost(), pathlib_expandnode(), pathlib_expandnode_box(), pathlib_expandnode_star(), pathlib_heuristic(), pathlib_merge_cnt, pathlib_mknode(), pathlib_movenode(), pathlib_movenode_goodnode, pathlib_nodeatpoint(), pathlib_searched_cnt, pathlib_swimnode(), pathlib_walknode(), tile_check(), vector, vlen(), and vtos().

Referenced by pathlib_astar().

◆ pathlib_mknode()

entity pathlib_mknode ( vector where,
entity parent )

Definition at line 38 of file main.qc.

39{
40 entity node = pathlib_nodeatpoint(where);
41 if(node)
42 {
43 #ifdef TURRET_DEBUG
44 mark_error(where, 60);
45 #endif
46 return node;
47 }
48
49 node = spawn();
50
51 setthink(node, SUB_Remove);
52 node.nextthink = time + PATHLIB_NODEEXPIRE;
54 node.is_path_node = true;
55 node.owner = openlist;
56 node.path_prev = parent;
57
58 setsize(node, '0 0 0', '0 0 0');
59
60 setorigin(node, where);
61#if DEBUGPATHING
62 pathlib_showsquare(where, 1 ,15);
63#endif
66
67 return node;
68}
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
const float PATHLIB_NODEEXPIRE
Definition main.qc:22

References entity(), g_pathlib_nodes, IL_PUSH(), openlist, parent, pathlib_made_cnt, pathlib_nodeatpoint(), PATHLIB_NODEEXPIRE, pathlib_open_cnt, setthink, spawn, SUB_Remove(), time, and vector.

Referenced by pathlib_astar(), and pathlib_makenode_adaptive().

Variable Documentation

◆ PATHLIB_NODEEXPIRE

const float PATHLIB_NODEEXPIRE = 20

Definition at line 22 of file main.qc.

Referenced by pathlib_mknode().