Extend Target with world-coordinate range checks.

This commit is contained in:
Paul Chote
2013-07-06 15:07:18 +12:00
parent eec986d93d
commit 399aac7e0f

View File

@@ -8,11 +8,15 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
namespace OpenRA.Traits
{
public struct Target // a target: either an actor, or a fixed location.
public struct Target
{
public static Target[] NoTargets = {};
public static readonly Target[] NoTargets = {};
Actor actor;
PPos pos;
@@ -43,6 +47,48 @@ namespace OpenRA.Traits
public PPos PxPosition { get { return IsActor ? actor.Trait<IHasLocation>().PxPosition : pos; } }
public PPos CenterLocation { get { return PxPosition; } }
// Representative position - see Positions for the full set of targetable positions.
public WPos CenterPosition
{
get
{
if (!IsValid)
throw new InvalidOperationException("Attempting to query the position of an invalid Target");
return actor != null ? actor.CenterPosition : pos.ToWPos(0);
}
}
// Positions available to target for range checks
static readonly WPos[] NoPositions = {};
public IEnumerable<WPos> Positions
{
get
{
if (!IsValid)
return NoPositions;
if (actor == null)
return new []{pos.ToWPos(0)};
var targetable = actor.TraitOrDefault<ITargetable>();
if (targetable == null)
return new []{actor.CenterPosition};
return targetable.TargetableCells(actor).Select(c => c.CenterPosition);
}
}
public bool IsInRange(WPos origin, WRange range)
{
if (!IsValid)
return false;
// Target ranges are calculated in 2D, so ignore height differences
return Positions.Any(t => (t.X - origin.X)*(t.X - origin.X) +
(t.Y - origin.Y)*(t.Y - origin.Y) <= range.Range*range.Range);
}
public Actor Actor { get { return IsActor ? actor : null; } }
public bool IsActor { get { return actor != null && !actor.Destroyed; } }
}