diff --git a/OpenRA.Mods.Common/Pathfinder/PathGraph.cs b/OpenRA.Mods.Common/Pathfinder/PathGraph.cs index 4336184890..6d643161d8 100644 --- a/OpenRA.Mods.Common/Pathfinder/PathGraph.cs +++ b/OpenRA.Mods.Common/Pathfinder/PathGraph.cs @@ -71,6 +71,7 @@ namespace OpenRA.Mods.Common.Pathfinder readonly CellConditions checkConditions; readonly MobileInfo mobileInfo; + readonly MobileInfo.WorldMovementInfo worldMovementInfo; CellLayer cellInfo; public PathGraph(CellLayer cellInfo, MobileInfo mobileInfo, Actor actor, World world, bool checkForBlocked) @@ -78,6 +79,7 @@ namespace OpenRA.Mods.Common.Pathfinder this.cellInfo = cellInfo; World = world; this.mobileInfo = mobileInfo; + worldMovementInfo = mobileInfo.GetWorldMovementInfo(world); Actor = actor; LaneBias = 1; checkConditions = checkForBlocked ? CellConditions.TransientActors : CellConditions.None; @@ -123,17 +125,9 @@ namespace OpenRA.Mods.Common.Pathfinder int GetCostToNode(CPos destNode, CVec direction) { - int movementCost; - if (mobileInfo.CanEnterCell( - World, - Actor, - destNode, - out movementCost, - IgnoredActor, - checkConditions) && !(CustomBlock != null && CustomBlock(destNode))) - { + var movementCost = mobileInfo.MovementCostToEnterCell(worldMovementInfo, Actor, destNode, IgnoredActor, checkConditions); + if (movementCost != int.MaxValue && !(CustomBlock != null && CustomBlock(destNode))) return CalculateCellCost(destNode, direction, movementCost); - } return Constants.InvalidNode; } diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 91351f3697..b3249393db 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -125,6 +125,17 @@ namespace OpenRA.Mods.Common.Traits } } + public struct WorldMovementInfo + { + internal readonly World World; + internal readonly TerrainInfo[] TerrainInfos; + internal WorldMovementInfo(World world, MobileInfo info) + { + World = world; + TerrainInfos = info.TilesetTerrainInfo[world.TileSet]; + } + } + public readonly Cache TilesetTerrainInfo; public readonly Cache TilesetMovementClass; @@ -136,14 +147,19 @@ namespace OpenRA.Mods.Common.Traits public int MovementCostForCell(World world, CPos cell) { - if (!world.Map.Contains(cell)) + return MovementCostForCell(world.Map, TilesetTerrainInfo[world.TileSet], cell); + } + + int MovementCostForCell(Map map, TerrainInfo[] terrainInfos, CPos cell) + { + if (!map.Contains(cell)) return int.MaxValue; - var index = world.Map.GetTerrainIndex(cell); + var index = map.GetTerrainIndex(cell); if (index == byte.MaxValue) return int.MaxValue; - return TilesetTerrainInfo[world.TileSet][index].Cost; + return terrainInfos[index].Cost; } public int CalculateTilesetMovementClass(TileSet tileset) @@ -236,12 +252,17 @@ namespace OpenRA.Mods.Common.Traits return false; } - public bool CanEnterCell(World world, Actor self, CPos cell, out int movementCost, Actor ignoreActor = null, CellConditions check = CellConditions.All) + public WorldMovementInfo GetWorldMovementInfo(World world) { - if ((movementCost = MovementCostForCell(world, cell)) == int.MaxValue) - return false; + return new WorldMovementInfo(world, this); + } - return CanMoveFreelyInto(world, self, cell, ignoreActor, check); + public int MovementCostToEnterCell(WorldMovementInfo worldMovementInfo, Actor self, CPos cell, Actor ignoreActor = null, CellConditions check = CellConditions.All) + { + var cost = MovementCostForCell(worldMovementInfo.World.Map, worldMovementInfo.TerrainInfos, cell); + if (cost == int.MaxValue || !CanMoveFreelyInto(worldMovementInfo.World, self, cell, ignoreActor, check)) + return int.MaxValue; + return cost; } public SubCell GetAvailableSubCell(