diff --git a/OpenRA.Mods.Common/Traits/AutoTarget.cs b/OpenRA.Mods.Common/Traits/AutoTarget.cs index e4e4b2d7b4..085187ffc1 100644 --- a/OpenRA.Mods.Common/Traits/AutoTarget.cs +++ b/OpenRA.Mods.Common/Traits/AutoTarget.cs @@ -60,10 +60,6 @@ namespace OpenRA.Mods.Common.Traits [Desc("Ticks to wait until next AutoTarget: attempt.")] public readonly int MaximumScanTimeInterval = 8; - public readonly bool TargetWhenIdle = true; - - public readonly bool TargetWhenDamaged = true; - public override object Create(ActorInitializer init) { return new AutoTarget(init, this); } public override void RulesetLoaded(Ruleset rules, ActorInfo info) @@ -157,17 +153,18 @@ namespace OpenRA.Mods.Common.Traits public void Damaged(Actor self, AttackInfo e) { - if (IsTraitDisabled) + if (IsTraitDisabled || !self.IsIdle || Stance < UnitStance.ReturnFire) return; - if (!self.IsIdle || !Info.TargetWhenDamaged) + // Don't retaliate against healers + if (e.Damage.Value < 0) return; var attacker = e.Attacker; - if (attacker.Disposed || Stance < UnitStance.ReturnFire) + if (attacker.Disposed) return; - if (!attacker.IsInWorld && !attacker.Disposed) + if (!attacker.IsInWorld) { // If the aggressor is in a transport, then attack the transport instead var passenger = attacker.TraitOrDefault(); @@ -175,19 +172,15 @@ namespace OpenRA.Mods.Common.Traits attacker = passenger.Transport; } - // not a lot we can do about things we can't hurt... although maybe we should automatically run away? + // Not a lot we can do about things we can't hurt... although maybe we should automatically run away? var attackerAsTarget = Target.FromActor(attacker); if (!activeAttackBases.Any(a => a.HasAnyValidWeapons(attackerAsTarget))) return; - // don't retaliate against own units force-firing on us. It's usually not what the player wanted. + // Don't retaliate against own units force-firing on us. It's usually not what the player wanted. if (attacker.AppearsFriendlyTo(self)) return; - // don't retaliate against healers - if (e.Damage.Value < 0) - return; - Aggressor = attacker; bool allowMove; @@ -197,10 +190,7 @@ namespace OpenRA.Mods.Common.Traits public void TickIdle(Actor self) { - if (IsTraitDisabled) - return; - - if (Stance < UnitStance.Defend || !Info.TargetWhenIdle) + if (IsTraitDisabled || Stance < UnitStance.Defend) return; bool allowMove; diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index ab93a20f72..79119ba3de 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -877,6 +877,82 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + // TargetWhenIdle and TargetWhenDamaged were removed from AutoTarget + if (engineVersion < 20170722) + { + if (node.Key.StartsWith("AutoTarget", StringComparison.Ordinal)) + { + var valueNodes = node.Value.Nodes; + var targetIdle = valueNodes.FirstOrDefault(n => n.Key == "TargetWhenIdle"); + var targetDamaged = valueNodes.FirstOrDefault(n => n.Key == "TargetWhenDamaged"); + var hasInitialStance = valueNodes.FirstOrDefault(n => n.Key == "InitialStance") != null; + var enableStances = valueNodes.FirstOrDefault(n => n.Key == "EnableStances"); + + if (targetDamaged == null) + { + if (targetIdle != null) + { + if (hasInitialStance) + Console.WriteLine("'TargetWhenIdle' was removed from 'AutoTarget'. 'InitialStance' might need to be adjusted."); + else + { + valueNodes.Add(new MiniYamlNode("InitialStance", targetIdle.Value.Value.ToLower() == "true" ? "Defend" : "ReturnFire")); + + if (enableStances != null) + enableStances.Value.Value = "false"; + else + valueNodes.Add(new MiniYamlNode("EnableStances", "false")); + } + + valueNodes.Remove(targetIdle); + } + } + else + { + if (targetIdle == null) + { + if (hasInitialStance) + Console.WriteLine("'TargetWhenDamaged' was removed from 'AutoTarget'. 'InitialStance' might need to be adjusted."); + else + { + // In this case the default for "TargetWhenIdle" (true) takes effect, i.e. use the "Defend" stance + valueNodes.Add(new MiniYamlNode("InitialStance", "Defend")); + + if (enableStances != null) + enableStances.Value.Value = "false"; + else + valueNodes.Add(new MiniYamlNode("EnableStances", "false")); + } + + valueNodes.Remove(targetDamaged); + } + else + { + if (hasInitialStance) + Console.WriteLine("'TargetWhenDamaged' and 'TargetWhenIdle' were removed from 'AutoTarget'. 'InitialStance' might need to be adjusted."); + else + { + var idle = targetIdle.Value.Value.ToLower() == "true"; + var damaged = targetDamaged.Value.Value.ToLower() == "true"; + + if (idle) + valueNodes.Add(new MiniYamlNode("InitialStance", "Defend")); + else + valueNodes.Add(new MiniYamlNode("InitialStance", damaged ? "ReturnFire" : "HoldFire")); + + if (enableStances != null) + enableStances.Value.Value = "false"; + else + valueNodes.Add(new MiniYamlNode("EnableStances", "false")); + } + + valueNodes.Remove(targetIdle); + valueNodes.Remove(targetDamaged); + } + } + } + } + UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1); } diff --git a/mods/cnc/maps/gdi06/rules.yaml b/mods/cnc/maps/gdi06/rules.yaml index 5e47824ca6..3b7d677878 100644 --- a/mods/cnc/maps/gdi06/rules.yaml +++ b/mods/cnc/maps/gdi06/rules.yaml @@ -74,8 +74,8 @@ RMBO: MustBeDestroyed: RequiredForShortGame: true AutoTarget: - TargetWhenIdle: false - TargetWhenDamaged: true + EnableStances: false + InitialStance: ReturnFire Health: HP: 150 diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index 622bb23e33..eb39aacd7f 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -118,9 +118,8 @@ MIG: RepulsionSpeed: 40 MaximumPitch: 56 AutoTarget: - TargetWhenIdle: false - TargetWhenDamaged: false - EnableStances: false + InitialStance: HoldFire + InitialStanceAI: HoldFire AmmoPool: Ammo: 8 ReturnOnIdle: @@ -183,9 +182,8 @@ YAK: RepulsionSpeed: 40 MaximumPitch: 56 AutoTarget: - TargetWhenIdle: false - TargetWhenDamaged: false - EnableStances: false + InitialStance: HoldFire + InitialStanceAI: HoldFire AmmoPool: Ammo: 18 PipCount: 6