Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

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 }