From f5c3575c5abb3d9e6ac103886f4a8ea003d4e077 Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Mon, 13 Jul 2015 15:22:39 -0500 Subject: [PATCH 1/9] Support multiple ITargetable traits --- OpenRA.Game/GameRules/WeaponInfo.cs | 8 ++++---- OpenRA.Game/Traits/Target.cs | 20 +++++++++++-------- OpenRA.Game/Traits/TraitsInterfaces.cs | 1 + OpenRA.Mods.Common/AI/States/StateBase.cs | 6 +++--- OpenRA.Mods.Common/AI/SupportPowerDecision.cs | 9 +++------ OpenRA.Mods.Common/Activities/Hunt.cs | 3 +-- .../Orders/UnitOrderTargeter.cs | 2 +- .../Traits/Air/TargetableAircraft.cs | 3 +-- .../Traits/Crates/DuplicateUnitCrateAction.cs | 4 ++-- OpenRA.Mods.Common/Traits/TargetableUnit.cs | 2 +- OpenRA.Mods.Common/Warheads/Warhead.cs | 9 +++++---- .../Traits/Infiltration/Infiltrates.cs | 7 ++++--- OpenRA.Mods.RA/Traits/TargetableSubmarine.cs | 3 +-- 13 files changed, 39 insertions(+), 38 deletions(-) diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index aacdb0fea9..6af645ce6b 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -125,8 +125,8 @@ namespace OpenRA.GameRules /// Checks if the weapon is valid against (can target) the actor. public bool IsValidAgainst(Actor victim, Actor firedBy) { - var targetable = victim.TraitOrDefault(); - if (targetable == null || !IsValidTarget(targetable.TargetTypes)) + var targetable = victim.TraitsImplementing().Where(Exts.IsTraitEnabled); + if (!IsValidTarget(targetable.SelectMany(t => t.TargetTypes))) return false; if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy))) @@ -138,8 +138,8 @@ namespace OpenRA.GameRules /// Checks if the weapon is valid against (can target) the frozen actor. public bool IsValidAgainst(FrozenActor victim, Actor firedBy) { - var targetable = victim.Info.Traits.GetOrDefault(); - if (targetable == null || !IsValidTarget(targetable.GetTargetTypes())) + var targetable = victim.Info.Traits.WithInterface(); + if (!IsValidTarget(targetable.SelectMany(t => t.GetTargetTypes()))) return false; if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy))) diff --git a/OpenRA.Game/Traits/Target.cs b/OpenRA.Game/Traits/Target.cs index d5261e04fa..bd0aa47018 100644 --- a/OpenRA.Game/Traits/Target.cs +++ b/OpenRA.Game/Traits/Target.cs @@ -22,7 +22,7 @@ namespace OpenRA.Traits TargetType type; Actor actor; - ITargetable targetable; + IEnumerable targetable; FrozenActor frozen; WPos pos; int generation; @@ -48,7 +48,7 @@ namespace OpenRA.Traits return new Target { actor = a, - targetable = a.TraitOrDefault(), + targetable = a.TraitsImplementing(), type = TargetType.Actor, generation = a.Generation, }; @@ -83,15 +83,18 @@ namespace OpenRA.Traits if (targeter == null || Type == TargetType.Invalid) return false; - if (targetable != null && !targetable.TargetableBy(actor, targeter)) + var targeted = this.actor; + if (targeted != null && !targetable.Any(t => t.IsTraitEnabled() && t.TargetableBy(targeted, targeter))) return false; return true; } + // Currently all or nothing. + // TODO: either replace based on target type or put in singleton trait public bool RequiresForceFire { - get { return targetable != null && targetable.RequiresForceFire; } + get { return targetable != null && targetable.Any(Exts.IsTraitEnabled) && targetable.Where(Exts.IsTraitEnabled).All(t => t.RequiresForceFire); } } // Representative position - see Positions for the full set of targetable positions. @@ -123,12 +126,13 @@ namespace OpenRA.Traits switch (Type) { case TargetType.Actor: - var targetable = actor.TraitOrDefault(); - if (targetable == null) + var targetable = actor.TraitsImplementing().Where(Exts.IsTraitEnabled); + if (!targetable.Any()) return new[] { actor.CenterPosition }; - var positions = targetable.TargetablePositions(actor); - return positions.Any() ? positions : new[] { actor.CenterPosition }; + var targeted = this.actor; + var positions = targetable.SelectMany(t => t.TargetablePositions(targeted)).Distinct(); + return positions.Any() ? positions : new[] { targeted.CenterPosition }; case TargetType.FrozenActor: return new[] { frozen.CenterPosition }; case TargetType.Terrain: diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index ffd7ebb581..0421dbc3ff 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -315,6 +315,7 @@ namespace OpenRA.Traits public interface ITargetable { + // Check IsTraitEnabled or !IsTraitDisabled first string[] TargetTypes { get; } IEnumerable TargetablePositions(Actor self); bool TargetableBy(Actor self, Actor byActor); diff --git a/OpenRA.Mods.Common/AI/States/StateBase.cs b/OpenRA.Mods.Common/AI/States/StateBase.cs index 7c898db728..fd255dbec5 100644 --- a/OpenRA.Mods.Common/AI/States/StateBase.cs +++ b/OpenRA.Mods.Common/AI/States/StateBase.cs @@ -63,13 +63,13 @@ namespace OpenRA.Mods.Common.AI if (!a.HasTrait()) return false; - var targetable = target.TraitOrDefault(); - if (targetable == null) + var targetTypes = target.TraitsImplementing().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes); + if (!targetTypes.Any()) return false; var arms = a.TraitsImplementing(); foreach (var arm in arms) - if (arm.Weapon.IsValidTarget(targetable.TargetTypes)) + if (arm.Weapon.IsValidTarget(targetTypes)) return true; return false; diff --git a/OpenRA.Mods.Common/AI/SupportPowerDecision.cs b/OpenRA.Mods.Common/AI/SupportPowerDecision.cs index a931e3b1de..13b0ad968c 100644 --- a/OpenRA.Mods.Common/AI/SupportPowerDecision.cs +++ b/OpenRA.Mods.Common/AI/SupportPowerDecision.cs @@ -125,14 +125,11 @@ namespace OpenRA.Mods.Common.AI if (a == null) return 0; - var targetable = a.TraitOrDefault(); - if (targetable == null) + var targetable = a.TraitsImplementing().Where(Exts.IsTraitEnabled); + if (!targetable.Any(t => t.TargetableBy(a, firedBy.PlayerActor))) return 0; - if (!targetable.TargetableBy(a, firedBy.PlayerActor)) - return 0; - - if (Types.Intersect(targetable.TargetTypes).Any()) + if (Types.Intersect(targetable.SelectMany(t => t.TargetTypes)).Any()) { switch (TargetMetric) { diff --git a/OpenRA.Mods.Common/Activities/Hunt.cs b/OpenRA.Mods.Common/Activities/Hunt.cs index af520042c6..55ff87989d 100644 --- a/OpenRA.Mods.Common/Activities/Hunt.cs +++ b/OpenRA.Mods.Common/Activities/Hunt.cs @@ -29,8 +29,7 @@ namespace OpenRA.Mods.Common.Activities bool IsTargetable(Actor self, Actor viewer) { - var targetable = self.TraitOrDefault(); - return targetable != null && targetable.TargetableBy(self, viewer); + return self.TraitsImplementing().Any(t => t.IsTraitEnabled() && t.TargetableBy(self, viewer)); } public override Activity Tick(Actor self) diff --git a/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs b/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs index 13ac615446..175da6c5b4 100644 --- a/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs +++ b/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs @@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Orders public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - return target.TraitsImplementing().Any(t => t.TargetTypes.Intersect(targetTypes).Any()); + return target.TraitsImplementing().Any(t => t.IsTraitEnabled() && t.TargetTypes.Intersect(targetTypes).Any()); } public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) diff --git a/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs b/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs index e8d9924197..fbd60e8003 100644 --- a/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs @@ -35,8 +35,7 @@ namespace OpenRA.Mods.Common.Traits { get { - return IsTraitDisabled ? None - : (self.CenterPosition.Z > 0 ? info.TargetTypes : info.GroundedTargetTypes); + return (self.CenterPosition.Z > 0) ? info.TargetTypes : info.GroundedTargetTypes; } } } diff --git a/OpenRA.Mods.Common/Traits/Crates/DuplicateUnitCrateAction.cs b/OpenRA.Mods.Common/Traits/Crates/DuplicateUnitCrateAction.cs index bfb78ec27b..f6a83327a6 100644 --- a/OpenRA.Mods.Common/Traits/Crates/DuplicateUnitCrateAction.cs +++ b/OpenRA.Mods.Common/Traits/Crates/DuplicateUnitCrateAction.cs @@ -57,8 +57,8 @@ namespace OpenRA.Mods.Common.Traits if (info.ValidFactions.Any() && !info.ValidFactions.Contains(collector.Owner.Faction.InternalName)) return false; - var targetable = collector.Info.Traits.GetOrDefault(); - if (targetable == null || !info.ValidTargets.Intersect(targetable.GetTargetTypes()).Any()) + var targetable = collector.TraitsImplementing(); + if (!info.ValidTargets.Intersect(targetable.SelectMany(t => t.TargetTypes)).Any()) return false; var positionable = collector.TraitOrDefault(); diff --git a/OpenRA.Mods.Common/Traits/TargetableUnit.cs b/OpenRA.Mods.Common/Traits/TargetableUnit.cs index 733c792b10..aa6c25fc6a 100644 --- a/OpenRA.Mods.Common/Traits/TargetableUnit.cs +++ b/OpenRA.Mods.Common/Traits/TargetableUnit.cs @@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.Traits return cloak.IsVisible(self, viewer.Owner); } - public virtual string[] TargetTypes { get { return IsTraitDisabled ? None : Info.TargetTypes; } } + public virtual string[] TargetTypes { get { return Info.TargetTypes; } } public virtual IEnumerable TargetablePositions(Actor self) { diff --git a/OpenRA.Mods.Common/Warheads/Warhead.cs b/OpenRA.Mods.Common/Warheads/Warhead.cs index 42cbe57661..b9b3e1c1a6 100644 --- a/OpenRA.Mods.Common/Warheads/Warhead.cs +++ b/OpenRA.Mods.Common/Warheads/Warhead.cs @@ -9,6 +9,7 @@ #endregion using System.Collections.Generic; +using System.Linq; using OpenRA.Traits; namespace OpenRA.Mods.Common.Warheads @@ -58,8 +59,8 @@ namespace OpenRA.Mods.Common.Warheads return false; // A target type is valid if it is in the valid targets list, and not in the invalid targets list. - var targetable = victim.TraitOrDefault(); - if (targetable == null || !IsValidTarget(targetable.TargetTypes)) + var targetable = victim.TraitsImplementing().Where(Exts.IsTraitEnabled); + if (!IsValidTarget(targetable.SelectMany(t => t.TargetTypes))) return false; return true; @@ -74,8 +75,8 @@ namespace OpenRA.Mods.Common.Warheads return false; // A target type is valid if it is in the valid targets list, and not in the invalid targets list. - var targetable = victim.Info.Traits.GetOrDefault(); - if (targetable == null || !IsValidTarget(targetable.GetTargetTypes())) + var targetable = victim.Info.Traits.WithInterface(); + if (!IsValidTarget(targetable.SelectMany(t => t.GetTargetTypes()))) return false; return true; diff --git a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs index a53da96ba1..f8c4e6ace8 100644 --- a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs +++ b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs @@ -79,8 +79,8 @@ namespace OpenRA.Mods.RA.Traits else ai = order.TargetActor.Info; - var i = ai.Traits.GetOrDefault(); - return i != null && i.GetTargetTypes().Intersect(Info.Types).Any(); + return ai.Traits.WithInterface() + .SelectMany(t => t.GetTargetTypes()).Intersect(Info.Types).Any(); } public string VoicePhraseForOrder(Actor self, Order order) @@ -95,7 +95,8 @@ namespace OpenRA.Mods.RA.Traits return; var target = self.ResolveFrozenActorOrder(order, Color.Red); - if (target.Type != TargetType.Actor) + if (target.Type != TargetType.Actor + || target.Actor.TraitsImplementing().SelectMany(t => t.TargetTypes).Intersect(Info.Types).Any()) return; if (!order.Queued) diff --git a/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs b/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs index f90d1d79aa..c5aad54b27 100644 --- a/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs +++ b/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs @@ -34,8 +34,7 @@ namespace OpenRA.Mods.RA.Traits { get { - return IsTraitDisabled ? None - : (cloak.Cloaked ? info.CloakedTargetTypes : info.TargetTypes); + return cloak.Cloaked ? info.CloakedTargetTypes : info.TargetTypes; } } } From 23d04244379d353198cda658f0861e58316a3251 Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Mon, 13 Jul 2015 15:22:39 -0500 Subject: [PATCH 2/9] Add ITargetablePositions seperating it from ITargetable --- OpenRA.Game/Traits/Target.cs | 12 +++-- OpenRA.Game/Traits/TraitsInterfaces.cs | 6 ++- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 3 +- .../Traits/Air/TargetableAircraft.cs | 4 +- .../Traits/Buildings/Building.cs | 7 ++- .../Traits/Buildings/TargetableBuilding.cs | 49 ------------------- .../{TargetableUnit.cs => Targetable.cs} | 13 ++--- .../UtilityCommands/UpgradeRules.cs | 11 +++++ OpenRA.Mods.RA/Traits/TargetableSubmarine.cs | 4 +- mods/cnc/maps/nod05/map.yaml | 2 +- mods/cnc/rules/civilian.yaml | 2 +- mods/cnc/rules/defaults.yaml | 20 ++++---- mods/cnc/rules/vehicles.yaml | 2 +- mods/d2k/rules/arrakis.yaml | 2 +- mods/d2k/rules/defaults.yaml | 8 +-- mods/d2k/rules/structures.yaml | 2 +- mods/ra/maps/allies-03a/map.yaml | 14 ++---- mods/ra/maps/allies-03b/map.yaml | 16 ++---- mods/ra/maps/allies-05a/map.yaml | 6 +-- mods/ra/maps/koth-hopes-anchor/map.yaml | 2 +- mods/ra/maps/monster-tank-madness/map.yaml | 2 +- mods/ra/maps/survival01/map.yaml | 2 +- mods/ra/rules/civilian.yaml | 10 ++-- mods/ra/rules/defaults.yaml | 22 ++++----- mods/ra/rules/fakes.yaml | 4 +- mods/ra/rules/infantry.yaml | 4 +- mods/ra/rules/misc.yaml | 6 +-- mods/ra/rules/ships.yaml | 4 +- mods/ra/rules/structures.yaml | 22 ++++----- mods/ra/rules/vehicles.yaml | 2 +- mods/ts/rules/civilian-infantry.yaml | 2 +- mods/ts/rules/defaults.yaml | 14 +++--- mods/ts/rules/gdi-structures.yaml | 4 +- mods/ts/rules/nod-structures.yaml | 6 +-- 34 files changed, 124 insertions(+), 165 deletions(-) delete mode 100644 OpenRA.Mods.Common/Traits/Buildings/TargetableBuilding.cs rename OpenRA.Mods.Common/Traits/{TargetableUnit.cs => Targetable.cs} (78%) diff --git a/OpenRA.Game/Traits/Target.cs b/OpenRA.Game/Traits/Target.cs index bd0aa47018..d8c8e3fff3 100644 --- a/OpenRA.Game/Traits/Target.cs +++ b/OpenRA.Game/Traits/Target.cs @@ -130,9 +130,15 @@ namespace OpenRA.Traits if (!targetable.Any()) return new[] { actor.CenterPosition }; - var targeted = this.actor; - var positions = targetable.SelectMany(t => t.TargetablePositions(targeted)).Distinct(); - return positions.Any() ? positions : new[] { targeted.CenterPosition }; + var targetablePositions = actor.TraitOrDefault(); + if (targetablePositions != null) + { + var positions = targetablePositions.TargetablePositions(actor); + if (positions.Any()) + return positions; + } + + return new[] { actor.CenterPosition }; case TargetType.FrozenActor: return new[] { frozen.CenterPosition }; case TargetType.Terrain: diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 0421dbc3ff..bef29acbf8 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -317,11 +317,15 @@ namespace OpenRA.Traits { // Check IsTraitEnabled or !IsTraitDisabled first string[] TargetTypes { get; } - IEnumerable TargetablePositions(Actor self); bool TargetableBy(Actor self, Actor byActor); bool RequiresForceFire { get; } } + public interface ITargetablePositions + { + IEnumerable TargetablePositions(Actor self); + } + public interface INotifyStanceChanged { void StanceChanged(Actor self, Player a, Player b, diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index aa9da4dc8c..e319012def 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -293,7 +293,6 @@ - @@ -476,7 +475,7 @@ - + diff --git a/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs b/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs index fbd60e8003..0bb6f759f6 100644 --- a/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs @@ -13,13 +13,13 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { - public class TargetableAircraftInfo : TargetableUnitInfo + public class TargetableAircraftInfo : TargetableInfo { public readonly string[] GroundedTargetTypes = { }; public override object Create(ActorInitializer init) { return new TargetableAircraft(init.Self, this); } } - public class TargetableAircraft : TargetableUnit + public class TargetableAircraft : Targetable { readonly TargetableAircraftInfo info; readonly Actor self; diff --git a/OpenRA.Mods.Common/Traits/Buildings/Building.cs b/OpenRA.Mods.Common/Traits/Buildings/Building.cs index ab0cdca8f5..2275addc09 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Building.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Building.cs @@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Traits bool IOccupySpaceInfo.SharesCell { get { return false; } } } - public class Building : IOccupySpace, INotifySold, INotifyTransform, ISync, INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld + public class Building : IOccupySpace, INotifySold, INotifyTransform, ISync, INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, ITargetablePositions { public readonly BuildingInfo Info; public bool BuildComplete { get; private set; } @@ -157,6 +157,11 @@ namespace OpenRA.Mods.Common.Traits Pair[] occupiedCells; public IEnumerable> OccupiedCells() { return occupiedCells; } + public IEnumerable TargetablePositions(Actor self) + { + return OccupiedCells().Select(c => self.World.Map.CenterOfCell(c.First)); + } + public void Created(Actor self) { if (SkipMakeAnimation || !self.HasTrait()) diff --git a/OpenRA.Mods.Common/Traits/Buildings/TargetableBuilding.cs b/OpenRA.Mods.Common/Traits/Buildings/TargetableBuilding.cs deleted file mode 100644 index e81b8fafbc..0000000000 --- a/OpenRA.Mods.Common/Traits/Buildings/TargetableBuilding.cs +++ /dev/null @@ -1,49 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using System.Collections.Generic; -using System.Linq; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - public class TargetableBuildingInfo : ITraitInfo, ITargetableInfo, Requires - { - [FieldLoader.Require] - public readonly string[] TargetTypes = { }; - public string[] GetTargetTypes() { return TargetTypes; } - - public bool RequiresForceFire = false; - - public object Create(ActorInitializer init) { return new TargetableBuilding(init.Self, this); } - } - - public class TargetableBuilding : ITargetable - { - readonly TargetableBuildingInfo info; - readonly Building building; - - public TargetableBuilding(Actor self, TargetableBuildingInfo info) - { - this.info = info; - building = self.Trait(); - } - - public string[] TargetTypes { get { return info.TargetTypes; } } - public bool TargetableBy(Actor self, Actor byActor) { return true; } - - public IEnumerable TargetablePositions(Actor self) - { - return building.OccupiedCells().Select(c => self.World.Map.CenterOfCell(c.First)); - } - - public bool RequiresForceFire { get { return info.RequiresForceFire; } } - } -} diff --git a/OpenRA.Mods.Common/Traits/TargetableUnit.cs b/OpenRA.Mods.Common/Traits/Targetable.cs similarity index 78% rename from OpenRA.Mods.Common/Traits/TargetableUnit.cs rename to OpenRA.Mods.Common/Traits/Targetable.cs index aa6c25fc6a..c7323aa7c5 100644 --- a/OpenRA.Mods.Common/Traits/TargetableUnit.cs +++ b/OpenRA.Mods.Common/Traits/Targetable.cs @@ -14,7 +14,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Actor can be targeted.")] - public class TargetableUnitInfo : UpgradableTraitInfo, ITargetableInfo + public class TargetableInfo : UpgradableTraitInfo, ITargetableInfo { [Desc("Target type. Used for filtering (in)valid targets.")] public readonly string[] TargetTypes = { }; @@ -22,15 +22,15 @@ namespace OpenRA.Mods.Common.Traits public bool RequiresForceFire = false; - public override object Create(ActorInitializer init) { return new TargetableUnit(init.Self, this); } + public override object Create(ActorInitializer init) { return new Targetable(init.Self, this); } } - public class TargetableUnit : UpgradableTrait, ITargetable + public class Targetable : UpgradableTrait, ITargetable { protected static readonly string[] None = new string[] { }; protected Cloak cloak; - public TargetableUnit(Actor self, TargetableUnitInfo info) + public Targetable(Actor self, TargetableInfo info) : base(info) { cloak = self.TraitOrDefault(); @@ -48,11 +48,6 @@ namespace OpenRA.Mods.Common.Traits public virtual string[] TargetTypes { get { return Info.TargetTypes; } } - public virtual IEnumerable TargetablePositions(Actor self) - { - yield return self.CenterPosition; - } - public bool RequiresForceFire { get { return Info.RequiresForceFire; } } } } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index ab12a839f0..3d7b71b5d4 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -1965,6 +1965,17 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + if (engineVersion < 20150902) + { + if (depth == 1) + { + if (node.Key == "TargetableUnit" || node.Key == "TargetableBuilding") + node.Key = "Targetable"; + else if (node.Key == "-TargetableUnit" || node.Key == "-TargetableBuilding") + node.Key = "-Targetable"; + } + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs b/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs index c5aad54b27..941caaa9fa 100644 --- a/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs +++ b/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs @@ -13,14 +13,14 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Traits { - public class TargetableSubmarineInfo : TargetableUnitInfo, Requires + public class TargetableSubmarineInfo : TargetableInfo, Requires { public readonly string[] CloakedTargetTypes = { }; public override object Create(ActorInitializer init) { return new TargetableSubmarine(init.Self, this); } } - public class TargetableSubmarine : TargetableUnit + public class TargetableSubmarine : Targetable { readonly TargetableSubmarineInfo info; diff --git a/mods/cnc/maps/nod05/map.yaml b/mods/cnc/maps/nod05/map.yaml index 95351d7f8c..7c202a329f 100644 --- a/mods/cnc/maps/nod05/map.yaml +++ b/mods/cnc/maps/nod05/map.yaml @@ -511,7 +511,7 @@ Rules: Buildable: Prerequisites: ~disabled A10: - TargetableUnit: + Targetable: Sequences: diff --git a/mods/cnc/rules/civilian.yaml b/mods/cnc/rules/civilian.yaml index ce160cf1bd..73a453b466 100644 --- a/mods/cnc/rules/civilian.yaml +++ b/mods/cnc/rules/civilian.yaml @@ -374,7 +374,7 @@ BRIDGEHUT: CustomSelectionSize: CustomBounds: 48,48 BridgeHut: - TargetableBuilding: + Targetable: TargetTypes: BridgeHut, C4 C1: diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index f5ef357ec2..115d76afc8 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -64,7 +64,7 @@ SelectionDecorations: Selectable: Bounds: 24,24 - TargetableUnit: + Targetable: TargetTypes: Ground, Vehicle Repairable: Passenger: @@ -172,7 +172,7 @@ SelectionDecorations: Selectable: Bounds: 12,17,0,-6 - TargetableUnit: + Targetable: TargetTypes: Ground, Infantry RenderSprites: QuantizeFacingsFromSequence: @@ -302,7 +302,7 @@ SelectionDecorations: Selectable: Bounds: 24,24 - TargetableUnit: + Targetable: TargetTypes: Ground HiddenUnderFog: QuantizeFacingsFromSequence: @@ -346,7 +346,7 @@ SelectionDecorations: Selectable: Bounds: 24,24 - TargetableUnit: + Targetable: TargetTypes: Ground AutoTarget: ScanRadius: 5 @@ -405,7 +405,7 @@ Water: 100 SelectionDecorations: Selectable: - TargetableUnit: + Targetable: TargetTypes: Ground, Water HiddenUnderFog: ActorLostNotification: @@ -421,7 +421,7 @@ SelectionDecorations: Selectable: Priority: 3 - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, Structure Armor: Type: Wood @@ -520,7 +520,7 @@ Tooltip: Name: Field -WithBuildingExplosion: - -TargetableBuilding: + -Targetable: -Demolishable: RenderSprites: Palette: terrain @@ -553,7 +553,7 @@ BuildSounds: hvydoor1.aud Adjacent: 7 TerrainTypes: Clear,Road - TargetableBuilding: + Targetable: TargetTypes: Ground, Wall Crushable: CrushClasses: wall @@ -662,7 +662,7 @@ AllowedTerrain: Clear, Rough, Road, Tiberium, BlueTiberium, Beach Burns: Interval: 2 - TargetableUnit: + Targetable: RequiresForceFire: yes TargetTypes: Ground, Husk Capturable: @@ -692,7 +692,7 @@ AlwaysVisible: Tooltip: Name: Bridge - TargetableBuilding: + Targetable: RequiresForceFire: yes TargetTypes: Ground, Water Health: diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml index 4591d5b62b..31c0657e6c 100644 --- a/mods/cnc/rules/vehicles.yaml +++ b/mods/cnc/rules/vehicles.yaml @@ -528,7 +528,7 @@ STNK: AttackFrontal: AutoTarget: InitialStance: HoldFire - TargetableUnit: + Targetable: SpawnActorOnDeath: Actor: STNK.Husk -MustBeDestroyed: diff --git a/mods/d2k/rules/arrakis.yaml b/mods/d2k/rules/arrakis.yaml index 2b442e5c74..8c68b70537 100644 --- a/mods/d2k/rules/arrakis.yaml +++ b/mods/d2k/rules/arrakis.yaml @@ -34,7 +34,7 @@ sandworm: Sand: 100 Dune: 100 Spice: 100 - TargetableUnit: + Targetable: TargetTypes: Ground WithFacingSpriteBody: WithAttackOverlay: diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index a00606d90d..d00a0e2d94 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -65,7 +65,7 @@ SelectionDecorations: Selectable: Bounds: 32,32 - TargetableUnit: + Targetable: TargetTypes: Ground, Vehicle, C4 Passenger: CargoType: Vehicle @@ -130,7 +130,7 @@ AllowedTerrain: Sand, Rock, Transition, Concrete, Spice, SpiceBlobs, Dune Burns: Interval: 4 - TargetableUnit: + Targetable: TargetTypes: Ground, Vehicle RequiresForceFire: yes Capturable: @@ -188,7 +188,7 @@ SelectionDecorations: Selectable: Bounds: 12,18,0,-6 - TargetableUnit: + Targetable: TargetTypes: Ground, Infantry UpgradeTypes: parachute UpgradeMaxEnabledLevel: 0 @@ -260,7 +260,7 @@ SelectionDecorations: Selectable: Priority: 2 - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, Structure Building: Dimensions: 1,1 diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index d1fe88a150..ee1901cdc0 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -509,7 +509,7 @@ wall: NodeTypes: wall, turret LineBuildNode: Types: wall - TargetableBuilding: + Targetable: TargetTypes: Ground, Wall RenderSprites: WithWallSpriteBody: diff --git a/mods/ra/maps/allies-03a/map.yaml b/mods/ra/maps/allies-03a/map.yaml index 1db802e6ab..9e3dde8905 100644 --- a/mods/ra/maps/allies-03a/map.yaml +++ b/mods/ra/maps/allies-03a/map.yaml @@ -1382,21 +1382,15 @@ Rules: -ExternalCaptures: Captures: CaptureTypes: building - Cloak@JAIL: + Targetable: UpgradeTypes: jail - UpgradeMinEnabledLevel: 1 - InitialDelay: 0 - CloakDelay: 0 - Palette: + UpgradeMaxEnabledLevel: 0 RenderSprites: Image: E6 MEDI: - Cloak@JAIL: + Targetable: UpgradeTypes: jail - UpgradeMinEnabledLevel: 1 - InitialDelay: 0 - CloakDelay: 0 - Palette: + UpgradeMaxEnabledLevel: 0 E7.noautotarget: Inherits: E7 AutoTarget: diff --git a/mods/ra/maps/allies-03b/map.yaml b/mods/ra/maps/allies-03b/map.yaml index 04745b5ce6..079d37d80f 100644 --- a/mods/ra/maps/allies-03b/map.yaml +++ b/mods/ra/maps/allies-03b/map.yaml @@ -1278,21 +1278,15 @@ Rules: Captures: CaptureTypes: building WithInfantryBody: - Cloak@JAIL: + Targetable: UpgradeTypes: jail - UpgradeMinEnabledLevel: 1 - InitialDelay: 0 - CloakDelay: 0 - Palette: + UpgradeMaxEnabledLevel: 0 RenderSprites: Image: E6 MEDI: - Cloak@JAIL: + Targetable: UpgradeTypes: jail - UpgradeMinEnabledLevel: 1 - InitialDelay: 0 - CloakDelay: 0 - Palette: + UpgradeMaxEnabledLevel: 0 E7.noautotarget: Inherits: E7 AutoTarget: @@ -1385,7 +1379,7 @@ Rules: -Selectable: -Demolishable: -Huntable: - -TargetableUnit: + -Targetable: -Armament: -WithMuzzleFlash: Cargo: diff --git a/mods/ra/maps/allies-05a/map.yaml b/mods/ra/maps/allies-05a/map.yaml index 48e58ce393..9dd53ff6e1 100644 --- a/mods/ra/maps/allies-05a/map.yaml +++ b/mods/ra/maps/allies-05a/map.yaml @@ -1651,7 +1651,7 @@ Rules: Prerequisites: ~disabled LST: -Selectable: - TargetableUnit: + Targetable: TargetTypes: Ground, Water Tooltip: GenericVisibility: Enemy @@ -1696,13 +1696,13 @@ Rules: ShowOwnerRow: false WEAP: -InfiltrateForSupportPower: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, Structure, Mission Objectives MISS: Tooltip: Name: Prison ShowOwnerRow: False - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, Structure, Mission Objectives E7.noautotarget: Inherits: E7 diff --git a/mods/ra/maps/koth-hopes-anchor/map.yaml b/mods/ra/maps/koth-hopes-anchor/map.yaml index d413d0e478..50174a9578 100644 --- a/mods/ra/maps/koth-hopes-anchor/map.yaml +++ b/mods/ra/maps/koth-hopes-anchor/map.yaml @@ -644,7 +644,7 @@ Rules: DamageMultiplier@INVULNERABLE: Modifier: 0 -Selectable: - -TargetableBuilding: + -Targetable: Player: StrategicVictoryConditions: TicksToHold: 3000 diff --git a/mods/ra/maps/monster-tank-madness/map.yaml b/mods/ra/maps/monster-tank-madness/map.yaml index 011807840e..949cf039f8 100644 --- a/mods/ra/maps/monster-tank-madness/map.yaml +++ b/mods/ra/maps/monster-tank-madness/map.yaml @@ -2241,7 +2241,7 @@ Rules: RenderSprites: Image: DOME -InfiltrateForExploration: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, MissionObjective SPY: Infiltrates: diff --git a/mods/ra/maps/survival01/map.yaml b/mods/ra/maps/survival01/map.yaml index 9740347103..5cabc1f8bb 100644 --- a/mods/ra/maps/survival01/map.yaml +++ b/mods/ra/maps/survival01/map.yaml @@ -1282,7 +1282,7 @@ Rules: Power: Amount: 0 -Selectable: - -TargetableBuilding: + -Targetable: -GivesBuildableArea: -Huntable: RenderSprites: diff --git a/mods/ra/rules/civilian.yaml b/mods/ra/rules/civilian.yaml index d9b74437af..e49ce53d38 100644 --- a/mods/ra/rules/civilian.yaml +++ b/mods/ra/rules/civilian.yaml @@ -242,7 +242,7 @@ V19.Husk: Sequence: fire-loop -Health: -Selectable: - -TargetableBuilding: + -Targetable: -Demolishable: BARL: @@ -259,7 +259,7 @@ BARL: AutoTargetIgnore: Armor: Type: None - TargetableBuilding: + Targetable: TargetTypes: Ground, DemoTruck -ShakeOnDeath: -SoundOnDamageTransition: @@ -279,7 +279,7 @@ BRL3: AutoTargetIgnore: Armor: Type: None - TargetableBuilding: + Targetable: TargetTypes: Ground, DemoTruck -ShakeOnDeath: -SoundOnDamageTransition: @@ -497,7 +497,7 @@ BRIDGEHUT: CustomSelectionSize: CustomBounds: 48,48 BridgeHut: - TargetableBuilding: + Targetable: TargetTypes: BridgeHut, C4 BRIDGEHUT.small: @@ -508,7 +508,7 @@ BRIDGEHUT.small: CustomSelectionSize: CustomBounds: 24,24 BridgeHut: - TargetableBuilding: + Targetable: TargetTypes: BridgeHut, C4 V20: diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 1d39ccdaea..83d2b684fe 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -77,7 +77,7 @@ SelectionDecorations: Selectable: Bounds: 24, 24 - TargetableUnit: + Targetable: TargetTypes: Ground, Repair, Vehicle UpgradeTypes: parachute UpgradeMaxEnabledLevel: 0 @@ -149,7 +149,7 @@ Ore: 70 Gems: 70 Beach: 70 - TargetableUnit: + Targetable: TargetTypes: Ground, C4, Repair, Tank ProximityCaptor: Types: Tank @@ -181,7 +181,7 @@ SelectionDecorations: Selectable: Bounds: 12,18,0,-8 - TargetableUnit: + Targetable: TargetTypes: Ground, Infantry, Disguise UpgradeTypes: parachute UpgradeMaxEnabledLevel: 0 @@ -299,7 +299,7 @@ SelectionDecorations: Selectable: Bounds: 24,24 - TargetableUnit: + Targetable: TargetTypes: Ground, Water, Repair HiddenUnderFog: AttackMove: @@ -385,7 +385,7 @@ SelectionDecorations: Selectable: Priority: 3 - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, Structure Building: Dimensions: 1,1 @@ -433,7 +433,7 @@ ^Defense: Inherits: ^Building - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, Structure, Defense MustBeDestroyed: RequiredForShortGame: false @@ -462,7 +462,7 @@ NodeTypes: wall LineBuildNode: Types: wall - TargetableBuilding: + Targetable: TargetTypes: Ground, DetonateAttack, Wall RenderSprites: Palette: effect @@ -518,7 +518,7 @@ AutoTargetIgnore: Armor: Type: Light - TargetableBuilding: + Targetable: TargetTypes: Ground, DetonateAttack ^CivBuilding: @@ -533,7 +533,7 @@ -Selectable: Tooltip: Name: Field - -TargetableBuilding: + -Targetable: -Demolishable: ProximityCaptor: Types: CivilianField @@ -598,7 +598,7 @@ TransformOnCapture: ForceHealthPercentage: 25 DisabledOverlay: - TargetableUnit: + Targetable: TargetTypes: Ground, Husk RequiresForceFire: true Chronoshiftable: @@ -625,7 +625,7 @@ AlwaysVisible: Tooltip: Name: Bridge - TargetableBuilding: + Targetable: TargetTypes: Ground, Water RequiresForceFire: true Building: diff --git a/mods/ra/rules/fakes.yaml b/mods/ra/rules/fakes.yaml index ee8d3226a6..03156e202c 100644 --- a/mods/ra/rules/fakes.yaml +++ b/mods/ra/rules/fakes.yaml @@ -57,7 +57,7 @@ SYRF: GenericName: Shipyard GenericVisibility: Enemy GenericStancePrefix: False - TargetableBuilding: + Targetable: TargetTypes: Ground, Water Building: Footprint: xxx xxx xxx @@ -73,7 +73,7 @@ SYRF: SPEF: Inherits: ^FakeBuilding - TargetableBuilding: + Targetable: TargetTypes: Ground, Water Buildable: BuildPaletteOrder: 910 diff --git a/mods/ra/rules/infantry.yaml b/mods/ra/rules/infantry.yaml index 3e146ea846..bb368b3588 100644 --- a/mods/ra/rules/infantry.yaml +++ b/mods/ra/rules/infantry.yaml @@ -32,7 +32,7 @@ DOG: Voice: Attack AttackMove: Voice: Move - TargetableUnit: + Targetable: TargetTypes: Ground, Infantry WithInfantryBody: AttackSequence: shoot @@ -587,7 +587,7 @@ Ant: AttackSequence: bite Armament: Weapon: mandible - TargetableUnit: + Targetable: TargetTypes: Ground, Infantry WithDeathAnimation: UseDeathTypeSuffix: false diff --git a/mods/ra/rules/misc.yaml b/mods/ra/rules/misc.yaml index ecf82012b5..29306efdf3 100644 --- a/mods/ra/rules/misc.yaml +++ b/mods/ra/rules/misc.yaml @@ -22,7 +22,7 @@ MINP: Name: Mine ProximityCaptor: Types: Mine - TargetableUnit: + Targetable: TargetTypes: Ground BodyOrientation: QuantizedFacings: 1 @@ -53,7 +53,7 @@ MINV: Name: Mine ProximityCaptor: Types: Mine - TargetableUnit: + Targetable: TargetTypes: Ground BodyOrientation: QuantizedFacings: 1 @@ -431,5 +431,5 @@ CTFLAG: DamageMultiplier@INVULNERABLE: Modifier: 0 -Selectable: - -TargetableBuilding: + -Targetable: diff --git a/mods/ra/rules/ships.yaml b/mods/ra/rules/ships.yaml index 88a30d1686..1ae7d98ce6 100644 --- a/mods/ra/rules/ships.yaml +++ b/mods/ra/rules/ships.yaml @@ -19,7 +19,7 @@ SS: Speed: 71 RevealsShroud: Range: 6c0 - -TargetableUnit: + -Targetable: TargetableSubmarine: TargetTypes: Ground, Water, Repair CloakedTargetTypes: Underwater, Repair @@ -68,7 +68,7 @@ MSUB: Speed: 42 RevealsShroud: Range: 6c0 - -TargetableUnit: + -Targetable: TargetableSubmarine: TargetTypes: Ground, Water, Repair CloakedTargetTypes: Underwater, Repair diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 851f536b3c..27c6662fbd 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -100,7 +100,7 @@ SPEN: Queue: Building BuildPaletteOrder: 50 Prerequisites: anypower, ~structures.soviet, ~techlevel.low - TargetableBuilding: + Targetable: TargetTypes: Ground, Water, C4, DetonateAttack, SpyInfiltrate Building: Footprint: xxx xxx xxx @@ -181,7 +181,7 @@ SYRD: Tooltip: Name: Shipyard Description: Produces and repairs ships\nand transports. - TargetableBuilding: + Targetable: TargetTypes: Ground, Water, C4, DetonateAttack, SpyInfiltrate Building: Footprint: xxx xxx xxx @@ -476,7 +476,7 @@ DOME: Building: Footprint: xx xx Dimensions: 2,2 - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate RequiresPower: CanPowerDown: @@ -823,7 +823,7 @@ WEAP: Power: Amount: -30 ProvidesPrerequisite@buildingname: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate InfiltrateForSupportPower: Proxy: vehicles.upgraded @@ -920,7 +920,7 @@ PROC: Bounds: 72,50,0,12 SelectionDecorations: VisualBounds: 72,70,0,-2 - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate Health: HP: 900 @@ -1050,7 +1050,7 @@ HPAD: RequiresPrerequisites: structures.germany Prerequisite: aircraft.germany ProvidesPrerequisite@buildingname: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate InfiltrateForSupportPower: Proxy: aircraft.upgraded @@ -1159,7 +1159,7 @@ AFLD: Power: Amount: -20 ProvidesPrerequisite@buildingname: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate InfiltrateForSupportPower: Proxy: aircraft.upgraded @@ -1191,7 +1191,7 @@ POWR: Amount: 100 InfiltrateForPowerOutage: AffectedByPowerOutage: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate ScalePowerWithHealth: DisabledOverlay: @@ -1232,7 +1232,7 @@ APWR: Amount: 200 InfiltrateForPowerOutage: AffectedByPowerOutage: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate ScalePowerWithHealth: DisabledOverlay: @@ -1332,7 +1332,7 @@ BARR: ProvidesPrerequisite@buildingname: InfiltrateForSupportPower: Proxy: barracks.upgraded - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate KENN: @@ -1439,7 +1439,7 @@ TENT: ProvidesPrerequisite@buildingname: InfiltrateForSupportPower: Proxy: barracks.upgraded - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, Structure, SpyInfiltrate FIX: diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index e5c7946ab8..5d28012b62 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -699,7 +699,7 @@ QTNK: VisualBounds: 44,38,0,-4 MadTank: -EjectOnDeath: - TargetableUnit: + Targetable: TargetTypes: Ground, MADTank, Repair STNK: diff --git a/mods/ts/rules/civilian-infantry.yaml b/mods/ts/rules/civilian-infantry.yaml index 3227e19cb5..6affd0532c 100644 --- a/mods/ts/rules/civilian-infantry.yaml +++ b/mods/ts/rules/civilian-infantry.yaml @@ -225,7 +225,7 @@ DOGGIE: Speed: 113 Voiced: VoiceSet: Fiend - TargetableUnit: + Targetable: TargetTypes: Ground Armament: Weapon: FiendShard diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index 7be22e3350..b7b3ce04a6 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -71,7 +71,7 @@ Palette: pips Selectable: Priority: 3 - TargetableBuilding: + Targetable: TargetTypes: Ground, Building, C4 Building: Dimensions: 1,1 @@ -187,7 +187,7 @@ NodeTypes: wall LineBuildNode: Types: wall - TargetableBuilding: + Targetable: TargetTypes: Ground, Wall, C4 RenderSprites: AutoSelectionSize: @@ -252,7 +252,7 @@ Bounds: 14,23,-1,-9 Voiced: VoiceSet: Infantry - TargetableUnit: + Targetable: TargetTypes: Ground, Infantry QuantizeFacingsFromSequence: Sequence: stand @@ -378,7 +378,7 @@ Palette: pips Voiced: VoiceSet: Vehicle - TargetableUnit: + Targetable: TargetTypes: Ground, Vehicle, Repair Repairable: RepairBuildings: gadept @@ -520,7 +520,7 @@ Palette: pips Selectable: Bounds: 26,26,0,-3 - TargetableUnit: + Targetable: TargetTypes: Ground AttackMove: HiddenUnderFog: @@ -651,7 +651,7 @@ SelectionDecorations: Palette: pips Selectable: - TargetableBuilding: + Targetable: TargetTypes: Ground, Repair Guardable: HiddenUnderFog: @@ -681,7 +681,7 @@ Palette: pips Voiced: VoiceSet: Vehicle - TargetableUnit: + Targetable: TargetTypes: Ground, Vehicle Passenger: CargoType: Infantry diff --git a/mods/ts/rules/gdi-structures.yaml b/mods/ts/rules/gdi-structures.yaml index 19c49c311a..259074a9e4 100644 --- a/mods/ts/rules/gdi-structures.yaml +++ b/mods/ts/rules/gdi-structures.yaml @@ -30,7 +30,7 @@ GAPOWR: Amount: 100 InfiltrateForPowerOutage: AffectedByPowerOutage: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate ScalePowerWithHealth: DisabledOverlay: @@ -288,7 +288,7 @@ GARADR: WithIdleOverlay@DISH: Sequence: idle-dish PauseOnLowPower: yes - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, SpyInfiltrate Power: Amount: -50 diff --git a/mods/ts/rules/nod-structures.yaml b/mods/ts/rules/nod-structures.yaml index bf0088f44c..7ed141a510 100644 --- a/mods/ts/rules/nod-structures.yaml +++ b/mods/ts/rules/nod-structures.yaml @@ -28,7 +28,7 @@ NAPOWR: Amount: 100 InfiltrateForPowerOutage: AffectedByPowerOutage: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate ScalePowerWithHealth: DisabledOverlay: @@ -65,7 +65,7 @@ NAAPWR: Amount: 200 InfiltrateForPowerOutage: AffectedByPowerOutage: - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate ScalePowerWithHealth: DisabledOverlay: @@ -243,7 +243,7 @@ NARADR: WithIdleOverlay@DISH: Sequence: idle-dish PauseOnLowPower: yes - TargetableBuilding: + Targetable: TargetTypes: Ground, C4, SpyInfiltrate Power: Amount: -50 From ecc15d9ae628c1beca206357a43afb326aa89a57 Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Mon, 13 Jul 2015 16:38:23 -0500 Subject: [PATCH 3/9] Grant upgrades while cloaked --- OpenRA.Mods.Common/Traits/Cloak.cs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Traits/Cloak.cs b/OpenRA.Mods.Common/Traits/Cloak.cs index 5f67f8327e..95860b4ed6 100644 --- a/OpenRA.Mods.Common/Traits/Cloak.cs +++ b/OpenRA.Mods.Common/Traits/Cloak.cs @@ -38,13 +38,18 @@ namespace OpenRA.Mods.Common.Traits public readonly string[] CloakTypes = { "Cloak" }; + [UpgradeGrantedReference] + [Desc("The upgrades to grant to self while cloaked.")] + public readonly string[] WhileCloakedUpgrades = { }; + public override object Create(ActorInitializer init) { return new Cloak(init.Self, this); } } - public class Cloak : UpgradableTrait, IRenderModifier, INotifyDamageStateChanged, INotifyAttack, ITick, IVisibilityModifier, IRadarColorModifier + public class Cloak : UpgradableTrait, IRenderModifier, INotifyDamageStateChanged, INotifyAttack, ITick, IVisibilityModifier, IRadarColorModifier, INotifyCreated { [Sync] int remainingTime; [Sync] bool damageDisabled; + UpgradeManager upgradeManager; Actor self; CPos? lastPos; @@ -57,6 +62,17 @@ namespace OpenRA.Mods.Common.Traits remainingTime = info.InitialDelay; } + public void Created(Actor self) + { + upgradeManager = self.TraitOrDefault(); + if (remainingTime == 0) + { + if (upgradeManager != null) + foreach (var u in Info.WhileCloakedUpgrades) + upgradeManager.GrantUpgrade(self, u, this); + } + } + protected override void UpgradeDisabled(Actor self) { Uncloak(); @@ -68,7 +84,12 @@ namespace OpenRA.Mods.Common.Traits public void Uncloak(int time) { if (Cloaked) + { Sound.Play(Info.UncloakSound, self.CenterPosition); + if (upgradeManager != null) + foreach (var u in Info.WhileCloakedUpgrades) + upgradeManager.RevokeUpgrade(self, u, this); + } remainingTime = Math.Max(remainingTime, time); } @@ -106,7 +127,12 @@ namespace OpenRA.Mods.Common.Traits return; if (remainingTime > 0 && !IsTraitDisabled && !damageDisabled && --remainingTime <= 0) + { Sound.Play(Info.CloakSound, self.CenterPosition); + if (upgradeManager != null) + foreach (var u in Info.WhileCloakedUpgrades) + upgradeManager.GrantUpgrade(self, u, this); + } if (self.IsDisabled()) Uncloak(); From a6cd770dcf191a5b187a2ee6cb0309a94f2cbfd9 Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Thu, 16 Jul 2015 00:33:25 -0500 Subject: [PATCH 4/9] Remove TargetableSubmarine --- .../UtilityCommands/UpgradeRules.cs | 39 ++++++++++++++++++ OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 - OpenRA.Mods.RA/Traits/TargetableSubmarine.cs | 41 ------------------- mods/ra/rules/ships.yaml | 22 +++++++--- 4 files changed, 55 insertions(+), 48 deletions(-) delete mode 100644 OpenRA.Mods.RA/Traits/TargetableSubmarine.cs diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 3d7b71b5d4..49e62850c5 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -1974,6 +1974,45 @@ namespace OpenRA.Mods.Common.UtilityCommands else if (node.Key == "-TargetableUnit" || node.Key == "-TargetableBuilding") node.Key = "-Targetable"; } + else if (depth == 0) + { + // Split TargetableSubmarine into two Targetable traits + var targetableSubmarine = node.Value.Nodes.FirstOrDefault(n => n.Key == "TargetableSubmarine"); + if (targetableSubmarine != null) + { + node.Value.Nodes.RemoveAll(n => n.Key == "-Targetable"); + targetableSubmarine.Key = "Targetable"; + targetableSubmarine.Value.Nodes.Add(new MiniYamlNode("UpgradeTypes", "underwater")); + targetableSubmarine.Value.Nodes.Add(new MiniYamlNode("UpgradeMaxEnabledLevel", "0")); + var cloakedTargetTypes = targetableSubmarine.Value.Nodes.FirstOrDefault(n => n.Key == "CloakedTargetTypes"); + if (cloakedTargetTypes != null) + { + targetableSubmarine.Value.Nodes.Remove(cloakedTargetTypes); + cloakedTargetTypes.Key = "TargetTypes"; + } + else + cloakedTargetTypes = new MiniYamlNode("TargetTypes", ""); + node.Value.Nodes.Add(new MiniYamlNode("Targetable@UNDERWATER", "", new List { + cloakedTargetTypes, + new MiniYamlNode("UpgradeTypes", "underwater"), + new MiniYamlNode("UpgradeMinEnabledLevel", "1") + })); + } + + // Add `WhileCloakedUpgrades: underwater` to Cloak trait if `CloakTypes: Underwater` + var cloak = node.Value.Nodes.FirstOrDefault(n => (n.Key == "Cloak" || n.Key.StartsWith("Cloak@")) + && n.Value.Nodes.Any(p => p.Key == "CloakTypes" && p.Value.Value == "Underwater")); + if (cloak != null) + cloak.Value.Nodes.Add(new MiniYamlNode("WhileCloakedUpgrades", "underwater")); + + // Remove split traits if TargetableSubmarine was removed + var untargetableSubmarine = node.Value.Nodes.FirstOrDefault(n => n.Key == "-TargetableSubmarine"); + if (untargetableSubmarine != null) + { + untargetableSubmarine.Key = "-Targetable"; + node.Value.Nodes.Add(new MiniYamlNode("-Targetable@UNDERWATER", "")); + } + } } UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 37f7fb9e3f..d023e3e648 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -112,7 +112,6 @@ - diff --git a/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs b/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs deleted file mode 100644 index 941caaa9fa..0000000000 --- a/OpenRA.Mods.RA/Traits/TargetableSubmarine.cs +++ /dev/null @@ -1,41 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using OpenRA.Mods.Common.Traits; -using OpenRA.Traits; - -namespace OpenRA.Mods.RA.Traits -{ - public class TargetableSubmarineInfo : TargetableInfo, Requires - { - public readonly string[] CloakedTargetTypes = { }; - - public override object Create(ActorInitializer init) { return new TargetableSubmarine(init.Self, this); } - } - - public class TargetableSubmarine : Targetable - { - readonly TargetableSubmarineInfo info; - - public TargetableSubmarine(Actor self, TargetableSubmarineInfo info) - : base(self, info) - { - this.info = info; - } - - public override string[] TargetTypes - { - get - { - return cloak.Cloaked ? info.CloakedTargetTypes : info.TargetTypes; - } - } - } -} diff --git a/mods/ra/rules/ships.yaml b/mods/ra/rules/ships.yaml index 1ae7d98ce6..52dd8c4666 100644 --- a/mods/ra/rules/ships.yaml +++ b/mods/ra/rules/ships.yaml @@ -19,16 +19,21 @@ SS: Speed: 71 RevealsShroud: Range: 6c0 - -Targetable: - TargetableSubmarine: + Targetable: TargetTypes: Ground, Water, Repair - CloakedTargetTypes: Underwater, Repair + UpgradeTypes: underwater + UpgradeMaxEnabledLevel: 0 + Targetable@UNDERWATER: + TargetTypes: Underwater, Repair + UpgradeTypes: underwater + UpgradeMinEnabledLevel: 1 Cloak: CloakTypes: Underwater InitialDelay: 0 CloakDelay: 50 CloakSound: subshow1.aud UncloakSound: subshow1.aud + WhileCloakedUpgrades: underwater Armament: Weapon: TorpTube LocalOffset: 0,-171,0, 0,171,0 @@ -68,16 +73,21 @@ MSUB: Speed: 42 RevealsShroud: Range: 6c0 - -Targetable: - TargetableSubmarine: + Targetable: TargetTypes: Ground, Water, Repair - CloakedTargetTypes: Underwater, Repair + UpgradeTypes: underwater + UpgradeMaxEnabledLevel: 0 + Targetable@UNDERWATER: + TargetTypes: Underwater, Repair + UpgradeTypes: underwater + UpgradeMinEnabledLevel: 1 Cloak: CloakTypes: Underwater InitialDelay: 0 CloakDelay: 100 CloakSound: subshow1.aud UncloakSound: subshow1.aud + WhileCloakedUpgrades: underwater Armament: Weapon: SubMissile LocalOffset: 0,-171,0, 0,171,0 From 97ce4766f3681a6ef77908a1adb3f5ccb3eb2659 Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Thu, 16 Jul 2015 08:48:15 -0500 Subject: [PATCH 5/9] Grant upgrades while aircraft is airborne --- OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 38 ++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index d5bbe680a2..57a146b5f3 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -46,22 +46,52 @@ namespace OpenRA.Mods.Common.Traits [VoiceReference] public readonly string Voice = "Action"; + [UpgradeGrantedReference] + [Desc("The upgrades to grant to self while airborne.")] + public readonly string[] AirborneUpgrades = { }; + public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary(); } bool IOccupySpaceInfo.SharesCell { get { return false; } } } - public class Aircraft : IFacing, IPositionable, ISync, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing + public class Aircraft : IFacing, IPositionable, ISync, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyCreated, INotifyActorDisposing { static readonly Pair[] NoCells = { }; readonly AircraftInfo info; readonly Actor self; + UpgradeManager um; [Sync] public int Facing { get; set; } [Sync] public WPos CenterPosition { get; private set; } public CPos TopLeft { get { return self.World.Map.CellContaining(CenterPosition); } } public IDisposable Reservation; public int ROT { get { return info.ROT; } } + bool IsAirborne + { + get + { + return airborne; + } + + set + { + if (airborne == value) + return; + airborne = value; + if (um != null) + { + if (airborne) + foreach (var u in info.AirborneUpgrades) + um.GrantUpgrade(self, u, this); + else + foreach (var u in info.AirborneUpgrades) + um.RevokeUpgrade(self, u, this); + } + } + } + + bool airborne = false; public Aircraft(ActorInitializer init, AircraftInfo info) { @@ -77,6 +107,8 @@ namespace OpenRA.Mods.Common.Traits Facing = init.Contains() ? init.Get() : info.InitialFacing; } + public void Created(Actor self) { um = self.TraitOrDefault(); } + bool firstTick = true; public virtual void Tick(Actor self) { @@ -197,6 +229,7 @@ namespace OpenRA.Mods.Common.Traits { self.World.ScreenMap.Update(self); self.World.ActorMap.UpdatePosition(self, this); + IsAirborne = self.World.Map.DistanceAboveTerrain(CenterPosition).Length > 0; } } @@ -213,6 +246,8 @@ namespace OpenRA.Mods.Common.Traits self.World.ActorMap.AddInfluence(self, this); self.World.ActorMap.AddPosition(self, this); self.World.ScreenMap.Add(self); + if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length > 0) + IsAirborne = true; } public void RemovedFromWorld(Actor self) @@ -221,6 +256,7 @@ namespace OpenRA.Mods.Common.Traits self.World.ActorMap.RemoveInfluence(self, this); self.World.ActorMap.RemovePosition(self, this); self.World.ScreenMap.Remove(self); + IsAirborne = false; } public bool AircraftCanEnter(Actor a) From 6986cd9f0eaeeb73f1d9abc7ea0d32120c1c1a6e Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Thu, 16 Jul 2015 08:57:50 -0500 Subject: [PATCH 6/9] Remove TargetableAircraft --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 - .../Traits/Air/TargetableAircraft.cs | 42 ------------------- .../UtilityCommands/UpgradeRules.cs | 36 ++++++++++++++++ mods/cnc/rules/aircraft.yaml | 8 ++++ mods/cnc/rules/defaults.yaml | 10 ++++- mods/d2k/rules/aircraft.yaml | 18 +++++++- mods/d2k/rules/misc.yaml | 1 + mods/ra/maps/allies-05a/map.yaml | 4 +- mods/ra/rules/aircraft.yaml | 10 ++++- mods/ra/rules/defaults.yaml | 9 +++- mods/ra/rules/husks.yaml | 7 ++++ mods/ts/rules/aircraft.yaml | 8 ++++ mods/ts/rules/defaults.yaml | 11 ++++- 13 files changed, 111 insertions(+), 54 deletions(-) delete mode 100644 OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index e319012def..e0cc610688 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -256,7 +256,6 @@ - diff --git a/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs b/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs deleted file mode 100644 index 0bb6f759f6..0000000000 --- a/OpenRA.Mods.Common/Traits/Air/TargetableAircraft.cs +++ /dev/null @@ -1,42 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using System.Collections.Generic; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - public class TargetableAircraftInfo : TargetableInfo - { - public readonly string[] GroundedTargetTypes = { }; - public override object Create(ActorInitializer init) { return new TargetableAircraft(init.Self, this); } - } - - public class TargetableAircraft : Targetable - { - readonly TargetableAircraftInfo info; - readonly Actor self; - - public TargetableAircraft(Actor self, TargetableAircraftInfo info) - : base(self, info) - { - this.info = info; - this.self = self; - } - - public override string[] TargetTypes - { - get - { - return (self.CenterPosition.Z > 0) ? info.TargetTypes : info.GroundedTargetTypes; - } - } - } -} diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 49e62850c5..7138902dc0 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -2012,6 +2012,42 @@ namespace OpenRA.Mods.Common.UtilityCommands untargetableSubmarine.Key = "-Targetable"; node.Value.Nodes.Add(new MiniYamlNode("-Targetable@UNDERWATER", "")); } + + // Split TargetableAircraft into two Targetable traits + var targetableAircraft = node.Value.Nodes.FirstOrDefault(n => n.Key == "TargetableAircraft"); + if (targetableAircraft != null) + { + node.Value.Nodes.RemoveAll(n => n.Key == "-Targetable"); + targetableAircraft.Key = "Targetable@AIRBORNE"; + targetableAircraft.Value.Nodes.Add(new MiniYamlNode("UpgradeTypes", "airborne")); + targetableAircraft.Value.Nodes.Add(new MiniYamlNode("UpgradeMinEnabledLevel", "1")); + var groundTargetTypes = targetableAircraft.Value.Nodes.FirstOrDefault(n => n.Key == "GroundedTargetTypes"); + if (groundTargetTypes != null) + { + targetableAircraft.Value.Nodes.Remove(groundTargetTypes); + groundTargetTypes.Key = "TargetTypes"; + } + else + groundTargetTypes = new MiniYamlNode("TargetTypes", ""); + node.Value.Nodes.Add(new MiniYamlNode("Targetable@GROUND", "", new List { + groundTargetTypes, + new MiniYamlNode("UpgradeTypes", "airborne"), + new MiniYamlNode("UpgradeMaxEnabledLevel", "0") + })); + } + + // Add `AirborneUpgrades: airborne` to Plane and Helicopter + var aircraft = node.Value.Nodes.FirstOrDefault(n => n.Key == "Plane" || n.Key == "Helicopter"); + if (aircraft != null) + aircraft.Value.Nodes.Add(new MiniYamlNode("AirborneUpgrades", "airborne")); + + // Remove split traits if TargetableAircraft was removed + var untargetableAircraft = node.Value.Nodes.FirstOrDefault(n => n.Key == "-TargetableAircraft"); + if (untargetableAircraft != null) + { + untargetableAircraft.Key = "-TargetableUnit@GROUND"; + node.Value.Nodes.Add(new MiniYamlNode("-TargetableUnit@AIRBORNE", "")); + } } } diff --git a/mods/cnc/rules/aircraft.yaml b/mods/cnc/rules/aircraft.yaml index d994101f9a..ee46c40815 100644 --- a/mods/cnc/rules/aircraft.yaml +++ b/mods/cnc/rules/aircraft.yaml @@ -16,6 +16,7 @@ TRAN: InitialFacing: 0 LandableTerrainTypes: Clear,Rough,Road,Ore,Beach,Tiberium,BlueTiberium AltitudeVelocity: 0c100 + AirborneUpgrades: airborne Health: HP: 90 Armor: @@ -56,6 +57,7 @@ HELI: RearmBuildings: hpad ROT: 4 Speed: 186 + AirborneUpgrades: airborne Health: HP: 125 Armor: @@ -107,6 +109,7 @@ ORCA: RearmBuildings: hpad ROT: 4 Speed: 186 + AirborneUpgrades: airborne Health: HP: 90 Armor: @@ -152,6 +155,7 @@ C17: ROT: 5 Speed: 326 Repulsable: False + AirborneUpgrades: airborne Health: HP: 25 Armor: @@ -188,6 +192,7 @@ A10: ROT: 4 Speed: 373 Repulsable: False + AirborneUpgrades: airborne Health: HP: 150 Armor: @@ -219,6 +224,7 @@ TRAN.Husk: Helicopter: ROT: 5 Speed: 140 + AirborneUpgrades: airborne RevealsShroud: Range: 8c0 Type: CenterPosition @@ -236,6 +242,7 @@ HELI.Husk: Helicopter: ROT: 4 Speed: 186 + AirborneUpgrades: airborne RevealsShroud: Range: 10c0 Type: CenterPosition @@ -251,6 +258,7 @@ ORCA.Husk: Helicopter: ROT: 4 Speed: 186 + AirborneUpgrades: airborne RevealsShroud: Range: 10c0 Type: CenterPosition diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 115d76afc8..5f4966994c 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -116,9 +116,14 @@ Inherits@2: ^GainsExperience AppearsOnRadar: UseLocation: yes - TargetableAircraft: + Targetable@GROUND: + TargetTypes: Ground, Vehicle + UpgradeTypes: airborne + UpgradeMaxEnabledLevel: 0 + Targetable@AIRBORNE: TargetTypes: Air - GroundedTargetTypes: Ground, Vehicle + UpgradeTypes: airborne + UpgradeMinEnabledLevel: 1 SelectionDecorations: Selectable: Bounds: 24,24 @@ -126,6 +131,7 @@ RepairBuildings: hpad RearmBuildings: LandWhenIdle: false + AirborneUpgrades: airborne HiddenUnderFog: Type: CenterPosition ActorLostNotification: diff --git a/mods/d2k/rules/aircraft.yaml b/mods/d2k/rules/aircraft.yaml index 8ee9f578be..f2de72efea 100644 --- a/mods/d2k/rules/aircraft.yaml +++ b/mods/d2k/rules/aircraft.yaml @@ -20,6 +20,7 @@ carryall.reinforce: Repulsable: False LandAltitude: 100 LandWhenIdle: False + AirborneUpgrades: airborne SpawnActorOnDeath: Actor: carryall.husk Carryall: @@ -53,6 +54,7 @@ carryall.infantry: RepairBuildings: repair RearmBuildings: Repulsable: False + AirborneUpgrades: airborne Cargo: MaxWeight: 5 Types: Infantry @@ -77,6 +79,7 @@ frigate: RepairBuildings: repair RearmBuildings: Repulsable: False + AirborneUpgrades: airborne Health: HP: 500 -AppearsOnRadar: @@ -116,14 +119,20 @@ orni: Speed: 280 RepairBuildings: repair RearmBuildings: + AirborneUpgrades: airborne SpawnActorOnDeath: Actor: orni.husk SelectionDecorations: Selectable: Bounds: 32,32 - TargetableAircraft: + Targetable@GROUND: + TargetTypes: Ground, Vehicle + UpgradeTypes: airborne + UpgradeMaxEnabledLevel: 0 + Targetable@AIRBORNE: TargetTypes: Air - GroundedTargetTypes: Ground, Vehicle + UpgradeTypes: airborne + UpgradeMinEnabledLevel: 1 Voiced: VoiceSet: GenericVoice @@ -142,6 +151,7 @@ orni.bomber: RepairBuildings: repair RearmBuildings: Repulsable: False + AirborneUpgrades: airborne AmmoPool: Ammo: 5 Tooltip: @@ -161,6 +171,7 @@ orni.husk: Speed: 280 RepairBuildings: RearmBuildings: + AirborneUpgrades: airborne RenderSprites: Image: orni @@ -173,6 +184,7 @@ orni.bomber.husk: Speed: 350 RepairBuildings: RearmBuildings: + AirborneUpgrades: airborne RenderSprites: Image: orni @@ -185,6 +197,7 @@ carryall.husk: Speed: 210 RepairBuildings: RearmBuildings: + AirborneUpgrades: airborne RenderSprites: Image: carryall @@ -197,6 +210,7 @@ carryall.infantry.husk: Speed: 280 RepairBuildings: RearmBuildings: + AirborneUpgrades: airborne RenderSprites: Image: carryall diff --git a/mods/d2k/rules/misc.yaml b/mods/d2k/rules/misc.yaml index 785732fddf..c47a6a6244 100644 --- a/mods/d2k/rules/misc.yaml +++ b/mods/d2k/rules/misc.yaml @@ -133,6 +133,7 @@ waypoint: Inherits: carryall Helicopter: InitialFacing: 104 + AirborneUpgrades: airborne RenderSprites: Image: carryall Palette: colorpicker diff --git a/mods/ra/maps/allies-05a/map.yaml b/mods/ra/maps/allies-05a/map.yaml index 9dd53ff6e1..6664e0ae5a 100644 --- a/mods/ra/maps/allies-05a/map.yaml +++ b/mods/ra/maps/allies-05a/map.yaml @@ -1668,8 +1668,8 @@ Rules: Range: 4c0 Tooltip: ShowOwnerRow: false - TargetableAircraft: - GroundedTargetTypes: Ground + Targetable@GROUND: + TargetTypes: Ground TRAN.IN: Inherits: TRAN RenderSprites: diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index 8fd804704b..5fb48bd807 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -12,6 +12,7 @@ BADR: Speed: 149 Repulsable: False MaximumPitch: 56 + AirborneUpgrades: airborne Cargo: MaxWeight: 10 -Selectable: @@ -49,6 +50,7 @@ BADR.Bomber: Speed: 149 Repulsable: False MaximumPitch: 56 + AirborneUpgrades: airborne AmmoPool: Ammo: 7 -Selectable: @@ -106,6 +108,7 @@ MIG: RearmBuildings: afld RepulsionSpeed: 40 MaximumPitch: 56 + AirborneUpgrades: airborne AutoTarget: TargetWhenIdle: false TargetWhenDamaged: false @@ -167,6 +170,7 @@ YAK: Speed: 178 RepulsionSpeed: 40 MaximumPitch: 56 + AirborneUpgrades: airborne AutoTarget: TargetWhenIdle: false TargetWhenDamaged: false @@ -215,6 +219,7 @@ TRAN: Speed: 112 LandableTerrainTypes: Clear,Rough,Road,Ore,Beach AltitudeVelocity: 0c100 + AirborneUpgrades: airborne WithRotor@PRIMARY: Offset: -597,0,341 Sequence: rotor2 @@ -261,6 +266,7 @@ HELI: InitialFacing: 20 ROT: 4 Speed: 149 + AirborneUpgrades: airborne AutoTarget: InitialStance: HoldFire WithRotor: @@ -312,6 +318,7 @@ HIND: InitialFacing: 20 ROT: 4 Speed: 112 + AirborneUpgrades: airborne AutoTarget: InitialStance: HoldFire WithRotor: @@ -341,10 +348,11 @@ U2: Speed: 373 Repulsable: False MaximumPitch: 56 + AirborneUpgrades: airborne AttackBomber: -Selectable: -Voiced: - -TargetableAircraft: + -Targetable@AIRBORNE: -GainsExperience: Contrail@1: Offset: -725,683,0 diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 83d2b684fe..98159c7e57 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -339,9 +339,14 @@ SelectionDecorations: Selectable: Bounds: 24,24 - TargetableAircraft: + Targetable@GROUND: + TargetTypes: Ground, Repair, Vehicle + UpgradeTypes: airborne + UpgradeMaxEnabledLevel: 0 + Targetable@AIRBORNE: TargetTypes: Air - GroundedTargetTypes: Ground, Repair, Vehicle + UpgradeTypes: airborne + UpgradeMinEnabledLevel: 1 HiddenUnderFog: Type: CenterPosition AttackMove: diff --git a/mods/ra/rules/husks.yaml b/mods/ra/rules/husks.yaml index c318134b13..7053e6a84e 100644 --- a/mods/ra/rules/husks.yaml +++ b/mods/ra/rules/husks.yaml @@ -88,6 +88,7 @@ TRAN.Husk: Helicopter: ROT: 4 Speed: 149 + AirborneUpgrades: airborne WithRotor@PRIMARY: Offset: -597,0,341 WithRotor@SECONDARY: @@ -119,6 +120,7 @@ BADR.Husk: Plane: ROT: 5 Speed: 149 + AirborneUpgrades: airborne SmokeTrailWhenDamaged@0: Offset: -432,560,0 Interval: 2 @@ -141,6 +143,7 @@ MIG.Husk: Plane: ROT: 5 Speed: 186 + AirborneUpgrades: airborne SmokeTrailWhenDamaged: Offset: -853,0,171 Interval: 2 @@ -160,6 +163,7 @@ YAK.Husk: Plane: ROT: 5 Speed: 149 + AirborneUpgrades: airborne SmokeTrailWhenDamaged: Offset: -853,0,0 Interval: 2 @@ -177,6 +181,7 @@ HELI.Husk: Helicopter: ROT: 4 Speed: 149 + AirborneUpgrades: airborne WithRotor: Offset: 0,0,85 SmokeTrailWhenDamaged: @@ -195,6 +200,7 @@ HIND.Husk: Helicopter: ROT: 4 Speed: 112 + AirborneUpgrades: airborne WithRotor: SmokeTrailWhenDamaged: Offset: -427,0,0 @@ -210,6 +216,7 @@ U2.Husk: Plane: ROT: 7 Speed: 373 + AirborneUpgrades: airborne Contrail@1: Offset: -725,683,0 Contrail@2: diff --git a/mods/ts/rules/aircraft.yaml b/mods/ts/rules/aircraft.yaml index 846b931d68..6cdcc566d2 100644 --- a/mods/ts/rules/aircraft.yaml +++ b/mods/ts/rules/aircraft.yaml @@ -10,6 +10,7 @@ DPOD: Speed: 149 InitialFacing: 0 LandableTerrainTypes: Clear + AirborneUpgrades: airborne Health: HP: 60 Armor: @@ -47,6 +48,7 @@ DSHP: LandableTerrainTypes: Clear TakeoffSound: dropup1.aud LandingSound: dropdwn1.aud + AirborneUpgrades: airborne Health: HP: 200 Armor: @@ -78,6 +80,7 @@ ORCA: RearmBuildings: gahpad, nahpad ROT: 5 Speed: 186 + AirborneUpgrades: airborne Health: HP: 200 Armor: @@ -117,6 +120,7 @@ ORCAB: MaximumPitch: 120 ROT: 3 Speed: 96 + AirborneUpgrades: airborne Health: HP: 260 Armor: @@ -159,6 +163,7 @@ ORCATRAN: LandableTerrainTypes: Clear TakeoffSound: dropup1.aud LandingSound: dropdwn1.aud + AirborneUpgrades: airborne Health: HP: 200 Armor: @@ -193,6 +198,7 @@ TRNSPORT: TakeoffSound: dropup1.aud LandingSound: dropdwn1.aud AltitudeVelocity: 64 + AirborneUpgrades: airborne Health: HP: 175 Armor: @@ -224,6 +230,7 @@ SCRIN: MaximumPitch: 90 ROT: 3 Speed: 168 + AirborneUpgrades: airborne Health: HP: 280 Armor: @@ -262,6 +269,7 @@ APACHE: RearmBuildings: gahpad, nahpad ROT: 5 Speed: 130 + AirborneUpgrades: airborne Health: HP: 225 Armor: diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index b7b3ce04a6..921cc974df 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -453,9 +453,14 @@ DrawLineToTarget: AppearsOnRadar: UseLocation: yes - TargetableAircraft: + Targetable@GROUND: + TargetTypes: Ground + UpgradeTypes: airborne + UpgradeMaxEnabledLevel: 0 + Targetable@AIRBORNE: TargetTypes: Air - GroundedTargetTypes: Ground + UpgradeTypes: airborne + UpgradeMinEnabledLevel: 1 Selectable: SelectionDecorations: Palette: pips @@ -484,6 +489,7 @@ LandWhenIdle: no CruiseAltitude: 2048 Voice: Move + AirborneUpgrades: airborne ^Plane: Inherits: ^Aircraft @@ -493,6 +499,7 @@ LandWhenIdle: no CruiseAltitude: 2560 Voice: Move + AirborneUpgrades: airborne ReturnOnIdle: ^Viceroid: From fadfd179cb17793412bc0cd79d1b20f2dfc6167a Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Thu, 16 Jul 2015 11:47:16 -0500 Subject: [PATCH 7/9] Cache FrozenActor ITargetable.TargetTypes union --- OpenRA.Game/GameRules/WeaponInfo.cs | 3 +-- OpenRA.Game/Traits/Player/FrozenActorLayer.cs | 2 ++ OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs | 2 +- OpenRA.Mods.Common/Warheads/Warhead.cs | 3 +-- OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs | 10 +++++----- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 6af645ce6b..00838d70a8 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -138,8 +138,7 @@ namespace OpenRA.GameRules /// Checks if the weapon is valid against (can target) the frozen actor. public bool IsValidAgainst(FrozenActor victim, Actor firedBy) { - var targetable = victim.Info.Traits.WithInterface(); - if (!IsValidTarget(targetable.SelectMany(t => t.GetTargetTypes()))) + if (!IsValidTarget(victim.TargetTypes)) return false; if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy))) diff --git a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs index 384de66273..a1c652889d 100644 --- a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs +++ b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs @@ -27,6 +27,7 @@ namespace OpenRA.Traits public readonly PPos[] Footprint; public readonly WPos CenterPosition; public readonly Rectangle Bounds; + public readonly string[] TargetTypes; readonly IRemoveFrozenActor[] removeFrozenActors; readonly Actor actor; readonly Shroud shroud; @@ -56,6 +57,7 @@ namespace OpenRA.Traits CenterPosition = self.CenterPosition; Bounds = self.Bounds; + TargetTypes = self.TraitsImplementing().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes).Distinct().ToArray(); UpdateVisibility(); } diff --git a/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs b/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs index 175da6c5b4..6e873260c1 100644 --- a/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs +++ b/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs @@ -82,7 +82,7 @@ namespace OpenRA.Mods.Common.Orders public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) { - return target.Info.Traits.WithInterface().Any(t => t.GetTargetTypes().Intersect(targetTypes).Any()); + return target.TargetTypes.Intersect(targetTypes).Any(); } } } diff --git a/OpenRA.Mods.Common/Warheads/Warhead.cs b/OpenRA.Mods.Common/Warheads/Warhead.cs index b9b3e1c1a6..a471a97925 100644 --- a/OpenRA.Mods.Common/Warheads/Warhead.cs +++ b/OpenRA.Mods.Common/Warheads/Warhead.cs @@ -75,8 +75,7 @@ namespace OpenRA.Mods.Common.Warheads return false; // A target type is valid if it is in the valid targets list, and not in the invalid targets list. - var targetable = victim.Info.Traits.WithInterface(); - if (!IsValidTarget(targetable.SelectMany(t => t.GetTargetTypes()))) + if (!IsValidTarget(victim.TargetTypes)) return false; return true; diff --git a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs index f8c4e6ace8..656ad379ac 100644 --- a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs +++ b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs @@ -61,7 +61,7 @@ namespace OpenRA.Mods.RA.Traits if (order.ExtraData == 0 && order.TargetActor == null) return false; - ActorInfo ai; + IEnumerable targetTypes; if (order.ExtraData != 0) { @@ -74,13 +74,13 @@ namespace OpenRA.Mods.RA.Traits if (frozen == null) return false; - ai = frozen.Info; + targetTypes = frozen.TargetTypes; } else - ai = order.TargetActor.Info; + targetTypes = order.TargetActor.TraitsImplementing().Where(Exts.IsTraitEnabled) + .SelectMany(t => t.TargetTypes); - return ai.Traits.WithInterface() - .SelectMany(t => t.GetTargetTypes()).Intersect(Info.Types).Any(); + return targetTypes.Intersect(Info.Types).Any(); } public string VoicePhraseForOrder(Actor self, Order order) From b789739352ba9eab2ef47498918d06bb08e32e7d Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Sat, 25 Jul 2015 19:16:42 -0500 Subject: [PATCH 8/9] Allies 03 - kill prisoners with barrels --- mods/ra/maps/allies-03a/map.yaml | 7 +++++++ mods/ra/maps/allies-03b/map.yaml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/mods/ra/maps/allies-03a/map.yaml b/mods/ra/maps/allies-03a/map.yaml index 9e3dde8905..cf2c79583f 100644 --- a/mods/ra/maps/allies-03a/map.yaml +++ b/mods/ra/maps/allies-03a/map.yaml @@ -1385,12 +1385,16 @@ Rules: Targetable: UpgradeTypes: jail UpgradeMaxEnabledLevel: 0 + Targetable@PRISONER: + TargetTypes: Prisoner RenderSprites: Image: E6 MEDI: Targetable: UpgradeTypes: jail UpgradeMaxEnabledLevel: 0 + Targetable@PRISONER: + TargetTypes: Prisoner E7.noautotarget: Inherits: E7 AutoTarget: @@ -1538,6 +1542,9 @@ Sequences: VoxelSequences: Weapons: + BarrelExplode: + Warhead@1Dam: + ValidTargets: Ground, Prisoner Voices: diff --git a/mods/ra/maps/allies-03b/map.yaml b/mods/ra/maps/allies-03b/map.yaml index 079d37d80f..707a184049 100644 --- a/mods/ra/maps/allies-03b/map.yaml +++ b/mods/ra/maps/allies-03b/map.yaml @@ -1281,12 +1281,16 @@ Rules: Targetable: UpgradeTypes: jail UpgradeMaxEnabledLevel: 0 + Targetable@PRISONER: + TargetTypes: Prisoner RenderSprites: Image: E6 MEDI: Targetable: UpgradeTypes: jail UpgradeMaxEnabledLevel: 0 + Targetable@PRISONER: + TargetTypes: Prisoner E7.noautotarget: Inherits: E7 AutoTarget: @@ -1426,6 +1430,9 @@ Weapons: FireballLauncher: Projectile: High: True + BarrelExplode: + Warhead@1Dam: + ValidTargets: Ground, Prisoner Voices: From 5f079f246343489ed3fb32f1544cf04d866a2801 Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Sat, 1 Aug 2015 22:07:48 -0500 Subject: [PATCH 9/9] Add MinAirborneAltitude to Aircraft trait to set airborne threshold --- OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 57a146b5f3..bf9b8a076d 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -35,6 +35,9 @@ namespace OpenRA.Mods.Common.Traits public readonly int InitialFacing = 0; public readonly int ROT = 255; public readonly int Speed = 1; + + [Desc("Minimum altitude where this aircraft is considered airborne")] + public readonly int MinAirborneAltitude = 1; public readonly string[] LandableTerrainTypes = { }; [Desc("Can the actor be ordered to move in to shroud?")] @@ -229,7 +232,7 @@ namespace OpenRA.Mods.Common.Traits { self.World.ScreenMap.Update(self); self.World.ActorMap.UpdatePosition(self, this); - IsAirborne = self.World.Map.DistanceAboveTerrain(CenterPosition).Length > 0; + IsAirborne = self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= info.MinAirborneAltitude; } } @@ -246,7 +249,7 @@ namespace OpenRA.Mods.Common.Traits self.World.ActorMap.AddInfluence(self, this); self.World.ActorMap.AddPosition(self, this); self.World.ScreenMap.Add(self); - if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length > 0) + if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= info.MinAirborneAltitude) IsAirborne = true; }