be_aas_debug.c 23 KB

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