Path planning no longer considers moving friendly units as blockers.

This commit is contained in:
James Dunne
2012-07-05 16:13:42 -05:00
parent 3d8e215598
commit 9c9a16d80e
6 changed files with 32 additions and 8 deletions

View File

@@ -66,7 +66,7 @@ namespace OpenRA.Mods.RA.Crates
for (var i = -1; i < 2; i++) for (var i = -1; i < 2; i++)
for (var j = -1; j < 2; j++) 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); yield return near + new CVec(i, j);
} }

View File

@@ -77,7 +77,7 @@ namespace OpenRA.Mods.RA.Move
{SubCell.FullCell, new PVecInt(0,0)}, {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) if (MovementCostForCell(world, cell) == int.MaxValue)
return false; return false;
@@ -85,7 +85,12 @@ namespace OpenRA.Mods.RA.Move
if (SharesCell && world.ActorMap.HasFreeSubCell(cell)) if (SharesCell && world.ActorMap.HasFreeSubCell(cell))
return true; 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) 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
@@ -342,7 +347,7 @@ namespace OpenRA.Mods.RA.Move
public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors) 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) public void EnteringCell(Actor self)

View File

@@ -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;
}
}
} }

View File

@@ -73,7 +73,7 @@ namespace OpenRA.Mods.RA.Move
{ {
var mi = self.Info.Traits.Get<MobileInfo>(); var mi = self.Info.Traits.Get<MobileInfo>();
var tilesInRange = world.FindTilesInCircle(target, range) 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( var path = FindBidiPath(
PathSearch.FromPoints(world, mi, self.Owner, tilesInRange, src, true), PathSearch.FromPoints(world, mi, self.Owner, tilesInRange, src, true),

View File

@@ -120,7 +120,7 @@ namespace OpenRA.Mods.RA.Move
if (costHere == int.MaxValue) if (costHere == int.MaxValue)
continue; continue;
if (!mobileInfo.CanEnterCell(world, owner, newHere, ignoreBuilding, checkForBlocked)) if (!mobileInfo.CanEnterCell(world, owner, newHere, ignoreBuilding, checkForBlocked, false))
continue; continue;
if (customBlock != null && customBlock(newHere)) if (customBlock != null && customBlock(newHere))

View File

@@ -129,7 +129,7 @@ namespace OpenRA.Mods.RA
var mobileInfo = producee.Traits.GetOrDefault<MobileInfo>(); var mobileInfo = producee.Traits.GetOrDefault<MobileInfo>();
return mobileInfo == null || 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);
} }
} }
} }