From 4f3c9aa0afbc47af740fa5d820fdb11070df1c68 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Wed, 7 Aug 2013 22:51:48 +1200 Subject: [PATCH] Introduce Target.Type property. --- OpenRA.Game/GameRules/WeaponInfo.cs | 10 ++--- OpenRA.Game/Traits/DrawLineToTarget.cs | 6 ++- OpenRA.Game/Traits/Target.cs | 43 +++++++++++++------ OpenRA.Game/Traits/Util.cs | 2 +- OpenRA.Mods.RA/Activities/Attack.cs | 2 +- OpenRA.Mods.RA/Activities/CaptureActor.cs | 2 +- OpenRA.Mods.RA/Activities/Demolish.cs | 4 +- OpenRA.Mods.RA/Activities/DonateSupplies.cs | 2 +- OpenRA.Mods.RA/Activities/Enter.cs | 2 +- OpenRA.Mods.RA/Activities/Heal.cs | 2 +- OpenRA.Mods.RA/Activities/Infiltrate.cs | 2 +- .../Activities/LegacyCaptureActor.cs | 4 +- OpenRA.Mods.RA/Activities/RepairBridge.cs | 2 +- OpenRA.Mods.RA/Activities/RepairBuilding.cs | 2 +- OpenRA.Mods.RA/Attack/AttackBase.cs | 4 +- OpenRA.Mods.RA/Attack/AttackLeap.cs | 2 +- OpenRA.Mods.RA/Attack/AttackTurreted.cs | 2 +- OpenRA.Mods.RA/Move/Move.cs | 2 +- 18 files changed, 56 insertions(+), 39 deletions(-) diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 8eaed63881..46ad55b65a 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -151,12 +151,10 @@ namespace OpenRA.GameRules public bool IsValidAgainst(Target target, World world) { - if (!target.IsValid) - return false; - - if (target.IsActor) + if (target.Type == TargetType.Actor) return IsValidAgainst(target.Actor); - else + + if (target.Type == TargetType.Terrain) { var cell = target.CenterPosition.ToCPos(); if (ValidTargets.Contains("Ground") && world.GetTerrainType(cell) != "Water") @@ -167,6 +165,8 @@ namespace OpenRA.GameRules return false; } + + return false; } } } diff --git a/OpenRA.Game/Traits/DrawLineToTarget.cs b/OpenRA.Game/Traits/DrawLineToTarget.cs index a241af6715..bf8baabfb4 100644 --- a/OpenRA.Game/Traits/DrawLineToTarget.cs +++ b/OpenRA.Game/Traits/DrawLineToTarget.cs @@ -109,8 +109,10 @@ namespace OpenRA.Traits self.World.AddFrameEndTask(w => { - if (self.Destroyed) return; - if (target.IsActor && display) + if (self.Destroyed) + return; + + if (target.Type == TargetType.Actor && display) w.Add(new FlashTarget(target.Actor)); var line = self.TraitOrDefault(); diff --git a/OpenRA.Game/Traits/Target.cs b/OpenRA.Game/Traits/Target.cs index 6611dab916..09c177ea13 100644 --- a/OpenRA.Game/Traits/Target.cs +++ b/OpenRA.Game/Traits/Target.cs @@ -14,18 +14,19 @@ using System.Linq; namespace OpenRA.Traits { + public enum TargetType { Invalid, Actor, Terrain } public struct Target { - public static readonly Target[] NoTargets = {}; - public static readonly Target None = new Target(); + public static readonly Target[] None = {}; + public static readonly Target Invalid = new Target { type = TargetType.Invalid }; + TargetType type; Actor actor; WPos pos; - bool valid; int generation; - public static Target FromPos(WPos p) { return new Target { pos = p, valid = true }; } - public static Target FromCell(CPos c) { return new Target { pos = c.CenterPosition, 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, type = TargetType.Terrain }; } public static Target FromOrder(Order o) { return o.TargetActor != null @@ -38,23 +39,39 @@ namespace OpenRA.Traits return new Target { actor = a, - valid = (a != null), + type = a != null ? TargetType.Actor : TargetType.Invalid, generation = a.Generation, }; } - public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && !actor.IsDead() && actor.Generation == generation)); } } - public Actor Actor { get { return IsActor ? actor : null; } } + public bool IsValid { get { return Type != TargetType.Invalid; } } + public Actor Actor { get { return actor; } } - // TODO: This should return true even if the actor is destroyed - public bool IsActor { get { return actor != null && !actor.Destroyed; } } + public TargetType Type + { + 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. public WPos CenterPosition { get { - if (!IsValid) + if (Type == TargetType.Invalid) throw new InvalidOperationException("Attempting to query the position of an invalid Target"); return actor != null ? actor.CenterPosition : pos; @@ -67,7 +84,7 @@ namespace OpenRA.Traits { get { - if (!IsValid) + if (Type == TargetType.Invalid) return NoPositions; if (actor == null) @@ -83,7 +100,7 @@ namespace OpenRA.Traits public bool IsInRange(WPos origin, WRange range) { - if (!IsValid) + if (Type == TargetType.Invalid) return false; // Target ranges are calculated in 2D, so ignore height differences diff --git a/OpenRA.Game/Traits/Util.cs b/OpenRA.Game/Traits/Util.cs index 02f1bd4d9d..c793944b5f 100755 --- a/OpenRA.Game/Traits/Util.cs +++ b/OpenRA.Game/Traits/Util.cs @@ -134,7 +134,7 @@ namespace OpenRA.Traits public static IEnumerable AdjacentCells(Target target) { - var cells = target.IsActor + var cells = target.Type == TargetType.Actor ? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray() : new CPos[] { }; diff --git a/OpenRA.Mods.RA/Activities/Attack.cs b/OpenRA.Mods.RA/Activities/Attack.cs index c583115ed8..a6ccc10edb 100755 --- a/OpenRA.Mods.RA/Activities/Attack.cs +++ b/OpenRA.Mods.RA/Activities/Attack.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Activities public Attack(Target target, WRange range, bool allowMovement) { Target = target; - if (target.IsActor) + if (target.Type == TargetType.Actor) targetable = target.Actor.TraitOrDefault(); Range = range; diff --git a/OpenRA.Mods.RA/Activities/CaptureActor.cs b/OpenRA.Mods.RA/Activities/CaptureActor.cs index 91af78a7aa..ee9379d780 100644 --- a/OpenRA.Mods.RA/Activities/CaptureActor.cs +++ b/OpenRA.Mods.RA/Activities/CaptureActor.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA.Activities public override Activity Tick(Actor self) { - if (!target.IsValid) + if (target.Type != TargetType.Actor) return NextActivity; var capturable = target.Actor.Trait(); diff --git a/OpenRA.Mods.RA/Activities/Demolish.cs b/OpenRA.Mods.RA/Activities/Demolish.cs index 2d9a9e0b26..5161cb7509 100644 --- a/OpenRA.Mods.RA/Activities/Demolish.cs +++ b/OpenRA.Mods.RA/Activities/Demolish.cs @@ -27,13 +27,13 @@ namespace OpenRA.Mods.RA.Activities public override Activity Tick(Actor self) { - if (IsCanceled || !target.IsValid) + if (IsCanceled || target.Type != TargetType.Actor) return NextActivity; self.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, () => { // Can't demolish an already dead actor - if (!target.IsValid) + if (target.Type != TargetType.Actor) return; // Invulnerable actors can't be demolished diff --git a/OpenRA.Mods.RA/Activities/DonateSupplies.cs b/OpenRA.Mods.RA/Activities/DonateSupplies.cs index 5d82168c76..4382f60895 100644 --- a/OpenRA.Mods.RA/Activities/DonateSupplies.cs +++ b/OpenRA.Mods.RA/Activities/DonateSupplies.cs @@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA.Activities public override Activity Tick(Actor self) { - if (IsCanceled || !target.IsValid || !target.IsActor) + if (IsCanceled || target.Type != TargetType.Actor) return NextActivity; var targetActor = target.Actor; diff --git a/OpenRA.Mods.RA/Activities/Enter.cs b/OpenRA.Mods.RA/Activities/Enter.cs index c4afe104b5..cddb4b1cf2 100755 --- a/OpenRA.Mods.RA/Activities/Enter.cs +++ b/OpenRA.Mods.RA/Activities/Enter.cs @@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA.Activities public override Activity Tick(Actor self) { - if (IsCanceled || !target.IsValid) + if (IsCanceled || target.Type != TargetType.Actor) return NextActivity; if (!Util.AdjacentCells(target).Any(c => c == self.Location)) diff --git a/OpenRA.Mods.RA/Activities/Heal.cs b/OpenRA.Mods.RA/Activities/Heal.cs index 199f89d041..ea000e910e 100755 --- a/OpenRA.Mods.RA/Activities/Heal.cs +++ b/OpenRA.Mods.RA/Activities/Heal.cs @@ -22,7 +22,7 @@ namespace OpenRA.Mods.RA.Activities 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 base.InnerTick(self, attack); diff --git a/OpenRA.Mods.RA/Activities/Infiltrate.cs b/OpenRA.Mods.RA/Activities/Infiltrate.cs index 60f1338442..9baad5547f 100644 --- a/OpenRA.Mods.RA/Activities/Infiltrate.cs +++ b/OpenRA.Mods.RA/Activities/Infiltrate.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Activities 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; foreach (var t in target.Actor.TraitsImplementing()) diff --git a/OpenRA.Mods.RA/Activities/LegacyCaptureActor.cs b/OpenRA.Mods.RA/Activities/LegacyCaptureActor.cs index 83d8dbad8d..8c2fb6d2ea 100644 --- a/OpenRA.Mods.RA/Activities/LegacyCaptureActor.cs +++ b/OpenRA.Mods.RA/Activities/LegacyCaptureActor.cs @@ -23,9 +23,7 @@ namespace OpenRA.Mods.RA.Activities public override Activity Tick(Actor self) { - if (IsCanceled) - return NextActivity; - if (!target.IsValid) + if (IsCanceled || target.Type != TargetType.Actor) return NextActivity; var b = target.Actor.TraitOrDefault(); diff --git a/OpenRA.Mods.RA/Activities/RepairBridge.cs b/OpenRA.Mods.RA/Activities/RepairBridge.cs index 90377a47e1..178eea6ce3 100644 --- a/OpenRA.Mods.RA/Activities/RepairBridge.cs +++ b/OpenRA.Mods.RA/Activities/RepairBridge.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Activities public override Activity Tick(Actor self) { - if (IsCanceled || !target.IsValid) + if (IsCanceled || target.Type != TargetType.Actor) return NextActivity; var hut = target.Actor.Trait(); diff --git a/OpenRA.Mods.RA/Activities/RepairBuilding.cs b/OpenRA.Mods.RA/Activities/RepairBuilding.cs index 8e5e4f4bc6..c5c13fafbe 100644 --- a/OpenRA.Mods.RA/Activities/RepairBuilding.cs +++ b/OpenRA.Mods.RA/Activities/RepairBuilding.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Activities public override Activity Tick(Actor self) { - if (IsCanceled || !target.IsValid) + if (IsCanceled || target.Type != TargetType.Actor) return NextActivity; var health = target.Actor.Trait(); diff --git a/OpenRA.Mods.RA/Attack/AttackBase.cs b/OpenRA.Mods.RA/Attack/AttackBase.cs index 9321698c67..94f2b5d8d0 100644 --- a/OpenRA.Mods.RA/Attack/AttackBase.cs +++ b/OpenRA.Mods.RA/Attack/AttackBase.cs @@ -54,7 +54,7 @@ namespace OpenRA.Mods.RA if (self.IsDisabled()) return false; - if (target.IsActor && target.Actor.HasTrait() && + if (target.Type == TargetType.Actor && target.Actor.HasTrait() && !target.Actor.Trait().TargetableBy(target.Actor,self)) return false; @@ -114,7 +114,7 @@ namespace OpenRA.Mods.RA { if (order is AttackOrderTargeter) { - if (target.IsActor) + if (target.Type == TargetType.Actor) return new Order("Attack", self, queued) { TargetActor = target.Actor }; else return new Order("Attack", self, queued) { TargetLocation = target.CenterPosition.ToCPos() }; diff --git a/OpenRA.Mods.RA/Attack/AttackLeap.cs b/OpenRA.Mods.RA/Attack/AttackLeap.cs index 75683b1673..9bfbed10cf 100644 --- a/OpenRA.Mods.RA/Attack/AttackLeap.cs +++ b/OpenRA.Mods.RA/Attack/AttackLeap.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA public override void DoAttack(Actor self, Target target) { - if (!CanAttack(self, target) || !target.IsActor) + if (target.Type != TargetType.Actor || !CanAttack(self, target)) return; var a = ChooseArmamentForTarget(target); diff --git a/OpenRA.Mods.RA/Attack/AttackTurreted.cs b/OpenRA.Mods.RA/Attack/AttackTurreted.cs index 06c944ce44..4708273e88 100644 --- a/OpenRA.Mods.RA/Attack/AttackTurreted.cs +++ b/OpenRA.Mods.RA/Attack/AttackTurreted.cs @@ -67,7 +67,7 @@ namespace OpenRA.Mods.RA base.ResolveOrder(self, order); if (order.OrderString == "Stop") - target = Target.None; + target = Target.Invalid; } public virtual void BuildingComplete(Actor self) { buildComplete = true; } diff --git a/OpenRA.Mods.RA/Move/Move.cs b/OpenRA.Mods.RA/Move/Move.cs index e3d8e79e0e..503b0bd2c8 100755 --- a/OpenRA.Mods.RA/Move/Move.cs +++ b/OpenRA.Mods.RA/Move/Move.cs @@ -258,7 +258,7 @@ namespace OpenRA.Mods.RA.Move return Enumerable.Reverse(path).Select(c => Target.FromCell(c)); if (destination != null) return new Target[] { Target.FromCell(destination.Value) }; - return Target.NoTargets; + return Target.None; } abstract class MovePart : Activity