diff --git a/AUTHORS b/AUTHORS index 4e478b7582..6e755fa8fb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -150,6 +150,7 @@ Also thanks to: * Teemu Nieminen (Temeez) * Thomas Christlieb (ThomasChr) * Tim Mylemans (gecko) + * Tinix * Tirili * Tomas Einarsson (Mesacer) * Tom van Leth (tovl) diff --git a/OpenRA.Mods.Cnc/Traits/SupportPowers/AttackOrderPower.cs b/OpenRA.Mods.Cnc/Traits/SupportPowers/AttackOrderPower.cs index c069637167..99d023ee22 100644 --- a/OpenRA.Mods.Cnc/Traits/SupportPowers/AttackOrderPower.cs +++ b/OpenRA.Mods.Cnc/Traits/SupportPowers/AttackOrderPower.cs @@ -34,13 +34,22 @@ namespace OpenRA.Mods.Cnc.Traits [Desc("Range circle border width.")] public readonly float CircleBorderWidth = 3; + [Desc("Condition set to the unit that will execute the attack while the support power is in targeting mode.")] + [GrantedConditionReference] + public readonly string SupportPowerTargetingCondition = "support-targeting"; + + [Desc("Condition set to the unit is executing the attack while the support power attack is in progress.")] + [GrantedConditionReference] + public readonly string SupportPowerAttackingCondition = "support-attacking"; + public override object Create(ActorInitializer init) { return new AttackOrderPower(init.Self, this); } } - sealed class AttackOrderPower : SupportPower, INotifyCreated, INotifyBurstComplete + sealed class AttackOrderPower : SupportPower, INotifyCreated, INotifyBurstComplete, INotifyBecomingIdle { readonly AttackOrderPowerInfo info; AttackBase attack; + int attackingToken = 0; public AttackOrderPower(Actor self, AttackOrderPowerInfo info) : base(self, info) @@ -58,6 +67,7 @@ namespace OpenRA.Mods.Cnc.Traits base.Activate(self, order, manager); PlayLaunchSounds(); + attackingToken = self.GrantCondition(info.SupportPowerAttackingCondition); attack.AttackTarget(order.Target, AttackSource.Default, false, false, true); } @@ -72,6 +82,11 @@ namespace OpenRA.Mods.Cnc.Traits { self.World.IssueOrder(new Order("Stop", self, false)); } + + void INotifyBecomingIdle.OnBecomingIdle(Actor self) + { + self.RevokeCondition(attackingToken); + } } public class SelectAttackPowerTarget : OrderGenerator @@ -83,14 +98,21 @@ namespace OpenRA.Mods.Cnc.Traits readonly string cursorBlocked; readonly MouseButton expectedButton; readonly AttackBase attack; + readonly Actor self; + readonly int targetingToken = 0; + bool isFiring; public SelectAttackPowerTarget(Actor self, string order, SupportPowerManager manager, string cursor, MouseButton button, AttackBase attack) { + this.self = self; + // Clear selection if using Left-Click Orders if (Game.Settings.Game.UseClassicMouseStyle) manager.Self.World.Selection.Clear(); instance = manager.GetPowersForActor(self).FirstOrDefault(); + targetingToken = self.GrantCondition((instance.Info as AttackOrderPowerInfo).SupportPowerTargetingCondition); + this.manager = manager; this.order = order; this.cursor = cursor; @@ -109,12 +131,21 @@ namespace OpenRA.Mods.Cnc.Traits protected override IEnumerable OrderInner(World world, CPos cell, int2 worldPixel, MouseInput mi) { + // CancelInputMode will call Deactivate before we could validate the target, so we need to delay clearing the targeting flag + isFiring = true; world.CancelInputMode(); if (mi.Button == expectedButton && IsValidTarget(world, cell)) + { + self.RevokeCondition(targetingToken); yield return new Order(order, manager.Self, Target.FromCell(world, cell), false) { SuppressVisualFeedback = true }; + } + else + { + self.RevokeCondition(targetingToken); + } } protected override void Tick(World world) @@ -124,6 +155,14 @@ namespace OpenRA.Mods.Cnc.Traits world.CancelInputMode(); } + protected override void Deactivate() + { + if (!isFiring) + { + self.RevokeCondition(targetingToken); + } + } + protected override IEnumerable Render(WorldRenderer wr, World world) { yield break; } protected override IEnumerable RenderAboveShroud(WorldRenderer wr, World world) { yield break; } diff --git a/OpenRA.Mods.Common/Orders/OrderGenerator.cs b/OpenRA.Mods.Common/Orders/OrderGenerator.cs index 271aa90d93..cca2d014f4 100644 --- a/OpenRA.Mods.Common/Orders/OrderGenerator.cs +++ b/OpenRA.Mods.Common/Orders/OrderGenerator.cs @@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Orders IEnumerable IOrderGenerator.RenderAboveShroud(WorldRenderer wr, World world) { return RenderAboveShroud(wr, world); } IEnumerable IOrderGenerator.RenderAnnotations(WorldRenderer wr, World world) { return RenderAnnotations(wr, world); } string IOrderGenerator.GetCursor(World world, CPos cell, int2 worldPixel, MouseInput mi) { return GetCursor(world, cell, worldPixel, mi); } - void IOrderGenerator.Deactivate() { } + void IOrderGenerator.Deactivate() { Deactivate(); } bool IOrderGenerator.HandleKeyPress(KeyInput e) { return false; } void IOrderGenerator.SelectionChanged(World world, IEnumerable selected) { SelectionChanged(world, selected); } @@ -42,5 +42,6 @@ namespace OpenRA.Mods.Common.Orders protected abstract string GetCursor(World world, CPos cell, int2 worldPixel, MouseInput mi); protected abstract IEnumerable OrderInner(World world, CPos cell, int2 worldPixel, MouseInput mi); protected virtual void SelectionChanged(World world, IEnumerable selected) { } + protected virtual void Deactivate() { } } } diff --git a/mods/ts/rules/shared-support.yaml b/mods/ts/rules/shared-support.yaml index d34251b7e7..9397a13375 100644 --- a/mods/ts/rules/shared-support.yaml +++ b/mods/ts/rules/shared-support.yaml @@ -25,7 +25,7 @@ NAPULS: InitialFacing: 896 RealignDelay: -1 AttackTurreted: - RequiresCondition: !build-incomplete && !empdisable && !disabled + RequiresCondition: !build-incomplete && !empdisable && !disabled && ( support-targeting || support-attacking ) Armament: Weapon: EMPulseCannon LocalOffset: 212,0,1768