When looking into the AI deadlock for running away, I noticed that with original pathfinding, the call to FindBestPath( pSoldier, GRIDSIZE, pSoldier->pathing.bLevel, DetermineMovementMode( pSoldier, AI_ACTION_RUN_AWAY ), COPYREACHABLE, 0 ) just before we actually look for a safe spot around our own location, would bias the AI to run towards EAST every single time instead of towards SOUTH where it could actually run away to another sector.
See screenshot.
Oddly enough, same issue is not present with A* algorithm that find the actual spot to retreat from.
Removing FindBestPath AND disabling the check for if (!(gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_REACHABLE)) allows both algorithms to find the same spot and AI can retreat. We should not have to call FindBestPath for a nonsensical target like GRIDSIZE when trying to find a safe spot to run away to near our current position.
When the call is removed, if the if (!(gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_REACHABLE)) inside the for loop is not removed also, we'll never find any suitable spots as all the tiles had that flag removed just above this part. It needs to be checked whether most of the code inside this FindSpotMaxDistFromOpponents(SOLDIERTYPE *pSoldier) function related to MAPELEMENT_REACHABLE is also unnecessary.
Two issues here that are somewhat related.
FindBestPath( pSoldier, GRIDSIZE, pSoldier->pathing.bLevel, DetermineMovementMode( pSoldier, AI_ACTION_RUN_AWAY ), COPYREACHABLE, 0 )
just before we actually look for a safe spot around our own location, would bias the AI to run towards EAST every single time instead of towards SOUTH where it could actually run away to another sector. See screenshot.Oddly enough, same issue is not present with A* algorithm that find the actual spot to retreat from.
Removing FindBestPath AND disabling the check for
if (!(gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_REACHABLE))
allows both algorithms to find the same spot and AI can retreat. We should not have to call FindBestPath for a nonsensical target like GRIDSIZE when trying to find a safe spot to run away to near our current position.if (!(gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_REACHABLE))
inside the for loop is not removed also, we'll never find any suitable spots as all the tiles had that flag removed just above this part. It needs to be checked whether most of the code inside thisFindSpotMaxDistFromOpponents(SOLDIERTYPE *pSoldier)
function related to MAPELEMENT_REACHABLE is also unnecessary.