#include "b_local.h"#include "g_nav.h"#include "anims.h"#include "../namespace_begin.h"#include "../namespace_end.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 94 of file NPC_goal.c. References qboolean, qfalse, qtrue, and vec3_t. Referenced by NAV_HitNavGoal(), NAV_TrueCollision(), and NPC_BSGM_Attack().
00095 {//NOTE: flush up against counts as overlapping
00096 if(mins1[0]>maxs2[0])
00097 return qfalse;
00098
00099 if(mins1[1]>maxs2[1])
00100 return qfalse;
00101
00102 if(mins1[2]>maxs2[2])
00103 return qfalse;
00104
00105 if(maxs1[0]<mins2[0])
00106 return qfalse;
00107
00108 if(maxs1[1]<mins2[1])
00109 return qfalse;
00110
00111 if(maxs1[2]<mins2[2])
00112 return qfalse;
00113
00114 return qtrue;
00115 }
|
|
||||||||||||||||||||
|
|
|
||||||||||||||||
|
Definition at line 324 of file NPC_move.c. References AngleVectors(), gentity_s::client, entityShared_t::currentAngles, DotProduct, floor(), usercmd_s::forwardmove, gentity_t, playerState_s::moveDir, NULL, gclient_s::ps, gentity_s::r, usercmd_s::rightmove, usercmd_t, vec3_t, VectorCopy, and VectorNormalize(). Referenced by NPC_MoveToGoal().
00325 {
00326 vec3_t forward, right;
00327 float fDot, rDot;
00328
00329 AngleVectors( self->r.currentAngles, forward, right, NULL );
00330
00331 dir[2] = 0;
00332 VectorNormalize( dir );
00333 //NPCs cheat and store this directly because converting movement into a ucmd loses precision
00334 VectorCopy( dir, self->client->ps.moveDir );
00335
00336 fDot = DotProduct( forward, dir ) * 127.0f;
00337 rDot = DotProduct( right, dir ) * 127.0f;
00338 //Must clamp this because DotProduct is not guaranteed to return a number within -1 to 1, and that would be bad when we're shoving this into a signed byte
00339 if ( fDot > 127.0f )
00340 {
00341 fDot = 127.0f;
00342 }
00343 if ( fDot < -127.0f )
00344 {
00345 fDot = -127.0f;
00346 }
00347 if ( rDot > 127.0f )
00348 {
00349 rDot = 127.0f;
00350 }
00351 if ( rDot < -127.0f )
00352 {
00353 rDot = -127.0f;
00354 }
00355 cmd->forwardmove = floor(fDot);
00356 cmd->rightmove = floor(rDot);
00357
00358 /*
00359 vec3_t wishvel;
00360 for ( int i = 0 ; i < 3 ; i++ )
00361 {
00362 wishvel[i] = forward[i]*cmd->forwardmove + right[i]*cmd->rightmove;
00363 }
00364 VectorNormalize( wishvel );
00365 if ( !VectorCompare( wishvel, dir ) )
00366 {
00367 Com_Printf( "PRECISION LOSS: %s != %s\n", vtos(wishvel), vtos(dir) );
00368 }
00369 */
00370 }
|
|
|
Referenced by NPC_BSST_Attack(), NPC_MoveToGoal(), and NPC_Think(). |
|
|
Definition at line 149 of file NPC_move.c. References frameNavInfo, and navInfo_t. Referenced by AI_CheckEnemyCollision().
00150 {
00151 *info = frameNavInfo;
00152 }
|
|
||||||||||||||||
|
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 442 of file g_navnew.c. References navInfo_s::blocker, gNPC_t::consecutiveBlockedMoves, CONTENTS_BODY, entityShared_t::currentOrigin, d_patched, navInfo_s::direction, navInfo_s::distance, EDGE_MOVEDIR, trace_t::entityNum, navInfo_s::flags, G_DrawEdge(), g_entities, gentity_t, vmCvar_t::integer, MAX_COLL_AVOID_DIST, NAV_CheckAhead(), NAV_TestForBlocked(), NAVDEBUG_showCollision, navInfo_t, NAVNEW_ResolveEntityCollision(), NIF_COLLISION, gentity_s::NPC, NPC_SetBlocked(), navInfo_s::pathDirection, qboolean, qfalse, qtrue, gentity_s::r, navInfo_s::trace, vec3_t, VectorCopy, and VectorMA. Referenced by NAVNEW_MoveToGoal(), and NPC_GetMoveDirectionAltRoute().
00443 {
00444 vec3_t movedir;
00445 vec3_t movepos;
00446
00447 //Cap our distance
00448 if ( info->distance > MAX_COLL_AVOID_DIST )
00449 {
00450 info->distance = MAX_COLL_AVOID_DIST;
00451 }
00452
00453 //Get an end position
00454 VectorMA( self->r.currentOrigin, info->distance, info->direction, movepos );
00455 VectorCopy( info->direction, movedir );
00456
00457 //Now test against entities
00458 if ( NAV_CheckAhead( self, movepos, &info->trace, CONTENTS_BODY ) == qfalse )
00459 {
00460 //Get the blocker
00461 info->blocker = &g_entities[ info->trace.entityNum ];
00462 info->flags |= NIF_COLLISION;
00463
00464 //Ok to hit our goal entity
00465 if ( goal == info->blocker )
00466 return qtrue;
00467
00468 if ( setBlockedInfo )
00469 {
00470 if ( self->NPC->consecutiveBlockedMoves > blockedMovesLimit )
00471 {
00472 if ( d_patched.integer )
00473 {//use patch-style navigation
00474 self->NPC->consecutiveBlockedMoves++;
00475 }
00476 NPC_SetBlocked( self, info->blocker );
00477 return qfalse;
00478 }
00479 self->NPC->consecutiveBlockedMoves++;
00480 }
00481 //See if we're moving along with them
00482 //if ( NAVNEW_TrueCollision( self, info->blocker, movedir, info->direction ) == qfalse )
00483 // return qtrue;
00484
00485 //Test for blocking by standing on goal
00486 if ( NAV_TestForBlocked( self, goal, info->blocker, info->distance, &info->flags ) == qtrue )
00487 return qfalse;
00488
00489 //If the above function said we're blocked, don't do the extra checks
00490 /*
00491 if ( info->flags & NIF_BLOCKED )
00492 return qtrue;
00493 */
00494
00495 //See if we can get that entity to move out of our way
00496 if ( NAVNEW_ResolveEntityCollision( self, info->blocker, movedir, info->pathDirection, setBlockedInfo ) == qfalse )
00497 return qfalse;
00498
00499 VectorCopy( movedir, info->direction );
00500
00501 return qtrue;
00502 }
00503 else
00504 {
00505 if ( setBlockedInfo )
00506 {
00507 self->NPC->consecutiveBlockedMoves = 0;
00508 }
00509 }
00510
00511 //Our path is clear, just move there
00512 if ( NAVDEBUG_showCollision )
00513 {
00514 G_DrawEdge( self->r.currentOrigin, movepos, EDGE_MOVEDIR );
00515 }
00516
00517 return qtrue;
00518 }
|
|
||||||||||||
|
NAVNEW_GetWaypoints( self, qtrue ) ) Definition at line 578 of file g_navnew.c. References gNPC_t::aiFlags, gNPC_t::blockedDest, entityShared_t::currentOrigin, d_altRoutes, d_patched, navInfo_s::direction, navInfo_s::distance, EDGE_PATH, G_DrawEdge(), G_DrawNode(), gentity_t, gNPC_t::goalEntity, vmCvar_t::integer, level, memcpy(), NAV_TestBestNode(), NAVDEBUG_showEnemyPath, navInfo_t, NAVNEW_AvoidCollision(), NAVNEW_TestNodeConnectionBlocked(), NF_CLEAR_PATH, NODE_GOAL, NODE_NAVGOAL, NODE_NONE, NODE_START, gentity_s::noWaypointTime, gentity_s::NPC, NPC_ClearBlocked(), NPCAI_BLOCKED, NPCInfo, NULL, entityState_s::number, Q_irand(), qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, gNPC_t::shoveCount, level_locals_t::time, trap_Nav_AddFailedEdge(), trap_Nav_AddFailedNode(), trap_Nav_GetBestNodeAltRoute2(), trap_Nav_GetBestPathBetweenEnts(), trap_Nav_GetNodePosition(), trap_Nav_NodesAreNeighbors(), trap_Nav_ShowPath(), vec3_t, VectorCopy, VectorNormalize(), VectorSubtract, gentity_s::waypoint, WAYPOINT_NONE, entityState_s::weapon, and WP_SABER. Referenced by NPC_GetMoveDirectionAltRoute().
00579 {
00580 int bestNode = WAYPOINT_NONE;
00581 qboolean foundClearPath = qfalse;
00582 vec3_t origin;
00583 navInfo_t tempInfo;
00584 qboolean setBlockedInfo = qtrue;
00585 qboolean inBestWP, inGoalWP, goalWPFailed = qfalse;
00586 int numTries = 0;
00587
00588 memcpy( &tempInfo, info, sizeof( tempInfo ) );
00589
00590 //Must have a goal entity to move there
00591 if( self->NPC->goalEntity == NULL )
00592 return WAYPOINT_NONE;
00593
00594 if ( self->waypoint == WAYPOINT_NONE && self->noWaypointTime > level.time )
00595 {//didn't have a valid one in about the past second, don't look again just yet
00596 return WAYPOINT_NONE;
00597 }
00598 if ( self->NPC->goalEntity->waypoint == WAYPOINT_NONE && self->NPC->goalEntity->noWaypointTime > level.time )
00599 {//didn't have a valid one in about the past second, don't look again just yet
00600 return WAYPOINT_NONE;
00601 }
00602 if ( self->noWaypointTime > level.time &&
00603 self->NPC->goalEntity->noWaypointTime > level.time )
00604 {//just use current waypoints
00605 bestNode = trap_Nav_GetBestNodeAltRoute2( self->waypoint, self->NPC->goalEntity->waypoint, bestNode );
00606 }
00607 //FIXME!!!!: this is making them wiggle back and forth between waypoints
00608 else if ( (bestNode = trap_Nav_GetBestPathBetweenEnts( self, self->NPC->goalEntity, NF_CLEAR_PATH )) == NODE_NONE )
00609 {//one of us didn't have a valid waypoint!
00610 if ( self->waypoint == NODE_NONE )
00611 {//don't even try to find one again for a bit
00612 self->noWaypointTime = level.time + Q_irand( 500, 1500 );
00613 }
00614 if ( self->NPC->goalEntity->waypoint == NODE_NONE )
00615 {//don't even try to find one again for a bit
00616 self->NPC->goalEntity->noWaypointTime = level.time + Q_irand( 500, 1500 );
00617 }
00618 return WAYPOINT_NONE;
00619 }
00620 else
00621 {
00622 if ( self->NPC->goalEntity->noWaypointTime < level.time )
00623 {
00624 self->NPC->goalEntity->noWaypointTime = level.time + Q_irand( 500, 1500 );
00625 }
00626 }
00627
00628 while( !foundClearPath )
00629 {
00630 inBestWP = inGoalWP = qfalse;
00631 /*
00632 bestNode = trap_Nav_GetBestNodeAltRoute( self->waypoint, self->NPC->goalEntity->waypoint, bestNode );
00633 */
00634
00635 if ( bestNode == WAYPOINT_NONE )
00636 {
00637 goto failed;
00638 }
00639
00640 //see if we can get directly to the next node off bestNode en route to goal's node...
00641 //NOTE: shouldn't be necc. now
00642 /*
00643 int oldBestNode = bestNode;
00644 bestNode = NAV_TestBestNode( self, self->waypoint, bestNode, qtrue );//, self->NPC->goalEntity->waypoint );//
00645 //NOTE: Guaranteed to return something
00646 if ( bestNode != oldBestNode )
00647 {//we were blocked somehow
00648 if ( setBlockedInfo )
00649 {
00650 self->NPC->aiFlags |= NPCAI_BLOCKED;
00651 trap_Nav_GetNodePosition( oldBestNode, NPCInfo->blockedDest );
00652 }
00653 }
00654 */
00655 trap_Nav_GetNodePosition( bestNode, origin );
00656 /*
00657 if ( !goalWPFailed )
00658 {//we haven't already tried to go straight to goal or goal's wp
00659 if ( bestNode == self->NPC->goalEntity->waypoint )
00660 {//our bestNode is the goal's wp
00661 if ( NAV_HitNavGoal( self->r.currentOrigin, self->r.mins, self->r.maxs, origin, trap_Nav_GetNodeRadius( bestNode ), FlyingCreature( self ) ) )
00662 {//we're in the goal's wp
00663 inGoalWP = qtrue;
00664 //we're in the goalEntity's waypoint already
00665 //so head for the goalEntity since we know it's clear of architecture
00666 //FIXME: this is pretty stupid because the NPCs try to go straight
00667 // towards their goal before then even try macro_nav...
00668 VectorCopy( self->NPC->goalEntity->r.currentOrigin, origin );
00669 }
00670 }
00671 }
00672 */
00673 if ( !inGoalWP )
00674 {//not heading straight for goal
00675 if ( bestNode == self->waypoint )
00676 {//we know it's clear or architecture
00677 //trap_Nav_GetNodePosition( self->waypoint, origin );
00678 /*
00679 if ( NAV_HitNavGoal( self->r.currentOrigin, self->r.mins, self->r.maxs, origin, trap_Nav_GetNodeRadius( bestNode ), FlyingCreature( self ) ) )
00680 {//we're in the wp we're heading for already
00681 inBestWP = qtrue;
00682 }
00683 */
00684 }
00685 else
00686 {//heading to an edge off our confirmed clear waypoint... make sure it's clear
00687 //it it's not, bestNode will fall back to our waypoint
00688 int oldBestNode = bestNode;
00689 bestNode = NAV_TestBestNode( self, self->waypoint, bestNode, qtrue );
00690 if ( bestNode == self->waypoint )
00691 {//we fell back to our waypoint, reset the origin
00692 self->NPC->aiFlags |= NPCAI_BLOCKED;
00693 trap_Nav_GetNodePosition( oldBestNode, NPCInfo->blockedDest );
00694 trap_Nav_GetNodePosition( bestNode, origin );
00695 }
00696 }
00697 }
00698 //Com_Printf( "goalwp = %d, mywp = %d, node = %d, origin = %s\n", self->NPC->goalEntity->waypoint, self->waypoint, bestNode, vtos(origin) );
00699
00700 memcpy( &tempInfo, info, sizeof( tempInfo ) );
00701 VectorSubtract( origin, self->r.currentOrigin, tempInfo.direction );
00702 VectorNormalize( tempInfo.direction );
00703
00704 //NOTE: One very important thing NAVNEW_AvoidCollision does is
00705 // it actually CHANGES the value of "direction" - it changes it to
00706 // whatever dir you need to go in to avoid the obstacle...
00707 foundClearPath = NAVNEW_AvoidCollision( self, self->NPC->goalEntity, &tempInfo, setBlockedInfo, 5 );
00708
00709 if ( !foundClearPath )
00710 {//blocked by an ent
00711 if ( inGoalWP )
00712 {//we were heading straight for the goal, head for the goal's wp instead
00713 trap_Nav_GetNodePosition( bestNode, origin );
00714 foundClearPath = NAVNEW_AvoidCollision( self, self->NPC->goalEntity, &tempInfo, setBlockedInfo, 5 );
00715 }
00716 }
00717
00718 if ( foundClearPath )
00719 {//clear!
00720 //If we got set to blocked, clear it
00721 NPC_ClearBlocked( self );
00722 //Take the dir
00723 memcpy( info, &tempInfo, sizeof( *info ) );
00724 if ( self->s.weapon == WP_SABER )
00725 {//jedi
00726 if ( info->direction[2] * info->distance > 64 )
00727 {
00728 self->NPC->aiFlags |= NPCAI_BLOCKED;
00729 VectorCopy( origin, NPCInfo->blockedDest );
00730 goto failed;
00731 }
00732 }
00733 }
00734 else
00735 {//blocked by ent!
00736 if ( setBlockedInfo )
00737 {
00738 self->NPC->aiFlags |= NPCAI_BLOCKED;
00739 trap_Nav_GetNodePosition( bestNode, NPCInfo->blockedDest );
00740 }
00741 //Only set blocked info first time
00742 setBlockedInfo = qfalse;
00743
00744 if ( inGoalWP )
00745 {//we headed for our goal and failed and our goal's WP and failed
00746 if ( self->waypoint == self->NPC->goalEntity->waypoint )
00747 {//our waypoint is our goal's waypoint, nothing we can do
00748 //remember that this node is blocked
00749 trap_Nav_AddFailedNode( self, self->waypoint );
00750 goto failed;
00751 }
00752 else
00753 {//try going for our waypoint this time
00754 goalWPFailed = qtrue;
00755 inGoalWP = qfalse;
00756 }
00757 }
00758 else if ( bestNode != self->waypoint )
00759 {//we headed toward our next waypoint (instead of our waypoint) and failed
00760 if ( d_altRoutes.integer )
00761 {//mark this edge failed and try our waypoint
00762 //NOTE: don't assume there is something blocking the direct path
00763 // between my waypoint and the bestNode... I could be off
00764 // that path because of collision avoidance...
00765 if ( d_patched.integer &&//use patch-style navigation
00766 ( !trap_Nav_NodesAreNeighbors( self->waypoint, bestNode )
00767 || NAVNEW_TestNodeConnectionBlocked( self->waypoint, bestNode, self, self->NPC->goalEntity->s.number, qfalse, qtrue ) ) )
00768 {//the direct path between these 2 nodes is blocked by an ent
00769 trap_Nav_AddFailedEdge( self->s.number, self->waypoint, bestNode );
00770 }
00771 bestNode = self->waypoint;
00772 }
00773 else
00774 {
00775 //we should stop
00776 goto failed;
00777 }
00778 }
00779 else
00780 {//we headed for *our* waypoint and couldn't get to it
00781 if ( d_altRoutes.integer )
00782 {
00783 //remember that this node is blocked
00784 trap_Nav_AddFailedNode( self, self->waypoint );
00785 //Now we should get our waypoints again
00786 //FIXME: cache the trace-data for subsequent calls as only the route info would have changed
00787 //if ( (bestNode = trap_Nav_GetBestPathBetweenEnts( self, self->NPC->goalEntity, NF_CLEAR_PATH )) == NODE_NONE )//!NAVNEW_GetWaypoints( self, qfalse ) )
00788 {//one of our waypoints is WAYPOINT_NONE now
00789 goto failed;
00790 }
00791 }
00792 else
00793 {
00794 //we should stop
00795 goto failed;
00796 }
00797 }
00798
00799 if ( ++numTries >= 10 )
00800 {
00801 goto failed;
00802 }
00803 }
00804 }
00805
00806 //finish:
00807 //Draw any debug info, if requested
00808 if ( NAVDEBUG_showEnemyPath )
00809 {
00810 vec3_t dest, start;
00811
00812 //Get the positions
00813 trap_Nav_GetNodePosition( self->NPC->goalEntity->waypoint, dest );
00814 trap_Nav_GetNodePosition( bestNode, start );
00815
00816 //Draw the route
00817 G_DrawNode( start, NODE_START );
00818 if ( bestNode != self->waypoint )
00819 {
00820 vec3_t wpPos;
00821 trap_Nav_GetNodePosition( self->waypoint, wpPos );
00822 G_DrawNode( wpPos, NODE_NAVGOAL );
00823 }
00824 G_DrawNode( dest, NODE_GOAL );
00825 G_DrawEdge( dest, self->NPC->goalEntity->r.currentOrigin, EDGE_PATH );
00826 G_DrawNode( self->NPC->goalEntity->r.currentOrigin, NODE_GOAL );
00827 trap_Nav_ShowPath( bestNode, self->NPC->goalEntity->waypoint );
00828 }
00829
00830 self->NPC->shoveCount = 0;
00831
00832 //let me keep this waypoint for a while
00833 if ( self->noWaypointTime < level.time )
00834 {
00835 self->noWaypointTime = level.time + Q_irand( 500, 1500 );
00836 }
00837 return bestNode;
00838
00839 failed:
00840 //FIXME: What we should really do here is have a list of the goal's and our
00841 // closest clearpath waypoints, ranked. If the first set fails, try the rest
00842 // until there are no alternatives.
00843
00844 trap_Nav_GetNodePosition( self->waypoint, origin );
00845
00846 //do this to avoid ping-ponging?
00847 return WAYPOINT_NONE;
00848 /*
00849 //this was causing ping-ponging
00850 if ( DistanceSquared( origin, self->r.currentOrigin ) < 16 )//woo, magic number
00851 {//We're right up on our waypoint, so that won't help, return none
00852 //Or maybe find the nextbest here?
00853 return WAYPOINT_NONE;
00854 }
00855 else
00856 {//Try going to our waypoint
00857 bestNode = self->waypoint;
00858
00859 VectorSubtract( origin, self->r.currentOrigin, info.direction );
00860 VectorNormalize( info.direction );
00861 }
00862
00863 goto finish;
00864 */
00865 }
|
|
|
Definition at line 497 of file NPC_move.c. References BG_PlayerStateToEntityState(), gentity_s::client, NPC, gclient_s::ps, qfalse, gentity_s::s, and trap_LinkEntity(). Referenced by NPC_ExecuteBState(), and NPC_Think().
00498 {
00499 BG_PlayerStateToEntityState( &NPC->client->ps, &NPC->s, qfalse );
00500 //VectorCopy ( NPC->r.currentOrigin, NPC->lastOrigin );
00501 //rwwFIXMEFIXME: Any significance to this?
00502
00503 // use the precise origin for linking
00504 trap_LinkEntity(NPC);
00505 }
|
|
|
Definition at line 78 of file NPC_move.c. References gNPC_t::combatMove, gentity_s::enemy, gNPC_t::goalEntity, NPC, NPCInfo, qboolean, qfalse, qtrue, and gNPC_t::watchTarget. Referenced by NPC_MoveToGoal().
00079 {
00080 //return NPCInfo->combatMove;
00081 if ( ( NPCInfo->goalEntity && NPC->enemy && NPCInfo->goalEntity == NPC->enemy ) || ( NPCInfo->combatMove ) )
00082 {
00083 return qtrue;
00084 }
00085
00086 if ( NPCInfo->goalEntity && NPCInfo->watchTarget )
00087 {
00088 if ( NPCInfo->goalEntity != NPCInfo->watchTarget )
00089 {
00090 return qtrue;
00091 }
00092 }
00093
00094 return qfalse;
00095 }
|
|
||||||||||||
|
Definition at line 27 of file NPC_move.c. References gentity_s::clipmask, CONTENTS_BODY, CONTENTS_BOTCLIP, entityShared_t::currentOrigin, trace_t::endpos, fabs(), FL_NAVGOAL, gentity_s::flags, FlyingCreature(), trace_t::fraction, gentity_t, gNPC_t::goalRadius, entityShared_t::maxs, entityShared_t::mins, NAV_CheckAhead(), NAV_HitNavGoal(), NPC, NPCInfo, qboolean, qfalse, qtrue, gentity_s::r, and vec3_t. Referenced by NPC_GetMoveDirection(), and NPC_GetMoveDirectionAltRoute().
00028 {
00029 trace_t trace;
00030 float radius, dist, tFrac;
00031
00032 //FIXME: What does do about area portals? THIS IS BROKEN
00033 //if ( gi.inPVS( NPC->r.currentOrigin, goal->r.currentOrigin ) == qfalse )
00034 // return qfalse;
00035
00036 //Look ahead and see if we're clear to move to our goal position
00037 if ( NAV_CheckAhead( NPC, goal->r.currentOrigin, &trace, ( NPC->clipmask & ~CONTENTS_BODY )|CONTENTS_BOTCLIP ) )
00038 {
00039 //VectorSubtract( goal->r.currentOrigin, NPC->r.currentOrigin, dir );
00040 return qtrue;
00041 }
00042
00043 if (!FlyingCreature(NPC))
00044 {
00045 //See if we're too far above
00046 if ( fabs( NPC->r.currentOrigin[2] - goal->r.currentOrigin[2] ) > 48 )
00047 return qfalse;
00048 }
00049
00050 //This is a work around
00051 radius = ( NPC->r.maxs[0] > NPC->r.maxs[1] ) ? NPC->r.maxs[0] : NPC->r.maxs[1];
00052 dist = Distance( NPC->r.currentOrigin, goal->r.currentOrigin );
00053 tFrac = 1.0f - ( radius / dist );
00054
00055 if ( trace.fraction >= tFrac )
00056 return qtrue;
00057
00058 //See if we're looking for a navgoal
00059 if ( goal->flags & FL_NAVGOAL )
00060 {
00061 //Okay, didn't get all the way there, let's see if we got close enough:
00062 if ( NAV_HitNavGoal( trace.endpos, NPC->r.mins, NPC->r.maxs, goal->r.currentOrigin, NPCInfo->goalRadius, FlyingCreature( NPC ) ) )
00063 {
00064 //VectorSubtract(goal->r.currentOrigin, NPC->r.currentOrigin, dir);
00065 return qtrue;
00066 }
00067 }
00068
00069 return qfalse;
00070 }
|
|
||||||||||||
|
Definition at line 160 of file NPC_move.c. References AngleNormalize360(), CONTENTS_LADDER, gNPC_t::desiredYaw, navInfo_s::direction, navInfo_s::distance, navInfo_s::flags, frameNavInfo, gNPC_t::goalEntity, memset(), NAV_AvoidCollision(), NAV_MoveToGoal(), NIF_MACRO_NAV, NPC, NPC_ClearPathToGoal(), NPC_GetMoveInformation(), NPCInfo, navInfo_s::pathDirection, qboolean, qfalse, qtrue, vec3_t, vectoangles(), VectorCopy, gentity_s::watertype, WAYPOINT_NONE, and YAW. Referenced by ImperialProbe_Hunt(), Interrogator_Hunt(), NPC_MoveToGoal(), Remote_Hunt(), Seeker_Hunt(), and Sentry_Hunt().
00161 {
00162 vec3_t angles;
00163
00164 //Clear the struct
00165 memset( &frameNavInfo, 0, sizeof( frameNavInfo ) );
00166
00167 //Get our movement, if any
00168 if ( NPC_GetMoveInformation( frameNavInfo.direction, &frameNavInfo.distance ) == qfalse )
00169 return qfalse;
00170
00171 //Setup the return value
00172 *distance = frameNavInfo.distance;
00173
00174 //For starters
00175 VectorCopy( frameNavInfo.direction, frameNavInfo.pathDirection );
00176
00177 //If on a ladder, move appropriately
00178 if ( NPC->watertype & CONTENTS_LADDER )
00179 {
00180 NPC_LadderMove( frameNavInfo.direction );
00181 return qtrue;
00182 }
00183
00184 //Attempt a straight move to goal
00185 if ( NPC_ClearPathToGoal( frameNavInfo.direction, NPCInfo->goalEntity ) == qfalse )
00186 {
00187 //See if we're just stuck
00188 if ( NAV_MoveToGoal( NPC, &frameNavInfo ) == WAYPOINT_NONE )
00189 {
00190 //Can't reach goal, just face
00191 vectoangles( frameNavInfo.direction, angles );
00192 NPCInfo->desiredYaw = AngleNormalize360( angles[YAW] );
00193 VectorCopy( frameNavInfo.direction, out );
00194 *distance = frameNavInfo.distance;
00195 return qfalse;
00196 }
00197
00198 frameNavInfo.flags |= NIF_MACRO_NAV;
00199 }
00200
00201 //Avoid any collisions on the way
00202 if ( NAV_AvoidCollision( NPC, NPCInfo->goalEntity, &frameNavInfo ) == qfalse )
00203 {
00204 //FIXME: Emit a warning, this is a worst case scenario
00205 //FIXME: if we have a clear path to our goal (exluding bodies), but then this
00206 // check (against bodies only) fails, shouldn't we fall back
00207 // to macro navigation? Like so:
00208 if ( !(frameNavInfo.flags&NIF_MACRO_NAV) )
00209 {//we had a clear path to goal and didn't try macro nav, but can't avoid collision so try macro nav here
00210 //See if we're just stuck
00211 if ( NAV_MoveToGoal( NPC, &frameNavInfo ) == WAYPOINT_NONE )
00212 {
00213 //Can't reach goal, just face
00214 vectoangles( frameNavInfo.direction, angles );
00215 NPCInfo->desiredYaw = AngleNormalize360( angles[YAW] );
00216 VectorCopy( frameNavInfo.direction, out );
00217 *distance = frameNavInfo.distance;
00218 return qfalse;
00219 }
00220
00221 frameNavInfo.flags |= NIF_MACRO_NAV;
00222 }
00223 }
00224
00225 //Setup the return values
00226 VectorCopy( frameNavInfo.direction, out );
00227 *distance = frameNavInfo.distance;
00228
00229 return qtrue;
00230 }
|
|
||||||||||||||||
|
Definition at line 239 of file NPC_move.c. References gNPC_t::aiFlags, AngleNormalize360(), CONTENTS_LADDER, d_altRoutes, gNPC_t::desiredYaw, navInfo_s::direction, navInfo_s::distance, navInfo_s::flags, frameNavInfo, gNPC_t::goalEntity, vmCvar_t::integer, memcpy(), memset(), navInfo_t, NAVNEW_AvoidCollision(), NAVNEW_MoveToGoal(), NIF_MACRO_NAV, NPC, NPC_ClearPathToGoal(), NPC_GetMoveInformation(), NPCAI_BLOCKED, NPCInfo, navInfo_s::pathDirection, qboolean, qfalse, qtrue, vec3_t, vectoangles(), VectorCopy, gentity_s::watertype, WAYPOINT_NONE, and YAW. Referenced by NPC_MoveToGoal().
00240 {
00241 vec3_t angles;
00242
00243 NPCInfo->aiFlags &= ~NPCAI_BLOCKED;
00244
00245 //Clear the struct
00246 memset( &frameNavInfo, 0, sizeof( frameNavInfo ) );
00247
00248 //Get our movement, if any
00249 if ( NPC_GetMoveInformation( frameNavInfo.direction, &frameNavInfo.distance ) == qfalse )
00250 return qfalse;
00251
00252 //Setup the return value
00253 *distance = frameNavInfo.distance;
00254
00255 //For starters
00256 VectorCopy( frameNavInfo.direction, frameNavInfo.pathDirection );
00257
00258 //If on a ladder, move appropriately
00259 if ( NPC->watertype & CONTENTS_LADDER )
00260 {
00261 NPC_LadderMove( frameNavInfo.direction );
00262 return qtrue;
00263 }
00264
00265 //Attempt a straight move to goal
00266 if ( !tryStraight || NPC_ClearPathToGoal( frameNavInfo.direction, NPCInfo->goalEntity ) == qfalse )
00267 {//blocked
00268 //Can't get straight to goal, use macro nav
00269 if ( NAVNEW_MoveToGoal( NPC, &frameNavInfo ) == WAYPOINT_NONE )
00270 {
00271 //Can't reach goal, just face
00272 vectoangles( frameNavInfo.direction, angles );
00273 NPCInfo->desiredYaw = AngleNormalize360( angles[YAW] );
00274 VectorCopy( frameNavInfo.direction, out );
00275 *distance = frameNavInfo.distance;
00276 return qfalse;
00277 }
00278 //else we are on our way
00279 frameNavInfo.flags |= NIF_MACRO_NAV;
00280 }
00281 else
00282 {//we have no architectural problems, see if there are ents inthe way and try to go around them
00283 //not blocked
00284 if ( d_altRoutes.integer )
00285 {//try macro nav
00286 navInfo_t tempInfo;
00287 memcpy( &tempInfo, &frameNavInfo, sizeof( tempInfo ) );
00288 if ( NAVNEW_AvoidCollision( NPC, NPCInfo->goalEntity, &tempInfo, qtrue, 5 ) == qfalse )
00289 {//revert to macro nav
00290 //Can't get straight to goal, dump tempInfo and use macro nav
00291 if ( NAVNEW_MoveToGoal( NPC, &frameNavInfo ) == WAYPOINT_NONE )
00292 {
00293 //Can't reach goal, just face
00294 vectoangles( frameNavInfo.direction, angles );
00295 NPCInfo->desiredYaw = AngleNormalize360( angles[YAW] );
00296 VectorCopy( frameNavInfo.direction, out );
00297 *distance = frameNavInfo.distance;
00298 return qfalse;
00299 }
00300 //else we are on our way
00301 frameNavInfo.flags |= NIF_MACRO_NAV;
00302 }
00303 else
00304 {//otherwise, either clear or can avoid
00305 memcpy( &frameNavInfo, &tempInfo, sizeof( frameNavInfo ) );
00306 }
00307 }
00308 else
00309 {//OR: just give up
00310 if ( NAVNEW_AvoidCollision( NPC, NPCInfo->goalEntity, &frameNavInfo, qtrue, 30 ) == qfalse )
00311 {//give up
00312 return qfalse;
00313 }
00314 }
00315 }
00316
00317 //Setup the return values
00318 VectorCopy( frameNavInfo.direction, out );
00319 *distance = frameNavInfo.distance;
00320
00321 return qtrue;
00322 }
|
|
||||||||||||
|
Definition at line 126 of file NPC_move.c. References gNPC_t::blockedDest, entityShared_t::currentOrigin, gNPC_t::goalEntity, NPC, NPCInfo, NULL, qboolean, qfalse, qtrue, gentity_s::r, vec3_t, VectorCopy, VectorNormalize(), and VectorSubtract. Referenced by NPC_GetMoveDirection(), and NPC_GetMoveDirectionAltRoute().
00127 {
00128 //NOTENOTE: Use path stacks!
00129
00130 //Make sure we have somewhere to go
00131 if ( NPCInfo->goalEntity == NULL )
00132 return qfalse;
00133
00134 //Get our move info
00135 VectorSubtract( NPCInfo->goalEntity->r.currentOrigin, NPC->r.currentOrigin, dir );
00136 *distance = VectorNormalize( dir );
00137
00138 VectorCopy( NPCInfo->goalEntity->r.currentOrigin, NPCInfo->blockedDest );
00139
00140 return qtrue;
00141 }
|
|
|
Definition at line 382 of file NPC_move.c. References AngleNormalize360(), BOTH_PAIN1, BOTH_PAIN18, BUTTON_WALKING, usercmd_s::buttons, gentity_s::client, gNPC_t::desiredPitch, gNPC_t::desiredYaw, gNPC_t::distToGoal, EF2_FLYING, playerState_s::eFlags2, usercmd_s::forwardmove, G_UcmdMoveForDir(), GetTime(), gNPC_t::lastPathAngles, entityState_s::legsAnim, NPC, NPC_CheckCombatMove(), NPC_GetMoveDirection(), NPC_GetMoveDirectionAltRoute(), NPCInfo, PITCH, PM_InKnockDown(), gclient_s::ps, qboolean, qfalse, qtrue, gNPCstats_e::runSpeed, gentity_s::s, playerState_s::speed, startTime, gNPC_t::stats, ucmd, vec3_t, vectoangles(), playerState_s::velocity, gNPCstats_e::walkSpeed, and YAW. Referenced by ATST_Hunt(), ATST_Patrol(), Droid_Patrol(), Howler_Combat(), Howler_Move(), Howler_Patrol(), ImperialProbe_Patrol(), Mark1_Hunt(), Mark1_Patrol(), Mark2_Hunt(), Mark2_Patrol(), MineMonster_Combat(), MineMonster_Idle(), MineMonster_Move(), MineMonster_Patrol(), NPC_BSCinematic(), NPC_BSDefault(), NPC_BSFlee(), NPC_BSGM_Patrol(), NPC_BSGrenadier_Patrol(), NPC_BSHuntAndKill(), NPC_BSIdle(), NPC_BSJedi_FollowLeader(), NPC_BSPatrol(), NPC_BSRun(), NPC_BSRunAndShoot(), NPC_BSSearch(), NPC_BSSniper_Patrol(), NPC_BSST_Investigate(), NPC_BSST_Patrol(), NPC_BSWander(), NPC_Sentry_Patrol(), NPC_SlideMoveToGoal(), Rancor_Combat(), Rancor_Idle(), Rancor_Move(), Rancor_Patrol(), Remote_Patrol(), Seeker_FollowOwner(), Wampa_Idle(), Wampa_Move(), and Wampa_Patrol().
00383 {
00384 float distance;
00385 vec3_t dir;
00386
00387 #if AI_TIMERS
00388 int startTime = GetTime(0);
00389 #endif// AI_TIMERS
00390 //If taking full body pain, don't move
00391 if ( PM_InKnockDown( &NPC->client->ps ) || ( ( NPC->s.legsAnim >= BOTH_PAIN1 ) && ( NPC->s.legsAnim <= BOTH_PAIN18 ) ) )
00392 {
00393 return qtrue;
00394 }
00395
00396 /*
00397 if( NPC->s.eFlags & EF_LOCKED_TO_WEAPON )
00398 {//If in an emplaced gun, never try to navigate!
00399 return qtrue;
00400 }
00401 */
00402 //rwwFIXMEFIXME: emplaced support
00403
00404 //FIXME: if can't get to goal & goal is a target (enemy), try to find a waypoint that has line of sight to target, at least?
00405 //Get our movement direction
00406 #if 1
00407 if ( NPC_GetMoveDirectionAltRoute( dir, &distance, tryStraight ) == qfalse )
00408 #else
00409 if ( NPC_GetMoveDirection( dir, &distance ) == qfalse )
00410 #endif
00411 return qfalse;
00412
00413 NPCInfo->distToGoal = distance;
00414
00415 //Convert the move to angles
00416 vectoangles( dir, NPCInfo->lastPathAngles );
00417 if ( (ucmd.buttons&BUTTON_WALKING) )
00418 {
00419 NPC->client->ps.speed = NPCInfo->stats.walkSpeed;
00420 }
00421 else
00422 {
00423 NPC->client->ps.speed = NPCInfo->stats.runSpeed;
00424 }
00425
00426 //FIXME: still getting ping-ponging in certain cases... !!! Nav/avoidance error? WTF???!!!
00427 //If in combat move, then move directly towards our goal
00428 if ( NPC_CheckCombatMove() )
00429 {//keep current facing
00430 G_UcmdMoveForDir( NPC, &ucmd, dir );
00431 }
00432 else
00433 {//face our goal
00434 //FIXME: strafe instead of turn if change in dir is small and temporary
00435 NPCInfo->desiredPitch = 0.0f;
00436 NPCInfo->desiredYaw = AngleNormalize360( NPCInfo->lastPathAngles[YAW] );
00437
00438 //Pitch towards the goal and also update if flying or swimming
00439 if ( (NPC->client->ps.eFlags2&EF2_FLYING) )//moveType == MT_FLYSWIM )
00440 {
00441 NPCInfo->desiredPitch = AngleNormalize360( NPCInfo->lastPathAngles[PITCH] );
00442
00443 if ( dir[2] )
00444 {
00445 float scale = (dir[2] * distance);
00446 if ( scale > 64 )
00447 {
00448 scale = 64;
00449 }
00450 else if ( scale < -64 )
00451 {
00452 scale = -64;
00453 }
00454 NPC->client->ps.velocity[2] = scale;
00455 //NPC->client->ps.velocity[2] = (dir[2] > 0) ? 64 : -64;
00456 }
00457 }
00458
00459 //Set any final info
00460 ucmd.forwardmove = 127;
00461 }
00462
00463 #if AI_TIMERS
00464 navTime += GetTime( startTime );
00465 #endif// AI_TIMERS
00466 return qtrue;
00467 }
|
|
|
Definition at line 476 of file NPC_move.c. References gentity_s::client, gNPC_t::combatMove, gNPC_t::desiredYaw, NPC, NPC_MoveToGoal(), NPCInfo, gclient_s::ps, qboolean, qtrue, playerState_s::viewangles, and YAW. Referenced by NPC_BSFollowLeader(), and NPC_BSMove().
00477 {
00478 float saveYaw = NPC->client->ps.viewangles[YAW];
00479 qboolean ret;
00480
00481 NPCInfo->combatMove = qtrue;
00482
00483 ret = NPC_MoveToGoal( qtrue );
00484
00485 NPCInfo->desiredYaw = saveYaw;
00486
00487 return ret;
00488 }
|
|
|
Definition at line 1216 of file bg_panimate.c.
01217 {
01218 switch ( (ps->legsAnim) )
01219 {
01220 case BOTH_KNOCKDOWN1:
01221 case BOTH_KNOCKDOWN2:
01222 case BOTH_KNOCKDOWN3:
01223 case BOTH_KNOCKDOWN4:
01224 case BOTH_KNOCKDOWN5:
01225 return qtrue;
01226 break;
01227 case BOTH_GETUP1:
01228 case BOTH_GETUP2:
01229 case BOTH_GETUP3:
01230 case BOTH_GETUP4:
01231 case BOTH_GETUP5:
01232 case BOTH_FORCE_GETUP_F1:
01233 case BOTH_FORCE_GETUP_F2:
01234 case BOTH_FORCE_GETUP_B1:
01235 case BOTH_FORCE_GETUP_B2:
01236 case BOTH_FORCE_GETUP_B3:
01237 case BOTH_FORCE_GETUP_B4:
01238 case BOTH_FORCE_GETUP_B5:
01239 case BOTH_GETUP_BROLL_B:
01240 case BOTH_GETUP_BROLL_F:
01241 case BOTH_GETUP_BROLL_L:
01242 case BOTH_GETUP_BROLL_R:
01243 case BOTH_GETUP_FROLL_B:
01244 case BOTH_GETUP_FROLL_F:
01245 case BOTH_GETUP_FROLL_L:
01246 case BOTH_GETUP_FROLL_R:
01247 if ( ps->legsTimer )
01248 {
01249 return qtrue;
01250 }
01251 break;
01252 }
01253 return qfalse;
01254 }
|
|
|
Definition at line 14 of file NPC_move.c. Referenced by NAV_GetLastMove(), NPC_GetMoveDirection(), and NPC_GetMoveDirectionAltRoute(). |