1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4
5 This file is part of Quake III Arena source code.
6
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
21 */
22
23 /*****************************************************************************
24 * name: be_aas_debug.c
25 *
26 * desc: AAS debug code
27 *
28 * $Archive: /MissionPack/code/botlib/be_aas_debug.c $
29 *
30 *****************************************************************************/
31
32 #include "../qcommon/q_shared.h"
33 #include "l_memory.h"
34 #include "l_script.h"
35 #include "l_precomp.h"
36 #include "l_struct.h"
37 #include "l_libvar.h"
38 #include "aasfile.h"
39 #include "botlib.h"
40 #include "be_aas.h"
41 #include "be_interface.h"
42 #include "be_aas_funcs.h"
43 #include "be_aas_def.h"
44
45 #define MAX_DEBUGLINES 1024
46 #define MAX_DEBUGPOLYGONS 8192
47
48 int debuglines[MAX_DEBUGLINES];
49 int debuglinevisible[MAX_DEBUGLINES];
50 int numdebuglines;
51
52 static int debugpolygons[MAX_DEBUGPOLYGONS];
53
54 //===========================================================================
55 //
56 // Parameter: -
57 // Returns: -
58 // Changes Globals: -
59 //===========================================================================
AAS_ClearShownPolygons(void)60 void AAS_ClearShownPolygons(void)
61 {
62 int i;
63 //*
64 for (i = 0; i < MAX_DEBUGPOLYGONS; i++)
65 {
66 if (debugpolygons[i]) botimport.DebugPolygonDelete(debugpolygons[i]);
67 debugpolygons[i] = 0;
68 } //end for
69 //*/
70 /*
71 for (i = 0; i < MAX_DEBUGPOLYGONS; i++)
72 {
73 botimport.DebugPolygonDelete(i);
74 debugpolygons[i] = 0;
75 } //end for
76 */
77 } //end of the function AAS_ClearShownPolygons
78 //===========================================================================
79 //
80 // Parameter: -
81 // Returns: -
82 // Changes Globals: -
83 //===========================================================================
AAS_ShowPolygon(int color,int numpoints,vec3_t * points)84 void AAS_ShowPolygon(int color, int numpoints, vec3_t *points)
85 {
86 int i;
87
88 for (i = 0; i < MAX_DEBUGPOLYGONS; i++)
89 {
90 if (!debugpolygons[i])
91 {
92 debugpolygons[i] = botimport.DebugPolygonCreate(color, numpoints, points);
93 break;
94 } //end if
95 } //end for
96 } //end of the function AAS_ShowPolygon
97 //===========================================================================
98 //
99 // Parameter: -
100 // Returns: -
101 // Changes Globals: -
102 //===========================================================================
AAS_ClearShownDebugLines(void)103 void AAS_ClearShownDebugLines(void)
104 {
105 int i;
106
107 //make all lines invisible
108 for (i = 0; i < MAX_DEBUGLINES; i++)
109 {
110 if (debuglines[i])
111 {
112 //botimport.DebugLineShow(debuglines[i], NULL, NULL, LINECOLOR_NONE);
113 botimport.DebugLineDelete(debuglines[i]);
114 debuglines[i] = 0;
115 debuglinevisible[i] = qfalse;
116 } //end if
117 } //end for
118 } //end of the function AAS_ClearShownDebugLines
119 //===========================================================================
120 //
121 // Parameter: -
122 // Returns: -
123 // Changes Globals: -
124 //===========================================================================
AAS_DebugLine(vec3_t start,vec3_t end,int color)125 void AAS_DebugLine(vec3_t start, vec3_t end, int color)
126 {
127 int line;
128
129 for (line = 0; line < MAX_DEBUGLINES; line++)
130 {
131 if (!debuglines[line])
132 {
133 debuglines[line] = botimport.DebugLineCreate();
134 debuglinevisible[line] = qfalse;
135 numdebuglines++;
136 } //end if
137 if (!debuglinevisible[line])
138 {
139 botimport.DebugLineShow(debuglines[line], start, end, color);
140 debuglinevisible[line] = qtrue;
141 return;
142 } //end else
143 } //end for
144 } //end of the function AAS_DebugLine
145 //===========================================================================
146 //
147 // Parameter: -
148 // Returns: -
149 // Changes Globals: -
150 //===========================================================================
AAS_PermanentLine(vec3_t start,vec3_t end,int color)151 void AAS_PermanentLine(vec3_t start, vec3_t end, int color)
152 {
153 int line;
154
155 line = botimport.DebugLineCreate();
156 botimport.DebugLineShow(line, start, end, color);
157 } //end of the function AAS_PermenentLine
158 //===========================================================================
159 //
160 // Parameter: -
161 // Returns: -
162 // Changes Globals: -
163 //===========================================================================
AAS_DrawPermanentCross(vec3_t origin,float size,int color)164 void AAS_DrawPermanentCross(vec3_t origin, float size, int color)
165 {
166 int i, debugline;
167 vec3_t start, end;
168
169 for (i = 0; i < 3; i++)
170 {
171 VectorCopy(origin, start);
172 start[i] += size;
173 VectorCopy(origin, end);
174 end[i] -= size;
175 AAS_DebugLine(start, end, color);
176 debugline = botimport.DebugLineCreate();
177 botimport.DebugLineShow(debugline, start, end, color);
178 } //end for
179 } //end of the function AAS_DrawPermanentCross
180 //===========================================================================
181 //
182 // Parameter: -
183 // Returns: -
184 // Changes Globals: -
185 //===========================================================================
AAS_DrawPlaneCross(vec3_t point,vec3_t normal,float dist,int type,int color)186 void AAS_DrawPlaneCross(vec3_t point, vec3_t normal, float dist, int type, int color)
187 {
188 int n0, n1, n2, j, line, lines[2];
189 vec3_t start1, end1, start2, end2;
190
191 //make a cross in the hit plane at the hit point
192 VectorCopy(point, start1);
193 VectorCopy(point, end1);
194 VectorCopy(point, start2);
195 VectorCopy(point, end2);
196
197 n0 = type % 3;
198 n1 = (type + 1) % 3;
199 n2 = (type + 2) % 3;
200 start1[n1] -= 6;
201 start1[n2] -= 6;
202 end1[n1] += 6;
203 end1[n2] += 6;
204 start2[n1] += 6;
205 start2[n2] -= 6;
206 end2[n1] -= 6;
207 end2[n2] += 6;
208
209 start1[n0] = (dist - (start1[n1] * normal[n1] +
210 start1[n2] * normal[n2])) / normal[n0];
211 end1[n0] = (dist - (end1[n1] * normal[n1] +
212 end1[n2] * normal[n2])) / normal[n0];
213 start2[n0] = (dist - (start2[n1] * normal[n1] +
214 start2[n2] * normal[n2])) / normal[n0];
215 end2[n0] = (dist - (end2[n1] * normal[n1] +
216 end2[n2] * normal[n2])) / normal[n0];
217
218 for (j = 0, line = 0; j < 2 && line < MAX_DEBUGLINES; line++)
219 {
220 if (!debuglines[line])
221 {
222 debuglines[line] = botimport.DebugLineCreate();
223 lines[j++] = debuglines[line];
224 debuglinevisible[line] = qtrue;
225 numdebuglines++;
226 } //end if
227 else if (!debuglinevisible[line])
228 {
229 lines[j++] = debuglines[line];
230 debuglinevisible[line] = qtrue;
231 } //end else
232 } //end for
233 botimport.DebugLineShow(lines[0], start1, end1, color);
234 botimport.DebugLineShow(lines[1], start2, end2, color);
235 } //end of the function AAS_DrawPlaneCross
236 //===========================================================================
237 //
238 // Parameter: -
239 // Returns: -
240 // Changes Globals: -
241 //===========================================================================
AAS_ShowBoundingBox(vec3_t origin,vec3_t mins,vec3_t maxs)242 void AAS_ShowBoundingBox(vec3_t origin, vec3_t mins, vec3_t maxs)
243 {
244 vec3_t bboxcorners[8];
245 int lines[3];
246 int i, j, line;
247
248 //upper corners
249 bboxcorners[0][0] = origin[0] + maxs[0];
250 bboxcorners[0][1] = origin[1] + maxs[1];
251 bboxcorners[0][2] = origin[2] + maxs[2];
252 //
253 bboxcorners[1][0] = origin[0] + mins[0];
254 bboxcorners[1][1] = origin[1] + maxs[1];
255 bboxcorners[1][2] = origin[2] + maxs[2];
256 //
257 bboxcorners[2][0] = origin[0] + mins[0];
258 bboxcorners[2][1] = origin[1] + mins[1];
259 bboxcorners[2][2] = origin[2] + maxs[2];
260 //
261 bboxcorners[3][0] = origin[0] + maxs[0];
262 bboxcorners[3][1] = origin[1] + mins[1];
263 bboxcorners[3][2] = origin[2] + maxs[2];
264 //lower corners
265 Com_Memcpy(bboxcorners[4], bboxcorners[0], sizeof(vec3_t) * 4);
266 for (i = 0; i < 4; i++) bboxcorners[4 + i][2] = origin[2] + mins[2];
267 //draw bounding box
268 for (i = 0; i < 4; i++)
269 {
270 for (j = 0, line = 0; j < 3 && line < MAX_DEBUGLINES; line++)
271 {
272 if (!debuglines[line])
273 {
274 debuglines[line] = botimport.DebugLineCreate();
275 lines[j++] = debuglines[line];
276 debuglinevisible[line] = qtrue;
277 numdebuglines++;
278 } //end if
279 else if (!debuglinevisible[line])
280 {
281 lines[j++] = debuglines[line];
282 debuglinevisible[line] = qtrue;
283 } //end else
284 } //end for
285 //top plane
286 botimport.DebugLineShow(lines[0], bboxcorners[i],
287 bboxcorners[(i+1)&3], LINECOLOR_RED);
288 //bottom plane
289 botimport.DebugLineShow(lines[1], bboxcorners[4+i],
290 bboxcorners[4+((i+1)&3)], LINECOLOR_RED);
291 //vertical lines
292 botimport.DebugLineShow(lines[2], bboxcorners[i],
293 bboxcorners[4+i], LINECOLOR_RED);
294 } //end for
295 } //end of the function AAS_ShowBoundingBox
296 //===========================================================================
297 //
298 // Parameter: -
299 // Returns: -
300 // Changes Globals: -
301 //===========================================================================
AAS_ShowFace(int facenum)302 void AAS_ShowFace(int facenum)
303 {
304 int i, color, edgenum;
305 aas_edge_t *edge;
306 aas_face_t *face;
307 aas_plane_t *plane;
308 vec3_t start, end;
309
310 color = LINECOLOR_YELLOW;
311 //check if face number is in range
312 if (facenum >= aasworld.numfaces)
313 {
314 botimport.Print(PRT_ERROR, "facenum %d out of range\n", facenum);
315 } //end if
316 face = &aasworld.faces[facenum];
317 //walk through the edges of the face
318 for (i = 0; i < face->numedges; i++)
319 {
320 //edge number
321 edgenum = abs(aasworld.edgeindex[face->firstedge + i]);
322 //check if edge number is in range
323 if (edgenum >= aasworld.numedges)
324 {
325 botimport.Print(PRT_ERROR, "edgenum %d out of range\n", edgenum);
326 } //end if
327 edge = &aasworld.edges[edgenum];
328 if (color == LINECOLOR_RED) color = LINECOLOR_GREEN;
329 else if (color == LINECOLOR_GREEN) color = LINECOLOR_BLUE;
330 else if (color == LINECOLOR_BLUE) color = LINECOLOR_YELLOW;
331 else color = LINECOLOR_RED;
332 AAS_DebugLine(aasworld.vertexes[edge->v[0]],
333 aasworld.vertexes[edge->v[1]],
334 color);
335 } //end for
336 plane = &aasworld.planes[face->planenum];
337 edgenum = abs(aasworld.edgeindex[face->firstedge]);
338 edge = &aasworld.edges[edgenum];
339 VectorCopy(aasworld.vertexes[edge->v[0]], start);
340 VectorMA(start, 20, plane->normal, end);
341 AAS_DebugLine(start, end, LINECOLOR_RED);
342 } //end of the function AAS_ShowFace
343 //===========================================================================
344 //
345 // Parameter: -
346 // Returns: -
347 // Changes Globals: -
348 //===========================================================================
AAS_ShowFacePolygon(int facenum,int color,int flip)349 void AAS_ShowFacePolygon(int facenum, int color, int flip)
350 {
351 int i, edgenum, numpoints;
352 vec3_t points[128];
353 aas_edge_t *edge;
354 aas_face_t *face;
355
356 //check if face number is in range
357 if (facenum >= aasworld.numfaces)
358 {
359 botimport.Print(PRT_ERROR, "facenum %d out of range\n", facenum);
360 } //end if
361 face = &aasworld.faces[facenum];
362 //walk through the edges of the face
363 numpoints = 0;
364 if (flip)
365 {
366 for (i = face->numedges-1; i >= 0; i--)
367 {
368 //edge number
369 edgenum = aasworld.edgeindex[face->firstedge + i];
370 edge = &aasworld.edges[abs(edgenum)];
371 VectorCopy(aasworld.vertexes[edge->v[edgenum < 0]], points[numpoints]);
372 numpoints++;
373 } //end for
374 } //end if
375 else
376 {
377 for (i = 0; i < face->numedges; i++)
378 {
379 //edge number
380 edgenum = aasworld.edgeindex[face->firstedge + i];
381 edge = &aasworld.edges[abs(edgenum)];
382 VectorCopy(aasworld.vertexes[edge->v[edgenum < 0]], points[numpoints]);
383 numpoints++;
384 } //end for
385 } //end else
386 AAS_ShowPolygon(color, numpoints, points);
387 } //end of the function AAS_ShowFacePolygon
388 //===========================================================================
389 //
390 // Parameter: -
391 // Returns: -
392 // Changes Globals: -
393 //===========================================================================
AAS_ShowArea(int areanum,int groundfacesonly)394 void AAS_ShowArea(int areanum, int groundfacesonly)
395 {
396 int areaedges[MAX_DEBUGLINES];
397 int numareaedges, i, j, n, color = 0, line;
398 int facenum, edgenum;
399 aas_area_t *area;
400 aas_face_t *face;
401 aas_edge_t *edge;
402
403 //
404 numareaedges = 0;
405 //
406 if (areanum < 0 || areanum >= aasworld.numareas)
407 {
408 botimport.Print(PRT_ERROR, "area %d out of range [0, %d]\n",
409 areanum, aasworld.numareas);
410 return;
411 } //end if
412 //pointer to the convex area
413 area = &aasworld.areas[areanum];
414 //walk through the faces of the area
415 for (i = 0; i < area->numfaces; i++)
416 {
417 facenum = abs(aasworld.faceindex[area->firstface + i]);
418 //check if face number is in range
419 if (facenum >= aasworld.numfaces)
420 {
421 botimport.Print(PRT_ERROR, "facenum %d out of range\n", facenum);
422 } //end if
423 face = &aasworld.faces[facenum];
424 //ground faces only
425 if (groundfacesonly)
426 {
427 if (!(face->faceflags & (FACE_GROUND | FACE_LADDER))) continue;
428 } //end if
429 //walk through the edges of the face
430 for (j = 0; j < face->numedges; j++)
431 {
432 //edge number
433 edgenum = abs(aasworld.edgeindex[face->firstedge + j]);
434 //check if edge number is in range
435 if (edgenum >= aasworld.numedges)
436 {
437 botimport.Print(PRT_ERROR, "edgenum %d out of range\n", edgenum);
438 } //end if
439 //check if the edge is stored already
440 for (n = 0; n < numareaedges; n++)
441 {
442 if (areaedges[n] == edgenum) break;
443 } //end for
444 if (n == numareaedges && numareaedges < MAX_DEBUGLINES)
445 {
446 areaedges[numareaedges++] = edgenum;
447 } //end if
448 } //end for
449 //AAS_ShowFace(facenum);
450 } //end for
451 //draw all the edges
452 for (n = 0; n < numareaedges; n++)
453 {
454 for (line = 0; line < MAX_DEBUGLINES; line++)
455 {
456 if (!debuglines[line])
457 {
458 debuglines[line] = botimport.DebugLineCreate();
459 debuglinevisible[line] = qfalse;
460 numdebuglines++;
461 } //end if
462 if (!debuglinevisible[line])
463 {
464 break;
465 } //end else
466 } //end for
467 if (line >= MAX_DEBUGLINES) return;
468 edge = &aasworld.edges[areaedges[n]];
469 if (color == LINECOLOR_RED) color = LINECOLOR_BLUE;
470 else if (color == LINECOLOR_BLUE) color = LINECOLOR_GREEN;
471 else if (color == LINECOLOR_GREEN) color = LINECOLOR_YELLOW;
472 else color = LINECOLOR_RED;
473 botimport.DebugLineShow(debuglines[line],
474 aasworld.vertexes[edge->v[0]],
475 aasworld.vertexes[edge->v[1]],
476 color);
477 debuglinevisible[line] = qtrue;
478 } //end for*/
479 } //end of the function AAS_ShowArea
480 //===========================================================================
481 //
482 // Parameter: -
483 // Returns: -
484 // Changes Globals: -
485 //===========================================================================
AAS_ShowAreaPolygons(int areanum,int color,int groundfacesonly)486 void AAS_ShowAreaPolygons(int areanum, int color, int groundfacesonly)
487 {
488 int i, facenum;
489 aas_area_t *area;
490 aas_face_t *face;
491
492 //
493 if (areanum < 0 || areanum >= aasworld.numareas)
494 {
495 botimport.Print(PRT_ERROR, "area %d out of range [0, %d]\n",
496 areanum, aasworld.numareas);
497 return;
498 } //end if
499 //pointer to the convex area
500 area = &aasworld.areas[areanum];
501 //walk through the faces of the area
502 for (i = 0; i < area->numfaces; i++)
503 {
504 facenum = abs(aasworld.faceindex[area->firstface + i]);
505 //check if face number is in range
506 if (facenum >= aasworld.numfaces)
507 {
508 botimport.Print(PRT_ERROR, "facenum %d out of range\n", facenum);
509 } //end if
510 face = &aasworld.faces[facenum];
511 //ground faces only
512 if (groundfacesonly)
513 {
514 if (!(face->faceflags & (FACE_GROUND | FACE_LADDER))) continue;
515 } //end if
516 AAS_ShowFacePolygon(facenum, color, face->frontarea != areanum);
517 } //end for
518 } //end of the function AAS_ShowAreaPolygons
519 //===========================================================================
520 //
521 // Parameter: -
522 // Returns: -
523 // Changes Globals: -
524 //===========================================================================
AAS_DrawCross(vec3_t origin,float size,int color)525 void AAS_DrawCross(vec3_t origin, float size, int color)
526 {
527 int i;
528 vec3_t start, end;
529
530 for (i = 0; i < 3; i++)
531 {
532 VectorCopy(origin, start);
533 start[i] += size;
534 VectorCopy(origin, end);
535 end[i] -= size;
536 AAS_DebugLine(start, end, color);
537 } //end for
538 } //end of the function AAS_DrawCross
539 //===========================================================================
540 //
541 // Parameter: -
542 // Returns: -
543 // Changes Globals: -
544 //===========================================================================
AAS_PrintTravelType(int traveltype)545 void AAS_PrintTravelType(int traveltype)
546 {
547 #ifdef DEBUG
548 char *str;
549 //
550 switch(traveltype & TRAVELTYPE_MASK)
551 {
552 case TRAVEL_INVALID: str = "TRAVEL_INVALID"; break;
553 case TRAVEL_WALK: str = "TRAVEL_WALK"; break;
554 case TRAVEL_CROUCH: str = "TRAVEL_CROUCH"; break;
555 case TRAVEL_BARRIERJUMP: str = "TRAVEL_BARRIERJUMP"; break;
556 case TRAVEL_JUMP: str = "TRAVEL_JUMP"; break;
557 case TRAVEL_LADDER: str = "TRAVEL_LADDER"; break;
558 case TRAVEL_WALKOFFLEDGE: str = "TRAVEL_WALKOFFLEDGE"; break;
559 case TRAVEL_SWIM: str = "TRAVEL_SWIM"; break;
560 case TRAVEL_WATERJUMP: str = "TRAVEL_WATERJUMP"; break;
561 case TRAVEL_TELEPORT: str = "TRAVEL_TELEPORT"; break;
562 case TRAVEL_ELEVATOR: str = "TRAVEL_ELEVATOR"; break;
563 case TRAVEL_ROCKETJUMP: str = "TRAVEL_ROCKETJUMP"; break;
564 case TRAVEL_BFGJUMP: str = "TRAVEL_BFGJUMP"; break;
565 case TRAVEL_GRAPPLEHOOK: str = "TRAVEL_GRAPPLEHOOK"; break;
566 case TRAVEL_JUMPPAD: str = "TRAVEL_JUMPPAD"; break;
567 case TRAVEL_FUNCBOB: str = "TRAVEL_FUNCBOB"; break;
568 default: str = "UNKNOWN TRAVEL TYPE"; break;
569 } //end switch
570 botimport.Print(PRT_MESSAGE, "%s", str);
571 #endif
572 } //end of the function AAS_PrintTravelType
573 //===========================================================================
574 //
575 // Parameter: -
576 // Returns: -
577 // Changes Globals: -
578 //===========================================================================
AAS_DrawArrow(vec3_t start,vec3_t end,int linecolor,int arrowcolor)579 void AAS_DrawArrow(vec3_t start, vec3_t end, int linecolor, int arrowcolor)
580 {
581 vec3_t dir, cross, p1, p2, up = {0, 0, 1};
582 float dot;
583
584 VectorSubtract(end, start, dir);
585 VectorNormalize(dir);
586 dot = DotProduct(dir, up);
587 if (dot > 0.99 || dot < -0.99) VectorSet(cross, 1, 0, 0);
588 else CrossProduct(dir, up, cross);
589
590 VectorMA(end, -6, dir, p1);
591 VectorCopy(p1, p2);
592 VectorMA(p1, 6, cross, p1);
593 VectorMA(p2, -6, cross, p2);
594
595 AAS_DebugLine(start, end, linecolor);
596 AAS_DebugLine(p1, end, arrowcolor);
597 AAS_DebugLine(p2, end, arrowcolor);
598 } //end of the function AAS_DrawArrow
599 //===========================================================================
600 //
601 // Parameter: -
602 // Returns: -
603 // Changes Globals: -
604 //===========================================================================
AAS_ShowReachability(aas_reachability_t * reach)605 void AAS_ShowReachability(aas_reachability_t *reach)
606 {
607 vec3_t dir, cmdmove, velocity;
608 float speed, zvel;
609 aas_clientmove_t move;
610
611 AAS_ShowAreaPolygons(reach->areanum, 5, qtrue);
612 //AAS_ShowArea(reach->areanum, qtrue);
613 AAS_DrawArrow(reach->start, reach->end, LINECOLOR_BLUE, LINECOLOR_YELLOW);
614 //
615 if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMP ||
616 (reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_WALKOFFLEDGE)
617 {
618 AAS_HorizontalVelocityForJump(aassettings.phys_jumpvel, reach->start, reach->end, &speed);
619 //
620 VectorSubtract(reach->end, reach->start, dir);
621 dir[2] = 0;
622 VectorNormalize(dir);
623 //set the velocity
624 VectorScale(dir, speed, velocity);
625 //set the command movement
626 VectorClear(cmdmove);
627 cmdmove[2] = aassettings.phys_jumpvel;
628 //
629 AAS_PredictClientMovement(&move, -1, reach->start, PRESENCE_NORMAL, qtrue,
630 velocity, cmdmove, 3, 30, 0.1f,
631 SE_HITGROUND|SE_ENTERWATER|SE_ENTERSLIME|
632 SE_ENTERLAVA|SE_HITGROUNDDAMAGE, 0, qtrue);
633 //
634 if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMP)
635 {
636 AAS_JumpReachRunStart(reach, dir);
637 AAS_DrawCross(dir, 4, LINECOLOR_BLUE);
638 } //end if
639 } //end if
640 else if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_ROCKETJUMP)
641 {
642 zvel = AAS_RocketJumpZVelocity(reach->start);
643 AAS_HorizontalVelocityForJump(zvel, reach->start, reach->end, &speed);
644 //
645 VectorSubtract(reach->end, reach->start, dir);
646 dir[2] = 0;
647 VectorNormalize(dir);
648 //get command movement
649 VectorScale(dir, speed, cmdmove);
650 VectorSet(velocity, 0, 0, zvel);
651 //
652 AAS_PredictClientMovement(&move, -1, reach->start, PRESENCE_NORMAL, qtrue,
653 velocity, cmdmove, 30, 30, 0.1f,
654 SE_ENTERWATER|SE_ENTERSLIME|
655 SE_ENTERLAVA|SE_HITGROUNDDAMAGE|
656 SE_TOUCHJUMPPAD|SE_HITGROUNDAREA, reach->areanum, qtrue);
657 } //end else if
658 else if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMPPAD)
659 {
660 VectorSet(cmdmove, 0, 0, 0);
661 //
662 VectorSubtract(reach->end, reach->start, dir);
663 dir[2] = 0;
664 VectorNormalize(dir);
665 //set the velocity
666 //NOTE: the edgenum is the horizontal velocity
667 VectorScale(dir, reach->edgenum, velocity);
668 //NOTE: the facenum is the Z velocity
669 velocity[2] = reach->facenum;
670 //
671 AAS_PredictClientMovement(&move, -1, reach->start, PRESENCE_NORMAL, qtrue,
672 velocity, cmdmove, 30, 30, 0.1f,
673 SE_ENTERWATER|SE_ENTERSLIME|
674 SE_ENTERLAVA|SE_HITGROUNDDAMAGE|
675 SE_TOUCHJUMPPAD|SE_HITGROUNDAREA, reach->areanum, qtrue);
676 } //end else if
677 } //end of the function AAS_ShowReachability
678 //===========================================================================
679 //
680 // Parameter: -
681 // Returns: -
682 // Changes Globals: -
683 //===========================================================================
AAS_ShowReachableAreas(int areanum)684 void AAS_ShowReachableAreas(int areanum)
685 {
686 aas_areasettings_t *settings;
687 static aas_reachability_t reach;
688 static int index, lastareanum;
689 static float lasttime;
690
691 if (areanum != lastareanum)
692 {
693 index = 0;
694 lastareanum = areanum;
695 } //end if
696 settings = &aasworld.areasettings[areanum];
697 //
698 if (!settings->numreachableareas) return;
699 //
700 if (index >= settings->numreachableareas) index = 0;
701 //
702 if (AAS_Time() - lasttime > 1.5)
703 {
704 Com_Memcpy(&reach, &aasworld.reachability[settings->firstreachablearea + index], sizeof(aas_reachability_t));
705 index++;
706 lasttime = AAS_Time();
707 AAS_PrintTravelType(reach.traveltype & TRAVELTYPE_MASK);
708 botimport.Print(PRT_MESSAGE, "\n");
709 } //end if
710 AAS_ShowReachability(&reach);
711 } //end of the function ShowReachableAreas
712
AAS_FloodAreas_r(int areanum,int cluster,int * done)713 void AAS_FloodAreas_r(int areanum, int cluster, int *done)
714 {
715 int nextareanum, i, facenum;
716 aas_area_t *area;
717 aas_face_t *face;
718 aas_areasettings_t *settings;
719 aas_reachability_t *reach;
720
721 AAS_ShowAreaPolygons(areanum, 1, qtrue);
722 //pointer to the convex area
723 area = &aasworld.areas[areanum];
724 settings = &aasworld.areasettings[areanum];
725 //walk through the faces of the area
726 for (i = 0; i < area->numfaces; i++)
727 {
728 facenum = abs(aasworld.faceindex[area->firstface + i]);
729 face = &aasworld.faces[facenum];
730 if (face->frontarea == areanum)
731 nextareanum = face->backarea;
732 else
733 nextareanum = face->frontarea;
734 if (!nextareanum)
735 continue;
736 if (done[nextareanum])
737 continue;
738 done[nextareanum] = qtrue;
739 if (aasworld.areasettings[nextareanum].contents & AREACONTENTS_VIEWPORTAL)
740 continue;
741 if (AAS_AreaCluster(nextareanum) != cluster)
742 continue;
743 AAS_FloodAreas_r(nextareanum, cluster, done);
744 } //end for
745 //
746 for (i = 0; i < settings->numreachableareas; i++)
747 {
748 reach = &aasworld.reachability[settings->firstreachablearea + i];
749 nextareanum = reach->areanum;
750 if (!nextareanum)
751 continue;
752 if (done[nextareanum])
753 continue;
754 done[nextareanum] = qtrue;
755 if (aasworld.areasettings[nextareanum].contents & AREACONTENTS_VIEWPORTAL)
756 continue;
757 if (AAS_AreaCluster(nextareanum) != cluster)
758 continue;
759 /*
760 if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_WALKOFFLEDGE)
761 {
762 AAS_DebugLine(reach->start, reach->end, 1);
763 }
764 */
765 AAS_FloodAreas_r(nextareanum, cluster, done);
766 }
767 }
768
AAS_FloodAreas(vec3_t origin)769 void AAS_FloodAreas(vec3_t origin)
770 {
771 int areanum, cluster, *done;
772
773 done = (int *) GetClearedMemory(aasworld.numareas * sizeof(int));
774 areanum = AAS_PointAreaNum(origin);
775 cluster = AAS_AreaCluster(areanum);
776 AAS_FloodAreas_r(areanum, cluster, done);
777 }
778