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

View File

@@ -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
@@ -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)

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 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),

View File

@@ -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))

View File

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