diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index a5e1a197c8..14976530ef 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -285,6 +285,7 @@ namespace OpenRA.Traits public interface IPositionable : IOccupySpace { + bool CanExistInCell(CPos location); bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any); bool CanEnterCell(CPos location, Actor ignoreActor = null, bool checkTransientActors = true); SubCell GetValidSubCell(SubCell preferred = SubCell.Any); diff --git a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs index 4505e4297a..534aae9f2e 100644 --- a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs +++ b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs @@ -154,6 +154,7 @@ namespace OpenRA.Mods.Cnc.Traits init.Add(new FacingInit(Facing)); } + public bool CanExistInCell(CPos cell) { return true; } public bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any) { return false; } public bool CanEnterCell(CPos cell, Actor ignoreActor = null, bool checkTransientActors = false) { return true; } public SubCell GetValidSubCell(SubCell preferred) { return SubCell.Invalid; } diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 19690d4cc8..93d1033f46 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -503,6 +503,7 @@ namespace OpenRA.Mods.Common.Traits #region Implement IPositionable + public bool CanExistInCell(CPos cell) { return true; } public bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any) { return false; } // TODO: Handle landing public bool CanEnterCell(CPos cell, Actor ignoreActor = null, bool checkTransientActors = true) { return true; } public SubCell GetValidSubCell(SubCell preferred) { return SubCell.Invalid; } diff --git a/OpenRA.Mods.Common/Traits/Crates/Crate.cs b/OpenRA.Mods.Common/Traits/Crates/Crate.cs index d5788d943f..7ce2a3ca89 100644 --- a/OpenRA.Mods.Common/Traits/Crates/Crate.cs +++ b/OpenRA.Mods.Common/Traits/Crates/Crate.cs @@ -44,13 +44,21 @@ namespace OpenRA.Mods.Common.Traits return GetAvailableSubCell(world, cell, ignoreActor, checkTransientActors) != SubCell.Invalid; } - public SubCell GetAvailableSubCell(World world, CPos cell, Actor ignoreActor = null, bool checkTransientActors = true) + public bool CanExistInCell(World world, CPos cell) { if (!world.Map.Contains(cell)) - return SubCell.Invalid; + return false; var type = world.Map.GetTerrainInfo(cell).Type; if (!TerrainTypes.Contains(type)) + return false; + + return true; + } + + public SubCell GetAvailableSubCell(World world, CPos cell, Actor ignoreActor = null, bool checkTransientActors = true) + { + if (!CanExistInCell(world, cell)) return SubCell.Invalid; if (world.WorldActor.Trait().GetBuildingAt(cell) != null) @@ -201,6 +209,8 @@ namespace OpenRA.Mods.Common.Traits return info.GetAvailableSubCell(self.World, cell, ignoreActor, checkTransientActors); } + public bool CanExistInCell(CPos cell) { return info.CanExistInCell(self.World, cell); } + public bool CanEnterCell(CPos a, Actor ignoreActor = null, bool checkTransientActors = true) { return GetAvailableSubCell(a, SubCell.Any, ignoreActor, checkTransientActors) != SubCell.Invalid; diff --git a/OpenRA.Mods.Common/Traits/Husk.cs b/OpenRA.Mods.Common/Traits/Husk.cs index 0ed8e3c0eb..3b97aa3cea 100644 --- a/OpenRA.Mods.Common/Traits/Husk.cs +++ b/OpenRA.Mods.Common/Traits/Husk.cs @@ -81,15 +81,23 @@ namespace OpenRA.Mods.Common.Traits self.QueueActivity(new Drag(self, CenterPosition, finalPosition, distance / dragSpeed)); } + public bool CanExistInCell(CPos cell) + { + if (!self.World.Map.Contains(cell)) + return false; + + if (!info.AllowedTerrain.Contains(self.World.Map.GetTerrainInfo(cell).Type)) + return false; + + return true; + } + public Pair[] OccupiedCells() { return new[] { Pair.New(TopLeft, SubCell.FullCell) }; } public bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any) { return false; } public SubCell GetValidSubCell(SubCell preferred = SubCell.Any) { return SubCell.FullCell; } public SubCell GetAvailableSubCell(CPos cell, SubCell preferredSubCell = SubCell.Any, Actor ignoreActor = null, bool checkTransientActors = true) { - if (!self.World.Map.Contains(cell)) - return SubCell.Invalid; - - if (!info.AllowedTerrain.Contains(self.World.Map.GetTerrainInfo(cell).Type)) + if (!CanExistInCell(cell)) return SubCell.Invalid; if (!checkTransientActors) diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index ba73549c16..eff3103a4b 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -687,6 +687,11 @@ namespace OpenRA.Mods.Common.Traits return Info.GetAvailableSubCell(self.World, self, a, preferredSubCell, ignoreActor, checkTransientActors ? CellConditions.All : CellConditions.None); } + public bool CanExistInCell(CPos cell) + { + return Info.MovementCostForCell(self.World, cell) != int.MaxValue; + } + public bool CanEnterCell(CPos cell, Actor ignoreActor = null, bool checkTransientActors = true) { return Info.CanEnterCell(self.World, self, cell, ignoreActor, checkTransientActors);