diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 7653a6cb5c..7769d2e422 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -182,7 +182,7 @@ namespace OpenRA.Traits { bool CanEnterCell(CPos location); bool CanEnterCell(CPos location, Actor ignoreActor, bool checkTransientActors); - void SetPosition(Actor self, CPos cell); + void SetPosition(Actor self, CPos cell, int subCell = -1); void SetPosition(Actor self, WPos pos); void SetVisualPosition(Actor self, WPos pos); } @@ -195,7 +195,7 @@ namespace OpenRA.Traits Activity MoveWithinRange(Target target, WRange range); Activity MoveWithinRange(Target target, WRange minRange, WRange maxRange); Activity MoveFollow(Actor self, Target target, WRange minRange, WRange maxRange); - Activity MoveIntoWorld(Actor self, CPos cell); + Activity MoveIntoWorld(Actor self, CPos cell, int subCell = -1); Activity VisualMove(Actor self, WPos fromPos, WPos toPos); CPos NearestMoveableCell(CPos target); bool IsMoving { get; set; } diff --git a/OpenRA.Game/Traits/World/ActorMap.cs b/OpenRA.Game/Traits/World/ActorMap.cs index 32f927a706..c4015d6e2b 100644 --- a/OpenRA.Game/Traits/World/ActorMap.cs +++ b/OpenRA.Game/Traits/World/ActorMap.cs @@ -88,8 +88,11 @@ namespace OpenRA.Traits return FreeSubCell(a) >= 0; } - public int FreeSubCell(CPos a) + public int FreeSubCell(CPos a, int preferredSubCell = -1) { + if (preferredSubCell >= 0 && !AnyUnitsAt(a, preferredSubCell)) + return preferredSubCell; + if (!AnyUnitsAt(a)) return map.SubCellDefaultIndex; diff --git a/OpenRA.Mods.RA/Air/Aircraft.cs b/OpenRA.Mods.RA/Air/Aircraft.cs index d13663c7c9..0451b06bde 100644 --- a/OpenRA.Mods.RA/Air/Aircraft.cs +++ b/OpenRA.Mods.RA/Air/Aircraft.cs @@ -170,7 +170,10 @@ namespace OpenRA.Mods.RA.Air } // Changes position, but not altitude - public void SetPosition(Actor self, CPos cell) { SetPosition(self, self.World.Map.CenterOfCell(cell) + new WVec(0, 0, CenterPosition.Z)); } + public void SetPosition(Actor self, CPos cell, int subCell = -1) + { + SetPosition(self, self.World.Map.CenterOfCell(cell) + new WVec(0, 0, CenterPosition.Z)); + } public void SetVisualPosition(Actor self, WPos pos) { SetPosition(self, pos); } public void AddedToWorld(Actor self) diff --git a/OpenRA.Mods.RA/Air/Helicopter.cs b/OpenRA.Mods.RA/Air/Helicopter.cs index c81a665e40..5f47f4a61e 100644 --- a/OpenRA.Mods.RA/Air/Helicopter.cs +++ b/OpenRA.Mods.RA/Air/Helicopter.cs @@ -148,7 +148,7 @@ namespace OpenRA.Mods.RA.Air public Activity MoveFollow(Actor self, Target target, WRange minRange, WRange maxRange) { return new Follow(self, target, minRange, maxRange); } public CPos NearestMoveableCell(CPos cell) { return cell; } - public Activity MoveIntoWorld(Actor self, CPos cell) + public Activity MoveIntoWorld(Actor self, CPos cell, int subCell = -1) { return new HeliFly(self, Target.FromCell(self.World, cell)); } diff --git a/OpenRA.Mods.RA/Air/Plane.cs b/OpenRA.Mods.RA/Air/Plane.cs index 20ea0929e9..a6c27f79c3 100644 --- a/OpenRA.Mods.RA/Air/Plane.cs +++ b/OpenRA.Mods.RA/Air/Plane.cs @@ -127,7 +127,7 @@ namespace OpenRA.Mods.RA.Air public Activity MoveFollow(Actor self, Target target, WRange minRange, WRange maxRange) { return new FlyFollow(self, target, minRange, maxRange); } public CPos NearestMoveableCell(CPos cell) { return cell; } - public Activity MoveIntoWorld(Actor self, CPos cell) { return new Fly(self, Target.FromCell(self.World, cell)); } + public Activity MoveIntoWorld(Actor self, CPos cell, int subCell = -1) { return new Fly(self, Target.FromCell(self.World, cell)); } public Activity VisualMove(Actor self, WPos fromPos, WPos toPos) { return Util.SequenceActivities(new CallFunc(() => SetVisualPosition(self, fromPos)), new Fly(self, Target.FromPos(toPos))); } } } diff --git a/OpenRA.Mods.RA/Crate.cs b/OpenRA.Mods.RA/Crate.cs index 1e90efc112..93bb2ac122 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -116,7 +116,7 @@ namespace OpenRA.Mods.RA public bool CanEnterCell(CPos cell) { return CanEnterCell(cell, null, true); } - public void SetPosition(Actor self, CPos cell) + public void SetPosition(Actor self, CPos cell, int subCell = -1) { self.World.ActorMap.RemoveInfluence(self, this); Location = cell; diff --git a/OpenRA.Mods.RA/Husk.cs b/OpenRA.Mods.RA/Husk.cs index eed63b2916..0619fa434c 100644 --- a/OpenRA.Mods.RA/Husk.cs +++ b/OpenRA.Mods.RA/Husk.cs @@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA } public bool CanEnterCell(CPos cell) { return CanEnterCell(cell, null, true); } - public void SetPosition(Actor self, CPos cell) { SetPosition(self, self.World.Map.CenterOfCell(cell)); } + public void SetPosition(Actor self, CPos cell, int subCell = -1) { SetPosition(self, self.World.Map.CenterOfCell(cell)); } public void SetVisualPosition(Actor self, WPos pos) { diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 6d3934a1e2..8fd1e6569c 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -258,10 +258,11 @@ namespace OpenRA.Mods.RA.Move SetVisualPosition(self, init.Get()); } - public void SetPosition(Actor self, CPos cell) + public void SetPosition(Actor self, CPos cell, int subCell = -1) { SetLocation(cell, fromSubCell, cell, fromSubCell); - SetVisualPosition(self, self.World.Map.CenterOfCell(fromCell) + self.World.Map.SubCellOffsets[fromSubCell]); + SetVisualPosition(self, self.World.Map.CenterOfCell(fromCell) + + self.World.Map.SubCellOffsets[subCell >= 0 ? subCell : fromSubCell]); FinishedMoving(self); } @@ -603,10 +604,16 @@ namespace OpenRA.Mods.RA.Move Nudge(self, blocking, true); } - public Activity MoveIntoWorld(Actor self, CPos cell) + public Activity MoveIntoWorld(Actor self, CPos cell, int subCell = -1) { var pos = self.CenterPosition; + subCell = self.World.ActorMap.FreeSubCell(cell, subCell); + + // TODO: solve/reduce cell is full problem + if (subCell < 0) + subCell = self.World.Map.SubCellDefaultIndex; + // Reserve the exit cell SetPosition(self, cell); SetVisualPosition(self, pos);