diff --git a/OpenRA.Mods.Common/Pathfinder/PathGraph.cs b/OpenRA.Mods.Common/Pathfinder/PathGraph.cs index ea41e7b2d3..a55f849cf9 100644 --- a/OpenRA.Mods.Common/Pathfinder/PathGraph.cs +++ b/OpenRA.Mods.Common/Pathfinder/PathGraph.cs @@ -174,7 +174,7 @@ namespace OpenRA.Mods.Common.Pathfinder { var dir = directions[i]; var neighbor = position + dir; - var pathCost = GetPathCostToNode(neighbor, dir); + var pathCost = GetPathCostToNode(position, neighbor, dir); // PERF: Skip closed cells already, 15% of all cells if (pathCost != PathCostForInvalidPath && info[neighbor].Status != CellStatus.Closed) @@ -192,7 +192,7 @@ namespace OpenRA.Mods.Common.Pathfinder var layerPosition = new CPos(position.X, position.Y, cml.Index); var entryCost = cml.EntryMovementCost(locomotor.Info, layerPosition); if (entryCost != MovementCostForUnreachableCell && - CanEnterNode(layerPosition) && + CanEnterNode(position, layerPosition) && this[layerPosition].Status != CellStatus.Closed) validNeighbors.Add(new GraphConnection(layerPosition, entryCost)); } @@ -202,7 +202,7 @@ namespace OpenRA.Mods.Common.Pathfinder var layerPosition = new CPos(position.X, position.Y, 0); var exitCost = cmls[layer].ExitMovementCost(locomotor.Info, layerPosition); if (exitCost != MovementCostForUnreachableCell && - CanEnterNode(layerPosition) && + CanEnterNode(position, layerPosition) && this[layerPosition].Status != CellStatus.Closed) validNeighbors.Add(new GraphConnection(layerPosition, exitCost)); } @@ -210,16 +210,16 @@ namespace OpenRA.Mods.Common.Pathfinder return validNeighbors; } - bool CanEnterNode(CPos destNode) + bool CanEnterNode(CPos srcNode, CPos destNode) { return - locomotor.MovementCostToEnterCell(Actor, destNode, checkConditions, IgnoreActor) + locomotor.MovementCostToEnterCell(Actor, srcNode, destNode, checkConditions, IgnoreActor) != MovementCostForUnreachableCell; } - int GetPathCostToNode(CPos destNode, CVec direction) + int GetPathCostToNode(CPos srcNode, CPos destNode, CVec direction) { - var movementCost = locomotor.MovementCostToEnterCell(Actor, destNode, checkConditions, IgnoreActor); + var movementCost = locomotor.MovementCostToEnterCell(Actor, srcNode, destNode, checkConditions, IgnoreActor); if (movementCost != MovementCostForUnreachableCell && !(CustomBlock != null && CustomBlock(destNode))) return CalculateCellPathCost(destNode, direction, movementCost); @@ -242,15 +242,6 @@ namespace OpenRA.Mods.Common.Pathfinder cellCost += customCost; } - // Prevent units from jumping over height discontinuities - if (checkTerrainHeight && neighborCPos.Layer == 0) - { - var heightLayer = World.Map.Height; - var from = neighborCPos - direction; - if (Math.Abs(heightLayer[neighborCPos] - heightLayer[from]) > 1) - return PathCostForInvalidPath; - } - // Directional bonuses for smoother flow! if (LaneBias != 0) { diff --git a/OpenRA.Mods.Common/Traits/World/Locomotor.cs b/OpenRA.Mods.Common/Traits/World/Locomotor.cs index be665623f0..a0cc08abc5 100644 --- a/OpenRA.Mods.Common/Traits/World/Locomotor.cs +++ b/OpenRA.Mods.Common/Traits/World/Locomotor.cs @@ -171,10 +171,23 @@ namespace OpenRA.Mods.Common.Traits } public short MovementCostForCell(CPos cell) + { + return MovementCostForCell(cell, null); + } + + short MovementCostForCell(CPos cell, CPos? fromCell) { if (!world.Map.Contains(cell)) return PathGraph.MovementCostForUnreachableCell; + // Prevent units from jumping over height discontinuities. + if (fromCell != null && cell.Layer == 0 && fromCell.Value.Layer == 0 && world.Map.Grid.MaximumTerrainHeight > 0) + { + var heightLayer = world.Map.Height; + if (Math.Abs(heightLayer[cell] - heightLayer[fromCell.Value]) > 1) + return PathGraph.MovementCostForUnreachableCell; + } + return cellsCost[cell.Layer][cell]; } @@ -186,12 +199,9 @@ namespace OpenRA.Mods.Common.Traits return terrainInfos[index].Speed; } - public short MovementCostToEnterCell(Actor actor, CPos destNode, BlockedByActor check, Actor ignoreActor) + public short MovementCostToEnterCell(Actor actor, CPos srcNode, CPos destNode, BlockedByActor check, Actor ignoreActor) { - if (!world.Map.Contains(destNode)) - return PathGraph.MovementCostForUnreachableCell; - - var cellCost = cellsCost[destNode.Layer][destNode]; + var cellCost = MovementCostForCell(destNode, srcNode); if (cellCost == PathGraph.MovementCostForUnreachableCell || !CanMoveFreelyInto(actor, destNode, check, ignoreActor))