#include "b_local.h"#include "g_nav.h"Go to the source code of this file.
|
|
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().
|
|
||||||||||||||||||||
|
Definition at line 16 of file g_nav.c. References vec3_t. Referenced by NAV_StackedCanyon(), NPC_BSJump(), and NPC_ShowDebugInfo().
00017 {
00018
00019 }
|
|
||||||||||||||||||||||||
|
Definition at line 21 of file g_nav.c. References vec3_t. Referenced by NAV_ClearPathToPoint().
00022 {
00023
00024 }
|
|
||||||||||||
|
Definition at line 36 of file g_nav.c. References vec3_t. Referenced by NAV_ShowDebugInfo().
00037 {
00038
00039 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||
|
Definition at line 31 of file g_nav.c. References vec3_t. Referenced by NAV_MoveToGoal(), NAV_ShowDebugInfo(), and NAVNEW_MoveToGoal().
00032 {
00033
00034 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
Definition at line 11 of file g_nav.c. References vec3_t.
00012 {
00013
00014 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
|
|
|
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 }
|
|
||||||||||||||||||||||||||||
|
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 }
|
|
|
Definition at line 1663 of file g_nav.c.
01664 {
01665 numStoredWaypoints = 0;
01666 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
Definition at line 1846 of file g_nav.c. References trap_Nav_Free().
01847 {
01848 trap_Nav_Free();
01849 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||||||||||
|
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 }
|
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
|
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 }
|
|
|
Definition at line 41 of file g_nav.c. Referenced by NAV_ShowDebugInfo().
00042 {
00043
00044 }
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
Definition at line 1616 of file g_nav.c. Referenced by NAV_CalculatePaths(), and NAV_WaypointsTooFar(). |
|
|
Definition at line 1615 of file g_nav.c. Referenced by NAV_CalculatePaths(), NAV_CheckCalcPaths(), and NAV_WaypointsTooFar(). |
|
|
Definition at line 1617 of file g_nav.c. Referenced by NAV_CalculatePaths(), and NAV_WaypointsTooFar(). |
|
|
Definition at line 1597 of file g_nav.c. Referenced by G_InitGame(), SP_waypoint(), and SP_waypoint_small(). |
|
|
Definition at line 1607 of file g_nav.c. Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f(). |
|
|
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(). |
|
|
Definition at line 1604 of file g_nav.c. Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f(). |
|
|
Definition at line 1601 of file g_nav.c. Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f(). |
|
|
Definition at line 1603 of file g_nav.c. Referenced by NAV_MoveToGoal(), NAVNEW_MoveToGoal(), and Svcmd_Nav_f(). |
|
|
Definition at line 1605 of file g_nav.c. Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f(). |
|
|
Definition at line 1599 of file g_nav.c. Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f(). |
|
|
Definition at line 1600 of file g_nav.c. Referenced by Svcmd_Nav_f(). |
|
|
Definition at line 1602 of file g_nav.c. Referenced by NAV_ShowDebugInfo(), and Svcmd_Nav_f(). |
|
|
Definition at line 58 of file g_nav.c. Referenced by CG_PredictPlayerState(), and NPC_ShowDebugInfo(). |