mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-05-11 04:56:41 +03:00
Hard reset
This commit is contained in:
commit
09bed43f97
1594 changed files with 892326 additions and 0 deletions
632
code/game/b_nav.cpp
Normal file
632
code/game/b_nav.cpp
Normal file
|
@ -0,0 +1,632 @@
|
|||
|
||||
//
|
||||
// b_nav.c
|
||||
//
|
||||
|
||||
//FIXME make botInfo, etc visible here too and get rid of all the mutliple dereferences like bot->bot->
|
||||
|
||||
#include "b_local.h"
|
||||
|
||||
|
||||
#define NAVF_EDGEZONE 0x00000001
|
||||
|
||||
#define INFINITE 1000000
|
||||
|
||||
#define BOTAI_PUSHED (1<<0)
|
||||
|
||||
cvar_t *nav_showsectors;
|
||||
|
||||
char *navFileData;
|
||||
|
||||
int surfaceCount;
|
||||
nsurface_t *surface;
|
||||
int neighborCount;
|
||||
nneighbor_t *neighbor;
|
||||
byte *route;
|
||||
|
||||
//#if 0
|
||||
|
||||
static int spawnpadModelIndex;
|
||||
|
||||
|
||||
int Nav_SurfaceUnderPlayer( gentity_t *player ) {
|
||||
vec3_t start;
|
||||
vec3_t end;
|
||||
vec3_t p;
|
||||
trace_t tr;
|
||||
float bestDist;
|
||||
int bestSurf;
|
||||
vec3_t v;
|
||||
int n;
|
||||
float dist;
|
||||
|
||||
VectorCopy( player->s.origin, start );
|
||||
VectorCopy( player->s.origin, end );
|
||||
end[2] -= 4096;
|
||||
|
||||
gi.trace ( &tr, start, player->mins, player->maxs, end, player->s.number, MASK_DEADSOLID, true );
|
||||
|
||||
// p[0] = ((int)tr.endpos[0] + 8) & (~16);
|
||||
// p[1] = ((int)tr.endpos[1] + 8) & (~16);
|
||||
p[0] = tr.endpos[0];
|
||||
p[1] = tr.endpos[1];
|
||||
p[2] = floor(tr.endpos[2]+player->mins[2]);
|
||||
|
||||
bestDist = INFINITE;
|
||||
bestSurf = -1;
|
||||
|
||||
for ( n = 0; n < surfaceCount; n++ ) {
|
||||
if ( Q_fabs( surface[n].origin[2] - p[2] ) > 24 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorSubtract( p, surface[n].origin, v );
|
||||
dist = VectorLength( v );
|
||||
if ( dist < bestDist ) {
|
||||
bestDist = dist;
|
||||
bestSurf = n;
|
||||
}
|
||||
|
||||
if ( surface[n].origin[2] != p[2] ) {
|
||||
continue;
|
||||
}
|
||||
if ( surface[n].absmin[0] > p[0] ) {
|
||||
continue;
|
||||
}
|
||||
if ( surface[n].absmax[0] < p[0] ) {
|
||||
continue;
|
||||
}
|
||||
if ( surface[n].absmin[1] > p[1] ) {
|
||||
continue;
|
||||
}
|
||||
if ( surface[n].absmax[1] < p[1] ) {
|
||||
continue;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// gi.Printf( "guess for %s at %s\n", ent->classname, vtos( p ) );
|
||||
return bestSurf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Nav_GroundSurfaceNumber
|
||||
|
||||
Returns the surface number for where an entity is currently located.
|
||||
If the entity is not on the ground, it returns -1.
|
||||
|
||||
FIXME we can make this more efficient
|
||||
right now surfaces are in Z sorted order
|
||||
we could make a Z index and binary search it to get to right z group fast
|
||||
=============
|
||||
*/
|
||||
int Nav_GroundSurfaceNumber( gentity_t *ent ) {
|
||||
vec3_t p;
|
||||
vec3_t v;
|
||||
int n;
|
||||
float dist;
|
||||
float bestDist;
|
||||
int bestSurf;
|
||||
gentity_t *groundEntity;
|
||||
|
||||
// if ent is not on the ground it is not on a surface
|
||||
if ( ent->s.groundEntityNum == -1 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// p[0] = ((int)ent->s.origin[0] + 8) & (~16);
|
||||
// p[1] = ((int)ent->s.origin[1] + 8) & (~16);
|
||||
p[0] = ent->s.origin[0];
|
||||
p[1] = ent->s.origin[1];
|
||||
p[2] = floor(ent->s.origin[2]+ent->mins[2]);
|
||||
|
||||
// if ground is not the world we need to handle it differently.
|
||||
if ( ent->s.groundEntityNum != ENTITYNUM_WORLD ) {
|
||||
groundEntity = &g_entities[ent->s.groundEntityNum];
|
||||
|
||||
// check for sitting on a spawn pad
|
||||
if ( !groundEntity->bmodel && groundEntity->s.modelindex == spawnpadModelIndex ) {
|
||||
p[2] -= 8.0;
|
||||
}
|
||||
// check for plats
|
||||
/* else if ( groundEntity->bmodel && Q_stricmp( groundEntity->classname, "func_plat" ) == 0 ) {
|
||||
// if at the top the return PLATHIGH surface number, otherwise return PLATLOW surface number
|
||||
if ( VectorCompare( groundEntity->currentOrigin, groundEntity->pos2 ) ) {
|
||||
return surface[groundEntity->navSurfaceNum].parm;
|
||||
}
|
||||
return groundEntity->navSurfaceNum;
|
||||
} */
|
||||
}
|
||||
|
||||
bestDist = INFINITE;
|
||||
bestSurf = -1;
|
||||
|
||||
for ( n = 0; n < surfaceCount; n++ ) {
|
||||
if ( Q_fabs( surface[n].origin[2] - p[2] ) > 24 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorSubtract( p, surface[n].origin, v );
|
||||
dist = VectorLength( v );
|
||||
if ( dist < bestDist ) {
|
||||
bestDist = dist;
|
||||
bestSurf = n;
|
||||
}
|
||||
|
||||
if ( surface[n].origin[2] != p[2] ) {
|
||||
continue;
|
||||
}
|
||||
if ( surface[n].absmin[0] > p[0] ) {
|
||||
continue;
|
||||
}
|
||||
if ( surface[n].absmax[0] < p[0] ) {
|
||||
continue;
|
||||
}
|
||||
if ( surface[n].absmin[1] > p[1] ) {
|
||||
continue;
|
||||
}
|
||||
if ( surface[n].absmax[1] < p[1] ) {
|
||||
continue;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// gi.Printf( "guess for %s at %s\n", ent->classname, vtos( p ) );
|
||||
return bestSurf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Nav_ItemSurfaceNumber
|
||||
|
||||
Returns the surface number for where an item entity is currently located.
|
||||
If the entity is not on the ground, it returns -1. This is a specialized
|
||||
copy of Nav_GroundSurfaceNumber for items that caches the result.
|
||||
=============
|
||||
*/
|
||||
int Nav_ItemSurfaceNumber( gentity_t *ent ) {
|
||||
if ( !VectorCompare( ent->s.origin, ent->navOrigin ) && level.time > ent->navTime ) {
|
||||
VectorCopy( ent->s.origin, ent->navOrigin );
|
||||
ent->navTime = level.time;
|
||||
ent->navSurfaceNum = Nav_GroundSurfaceNumber( ent );
|
||||
}
|
||||
return ent->navSurfaceNum;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Nav_EntitySurfaceNumber
|
||||
=============
|
||||
*/
|
||||
int Nav_EntitySurfaceNumber( gentity_t *ent ) {
|
||||
if ( ent->s.eType == ET_ITEM ) {
|
||||
return Nav_ItemSurfaceNumber( ent );
|
||||
}
|
||||
|
||||
/*if ( ent->classname&& strcmp( ent->classname, "bot_goal" ) == 0 ) {
|
||||
return Nav_SurfaceUnderPlayer( ent );
|
||||
}*/
|
||||
|
||||
return Nav_GroundSurfaceNumber( ent );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
PathEdge
|
||||
=============
|
||||
*/
|
||||
|
||||
static nneighbor_t *PathEdge( int sourceSurfNum, int destSurfNum ) {
|
||||
int base;
|
||||
int n;
|
||||
|
||||
base = surface[sourceSurfNum].neighborIndex;
|
||||
for ( n = 0; n < surface[sourceSurfNum].neighborCount; n++ ) {
|
||||
if ( neighbor[base+n].surfaceNum == destSurfNum ) {
|
||||
return &neighbor[base+n];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
PointIsInEdgeRegion
|
||||
=============
|
||||
*/
|
||||
|
||||
static qboolean PointIsInEdgeRegion( vec3_t p, nneighbor_t *n ) {
|
||||
if ( p[0] < n->absmin[0] ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( p[0] > n->absmax[0] ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( p[1] < n->absmin[1] ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( p[1] > n->absmax[1] ) {
|
||||
return qfalse;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Nav_MoveToGoal
|
||||
=============
|
||||
*/
|
||||
|
||||
int Nav_MoveToGoal( gentity_t *bot, vec3_t dir, int *flags ) {
|
||||
int currentSurf;
|
||||
int nextSurf;
|
||||
int thirdSurf;
|
||||
int goalSurf;
|
||||
int routeIndex;
|
||||
nneighbor_t *edge;
|
||||
nneighbor_t *nextEdge;
|
||||
//gentity_t *ent;
|
||||
//float dist;
|
||||
|
||||
*flags = 0;
|
||||
VectorCopy( bot->navDir, dir );
|
||||
|
||||
currentSurf = bot->currentSurface;
|
||||
|
||||
// if bot is airborne, just keep heading the same
|
||||
if ( currentSurf == -1 ) {
|
||||
if ( bot->aiFlags & BOTAI_PUSHED ) {
|
||||
//gi.Printf( "bot was bounced\n" );
|
||||
*flags |= NAVF_HOLD;
|
||||
}
|
||||
//gi.Printf( "not on ground\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( bot->pushedTime < level.time ) {
|
||||
bot->aiFlags &= ~BOTAI_PUSHED;
|
||||
}
|
||||
|
||||
if ( !bot->goalEntity ) {
|
||||
// gi.Printf( ERROR "Nav_MoveToGoal called with no goalEntity set\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
goalSurf = Nav_EntitySurfaceNumber( bot->goalEntity );
|
||||
if ( goalSurf == -1 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if we've changed surfaces, the surface to surface navigation flags and timer need to be cleared
|
||||
if ( currentSurf != bot->lastSurface ) {
|
||||
bot->navFlags = 0;
|
||||
bot->navTime = 0;
|
||||
//gi.Printf( "surface changed from %i to %i\n", bot->bot->lastSurface, bot->bot->currentSurface );
|
||||
}
|
||||
|
||||
if ( currentSurf == goalSurf ) {
|
||||
//gi.Printf( "On target surface\n" );
|
||||
VectorSubtract( bot->goalEntity->s.origin, bot->s.origin, dir );
|
||||
//VectorCopy( dir, bot->bot->navDir );
|
||||
VectorCopy( dir, bot->navDir );
|
||||
return 0;
|
||||
}
|
||||
|
||||
routeIndex = route[currentSurf * surfaceCount + goalSurf];
|
||||
if ( routeIndex == 255 ) {
|
||||
//gi.Printf( "Nav_MoveToGoal - no known route from %i to %i\n", currentSurf, goalSurf );
|
||||
return -1;
|
||||
}
|
||||
if ( routeIndex >= surface[currentSurf].neighborCount ) {
|
||||
gi.Printf( ERROR "Nav_MoveToGoal - bad routeIndex\n" );
|
||||
return -1;
|
||||
}
|
||||
nextSurf = neighbor[surface[currentSurf].neighborIndex + routeIndex].surfaceNum;
|
||||
|
||||
edge = PathEdge( currentSurf, nextSurf );
|
||||
if ( !edge ) {
|
||||
gi.Printf( ERROR "Nav_MoveToGoal - %i does not have %i as a neighbor\n", currentSurf, nextSurf );
|
||||
VectorClear( dir );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ! ( bot->navFlags & NAVF_EDGEZONE ) ) {
|
||||
if ( PointIsInEdgeRegion( bot->s.origin, edge ) ) {
|
||||
//gi.Printf( "hit edge\n" );
|
||||
bot->navFlags |= NAVF_EDGEZONE;
|
||||
bot->navTime = level.time;
|
||||
}
|
||||
}
|
||||
|
||||
// if we are in the edge zone
|
||||
if ( bot->navFlags & NAVF_EDGEZONE ) {
|
||||
// if we're trying to get onto a plat, we must make sure it's there
|
||||
/*if ( surface[nextSurf].flags & SF_PLATLOW ) {
|
||||
ent = &g_entities[surface[surface[nextSurf].parm].parm]; //FIXME this works for now, but I don't like it
|
||||
if ( VectorCompare( ent->currentOrigin, ent->pos1 ) == 0 ) {
|
||||
*flags |= NAVF_HOLD;
|
||||
//gi.Printf(" wait for plat2\n" );
|
||||
}
|
||||
}*/
|
||||
|
||||
// if we're riding up on a plat, we don't need to move
|
||||
if ( surface[nextSurf].flags & SF_PLATHIGH ) {
|
||||
*flags |= NAVF_HOLD;
|
||||
//gi.Printf(" hold on plat\n" );
|
||||
}
|
||||
|
||||
// if the next surface contains the goalEntity, head towards it
|
||||
if ( nextSurf == goalSurf ) {
|
||||
//gi.Printf( "next surf has goal - targeting directly\n" );
|
||||
VectorSubtract( bot->goalEntity->s.origin, bot->s.origin, dir );
|
||||
//VectorCopy( dir, bot->bot->navDir );
|
||||
VectorCopy( dir, bot->navDir );
|
||||
}
|
||||
// start heading towards the next edge
|
||||
else {
|
||||
routeIndex = route[nextSurf * surfaceCount + goalSurf];
|
||||
if ( routeIndex == 255 ) {
|
||||
gi.Printf( ERROR "Nav_MoveToGoal - no known route from %i to %i\n", nextSurf, goalSurf );
|
||||
return -1;
|
||||
}
|
||||
if ( routeIndex >= surface[nextSurf].neighborCount ) {
|
||||
gi.Printf( ERROR "Nav_MoveToGoal - bad routeIndex\n" );
|
||||
return -1;
|
||||
}
|
||||
thirdSurf = neighbor[surface[nextSurf].neighborIndex + routeIndex].surfaceNum;
|
||||
nextEdge = PathEdge( nextSurf, thirdSurf );
|
||||
if ( !nextEdge ) {
|
||||
gi.Printf( ERROR "Nav_MoveToGoal - %i does not have %i as a neighbor\n", nextSurf, thirdSurf );
|
||||
VectorClear( dir );
|
||||
return -1;
|
||||
}
|
||||
//gi.Printf( "targeting next edge\n" );
|
||||
if ( surface[nextSurf].flags & SF_PLATHIGH ) {
|
||||
VectorSubtract( nextEdge->origin, surface[nextSurf].origin, dir );
|
||||
}
|
||||
else {
|
||||
VectorSubtract( nextEdge->origin, bot->s.origin, dir );
|
||||
}
|
||||
//VectorCopy( dir, bot->bot->navDir );
|
||||
VectorCopy( dir, bot->navDir );
|
||||
}
|
||||
|
||||
if ( edge->flags & NF_DUCK ) {
|
||||
*flags |= NAVF_DUCK;
|
||||
}
|
||||
if ( edge->flags & NF_JUMP ) {
|
||||
*flags |= NAVF_JUMP;
|
||||
}
|
||||
}
|
||||
else {
|
||||
VectorSubtract( edge->origin, bot->s.origin, dir );
|
||||
//VectorCopy( dir, bot->bot->navDir );
|
||||
VectorCopy( dir, bot->navDir );
|
||||
|
||||
/*if ( surface[nextSurf].flags & SF_PLATLOW ) {
|
||||
ent = &g_entities[surface[surface[nextSurf].parm].parm]; //FIXME this works for now, but I don't like it
|
||||
if ( VectorCompare( ent->currentOrigin, ent->pos1 ) == 0 ) {
|
||||
dist = VectorLength( dir );
|
||||
if ( dist > 64 ) {
|
||||
*flags |= NAVF_SLOW;
|
||||
//gi.Printf(" slow for plat\n" );
|
||||
}
|
||||
else {
|
||||
*flags |= NAVF_HOLD;
|
||||
//gi.Printf(" wait for plat\n" );
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Nav_ShowPath( gentity_t *bot ) {
|
||||
#if 0
|
||||
gentity_t *tent;
|
||||
int m, n;
|
||||
|
||||
if ( !bot->bot->goalEntity ) {
|
||||
return;
|
||||
}
|
||||
|
||||
tent = G_TempEntity( bot->s.origin, EV_DEBUG_LINE );
|
||||
VectorCopy( bot->bot->currentWaypoint->s.origin, tent->s.origin2 );
|
||||
|
||||
m = bot->bot->currentWaypoint->count;
|
||||
for (;;) {
|
||||
if ( m == bot->bot->finalWaypoint->count ) {
|
||||
break;
|
||||
}
|
||||
n = route[m*maxwaypoints+bot->bot->finalWaypoint->count];
|
||||
if ( n == -1 ) {
|
||||
break;
|
||||
}
|
||||
tent = G_TempEntity( rents[m]->s.origin, EV_DEBUG_LINE );
|
||||
VectorCopy( rents[n]->s.origin, tent->s.origin2 );
|
||||
m = n;
|
||||
}
|
||||
|
||||
if ( bot->bot->finalWaypoint != bot->bot->goalEntity ) {
|
||||
tent = G_TempEntity( bot->bot->finalWaypoint->s.origin, EV_DEBUG_LINE );
|
||||
VectorCopy( bot->bot->goalEntity->s.origin, tent->s.origin2 );
|
||||
}
|
||||
#endif
|
||||
/* gentity_t *tent;
|
||||
int m, n;
|
||||
gentity_t *player;
|
||||
int pSurf;
|
||||
|
||||
player = &g_entities[1];
|
||||
pSurf = Nav_GroundSurfaceNumber( player );
|
||||
|
||||
tent = G_TempEntity( player->s.origin, EV_DEBUG_LINE );
|
||||
VectorCopy( surface[pSurf].origin, tent->s.origin2 ); */
|
||||
}
|
||||
//#endif
|
||||
|
||||
|
||||
/*
|
||||
// Init and Shutdown
|
||||
//
|
||||
//
|
||||
*/
|
||||
|
||||
static void Nav_Cleanup( void ) {
|
||||
if ( navFileData ) {
|
||||
gi.FS_FreeFile ( navFileData );
|
||||
navFileData = NULL;
|
||||
}
|
||||
surfaceCount = 0;
|
||||
neighborCount = 0;
|
||||
}
|
||||
|
||||
void Nav_InitPreSpawn( void ) {
|
||||
nav_showsectors = gi.cvar( "nav_showsectors", "0", 0 );
|
||||
Nav_Cleanup();
|
||||
Nav_LoadRoutes();
|
||||
}
|
||||
|
||||
void Nav_InitPostSpawn( void ) {
|
||||
#if 0
|
||||
int n;
|
||||
nsurface_t *s;
|
||||
gentity_t *ent;
|
||||
|
||||
// FIXME resolve targetnames here (like button needed to open a door)
|
||||
|
||||
// get the modelindex for the spawnpad model so we can use it for surface determination
|
||||
spawnpadModelIndex = G_ModelIndex( "models/objects/dmspot.md3" );
|
||||
|
||||
// set the navSurface for plats
|
||||
for ( n = 0; n < surfaceCount; n++ ) {
|
||||
s = &surface[n];
|
||||
if ( s->flags & SF_PLATLOW ) {
|
||||
ent = &g_entities[surface[s->parm].parm]; //FIXME this works for now, but I don't like it
|
||||
ent->navSurfaceNum = n;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Nav_Shutdown ( void ) {
|
||||
Nav_Cleanup();
|
||||
}
|
||||
|
||||
void Nav_Test_f( void ) {
|
||||
#if 0
|
||||
gentity_t *player;
|
||||
gentity_t *goal;
|
||||
char *goalname;
|
||||
int pSurf;
|
||||
int gSurf;
|
||||
int cSurf;
|
||||
int n;
|
||||
gentity_t *tent;
|
||||
|
||||
player = &g_entities[0];
|
||||
pSurf = Nav_GroundSurfaceNumber( player );
|
||||
|
||||
goalname = gi.argv(2);
|
||||
if ( !goalname[0] ) {
|
||||
gi.Printf( "Player1 is at (%f, %f, %f) on surface %i\n", player->s.origin[0], player->s.origin[1], player->s.origin[2] + player->mins[2], pSurf );
|
||||
return;
|
||||
}
|
||||
|
||||
goal = NULL;
|
||||
goal = G_Find( goal, FOFS( classname ), goalname );
|
||||
if ( !goal ) {
|
||||
gi.Printf( "no %s on level\n", goalname );
|
||||
return;
|
||||
}
|
||||
gSurf = Nav_EntitySurfaceNumber( goal );
|
||||
|
||||
|
||||
cSurf = pSurf;
|
||||
while ( cSurf != gSurf ) {
|
||||
n = route[cSurf * surfaceCount + gSurf];
|
||||
if ( n == 255 ) {
|
||||
//gi.Printf( "no known route from %i to %i\n", cSurf, gSurf );
|
||||
return;
|
||||
}
|
||||
if ( n >= surface[cSurf].neighborCount ) {
|
||||
gi.Printf( ERROR "bad routeIndex\n" );
|
||||
return;
|
||||
}
|
||||
n = neighbor[surface[cSurf].neighborIndex + n].surfaceNum;
|
||||
|
||||
if ( cSurf == pSurf ) {
|
||||
tent = G_TempEntity( player->s.origin, EV_DEBUG_LINE );
|
||||
}
|
||||
else {
|
||||
tent = G_TempEntity( surface[cSurf].origin, EV_DEBUG_LINE );
|
||||
}
|
||||
if ( n == gSurf ) {
|
||||
VectorCopy( goal->s.origin, tent->s.origin2 );
|
||||
}
|
||||
else {
|
||||
VectorCopy( surface[n].origin, tent->s.origin2 );
|
||||
}
|
||||
|
||||
cSurf = n;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Nav_Gen_f( void );
|
||||
|
||||
void Cmd_Nav_f( void )
|
||||
{
|
||||
char *cmd;
|
||||
|
||||
cmd = gi.argv(1);
|
||||
|
||||
if ( Q_stricmp ( cmd, "gen" ) == 0 ) {
|
||||
Nav_Gen_f();
|
||||
Nav_InitPreSpawn();
|
||||
}
|
||||
else if ( Q_stricmp ( cmd, "test" ) == 0 ) {
|
||||
Nav_Test_f();
|
||||
}
|
||||
else {
|
||||
gi.Printf("Unknown nav command '%s'\n", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void Nav_ShowStuff
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
int i;
|
||||
nsurface_t *surf;
|
||||
|
||||
if ( !nav_showsectors->integer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G_Color4f( 1, 1, 0, 1 );
|
||||
for( i = 0; i < surfaceCount; i++ )
|
||||
{
|
||||
surf = &surface[ i ];
|
||||
|
||||
G_BeginLine();
|
||||
G_Vertex( Vector( surf->absmin[ 0 ], surf->absmin[ 1 ], surf->origin[ 2 ] ) );
|
||||
G_Vertex( Vector( surf->absmin[ 0 ], surf->absmax[ 1 ], surf->origin[ 2 ] ) );
|
||||
G_Vertex( Vector( surf->absmax[ 0 ], surf->absmax[ 1 ], surf->origin[ 2 ] ) );
|
||||
G_Vertex( Vector( surf->absmax[ 0 ], surf->absmin[ 1 ], surf->origin[ 2 ] ) );
|
||||
G_Vertex( Vector( surf->absmin[ 0 ], surf->absmin[ 1 ], surf->origin[ 2 ] ) );
|
||||
G_EndLine();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue