be_aas_debug.c (23598B)
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 Foobar; 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 "../game/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 "../game/botlib.h" 40 #include "../game/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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 //=========================================================================== 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 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 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 }