diff --git a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs index 33540f556f..c3992824c5 100644 --- a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs +++ b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs @@ -12,19 +12,19 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; -using OpenRA.GameRules; using OpenRA.Mods.Common; using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits.Render; using OpenRA.Primitives; +using OpenRA.Support; using OpenRA.Traits; namespace OpenRA.Mods.Cnc.Traits { [Desc("Implements the special case handling for the Chronoshiftable return on a construction yard.", - "Actors that are actively (un)deploying will be returned to the origin as the original actor.", + "If ReturnOriginalActorOnCondition evaluates true and the actor is not being sold then OriginalActor will be returned to the origin.", "Otherwise, a vortex animation is played and damage is dealt each tick, ignoring modifiers.")] - public class ConyardChronoReturnInfo : ITraitInfo, Requires, Requires + public class ConyardChronoReturnInfo : IObservesVariablesInfo, Requires, Requires { [Desc("Sequence name with the baked-in vortex animation"), SequenceReference] public readonly string Sequence = "pdox"; @@ -42,7 +42,12 @@ namespace OpenRA.Mods.Cnc.Traits [Desc("Apply the damage using these damagetypes.")] public readonly BitSet DamageTypes = default(BitSet); - [Desc("Actor to transform into when the timer expires during (un)deploy."), ActorReference] + [ConsumedConditionReference] + [Desc("Boolean expression defining the condition under which to teleport a replacement actor instead of triggering the vortex.")] + public readonly BooleanExpression ReturnOriginalActorOnCondition = null; + + [ActorReference(typeof(MobileInfo))] + [Desc("Replacement actor to create when ReturnOriginalActorOnCondition evaluates true.")] public readonly string OriginalActor = "mcv"; [Desc("Facing of the returned actor.")] @@ -56,8 +61,8 @@ namespace OpenRA.Mods.Cnc.Traits public object Create(ActorInitializer init) { return new ConyardChronoReturn(init, this); } } - public class ConyardChronoReturn : INotifyCreated, ITick, ISync, ISelectionBar, IDeathActorInitModifier, - ITransformActorInitModifier, INotifyBuildComplete, INotifySold, INotifyTransform + public class ConyardChronoReturn : INotifyCreated, ITick, ISync, IObservesVariables, ISelectionBar, INotifySold, + IDeathActorInitModifier, ITransformActorInitModifier { readonly ConyardChronoReturnInfo info; readonly WithSpriteBody wsb; @@ -70,7 +75,7 @@ namespace OpenRA.Mods.Cnc.Traits Actor chronosphere; int duration; - bool buildComplete; + bool returnOriginal; bool selling; [Sync] @@ -110,6 +115,17 @@ namespace OpenRA.Mods.Cnc.Traits conditionManager = self.TraitOrDefault(); } + IEnumerable IObservesVariables.GetVariableObservers() + { + if (info.ReturnOriginalActorOnCondition != null) + yield return new VariableObserver(ReplacementConditionChanged, info.ReturnOriginalActorOnCondition.Variables); + } + + void ReplacementConditionChanged(Actor self, IReadOnlyDictionary conditions) + { + returnOriginal = info.ReturnOriginalActorOnCondition.Evaluate(conditions); + } + void TriggerVortex() { if (conditionManager != null && !string.IsNullOrEmpty(info.Condition) && conditionToken == ConditionManager.InvalidConditionToken) @@ -194,7 +210,7 @@ namespace OpenRA.Mods.Cnc.Traits if (returnTicks <= 0 || --returnTicks > 0) return; - if (!buildComplete && !selling) + if (returnOriginal && !selling) ReturnToOrigin(); else TriggerVortex(); @@ -228,26 +244,12 @@ namespace OpenRA.Mods.Cnc.Traits void IDeathActorInitModifier.ModifyDeathActorInit(Actor self, TypeDictionary init) { ModifyActorInit(init); } void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init) { ModifyActorInit(init); } - void INotifyBuildComplete.BuildingComplete(Actor self) - { - buildComplete = true; - } - void INotifySold.Sold(Actor self) { } void INotifySold.Selling(Actor self) { - buildComplete = false; selling = true; } - void INotifyTransform.BeforeTransform(Actor self) - { - buildComplete = false; - } - - void INotifyTransform.OnTransform(Actor self) { } - void INotifyTransform.AfterTransform(Actor self) { } - // Show the remaining time as a bar float ISelectionBar.GetValue() { diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/20180923/RemovedNotifyBuildComplete.cs b/OpenRA.Mods.Common/UpdateRules/Rules/20180923/RemovedNotifyBuildComplete.cs index 1125f9b068..179fcf8fef 100644 --- a/OpenRA.Mods.Common/UpdateRules/Rules/20180923/RemovedNotifyBuildComplete.cs +++ b/OpenRA.Mods.Common/UpdateRules/Rules/20180923/RemovedNotifyBuildComplete.cs @@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules get { return "Traits are no longer force-disabled while the WithMakeAnimation trait is active.\n" + - "This affects the With*Animation, With*Overlay, and Gate traits.\n" + + "This affects the With*Animation, With*Overlay, Gate, and ConyardChronoReturn traits.\n" + "Affected actors are listed so that conditions may be manually defined."; } } @@ -51,7 +51,8 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules "WithDeliveryAnimation", "WithCrumbleOverlay", "WithDeliveryOverlay", - "Gate" + "Gate", + "ConyardChronoReturn" }; readonly Dictionary> locations = new Dictionary>(); diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index f0e9bbfdf1..d134fd3a17 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -1162,6 +1162,7 @@ FACT: TopLeft: -1536, -1536 BottomRight: 1536, 1536 ConyardChronoReturn: + ReturnOriginalActorOnCondition: build-incomplete Condition: chrono-vortex Damage: 950 TransferTimedExternalConditionOnTransform: