From 0dfdea18265eb19e803278c981027fe1468e3bee Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Thu, 16 Mar 2017 16:16:23 -0500 Subject: [PATCH] Convert AffectedByPowerOutage from disabler to conditional condition granter. --- .../Traits/Power/AffectedByPowerOutage.cs | 45 +++++++++++++++---- .../Traits/Power/Player/PowerManager.cs | 8 ++-- mods/ra/rules/defaults.yaml | 9 ++++ mods/ra/rules/structures.yaml | 6 +-- mods/ts/rules/defaults.yaml | 9 ++++ mods/ts/rules/gdi-structures.yaml | 7 ++- mods/ts/rules/nod-structures.yaml | 6 +-- 7 files changed, 65 insertions(+), 25 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Power/AffectedByPowerOutage.cs b/OpenRA.Mods.Common/Traits/Power/AffectedByPowerOutage.cs index c89fc0018f..019bbb4adb 100644 --- a/OpenRA.Mods.Common/Traits/Power/AffectedByPowerOutage.cs +++ b/OpenRA.Mods.Common/Traits/Power/AffectedByPowerOutage.cs @@ -15,23 +15,39 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Disables the actor when a power outage is triggered (see `InfiltrateForPowerOutage` for more information).")] - public class AffectedByPowerOutageInfo : ITraitInfo + public class AffectedByPowerOutageInfo : ConditionalTraitInfo { - public object Create(ActorInitializer init) { return new AffectedByPowerOutage(init.Self); } + [GrantedConditionReference] + [Desc("The condition to grant while there is a power outage.")] + public readonly string Condition = null; + + public override object Create(ActorInitializer init) { return new AffectedByPowerOutage(init.Self, this); } } - public class AffectedByPowerOutage : INotifyOwnerChanged, ISelectionBar, IPowerModifier, IDisable + public class AffectedByPowerOutage : ConditionalTrait, INotifyOwnerChanged, ISelectionBar, INotifyCreated, INotifyAddedToWorld { PowerManager playerPower; + ConditionManager conditionManager; + int token = ConditionManager.InvalidConditionToken; - public AffectedByPowerOutage(Actor self) + public AffectedByPowerOutage(Actor self, AffectedByPowerOutageInfo info) + : base(info) { playerPower = self.Owner.PlayerActor.Trait(); } + void INotifyAddedToWorld.AddedToWorld(Actor self) { UpdateStatus(self); } + protected override void TraitEnabled(Actor self) { UpdateStatus(self); } + protected override void TraitDisabled(Actor self) { Revoke(self); } + + void INotifyCreated.Created(Actor self) + { + conditionManager = self.TraitOrDefault(); + } + float ISelectionBar.GetValue() { - if (playerPower.PowerOutageRemainingTicks <= 0) + if (IsTraitDisabled || playerPower.PowerOutageRemainingTicks <= 0) return 0; return (float)playerPower.PowerOutageRemainingTicks / playerPower.PowerOutageTotalTicks; @@ -44,19 +60,30 @@ namespace OpenRA.Mods.Common.Traits bool ISelectionBar.DisplayWhenEmpty { get { return false; } } - int IPowerModifier.GetPowerModifier() + public void UpdateStatus(Actor self) { - return playerPower.PowerOutageRemainingTicks > 0 ? 0 : 100; + if (!IsTraitDisabled && playerPower.PowerOutageRemainingTicks > 0) + Grant(self); + else + Revoke(self); } - public bool Disabled + void Grant(Actor self) { - get { return playerPower.PowerOutageRemainingTicks > 0; } + if (token == ConditionManager.InvalidConditionToken) + token = conditionManager.GrantCondition(self, Info.Condition); + } + + void Revoke(Actor self) + { + if (token != ConditionManager.InvalidConditionToken) + token = conditionManager.RevokeCondition(self, token); } void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { playerPower = newOwner.PlayerActor.Trait(); + UpdateStatus(self); } } } diff --git a/OpenRA.Mods.Common/Traits/Power/Player/PowerManager.cs b/OpenRA.Mods.Common/Traits/Power/Player/PowerManager.cs index 5a0b02cbb8..30dfd9eca4 100644 --- a/OpenRA.Mods.Common/Traits/Power/Player/PowerManager.cs +++ b/OpenRA.Mods.Common/Traits/Power/Player/PowerManager.cs @@ -141,11 +141,11 @@ namespace OpenRA.Mods.Common.Traits void UpdatePowerOutageActors() { - var actors = self.World.ActorsHavingTrait() - .Where(a => !a.IsDead && a.IsInWorld && a.Owner == self.Owner); + var traitPairs = self.World.ActorsWithTrait() + .Where(p => !p.Actor.IsDead && p.Actor.IsInWorld && p.Actor.Owner == self.Owner); - foreach (var a in actors) - UpdateActor(a); + foreach (var p in traitPairs) + p.Trait.UpdateStatus(p.Actor); } void IResolveOrder.ResolveOrder(Actor self, Order order) diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index bede68cdd8..da413cbb0c 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -933,3 +933,12 @@ Palette: disabled GrantConditionOnDisabled@IDISABLE: Condition: disabled + +^DisabledByPowerOutage: + AffectedByPowerOutage: + Condition: power-outage + InfiltrateForPowerOutage: + DisableOnCondition@POWER_OUTAGE: + RequiresCondition: power-outage + Power: + RequiresCondition: !power-outage diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 4908d2cb41..6999531d0f 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -1304,6 +1304,7 @@ AFLD: POWR: Inherits: ^Building Inherits@IDISABLE: ^DisabledOverlay + Inherits@POWER_OUTAGE: ^DisabledByPowerOutage Buildable: Queue: Building BuildPaletteOrder: 10 @@ -1327,8 +1328,6 @@ POWR: Bib: Power: Amount: 100 - InfiltrateForPowerOutage: - AffectedByPowerOutage: Targetable: TargetTypes: Ground, Structure, C4, DetonateAttack, SpyInfiltrate ScalePowerWithHealth: @@ -1339,6 +1338,7 @@ POWR: APWR: Inherits: ^Building Inherits@IDISABLE: ^DisabledOverlay + Inherits@POWER_OUTAGE: ^DisabledByPowerOutage Buildable: Queue: Building BuildPaletteOrder: 110 @@ -1366,8 +1366,6 @@ APWR: Bib: Power: Amount: 200 - InfiltrateForPowerOutage: - AffectedByPowerOutage: Targetable: TargetTypes: Ground, Structure, C4, DetonateAttack, SpyInfiltrate ScalePowerWithHealth: diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index 02422a42fb..6b44f5678f 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -954,3 +954,12 @@ Palette: disabled GrantConditionOnDisabled@IDISABLE: Condition: disabled + +^DisabledByPowerOutage: + AffectedByPowerOutage: + Condition: power-outage + InfiltrateForPowerOutage: + DisableOnCondition@POWER_OUTAGE: + RequiresCondition: power-outage + Power: + RequiresCondition: !power-outage diff --git a/mods/ts/rules/gdi-structures.yaml b/mods/ts/rules/gdi-structures.yaml index 5c483d8eaf..0ca13c3d70 100644 --- a/mods/ts/rules/gdi-structures.yaml +++ b/mods/ts/rules/gdi-structures.yaml @@ -1,6 +1,7 @@ GAPOWR: Inherits: ^Building Inherits@IDISABLE: ^DisabledOverlay + Inherits@POWER_OUTAGE: ^DisabledByPowerOutage Buildable: Queue: Building BuildPaletteOrder: 10 @@ -32,8 +33,6 @@ GAPOWR: Bounds: 90, 48, 0, -6 Power: Amount: 100 - InfiltrateForPowerOutage: - AffectedByPowerOutage: PowerTooltip: Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate @@ -43,7 +42,7 @@ GAPOWR: Conditions: powrup: powrup.a Power@pluga: - RequiresCondition: powrup.a + RequiresCondition: powrup.a && !power-outage Amount: 50 WithIdleOverlay@pluga: RequiresCondition: powrup.a @@ -58,7 +57,7 @@ GAPOWR: PauseOnCondition: disabled Sequence: idle-powrupb Power@plugb: - RequiresCondition: powrup.b + RequiresCondition: powrup.b && !power-outage Amount: 50 ProvidesPrerequisite@buildingname: SelectionDecorations: diff --git a/mods/ts/rules/nod-structures.yaml b/mods/ts/rules/nod-structures.yaml index 267286bcc5..cdc1b98ba7 100644 --- a/mods/ts/rules/nod-structures.yaml +++ b/mods/ts/rules/nod-structures.yaml @@ -1,6 +1,7 @@ NAPOWR: Inherits: ^Building Inherits@IDISABLE: ^DisabledOverlay + Inherits@POWER_OUTAGE: ^DisabledByPowerOutage Buildable: Queue: Building BuildPaletteOrder: 20 @@ -29,8 +30,6 @@ NAPOWR: Sequence: idle-lights Power: Amount: 100 - InfiltrateForPowerOutage: - AffectedByPowerOutage: Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate ScalePowerWithHealth: @@ -41,6 +40,7 @@ NAPOWR: NAAPWR: Inherits: ^Building Inherits@IDISABLE: ^DisabledOverlay + Inherits@POWER_OUTAGE: ^DisabledByPowerOutage Buildable: Queue: Building BuildPaletteOrder: 120 @@ -69,8 +69,6 @@ NAAPWR: Sequence: idle-lights Power: Amount: 200 - InfiltrateForPowerOutage: - AffectedByPowerOutage: Targetable: TargetTypes: Ground, C4, DetonateAttack, SpyInfiltrate ScalePowerWithHealth: