Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Units heading in generally opposite directions are now considered blo…

…ckers; this fixes pathing deadlocks.
  • Loading branch information...
commit ba1a36f26ed33e1db07d583404cbd97ae4bcefba 1 parent 9c9a16d
@JamesDunne JamesDunne authored
View
2  OpenRA.Mods.RA/Activities/FindResources.cs
@@ -53,7 +53,7 @@ public override Activity Tick(Actor self)
// Find harvestable resources nearby:
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(
- PathSearch.Search(self.World, mobileInfo, self.Owner, true)
+ PathSearch.Search(self.World, mobileInfo, self, true)
.WithCustomCost(loc =>
{
// Avoid enemy territory:
View
4 OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs
@@ -25,7 +25,7 @@ public override Activity Tick( Actor self )
var mobile = self.Trait<Mobile>();
- var ps1 = new PathSearch( self.World, mobile.Info, self.Owner )
+ var ps1 = new PathSearch( self.World, mobile.Info, self )
{
checkForBlocked = true,
heuristic = location => 0,
@@ -40,7 +40,7 @@ public override Activity Tick( Actor self )
ps1.heuristic = PathSearch.DefaultEstimator( mobile.toCell );
- var ps2 = PathSearch.FromPoint( self.World, mobile.Info, self.Owner, mobile.toCell, target.CenterLocation.ToCPos(), true );
+ var ps2 = PathSearch.FromPoint( self.World, mobile.Info, self, mobile.toCell, target.CenterLocation.ToCPos(), true );
var ret = self.World.WorldActor.Trait<PathFinder>().FindBidiPath( ps1, ps2 );
return Util.SequenceActivities( mobile.MoveTo( () => ret ), this );
View
2  OpenRA.Mods.RA/Crates/GiveUnitCrateAction.cs
@@ -66,7 +66,7 @@ IEnumerable<CPos> GetSuitableCells(CPos near)
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, true))
+ if (mi.CanEnterCell(self.World, self, near + new CVec(i, j), null, true, true))
yield return near + new CVec(i, j);
}
View
4 OpenRA.Mods.RA/Harvester.cs
@@ -112,7 +112,7 @@ Actor ClosestProc(Actor self, Actor ignore)
// Start a search from each refinery's delivery location:
var mi = self.Info.Traits.Get<MobileInfo>();
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(
- PathSearch.FromPoints(self.World, mi, self.Owner, refs.Values.Select(r => r.Location), self.Location, false)
+ PathSearch.FromPoints(self.World, mi, self, refs.Values.Select(r => r.Location), self.Location, false)
.WithCustomCost((loc) =>
{
if (!refs.ContainsKey(loc)) return 0;
@@ -349,7 +349,7 @@ public void ResolveOrder(Actor self, Order order)
// Find any harvestable resources:
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(
- PathSearch.Search(self.World, mobileInfo, self.Owner, true)
+ PathSearch.Search(self.World, mobileInfo, self, true)
.WithHeuristic(loc =>
{
// Get the resource at this location:
View
26 OpenRA.Mods.RA/Move/Mobile.cs
@@ -77,7 +77,25 @@ public int MovementCostForCell(World world, CPos cell)
{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 @@ public bool CanEnterCell(World world, Player owner, CPos cell, Actor ignoreActor
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 @@ public bool CanEnterCell(World world, Player owner, CPos cell, Actor ignoreActor
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 @@ public bool CanEnterCell(CPos p)
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)
View
4 OpenRA.Mods.RA/Move/Move.cs
@@ -32,7 +32,7 @@ public Move(CPos destination)
{
this.getPath = (self,mobile) =>
self.World.WorldActor.Trait<PathFinder>().FindPath(
- PathSearch.FromPoint( self.World, mobile.Info, self.Owner, mobile.toCell, destination, false )
+ PathSearch.FromPoint( self.World, mobile.Info, self, mobile.toCell, destination, false )
.WithoutLaneBias());
this.destination = destination;
this.nearEnough = 0;
@@ -49,7 +49,7 @@ public Move(CPos destination, Actor ignoreBuilding)
{
this.getPath = (self,mobile) =>
self.World.WorldActor.Trait<PathFinder>().FindPath(
- PathSearch.FromPoint( self.World, mobile.Info, self.Owner, mobile.toCell, destination, false )
+ PathSearch.FromPoint( self.World, mobile.Info, self, mobile.toCell, destination, false )
.WithIgnoredBuilding( ignoreBuilding ));
this.destination = destination;
View
10 OpenRA.Mods.RA/Move/PathFinder.cs
@@ -55,8 +55,8 @@ public List<CPos> FindUnitPath(CPos from, CPos target, Actor self)
var mi = self.Info.Traits.Get<MobileInfo>();
var pb = FindBidiPath(
- PathSearch.FromPoint(world, mi, self.Owner, target, from, true),
- PathSearch.FromPoint(world, mi, self.Owner, from, target, true).InReverse()
+ PathSearch.FromPoint(world, mi, self, target, from, true),
+ PathSearch.FromPoint(world, mi, self, from, target, true).InReverse()
);
CheckSanePath2(pb, from, target);
@@ -73,11 +73,11 @@ public List<CPos> FindUnitPathToRange(CPos src, CPos target, int range, Actor se
{
var mi = self.Info.Traits.Get<MobileInfo>();
var tilesInRange = world.FindTilesInCircle(target, range)
- .Where(t => mi.CanEnterCell(self.World, self.Owner, t, null, true, true));
+ .Where(t => mi.CanEnterCell(self.World, self, t, null, true, true));
var path = FindBidiPath(
- PathSearch.FromPoints(world, mi, self.Owner, tilesInRange, src, true),
- PathSearch.FromPoint(world, mi, self.Owner, src, target, true).InReverse()
+ PathSearch.FromPoints(world, mi, self, tilesInRange, src, true),
+ PathSearch.FromPoint(world, mi, self, src, target, true).InReverse()
);
return path;
View
21 OpenRA.Mods.RA/Move/PathSearch.cs
@@ -28,14 +28,15 @@ public class PathSearch : IDisposable
public bool inReverse;
MobileInfo mobileInfo;
- Player owner;
+ Actor self;
+ public Player owner { get { return self.Owner; } }
- public PathSearch(World world, MobileInfo mobileInfo, Player owner)
+ public PathSearch(World world, MobileInfo mobileInfo, Actor self)
{
this.world = world;
cellInfo = InitCellInfo();
this.mobileInfo = mobileInfo;
- this.owner = owner;
+ this.self = self;
customCost = null;
queue = new PriorityQueue<PathDistance>();
}
@@ -120,7 +121,7 @@ public CPos Expand(World world)
if (costHere == int.MaxValue)
continue;
- if (!mobileInfo.CanEnterCell(world, owner, newHere, ignoreBuilding, checkForBlocked, false))
+ if (!mobileInfo.CanEnterCell(world, self, newHere, ignoreBuilding, checkForBlocked, false))
continue;
if (customBlock != null && customBlock(newHere))
@@ -182,18 +183,18 @@ public void AddInitialCell(CPos location)
queue.Add(new PathDistance(heuristic(location), location));
}
- public static PathSearch Search(World world, MobileInfo mi, Player owner, bool checkForBlocked)
+ public static PathSearch Search(World world, MobileInfo mi, Actor self, bool checkForBlocked)
{
- var search = new PathSearch(world, mi, owner)
+ var search = new PathSearch(world, mi, self)
{
checkForBlocked = checkForBlocked
};
return search;
}
- public static PathSearch FromPoint(World world, MobileInfo mi, Player owner, CPos from, CPos target, bool checkForBlocked)
+ public static PathSearch FromPoint(World world, MobileInfo mi, Actor self, CPos from, CPos target, bool checkForBlocked)
{
- var search = new PathSearch(world, mi, owner)
+ var search = new PathSearch(world, mi, self)
{
heuristic = DefaultEstimator(target),
checkForBlocked = checkForBlocked
@@ -203,9 +204,9 @@ public static PathSearch FromPoint(World world, MobileInfo mi, Player owner, CPo
return search;
}
- public static PathSearch FromPoints(World world, MobileInfo mi, Player owner, IEnumerable<CPos> froms, CPos target, bool checkForBlocked)
+ public static PathSearch FromPoints(World world, MobileInfo mi, Actor self, IEnumerable<CPos> froms, CPos target, bool checkForBlocked)
{
- var search = new PathSearch(world, mi, owner)
+ var search = new PathSearch(world, mi, self)
{
heuristic = DefaultEstimator(target),
checkForBlocked = checkForBlocked
View
2  OpenRA.Mods.RA/Production.cs
@@ -129,7 +129,7 @@ static bool CanUseExit(Actor self, ActorInfo producee, ExitInfo s)
var mobileInfo = producee.Traits.GetOrDefault<MobileInfo>();
return mobileInfo == null ||
- mobileInfo.CanEnterCell(self.World, self.Owner, self.Location + s.ExitCellVector, self, true, true);
+ mobileInfo.CanEnterCell(self.World, self, self.Location + s.ExitCellVector, self, true, true);
}
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.