codemp/game/g_nav.c File Reference

#include "b_local.h"
#include "g_nav.h"

Go to the source code of this file.

Functions

qboolean G_EntIsUnlockedDoor (int entityNum)
qboolean G_EntIsDoor (int entityNum)
qboolean G_EntIsBreakable (int entityNum)
qboolean G_EntIsRemovableUsable (int entNum)
qboolean G_FindClosestPointOnLineSegment (const vec3_t start, const vec3_t end, const vec3_t from, vec3_t result)
void G_Line (vec3_t start, vec3_t end, vec3_t color, float alpha)
void G_Cube (vec3_t mins, vec3_t maxs, vec3_t color, float alpha)
void G_CubeOutline (vec3_t mins, vec3_t maxs, int time, unsigned int color, float alpha)
void G_DrawEdge (vec3_t start, vec3_t end, int type)
void G_DrawNode (vec3_t origin, int type)
void G_DrawCombatPoint (vec3_t origin, int type)
void TAG_ShowTags (int flags)
qboolean FlyingCreature (gentity_t *ent)
qboolean NAV_CheckAhead (gentity_t *self, vec3_t end, trace_t *trace, int clipmask)
void NAV_StoreWaypoint (gentity_t *ent)
void NPC_Blocked (gentity_t *self, gentity_t *blocker)
void NPC_SetMoveGoal (gentity_t *ent, vec3_t point, int radius, qboolean isNavGoal, int combatPoint, gentity_t *targetEnt)
qboolean NAV_HitNavGoal (vec3_t point, vec3_t mins, vec3_t maxs, vec3_t dest, int radius, qboolean flying)
qboolean NAV_ClearPathToPoint (gentity_t *self, vec3_t pmins, vec3_t pmaxs, vec3_t point, int clipmask, int okToHitEntNum)
int NAV_FindClosestWaypointForEnt (gentity_t *ent, int targWp)
int NAV_FindClosestWaypointForPoint (gentity_t *ent, vec3_t point)
int NAV_FindClosestWaypointForPoint2 (vec3_t point)
void NAV_ClearBlockedInfo (gentity_t *self)
void NAV_SetBlockedInfo (gentity_t *self, int entId)
int NAV_Steer (gentity_t *self, vec3_t dir, float distance)
qboolean NAV_Bypass (gentity_t *self, gentity_t *blocker, vec3_t blocked_dir, float blocked_dist, vec3_t movedir)
qboolean NAV_MoveBlocker (gentity_t *self, vec3_t shove_dir)
qboolean NAV_ResolveBlock (gentity_t *self, gentity_t *blocker, vec3_t blocked_dir)
qboolean NAV_TrueCollision (gentity_t *self, gentity_t *blocker, vec3_t movedir, vec3_t blocked_dir)
qboolean NAV_StackedCanyon (gentity_t *self, gentity_t *blocker, vec3_t pathDir)
qboolean NAV_ResolveEntityCollision (gentity_t *self, gentity_t *blocker, vec3_t movedir, vec3_t pathDir)
qboolean NAV_TestForBlocked (gentity_t *self, gentity_t *goal, gentity_t *blocker, float distance, int *flags)
qboolean NAV_AvoidCollision (gentity_t *self, gentity_t *goal, navInfo_t *info)
int NAV_TestBestNode (gentity_t *self, int startID, int endID, qboolean failEdge)
int NAV_GetNearestNode (gentity_t *self, int lastNode)
qboolean NAV_MicroError (vec3_t start, vec3_t end)
int NAV_MoveToGoal (gentity_t *self, navInfo_t *info)
unsigned int waypoint_testDirection (vec3_t origin, float yaw, unsigned int minDist)
unsigned int waypoint_getRadius (gentity_t *ent)
void SP_waypoint (gentity_t *ent)
void SP_waypoint_small (gentity_t *ent)
void SP_waypoint_navgoal (gentity_t *ent)
void SP_waypoint_navgoal_8 (gentity_t *ent)
void SP_waypoint_navgoal_4 (gentity_t *ent)
void SP_waypoint_navgoal_2 (gentity_t *ent)
void SP_waypoint_navgoal_1 (gentity_t *ent)
void Svcmd_Nav_f (void)
qboolean NAV_WaypointsTooFar (gentity_t *wp1, gentity_t *wp2)
void NAV_ClearStoredWaypoints (void)
int NAV_GetStoredWaypoint (char *targetname)
void NAV_CalculatePaths (const char *filename, int checksum)
void NAV_Shutdown (void)
void NAV_ShowDebugInfo (void)
void NAV_FindPlayerWaypoint (int clNum)

Variables

vec3_t NPCDEBUG_RED
qboolean navCalculatePaths = qfalse
qboolean NAVDEBUG_showNodes = qfalse
qboolean NAVDEBUG_showRadius = qfalse
qboolean NAVDEBUG_showEdges = qfalse
qboolean NAVDEBUG_showTestPath = qfalse
qboolean NAVDEBUG_showEnemyPath = qfalse
qboolean NAVDEBUG_showCombatPoints = qfalse
qboolean NAVDEBUG_showNavGoals = qfalse
qboolean NAVDEBUG_showCollision = qfalse
int NAVDEBUG_curGoal = 0
int fatalErrors = 0
char * fatalErrorPointer = NULL
char fatalErrorString [4096]


Function Documentation

qboolean FlyingCreature gentity_t ent  ) 
 

Definition at line 46 of file g_nav.c.

References gentity_s::client, gentity_t, playerState_s::gravity, gclient_s::ps, qboolean, qfalse, and qtrue.

Referenced by G_CheckMovingLoopingSounds(), and NPC_ClearPathToGoal().

00047 {
00048         if (ent->client && ent->client->ps.gravity <= 0)
00049         {
00050                 return qtrue;
00051         }
00052         return qfalse;
00053 }

void G_Cube vec3_t  mins,
vec3_t  maxs,
vec3_t  color,
float  alpha
 

Definition at line 16 of file g_nav.c.

References vec3_t.

Referenced by NAV_StackedCanyon(), NPC_BSJump(), and NPC_ShowDebugInfo().

00017 {
00018 
00019 }

void G_CubeOutline vec3_t  mins,
vec3_t  maxs,
int  time,
unsigned int  color,
float  alpha
 

Definition at line 21 of file g_nav.c.

References vec3_t.

Referenced by NAV_ClearPathToPoint().

00022 {
00023 
00024 }

void G_DrawCombatPoint vec3_t  origin,
int  type
 

Definition at line 36 of file g_nav.c.

References vec3_t.

Referenced by NAV_ShowDebugInfo().

00037 {
00038 
00039 }

void G_DrawEdge vec3_t  start,
vec3_t  end,
int  type
 

Definition at line 26 of file g_nav.c.

References vec3_t.

Referenced by NAV_AvoidCollision(), NAV_Bypass(), NAV_ClearPathToPoint(), NAV_Steer(), NAVNEW_AvoidCollision(), NAVNEW_Bypass(), and NAVNEW_MoveToGoal().

00027 {
00028 
00029 }

void G_DrawNode vec3_t  origin,
int  type
 

Definition at line 31 of file g_nav.c.

References vec3_t.

Referenced by NAV_MoveToGoal(), NAV_ShowDebugInfo(), and NAVNEW_MoveToGoal().

00032 {
00033 
00034 }

qboolean G_EntIsBreakable int  entityNum  ) 
 

Definition at line 2817 of file g_mover.c.

02818 {
02819         gentity_t *ent;
02820 
02821         if ( entityNum < 0 || entityNum >= ENTITYNUM_WORLD )
02822         {
02823                 return qfalse;
02824         }
02825 
02826         ent = &g_entities[entityNum];
02827         if ( (ent->r.svFlags & SVF_GLASS_BRUSH) )
02828         {
02829                 return qtrue;
02830         }
02831         /*
02832         if ( (ent->svFlags&SVF_BBRUSH) )
02833         {
02834                 return qtrue;
02835         }
02836         */
02837         if ( !Q_stricmp( "func_breakable", ent->classname ) )
02838         {
02839                 return qtrue;
02840         }
02841 
02842         if ( !Q_stricmp( "misc_model_breakable", ent->classname ) )
02843         {
02844                 return qtrue;
02845         }
02846         if ( !Q_stricmp( "misc_maglock", ent->classname ) )
02847         {
02848                 return qtrue;
02849         }
02850 
02851         return qfalse;
02852 }

qboolean G_EntIsDoor int  entityNum  ) 
 

Definition at line 1212 of file g_mover.c.

References gentity_s::classname, ENTITYNUM_WORLD, g_entities, gentity_t, Q_stricmp(), qboolean, qfalse, and qtrue.

Referenced by G_EntIsUnlockedDoor(), NAV_TestBestNode(), and vmMain().

01213 {
01214         gentity_t *ent;
01215 
01216         if ( entityNum < 0 || entityNum >= ENTITYNUM_WORLD )
01217         {
01218                 return qfalse;
01219         }
01220 
01221         ent = &g_entities[entityNum];
01222         if ( ent && !Q_stricmp( "func_door", ent->classname ) )
01223         {//blocked by a door
01224                 return qtrue;
01225         }
01226         return qfalse;
01227 }

qboolean G_EntIsRemovableUsable int  entNum  ) 
 

Definition at line 3023 of file g_mover.c.

References gentity_s::classname, EF_SHADER_ANIM, entityState_s::eFlags, g_entities, gentity_t, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::s, gentity_s::spawnflags, and gentity_s::targetname.

Referenced by NAV_TestBestNode(), and vmMain().

03024 {
03025         gentity_t *ent = &g_entities[entNum];
03026         if ( ent->classname && !Q_stricmp( "func_usable", ent->classname ) )
03027         {
03028                 if ( !(ent->s.eFlags&EF_SHADER_ANIM) && !(ent->spawnflags&8) && ent->targetname )
03029                 {//not just a shader-animator and not ALWAYS_ON, so it must be removable somehow
03030                         return qtrue;
03031                 }
03032         }
03033         return qfalse;
03034 }

qboolean G_EntIsUnlockedDoor int  entityNum  ) 
 

Definition at line 1272 of file g_mover.c.

References gentity_s::classname, ENTITYNUM_WORLD, FL_INACTIVE, FL_TEAMSLAVE, gentity_s::flags, FOFS, G_EntIsDoor(), g_entities, G_Find(), G_FindDoorTrigger(), gentity_t, gentity_s::health, MOVER_FORCE_ACTIVATE, MOVER_LOCKED, MOVER_PLAYER_USE, NULL, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::spawnflags, gentity_s::targetname, and gentity_s::teammaster.

Referenced by NAV_CheckAhead(), NAV_ResolveEntityCollision(), NAV_TestBestNode(), and vmMain().

01273 {
01274         if ( entityNum < 0 || entityNum >= ENTITYNUM_WORLD )
01275         {
01276                 return qfalse;
01277         }
01278 
01279         if ( G_EntIsDoor( entityNum ) )
01280         {
01281                 gentity_t *ent = &g_entities[entityNum];
01282                 gentity_t *owner = NULL;
01283                 if ( ent->flags & FL_TEAMSLAVE )
01284                 {//not the master door, get the master door
01285                         while ( ent->teammaster && (ent->flags&FL_TEAMSLAVE))
01286                         {
01287                                 ent = ent->teammaster;
01288                         }
01289                 }
01290                 if ( ent->targetname )
01291                 {//find out what is targetting it
01292                         owner = NULL;
01293                         //FIXME: if ent->targetname, check what kind of trigger/ent is targetting it?  If a normal trigger (active, etc), then it's okay?
01294                         while ( (owner = G_Find( owner, FOFS( target ), ent->targetname )) != NULL )
01295                         {
01296                                 if ( !Q_stricmp( "trigger_multiple", owner->classname ) )//FIXME: other triggers okay too?
01297                                 {
01298                                         if ( !(owner->flags & FL_INACTIVE) )
01299                                         {
01300                                                 return qtrue;
01301                                         }
01302                                 }
01303                         }
01304                         owner = NULL;
01305                         while ( (owner = G_Find( owner, FOFS( target2 ), ent->targetname )) != NULL )
01306                         {
01307                                 if ( !Q_stricmp( "trigger_multiple", owner->classname ) )//FIXME: other triggers okay too?
01308                                 {
01309                                         if ( !(owner->flags & FL_INACTIVE) )
01310                                         {
01311                                                 return qtrue;
01312                                         }
01313                                 }
01314                         }
01315                         return qfalse;
01316                 }
01317                 else
01318                 {//check the door's auto-created trigger instead
01319                         owner = G_FindDoorTrigger( ent );
01320                         if ( owner && (owner->flags&FL_INACTIVE) )
01321                         {//owning auto-created trigger is inactive
01322                                 return qfalse;
01323                         }
01324                 }
01325                 if ( !(ent->flags & FL_INACTIVE) && //assumes that the reactivate trigger isn't right next to the door!
01326                         !ent->health &&
01327                         !(ent->spawnflags & MOVER_PLAYER_USE) &&
01328                         !(ent->spawnflags & MOVER_FORCE_ACTIVATE) &&
01329                         !(ent->spawnflags & MOVER_LOCKED))
01330                         //FIXME: what about MOVER_GOODIE?
01331                 {
01332                         return qtrue;
01333                 }
01334         }
01335         return qfalse;
01336 }

qboolean G_FindClosestPointOnLineSegment const vec3_t  start,
const vec3_t  end,
const vec3_t  from,
vec3_t  result
 

Definition at line 1524 of file q_math.c.

01525 {
01526         vec3_t  vecStart2From, vecStart2End, vecEnd2Start, vecEnd2From;
01527         float   distEnd2From, distEnd2Result, theta, cos_theta, dot;
01528 
01529         //Find the perpendicular vector to vec from start to end
01530         VectorSubtract( from, start, vecStart2From);
01531         VectorSubtract( end, start, vecStart2End);
01532 
01533         dot = DotProductNormalize( vecStart2From, vecStart2End );
01534 
01535         if ( dot <= 0 )
01536         {
01537                 //The perpendicular would be beyond or through the start point
01538                 VectorCopy( start, result );
01539                 return qfalse;
01540         }
01541 
01542         if ( dot == 1 )
01543         {
01544                 //parallel, closer of 2 points will be the target
01545                 if( (VectorLengthSquared( vecStart2From )) < (VectorLengthSquared( vecStart2End )) )
01546                 {
01547                         VectorCopy( from, result );
01548                 }
01549                 else
01550                 {
01551                         VectorCopy( end, result );
01552                 }
01553                 return qfalse;
01554         }
01555 
01556         //Try other end
01557         VectorSubtract( from, end, vecEnd2From);
01558         VectorSubtract( start, end, vecEnd2Start);
01559 
01560         dot = DotProductNormalize( vecEnd2From, vecEnd2Start );
01561 
01562         if ( dot <= 0 )
01563         {//The perpendicular would be beyond or through the start point
01564                 VectorCopy( end, result );
01565                 return qfalse;
01566         }
01567 
01568         if ( dot == 1 )
01569         {//parallel, closer of 2 points will be the target
01570                 if( (VectorLengthSquared( vecEnd2From )) < (VectorLengthSquared( vecEnd2Start )))
01571                 {
01572                         VectorCopy( from, result );
01573                 }
01574                 else
01575                 {
01576                         VectorCopy( end, result );
01577                 }
01578                 return qfalse;
01579         }
01580 
01581         //                    /|
01582         //                c  / |
01583         //                  /  |a
01584         //      theta  /)__|    
01585         //                    b
01586         //cos(theta) = b / c
01587         //solve for b
01588         //b = cos(theta) * c
01589 
01590         //angle between vecs end2from and end2start, should be between 0 and 90
01591         theta = 90 * (1 - dot);//theta
01592         
01593         //Get length of side from End2Result using sine of theta
01594         distEnd2From = VectorLength( vecEnd2From );//c
01595         cos_theta = cos(DEG2RAD(theta));//cos(theta)
01596         distEnd2Result = cos_theta * distEnd2From;//b
01597 
01598         //Extrapolate to find result
01599         VectorNormalize( vecEnd2Start );
01600         VectorMA( end, distEnd2Result, vecEnd2Start, result );
01601         
01602         //perpendicular intersection is between the 2 endpoints
01603         return qtrue;
01604 }

void G_Line vec3_t  start,
vec3_t  end,
vec3_t  color,
float  alpha
 

Definition at line 11 of file g_nav.c.

References vec3_t.

00012 {
00013 
00014 }

qboolean NAV_AvoidCollision gentity_t self,
gentity_t goal,
navInfo_t info
 

Definition at line 902 of file g_nav.c.

References gNPC_t::aiFlags, navInfo_s::blocker, CONTENTS_BODY, entityShared_t::currentOrigin, navInfo_s::direction, navInfo_s::distance, EDGE_PATH, trace_t::entityNum, navInfo_s::flags, G_DrawEdge(), g_entities, gentity_t, MAX_COLL_AVOID_DIST, NAV_CheckAhead(), NAV_ClearBlockedInfo(), NAV_ResolveEntityCollision(), NAV_TestForBlocked(), NAVDEBUG_showCollision, navInfo_t, NIF_BLOCKED, NIF_COLLISION, gentity_s::NPC, NPC, NPCAI_NO_COLL_AVOID, navInfo_s::pathDirection, qboolean, qfalse, qtrue, gentity_s::r, navInfo_s::trace, vec3_t, VectorCopy, and VectorMA.

Referenced by NPC_GetMoveDirection().

00903 {
00904         vec3_t  movedir;
00905         vec3_t  movepos;
00906 
00907         //Clear our block info for this frame
00908         NAV_ClearBlockedInfo( NPC );
00909 
00910         //Cap our distance
00911         if ( info->distance > MAX_COLL_AVOID_DIST )
00912         {
00913                 info->distance = MAX_COLL_AVOID_DIST;
00914         }
00915 
00916         //Get an end position
00917         VectorMA( self->r.currentOrigin, info->distance, info->direction, movepos );
00918         VectorCopy( info->direction, movedir );
00919 
00920         if ( self && self->NPC && (self->NPC->aiFlags&NPCAI_NO_COLL_AVOID) )
00921         {//pretend there's no-one in the way
00922                 return qtrue;
00923         }
00924         //Now test against entities
00925         if ( NAV_CheckAhead( self, movepos, &info->trace, CONTENTS_BODY ) == qfalse )
00926         {
00927                 //Get the blocker
00928                 info->blocker = &g_entities[ info->trace.entityNum ];
00929                 info->flags |= NIF_COLLISION;
00930 
00931                 //Ok to hit our goal entity
00932                 if ( goal == info->blocker )
00933                         return qtrue;
00934 
00935                 //See if we're moving along with them
00936                 //if ( NAV_TrueCollision( self, info.blocker, movedir, info.direction ) == qfalse )
00937                 //      return qtrue;
00938 
00939                 //Test for blocking by standing on goal
00940                 if ( NAV_TestForBlocked( self, goal, info->blocker, info->distance, &info->flags ) == qtrue )
00941                         return qfalse;
00942 
00943                 //If the above function said we're blocked, don't do the extra checks
00944                 if ( info->flags & NIF_BLOCKED )
00945                         return qtrue;
00946 
00947                 //See if we can get that entity to move out of our way
00948                 if ( NAV_ResolveEntityCollision( self, info->blocker, movedir, info->pathDirection ) == qfalse )
00949                         return qfalse;
00950 
00951                 VectorCopy( movedir, info->direction );
00952                 
00953                 return qtrue;
00954         }
00955 
00956         //Our path is clear, just move there
00957         if ( NAVDEBUG_showCollision )
00958         {
00959                 G_DrawEdge( self->r.currentOrigin, movepos, EDGE_PATH );
00960         }
00961 
00962         return qtrue;
00963 }

qboolean NAV_Bypass gentity_t self,
gentity_t blocker,
vec3_t  blocked_dir,
float  blocked_dist,
vec3_t  movedir
 

Definition at line 589 of file g_nav.c.

References AngleNormalize360(), AngleVectors(), gentity_s::client, gentity_s::clipmask, CONTENTS_BODY, CONTENTS_BOTCLIP, entityShared_t::currentAngles, entityShared_t::currentOrigin, DotProduct, EDGE_NORMAL, G_DrawEdge(), gentity_t, entityShared_t::maxs, NAV_CheckAhead(), NAVDEBUG_showCollision, NULL, gclient_s::ps, qboolean, qfalse, qtrue, gentity_s::r, sqrt(), vec3_origin, vec3_t, VectorCopy, VectorMA, VectorNormalize2(), VectorScale, vectoyaw(), and playerState_s::velocity.

Referenced by NAV_ResolveEntityCollision().

00590 {
00591         float dot, yaw, avoidRadius, arcAngle;
00592         vec3_t  right;
00593 
00594         //Draw debug info if requested
00595         if ( NAVDEBUG_showCollision )
00596         {
00597                 G_DrawEdge( self->r.currentOrigin, blocker->r.currentOrigin, EDGE_NORMAL );
00598         }
00599 
00600         AngleVectors( self->r.currentAngles, NULL, right, NULL );
00601 
00602         //Get the blocked direction
00603         yaw = vectoyaw( blocked_dir );
00604 
00605         //Get the avoid radius
00606         avoidRadius = sqrt( ( blocker->r.maxs[0] * blocker->r.maxs[0] ) + ( blocker->r.maxs[1] * blocker->r.maxs[1] ) ) + 
00607                                                 sqrt( ( self->r.maxs[0] * self->r.maxs[0] ) + ( self->r.maxs[1] * self->r.maxs[1] ) );
00608 
00609         //See if we're inside our avoidance radius
00610         arcAngle = ( blocked_dist <= avoidRadius ) ? 135 : ( ( avoidRadius / blocked_dist ) * 90 );
00611 
00612         //FIXME: Although the below code will cause the NPC to take the "better" route, it can cause NPCs to become stuck on
00613         //               one another in certain situations where both decide to take the same direction.
00614 
00615         //Check to see what dir the other guy is moving in (if any) and pick the opposite dir
00616         if ( blocker->client && !VectorCompare( blocker->client->ps.velocity, vec3_origin ) )
00617         {
00618                 vec3_t blocker_movedir;
00619                 VectorNormalize2( blocker->client->ps.velocity, blocker_movedir );
00620                 dot = DotProduct( blocker_movedir, blocked_dir );
00621                 if ( dot < 0.35f && dot > -0.35f )
00622                 {//he's moving to the side of me
00623                         vec3_t  block_pos;
00624                         trace_t tr;
00625                         VectorScale( blocker_movedir, -1, blocker_movedir );
00626                         VectorMA( self->r.currentOrigin, blocked_dist, blocker_movedir, block_pos );
00627                         if ( NAV_CheckAhead( self, block_pos, &tr, ( self->clipmask & ~CONTENTS_BODY )|CONTENTS_BOTCLIP ) )
00628                         {
00629                                 VectorCopy( blocker_movedir, movedir );
00630                                 return qtrue;
00631                         }
00632                 }
00633         }
00634 
00635         //FIXME: this makes NPCs stack up and ping-pong like crazy.
00636         //                      Need to keep track of this and stop trying after a while
00637         dot = DotProduct( blocked_dir, right );
00638 
00639         //Go right on the first try if that works better
00640         if ( dot < 0.0f )
00641                 arcAngle *= -1;
00642 
00643         //Test full, best position first
00644         if ( NAV_TestBypass( self, AngleNormalize360( yaw + arcAngle ), blocked_dist, movedir ) )
00645                 return qtrue;
00646 
00647         //Try a smaller arc
00648         if ( NAV_TestBypass( self, AngleNormalize360( yaw + ( arcAngle * 0.5f ) ), blocked_dist, movedir ) )
00649                 return qtrue;
00650 
00651         //Try the other direction
00652         if ( NAV_TestBypass( self, AngleNormalize360( yaw + ( arcAngle * -1 ) ), blocked_dist, movedir ) )
00653                 return qtrue;
00654 
00655         //Try the other direction more precisely
00656         if ( NAV_TestBypass( self, AngleNormalize360( yaw + ( ( arcAngle * -1 ) * 0.5f ) ), blocked_dist, movedir ) )
00657                 return qtrue;
00658 
00659         //Unable to go around
00660         return qfalse;
00661 }

void NAV_CalculatePaths const char *  filename,
int  checksum
 

Definition at line 1734 of file g_nav.c.

References Com_Printf(), fatalErrorPointer, fatalErrors, fatalErrorString, memset(), NAV_GetStoredWaypoint(), qfalse, trap_Nav_CheckBlockedEdges(), trap_Nav_HardConnect(), and trap_Nav_SetPathsCalculated().

Referenced by NAV_CheckCalcPaths().

01735 {
01736         int target = -1;
01737         int i;
01738 
01739         if ( !tempWaypointList )
01740         {
01741                 return;
01742         }
01743 #ifndef FINAL_BUILD
01744         fatalErrors = 0;
01745         memset( fatalErrorString, 0, sizeof( fatalErrorString ) );
01746         fatalErrorPointer = &fatalErrorString[0];
01747 #endif
01748 #if _HARD_CONNECT
01749 
01750         //Find all connections and hard connect them
01751         for ( i = 0; i < numStoredWaypoints; i++ )
01752         {
01753                 //Find the first connection
01754                 target = NAV_GetStoredWaypoint( tempWaypointList[i].target );
01755 
01756                 if ( target != -1 )
01757                 {
01758 #ifndef FINAL_BUILD
01759 //                      if ( !NAV_WaypointsTooFar( ent, target ) )
01760 #endif
01761                         {
01762                                 trap_Nav_HardConnect( tempWaypointList[i].nodeID, tempWaypointList[target].nodeID );
01763                         }
01764                 }
01765 
01766                 //Find a possible second connection
01767                 target = NAV_GetStoredWaypoint( tempWaypointList[i].target2 );
01768 
01769                 if ( target != -1 )
01770                 {
01771 #ifndef FINAL_BUILD
01772 //                      if ( !NAV_WaypointsTooFar( ent, target ) )
01773 #endif
01774                         {
01775                                 trap_Nav_HardConnect( tempWaypointList[i].nodeID, tempWaypointList[target].nodeID );
01776                         }
01777                 }
01778 
01779                 //Find a possible third connection
01780                 target = NAV_GetStoredWaypoint( tempWaypointList[i].target3 );
01781 
01782                 if ( target != -1 )
01783                 {
01784 #ifndef FINAL_BUILD
01785 //                      if ( !NAV_WaypointsTooFar( ent, target ) )
01786 #endif
01787                         {
01788                                 trap_Nav_HardConnect( tempWaypointList[i].nodeID, tempWaypointList[target].nodeID );
01789                         }
01790                 }
01791 
01792                 //Find a possible fourth connection
01793                 target = NAV_GetStoredWaypoint( tempWaypointList[i].target4 );
01794 
01795                 if ( target != -1 )
01796                 {
01797 #ifndef FINAL_BUILD
01798 //                      if ( !NAV_WaypointsTooFar( ent, target ) )
01799 #endif
01800                         {
01801                                 trap_Nav_HardConnect( tempWaypointList[i].nodeID, tempWaypointList[target].nodeID );
01802                         }
01803                 }
01804         }
01805 
01806 #endif
01807 
01808         //Remove all waypoints now that they're done
01809         //gi.Free(tempWaypointList);
01810         /*
01811         trap_TrueFree((void **)&tempWaypointList);
01812         tempWaypointList=0;
01813         */
01814 
01815         //Now check all blocked edges, mark failed ones
01816         trap_Nav_CheckBlockedEdges();
01817 
01818         trap_Nav_SetPathsCalculated(qfalse);
01819         //navigator.pathsCalculated = qfalse;
01820 
01821         //Calculate the paths based on the supplied waypoints
01822         //trap_Nav_CalculatePaths();
01823 
01824         //Save the resulting information
01825         /*
01826         if ( trap_Nav_Save( filename, checksum ) == qfalse )
01827         {
01828                 Com_Printf("Unable to save navigations data for map \"%s\" (checksum:%d)\n", filename, checksum );
01829         }
01830         */
01831 #ifndef FINAL_BUILD
01832         if ( fatalErrors )
01833         {
01834                 //Com_Error( ERR_DROP, "%s%d FATAL NAV ERRORS\n", fatalErrorString, fatalErrors );
01835                 Com_Printf( "%s%d FATAL NAV ERRORS\n", fatalErrorString, fatalErrors );
01836         }
01837 #endif
01838 }

qboolean NAV_CheckAhead gentity_t self,
vec3_t  end,
trace_t trace,
int  clipmask
 

void NAV_ClearBlockedInfo gentity_t self  ) 
 

Definition at line 416 of file g_nav.c.

References gNPC_t::aiFlags, gNPC_t::blockingEntNum, ENTITYNUM_WORLD, gentity_t, gentity_s::NPC, and NPCAI_BLOCKED.

Referenced by NAV_AvoidCollision().

00417 {
00418         self->NPC->aiFlags &= ~NPCAI_BLOCKED;
00419         self->NPC->blockingEntNum = ENTITYNUM_WORLD;
00420 }

qboolean NAV_ClearPathToPoint gentity_t self,
vec3_t  pmins,
vec3_t  pmaxs,
vec3_t  point,
int  clipmask,
int  okToHitEntNum
 

Definition at line 222 of file g_nav.c.

References trace_t::allsolid, gentity_s::client, trace_t::contents, CONTENTS_BODY, CONTENTS_BOTCLIP, CONTENTS_MONSTERCLIP, entityShared_t::currentOrigin, EDGE_PATH, trace_t::endpos, trace_t::entityNum, ENTITYNUM_NONE, ENTITYNUM_WORLD, ET_MOVER, FL_NAVGOAL, gentity_s::flags, FlyingCreature(), trace_t::fraction, FRAMETIME, G_CubeOutline(), G_DrawEdge(), g_entities, gentity_t, gNPC_t::goalRadius, entityShared_t::maxs, entityShared_t::mins, NAV_HitNavGoal(), NAVDEBUG_showCollision, NPCInfo, NULL, entityState_s::number, gentity_s::parent, qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, trace_t::startsolid, STEPSIZE, trap_InPVS(), trap_Trace(), vec3_t, VectorAdd, and VectorCopy.

Referenced by NPC_FindCombatPoint(), NPC_SearchForWeapons(), and vmMain().

00223 {
00224 //      trace_t trace;
00225 //      return NAV_CheckAhead( self, point, trace, clipmask|CONTENTS_BOTCLIP );
00226 
00227         vec3_t  mins, maxs;
00228         trace_t trace;
00229 
00230         //Test if they're even conceivably close to one another
00231         if ( !trap_InPVS( self->r.currentOrigin, point ) )
00232                 return qfalse;
00233 
00234         if ( self->flags & FL_NAVGOAL )
00235         {
00236                 if ( !self->parent )
00237                 {
00238                         //SHOULD NEVER HAPPEN!!!
00239                         assert(self->parent);
00240                         return qfalse;
00241                 }
00242                 VectorCopy( self->parent->r.mins, mins );
00243                 VectorCopy( self->parent->r.maxs, maxs );
00244         }
00245         else
00246         {
00247                 VectorCopy( pmins, mins );
00248                 VectorCopy( pmaxs, maxs );
00249         }
00250         
00251         if ( self->client || ( self->flags & FL_NAVGOAL ) )
00252         {
00253                 //Clients can step up things, or if this is a navgoal check, a client will be using this info
00254                 mins[2] += STEPSIZE;
00255 
00256                 //don't let box get inverted
00257                 if ( mins[2] > maxs[2] )
00258                 {       
00259                         mins[2] = maxs[2];
00260                 }
00261         }
00262 
00263         if ( self->flags & FL_NAVGOAL )
00264         {
00265                 //Trace from point to navgoal
00266                 trap_Trace( &trace, point, mins, maxs, self->r.currentOrigin, self->parent->s.number, (clipmask|CONTENTS_MONSTERCLIP|CONTENTS_BOTCLIP)&~CONTENTS_BODY );
00267                 if ( trace.startsolid&&(trace.contents&CONTENTS_BOTCLIP) )
00268                 {//started inside do not enter, so ignore them
00269                         clipmask &= ~CONTENTS_BOTCLIP;
00270                         trap_Trace( &trace, point, mins, maxs, self->r.currentOrigin, self->parent->s.number, (clipmask|CONTENTS_MONSTERCLIP)&~CONTENTS_BODY );
00271                 }
00272                 
00273                 if ( trace.startsolid || trace.allsolid )
00274                 {
00275                         return qfalse;
00276                 }
00277                 
00278                 //Made it
00279                 if ( trace.fraction == 1.0 )
00280                 {
00281                         return qtrue;
00282                 }
00283                 
00284                 if ( okToHitEntNum != ENTITYNUM_NONE && trace.entityNum == okToHitEntNum )
00285                 {
00286                         return qtrue;
00287                 }
00288 
00289                 //Okay, didn't get all the way there, let's see if we got close enough:
00290                 if ( NAV_HitNavGoal( self->r.currentOrigin, self->parent->r.mins, self->parent->r.maxs, trace.endpos, NPCInfo->goalRadius, FlyingCreature( self->parent ) ) )
00291                 {
00292                         return qtrue;
00293                 }
00294                 else
00295                 {
00296                         if ( NAVDEBUG_showCollision )
00297                         {
00298                                 if ( trace.entityNum < ENTITYNUM_WORLD && (&g_entities[trace.entityNum] != NULL) && g_entities[trace.entityNum].s.eType != ET_MOVER )
00299                                 {
00300                                         vec3_t  p1, p2;
00301                                         G_DrawEdge( point, trace.endpos, EDGE_PATH );
00302                                         VectorAdd(g_entities[trace.entityNum].r.mins, g_entities[trace.entityNum].r.currentOrigin, p1);
00303                                         VectorAdd(g_entities[trace.entityNum].r.maxs, g_entities[trace.entityNum].r.currentOrigin, p2);
00304                                         G_CubeOutline( p1, p2, FRAMETIME, 0x0000ff, 0.5 );
00305                                 }
00306                                 //FIXME: if it is a bmodel, light up the surf?
00307                         }
00308                 }
00309         }
00310         else
00311         {
00312                 trap_Trace( &trace, self->r.currentOrigin, mins, maxs, point, self->s.number, clipmask|CONTENTS_MONSTERCLIP|CONTENTS_BOTCLIP);
00313                 if ( trace.startsolid&&(trace.contents&CONTENTS_BOTCLIP) )
00314                 {//started inside do not enter, so ignore them
00315                         clipmask &= ~CONTENTS_BOTCLIP;
00316                         trap_Trace( &trace, self->r.currentOrigin, mins, maxs, point, self->s.number, clipmask|CONTENTS_MONSTERCLIP);
00317                 }
00318 
00319                 if( ( ( trace.startsolid == qfalse ) && ( trace.allsolid == qfalse ) ) && ( trace.fraction == 1.0f ) )
00320                 {//FIXME: check for drops
00321                         return qtrue;
00322                 }
00323 
00324                 if ( okToHitEntNum != ENTITYNUM_NONE && trace.entityNum == okToHitEntNum )
00325                 {
00326                         return qtrue;
00327                 }
00328 
00329                 if ( NAVDEBUG_showCollision )
00330                 {
00331                         if ( trace.entityNum < ENTITYNUM_WORLD && (&g_entities[trace.entityNum] != NULL) && g_entities[trace.entityNum].s.eType != ET_MOVER )
00332                         {
00333                                 vec3_t  p1, p2;
00334                                 G_DrawEdge( self->r.currentOrigin, trace.endpos, EDGE_PATH );
00335                                 VectorAdd(g_entities[trace.entityNum].r.mins, g_entities[trace.entityNum].r.currentOrigin, p1);
00336                                 VectorAdd(g_entities[trace.entityNum].r.maxs, g_entities[trace.entityNum].r.currentOrigin, p2);
00337                                 G_CubeOutline( p1, p2, FRAMETIME, 0x0000ff, 0.5 );
00338                         }
00339                         //FIXME: if it is a bmodel, light up the surf?
00340                 }
00341         }
00342 
00343         return qfalse;
00344 }

void NAV_ClearStoredWaypoints void   ) 
 

Definition at line 1663 of file g_nav.c.

01664 {
01665         numStoredWaypoints = 0;
01666 }

int NAV_FindClosestWaypointForEnt gentity_t ent,
int  targWp
 

Definition at line 352 of file g_nav.c.

References gentity_t, NF_CLEAR_PATH, trap_Nav_GetNearestNode(), and gentity_s::waypoint.

Referenced by AI_SortGroupByPathCostToEnemy(), NPC_BSSearch(), NPC_BSSearchStart(), NPC_BSWander(), and ST_Commander().

00353 {
00354         //FIXME: Take the target into account
00355         return trap_Nav_GetNearestNode( ent, ent->waypoint, NF_CLEAR_PATH, targWp );
00356 }

int NAV_FindClosestWaypointForPoint gentity_t ent,
vec3_t  point
 

Definition at line 358 of file g_nav.c.

References gentity_s::clipmask, G_FreeEntity(), G_SetOrigin(), G_Spawn(), gentity_t, entityShared_t::maxs, entityShared_t::mins, NF_CLEAR_PATH, gentity_s::r, trap_Nav_GetNearestNode(), vec3_t, VectorCopy, gentity_s::waypoint, and WAYPOINT_NONE.

Referenced by AI_ClosestGroupEntityNumToPoint().

00359 {
00360         int     bestWP;
00361         //FIXME: can we make this a static ent?
00362         gentity_t *marker = G_Spawn();
00363         
00364         if ( !marker )
00365         {
00366                 return WAYPOINT_NONE;
00367         }
00368 
00369         G_SetOrigin( marker, point );
00370 
00371         VectorCopy( ent->r.mins, marker->r.mins );//stepsize?
00372         VectorCopy( ent->r.mins, marker->r.maxs );//crouching?
00373 
00374         marker->clipmask = ent->clipmask;
00375         marker->waypoint = WAYPOINT_NONE;
00376 
00377         bestWP = trap_Nav_GetNearestNode( marker, marker->waypoint, NF_CLEAR_PATH, WAYPOINT_NONE );
00378 
00379         G_FreeEntity( marker );
00380 
00381         return bestWP;
00382 }

int NAV_FindClosestWaypointForPoint2 vec3_t  point  ) 
 

Definition at line 384 of file g_nav.c.

References gentity_s::clipmask, G_FreeEntity(), G_SetOrigin(), G_Spawn(), gentity_t, MASK_NPCSOLID, entityShared_t::maxs, entityShared_t::mins, NF_CLEAR_PATH, gentity_s::r, trap_Nav_GetNearestNode(), vec3_t, VectorSet, gentity_s::waypoint, and WAYPOINT_NONE.

Referenced by CP_FindCombatPointWaypoints().

00385 {
00386         int     bestWP;
00387         //FIXME: can we make this a static ent?
00388         gentity_t *marker = G_Spawn();
00389         
00390         if ( !marker )
00391         {
00392                 return WAYPOINT_NONE;
00393         }
00394 
00395         G_SetOrigin( marker, point );
00396 
00397         VectorSet( marker->r.mins, -16, -16, -6 );//includes stepsize
00398         VectorSet( marker->r.maxs, 16, 16, 32 );
00399 
00400         marker->clipmask = MASK_NPCSOLID;
00401         marker->waypoint = WAYPOINT_NONE;
00402 
00403         bestWP = trap_Nav_GetNearestNode( marker, marker->waypoint, NF_CLEAR_PATH, WAYPOINT_NONE );
00404 
00405         G_FreeEntity( marker );
00406 
00407         return bestWP;
00408 }

void NAV_FindPlayerWaypoint int  clNum  ) 
 

Definition at line 1911 of file g_nav.c.

References g_entities, NF_CLEAR_PATH, trap_Nav_GetNearestNode(), gentity_s::waypoint, and WAYPOINT_NONE.

Referenced by G_RunFrame().

01912 {
01913         g_entities[clNum].waypoint = trap_Nav_GetNearestNode( &g_entities[clNum], g_entities[clNum].lastWaypoint, NF_CLEAR_PATH, WAYPOINT_NONE );
01914 }

int NAV_GetNearestNode gentity_t self,
int  lastNode
 

Definition at line 1083 of file g_nav.c.

References gentity_t, NF_CLEAR_PATH, trap_Nav_GetNearestNode(), and WAYPOINT_NONE.

Referenced by NAV_MoveToGoal(), NPC_BSFlee(), and NPC_FindCombatPoint().

01084 {
01085         return trap_Nav_GetNearestNode( self, lastNode, NF_CLEAR_PATH, WAYPOINT_NONE );
01086 }

int NAV_GetStoredWaypoint char *  targetname  ) 
 

Definition at line 1713 of file g_nav.c.

References Q_stricmp(), and waypointData_t::targetname.

Referenced by NAV_CalculatePaths().

01714 {
01715         int i;
01716 
01717         if ( !tempWaypointList || !targetname || !targetname[0] )
01718         {
01719                 return -1;
01720         }
01721         for ( i = 0; i < numStoredWaypoints; i++ )
01722         {
01723                 if ( tempWaypointList[i].targetname[0] )
01724                 {
01725                         if ( !Q_stricmp( targetname, tempWaypointList[i].targetname ) )
01726                         {
01727                                 return i;
01728                         }
01729                 }
01730         }
01731         return -1;
01732 }

qboolean NAV_HitNavGoal vec3_t  point,
vec3_t  mins,
vec3_t  maxs,
vec3_t  dest,
int  radius,
qboolean  flying
 

Definition at line 167 of file g_nav.c.

References fabs(), G_BoundsOverlap(), NAVGOAL_USE_RADIUS, qboolean, vec3_t, VectorAdd, VectorSet, and VectorSubtract.

Referenced by NAV_ClearPathToPoint(), NAV_TestForBlocked(), NPC_BSST_Investigate(), NPC_ClearPathToGoal(), and ReachedGoal().

00168 {
00169         vec3_t  dmins, dmaxs, pmins, pmaxs;
00170 
00171         if ( radius & NAVGOAL_USE_RADIUS )
00172         {
00173                 radius &= ~NAVGOAL_USE_RADIUS;
00174                 //NOTE:  This needs to do a DistanceSquared on navgoals that had
00175                 //                      a radius manually set! We can't do the smaller navgoals against
00176                 //                      walls to get around this because player-sized traces to them
00177                 //                      from angles will not work... - MCG
00178                 if ( !flying )
00179                 {//Allow for a little z difference
00180                         vec3_t  diff;
00181                         VectorSubtract( point, dest, diff );
00182                         if ( fabs(diff[2]) <= 24 )
00183                         {
00184                                 diff[2] = 0;
00185                         }
00186                         return ( VectorLengthSquared( diff ) <= (radius*radius) );
00187                 }
00188                 else
00189                 {//must hit exactly
00190                         return ( DistanceSquared(dest, point) <= (radius*radius) );
00191                 }
00192                 //There is probably a better way to do this, either by preserving the original
00193                 //              mins and maxs of the navgoal and doing this check ONLY if the radius 
00194                 //              is non-zero (like the original implementation) or some boolean to
00195                 //              tell us to do this check rather than the fake bbox overlap check...
00196         }
00197         else
00198         {
00199                 //Construct a dummy bounding box from our radius value
00200                 VectorSet( dmins, -radius, -radius, -radius );
00201                 VectorSet( dmaxs,  radius,  radius,  radius );
00202 
00203                 //Translate it
00204                 VectorAdd( dmins, dest, dmins );
00205                 VectorAdd( dmaxs, dest, dmaxs );
00206 
00207                 //Translate the starting box
00208                 VectorAdd( point, mins, pmins );
00209                 VectorAdd( point, maxs, pmaxs );
00210 
00211                 //See if they overlap
00212                 return G_BoundsOverlap( pmins, pmaxs, dmins, dmaxs );
00213         }
00214 }

qboolean NAV_MicroError vec3_t  start,
vec3_t  end
 

Definition at line 1094 of file g_nav.c.

References entityShared_t::currentOrigin, NPC, qboolean, qfalse, qtrue, gentity_s::r, and vec3_t.

01095 {
01096         if ( VectorCompare( start, end ) )
01097         {
01098                 if ( DistanceSquared( NPC->r.currentOrigin, start ) < (8*8) )
01099                 {
01100                         return qtrue;
01101                 }
01102         }
01103 
01104         return qfalse;
01105 }

qboolean NAV_MoveBlocker gentity_t self,
vec3_t  shove_dir
 

Definition at line 669 of file g_nav.c.

References AngleVectors(), gentity_s::client, gentity_t, NULL, gclient_s::ps, qboolean, qtrue, SHOVE_LIFT, SHOVE_SPEED, vec3_t, vectoangles(), VectorScale, playerState_s::velocity, and YAW.

00670 {
00671         //FIXME: This is a temporary method for making blockers move
00672         
00673         //FIXME: This will, of course, push blockers off of cliffs, into walls and all over the place
00674 
00675         vec3_t  temp_dir, forward;
00676 
00677         vectoangles( shove_dir, temp_dir );
00678 
00679         temp_dir[YAW] += 45;
00680         AngleVectors( temp_dir, forward, NULL, NULL );
00681 
00682         VectorScale( forward, SHOVE_SPEED, self->client->ps.velocity );
00683         self->client->ps.velocity[2] += SHOVE_LIFT;
00684 
00685         //self->NPC->shoveDebounce = level.time + 100;
00686 
00687         return qtrue;
00688 }

int NAV_MoveToGoal gentity_t self,
navInfo_t info
 

Definition at line 1113 of file g_nav.c.

References gentity_s::clipmask, CONTENTS_BODY, CONTENTS_BOTCLIP, entityShared_t::currentOrigin, navInfo_s::direction, navInfo_s::distance, G_DrawNode(), G_FindClosestPointOnLineSegment(), gentity_t, gNPC_t::goalEntity, gentity_s::lastWaypoint, NAV_CheckAhead(), NAV_GetNearestNode(), NAV_TestBestNode(), NAVDEBUG_showEnemyPath, navInfo_t, NODE_GOAL, NODE_NONE, NODE_START, gentity_s::NPC, NULL, entityState_s::number, navInfo_s::pathDirection, qfalse, gentity_s::r, gentity_s::s, navInfo_s::trace, trap_Nav_GetBestNode(), trap_Nav_GetNodePosition(), trap_Nav_ShowPath(), vec3_t, VectorNormalize(), VectorSubtract, gentity_s::waypoint, and WAYPOINT_NONE.

Referenced by NPC_GetMoveDirection().

01114 {
01115         int bestNode;
01116         vec3_t  origin, end;
01117 
01118         //Must have a goal entity to move there
01119         if( self->NPC->goalEntity == NULL )
01120                 return WAYPOINT_NONE;
01121 
01122         //Check special player optimizations
01123         if ( self->NPC->goalEntity->s.number == 0 )
01124         {
01125                 //If we couldn't find the point, then we won't be able to this turn
01126                 if ( self->NPC->goalEntity->waypoint == WAYPOINT_NONE )
01127                         return WAYPOINT_NONE;
01128 
01129                 //NOTENOTE: Otherwise trust this waypoint for the whole frame (reduce all unnecessary calculations)
01130         }
01131         else
01132         {
01133                 //Find the target's waypoint
01134                 if ( ( self->NPC->goalEntity->waypoint = NAV_GetNearestNode( self->NPC->goalEntity, self->NPC->goalEntity->waypoint ) ) == WAYPOINT_NONE )
01135                         return WAYPOINT_NONE;
01136         }
01137 
01138         //Find our waypoint
01139         if ( ( self->waypoint = NAV_GetNearestNode( self, self->lastWaypoint ) ) == WAYPOINT_NONE )
01140                 return WAYPOINT_NONE;
01141 
01142         bestNode = trap_Nav_GetBestNode( self->waypoint, self->NPC->goalEntity->waypoint, NODE_NONE );
01143 
01144         if ( bestNode == WAYPOINT_NONE )
01145         {
01146                 if ( NAVDEBUG_showEnemyPath )
01147                 {
01148                         vec3_t  origin, torigin;
01149 
01150                         trap_Nav_GetNodePosition( self->NPC->goalEntity->waypoint, torigin );
01151                         trap_Nav_GetNodePosition( self->waypoint, origin );
01152 
01153                         G_DrawNode( torigin, NODE_GOAL );
01154                         G_DrawNode( origin, NODE_GOAL );
01155                         G_DrawNode( self->NPC->goalEntity->r.currentOrigin, NODE_START );
01156                 }
01157                 
01158                 return WAYPOINT_NONE;
01159         }
01160 
01161         //Check this node
01162         bestNode = NAV_TestBestNode( self, bestNode, self->NPC->goalEntity->waypoint, qfalse );
01163 
01164         //trace_t       trace;
01165 
01166         //Get this position
01167         trap_Nav_GetNodePosition( bestNode, origin );
01168         trap_Nav_GetNodePosition( self->waypoint, end );
01169 
01170         //Basically, see if the path we have isn't helping
01171         //if ( NAV_MicroError( origin, end ) )
01172         //      return WAYPOINT_NONE;
01173 
01174         //Test the path connection from our current position to the best node
01175         if ( NAV_CheckAhead( self, origin, &info->trace, (self->clipmask&~CONTENTS_BODY)|CONTENTS_BOTCLIP ) == qfalse )
01176         {
01177                 //First attempt to move to the closest point on the line between the waypoints
01178                 G_FindClosestPointOnLineSegment( origin, end, self->r.currentOrigin, origin );
01179 
01180                 //See if we can go there
01181                 if ( NAV_CheckAhead( self, origin, &info->trace, (self->clipmask&~CONTENTS_BODY)|CONTENTS_BOTCLIP ) == qfalse )
01182                 {
01183                         //Just move towards our current waypoint
01184                         bestNode = self->waypoint;
01185                         trap_Nav_GetNodePosition( bestNode, origin );
01186                 }
01187         }
01188 
01189         //Setup our new move information
01190         VectorSubtract( origin, self->r.currentOrigin, info->direction );
01191         info->distance = VectorNormalize( info->direction );
01192 
01193         VectorSubtract( end, origin, info->pathDirection );
01194         VectorNormalize( info->pathDirection );
01195 
01196         //Draw any debug info, if requested
01197         if ( NAVDEBUG_showEnemyPath )
01198         {
01199                 vec3_t  dest, start;
01200 
01201                 //Get the positions
01202                 trap_Nav_GetNodePosition( self->NPC->goalEntity->waypoint, dest );
01203                 trap_Nav_GetNodePosition( bestNode, start );
01204 
01205                 //Draw the route
01206                 G_DrawNode( start, NODE_START );
01207                 G_DrawNode( dest, NODE_GOAL );
01208                 trap_Nav_ShowPath( self->waypoint, self->NPC->goalEntity->waypoint );
01209         }
01210 
01211         return bestNode;
01212 }

qboolean NAV_ResolveBlock gentity_t self,
gentity_t blocker,
vec3_t  blocked_dir
 

Definition at line 696 of file g_nav.c.

References gNPC_t::blockingEntNum, gentity_t, gentity_s::NPC, NPC_Blocked(), NPC_FaceEntity(), entityState_s::number, qboolean, qfalse, qtrue, gentity_s::s, and vec3_t.

Referenced by NAV_ResolveEntityCollision().

00697 {
00698         //Stop double waiting
00699         if ( ( blocker->NPC ) && ( blocker->NPC->blockingEntNum == self->s.number ) )
00700                 return qtrue;
00701 
00702         //For now, just complain about it
00703         NPC_Blocked( self, blocker );
00704         NPC_FaceEntity( blocker, qtrue );
00705 
00706         return qfalse;
00707 }

qboolean NAV_ResolveEntityCollision gentity_t self,
gentity_t blocker,
vec3_t  movedir,
vec3_t  pathDir
 

Definition at line 824 of file g_nav.c.

References entityShared_t::currentOrigin, G_EntIsUnlockedDoor(), gentity_t, MIN_DOOR_BLOCK_DIST_SQR, NAV_Bypass(), NAV_ResolveBlock(), NAV_StackedCanyon(), NPC_Blocked(), NPC_FaceEntity(), entityState_s::number, qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, vec3_t, VectorNormalize(), and VectorSubtract.

Referenced by NAV_AvoidCollision().

00825 {
00826         vec3_t  blocked_dir;
00827         float blocked_dist;
00828 
00829         //Doors are ignored
00830         if ( G_EntIsUnlockedDoor( blocker->s.number ) )
00831         //if ( Q_stricmp( blocker->classname, "func_door" ) == 0 )
00832         {
00833                 if ( DistanceSquared( self->r.currentOrigin, blocker->r.currentOrigin ) > MIN_DOOR_BLOCK_DIST_SQR )
00834                         return qtrue;
00835         }
00836 
00837         VectorSubtract( blocker->r.currentOrigin, self->r.currentOrigin, blocked_dir );
00838         blocked_dist = VectorNormalize( blocked_dir );
00839 
00840         //Make sure an actual collision is going to happen
00841 //      if ( NAV_PredictCollision( self, blocker, movedir, blocked_dir ) == qfalse )
00842 //              return qtrue;
00843         
00844         //See if we can get around the blocker at all (only for player!)
00845         if ( blocker->s.number == 0 )
00846         {
00847                 if ( NAV_StackedCanyon( self, blocker, pathDir ) )
00848                 {
00849                         NPC_Blocked( self, blocker );
00850                         NPC_FaceEntity( blocker, qtrue );
00851 
00852                         return qfalse;
00853                 }
00854         }
00855 
00856         //First, attempt to walk around the blocker
00857         if ( NAV_Bypass( self, blocker, blocked_dir, blocked_dist, movedir ) )
00858                 return qtrue;
00859 
00860         //Second, attempt to calculate a good move position for the blocker
00861         if ( NAV_ResolveBlock( self, blocker, blocked_dir ) )
00862                 return qtrue;
00863 
00864         return qfalse;
00865 }

void NAV_SetBlockedInfo gentity_t self,
int  entId
 

Definition at line 428 of file g_nav.c.

References gNPC_t::aiFlags, gNPC_t::blockingEntNum, gentity_t, gentity_s::NPC, and NPCAI_BLOCKED.

00429 {
00430         self->NPC->aiFlags |= NPCAI_BLOCKED;
00431         self->NPC->blockingEntNum = entId;
00432 }

void NAV_ShowDebugInfo void   ) 
 

Definition at line 1857 of file g_nav.c.

References level_locals_t::combatPoints, G_DrawCombatPoint(), G_DrawNode(), g_entities, level, NAV_TestBestNode(), NAVDEBUG_curGoal, NAVDEBUG_showCombatPoints, NAVDEBUG_showEdges, NAVDEBUG_showNavGoals, NAVDEBUG_showNodes, NAVDEBUG_showTestPath, NF_ANY, NODE_GOAL, NODE_NONE, NODE_START, level_locals_t::numCombatPoints, combatPoint_t::origin, qfalse, RTF_NAVGOAL, TAG_ShowTags(), trap_Nav_GetBestNode(), trap_Nav_GetNearestNode(), trap_Nav_GetNodePosition(), trap_Nav_ShowEdges(), trap_Nav_ShowNodes(), trap_Nav_ShowPath(), vec3_t, and WAYPOINT_NONE.

01858 {
01859         int i;
01860 
01861         if ( NAVDEBUG_showNodes )
01862         {
01863                 trap_Nav_ShowNodes();
01864         }
01865 
01866         if ( NAVDEBUG_showEdges )
01867         {
01868                 trap_Nav_ShowEdges();
01869         }
01870 
01871         if ( NAVDEBUG_showTestPath )
01872         {
01873                 //Get the nearest node to the player
01874                 int     nearestNode = trap_Nav_GetNearestNode( &g_entities[0], g_entities[0].waypoint, NF_ANY, WAYPOINT_NONE );
01875                 int     testNode = trap_Nav_GetBestNode( nearestNode, NAVDEBUG_curGoal, NODE_NONE );
01876                 vec3_t  dest, start;
01877                 
01878                 nearestNode = NAV_TestBestNode( &g_entities[0], nearestNode, testNode, qfalse );
01879 
01880                 //Show the connection
01881 
01882                 //Get the positions
01883                 trap_Nav_GetNodePosition( NAVDEBUG_curGoal, dest );
01884                 trap_Nav_GetNodePosition( nearestNode, start );
01885 
01886                 G_DrawNode( start, NODE_START );
01887                 G_DrawNode( dest, NODE_GOAL );
01888                 trap_Nav_ShowPath( nearestNode, NAVDEBUG_curGoal );
01889         }
01890 
01891         if ( NAVDEBUG_showCombatPoints )
01892         {
01893                 for ( i = 0; i < level.numCombatPoints; i++ )
01894                 {
01895                         G_DrawCombatPoint( level.combatPoints[i].origin, 0 );
01896                 }
01897         }
01898 
01899         if ( NAVDEBUG_showNavGoals )
01900         {
01901                 TAG_ShowTags( RTF_NAVGOAL );
01902         }
01903 }

void NAV_Shutdown void   ) 
 

Definition at line 1846 of file g_nav.c.

References trap_Nav_Free().

01847 {
01848         trap_Nav_Free();
01849 }

qboolean NAV_StackedCanyon gentity_t self,
gentity_t blocker,
vec3_t  pathDir
 

Definition at line 758 of file g_nav.c.

References trace_t::allsolid, gentity_s::clipmask, trace_t::contents, CONTENTS_BOTCLIP, entityShared_t::currentOrigin, G_Cube(), gentity_t, entityShared_t::maxs, entityShared_t::mins, NAVDEBUG_showCollision, entityState_s::number, PerpendicularVector(), qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, sqrt(), trace_t::startsolid, trap_Trace(), vec3_t, VectorAdd, and VectorMA.

Referenced by NAV_ResolveEntityCollision().

00759 {
00760         vec3_t  perp, cross, test;
00761         float   avoidRadius;
00762         int             extraClip = CONTENTS_BOTCLIP;
00763         trace_t tr;
00764 
00765         PerpendicularVector( perp, pathDir );
00766         CrossProduct( pathDir, perp, cross );
00767 
00768         avoidRadius =   sqrt( ( blocker->r.maxs[0] * blocker->r.maxs[0] ) + ( blocker->r.maxs[1] * blocker->r.maxs[1] ) ) + 
00769                                         sqrt( ( self->r.maxs[0] * self->r.maxs[0] ) + ( self->r.maxs[1] * self->r.maxs[1] ) );
00770 
00771         VectorMA( blocker->r.currentOrigin, avoidRadius, cross, test );
00772 
00773         trap_Trace( &tr, test, self->r.mins, self->r.maxs, test, self->s.number, self->clipmask|extraClip );
00774         if ( tr.startsolid&&(tr.contents&CONTENTS_BOTCLIP) )
00775         {//started inside do not enter, so ignore them
00776                 extraClip &= ~CONTENTS_BOTCLIP;
00777                 trap_Trace( &tr, test, self->r.mins, self->r.maxs, test, self->s.number, self->clipmask|extraClip );
00778         }
00779 
00780         if ( NAVDEBUG_showCollision )
00781         {
00782                 vec3_t  mins, maxs;
00783                 vec3_t  RED = { 1.0f, 0.0f, 0.0f };
00784 
00785                 VectorAdd( test, self->r.mins, mins );
00786                 VectorAdd( test, self->r.maxs, maxs );
00787                 G_Cube( mins, maxs, RED, 0.25 );
00788         }
00789 
00790         if ( tr.startsolid == qfalse && tr.allsolid == qfalse )
00791                 return qfalse;
00792 
00793         VectorMA( blocker->r.currentOrigin, -avoidRadius, cross, test );
00794 
00795         trap_Trace( &tr, test, self->r.mins, self->r.maxs, test, self->s.number, self->clipmask|extraClip );
00796         if ( tr.startsolid&&(tr.contents&CONTENTS_BOTCLIP) )
00797         {//started inside do not enter, so ignore them
00798                 extraClip &= ~CONTENTS_BOTCLIP;
00799                 trap_Trace( &tr, test, self->r.mins, self->r.maxs, test, self->s.number, self->clipmask|extraClip );
00800         }
00801 
00802         if ( tr.startsolid == qfalse && tr.allsolid == qfalse )
00803                 return qfalse;
00804 
00805         if ( NAVDEBUG_showCollision )
00806         {
00807                 vec3_t  mins, maxs;
00808                 vec3_t  RED = { 1.0f, 0.0f, 0.0f };
00809 
00810                 VectorAdd( test, self->r.mins, mins );
00811                 VectorAdd( test, self->r.maxs, maxs );
00812                 G_Cube( mins, maxs, RED, 0.25 );
00813         }
00814 
00815         return qtrue;
00816 }

int NAV_Steer gentity_t self,
vec3_t  dir,
float  distance
 

Definition at line 440 of file g_nav.c.

References AngleVectors(), gentity_s::clipmask, CONTENTS_BOTCLIP, entityShared_t::currentOrigin, EDGE_PATH, trace_t::fraction, G_DrawEdge(), gentity_t, NAV_CheckAhead(), NAVDEBUG_showCollision, NULL, gentity_s::r, vec3_t, VectorCopy, VectorMA, and YAW.

00441 {
00442         vec3_t  right_test, left_test;
00443         vec3_t  deviation;
00444         trace_t tr;
00445         float   right_push;
00446         float   left_push;
00447         float   right_ang       = dir[YAW] + 45;
00448         float   left_ang        = dir[YAW] - 45;
00449 
00450         //Get the steering angles
00451         VectorCopy( dir, deviation );
00452         deviation[YAW] = right_ang;
00453 
00454         AngleVectors( deviation, right_test, NULL, NULL );
00455 
00456         deviation[YAW] = left_ang;
00457 
00458         AngleVectors( deviation, left_test, NULL, NULL );
00459 
00460         //Find the end positions
00461         VectorMA( self->r.currentOrigin, distance, right_test, right_test );
00462         VectorMA( self->r.currentOrigin, distance, left_test,  left_test );
00463 
00464         //Draw for debug purposes
00465         if ( NAVDEBUG_showCollision )
00466         {
00467                 G_DrawEdge( self->r.currentOrigin, right_test, EDGE_PATH );
00468                 G_DrawEdge( self->r.currentOrigin, left_test,  EDGE_PATH );
00469         }
00470 
00471         //Find the right influence
00472         NAV_CheckAhead( self, right_test, &tr, self->clipmask|CONTENTS_BOTCLIP );
00473 
00474         right_push = -45 * ( 1.0f - tr.fraction );
00475 
00476         //Find the left influence
00477         NAV_CheckAhead( self, left_test, &tr, self->clipmask|CONTENTS_BOTCLIP );
00478 
00479         left_push = 45 * ( 1.0f - tr.fraction );
00480 
00481         //Influence the mover to respond to the steering
00482         VectorCopy( dir, deviation );
00483         deviation[YAW] += ( left_push + right_push );
00484 
00485         return deviation[YAW];
00486 }

void NAV_StoreWaypoint gentity_t ent  ) 
 

Definition at line 1669 of file g_nav.c.

References gentity_t, gentity_s::health, MAX_QPATH, MAX_STORED_WAYPOINTS, Q_strncpyz(), gentity_s::target, gentity_s::target2, gentity_s::target3, gentity_s::target4, and gentity_s::targetname.

Referenced by SP_waypoint(), and SP_waypoint_small().

01670 {
01671         /*
01672         if ( !tempWaypointList )
01673         {
01674                 //tempWaypointList = (waypointData_t *) gi.Malloc(sizeof(waypointData_t)*MAX_STORED_WAYPOINTS, TAG_TEMP_WORKSPACE, qtrue);
01675 
01676                 int size = sizeof(waypointData_t)*MAX_STORED_WAYPOINTS;
01677                 trap_TrueMalloc((void **)&tempWaypointList, size);
01678                 memset(tempWaypointList, 0, size);
01679         }
01680         */
01681 
01682         if ( numStoredWaypoints >= MAX_STORED_WAYPOINTS )
01683         {
01684                 //G_Error( "Too many waypoints!  (%d > %d)\n", numStoredWaypoints, MAX_STORED_WAYPOINTS );
01685                 //rwwFIXMEFIXME: commented this out so I can load some of the SP levels.
01686                 return;
01687         }
01688         if ( ent->targetname )
01689         {
01690                 Q_strncpyz( tempWaypointList[numStoredWaypoints].targetname, ent->targetname, MAX_QPATH );
01691         }
01692         if ( ent->target )
01693         {
01694                 Q_strncpyz( tempWaypointList[numStoredWaypoints].target, ent->target, MAX_QPATH );
01695         }
01696         if ( ent->target2 )
01697         {
01698                 Q_strncpyz( tempWaypointList[numStoredWaypoints].target2, ent->target2, MAX_QPATH );
01699         }
01700         if ( ent->target3 )
01701         {
01702                 Q_strncpyz( tempWaypointList[numStoredWaypoints].target3, ent->target3, MAX_QPATH );
01703         }
01704         if ( ent->target4 )
01705         {
01706                 Q_strncpyz( tempWaypointList[numStoredWaypoints].target4, ent->target4, MAX_QPATH );
01707         }
01708         tempWaypointList[numStoredWaypoints].nodeID = ent->health;
01709 
01710         numStoredWaypoints++;
01711 }

int NAV_TestBestNode gentity_t self,
int  startID,
int  endID,
qboolean  failEdge
 

Definition at line 971 of file g_nav.c.

References trace_t::allsolid, gentity_s::classname, gentity_s::clipmask, trace_t::contents, entityShared_t::contents, CONTENTS_BODY, CONTENTS_BOTCLIP, CONTENTS_MONSTERCLIP, entityShared_t::currentOrigin, trace_t::endpos, trace_t::entityNum, ENTITYNUM_WORLD, fabs(), trace_t::fraction, G_EntIsBreakable(), G_EntIsDoor(), G_EntIsRemovableUsable(), G_EntIsUnlockedDoor(), g_entities, gentity_t, entityShared_t::maxs, MIN_DOOR_BLOCK_DIST_SQR, entityShared_t::mins, NPC, entityState_s::number, qfalse, gentity_s::r, gentity_s::s, entityState_s::solid, SOLID_BMODEL, trace_t::startsolid, STEPSIZE, gentity_s::targetname, trap_Nav_AddFailedEdge(), trap_Nav_GetNodePosition(), trap_Trace(), VALIDSTRING, vec3_t, VectorSet, entityState_s::weapon, and WP_SABER.

Referenced by NAV_MoveToGoal(), NAV_ShowDebugInfo(), and NAVNEW_MoveToGoal().

00972 {//check only against architectrure
00973         vec3_t  end;
00974         trace_t trace;
00975         vec3_t  mins;
00976         int             clipmask = (NPC->clipmask&~CONTENTS_BODY)|CONTENTS_BOTCLIP;
00977 
00978         //get the position for the test choice
00979         trap_Nav_GetNodePosition( endID, end );
00980 
00981         //Offset the step height
00982         VectorSet( mins, self->r.mins[0], self->r.mins[1], self->r.mins[2] + STEPSIZE );
00983         
00984         trap_Trace( &trace, self->r.currentOrigin, mins, self->r.maxs, end, self->s.number, clipmask );
00985 
00986         if ( trace.startsolid&&(trace.contents&CONTENTS_BOTCLIP) )
00987         {//started inside do not enter, so ignore them
00988                 clipmask &= ~CONTENTS_BOTCLIP;
00989                 trap_Trace( &trace, self->r.currentOrigin, mins, self->r.maxs, end, self->s.number, clipmask );
00990         }
00991         //Do a simple check
00992         if ( ( trace.allsolid == qfalse ) && ( trace.startsolid == qfalse ) && ( trace.fraction == 1.0f ) )
00993         {//it's clear
00994                 return endID;
00995         }
00996 
00997         //See if we're too far above
00998         if ( self->s.weapon != WP_SABER && fabs( self->r.currentOrigin[2] - end[2] ) > 48 )
00999         {
01000         }
01001         else
01002         {
01003                 //This is a work around
01004                 float   radius = ( self->r.maxs[0] > self->r.maxs[1] ) ? self->r.maxs[0] : self->r.maxs[1];
01005                 float   dist = Distance( self->r.currentOrigin, end );
01006                 float   tFrac = 1.0f - ( radius / dist );
01007 
01008                 if ( trace.fraction >= tFrac )
01009                 {//it's clear
01010                         return endID;
01011                 }
01012         }
01013 
01014         //Do a special check for doors
01015         if ( trace.entityNum < ENTITYNUM_WORLD )
01016         {
01017                 gentity_t       *blocker = &g_entities[trace.entityNum];
01018                 
01019                 if VALIDSTRING( blocker->classname )
01020                 {//special case: doors are architecture, but are dynamic, like entitites
01021                         if ( G_EntIsUnlockedDoor( blocker->s.number ) )
01022                         //if ( Q_stricmp( blocker->classname, "func_door" ) == 0 )
01023                         {//it's unlocked, go for it
01024                                 //We're too close, try and avoid the door (most likely stuck on a lip)
01025                                 if ( DistanceSquared( self->r.currentOrigin, trace.endpos ) < MIN_DOOR_BLOCK_DIST_SQR )
01026                                 {
01027                                         return startID;
01028                                 }
01029                                 //we can keep heading to the door, it should open
01030                                 if ( self->s.weapon != WP_SABER && fabs( self->r.currentOrigin[2] - end[2] ) > 48 )
01031                                 {//too far above
01032                                 }
01033                                 else
01034                                 {
01035                                         return endID;
01036                                 }
01037                         }
01038                         else if ( G_EntIsDoor( blocker->s.number ) )
01039                         {//a locked door!
01040                                 //path is blocked by a locked door, mark it as such if instructed to do so
01041                                 if ( failEdge )
01042                                 {
01043                                         trap_Nav_AddFailedEdge( self->s.number, startID, endID );
01044                                 }
01045                         }
01046                         else if ( G_EntIsBreakable( blocker->s.number ) )
01047                         {//do same for breakable brushes/models/glass?
01048                                 //path is blocked by a breakable, mark it as such if instructed to do so
01049                                 if ( failEdge )
01050                                 {
01051                                         trap_Nav_AddFailedEdge( self->s.number, startID, endID );
01052                                 }
01053                         }
01054                         else if ( G_EntIsRemovableUsable( blocker->s.number ) )
01055                         {//and removable usables
01056                                 //path is blocked by a removable usable, mark it as such if instructed to do so
01057                                 if ( failEdge )
01058                                 {
01059                                         trap_Nav_AddFailedEdge( self->s.number, startID, endID );
01060                                 }
01061                         }
01062                         else if ( blocker->targetname && blocker->s.solid == SOLID_BMODEL && ((blocker->r.contents&CONTENTS_MONSTERCLIP)|| (blocker->r.contents&CONTENTS_BOTCLIP)) )
01063                         {//some other kind of do not enter entity brush that will probably be removed
01064                                 //path is blocked by a removable brushent, mark it as such if instructed to do so
01065                                 if ( failEdge )
01066                                 {
01067                                         trap_Nav_AddFailedEdge( self->s.number, startID, endID );
01068                                 }
01069                         }
01070                 }
01071         }
01072         //path is blocked 
01073         //use the fallback choice
01074         return startID;
01075 }

qboolean NAV_TestForBlocked gentity_t self,
gentity_t goal,
gentity_t blocker,
float  distance,
int *  flags
 

Definition at line 873 of file g_nav.c.

References entityShared_t::currentOrigin, ET_ITEM, entityState_s::eType, gentity_t, entityShared_t::maxs, MIN_STOP_DIST, entityShared_t::mins, NAV_HitNavGoal(), NIF_BLOCKED, NPC_Blocked(), NPC_FaceEntity(), NULL, qboolean, qfalse, qtrue, gentity_s::r, and gentity_s::s.

Referenced by NAV_AvoidCollision(), and NAVNEW_AvoidCollision().

00874 {
00875         if ( goal == NULL )
00876                 return qfalse;
00877 
00878         if ( blocker->s.eType == ET_ITEM )
00879                 return qfalse;
00880 
00881         if ( NAV_HitNavGoal( blocker->r.currentOrigin, blocker->r.mins, blocker->r.maxs, goal->r.currentOrigin, 12, qfalse ) )
00882         {
00883                 *flags |= NIF_BLOCKED;
00884 
00885                 if ( distance <= MIN_STOP_DIST )
00886                 {
00887                         NPC_Blocked( self, blocker );
00888                         NPC_FaceEntity( blocker, qtrue );
00889                         return qtrue;
00890                 }
00891         }
00892 
00893         return qfalse;
00894 }

qboolean NAV_TrueCollision gentity_t self,
gentity_t blocker,
vec3_t  movedir,
vec3_t  blocked_dir
 

Definition at line 715 of file g_nav.c.

References gentity_s::client, entityShared_t::currentOrigin, DotProduct, FRAMETIME, G_BoundsOverlap(), gentity_t, entityShared_t::maxs, entityShared_t::mins, NULL, gclient_s::ps, qboolean, qfalse, qtrue, gentity_s::r, vec3_t, VectorAdd, VectorCopy, VectorMA, VectorNormalize2(), and playerState_s::velocity.

00716 {
00717         vec3_t  velocityDir;
00718         float speed, dot;
00719         vec3_t  testPos;
00720         vec3_t  ptmins, ptmaxs, tmins, tmaxs;
00721 
00722         //TODO: Handle all ents
00723         if ( blocker->client == NULL )
00724                 return qfalse;
00725 
00726         //Get the player's move direction and speed
00727         speed = VectorNormalize2( self->client->ps.velocity, velocityDir );
00728 
00729         //See if it's even feasible
00730         dot = DotProduct( movedir, velocityDir );
00731 
00732         if ( dot < 0.85 )
00733                 return qfalse;
00734 
00735         VectorMA( self->r.currentOrigin, speed*FRAMETIME, velocityDir, testPos );
00736 
00737         VectorAdd( blocker->r.currentOrigin, blocker->r.mins, tmins );
00738         VectorAdd( blocker->r.currentOrigin, blocker->r.maxs, tmaxs );
00739 
00740         VectorAdd( testPos, self->r.mins, ptmins );
00741         VectorAdd( testPos, self->r.maxs, ptmaxs );
00742 
00743         if ( G_BoundsOverlap( ptmins, ptmaxs, tmins, tmaxs ) )
00744         {
00745                 VectorCopy( velocityDir, blocked_dir );
00746                 return qtrue;
00747         }
00748 
00749         return qfalse;
00750 }

qboolean NAV_WaypointsTooFar gentity_t wp1,
gentity_t wp2
 

Definition at line 1618 of file g_nav.c.

References Com_Error(), Com_sprintf(), entityShared_t::currentOrigin, ERR_DROP, fatalErrorPointer, fatalErrors, fatalErrorString, gentity_t, qboolean, qfalse, qtrue, gentity_s::r, S_COLOR_RED, strcat(), strlen(), gentity_s::targetname, and vtos().

01619 {
01620         if ( Distance( wp1->r.currentOrigin, wp2->r.currentOrigin ) > 1024 )
01621         {
01622                 char    temp[1024];
01623                 int             len;
01624                 fatalErrors++;
01625                 if ( !wp1->targetname && !wp2->targetname )
01626                 {
01627                         Com_sprintf( temp, sizeof(temp), S_COLOR_RED"Waypoint conn %s->%s > 1024\n", vtos( wp1->r.currentOrigin ), vtos( wp2->r.currentOrigin ) );
01628                 }
01629                 else if ( !wp1->targetname )
01630                 {
01631                         Com_sprintf( temp, sizeof(temp), S_COLOR_RED"Waypoint conn %s->%s > 1024\n", vtos( wp1->r.currentOrigin ), wp2->targetname );
01632                 }
01633                 else if ( !wp2->targetname )
01634                 {
01635                         Com_sprintf( temp, sizeof(temp), S_COLOR_RED"Waypoint conn %s->%s > 1024\n", wp1->targetname, vtos( wp2->r.currentOrigin ) );
01636                 }
01637                 else
01638                 {//they both have valid targetnames
01639                         Com_sprintf( temp, sizeof(temp), S_COLOR_RED"Waypoint conn %s->%s > 1024\n", wp1->targetname, wp2->targetname );
01640                 }
01641                 len = strlen( temp );
01642                 if ( (fatalErrorPointer-fatalErrorString)+len >= sizeof( fatalErrorString ) )
01643                 {
01644                         Com_Error( ERR_DROP, "%s%s%dTOO MANY FATAL NAV ERRORS!!!\n", fatalErrorString, temp, fatalErrors );
01645                         return qtrue;
01646                 }
01647                 strcat( fatalErrorPointer, temp );
01648                 fatalErrorPointer += len;
01649                 return qtrue;
01650         }
01651         else
01652         {
01653                 return qfalse;
01654         }
01655 }

void NPC_Blocked gentity_t self,
gentity_t blocker
 

Definition at line 68 of file g_nav.c.

References gNPC_t::blockedSpeechDebounceTime, gNPC_t::blockingEntNum, BSET_BLOCKED, gentity_s::client, gclient_s::enemyTeam, G_ActivateBehavior(), G_SetEnemy(), gentity_t, level, MIN_BLOCKED_SPEECH_TIME, gentity_s::NPC, NULL, entityState_s::number, gclient_s::playerTeam, random, gentity_s::s, and level_locals_t::time.

Referenced by NAV_ResolveBlock(), NAV_ResolveEntityCollision(), and NAV_TestForBlocked().

00069 {
00070         if ( self->NPC == NULL )
00071                 return;
00072 
00073         //Don't do this too often
00074         if ( self->NPC->blockedSpeechDebounceTime > level.time )
00075                 return;
00076 
00077         //Attempt to run any blocked scripts
00078         if ( G_ActivateBehavior( self, BSET_BLOCKED ) )
00079         {
00080                 return;
00081         }
00082 
00083         //If this is one of our enemies, then just attack him
00084         if ( blocker->client && ( blocker->client->playerTeam == self->client->enemyTeam ) )
00085         {
00086                 G_SetEnemy( self, blocker );
00087                 return;
00088         }
00089 
00090         //Debug_Printf( debugNPCAI, DEBUG_LEVEL_WARNING, "%s: Excuse me, %s %s!\n", self->targetname, blocker->classname, blocker->targetname );
00091         
00092         //If we're being blocked by the player, say something to them
00093         if ( ( blocker->s.number == 0 ) && ( ( blocker->client->playerTeam == self->client->playerTeam ) ) )
00094         {
00095                 //guys in formation are not trying to get to a critical point, 
00096                 //don't make them yell at the player (unless they have an enemy and
00097                 //are in combat because BP thinks it sounds cool during battle)
00098                 //NOTE: only imperials, misc crewmen and hazard team have these wav files now
00099                 //G_AddVoiceEvent( self, Q_irand(EV_BLOCKED1, EV_BLOCKED3), 0 );
00100         }
00101 
00102         self->NPC->blockedSpeechDebounceTime = level.time + MIN_BLOCKED_SPEECH_TIME + ( random() * 4000 );
00103         self->NPC->blockingEntNum = blocker->s.number;
00104 }

void NPC_SetMoveGoal gentity_t ent,
vec3_t  point,
int  radius,
qboolean  isNavGoal,
int  combatPoint,
gentity_t targetEnt
 

Definition at line 112 of file g_nav.c.

References gentity_s::clipmask, gentity_s::combatPoint, entityShared_t::currentOrigin, gentity_s::enemy, FL_NAVGOAL, gentity_s::flags, gentity_t, gNPC_t::goalEntity, gNPC_t::goalRadius, entityShared_t::maxs, entityShared_t::mins, gentity_s::noWaypointTime, gentity_s::NPC, NULL, gentity_s::parent, gentity_s::r, gentity_s::target, gNPC_t::tempGoal, trap_LinkEntity(), vec3_t, VectorCopy, gentity_s::waypoint, and WAYPOINT_NONE.

Referenced by NPC_BSAdvanceFight(), NPC_BSFlee(), NPC_SetPickUpGoal(), NPC_StartFlee(), ST_Commander(), ST_TrackEnemy(), and ST_TransferMoveGoal().

00113 {
00114         //Must be an NPC
00115         if ( ent->NPC == NULL )
00116         {
00117                 return;
00118         }
00119 
00120         if ( ent->NPC->tempGoal == NULL )
00121         {//must still have a goal
00122                 return;
00123         }
00124 
00125         //Copy the origin
00126         //VectorCopy( point, ent->NPC->goalPoint );     //FIXME: Make it use this, and this alone!
00127         VectorCopy( point, ent->NPC->tempGoal->r.currentOrigin );
00128         
00129         //Copy the mins and maxs to the tempGoal
00130         VectorCopy( ent->r.mins, ent->NPC->tempGoal->r.mins );
00131         VectorCopy( ent->r.mins, ent->NPC->tempGoal->r.maxs );
00132 
00133         ent->NPC->tempGoal->target = NULL;
00134         ent->NPC->tempGoal->clipmask = ent->clipmask;
00135         ent->NPC->tempGoal->flags &= ~FL_NAVGOAL;
00136         if ( targetEnt && targetEnt->waypoint >= 0 )
00137         {
00138                 ent->NPC->tempGoal->waypoint = targetEnt->waypoint;
00139         }
00140         else
00141         {
00142                 ent->NPC->tempGoal->waypoint = WAYPOINT_NONE;
00143         }
00144         ent->NPC->tempGoal->noWaypointTime = 0;
00145 
00146         if ( isNavGoal )
00147         {
00148                 assert(ent->NPC->tempGoal->parent);
00149                 ent->NPC->tempGoal->flags |= FL_NAVGOAL;
00150         }
00151 
00152         ent->NPC->tempGoal->combatPoint = combatPoint;
00153         ent->NPC->tempGoal->enemy = targetEnt;
00154 
00155         ent->NPC->goalEntity = ent->NPC->tempGoal;
00156         ent->NPC->goalRadius = radius;
00157 
00158         trap_LinkEntity( ent->NPC->goalEntity );
00159 }

void SP_waypoint gentity_t ent  ) 
 

Definition at line 1275 of file g_nav.c.

References gentity_s::classname, gentity_s::clipmask, Com_Printf(), entityShared_t::contents, CONTENTS_TRIGGER, gentity_s::count, CROUCH_MAXS_2, entityShared_t::currentOrigin, DEFAULT_MAXS_2, DEFAULT_MINS_2, G_CheckInSolid(), G_FreeEntity(), gentity_t, gentity_s::health, MASK_DEADSOLID, entityShared_t::maxs, entityShared_t::mins, NAV_StoreWaypoint(), navCalculatePaths, qtrue, gentity_s::r, S_COLOR_RED, gentity_s::spawnflags, gentity_s::targetname, trap_LinkEntity(), trap_Nav_AddRawPoint(), VectorSet, vtos(), and waypoint_getRadius().

01276 {
01277         if ( navCalculatePaths )
01278         {
01279                 unsigned int radius;
01280 
01281                 VectorSet(ent->r.mins, -15, -15, DEFAULT_MINS_2);
01282                 VectorSet(ent->r.maxs, 15, 15, DEFAULT_MAXS_2);
01283                 
01284                 ent->r.contents = CONTENTS_TRIGGER;
01285                 ent->clipmask = MASK_DEADSOLID;
01286 
01287                 trap_LinkEntity( ent );
01288 
01289                 ent->count = -1;
01290                 ent->classname = "waypoint";
01291 
01292                 if( !(ent->spawnflags&1) && G_CheckInSolid (ent, qtrue))
01293                 {//if not SOLID_OK, and in solid
01294                         ent->r.maxs[2] = CROUCH_MAXS_2;
01295                         if(G_CheckInSolid (ent, qtrue))
01296                         {
01297                                 Com_Printf(S_COLOR_RED"ERROR: Waypoint %s at %s in solid!\n", ent->targetname, vtos(ent->r.currentOrigin));
01298                                 assert(0 && "Waypoint in solid!");
01299                                 G_FreeEntity(ent);
01300                                 return;
01301                         }
01302                 }
01303 
01304                 radius = waypoint_getRadius( ent );
01305 
01306                 ent->health = trap_Nav_AddRawPoint( ent->r.currentOrigin, ent->spawnflags, radius );
01307                 NAV_StoreWaypoint( ent );
01308                 G_FreeEntity(ent);
01309                 return;
01310         }
01311 
01312         G_FreeEntity(ent);
01313 }

void SP_waypoint_navgoal gentity_t ent  ) 
 

Definition at line 1370 of file g_nav.c.

References entityState_s::angles, gentity_s::classname, Com_Printf(), entityShared_t::currentOrigin, G_CheckInSolid(), G_FreeEntity(), gentity_t, entityShared_t::maxs, entityShared_t::mins, NAVGOAL_USE_RADIUS, NULL, entityState_s::origin, qfalse, gentity_s::r, gentity_s::radius, RTF_NAVGOAL, gentity_s::s, S_COLOR_RED, gentity_s::spawnflags, TAG_Add(), gentity_s::targetname, VectorSet, and vtos().

01371 {
01372         int radius = ( ent->radius ) ? (((int)ent->radius)|NAVGOAL_USE_RADIUS) : 12;
01373 
01374         VectorSet( ent->r.mins, -16, -16, -24 );
01375         VectorSet( ent->r.maxs, 16, 16, 32 );
01376         ent->s.origin[2] += 0.125;
01377         if ( !(ent->spawnflags&1) && G_CheckInSolid( ent, qfalse ) )
01378         {
01379                 Com_Printf(S_COLOR_RED"ERROR: Waypoint_navgoal %s at %s in solid!\n", ent->targetname, vtos(ent->r.currentOrigin));
01380                 assert(0);
01381         }
01382         TAG_Add( ent->targetname, NULL, ent->s.origin, ent->s.angles, radius, RTF_NAVGOAL );
01383 
01384         ent->classname = "navgoal";
01385         G_FreeEntity( ent );//can't do this, they need to be found later by some functions, though those could be fixed, maybe?
01386 }

void SP_waypoint_navgoal_1 gentity_t ent  ) 
 

Definition at line 1495 of file g_nav.c.

References entityState_s::angles, gentity_s::classname, Com_Printf(), entityShared_t::currentOrigin, G_CheckInSolid(), G_FreeEntity(), gentity_t, entityShared_t::maxs, entityShared_t::mins, NULL, entityState_s::origin, qfalse, gentity_s::r, RTF_NAVGOAL, gentity_s::s, S_COLOR_RED, gentity_s::spawnflags, TAG_Add(), gentity_s::targetname, VectorSet, and vtos().

01496 {
01497         VectorSet( ent->r.mins, -1, -1, -24 );
01498         VectorSet( ent->r.maxs, 1, 1, 32 );
01499         ent->s.origin[2] += 0.125;
01500         if ( !(ent->spawnflags&1) && G_CheckInSolid( ent, qfalse ) )
01501         {
01502                 Com_Printf(S_COLOR_RED"ERROR: Waypoint_navgoal_1 %s at %s in solid!\n", ent->targetname, vtos(ent->r.currentOrigin));
01503                 assert(0);
01504         }
01505 
01506         TAG_Add( ent->targetname, NULL, ent->s.origin, ent->s.angles, 1, RTF_NAVGOAL );
01507 
01508         ent->classname = "navgoal";
01509         G_FreeEntity( ent );//can't do this, they need to be found later by some functions, though those could be fixed, maybe?
01510 }

void SP_waypoint_navgoal_2 gentity_t ent  ) 
 

Definition at line 1464 of file g_nav.c.

References entityState_s::angles, gentity_s::classname, Com_Printf(), entityShared_t::currentOrigin, G_CheckInSolid(), G_FreeEntity(), gentity_t, entityShared_t::maxs, entityShared_t::mins, NULL, entityState_s::origin, qfalse, gentity_s::r, RTF_NAVGOAL, gentity_s::s, S_COLOR_RED, gentity_s::spawnflags, TAG_Add(), gentity_s::targetname, VectorSet, and vtos().

01465 {       
01466         VectorSet( ent->r.mins, -2, -2, -24 );
01467         VectorSet( ent->r.maxs, 2, 2, 32 );
01468         ent->s.origin[2] += 0.125;
01469         if ( !(ent->spawnflags&1) && G_CheckInSolid( ent, qfalse ) )
01470         {
01471                 Com_Printf(S_COLOR_RED"ERROR: Waypoint_navgoal_2 %s at %s in solid!\n", ent->targetname, vtos(ent->r.currentOrigin));
01472                 assert(0);
01473         }
01474 
01475         TAG_Add( ent->targetname, NULL, ent->s.origin, ent->s.angles, 2, RTF_NAVGOAL );
01476 
01477         ent->classname = "navgoal";
01478         G_FreeEntity( ent );//can't do this, they need to be found later by some functions, though those could be fixed, maybe?
01479 }

void SP_waypoint_navgoal_4 gentity_t ent  ) 
 

Definition at line 1433 of file g_nav.c.

References entityState_s::angles, gentity_s::classname, Com_Printf(), entityShared_t::currentOrigin, G_CheckInSolid(), G_FreeEntity(), gentity_t, entityShared_t::maxs, entityShared_t::mins, NULL, entityState_s::origin, qfalse, gentity_s::r, RTF_NAVGOAL, gentity_s::s, S_COLOR_RED, gentity_s::spawnflags, TAG_Add(), gentity_s::targetname, VectorSet, and vtos().

01434 {
01435         VectorSet( ent->r.mins, -4, -4, -24 );
01436         VectorSet( ent->r.maxs, 4, 4, 32 );
01437         ent->s.origin[2] += 0.125;
01438         if ( !(ent->spawnflags&1) && G_CheckInSolid( ent, qfalse ) )
01439         {
01440                 Com_Printf(S_COLOR_RED"ERROR: Waypoint_navgoal_4 %s at %s in solid!\n", ent->targetname, vtos(ent->r.currentOrigin));
01441                 assert(0);
01442         }
01443 
01444         TAG_Add( ent->targetname, NULL, ent->s.origin, ent->s.angles, 4, RTF_NAVGOAL );
01445 
01446         ent->classname = "navgoal";
01447         G_FreeEntity( ent );//can't do this, they need to be found later by some functions, though those could be fixed, maybe?
01448 }

void SP_waypoint_navgoal_8 gentity_t ent  ) 
 

Definition at line 1402 of file g_nav.c.

References entityState_s::angles, gentity_s::classname, Com_Printf(), entityShared_t::currentOrigin, G_CheckInSolid(), G_FreeEntity(), gentity_t, entityShared_t::maxs, entityShared_t::mins, NULL, entityState_s::origin, qfalse, gentity_s::r, RTF_NAVGOAL, gentity_s::s, S_COLOR_RED, gentity_s::spawnflags, TAG_Add(), gentity_s::targetname, VectorSet, and vtos().

01403 {
01404         VectorSet( ent->r.mins, -8, -8, -24 );
01405         VectorSet( ent->r.maxs, 8, 8, 32 );
01406         ent->s.origin[2] += 0.125;
01407         if ( !(ent->spawnflags&1) && G_CheckInSolid( ent, qfalse ) )
01408         {
01409                 Com_Printf(S_COLOR_RED"ERROR: Waypoint_navgoal_8 %s at %s in solid!\n", ent->targetname, vtos(ent->r.currentOrigin));
01410                 assert(0);
01411         }
01412 
01413         TAG_Add( ent->targetname, NULL, ent->s.origin, ent->s.angles, 8, RTF_NAVGOAL );
01414 
01415         ent->classname = "navgoal";
01416         G_FreeEntity( ent );//can't do this, they need to be found later by some functions, though those could be fixed, maybe?
01417 }

void SP_waypoint_small gentity_t ent  ) 
 

Definition at line 1318 of file g_nav.c.

References gentity_s::classname, gentity_s::clipmask, Com_Printf(), entityShared_t::contents, CONTENTS_TRIGGER, gentity_s::count, CROUCH_MAXS_2, entityShared_t::currentOrigin, DEFAULT_MAXS_2, DEFAULT_MINS_2, G_CheckInSolid(), G_FreeEntity(), gentity_t, gentity_s::health, MASK_DEADSOLID, entityShared_t::maxs, entityShared_t::mins, NAV_StoreWaypoint(), navCalculatePaths, qtrue, gentity_s::r, S_COLOR_RED, gentity_s::spawnflags, gentity_s::targetname, trap_LinkEntity(), trap_Nav_AddRawPoint(), VectorSet, and vtos().

01319 {
01320         if ( navCalculatePaths )
01321         {
01322                 VectorSet(ent->r.mins, -2, -2, DEFAULT_MINS_2);
01323                 VectorSet(ent->r.maxs, 2, 2, DEFAULT_MAXS_2);
01324 
01325                 ent->r.contents = CONTENTS_TRIGGER;
01326                 ent->clipmask = MASK_DEADSOLID;
01327 
01328                 trap_LinkEntity( ent );
01329 
01330                 ent->count = -1;
01331                 ent->classname = "waypoint";
01332 
01333                 if ( !(ent->spawnflags&1) && G_CheckInSolid( ent, qtrue ) )
01334                 {
01335                         ent->r.maxs[2] = CROUCH_MAXS_2;
01336                         if ( G_CheckInSolid( ent, qtrue ) )
01337                         {
01338                                 Com_Printf(S_COLOR_RED"ERROR: Waypoint_small %s at %s in solid!\n", ent->targetname, vtos(ent->r.currentOrigin));
01339                                 assert(0);
01340                                 G_FreeEntity(ent);
01341                                 return;
01342                         }
01343                 }
01344 
01345                 ent->health = trap_Nav_AddRawPoint( ent->r.currentOrigin, ent->spawnflags, 2 );
01346                 NAV_StoreWaypoint( ent );
01347                 G_FreeEntity(ent);
01348                 return;
01349         }
01350 
01351         G_FreeEntity(ent);
01352 }

void Svcmd_Nav_f void   ) 
 

Definition at line 1518 of file g_nav.c.

References Com_Printf(), g_entities, level, NAVDEBUG_curGoal, NAVDEBUG_showCollision, NAVDEBUG_showCombatPoints, NAVDEBUG_showEdges, NAVDEBUG_showEnemyPath, NAVDEBUG_showNavGoals, NAVDEBUG_showNodes, NAVDEBUG_showRadius, NAVDEBUG_showTestPath, NF_CLEAR_PATH, level_locals_t::numCombatPoints, Q_stricmp(), trap_Argv(), trap_Nav_GetNearestNode(), trap_Nav_GetNumNodes(), and WAYPOINT_NONE.

01519 {
01520         char cmd[1024];
01521         trap_Argv( 1, cmd, 1024 );
01522 
01523         if ( Q_stricmp( cmd, "show" ) == 0 )
01524         {
01525                 trap_Argv(2, cmd, 1024);
01526 
01527                 if ( Q_stricmp( cmd, "all" ) == 0 )
01528                 {
01529                         NAVDEBUG_showNodes = !NAVDEBUG_showNodes;
01530                         
01531                         //NOTENOTE: This causes the two states to sync up if they aren't already
01532                         NAVDEBUG_showCollision = NAVDEBUG_showNavGoals = 
01533                         NAVDEBUG_showCombatPoints = NAVDEBUG_showEnemyPath = 
01534                         NAVDEBUG_showEdges = NAVDEBUG_showRadius = NAVDEBUG_showNodes;          
01535                 }
01536                 else if ( Q_stricmp( cmd, "nodes" ) == 0 )
01537                 {
01538                         NAVDEBUG_showNodes = !NAVDEBUG_showNodes;
01539                 }
01540                 else if ( Q_stricmp( cmd, "radius" ) == 0 )
01541                 {
01542                         NAVDEBUG_showRadius = !NAVDEBUG_showRadius;
01543                 }
01544                 else if ( Q_stricmp( cmd, "edges" ) == 0 )
01545                 {
01546                         NAVDEBUG_showEdges = !NAVDEBUG_showEdges;
01547                 }
01548                 else if ( Q_stricmp( cmd, "testpath" ) == 0 )
01549                 {
01550                         NAVDEBUG_showTestPath = !NAVDEBUG_showTestPath;
01551                 }
01552                 else if ( Q_stricmp( cmd, "enemypath" ) == 0 )
01553                 {
01554                         NAVDEBUG_showEnemyPath = !NAVDEBUG_showEnemyPath;
01555                 }
01556                 else if ( Q_stricmp( cmd, "combatpoints" ) == 0 )
01557                 {
01558                         NAVDEBUG_showCombatPoints = !NAVDEBUG_showCombatPoints;
01559                 }
01560                 else if ( Q_stricmp( cmd, "navgoals" ) == 0 )
01561                 {
01562                         NAVDEBUG_showNavGoals = !NAVDEBUG_showNavGoals;
01563                 }
01564                 else if ( Q_stricmp( cmd, "collision" ) == 0 )
01565                 {
01566                         NAVDEBUG_showCollision = !NAVDEBUG_showCollision;
01567                 }
01568         }
01569         else if ( Q_stricmp( cmd, "set" ) == 0 )
01570         {
01571                 trap_Argv( 2, cmd, 1024 );
01572 
01573                 if ( Q_stricmp( cmd, "testgoal" ) == 0 )
01574                 {
01575                         NAVDEBUG_curGoal = trap_Nav_GetNearestNode( &g_entities[0], g_entities[0].waypoint, NF_CLEAR_PATH, WAYPOINT_NONE );
01576                 }
01577         }
01578         else if ( Q_stricmp( cmd, "totals" ) == 0 )
01579         {
01580                 Com_Printf("Navigation Totals:\n");
01581                 Com_Printf("------------------\n");
01582                 Com_Printf("Total Nodes:         %d\n", trap_Nav_GetNumNodes() );
01583                 Com_Printf("Total Combat Points: %d\n", level.numCombatPoints );
01584         }
01585         else
01586         {
01587                 //Print the available commands
01588                 Com_Printf("nav - valid commands\n---\n" );
01589                 Com_Printf("show\n - nodes\n - edges\n - testpath\n - enemypath\n - combatpoints\n - navgoals\n---\n");
01590                 Com_Printf("set\n - testgoal\n---\n" );
01591         }
01592 }

void TAG_ShowTags int  flags  ) 
 

Definition at line 41 of file g_nav.c.

Referenced by NAV_ShowDebugInfo().

00042 {
00043 
00044 }

unsigned int waypoint_getRadius gentity_t ent  ) 
 

Definition at line 1251 of file g_nav.c.

References entityShared_t::currentOrigin, gentity_t, MAX_RADIUS_CHECK, gentity_s::r, waypoint_testDirection(), and YAW_ITERATIONS.

Referenced by SP_waypoint().

01252 {
01253         unsigned int    minDist = MAX_RADIUS_CHECK + 1; // (unsigned int) -1;
01254         unsigned int    dist;
01255         int                             i;
01256 
01257         for ( i = 0; i < YAW_ITERATIONS; i++ )
01258         {
01259                 dist = waypoint_testDirection( ent->r.currentOrigin, ((360.0f/YAW_ITERATIONS) * i), minDist );
01260 
01261                 if ( dist < minDist )
01262                         minDist = dist;
01263         }
01264 
01265         return minDist;
01266 }

unsigned int waypoint_testDirection vec3_t  origin,
float  yaw,
unsigned int  minDist
 

Definition at line 1220 of file g_nav.c.

References AngleVectors(), CONTENTS_BOTCLIP, CONTENTS_MONSTERCLIP, CONTENTS_SOLID, DEFAULT_MAXS_2, DEFAULT_MINS_2, ENTITYNUM_NONE, trace_t::fraction, NULL, STEPSIZE, trap_Trace(), vec3_t, VectorMA, and VectorSet.

Referenced by waypoint_getRadius().

01221 {
01222         vec3_t  trace_dir, test_pos;
01223         vec3_t  maxs, mins;
01224         vec3_t  angles;
01225         trace_t tr;
01226 
01227         //Setup the mins and max
01228         VectorSet( maxs, 15, 15, DEFAULT_MAXS_2 );
01229         VectorSet( mins, -15, -15, DEFAULT_MINS_2 + STEPSIZE );
01230 
01231         //Get our test direction
01232         VectorSet(angles, 0, yaw, 0 );
01233         AngleVectors( angles, trace_dir, NULL, NULL );
01234 
01235         //Move ahead
01236 //      VectorMA( origin, MAX_RADIUS_CHECK, trace_dir, test_pos );
01237         VectorMA( origin, minDist, trace_dir, test_pos );
01238 
01239         trap_Trace( &tr, origin, mins, maxs, test_pos, ENTITYNUM_NONE, ( CONTENTS_SOLID | CONTENTS_MONSTERCLIP | CONTENTS_BOTCLIP ) );
01240 
01241         //return (unsigned int) ( (float) MAX_RADIUS_CHECK * tr.fraction );
01242         return (unsigned int) ( (float) minDist * tr.fraction );
01243 }


Variable Documentation

char* fatalErrorPointer = NULL
 

Definition at line 1616 of file g_nav.c.

Referenced by NAV_CalculatePaths(), and NAV_WaypointsTooFar().

int fatalErrors = 0
 

Definition at line 1615 of file g_nav.c.

Referenced by NAV_CalculatePaths(), NAV_CheckCalcPaths(), and NAV_WaypointsTooFar().

char fatalErrorString[4096]
 

Definition at line 1617 of file g_nav.c.

Referenced by NAV_CalculatePaths(), and NAV_WaypointsTooFar().

qboolean navCalculatePaths = qfalse
 

Definition at line 1597 of file g_nav.c.

Referenced by G_InitGame(), SP_waypoint(), and SP_waypoint_small().

int NAVDEBUG_curGoal = 0
 

Definition at line 1607 of file g_nav.c.

Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f().

qboolean NAVDEBUG_showCollision = qfalse
 

Definition at line 1606 of file g_nav.c.

Referenced by NAV_AvoidCollision(), NAV_Bypass(), NAV_ClearPathToPoint(), NAV_StackedCanyon(), NAV_Steer(), NAVNEW_AvoidCollision(), NAVNEW_Bypass(), and Svcmd_Nav_f().

qboolean NAVDEBUG_showCombatPoints = qfalse
 

Definition at line 1604 of file g_nav.c.

Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f().

qboolean NAVDEBUG_showEdges = qfalse
 

Definition at line 1601 of file g_nav.c.

Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f().

qboolean NAVDEBUG_showEnemyPath = qfalse
 

Definition at line 1603 of file g_nav.c.

Referenced by NAV_MoveToGoal(), NAVNEW_MoveToGoal(), and Svcmd_Nav_f().

qboolean NAVDEBUG_showNavGoals = qfalse
 

Definition at line 1605 of file g_nav.c.

Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f().

qboolean NAVDEBUG_showNodes = qfalse
 

Definition at line 1599 of file g_nav.c.

Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f().

qboolean NAVDEBUG_showRadius = qfalse
 

Definition at line 1600 of file g_nav.c.

Referenced by Svcmd_Nav_f().

qboolean NAVDEBUG_showTestPath = qfalse
 

Definition at line 1602 of file g_nav.c.

Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f().

vec3_t NPCDEBUG_RED
 

Definition at line 58 of file g_nav.c.

Referenced by CG_PredictPlayerState(), and NPC_ShowDebugInfo().