When gfTacticalAIRetreat is on, the AI will end up at a call to HandleAITacticalTraversal( pSoldier ); prematurely in HandleSoldierAI() on their next movement after beginning AI_ACTION_RUNNINGAWAY action.
The stored path gets reset, which then makes us evaluate the ubQuoteActionID branch and we end up to the tactical traversal call even if nowhere near a map edge grid.
else
{
// an old action was in progress; continue it
if (pSoldier->aiData.bAction >= FIRST_MOVEMENT_ACTION && pSoldier->aiData.bAction <= LAST_MOVEMENT_ACTION && !pSoldier->flags.fDelayedMovement)
{
----------> // !!! This call evaluates to true because usPathIndex == usPathDataSize == 0 !!!
if (pSoldier->pathing.usPathIndex == pSoldier->pathing.usPathDataSize)
{
----------> // !!! This will be false as sAbsoluteFinalDestination == NOWHERE !!!
if (!TileIsOutOfBounds(pSoldier->sAbsoluteFinalDestination))
{
if ( !ACTING_ON_SCHEDULE( pSoldier ) && SpacesAway( pSoldier->sGridNo, pSoldier->sAbsoluteFinalDestination ) < 4 )
{
// This is close enough... reached final destination for NPC system move
if ( pSoldier->sAbsoluteFinalDestination != pSoldier->sGridNo )
{
// update NPC records to replace our final dest with this location
ReplaceLocationInNPCDataFromProfileID( pSoldier->ubProfile, pSoldier->sAbsoluteFinalDestination, pSoldier->sGridNo );
}
pSoldier->sAbsoluteFinalDestination = pSoldier->sGridNo;
// change action data so that we consider this our final destination below
pSoldier->aiData.usActionData = pSoldier->sGridNo;
}
if ( pSoldier->sAbsoluteFinalDestination == pSoldier->sGridNo )
{
pSoldier->sAbsoluteFinalDestination = NOWHERE;
if ( !ACTING_ON_SCHEDULE( pSoldier ) && pSoldier->ubQuoteRecord && pSoldier->ubQuoteActionID == QUOTE_ACTION_ID_CHECKFORDEST )
{
NPCReachedDestination( pSoldier, FALSE );
// wait just a little bit so the queue can be processed
pSoldier->aiData.bNextAction = AI_ACTION_WAIT;
pSoldier->aiData.usNextActionData = 500;
}
else if (pSoldier->ubQuoteActionID >= QUOTE_ACTION_ID_TRAVERSE_EAST && pSoldier->ubQuoteActionID <= QUOTE_ACTION_ID_TRAVERSE_NORTH)
{
HandleAITacticalTraversal( pSoldier );
return;
}
}
else
{
// make sure this guy is handled next frame!
pSoldier->flags.uiStatusFlags |= AI_HANDLE_EVERY_FRAME;
}
}
---------> /// !!! This evaluates to true because ubQuoteActionID is *not* reset along with the stored path !!!
// for regular guys still have to check for leaving the map
else if (pSoldier->ubQuoteActionID >= QUOTE_ACTION_ID_TRAVERSE_EAST && pSoldier->ubQuoteActionID <= QUOTE_ACTION_ID_TRAVERSE_NORTH)
{
HandleAITacticalTraversal( pSoldier );
return;
}
When gfTacticalAIRetreat is on, the AI will end up at a call to HandleAITacticalTraversal( pSoldier ); prematurely in HandleSoldierAI() on their next movement after beginning AI_ACTION_RUNNINGAWAY action.
The stored path gets reset, which then makes us evaluate the ubQuoteActionID branch and we end up to the tactical traversal call even if nowhere near a map edge grid.