From 9c9a16d80e01142c6a430a12a9605d4edb6471cc Mon Sep 17 00:00:00 2001 From: James Dunne Date: Thu, 5 Jul 2012 16:13:42 -0500 Subject: [PATCH] Path planning no longer considers moving friendly units as blockers. --- OpenRA.Mods.RA/Crates/GiveUnitCrateAction.cs | 2 +- OpenRA.Mods.RA/Move/Mobile.cs | 13 +++++++++---- OpenRA.Mods.RA/Move/Move.cs | 19 +++++++++++++++++++ OpenRA.Mods.RA/Move/PathFinder.cs | 2 +- OpenRA.Mods.RA/Move/PathSearch.cs | 2 +- OpenRA.Mods.RA/Production.cs | 2 +- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/OpenRA.Mods.RA/Crates/GiveUnitCrateAction.cs b/OpenRA.Mods.RA/Crates/GiveUnitCrateAction.cs index a6c33d4195..614b518a9f 100644 --- a/OpenRA.Mods.RA/Crates/GiveUnitCrateAction.cs +++ b/OpenRA.Mods.RA/Crates/GiveUnitCrateAction.cs @@ -66,7 +66,7 @@ namespace OpenRA.Mods.RA.Crates for (var i = -1; i < 2; i++) for (var j = -1; j < 2; j++) - if (mi.CanEnterCell(self.World, self.Owner, near + new CVec(i, j), null, true)) + if (mi.CanEnterCell(self.World, self.Owner, near + new CVec(i, j), null, true, true)) yield return near + new CVec(i, j); } diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 0eff2703bb..797f359597 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -77,7 +77,7 @@ namespace OpenRA.Mods.RA.Move {SubCell.FullCell, new PVecInt(0,0)}, }; - public bool CanEnterCell(World world, Player owner, CPos cell, Actor ignoreActor, bool checkTransientActors) + public bool CanEnterCell(World world, Player owner, CPos cell, Actor ignoreActor, bool checkTransientActors, bool blockedByMovers) { if (MovementCostForCell(world, cell) == int.MaxValue) return false; @@ -85,7 +85,12 @@ namespace OpenRA.Mods.RA.Move if (SharesCell && world.ActorMap.HasFreeSubCell(cell)) return true; - var blockingActors = world.ActorMap.GetUnitsAt(cell).Where(x => x != ignoreActor).ToList(); + 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 || ((owner.Stances[x.Owner] != Stance.Ally) || !x.IsMoving())) + .ToList(); + if (checkTransientActors && blockingActors.Count > 0) { // Non-sharable unit can enter a cell with shareable units only if it can crush all of them @@ -93,7 +98,7 @@ namespace OpenRA.Mods.RA.Move return false; if (blockingActors.Any(a => !(a.HasTrait() && - a.TraitsImplementing().Any(b => b.CrushableBy(Crushes, owner))))) + a.TraitsImplementing().Any(b => b.CrushableBy(Crushes, owner))))) return false; } @@ -342,7 +347,7 @@ namespace OpenRA.Mods.RA.Move public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors) { - return Info.CanEnterCell(self.World, self.Owner, cell, ignoreActor, checkTransientActors); + return Info.CanEnterCell(self.World, self.Owner, cell, ignoreActor, checkTransientActors, true); } public void EnteringCell(Actor self) diff --git a/OpenRA.Mods.RA/Move/Move.cs b/OpenRA.Mods.RA/Move/Move.cs index 1428961438..fe9f8bb261 100755 --- a/OpenRA.Mods.RA/Move/Move.cs +++ b/OpenRA.Mods.RA/Move/Move.cs @@ -388,4 +388,23 @@ namespace OpenRA.Mods.RA.Move } } } + + public static class ActorExtensionsForMove + { + public static bool IsMoving(this Actor self) + { + if (self.IsIdle) return false; + + Activity a = self.GetCurrentActivity(); + Debug.Assert(a != null); + + // Dirty, but it suffices until we do something better: + if (a.GetType() == typeof(Move)) return true; + if (a.GetType() == typeof(MoveAdjacentTo)) return true; + if (a.GetType() == typeof(AttackMove)) return true; + + // Not a move: + return false; + } + } } diff --git a/OpenRA.Mods.RA/Move/PathFinder.cs b/OpenRA.Mods.RA/Move/PathFinder.cs index 7322c08094..0a3e465656 100755 --- a/OpenRA.Mods.RA/Move/PathFinder.cs +++ b/OpenRA.Mods.RA/Move/PathFinder.cs @@ -73,7 +73,7 @@ namespace OpenRA.Mods.RA.Move { var mi = self.Info.Traits.Get(); var tilesInRange = world.FindTilesInCircle(target, range) - .Where(t => mi.CanEnterCell(self.World, self.Owner, t, null, true)); + .Where(t => mi.CanEnterCell(self.World, self.Owner, t, null, true, true)); var path = FindBidiPath( PathSearch.FromPoints(world, mi, self.Owner, tilesInRange, src, true), diff --git a/OpenRA.Mods.RA/Move/PathSearch.cs b/OpenRA.Mods.RA/Move/PathSearch.cs index 89d0ebc941..cc1226c69e 100755 --- a/OpenRA.Mods.RA/Move/PathSearch.cs +++ b/OpenRA.Mods.RA/Move/PathSearch.cs @@ -120,7 +120,7 @@ namespace OpenRA.Mods.RA.Move if (costHere == int.MaxValue) continue; - if (!mobileInfo.CanEnterCell(world, owner, newHere, ignoreBuilding, checkForBlocked)) + if (!mobileInfo.CanEnterCell(world, owner, newHere, ignoreBuilding, checkForBlocked, false)) continue; if (customBlock != null && customBlock(newHere)) diff --git a/OpenRA.Mods.RA/Production.cs b/OpenRA.Mods.RA/Production.cs index f92ade2f58..06a5a8ad91 100755 --- a/OpenRA.Mods.RA/Production.cs +++ b/OpenRA.Mods.RA/Production.cs @@ -129,7 +129,7 @@ namespace OpenRA.Mods.RA var mobileInfo = producee.Traits.GetOrDefault(); return mobileInfo == null || - mobileInfo.CanEnterCell(self.World, self.Owner, self.Location + s.ExitCellVector, self, true); + mobileInfo.CanEnterCell(self.World, self.Owner, self.Location + s.ExitCellVector, self, true, true); } } }