diff --git a/OpenRa.Game/PathSearch.cs b/OpenRa.Game/PathSearch.cs index 02561b8ace..b2a8ec43fc 100755 --- a/OpenRa.Game/PathSearch.cs +++ b/OpenRa.Game/PathSearch.cs @@ -14,7 +14,6 @@ namespace OpenRa public UnitMovementType umt; Func customBlock; public bool checkForBlocked; - public bool ignoreTerrain; public Actor ignoreBuilding; public PathSearch() @@ -40,9 +39,8 @@ namespace OpenRa var p = queue.Pop(); cellInfo[ p.Location.X, p.Location.Y ].Seen = true; - if (!ignoreTerrain) - if (passableCost[(int)umt][p.Location.X, p.Location.Y] == float.PositiveInfinity) - return p.Location; + if (passableCost[(int)umt][p.Location.X, p.Location.Y] == float.PositiveInfinity) + return p.Location; foreach( int2 d in Util.directions ) { @@ -51,17 +49,18 @@ namespace OpenRa if (!Game.world.Map.IsInMap(newHere.X, newHere.Y)) continue; if( cellInfo[ newHere.X, newHere.Y ].Seen ) continue; - - if (!ignoreTerrain) - { - if (passableCost[(int)umt][newHere.X, newHere.Y] == float.PositiveInfinity) - continue; - if (!Game.world.BuildingInfluence.CanMoveHere(newHere) && - Game.world.BuildingInfluence.GetBuildingAt(newHere) != ignoreBuilding) - continue; - if (Game.world.Map.IsOverlaySolid(newHere)) - continue; - } + + var custom = Game.world.customTerrain[newHere.X, newHere.Y]; + if (custom != null + && custom.GetCost(newHere, umt) == float.PositiveInfinity) + continue; + if (passableCost[(int)umt][newHere.X, newHere.Y] == float.PositiveInfinity) + continue; + if (!Game.world.BuildingInfluence.CanMoveHere(newHere) && + Game.world.BuildingInfluence.GetBuildingAt(newHere) != ignoreBuilding) + continue; + if (Game.world.Map.IsOverlaySolid(newHere)) + continue; // Replicate real-ra behavior of not being able to enter a cell if there is a mixture of crushable and uncrushable units if (checkForBlocked && (Game.world.UnitInfluence.GetUnitsAt(newHere).Any(a => !Game.world.IsActorPathableToCrush(a, umt)))) @@ -69,14 +68,15 @@ namespace OpenRa if (customBlock != null && customBlock(newHere)) continue; - var est = heuristic( newHere ); if( est == float.PositiveInfinity ) continue; - float cellCost = ( ( d.X * d.Y != 0 ) ? 1.414213563f : 1.0f ) * - (ignoreTerrain ? 1 : passableCost[ (int)umt ][ newHere.X, newHere.Y ]); + float cellCost = ((d.X * d.Y != 0) ? 1.414213563f : 1.0f) * + (custom != null + ? custom.GetCost(newHere, umt) : + passableCost[(int)umt][newHere.X, newHere.Y]); float newCost = cellInfo[ p.Location.X, p.Location.Y ].MinCost + cellCost; if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost ) diff --git a/OpenRa.Game/Traits/Bridge.cs b/OpenRa.Game/Traits/Bridge.cs index cda11d1923..f00434601e 100644 --- a/OpenRa.Game/Traits/Bridge.cs +++ b/OpenRa.Game/Traits/Bridge.cs @@ -9,12 +9,12 @@ using System.Drawing; namespace OpenRa.Traits { - class BridgeInfo : ITraitInfo + class BridgeInfo : OwnedActorInfo, ITraitInfo { public object Create(Actor self) { return new Bridge(self); } } - class Bridge : IRender, ITick, ICustomTerrain + class Bridge : IRender, ICustomTerrain { Dictionary Tiles; TileTemplate Template; @@ -34,8 +34,6 @@ namespace OpenRa.Traits yield return new Renderable(t.Value, Game.CellSize * t.Key, PaletteType.Gold); } - public void Tick(Actor self) {} - public void SetTiles(TileTemplate template, Dictionary replacedTiles) { Template = template; @@ -49,10 +47,10 @@ namespace OpenRa.Traits a => Sprites[new TileReference { tile = (ushort)template.Index, image = (byte)a.Value }]); } - public double GetCost(int2 p, UnitMovementType umt) + public float GetCost(int2 p, UnitMovementType umt) { var origTile = Tiles[p]; // if this explodes, then SetTiles did something horribly wrong. - return 1.0; + return float.PositiveInfinity; } } } diff --git a/OpenRa.Game/Traits/TraitsInterfaces.cs b/OpenRa.Game/Traits/TraitsInterfaces.cs index 51f401d358..ad2094dc40 100644 --- a/OpenRa.Game/Traits/TraitsInterfaces.cs +++ b/OpenRa.Game/Traits/TraitsInterfaces.cs @@ -25,7 +25,7 @@ namespace OpenRa.Traits public interface IAcceptThief { void OnSteal(Actor self, Actor thief); } public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); } - public interface ICustomTerrain { double GetCost(int2 p, UnitMovementType umt); } + public interface ICustomTerrain { float GetCost(int2 p, UnitMovementType umt); } interface IProducer {