diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 3f7d5e079e..73b9de1e94 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -81,11 +81,21 @@ namespace OpenRA.Traits { int2 PxPosition { get; } } + + public enum SubCell + { + FullCell, + TopLeft, + TopRight, + Center, + BottomLeft, + BottomRight + } public interface IOccupySpace : IHasLocation { int2 TopLeft { get; } - IEnumerable OccupiedCells(); + IEnumerable> OccupiedCells(); } public static class IOccupySpaceExts @@ -96,10 +106,10 @@ namespace OpenRA.Traits var nearestDistance = int.MaxValue; foreach( var cell in ios.OccupiedCells() ) { - var dist = ( other - cell ).LengthSquared; + var dist = ( other - cell.First ).LengthSquared; if( dist < nearestDistance ) { - nearest = cell; + nearest = cell.First; nearestDistance = dist; } } diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index bd371a7bdd..8ef65361e5 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -136,7 +136,7 @@ namespace OpenRA.Traits if (ios != null) { var cells = ios.OccupiedCells(); - if (cells.Any()) return cells; + if (cells.Any()) return cells.Select(c => c.First); } return new[] { a.CenterLocation / Game.CellSize }; diff --git a/OpenRA.Game/Traits/World/UnitInfluence.cs b/OpenRA.Game/Traits/World/UnitInfluence.cs index 9617c72901..9d7c776b69 100644 --- a/OpenRA.Game/Traits/World/UnitInfluence.cs +++ b/OpenRA.Game/Traits/World/UnitInfluence.cs @@ -26,9 +26,10 @@ namespace OpenRA.Traits class InfluenceNode { public InfluenceNode next; + public SubCell subCell; public Actor actor; } - + InfluenceNode[,] influence; Map map; @@ -51,21 +52,32 @@ namespace OpenRA.Traits public bool AnyUnitsAt(int2 a) { - return /*map.IsInMap(a) && */influence[ a.X, a.Y ] != null; + return influence[ a.X, a.Y ] != null; + } + + public bool AnyUnitsAt(int2 a, SubCell sub) + { + var node = influence[ a.X, a.Y ]; + while (node != null) + { + if (node.subCell == sub) return true; + node = node.next; + } + return false; } public void Add( Actor self, IOccupySpace unit ) { if (unit != null) foreach( var c in unit.OccupiedCells() ) - influence[ c.X, c.Y ] = new InfluenceNode { next = influence[ c.X, c.Y ], actor = self }; + influence[ c.First.X, c.First.Y ] = new InfluenceNode { next = influence[ c.First.X, c.First.Y ], subCell = c.Second, actor = self }; } public void Remove( Actor self, IOccupySpace unit ) { if (unit != null) foreach (var c in unit.OccupiedCells()) - RemoveInner( ref influence[ c.X, c.Y ], self ); + RemoveInner( ref influence[ c.First.X, c.First.Y ], self ); } void RemoveInner( ref InfluenceNode influenceNode, Actor toRemove ) diff --git a/OpenRA.Mods.RA/Activities/CaptureBuilding.cs b/OpenRA.Mods.RA/Activities/CaptureBuilding.cs index 27a6b0a7e0..ae719d5cbe 100644 --- a/OpenRA.Mods.RA/Activities/CaptureBuilding.cs +++ b/OpenRA.Mods.RA/Activities/CaptureBuilding.cs @@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Activities if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; if (target.Owner == self.Owner) return NextActivity; - if( !target.Trait().OccupiedCells().Any( x => x == self.Location ) ) + if( !target.Trait().OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; // todo: clean this up diff --git a/OpenRA.Mods.RA/Activities/Demolish.cs b/OpenRA.Mods.RA/Activities/Demolish.cs index 616ec96eaf..506be2da10 100644 --- a/OpenRA.Mods.RA/Activities/Demolish.cs +++ b/OpenRA.Mods.RA/Activities/Demolish.cs @@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Activities if (IsCanceled) return NextActivity; if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; - if( !target.Trait().OccupiedCells().Any( x => x == self.Location ) ) + if( !target.Trait().OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; self.World.AddFrameEndTask(w => w.Add(new DelayedAction(25 * 2, diff --git a/OpenRA.Mods.RA/Activities/Infiltrate.cs b/OpenRA.Mods.RA/Activities/Infiltrate.cs index 21b34ec97d..ddc4490526 100644 --- a/OpenRA.Mods.RA/Activities/Infiltrate.cs +++ b/OpenRA.Mods.RA/Activities/Infiltrate.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; if (target.Owner == self.Owner) return NextActivity; - if( !target.Trait().OccupiedCells().Any( x => x == self.Location ) ) + if( !target.Trait().OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; foreach (var t in target.TraitsImplementing()) diff --git a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs index 4d6220f204..3cf7266aea 100755 --- a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs +++ b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs @@ -39,8 +39,8 @@ namespace OpenRA.Mods.RA.Activities }; foreach( var cell in target.Trait().OccupiedCells() ) { - ps1.AddInitialCell( cell ); - if( ( mobile.toCell - cell ).LengthSquared <= 2 ) + ps1.AddInitialCell( cell.First ); + if( ( mobile.toCell - cell.First ).LengthSquared <= 2 ) return NextActivity; } ps1.heuristic = PathSearch.DefaultEstimator( mobile.toCell ); diff --git a/OpenRA.Mods.RA/Activities/RepairBuilding.cs b/OpenRA.Mods.RA/Activities/RepairBuilding.cs index 0ce0c28286..b8f0a0f814 100644 --- a/OpenRA.Mods.RA/Activities/RepairBuilding.cs +++ b/OpenRA.Mods.RA/Activities/RepairBuilding.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA.Activities { if (IsCanceled) return NextActivity; if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; - if( !target.Trait().OccupiedCells().Any( x => x == self.Location ) ) + if( !target.Trait().OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; var health = target.Trait(); diff --git a/OpenRA.Mods.RA/Air/Aircraft.cs b/OpenRA.Mods.RA/Air/Aircraft.cs index fab016cd05..0178a72538 100755 --- a/OpenRA.Mods.RA/Air/Aircraft.cs +++ b/OpenRA.Mods.RA/Air/Aircraft.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA.Air { @@ -135,8 +136,8 @@ namespace OpenRA.Mods.RA.Air } } - int2[] noCells = new int2[] { }; - public IEnumerable OccupiedCells() { return noCells; } + Pair[] noCells = new Pair[] { }; + public IEnumerable> OccupiedCells() { return noCells; } public void TickMove( int speed, int facing ) { diff --git a/OpenRA.Mods.RA/AppearsOnRadar.cs b/OpenRA.Mods.RA/AppearsOnRadar.cs index e64371f5d0..49d5f74394 100755 --- a/OpenRA.Mods.RA/AppearsOnRadar.cs +++ b/OpenRA.Mods.RA/AppearsOnRadar.cs @@ -36,7 +36,7 @@ namespace OpenRA.Mods.RA { if (Space == null) Space = self.Trait(); - return Space.OccupiedCells(); + return Space.OccupiedCells().Select(c => c.First); } } diff --git a/OpenRA.Mods.RA/Buildings/Building.cs b/OpenRA.Mods.RA/Buildings/Building.cs index 9d8dd849e8..f0ee97001b 100755 --- a/OpenRA.Mods.RA/Buildings/Building.cs +++ b/OpenRA.Mods.RA/Buildings/Building.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA.Buildings { @@ -110,9 +111,9 @@ namespace OpenRA.Mods.RA.Buildings get { return topLeft; } } - public IEnumerable OccupiedCells() + public IEnumerable> OccupiedCells() { - return FootprintUtils.UnpathableTiles( self.Info.Name, Info, TopLeft ); + return FootprintUtils.UnpathableTiles( self.Info.Name, Info, TopLeft ).Select(c => Pair.New(c, SubCell.FullCell)); } public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner) diff --git a/OpenRA.Mods.RA/Crate.cs b/OpenRA.Mods.RA/Crate.cs index 2098e5d4cd..50fdf9b603 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -80,7 +80,7 @@ namespace OpenRA.Mods.RA } public int2 TopLeft { get { return Location; } } - public IEnumerable OccupiedCells() { return new int2[] { Location }; } + public IEnumerable> OccupiedCells() { yield return Pair.New( Location, SubCell.FullCell); } public int2 PxPosition { get; private set; } diff --git a/OpenRA.Mods.RA/Husk.cs b/OpenRA.Mods.RA/Husk.cs index b318ec7d00..a44d1acff1 100644 --- a/OpenRA.Mods.RA/Husk.cs +++ b/OpenRA.Mods.RA/Husk.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA { @@ -36,7 +37,7 @@ namespace OpenRA.Mods.RA public int2 TopLeft { get { return location; } } - public IEnumerable OccupiedCells() { yield return TopLeft; } + public IEnumerable> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); } public int2 PxPosition { get { return Util.CenterOfCell( location ); } } } } diff --git a/OpenRA.Mods.RA/Mine.cs b/OpenRA.Mods.RA/Mine.cs index 524f800422..8e0492bbe0 100644 --- a/OpenRA.Mods.RA/Mine.cs +++ b/OpenRA.Mods.RA/Mine.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using OpenRA.Mods.RA.Activities; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA { @@ -53,7 +54,7 @@ namespace OpenRA.Mods.RA public int2 TopLeft { get { return location; } } - public IEnumerable OccupiedCells() { yield return TopLeft; } + public IEnumerable> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); } public int2 PxPosition { get { return Util.CenterOfCell( location ); } } } diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 2dd0c2d35f..4b8fd4df4e 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -271,13 +271,17 @@ namespace OpenRA.Mods.RA.Move public int2 TopLeft { get { return toCell; } } - public IEnumerable OccupiedCells() + public IEnumerable> OccupiedCells() { - return (fromCell == toCell) - ? new[] { fromCell } - : CanEnterCell(toCell) - ? new[] { toCell } - : new[] { fromCell, toCell }; + if (fromCell == toCell) + yield return Pair.New(fromCell, SubCell.FullCell); + else if (CanEnterCell(toCell)) + yield return Pair.New(toCell, SubCell.FullCell); + else + { + yield return Pair.New(fromCell, SubCell.FullCell); + yield return Pair.New(toCell, SubCell.FullCell); + } } public bool CanEnterCell(int2 p) diff --git a/OpenRA.Mods.RA/TargetableBuilding.cs b/OpenRA.Mods.RA/TargetableBuilding.cs index e27801bd8d..76ca9d6390 100755 --- a/OpenRA.Mods.RA/TargetableBuilding.cs +++ b/OpenRA.Mods.RA/TargetableBuilding.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using OpenRA.Mods.RA.Buildings; using OpenRA.Traits; +using System.Linq; namespace OpenRA.Mods.RA { @@ -32,7 +33,7 @@ namespace OpenRA.Mods.RA public bool TargetableBy(Actor self, Actor byActor) { return true; } public IEnumerable TargetableCells( Actor self ) { - return self.Trait().OccupiedCells(); + return self.Trait().OccupiedCells().Select(c => c.First); } } }