mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
CPathfinder: add one turn boundary for flying and water walking
Now when oneTurnSpecialLayersLimit is enabled hero won't be able to stop on blocked or water tiles between turns. It's default H3 mechanics so it's enabled by default.
This commit is contained in:
parent
2fb73c55e1
commit
4af9c7c29d
@ -29,6 +29,7 @@ CPathfinder::PathfinderOptions::PathfinderOptions()
|
|||||||
useTeleportWhirlpool = false;
|
useTeleportWhirlpool = false;
|
||||||
|
|
||||||
lightweightFlyingMode = false;
|
lightweightFlyingMode = false;
|
||||||
|
oneTurnSpecialLayersLimit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPathfinder::CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance *_hero)
|
CPathfinder::CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance *_hero)
|
||||||
@ -66,6 +67,19 @@ void CPathfinder::calculatePaths()
|
|||||||
return cp->layer == EPathfindingLayer::SAIL ? maxMovePointsWater : maxMovePointsLand;
|
return cp->layer == EPathfindingLayer::SAIL ? maxMovePointsWater : maxMovePointsLand;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto passOneTurnLimitCheck = [&](bool shouldCheck) -> bool
|
||||||
|
{
|
||||||
|
if(options.oneTurnSpecialLayersLimit && shouldCheck)
|
||||||
|
{
|
||||||
|
if((cp->layer == EPathfindingLayer::AIR || cp->layer == EPathfindingLayer::WATER)
|
||||||
|
&& cp->accessible != CGPathNode::ACCESSIBLE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
auto isBetterWay = [&](int remains, int turn) -> bool
|
auto isBetterWay = [&](int remains, int turn) -> bool
|
||||||
{
|
{
|
||||||
if(dp->turns == 0xff) //we haven't been here before
|
if(dp->turns == 0xff) //we haven't been here before
|
||||||
@ -113,9 +127,13 @@ void CPathfinder::calculatePaths()
|
|||||||
if(dp->locked)
|
if(dp->locked)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(!passOneTurnLimitCheck(cp->turns != turn))
|
||||||
|
continue;
|
||||||
|
|
||||||
if(cp->layer != i && !isLayerTransitionPossible())
|
if(cp->layer != i && !isLayerTransitionPossible())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
destAction = CGPathNode::UNKNOWN;
|
destAction = CGPathNode::UNKNOWN;
|
||||||
if(!isMovementToDestPossible())
|
if(!isMovementToDestPossible())
|
||||||
continue;
|
continue;
|
||||||
@ -127,7 +145,6 @@ void CPathfinder::calculatePaths()
|
|||||||
remains = hero->movementPointsAfterEmbark(movement, cost, destAction - 1);
|
remains = hero->movementPointsAfterEmbark(movement, cost, destAction - 1);
|
||||||
cost = movement - remains;
|
cost = movement - remains;
|
||||||
}
|
}
|
||||||
|
|
||||||
int turnAtNextTile = turn;
|
int turnAtNextTile = turn;
|
||||||
if(remains < 0)
|
if(remains < 0)
|
||||||
{
|
{
|
||||||
@ -138,7 +155,8 @@ void CPathfinder::calculatePaths()
|
|||||||
remains = moveAtNextTile - cost;
|
remains = moveAtNextTile - cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isBetterWay(remains, turnAtNextTile))
|
if(isBetterWay(remains, turnAtNextTile)
|
||||||
|
&& passOneTurnLimitCheck(cp->turns != turnAtNextTile || !remains))
|
||||||
{
|
{
|
||||||
assert(dp != cp->theNodeBefore); //two tiles can't point to each other
|
assert(dp != cp->theNodeBefore); //two tiles can't point to each other
|
||||||
dp->moveRemains = remains;
|
dp->moveRemains = remains;
|
||||||
@ -439,11 +457,16 @@ bool CPathfinder::isDestinationGuardian()
|
|||||||
|
|
||||||
void CPathfinder::initializeGraph()
|
void CPathfinder::initializeGraph()
|
||||||
{
|
{
|
||||||
auto updateNode = [&](int3 pos, EPathfindingLayer layer, const TerrainTile *tinfo)
|
auto updateNode = [&](int3 pos, EPathfindingLayer layer, const TerrainTile *tinfo, bool blockNotAccessible)
|
||||||
{
|
{
|
||||||
auto node = out.getNode(pos, layer);
|
auto node = out.getNode(pos, layer);
|
||||||
node->reset();
|
node->reset();
|
||||||
node->accessible = evaluateAccessibility(pos, tinfo);
|
|
||||||
|
auto accessibility = evaluateAccessibility(pos, tinfo);
|
||||||
|
if(blockNotAccessible
|
||||||
|
&& (accessibility != CGPathNode::ACCESSIBLE || tinfo->terType == ETerrainType::WATER))
|
||||||
|
accessibility = CGPathNode::BLOCKED;
|
||||||
|
node->accessible = accessibility;
|
||||||
};
|
};
|
||||||
|
|
||||||
int3 pos;
|
int3 pos;
|
||||||
@ -459,16 +482,16 @@ void CPathfinder::initializeGraph()
|
|||||||
case ETerrainType::ROCK:
|
case ETerrainType::ROCK:
|
||||||
break;
|
break;
|
||||||
case ETerrainType::WATER:
|
case ETerrainType::WATER:
|
||||||
updateNode(pos, EPathfindingLayer::SAIL, tinfo);
|
updateNode(pos, EPathfindingLayer::SAIL, tinfo, false);
|
||||||
if(options.useFlying)
|
if(options.useFlying)
|
||||||
updateNode(pos, EPathfindingLayer::AIR, tinfo);
|
updateNode(pos, EPathfindingLayer::AIR, tinfo, true);
|
||||||
if(options.useWaterWalking)
|
if(options.useWaterWalking)
|
||||||
updateNode(pos, EPathfindingLayer::WATER, tinfo);
|
updateNode(pos, EPathfindingLayer::WATER, tinfo, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
updateNode(pos, EPathfindingLayer::LAND, tinfo);
|
updateNode(pos, EPathfindingLayer::LAND, tinfo, false);
|
||||||
if(options.useFlying)
|
if(options.useFlying)
|
||||||
updateNode(pos, EPathfindingLayer::AIR, tinfo);
|
updateNode(pos, EPathfindingLayer::AIR, tinfo, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,13 @@ private:
|
|||||||
/// Downside is less MP effective paths calculation.
|
/// Downside is less MP effective paths calculation.
|
||||||
bool lightweightFlyingMode;
|
bool lightweightFlyingMode;
|
||||||
|
|
||||||
|
/// This option enable one turn limitation for flying and water walking.
|
||||||
|
/// So if we're out of MP while cp is blocked or water tile we won't add dest tile to queue.
|
||||||
|
///
|
||||||
|
/// Following imitation is default H3 mechanics, but someone may want to disable it in mods.
|
||||||
|
/// After all this limit should benefit performance on maps with tons of water or blocked tiles.
|
||||||
|
bool oneTurnSpecialLayersLimit;
|
||||||
|
|
||||||
PathfinderOptions();
|
PathfinderOptions();
|
||||||
} options;
|
} options;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user