Added MoveWithinRange activity for Mobile units.

This commit is contained in:
Paul Chote
2014-01-13 22:05:26 +13:00
parent 887a515e14
commit 64ab0a77a9
3 changed files with 87 additions and 6 deletions

View File

@@ -17,14 +17,14 @@ namespace OpenRA.Mods.RA.Activities
{
public class MoveAdjacentTo : Activity
{
readonly Target target;
protected readonly Target target;
readonly Mobile mobile;
readonly PathFinder pathFinder;
readonly DomainIndex domainIndex;
readonly uint movementClass;
protected CPos targetPosition;
Activity inner;
CPos targetPosition;
bool repath;
public MoveAdjacentTo(Actor self, Target target)
@@ -39,6 +39,16 @@ namespace OpenRA.Mods.RA.Activities
repath = true;
}
protected virtual bool ShouldStop(Actor self, CPos oldTargetPosition)
{
return false;
}
protected virtual bool ShouldRepath(Actor self, CPos oldTargetPosition)
{
return targetPosition != oldTargetPosition;
}
public override Activity Tick(Actor self)
{
var targetIsValid = target.IsValidFor(self);
@@ -59,15 +69,17 @@ namespace OpenRA.Mods.RA.Activities
if (targetIsValid)
{
// Check if the target has moved
var oldPosition = targetPosition;
var oldTargetPosition = targetPosition;
targetPosition = target.CenterPosition.ToCPos();
if (!repath && targetPosition != oldPosition)
var shroudStop = ShouldStop(self, oldTargetPosition);
if (shroudStop || (!repath && ShouldRepath(self, oldTargetPosition)))
{
// Finish moving into the next cell and then repath.
if (inner != null)
inner.Cancel(self);
repath = true;
repath = !shroudStop;
}
}
else
@@ -84,9 +96,14 @@ namespace OpenRA.Mods.RA.Activities
return this;
}
protected virtual IEnumerable<CPos> CandidateMovementCells(Actor self)
{
return Util.AdjacentCells(target);
}
void UpdateInnerPath(Actor self)
{
var targetCells = Util.AdjacentCells(target);
var targetCells = CandidateMovementCells(self);
var searchCells = new List<CPos>();
var loc = self.Location;

View File

@@ -0,0 +1,63 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
{
public class MoveWithinRange : MoveAdjacentTo
{
readonly WRange maxRange;
readonly WRange minRange;
public MoveWithinRange(Actor self, Target target, WRange minRange, WRange maxRange)
: base(self, target)
{
this.minRange = minRange;
this.maxRange = maxRange;
}
protected override bool ShouldStop(Actor self, CPos oldTargetPosition)
{
// We are now in range. Don't move any further!
// HACK: This works around the pathfinder not returning the shortest path
var cp = self.CenterPosition;
return target.IsInRange(cp, maxRange) && !target.IsInRange(cp, minRange);
}
protected override bool ShouldRepath(Actor self, CPos oldTargetPosition)
{
var cp = self.CenterPosition;
return targetPosition != oldTargetPosition && (!target.IsInRange(cp, maxRange) || target.IsInRange(cp, minRange));
}
protected override IEnumerable<CPos> CandidateMovementCells(Actor self)
{
var maxCells = (maxRange.Range + 1023) / 1024;
var outerCells = self.World.Map.FindTilesInCircle(targetPosition, maxCells);
var minCells = minRange.Range / 1024;
var innerCells = self.World.Map.FindTilesInCircle(targetPosition, minCells);
var outerSq = maxRange.Range * maxRange.Range;
var innerSq = minRange.Range * minRange.Range;
var center = target.CenterPosition;
return outerCells.Except(innerCells).Where(c =>
{
var dxSq = (c.CenterPosition - center).HorizontalLengthSquared;
return dxSq >= innerSq && dxSq <= outerSq;
});
}
}
}