Merge pull request #5977 from pchote/oi-keep-moving
Don’t cancel MoveAdjacentTo / MoveWithinRange when target becomes invalid
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Mods.RA.Move;
|
using OpenRA.Mods.RA.Move;
|
||||||
@@ -17,12 +18,14 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
{
|
{
|
||||||
public class MoveAdjacentTo : Activity
|
public class MoveAdjacentTo : Activity
|
||||||
{
|
{
|
||||||
protected readonly Target target;
|
static readonly List<CPos> NoPath = new List<CPos>();
|
||||||
|
|
||||||
readonly Mobile mobile;
|
readonly Mobile mobile;
|
||||||
readonly PathFinder pathFinder;
|
readonly PathFinder pathFinder;
|
||||||
readonly DomainIndex domainIndex;
|
readonly DomainIndex domainIndex;
|
||||||
readonly uint movementClass;
|
readonly uint movementClass;
|
||||||
|
|
||||||
|
protected Target target { get; private set; }
|
||||||
protected CPos targetPosition;
|
protected CPos targetPosition;
|
||||||
Activity inner;
|
Activity inner;
|
||||||
bool repath;
|
bool repath;
|
||||||
@@ -52,6 +55,11 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
return targetPosition != oldTargetPosition;
|
return targetPosition != oldTargetPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual IEnumerable<CPos> CandidateMovementCells(Actor self)
|
||||||
|
{
|
||||||
|
return Util.AdjacentCells(self.World, target);
|
||||||
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
var targetIsValid = target.IsValidFor(self);
|
var targetIsValid = target.IsValidFor(self);
|
||||||
@@ -65,7 +73,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
// Target has moved, and MoveAdjacentTo is still valid.
|
// Target has moved, and MoveAdjacentTo is still valid.
|
||||||
UpdateInnerPath(self);
|
inner = mobile.MoveTo(() => CalculatePathToTarget(self));
|
||||||
repath = false;
|
repath = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,22 +83,20 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
var oldTargetPosition = targetPosition;
|
var oldTargetPosition = targetPosition;
|
||||||
targetPosition = self.World.Map.CellContaining(target.CenterPosition);
|
targetPosition = self.World.Map.CellContaining(target.CenterPosition);
|
||||||
|
|
||||||
var shroudStop = ShouldStop(self, oldTargetPosition);
|
var shouldStop = ShouldStop(self, oldTargetPosition);
|
||||||
if (shroudStop || (!repath && ShouldRepath(self, oldTargetPosition)))
|
if (shouldStop || (!repath && ShouldRepath(self, oldTargetPosition)))
|
||||||
{
|
{
|
||||||
// Finish moving into the next cell and then repath.
|
// Finish moving into the next cell and then repath.
|
||||||
if (inner != null)
|
if (inner != null)
|
||||||
inner.Cancel(self);
|
inner.Cancel(self);
|
||||||
|
|
||||||
repath = !shroudStop;
|
repath = !shouldStop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Target became invalid. Cancel the inner order,
|
// Target became invalid. Move to its last known position.
|
||||||
// and then wait for it to move into the next cell
|
target = Target.FromCell(self.World, targetPosition);
|
||||||
// before finishing this order (handled above).
|
|
||||||
inner.Cancel(self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ticks the inner move activity to actually move the actor.
|
// Ticks the inner move activity to actually move the actor.
|
||||||
@@ -99,12 +105,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual IEnumerable<CPos> CandidateMovementCells(Actor self)
|
List<CPos> CalculatePathToTarget(Actor self)
|
||||||
{
|
|
||||||
return Util.AdjacentCells(self.World, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateInnerPath(Actor self)
|
|
||||||
{
|
{
|
||||||
var targetCells = CandidateMovementCells(self);
|
var targetCells = CandidateMovementCells(self);
|
||||||
var searchCells = new List<CPos>();
|
var searchCells = new List<CPos>();
|
||||||
@@ -115,14 +116,12 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
searchCells.Add(cell);
|
searchCells.Add(cell);
|
||||||
|
|
||||||
if (!searchCells.Any())
|
if (!searchCells.Any())
|
||||||
return;
|
return NoPath;
|
||||||
|
|
||||||
var path = pathFinder.FindBidiPath(
|
var fromSrc = PathSearch.FromPoints(self.World, mobile.Info, self, searchCells, loc, true);
|
||||||
PathSearch.FromPoints(self.World, mobile.Info, self, searchCells, loc, true),
|
var fromDest = PathSearch.FromPoint(self.World, mobile.Info, self, loc, targetPosition, true).Reverse();
|
||||||
PathSearch.FromPoint(self.World, mobile.Info, self, loc, targetPosition, true).Reverse()
|
|
||||||
);
|
|
||||||
|
|
||||||
inner = mobile.MoveTo(() => path);
|
return pathFinder.FindBidiPath(fromSrc, fromDest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<Target> GetTargets(Actor self)
|
public override IEnumerable<Target> GetTargets(Actor self)
|
||||||
|
|||||||
Reference in New Issue
Block a user