Improve support for picking a valid actor spawn cell.
This commit is contained in:
@@ -75,6 +75,7 @@ namespace OpenRA
|
||||
[FieldFromYamlKey] public readonly int value = 0;
|
||||
public SubCellInit() { }
|
||||
public SubCellInit(int init) { value = init; }
|
||||
public SubCellInit(SubCell init) { value = (int)init; }
|
||||
public SubCell Value(World world) { return (SubCell)value; }
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,16 @@ namespace OpenRA
|
||||
SubCell.BottomLeft, SubCell.BottomRight }.Any(b => !AnyUnitsAt(a,b));
|
||||
}
|
||||
|
||||
public SubCell? FreeSubCell(CPos a)
|
||||
{
|
||||
if (!HasFreeSubCell(a))
|
||||
return null;
|
||||
|
||||
return new[]{ SubCell.TopLeft, SubCell.TopRight, SubCell.Center,
|
||||
SubCell.BottomLeft, SubCell.BottomRight }.First(b => !AnyUnitsAt(a,b));
|
||||
}
|
||||
|
||||
|
||||
public bool AnyUnitsAt(CPos a)
|
||||
{
|
||||
return influence[ a.X, a.Y ] != null;
|
||||
|
||||
@@ -109,6 +109,11 @@ namespace OpenRA.Mods.RA.Move
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanEnterCell(World world, CPos cell)
|
||||
{
|
||||
return CanEnterCell(world, null, cell, null, true, true);
|
||||
}
|
||||
|
||||
public bool CanEnterCell(World world, Actor self, CPos cell, Actor ignoreActor, bool checkTransientActors, bool blockedByMovers)
|
||||
{
|
||||
if (MovementCostForCell(world, cell) == int.MaxValue)
|
||||
@@ -120,13 +125,13 @@ namespace OpenRA.Mods.RA.Move
|
||||
var blockingActors = world.ActorMap.GetUnitsAt(cell)
|
||||
.Where(x => x != ignoreActor)
|
||||
// Neutral/enemy units are blockers. Allied units that are moving are not blockers.
|
||||
.Where(x => blockedByMovers || ((self.Owner.Stances[x.Owner] != Stance.Ally) || !IsMovingInMyDirection(self, x)))
|
||||
.Where(x => blockedByMovers || (self == null || self.Owner.Stances[x.Owner] != Stance.Ally || !IsMovingInMyDirection(self, x)))
|
||||
.ToList();
|
||||
|
||||
if (checkTransientActors && blockingActors.Count > 0)
|
||||
{
|
||||
// Non-sharable unit can enter a cell with shareable units only if it can crush all of them
|
||||
if (Crushes == null)
|
||||
if (self == null || Crushes == null)
|
||||
return false;
|
||||
|
||||
if (blockingActors.Any(a => !(a.HasTrait<ICrushable>() &&
|
||||
|
||||
Reference in New Issue
Block a user