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