From 7e4f0be7fbc3f36e29b31b354fb7126f3f6186c6 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Mon, 16 Nov 2015 00:48:27 +0200 Subject: [PATCH 1/3] Add support for deploy animations using a specific upgrade Also ignore orders while playing a deploy/undeploy animation. Fixes 9242. We grant a level 1 Undeployed upgrade(s) when the actor is created which enables the default behavior of the actor. When the actor receives a deploy order, the Undeployed upgrade(s) is(are) revoked, which may or may not be used to enable a trait to play a deploy animation. Once the deployment is complete, the Deployed upgrade(s) is(are) granted. Then do the reverse when undeploying, disabling weapons and other systems first by revoking the Deployed upgrade(s), and granting the Undeployed upgrade(s) when the undeploy animation is done. --- .../Traits/Upgrades/DeployToUpgrade.cs | 149 +++++++++++------- 1 file changed, 94 insertions(+), 55 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Upgrades/DeployToUpgrade.cs b/OpenRA.Mods.Common/Traits/Upgrades/DeployToUpgrade.cs index ee42381119..24338ef1f3 100644 --- a/OpenRA.Mods.Common/Traits/Upgrades/DeployToUpgrade.cs +++ b/OpenRA.Mods.Common/Traits/Upgrades/DeployToUpgrade.cs @@ -10,7 +10,6 @@ using System; using System.Collections.Generic; -using System.Linq; using OpenRA.Activities; using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Orders; @@ -20,9 +19,13 @@ namespace OpenRA.Mods.Common.Traits { public class DeployToUpgradeInfo : ITraitInfo, Requires { + [UpgradeGrantedReference] + [Desc("The upgrades to grant while the actor is undeployed.")] + public readonly string[] UndeployedUpgrades = { }; + [UpgradeGrantedReference, FieldLoader.Require] - [Desc("The upgrades to grant when deploying and revoke when undeploying.")] - public readonly string[] Upgrades = { }; + [Desc("The upgrades to grant after deploying and revoke before undeploying.")] + public readonly string[] DeployedUpgrades = { }; [Desc("The terrain types that this actor can deploy on to receive these upgrades. " + "Leave empty to allow any.")] @@ -52,8 +55,10 @@ namespace OpenRA.Mods.Common.Traits public object Create(ActorInitializer init) { return new DeployToUpgrade(init.Self, this); } } - public class DeployToUpgrade : IResolveOrder, IIssueOrder + public class DeployToUpgrade : IResolveOrder, IIssueOrder, INotifyCreated { + enum DeployState { Undeployed, Deploying, Deployed } + readonly Actor self; readonly DeployToUpgradeInfo info; readonly UpgradeManager manager; @@ -61,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits readonly bool canTurn; readonly Lazy body; - bool isUpgraded; + DeployState deployState; public DeployToUpgrade(Actor self, DeployToUpgradeInfo info) { @@ -73,6 +78,11 @@ namespace OpenRA.Mods.Common.Traits body = Exts.Lazy(self.TraitOrDefault); } + public void Created(Actor self) + { + OnUndeployCompleted(); + } + public IEnumerable Orders { get { yield return new DeployOrderTargeter("DeployToUpgrade", 5, @@ -89,59 +99,24 @@ namespace OpenRA.Mods.Common.Traits public void ResolveOrder(Actor self, Order order) { - if (order.OrderString != "DeployToUpgrade") + if (order.OrderString != "DeployToUpgrade" || deployState == DeployState.Deploying) return; - if (!IsOnValidTerrain()) - return; - - if (isUpgraded) - { - // Play undeploy animation and after that revoke the upgrades - self.QueueActivity(false, new CallFunc(() => - { - if (!string.IsNullOrEmpty(info.UndeploySound)) - Game.Sound.Play(info.UndeploySound, self.CenterPosition); - - if (string.IsNullOrEmpty(info.DeployAnimation)) - { - RevokeUpgrades(); - return; - } - - if (body.Value != null) - body.Value.PlayCustomAnimationBackwards(self, info.DeployAnimation, RevokeUpgrades); - else - RevokeUpgrades(); - })); - } - else - { + if (!order.Queued) self.CancelActivity(); - // Turn + if (deployState == DeployState.Deployed) + { + self.QueueActivity(new CallFunc(Undeploy)); + } + else if (deployState == DeployState.Undeployed) + { + // Turn to the required facing. if (info.Facing != -1 && canTurn) self.QueueActivity(new Turn(self, info.Facing)); - // Grant the upgrade - self.QueueActivity(new CallFunc(GrantUpgrades)); - - // Play deploy sound and animation - self.QueueActivity(new CallFunc(() => - { - if (!string.IsNullOrEmpty(info.DeploySound)) - Game.Sound.Play(info.DeploySound, self.CenterPosition); - - if (string.IsNullOrEmpty(info.DeployAnimation)) - return; - - if (body.Value != null) - body.Value.PlayCustomAnimation(self, info.DeployAnimation, - () => body.Value.PlayCustomAnimationRepeating(self, "idle")); - })); + self.QueueActivity(new CallFunc(Deploy)); } - - isUpgraded = !isUpgraded; } bool IsOnValidTerrain() @@ -181,16 +156,80 @@ namespace OpenRA.Mods.Common.Traits return ramp == 0; } - void GrantUpgrades() + /// Play deploy sound and animation. + void Deploy() { - foreach (var up in info.Upgrades) - manager.GrantUpgrade(self, up, this); + // Something went wrong, most likely due to deploy order spam and the fact that this is a delayed action. + if (deployState != DeployState.Undeployed) + return; + + if (!IsOnValidTerrain()) + return; + + if (!string.IsNullOrEmpty(info.DeploySound)) + Game.Sound.Play(info.DeploySound, self.CenterPosition); + + // Revoke upgrades that are used while undeployed. + OnDeployStarted(); + + // If there is no animation to play just grant the upgrades that are used while deployed. + // Alternatively, play the deploy animation and then grant the upgrades. + if (string.IsNullOrEmpty(info.DeployAnimation) || body.Value == null) + OnDeployCompleted(); + else + body.Value.PlayCustomAnimation(self, info.DeployAnimation, OnDeployCompleted); } - void RevokeUpgrades() + /// Play undeploy sound and animation and after that revoke the upgrades. + void Undeploy() { - foreach (var up in info.Upgrades) + // Something went wrong, most likely due to deploy order spam and the fact that this is a delayed action. + if (deployState != DeployState.Deployed) + return; + + if (!string.IsNullOrEmpty(info.UndeploySound)) + Game.Sound.Play(info.UndeploySound, self.CenterPosition); + + OnUndeployStarted(); + + // If there is no animation to play just grant the upgrades that are used while undeployed. + // Alternatively, play the undeploy animation and then grant the upgrades. + if (string.IsNullOrEmpty(info.DeployAnimation) || body.Value == null) + OnUndeployCompleted(); + else + body.Value.PlayCustomAnimationBackwards(self, info.DeployAnimation, OnUndeployCompleted); + } + + void OnDeployStarted() + { + foreach (var up in info.UndeployedUpgrades) manager.RevokeUpgrade(self, up, this); + + deployState = DeployState.Deploying; + } + + void OnDeployCompleted() + { + foreach (var up in info.DeployedUpgrades) + manager.GrantUpgrade(self, up, this); + + deployState = DeployState.Deployed; + } + + void OnUndeployStarted() + { + foreach (var up in info.DeployedUpgrades) + manager.RevokeUpgrade(self, up, this); + + deployState = DeployState.Deploying; + } + + void OnUndeployCompleted() + { + foreach (var up in info.UndeployedUpgrades) + manager.GrantUpgrade(self, up, this); + + deployState = DeployState.Undeployed; } } } From 64dd2357cd957f241109d66357921bf03691e87d Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Mon, 16 Nov 2015 00:54:27 +0200 Subject: [PATCH 2/3] Update thumpers and Mobile Sensor Arrays to the new DeployToUpgrade Currently those are the only two usages of the trait. --- mods/d2k/rules/infantry.yaml | 2 +- mods/ts/rules/shared-vehicles.yaml | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/mods/d2k/rules/infantry.yaml b/mods/d2k/rules/infantry.yaml index ea191795f8..6cf9df6440 100644 --- a/mods/d2k/rules/infantry.yaml +++ b/mods/d2k/rules/infantry.yaml @@ -95,7 +95,7 @@ thumper: Mobile: Speed: 43 DeployToUpgrade: - Upgrades: deployed + DeployedUpgrades: deployed Facing: 128 AllowedTerrainTypes: Sand, Spice, Dune WithInfantryBody: diff --git a/mods/ts/rules/shared-vehicles.yaml b/mods/ts/rules/shared-vehicles.yaml index b779ea67bd..e6b37261f3 100644 --- a/mods/ts/rules/shared-vehicles.yaml +++ b/mods/ts/rules/shared-vehicles.yaml @@ -126,7 +126,8 @@ LPST: gdi: lpst.gdi nod: lpst.nod DeployToUpgrade: - Upgrades: deployed + DeployedUpgrades: deployed + UndeployedUpgrades: undeployed DeployAnimation: make Facing: 160 AllowedTerrainTypes: Clear, Road, DirtRoad, Rough @@ -134,15 +135,15 @@ LPST: UndeploySound: clicky1.aud WithVoxelBody: Image: lpst - UpgradeTypes: deployed - UpgradeMaxEnabledLevel: 0 + UpgradeTypes: undeployed + UpgradeMinEnabledLevel: 1 WithSpriteBody@deployed: StartSequence: make - UpgradeTypes: deployed - UpgradeMinEnabledLevel: 1 + UpgradeTypes: undeployed + UpgradeMaxEnabledLevel: 0 DisableOnUpgrade: - UpgradeTypes: deployed - UpgradeMinEnabledLevel: 1 + UpgradeTypes: undeployed + UpgradeMaxEnabledLevel: 0 DetectCloaked: UpgradeTypes: deployed UpgradeMinEnabledLevel: 1 From ea19f7cd54fe67995e7cdd2ac041ea99ce204d22 Mon Sep 17 00:00:00 2001 From: abcdefg30 Date: Sat, 21 Nov 2015 21:39:17 +0100 Subject: [PATCH 3/3] Add an upgrade rule for the Upgrades -> DeployedUpgrades change --- OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index a9494682ee..74a5db7f47 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -2388,6 +2388,17 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + // Upgrades on DeployToUpgrade were renamed to DeployedUpgrades + if (engineVersion < 20151122) + { + if (node.Key == "DeployToUpgrade") + { + var u = node.Value.Nodes.FirstOrDefault(n => n.Key == "Upgrades"); + if (u != null) + u.Key = "DeployedUpgrades"; + } + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } }