diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 570ea1ea4d..301d162542 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -158,7 +158,12 @@ namespace OpenRA.Traits public interface IRadarColorModifier { Color RadarColorOverride(Actor self); } - public interface IOccupySpaceInfo : ITraitInfo { } + public interface IOccupySpaceInfo : ITraitInfo + { + IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any); + bool SharesCell { get; } + } + public interface IOccupySpace { WPos CenterPosition { get; } diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index b5c920d19d..fbe23c3a0b 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -43,6 +43,9 @@ namespace OpenRA.Mods.Common.Traits public virtual object Create(ActorInitializer init) { return new Aircraft(init, this); } public int GetInitialFacing() { return InitialFacing; } public WRange GetCruiseAltitude() { return CruiseAltitude; } + + public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary(); } + bool IOccupySpaceInfo.SharesCell { get { return false; } } } public class Aircraft : IFacing, IPositionable, ISync, INotifyKilled, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld diff --git a/OpenRA.Mods.Common/Traits/Buildings/Building.cs b/OpenRA.Mods.Common/Traits/Buildings/Building.cs index 4985072538..59984719ce 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Building.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Building.cs @@ -104,6 +104,16 @@ namespace OpenRA.Mods.Common.Traits .Any(b => Math.Abs(a.X - b.X) <= Adjacent && Math.Abs(a.Y - b.Y) <= Adjacent)); } + + public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos topLeft, SubCell subCell = SubCell.Any) + { + var occupied = FootprintUtils.UnpathableTiles(info.Name, this, topLeft) + .ToDictionary(c => c, c => SubCell.FullCell); + + return new ReadOnlyDictionary(occupied); + } + + bool IOccupySpaceInfo.SharesCell { get { return false; } } } public class Building : IOccupySpace, INotifySold, INotifyTransform, ISync, INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld diff --git a/OpenRA.Mods.Common/Traits/Crates/Crate.cs b/OpenRA.Mods.Common/Traits/Crates/Crate.cs index 3ab80b2234..aef7c0ff83 100644 --- a/OpenRA.Mods.Common/Traits/Crates/Crate.cs +++ b/OpenRA.Mods.Common/Traits/Crates/Crate.cs @@ -28,6 +28,14 @@ namespace OpenRA.Mods.Common.Traits public readonly string CrushClass = "crate"; public object Create(ActorInitializer init) { return new Crate(init, this); } + + public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) + { + var occupied = new Dictionary() { { location, SubCell.FullCell } }; + return new ReadOnlyDictionary(occupied); + } + + bool IOccupySpaceInfo.SharesCell { get { return false; } } } class Crate : ITick, IPositionable, ICrushable, ISync, INotifyParachuteLanded, INotifyAddedToWorld, INotifyRemovedFromWorld diff --git a/OpenRA.Mods.Common/Traits/Husk.cs b/OpenRA.Mods.Common/Traits/Husk.cs index 14c5e6eeb3..00cfdc4d87 100644 --- a/OpenRA.Mods.Common/Traits/Husk.cs +++ b/OpenRA.Mods.Common/Traits/Husk.cs @@ -24,6 +24,14 @@ namespace OpenRA.Mods.Common.Traits public object Create(ActorInitializer init) { return new Husk(init, this); } public int GetInitialFacing() { return 128; } + + public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) + { + var occupied = new Dictionary() { { location, SubCell.FullCell } }; + return new ReadOnlyDictionary(occupied); + } + + bool IOccupySpaceInfo.SharesCell { get { return false; } } } public class Husk : IPositionable, IFacing, ISync, INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, IDisable diff --git a/OpenRA.Mods.Common/Traits/Immobile.cs b/OpenRA.Mods.Common/Traits/Immobile.cs index 043d306cef..be0ea75bbd 100644 --- a/OpenRA.Mods.Common/Traits/Immobile.cs +++ b/OpenRA.Mods.Common/Traits/Immobile.cs @@ -18,6 +18,16 @@ namespace OpenRA.Mods.Common.Traits { public readonly bool OccupiesSpace = true; public object Create(ActorInitializer init) { return new Immobile(init, this); } + + public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) + { + var occupied = OccupiesSpace ? new Dictionary() { { location, SubCell.FullCell } } : + new Dictionary(); + + return new ReadOnlyDictionary(occupied); + } + + bool IOccupySpaceInfo.SharesCell { get { return false; } } } class Immobile : IOccupySpace, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 28c69392ac..87509573b4 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -295,6 +295,13 @@ namespace OpenRA.Mods.Common.Traits } public int GetInitialFacing() { return InitialFacing; } + + public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) + { + return new ReadOnlyDictionary(new Dictionary() { { location, subCell } }); + } + + bool IOccupySpaceInfo.SharesCell { get { return SharesCell; } } } public class Mobile : IIssueOrder, IResolveOrder, IOrderVoice, IPositionable, IMove, IFacing, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove diff --git a/OpenRA.Mods.RA/Traits/Mine.cs b/OpenRA.Mods.RA/Traits/Mine.cs index 5abd3e0ede..6e27882fc0 100644 --- a/OpenRA.Mods.RA/Traits/Mine.cs +++ b/OpenRA.Mods.RA/Traits/Mine.cs @@ -14,7 +14,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Traits { - class MineInfo : ITraitInfo, IOccupySpaceInfo + class MineInfo : ITraitInfo { public readonly string[] CrushClasses = { }; public readonly bool AvoidFriendly = true;