Improve support for picking a valid actor spawn cell.

This commit is contained in:
Paul Chote
2013-07-12 20:21:21 +12:00
parent 6bf783e674
commit 2091a386fb
3 changed files with 18 additions and 2 deletions

View File

@@ -75,6 +75,7 @@ namespace OpenRA
[FieldFromYamlKey] public readonly int value = 0; [FieldFromYamlKey] public readonly int value = 0;
public SubCellInit() { } public SubCellInit() { }
public SubCellInit(int init) { value = init; } public SubCellInit(int init) { value = init; }
public SubCellInit(SubCell init) { value = (int)init; }
public SubCell Value(World world) { return (SubCell)value; } public SubCell Value(World world) { return (SubCell)value; }
} }

View File

@@ -64,6 +64,16 @@ namespace OpenRA
SubCell.BottomLeft, SubCell.BottomRight }.Any(b => !AnyUnitsAt(a,b)); 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) public bool AnyUnitsAt(CPos a)
{ {
return influence[ a.X, a.Y ] != null; return influence[ a.X, a.Y ] != null;

View File

@@ -109,6 +109,11 @@ namespace OpenRA.Mods.RA.Move
return true; 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) public bool CanEnterCell(World world, Actor self, CPos cell, Actor ignoreActor, bool checkTransientActors, bool blockedByMovers)
{ {
if (MovementCostForCell(world, cell) == int.MaxValue) if (MovementCostForCell(world, cell) == int.MaxValue)
@@ -120,13 +125,13 @@ namespace OpenRA.Mods.RA.Move
var blockingActors = world.ActorMap.GetUnitsAt(cell) var blockingActors = world.ActorMap.GetUnitsAt(cell)
.Where(x => x != ignoreActor) .Where(x => x != ignoreActor)
// Neutral/enemy units are blockers. Allied units that are moving are not blockers. // 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(); .ToList();
if (checkTransientActors && blockingActors.Count > 0) if (checkTransientActors && blockingActors.Count > 0)
{ {
// Non-sharable unit can enter a cell with shareable units only if it can crush all of them // 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; return false;
if (blockingActors.Any(a => !(a.HasTrait<ICrushable>() && if (blockingActors.Any(a => !(a.HasTrait<ICrushable>() &&