Fixed UnloadCargo stacking using new subcell API exposure

This commit is contained in:
atlimit8
2014-08-08 14:27:54 -05:00
parent 9efcf231e1
commit ff7ad53dee
8 changed files with 35 additions and 12 deletions

View File

@@ -28,7 +28,11 @@ namespace OpenRA.Traits
int generation; int generation;
public static Target FromPos(WPos p) { return new Target { pos = p, type = TargetType.Terrain }; } 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) public static Target FromOrder(World w, Order o)
{ {
return o.TargetActor != null return o.TargetActor != null

View File

@@ -182,6 +182,7 @@ namespace OpenRA.Traits
{ {
bool CanEnterCell(CPos location); bool CanEnterCell(CPos location);
bool CanEnterCell(CPos location, Actor ignoreActor, bool checkTransientActors); 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, CPos cell, int subCell = -1);
void SetPosition(Actor self, WPos pos); void SetPosition(Actor self, WPos pos);
void SetVisualPosition(Actor self, WPos pos); void SetVisualPosition(Actor self, WPos pos);

View File

@@ -11,6 +11,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using OpenRA.Mods.RA.Move;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities namespace OpenRA.Mods.RA.Activities
@@ -30,14 +32,15 @@ namespace OpenRA.Mods.RA.Activities
this.unloadAll = unloadAll; this.unloadAll = unloadAll;
} }
public CPos? ChooseExitCell(Actor passenger) public Pair<CPos, int>? ChooseExitSubCell(Actor passenger)
{ {
var pos = passenger.Trait<IPositionable>(); var pos = passenger.Trait<IPositionable>();
return cargo.CurrentAdjacentCells return cargo.CurrentAdjacentCells
.Shuffle(self.World.SharedRandom) .Shuffle(self.World.SharedRandom)
.Cast<CPos?>() .Select(c => Pair.New(c, pos.GetDesiredSubcell(c, null)))
.FirstOrDefault(c => pos.CanEnterCell(c.Value)); .Cast<Pair<CPos, int>?>()
.FirstOrDefault(s => s.Value.Second >= 0);
} }
IEnumerable<CPos> BlockedExitCells(Actor passenger) IEnumerable<CPos> BlockedExitCells(Actor passenger)
@@ -60,8 +63,8 @@ namespace OpenRA.Mods.RA.Activities
var actor = cargo.Peek(self); var actor = cargo.Peek(self);
var spawn = self.CenterPosition; var spawn = self.CenterPosition;
var exitCell = ChooseExitCell(actor); var exitSubCell = ChooseExitSubCell(actor);
if (exitCell == null) if (exitSubCell == null)
{ {
foreach (var blocker in BlockedExitCells(actor).SelectMany(p => self.World.ActorMap.GetUnitsAt(p))) 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); w.Add(actor);
actor.CancelActivity(); actor.CancelActivity();
pos.SetVisualPosition(actor, spawn); pos.SetVisualPosition(actor, spawn);
actor.QueueActivity(move.MoveIntoWorld(actor, exitCell.Value)); var mobile = move as Mobile;
actor.SetTargetLine(Target.FromCell(w, exitCell.Value), Color.Green, false); 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)) if (!unloadAll || cargo.IsEmpty(self))

View File

@@ -198,7 +198,8 @@ namespace OpenRA.Mods.RA.Air
return info.RearmBuildings.Contains(a.Info.Name) return info.RearmBuildings.Contains(a.Info.Name)
|| info.RepairBuildings.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 location) { return true; }
public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors) { return true; } public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors) { return true; }

View File

@@ -114,6 +114,7 @@ namespace OpenRA.Mods.RA
.Any(); .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 bool CanEnterCell(CPos cell) { return CanEnterCell(cell, null, true); }
public void SetPosition(Actor self, CPos cell, int subCell = -1) public void SetPosition(Actor self, CPos cell, int subCell = -1)

View File

@@ -69,6 +69,7 @@ namespace OpenRA.Mods.RA
.Any(); .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 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)); } public void SetPosition(Actor self, CPos cell, int subCell = -1) { SetPosition(self, self.World.Map.CenterOfCell(cell)); }

View File

@@ -627,18 +627,19 @@ namespace OpenRA.Mods.RA.Move
{ {
var pos = self.CenterPosition; 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 // TODO: solve/reduce cell is full problem
if (subCell < 0) if (subCell < 0)
subCell = self.World.Map.SubCellDefaultIndex; subCell = self.World.Map.SubCellDefaultIndex;
// Reserve the exit cell // Reserve the exit cell
SetPosition(self, cell); SetPosition(self, cell, subCell);
SetVisualPosition(self, pos); SetVisualPosition(self, pos);
// Animate transition // 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 speed = MovementSpeedForCell(self, cell);
var length = speed > 0 ? (to - pos).Length / speed : 0; var length = speed > 0 ? (to - pos).Length / speed : 0;

View File

@@ -57,6 +57,14 @@ namespace OpenRA.Mods.RA.Move
this.nearEnough = nearEnough; this.nearEnough = nearEnough;
} }
public Move(CPos destination, int subCell, WRange nearEnough)
{
this.getPath = (self, mobile) => self.World.WorldActor.Trait<PathFinder>()
.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) public Move(CPos destination, Actor ignoreBuilding)
{ {
this.getPath = (self, mobile) => this.getPath = (self, mobile) =>