Units heading in generally opposite directions are now considered blockers; this fixes pathing deadlocks.
This commit is contained in:
@@ -77,7 +77,25 @@ namespace OpenRA.Mods.RA.Move
|
||||
{SubCell.FullCell, new PVecInt(0,0)},
|
||||
};
|
||||
|
||||
public bool CanEnterCell(World world, Player owner, CPos cell, Actor ignoreActor, bool checkTransientActors, bool blockedByMovers)
|
||||
static bool IsMovingInMyDirection(Actor self, Actor other)
|
||||
{
|
||||
if (!other.IsMoving()) return false;
|
||||
if (self == null) return true;
|
||||
|
||||
var selfMobile = self.TraitOrDefault<Mobile>();
|
||||
if (selfMobile == null) return false;
|
||||
|
||||
var otherMobile = other.TraitOrDefault<Mobile>();
|
||||
if (otherMobile == null) return false;
|
||||
|
||||
// Sign of dot-product indicates (roughly) if vectors are facing in same or opposite directions:
|
||||
var dp = CVec.Dot((selfMobile.toCell - self.Location), (otherMobile.toCell - other.Location));
|
||||
if (dp <= 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanEnterCell(World world, Actor self, CPos cell, Actor ignoreActor, bool checkTransientActors, bool blockedByMovers)
|
||||
{
|
||||
if (MovementCostForCell(world, cell) == int.MaxValue)
|
||||
return false;
|
||||
@@ -88,7 +106,7 @@ 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 || ((owner.Stances[x.Owner] != Stance.Ally) || !x.IsMoving()))
|
||||
.Where(x => blockedByMovers || ((self.Owner.Stances[x.Owner] != Stance.Ally) || !IsMovingInMyDirection(self, x)))
|
||||
.ToList();
|
||||
|
||||
if (checkTransientActors && blockingActors.Count > 0)
|
||||
@@ -98,7 +116,7 @@ namespace OpenRA.Mods.RA.Move
|
||||
return false;
|
||||
|
||||
if (blockingActors.Any(a => !(a.HasTrait<ICrushable>() &&
|
||||
a.TraitsImplementing<ICrushable>().Any(b => b.CrushableBy(Crushes, owner)))))
|
||||
a.TraitsImplementing<ICrushable>().Any(b => b.CrushableBy(Crushes, self.Owner)))))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -347,7 +365,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, true);
|
||||
return Info.CanEnterCell(self.World, self, cell, ignoreActor, checkTransientActors, true);
|
||||
}
|
||||
|
||||
public void EnteringCell(Actor self)
|
||||
|
||||
Reference in New Issue
Block a user