From 40a9caddc7e849ef725a8b9b130dad21dc63d78e Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Thu, 8 Aug 2013 14:34:49 +1200 Subject: [PATCH] Add FrozenActor target type. --- OpenRA.Game/GameRules/WeaponInfo.cs | 16 ++++++++++ OpenRA.Game/Traits/Target.cs | 46 ++++++++++++++++++++--------- OpenRA.Game/Traits/Util.cs | 8 +---- OpenRA.Mods.RA/Activities/Attack.cs | 5 ++-- OpenRA.Mods.RA/Attack/AttackBase.cs | 12 ++++---- 5 files changed, 59 insertions(+), 28 deletions(-) diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 46ad55b65a..91efe67c56 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -149,11 +149,27 @@ namespace OpenRA.GameRules return true; } + public bool IsValidAgainst(FrozenActor a) + { + var targetable = a.Info.Traits.GetOrDefault(); + if (targetable == null || !ValidTargets.Intersect(targetable.GetTargetTypes()).Any()) + return false; + + if (Warheads.All(w => w.EffectivenessAgainst(a.Info) <= 0)) + return false; + + return true; + } + + public bool IsValidAgainst(Target target, World world) { if (target.Type == TargetType.Actor) return IsValidAgainst(target.Actor); + if (target.Type == TargetType.FrozenActor) + return IsValidAgainst(target.FrozenActor); + if (target.Type == TargetType.Terrain) { var cell = target.CenterPosition.ToCPos(); diff --git a/OpenRA.Game/Traits/Target.cs b/OpenRA.Game/Traits/Target.cs index 09c177ea13..bc7ae62151 100644 --- a/OpenRA.Game/Traits/Target.cs +++ b/OpenRA.Game/Traits/Target.cs @@ -14,7 +14,7 @@ using System.Linq; namespace OpenRA.Traits { - public enum TargetType { Invalid, Actor, Terrain } + public enum TargetType { Invalid, Actor, Terrain, FrozenActor } public struct Target { public static readonly Target[] None = {}; @@ -22,6 +22,7 @@ namespace OpenRA.Traits TargetType type; Actor actor; + FrozenActor frozen; WPos pos; int generation; @@ -44,8 +45,11 @@ namespace OpenRA.Traits }; } + public static Target FromFrozenActor(FrozenActor a) { return new Target { frozen = a, type = TargetType.FrozenActor }; } + public bool IsValid { get { return Type != TargetType.Invalid; } } public Actor Actor { get { return actor; } } + public FrozenActor FrozenActor { get { return frozen; } } public TargetType Type { @@ -71,10 +75,18 @@ namespace OpenRA.Traits { get { - if (Type == TargetType.Invalid) + switch (Type) + { + case TargetType.Actor: + return actor.CenterPosition; + case TargetType.FrozenActor: + return frozen.CenterPosition; + case TargetType.Terrain: + return pos; + default: + case TargetType.Invalid: throw new InvalidOperationException("Attempting to query the position of an invalid Target"); - - return actor != null ? actor.CenterPosition : pos; + } } } @@ -84,17 +96,23 @@ namespace OpenRA.Traits { get { - if (Type == TargetType.Invalid) + switch (Type) + { + case TargetType.Actor: + var targetable = actor.TraitOrDefault(); + if (targetable == null) + return new [] { actor.CenterPosition }; + + var positions = targetable.TargetablePositions(actor); + return positions.Any() ? positions : new [] { actor.CenterPosition }; + case TargetType.FrozenActor: + return new [] { frozen.CenterPosition }; + case TargetType.Terrain: + return new [] { pos }; + default: + case TargetType.Invalid: return NoPositions; - - if (actor == null) - return new []{pos}; - - var targetable = actor.TraitOrDefault(); - if (targetable == null) - return new []{actor.CenterPosition}; - - return targetable.TargetablePositions(actor); + } } } diff --git a/OpenRA.Game/Traits/Util.cs b/OpenRA.Game/Traits/Util.cs index c793944b5f..5e9119e8da 100755 --- a/OpenRA.Game/Traits/Util.cs +++ b/OpenRA.Game/Traits/Util.cs @@ -134,13 +134,7 @@ namespace OpenRA.Traits public static IEnumerable AdjacentCells(Target target) { - var cells = target.Type == TargetType.Actor - ? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray() - : new CPos[] { }; - - if (cells.Length == 0) - cells = new CPos[] { target.CenterPosition.ToCPos() }; - + var cells = target.Positions.Select(p => p.ToCPos()).Distinct(); return Util.ExpandFootprint(cells, true); } } diff --git a/OpenRA.Mods.RA/Activities/Attack.cs b/OpenRA.Mods.RA/Activities/Attack.cs index a6ccc10edb..0d8f045cd6 100755 --- a/OpenRA.Mods.RA/Activities/Attack.cs +++ b/OpenRA.Mods.RA/Activities/Attack.cs @@ -53,10 +53,11 @@ namespace OpenRA.Mods.RA.Activities if (IsCanceled) return NextActivity; - if (!Target.IsValid) + var type = Target.Type; + if (type != TargetType.Actor && type != TargetType.Terrain) return NextActivity; - if (!self.Owner.HasFogVisibility() && Target.Actor != null && Target.Actor.HasTrait() && !self.Owner.Shroud.IsTargetable(Target.Actor)) + if (type == TargetType.Actor && !self.Owner.HasFogVisibility() && Target.Actor.HasTrait() && !self.Owner.Shroud.IsTargetable(Target.Actor)) return NextActivity; if (targetable != null && !targetable.TargetableBy(Target.Actor, self)) diff --git a/OpenRA.Mods.RA/Attack/AttackBase.cs b/OpenRA.Mods.RA/Attack/AttackBase.cs index 7406e0be06..009a94d559 100644 --- a/OpenRA.Mods.RA/Attack/AttackBase.cs +++ b/OpenRA.Mods.RA/Attack/AttackBase.cs @@ -216,13 +216,15 @@ namespace OpenRA.Mods.RA public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) { - if (target.Type == TargetType.Actor) + switch (target.Type) + { + case TargetType.Actor: return CanTargetActor(self, target.Actor, modifiers, ref cursor); - - if (target.Type == TargetType.Terrain) + case TargetType.Terrain: return CanTargetLocation(self, target.CenterPosition.ToCPos(), othersAtTarget, modifiers, ref cursor); - - return false; + default: + return false; + } } public bool IsQueued { get; protected set; }