Introduce Target.Type property.

This commit is contained in:
Paul Chote
2013-08-07 22:51:48 +12:00
parent fa517b8787
commit 4f3c9aa0af
18 changed files with 56 additions and 39 deletions

View File

@@ -151,12 +151,10 @@ namespace OpenRA.GameRules
public bool IsValidAgainst(Target target, World world) public bool IsValidAgainst(Target target, World world)
{ {
if (!target.IsValid) if (target.Type == TargetType.Actor)
return false;
if (target.IsActor)
return IsValidAgainst(target.Actor); return IsValidAgainst(target.Actor);
else
if (target.Type == TargetType.Terrain)
{ {
var cell = target.CenterPosition.ToCPos(); var cell = target.CenterPosition.ToCPos();
if (ValidTargets.Contains("Ground") && world.GetTerrainType(cell) != "Water") if (ValidTargets.Contains("Ground") && world.GetTerrainType(cell) != "Water")
@@ -167,6 +165,8 @@ namespace OpenRA.GameRules
return false; return false;
} }
return false;
} }
} }
} }

View File

@@ -109,8 +109,10 @@ namespace OpenRA.Traits
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {
if (self.Destroyed) return; if (self.Destroyed)
if (target.IsActor && display) return;
if (target.Type == TargetType.Actor && display)
w.Add(new FlashTarget(target.Actor)); w.Add(new FlashTarget(target.Actor));
var line = self.TraitOrDefault<DrawLineToTarget>(); var line = self.TraitOrDefault<DrawLineToTarget>();

View File

@@ -14,18 +14,19 @@ using System.Linq;
namespace OpenRA.Traits namespace OpenRA.Traits
{ {
public enum TargetType { Invalid, Actor, Terrain }
public struct Target public struct Target
{ {
public static readonly Target[] NoTargets = {}; public static readonly Target[] None = {};
public static readonly Target None = new Target(); public static readonly Target Invalid = new Target { type = TargetType.Invalid };
TargetType type;
Actor actor; Actor actor;
WPos pos; WPos pos;
bool valid;
int generation; int generation;
public static Target FromPos(WPos p) { return new Target { pos = p, valid = true }; } public static Target FromPos(WPos p) { return new Target { pos = p, type = TargetType.Terrain }; }
public static Target FromCell(CPos c) { return new Target { pos = c.CenterPosition, valid = true }; } public static Target FromCell(CPos c) { return new Target { pos = c.CenterPosition, type = TargetType.Terrain }; }
public static Target FromOrder(Order o) public static Target FromOrder(Order o)
{ {
return o.TargetActor != null return o.TargetActor != null
@@ -38,23 +39,39 @@ namespace OpenRA.Traits
return new Target return new Target
{ {
actor = a, actor = a,
valid = (a != null), type = a != null ? TargetType.Actor : TargetType.Invalid,
generation = a.Generation, generation = a.Generation,
}; };
} }
public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && !actor.IsDead() && actor.Generation == generation)); } } public bool IsValid { get { return Type != TargetType.Invalid; } }
public Actor Actor { get { return IsActor ? actor : null; } } public Actor Actor { get { return actor; } }
// TODO: This should return true even if the actor is destroyed public TargetType Type
public bool IsActor { get { return actor != null && !actor.Destroyed; } } {
get
{
if (type == TargetType.Actor)
{
// Actor is no longer in the world
if (!actor.IsInWorld || actor.IsDead())
return TargetType.Invalid;
// Actor generation has changed (teleported or captured)
if (actor.Generation != generation)
return TargetType.Invalid;
}
return type;
}
}
// Representative position - see Positions for the full set of targetable positions. // Representative position - see Positions for the full set of targetable positions.
public WPos CenterPosition public WPos CenterPosition
{ {
get get
{ {
if (!IsValid) if (Type == TargetType.Invalid)
throw new InvalidOperationException("Attempting to query the position of an invalid Target"); throw new InvalidOperationException("Attempting to query the position of an invalid Target");
return actor != null ? actor.CenterPosition : pos; return actor != null ? actor.CenterPosition : pos;
@@ -67,7 +84,7 @@ namespace OpenRA.Traits
{ {
get get
{ {
if (!IsValid) if (Type == TargetType.Invalid)
return NoPositions; return NoPositions;
if (actor == null) if (actor == null)
@@ -83,7 +100,7 @@ namespace OpenRA.Traits
public bool IsInRange(WPos origin, WRange range) public bool IsInRange(WPos origin, WRange range)
{ {
if (!IsValid) if (Type == TargetType.Invalid)
return false; return false;
// Target ranges are calculated in 2D, so ignore height differences // Target ranges are calculated in 2D, so ignore height differences

View File

@@ -134,7 +134,7 @@ namespace OpenRA.Traits
public static IEnumerable<CPos> AdjacentCells(Target target) public static IEnumerable<CPos> AdjacentCells(Target target)
{ {
var cells = target.IsActor var cells = target.Type == TargetType.Actor
? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray() ? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray()
: new CPos[] { }; : new CPos[] { };

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Activities
public Attack(Target target, WRange range, bool allowMovement) public Attack(Target target, WRange range, bool allowMovement)
{ {
Target = target; Target = target;
if (target.IsActor) if (target.Type == TargetType.Actor)
targetable = target.Actor.TraitOrDefault<ITargetable>(); targetable = target.Actor.TraitOrDefault<ITargetable>();
Range = range; Range = range;

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (!target.IsValid) if (target.Type != TargetType.Actor)
return NextActivity; return NextActivity;
var capturable = target.Actor.Trait<Capturable>(); var capturable = target.Actor.Trait<Capturable>();

View File

@@ -27,13 +27,13 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled || !target.IsValid) if (IsCanceled || target.Type != TargetType.Actor)
return NextActivity; return NextActivity;
self.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, () => self.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, () =>
{ {
// Can't demolish an already dead actor // Can't demolish an already dead actor
if (!target.IsValid) if (target.Type != TargetType.Actor)
return; return;
// Invulnerable actors can't be demolished // Invulnerable actors can't be demolished

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled || !target.IsValid || !target.IsActor) if (IsCanceled || target.Type != TargetType.Actor)
return NextActivity; return NextActivity;
var targetActor = target.Actor; var targetActor = target.Actor;

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled || !target.IsValid) if (IsCanceled || target.Type != TargetType.Actor)
return NextActivity; return NextActivity;
if (!Util.AdjacentCells(target).Any(c => c == self.Location)) if (!Util.AdjacentCells(target).Any(c => c == self.Location))

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.RA.Activities
protected override Activity InnerTick(Actor self, AttackBase attack) protected override Activity InnerTick(Actor self, AttackBase attack)
{ {
if (Target.IsActor && Target.Actor.GetDamageState() == DamageState.Undamaged) if (Target.Type == TargetType.Actor && Target.Actor.GetDamageState() == DamageState.Undamaged)
return NextActivity; return NextActivity;
return base.InnerTick(self, attack); return base.InnerTick(self, attack);

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled || !target.IsValid || target.Actor.Owner == self.Owner) if (IsCanceled || target.Type != TargetType.Actor || target.Actor.Owner == self.Owner)
return NextActivity; return NextActivity;
foreach (var t in target.Actor.TraitsImplementing<IAcceptInfiltrator>()) foreach (var t in target.Actor.TraitsImplementing<IAcceptInfiltrator>())

View File

@@ -23,9 +23,7 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled) if (IsCanceled || target.Type != TargetType.Actor)
return NextActivity;
if (!target.IsValid)
return NextActivity; return NextActivity;
var b = target.Actor.TraitOrDefault<Building>(); var b = target.Actor.TraitOrDefault<Building>();

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled || !target.IsValid) if (IsCanceled || target.Type != TargetType.Actor)
return NextActivity; return NextActivity;
var hut = target.Actor.Trait<BridgeHut>(); var hut = target.Actor.Trait<BridgeHut>();

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled || !target.IsValid) if (IsCanceled || target.Type != TargetType.Actor)
return NextActivity; return NextActivity;
var health = target.Actor.Trait<Health>(); var health = target.Actor.Trait<Health>();

View File

@@ -54,7 +54,7 @@ namespace OpenRA.Mods.RA
if (self.IsDisabled()) if (self.IsDisabled())
return false; return false;
if (target.IsActor && target.Actor.HasTrait<ITargetable>() && if (target.Type == TargetType.Actor && target.Actor.HasTrait<ITargetable>() &&
!target.Actor.Trait<ITargetable>().TargetableBy(target.Actor,self)) !target.Actor.Trait<ITargetable>().TargetableBy(target.Actor,self))
return false; return false;
@@ -114,7 +114,7 @@ namespace OpenRA.Mods.RA
{ {
if (order is AttackOrderTargeter) if (order is AttackOrderTargeter)
{ {
if (target.IsActor) if (target.Type == TargetType.Actor)
return new Order("Attack", self, queued) { TargetActor = target.Actor }; return new Order("Attack", self, queued) { TargetActor = target.Actor };
else else
return new Order("Attack", self, queued) { TargetLocation = target.CenterPosition.ToCPos() }; return new Order("Attack", self, queued) { TargetLocation = target.CenterPosition.ToCPos() };

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA
public override void DoAttack(Actor self, Target target) public override void DoAttack(Actor self, Target target)
{ {
if (!CanAttack(self, target) || !target.IsActor) if (target.Type != TargetType.Actor || !CanAttack(self, target))
return; return;
var a = ChooseArmamentForTarget(target); var a = ChooseArmamentForTarget(target);

View File

@@ -67,7 +67,7 @@ namespace OpenRA.Mods.RA
base.ResolveOrder(self, order); base.ResolveOrder(self, order);
if (order.OrderString == "Stop") if (order.OrderString == "Stop")
target = Target.None; target = Target.Invalid;
} }
public virtual void BuildingComplete(Actor self) { buildComplete = true; } public virtual void BuildingComplete(Actor self) { buildComplete = true; }

View File

@@ -258,7 +258,7 @@ namespace OpenRA.Mods.RA.Move
return Enumerable.Reverse(path).Select(c => Target.FromCell(c)); return Enumerable.Reverse(path).Select(c => Target.FromCell(c));
if (destination != null) if (destination != null)
return new Target[] { Target.FromCell(destination.Value) }; return new Target[] { Target.FromCell(destination.Value) };
return Target.NoTargets; return Target.None;
} }
abstract class MovePart : Activity abstract class MovePart : Activity