Make knowledge of height discontinuities live in Locomotor not PathGraph.

This commit is contained in:
RoosterDragon
2021-11-14 09:40:35 +00:00
committed by abcdefg30
parent 8c627aa185
commit f0e24f6d21
2 changed files with 22 additions and 21 deletions

View File

@@ -174,7 +174,7 @@ namespace OpenRA.Mods.Common.Pathfinder
{ {
var dir = directions[i]; var dir = directions[i];
var neighbor = position + dir; var neighbor = position + dir;
var pathCost = GetPathCostToNode(neighbor, dir); var pathCost = GetPathCostToNode(position, neighbor, dir);
// PERF: Skip closed cells already, 15% of all cells // PERF: Skip closed cells already, 15% of all cells
if (pathCost != PathCostForInvalidPath && info[neighbor].Status != CellStatus.Closed) 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 layerPosition = new CPos(position.X, position.Y, cml.Index);
var entryCost = cml.EntryMovementCost(locomotor.Info, layerPosition); var entryCost = cml.EntryMovementCost(locomotor.Info, layerPosition);
if (entryCost != MovementCostForUnreachableCell && if (entryCost != MovementCostForUnreachableCell &&
CanEnterNode(layerPosition) && CanEnterNode(position, layerPosition) &&
this[layerPosition].Status != CellStatus.Closed) this[layerPosition].Status != CellStatus.Closed)
validNeighbors.Add(new GraphConnection(layerPosition, entryCost)); 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 layerPosition = new CPos(position.X, position.Y, 0);
var exitCost = cmls[layer].ExitMovementCost(locomotor.Info, layerPosition); var exitCost = cmls[layer].ExitMovementCost(locomotor.Info, layerPosition);
if (exitCost != MovementCostForUnreachableCell && if (exitCost != MovementCostForUnreachableCell &&
CanEnterNode(layerPosition) && CanEnterNode(position, layerPosition) &&
this[layerPosition].Status != CellStatus.Closed) this[layerPosition].Status != CellStatus.Closed)
validNeighbors.Add(new GraphConnection(layerPosition, exitCost)); validNeighbors.Add(new GraphConnection(layerPosition, exitCost));
} }
@@ -210,16 +210,16 @@ namespace OpenRA.Mods.Common.Pathfinder
return validNeighbors; return validNeighbors;
} }
bool CanEnterNode(CPos destNode) bool CanEnterNode(CPos srcNode, CPos destNode)
{ {
return return
locomotor.MovementCostToEnterCell(Actor, destNode, checkConditions, IgnoreActor) locomotor.MovementCostToEnterCell(Actor, srcNode, destNode, checkConditions, IgnoreActor)
!= MovementCostForUnreachableCell; != 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))) if (movementCost != MovementCostForUnreachableCell && !(CustomBlock != null && CustomBlock(destNode)))
return CalculateCellPathCost(destNode, direction, movementCost); return CalculateCellPathCost(destNode, direction, movementCost);
@@ -242,15 +242,6 @@ namespace OpenRA.Mods.Common.Pathfinder
cellCost += customCost; 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! // Directional bonuses for smoother flow!
if (LaneBias != 0) if (LaneBias != 0)
{ {

View File

@@ -171,10 +171,23 @@ namespace OpenRA.Mods.Common.Traits
} }
public short MovementCostForCell(CPos cell) public short MovementCostForCell(CPos cell)
{
return MovementCostForCell(cell, null);
}
short MovementCostForCell(CPos cell, CPos? fromCell)
{ {
if (!world.Map.Contains(cell)) if (!world.Map.Contains(cell))
return PathGraph.MovementCostForUnreachableCell; 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]; return cellsCost[cell.Layer][cell];
} }
@@ -186,12 +199,9 @@ namespace OpenRA.Mods.Common.Traits
return terrainInfos[index].Speed; 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)) var cellCost = MovementCostForCell(destNode, srcNode);
return PathGraph.MovementCostForUnreachableCell;
var cellCost = cellsCost[destNode.Layer][destNode];
if (cellCost == PathGraph.MovementCostForUnreachableCell || if (cellCost == PathGraph.MovementCostForUnreachableCell ||
!CanMoveFreelyInto(actor, destNode, check, ignoreActor)) !CanMoveFreelyInto(actor, destNode, check, ignoreActor))