Extend Target with world-coordinate range checks.
This commit is contained in:
@@ -8,11 +8,15 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace OpenRA.Traits
|
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;
|
Actor actor;
|
||||||
PPos pos;
|
PPos pos;
|
||||||
@@ -43,6 +47,48 @@ namespace OpenRA.Traits
|
|||||||
public PPos PxPosition { get { return IsActor ? actor.Trait<IHasLocation>().PxPosition : pos; } }
|
public PPos PxPosition { get { return IsActor ? actor.Trait<IHasLocation>().PxPosition : pos; } }
|
||||||
public PPos CenterLocation { get { return PxPosition; } }
|
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 Actor Actor { get { return IsActor ? actor : null; } }
|
||||||
public bool IsActor { get { return actor != null && !actor.Destroyed; } }
|
public bool IsActor { get { return actor != null && !actor.Destroyed; } }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user