From f9913db5e8974e3f6461526826d32b858ec96d18 Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Sun, 30 Apr 2017 18:28:13 +0000 Subject: [PATCH] Make Transform use child activities --- OpenRA.Mods.Common/Activities/Transform.cs | 55 ++++++++++++++++++- .../Traits/Render/WithMakeAnimation.cs | 4 +- OpenRA.Mods.Common/Traits/Transforms.cs | 47 +++------------- 3 files changed, 63 insertions(+), 43 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/Transform.cs b/OpenRA.Mods.Common/Activities/Transform.cs index 3cfd3d683e..f5eaf34e02 100644 --- a/OpenRA.Mods.Common/Activities/Transform.cs +++ b/OpenRA.Mods.Common/Activities/Transform.cs @@ -12,7 +12,9 @@ using System.Linq; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Mods.Common.Traits.Render; using OpenRA.Primitives; +using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities { @@ -32,11 +34,61 @@ namespace OpenRA.Mods.Common.Activities ToActor = toActor; } + protected override void OnFirstRun(Actor self) + { + if (self.Info.HasTraitInfo()) + QueueChild(new Turn(self, Facing)); + + if (self.Info.HasTraitInfo()) + QueueChild(new HeliLand(self, true)); + } + public override Activity Tick(Actor self) { if (IsCanceled) return NextActivity; + if (ChildActivity != null) + { + ActivityUtils.RunActivity(self, ChildActivity); + return this; + } + + // Prevent deployment in bogus locations + var transforms = self.TraitOrDefault(); + var building = self.TraitOrDefault(); + if ((transforms != null && !transforms.CanDeploy()) || (building != null && !building.Lock())) + { + Cancel(self, true); + return NextActivity; + } + + foreach (var nt in self.TraitsImplementing()) + nt.BeforeTransform(self); + + var makeAnimation = self.TraitOrDefault(); + if (makeAnimation != null) + { + // Once the make animation starts the activity must not be stopped anymore. + IsInterruptible = false; + + // Wait forever + QueueChild(new WaitFor(() => false)); + makeAnimation.Reverse(self, () => DoTransform(self)); + return this; + } + + return NextActivity; + } + + protected override void OnLastRun(Actor self) + { + if (!IsCanceled) + DoTransform(self); + } + + void DoTransform(Actor self) + { self.World.AddFrameEndTask(w => { if (self.IsDead) @@ -84,11 +136,10 @@ namespace OpenRA.Mods.Common.Activities if (selected) w.Selection.Add(w, a); + if (controlgroup.HasValue) w.Selection.AddToControlGroup(a, controlgroup.Value); }); - - return this; } } } diff --git a/OpenRA.Mods.Common/Traits/Render/WithMakeAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithMakeAnimation.cs index be03da03e6..dec70c2c5e 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithMakeAnimation.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithMakeAnimation.cs @@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits.Render Forward(self, () => building.NotifyBuildingComplete(self)); } - void Forward(Actor self, Action onComplete) + public void Forward(Actor self, Action onComplete) { if (conditionManager != null && !string.IsNullOrEmpty(info.Condition) && token == ConditionManager.InvalidConditionToken) token = conditionManager.GrantCondition(self, info.Condition); @@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits.Render }); } - void Reverse(Actor self, Action onComplete) + public void Reverse(Actor self, Action onComplete) { if (conditionManager != null && !string.IsNullOrEmpty(info.Condition) && token == ConditionManager.InvalidConditionToken) token = conditionManager.GrantCondition(self, info.Condition); diff --git a/OpenRA.Mods.Common/Traits/Transforms.cs b/OpenRA.Mods.Common/Traits/Transforms.cs index da93479c40..dcb184143d 100644 --- a/OpenRA.Mods.Common/Traits/Transforms.cs +++ b/OpenRA.Mods.Common/Traits/Transforms.cs @@ -10,10 +10,8 @@ #endregion using System.Collections.Generic; -using OpenRA.Activities; using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Orders; -using OpenRA.Mods.Common.Traits.Render; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -73,7 +71,7 @@ namespace OpenRA.Mods.Common.Traits return (order.OrderString == "DeployTransform") ? info.Voice : null; } - bool CanDeploy() + public bool CanDeploy() { var building = self.TraitOrDefault(); if (building != null && building.Locked) @@ -113,43 +111,14 @@ namespace OpenRA.Mods.Common.Traits if (!queued) self.CancelActivity(); - if (self.Info.HasTraitInfo()) - self.QueueActivity(new Turn(self, info.Facing)); - - if (self.Info.HasTraitInfo()) - self.QueueActivity(new HeliLand(self, true)); - - self.QueueActivity(new CallFunc(() => + self.QueueActivity(new Transform(self, info.IntoActor) { - // Prevent deployment in bogus locations - var building = self.TraitOrDefault(); - if (!CanDeploy() || (building != null && !building.Lock())) - return; - - foreach (var nt in self.TraitsImplementing()) - nt.BeforeTransform(self); - - var transform = new Transform(self, info.IntoActor) - { - Offset = info.Offset, - Facing = info.Facing, - Sounds = info.TransformSounds, - Notification = info.TransformNotification, - Faction = faction - }; - - // Try and stop the actor from doing anything between the sanity checks above - // and the actual transform, which we're about to queue. - // TODO: The proper way to do this is to write all the transform code as a nested activity. - if (self.CurrentActivity.NextInQueue != null) - self.CurrentActivity.NextInQueue.Cancel(self); - - var makeAnimation = self.TraitOrDefault(); - if (makeAnimation != null) - makeAnimation.Reverse(self, transform); - else - self.QueueActivity(transform); - })); + Offset = info.Offset, + Facing = info.Facing, + Sounds = info.TransformSounds, + Notification = info.TransformNotification, + Faction = faction + }); } public void ResolveOrder(Actor self, Order order)