Path planning no longer considers moving friendly units as blockers.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -93,7 +98,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (blockingActors.Any(a => !(a.HasTrait<ICrushable>() &&
|
if (blockingActors.Any(a => !(a.HasTrait<ICrushable>() &&
|
||||||
a.TraitsImplementing<ICrushable>().Any(b => b.CrushableBy(Crushes, owner)))))
|
a.TraitsImplementing<ICrushable>().Any(b => b.CrushableBy(Crushes, owner)))))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user