Fixed UnloadCargo stacking using new subcell API exposure
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)); }
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user