Merge pull request #4038 from IvanSavenko/pathfinder_fixes
[1.5.2] Pathfinder fixes
This commit is contained in:
4 files changed
+33
-34
No files matched your search
@@ -664,15 +664,15 @@ size_t MapRendererPath::selectImageArrow(bool reachableToday, const int3 & curr,
|
||||
// is (directionToArrowIndex[7][5])
|
||||
//
|
||||
const static size_t directionToArrowIndex[9][9] = {
|
||||
{16, 17, 18, 7, 0, 19, 6, 5, 0 },
|
||||
{8, 9, 18, 7, 0, 19, 6, 0, 20},
|
||||
{8, 1, 10, 7, 0, 19, 0, 21, 20},
|
||||
{24, 17, 18, 15, 0, 0, 6, 5, 4 },
|
||||
{16, 17, 18, 7, 0, 19, 6, 5, 12},
|
||||
{8, 9, 18, 7, 0, 19, 6, 13, 20},
|
||||
{8, 1, 10, 7, 0, 19, 14, 21, 20},
|
||||
{24, 17, 18, 15, 0, 11, 6, 5, 4 },
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{8, 1, 2, 0, 0, 11, 22, 21, 20},
|
||||
{24, 17, 0, 23, 0, 3, 14, 5, 4 },
|
||||
{24, 0, 2, 23, 0, 3, 22, 13, 4 },
|
||||
{0, 1, 2, 23, 0, 3, 22, 21, 12}
|
||||
{8, 1, 2, 15, 0, 11, 22, 21, 20},
|
||||
{24, 17, 10, 23, 0, 3, 14, 5, 4 },
|
||||
{24, 9, 2, 23, 0, 3, 22, 13, 4 },
|
||||
{16, 1, 2, 23, 0, 3, 22, 21, 12}
|
||||
};
|
||||
|
||||
size_t enterDirection = (curr.x - next.x + 1) + 3 * (curr.y - next.y + 1);
|
||||
|
||||
@@ -37,6 +37,7 @@ enum class EPathAccessibility : ui8
|
||||
NOT_SET,
|
||||
ACCESSIBLE, //tile can be entered and passed
|
||||
VISITABLE, //tile can be entered as the last tile in path
|
||||
GUARDED, //tile can be entered, but is in zone of control of nearby monster (may also contain visitable object, if any)
|
||||
BLOCKVIS, //visitable from neighboring tile but not passable
|
||||
FLYABLE, //can only be accessed in air layer
|
||||
BLOCKED //tile can be neither entered nor visited
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace PathfinderUtil
|
||||
else if(gs->guardingCreaturePosition(pos).valid())
|
||||
{
|
||||
// Monster close by; blocked visit for battle
|
||||
return EPathAccessibility::BLOCKVIS;
|
||||
return EPathAccessibility::GUARDED;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -267,7 +267,11 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking
|
||||
return BlockingReason::DESTINATION_BLOCKED;
|
||||
|
||||
case EPathNodeAction::BATTLE:
|
||||
/// Movement after BATTLE action only possible from guarded tile to guardian tile
|
||||
// H3 rule: do not allow direct attack on wandering monsters if hero lands on visitable object
|
||||
if (config->options.originalFlyRules && destination.nodeObject && source.node->layer == EPathfindingLayer::AIR)
|
||||
return BlockingReason::DESTINATION_BLOCKED;
|
||||
|
||||
// Movement after BATTLE action only possible from guarded tile to guardian tile
|
||||
if(destination.guarded)
|
||||
{
|
||||
if (pathfinderHelper->options.ignoreGuards)
|
||||
@@ -275,7 +279,6 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking
|
||||
else
|
||||
return BlockingReason::DESTINATION_GUARDED;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -301,7 +304,7 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea
|
||||
|
||||
if(source.guarded)
|
||||
{
|
||||
if(!(pathfinderConfig->options.originalFlyRules && source.node->layer == EPathfindingLayer::AIR)
|
||||
if(source.node->layer != EPathfindingLayer::AIR // zone of control is ignored when flying
|
||||
&& !pathfinderConfig->options.ignoreGuards
|
||||
&& (!destination.isGuardianTile || pathfinderHelper->getGuardiansCount(source.coord) > 1)) // Can step into tile of guard
|
||||
{
|
||||
@@ -339,11 +342,11 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea
|
||||
break;
|
||||
|
||||
case EPathfindingLayer::WATER:
|
||||
if(!pathfinderHelper->canMoveBetween(source.coord, destination.coord)
|
||||
|| destination.node->accessible != EPathAccessibility::ACCESSIBLE)
|
||||
{
|
||||
if(!pathfinderHelper->canMoveBetween(source.coord, destination.coord))
|
||||
return BlockingReason::DESTINATION_BLOCKED;
|
||||
|
||||
if (destination.node->accessible != EPathAccessibility::ACCESSIBLE)
|
||||
return BlockingReason::DESTINATION_BLOCKED;
|
||||
}
|
||||
|
||||
if(destination.guarded)
|
||||
return BlockingReason::DESTINATION_BLOCKED;
|
||||
@@ -376,38 +379,33 @@ void LayerTransitionRule::process(
|
||||
break;
|
||||
|
||||
case EPathfindingLayer::SAIL:
|
||||
//tile must be accessible -> exception: unblocked blockvis tiles -> clear but guarded by nearby monster coast
|
||||
if((destination.node->accessible != EPathAccessibility::ACCESSIBLE && (destination.node->accessible != EPathAccessibility::BLOCKVIS || destination.tile->blocked))
|
||||
|| destination.tile->visitable) //TODO: passableness problem -> town says it's passable (thus accessible) but we obviously can't disembark onto town gate
|
||||
{
|
||||
// have to disembark first before visiting objects on land
|
||||
if (destination.tile->visitable)
|
||||
destination.blocked = true;
|
||||
|
||||
//can disembark only on accessible tiles or tiles guarded by nearby monster
|
||||
if((destination.node->accessible != EPathAccessibility::ACCESSIBLE && destination.node->accessible != EPathAccessibility::GUARDED))
|
||||
destination.blocked = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EPathfindingLayer::AIR:
|
||||
if(pathfinderConfig->options.originalFlyRules)
|
||||
{
|
||||
if(source.node->accessible != EPathAccessibility::ACCESSIBLE &&
|
||||
source.node->accessible != EPathAccessibility::VISITABLE &&
|
||||
destination.node->accessible != EPathAccessibility::VISITABLE &&
|
||||
destination.node->accessible != EPathAccessibility::ACCESSIBLE)
|
||||
if(source.node->accessible != EPathAccessibility::ACCESSIBLE && source.node->accessible != EPathAccessibility::VISITABLE)
|
||||
{
|
||||
if(destination.node->accessible == EPathAccessibility::BLOCKVIS)
|
||||
if (destination.node->accessible == EPathAccessibility::BLOCKVIS)
|
||||
{
|
||||
if(source.nodeObject || (source.tile->blocked && destination.tile->blocked))
|
||||
{
|
||||
// Can't visit 'blockvisit' objects on coast if hero will end up on water terrain
|
||||
if (source.tile->blocked || !destination.tile->entrableTerrain(source.tile))
|
||||
destination.blocked = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
destination.blocked = true;
|
||||
}
|
||||
}
|
||||
else if(destination.node->accessible != EPathAccessibility::ACCESSIBLE)
|
||||
else
|
||||
{
|
||||
/// Hero that fly can only land on accessible tiles
|
||||
if(destination.nodeObject)
|
||||
// Hero that fly can only land on accessible tiles
|
||||
if(destination.node->accessible != EPathAccessibility::ACCESSIBLE && destination.nodeObject)
|
||||
destination.blocked = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user