diff --git a/OpenRA.Game/ActorInitializer.cs b/OpenRA.Game/ActorInitializer.cs index 5f8a6bb7b2..71ee1eb43f 100755 --- a/OpenRA.Game/ActorInitializer.cs +++ b/OpenRA.Game/ActorInitializer.cs @@ -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; } } diff --git a/OpenRA.Game/ActorMap.cs b/OpenRA.Game/ActorMap.cs index 6e276b4262..5fc8ac1f8f 100644 --- a/OpenRA.Game/ActorMap.cs +++ b/OpenRA.Game/ActorMap.cs @@ -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; diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index df97bc8c3d..f7679b096c 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -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() &&