From fd49e487ecec92d2dfa8968e4372f4dbcdd8c080 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 3 Jul 2018 22:11:20 +0000 Subject: [PATCH] Fix MCV deploy erasing Iron Curtain history. --- OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj | 1 + ...ansferTimedExternalConditionOnTransform.cs | 64 +++++++++++++++++++ .../Traits/Conditions/ExternalCondition.cs | 9 ++- mods/ra/rules/structures.yaml | 2 + mods/ra/rules/vehicles.yaml | 2 + 5 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 OpenRA.Mods.Cnc/Traits/TransferTimedExternalConditionOnTransform.cs diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj index 762a7a7d93..30340c17aa 100644 --- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj +++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj @@ -159,6 +159,7 @@ + diff --git a/OpenRA.Mods.Cnc/Traits/TransferTimedExternalConditionOnTransform.cs b/OpenRA.Mods.Cnc/Traits/TransferTimedExternalConditionOnTransform.cs new file mode 100644 index 0000000000..7a966d9410 --- /dev/null +++ b/OpenRA.Mods.Cnc/Traits/TransferTimedExternalConditionOnTransform.cs @@ -0,0 +1,64 @@ +#region Copyright & License Information +/* + * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.Linq; +using OpenRA.Mods.Common.Traits; +using OpenRA.Traits; + +namespace OpenRA.Mods.Cnc.Traits +{ + [Desc("A special case trait that re-grants a timed external condition when this actor transforms.", + "This trait does not work with permanently granted external conditions.", + "This trait changes the external condition source, so cannot be used for conditions that may later be revoked")] + public class TransferTimedExternalConditionOnTransformInfo : ITraitInfo, Requires + { + [FieldLoader.Require] + [Desc("External condition to transfer")] + public readonly string Condition = null; + + public object Create(ActorInitializer init) { return new TransferTimedExternalConditionOnTransform(this); } + } + + public class TransferTimedExternalConditionOnTransform : IConditionTimerWatcher, INotifyTransform + { + readonly TransferTimedExternalConditionOnTransformInfo info; + int duration = 0; + int remaining = 0; + + public TransferTimedExternalConditionOnTransform(TransferTimedExternalConditionOnTransformInfo info) + { + this.info = info; + } + + void INotifyTransform.BeforeTransform(Actor self) { } + void INotifyTransform.OnTransform(Actor self) { } + + void INotifyTransform.AfterTransform(Actor toActor) + { + if (remaining <= 0) + return; + + var external = toActor.TraitsImplementing() + .FirstOrDefault(t => t.Info.Condition == info.Condition && t.CanGrantCondition(toActor, this)); + + if (external != null) + external.GrantCondition(toActor, this, duration, remaining); + } + + void IConditionTimerWatcher.Update(int duration, int remaining) + { + this.duration = duration; + this.remaining = remaining; + } + + string IConditionTimerWatcher.Condition { get { return info.Condition; } } + } +} diff --git a/OpenRA.Mods.Common/Traits/Conditions/ExternalCondition.cs b/OpenRA.Mods.Common/Traits/Conditions/ExternalCondition.cs index a8a98ac0b1..84a684edcb 100644 --- a/OpenRA.Mods.Common/Traits/Conditions/ExternalCondition.cs +++ b/OpenRA.Mods.Common/Traits/Conditions/ExternalCondition.cs @@ -91,7 +91,7 @@ namespace OpenRA.Mods.Common.Traits return true; } - public int GrantCondition(Actor self, object source, int duration = 0) + public int GrantCondition(Actor self, object source, int duration = 0, int remaining = 0) { if (!CanGrantCondition(self, source)) return ConditionManager.InvalidConditionToken; @@ -100,6 +100,11 @@ namespace OpenRA.Mods.Common.Traits HashSet permanent; permanentTokens.TryGetValue(source, out permanent); + // Callers can override the amount of time remaining by passing a value + // between 1 and the duration + if (remaining <= 0 || remaining > duration) + remaining = duration; + if (duration > 0) { // Check level caps @@ -137,7 +142,7 @@ namespace OpenRA.Mods.Common.Traits } } - var timedToken = new TimedToken(token, self, source, duration); + var timedToken = new TimedToken(token, self, source, remaining); var index = timedTokens.FindIndex(t => t.Expires >= timedToken.Expires); if (index >= 0) timedTokens.Insert(index, timedToken); diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 130895235e..0653b2a4f1 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -1136,6 +1136,8 @@ FACT: ConyardChronoReturn: Condition: chrono-vortex Damage: 950 + TransferTimedExternalConditionOnTransform: + Condition: invulnerability PROC: Inherits: ^Building diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index 94b1b2654a..0c5e28b8ff 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -368,6 +368,8 @@ MCV: Actor: MCV.Husk OwnerType: InternalName EffectiveOwnerFromOwner: true + TransferTimedExternalConditionOnTransform: + Condition: invulnerability JEEP: Inherits: ^Vehicle