From ff7ad53dee1c96c793f2ac1812e128d8d195bf3f Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Fri, 8 Aug 2014 14:27:54 -0500 Subject: [PATCH] Fixed UnloadCargo stacking using new subcell API exposure --- OpenRA.Game/Traits/Target.cs | 6 +++++- OpenRA.Game/Traits/TraitsInterfaces.cs | 1 + OpenRA.Mods.RA/Activities/UnloadCargo.cs | 20 +++++++++++++------- OpenRA.Mods.RA/Air/Aircraft.cs | 3 ++- OpenRA.Mods.RA/Crate.cs | 1 + OpenRA.Mods.RA/Husk.cs | 1 + OpenRA.Mods.RA/Move/Mobile.cs | 7 ++++--- OpenRA.Mods.RA/Move/Move.cs | 8 ++++++++ 8 files changed, 35 insertions(+), 12 deletions(-) diff --git a/OpenRA.Game/Traits/Target.cs b/OpenRA.Game/Traits/Target.cs index de6994bd5f..0f9d8873ce 100644 --- a/OpenRA.Game/Traits/Target.cs +++ b/OpenRA.Game/Traits/Target.cs @@ -28,7 +28,11 @@ namespace OpenRA.Traits int generation; public static Target FromPos(WPos p) { return new Target { pos = p, type = TargetType.Terrain }; } - public static Target FromCell(World w, CPos c) { return new Target { pos = w.Map.CenterOfCell(c), type = TargetType.Terrain }; } + public static Target FromCell(World w, CPos c, int subCell = 0) + { + return new Target { pos = w.Map.CenterOfCell(c) + w.Map.SubCellOffsets[subCell], type = TargetType.Terrain }; + } + public static Target FromOrder(World w, Order o) { return o.TargetActor != null diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 7769d2e422..74ba23fa9f 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -182,6 +182,7 @@ namespace OpenRA.Traits { bool CanEnterCell(CPos location); bool CanEnterCell(CPos location, Actor ignoreActor, bool checkTransientActors); + int GetDesiredSubcell(CPos a, Actor ignoreActor); void SetPosition(Actor self, CPos cell, int subCell = -1); void SetPosition(Actor self, WPos pos); void SetVisualPosition(Actor self, WPos pos); diff --git a/OpenRA.Mods.RA/Activities/UnloadCargo.cs b/OpenRA.Mods.RA/Activities/UnloadCargo.cs index 8e4de044a9..fb4f68ec4f 100644 --- a/OpenRA.Mods.RA/Activities/UnloadCargo.cs +++ b/OpenRA.Mods.RA/Activities/UnloadCargo.cs @@ -11,6 +11,8 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; +using OpenRA.Mods.RA.Move; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities @@ -30,14 +32,15 @@ namespace OpenRA.Mods.RA.Activities this.unloadAll = unloadAll; } - public CPos? ChooseExitCell(Actor passenger) + public Pair? ChooseExitSubCell(Actor passenger) { var pos = passenger.Trait(); return cargo.CurrentAdjacentCells .Shuffle(self.World.SharedRandom) - .Cast() - .FirstOrDefault(c => pos.CanEnterCell(c.Value)); + .Select(c => Pair.New(c, pos.GetDesiredSubcell(c, null))) + .Cast?>() + .FirstOrDefault(s => s.Value.Second >= 0); } IEnumerable BlockedExitCells(Actor passenger) @@ -60,8 +63,8 @@ namespace OpenRA.Mods.RA.Activities var actor = cargo.Peek(self); var spawn = self.CenterPosition; - var exitCell = ChooseExitCell(actor); - if (exitCell == null) + var exitSubCell = ChooseExitSubCell(actor); + if (exitSubCell == null) { foreach (var blocker in BlockedExitCells(actor).SelectMany(p => self.World.ActorMap.GetUnitsAt(p))) { @@ -83,8 +86,11 @@ namespace OpenRA.Mods.RA.Activities w.Add(actor); actor.CancelActivity(); pos.SetVisualPosition(actor, spawn); - actor.QueueActivity(move.MoveIntoWorld(actor, exitCell.Value)); - actor.SetTargetLine(Target.FromCell(w, exitCell.Value), Color.Green, false); + var mobile = move as Mobile; + if (mobile != null) + mobile.SetLocation(exitSubCell.Value.First, exitSubCell.Value.Second, exitSubCell.Value.First, exitSubCell.Value.Second); + actor.QueueActivity(move.MoveIntoWorld(actor, exitSubCell.Value.First, exitSubCell.Value.Second)); + actor.SetTargetLine(Target.FromCell(w, exitSubCell.Value.First, exitSubCell.Value.Second), Color.Green, false); }); if (!unloadAll || cargo.IsEmpty(self)) diff --git a/OpenRA.Mods.RA/Air/Aircraft.cs b/OpenRA.Mods.RA/Air/Aircraft.cs index 0451b06bde..687f62d166 100644 --- a/OpenRA.Mods.RA/Air/Aircraft.cs +++ b/OpenRA.Mods.RA/Air/Aircraft.cs @@ -198,7 +198,8 @@ namespace OpenRA.Mods.RA.Air return info.RearmBuildings.Contains(a.Info.Name) || info.RepairBuildings.Contains(a.Info.Name); } - + + public int GetDesiredSubcell(CPos a, Actor ignoreActor) { return -1; } // does not use any subcell public bool CanEnterCell(CPos location) { return true; } public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors) { return true; } diff --git a/OpenRA.Mods.RA/Crate.cs b/OpenRA.Mods.RA/Crate.cs index 93bb2ac122..599b27c90a 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -114,6 +114,7 @@ namespace OpenRA.Mods.RA .Any(); } + public int GetDesiredSubcell(CPos a, Actor ignoreActor) { return CanEnterCell(a, ignoreActor, true) ? 0 : -1; } public bool CanEnterCell(CPos cell) { return CanEnterCell(cell, null, true); } public void SetPosition(Actor self, CPos cell, int subCell = -1) diff --git a/OpenRA.Mods.RA/Husk.cs b/OpenRA.Mods.RA/Husk.cs index 0619fa434c..d4d1c366a6 100644 --- a/OpenRA.Mods.RA/Husk.cs +++ b/OpenRA.Mods.RA/Husk.cs @@ -69,6 +69,7 @@ namespace OpenRA.Mods.RA .Any(); } + public int GetDesiredSubcell(CPos a, Actor ignoreActor) { return CanEnterCell(a, ignoreActor, true) ? 0 : -1; } public bool CanEnterCell(CPos cell) { return CanEnterCell(cell, null, true); } public void SetPosition(Actor self, CPos cell, int subCell = -1) { SetPosition(self, self.World.Map.CenterOfCell(cell)); } diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index f768946088..e0283487d0 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -627,18 +627,19 @@ namespace OpenRA.Mods.RA.Move { var pos = self.CenterPosition; - subCell = self.World.ActorMap.FreeSubCell(cell, subCell); + if (subCell == -1) + 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); + SetPosition(self, cell, subCell); SetVisualPosition(self, pos); // Animate transition - var to = self.World.Map.CenterOfCell(cell); + var to = self.World.Map.CenterOfCell(cell) + self.World.Map.SubCellOffsets[subCell]; var speed = MovementSpeedForCell(self, cell); var length = speed > 0 ? (to - pos).Length / speed : 0; diff --git a/OpenRA.Mods.RA/Move/Move.cs b/OpenRA.Mods.RA/Move/Move.cs index 73e4d21c9c..1cd3c83c7c 100755 --- a/OpenRA.Mods.RA/Move/Move.cs +++ b/OpenRA.Mods.RA/Move/Move.cs @@ -57,6 +57,14 @@ namespace OpenRA.Mods.RA.Move this.nearEnough = nearEnough; } + public Move(CPos destination, int subCell, WRange nearEnough) + { + this.getPath = (self, mobile) => self.World.WorldActor.Trait() + .FindUnitPathToRange(mobile.fromCell, subCell, self.World.Map.CenterOfCell(destination) + self.World.Map.SubCellOffsets[subCell], nearEnough, self); + this.destination = destination; + this.nearEnough = nearEnough; + } + public Move(CPos destination, Actor ignoreBuilding) { this.getPath = (self, mobile) =>