Extend Target with world-coordinate range checks.
This commit is contained in:
@@ -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; } }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user