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

View File

@@ -528,6 +528,7 @@
<Compile Include="Console\PlayerCommands.cs" /> <Compile Include="Console\PlayerCommands.cs" />
<Compile Include="Render\WithRepairAnimation.cs" /> <Compile Include="Render\WithRepairAnimation.cs" />
<Compile Include="Render\WithRepairOverlay.cs" /> <Compile Include="Render\WithRepairOverlay.cs" />
<Compile Include="Activities\MoveWithinRange.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj"> <ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj">