diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index c814004268..c65b6b5f84 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -331,7 +331,7 @@ - + @@ -373,7 +373,7 @@ - + diff --git a/OpenRA.Mods.Common/Traits/GlobalUpgradable.cs b/OpenRA.Mods.Common/Traits/GlobalUpgradable.cs deleted file mode 100644 index c9f9a3c652..0000000000 --- a/OpenRA.Mods.Common/Traits/GlobalUpgradable.cs +++ /dev/null @@ -1,72 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2016 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.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - [Desc("Grants upgrades to the actor this is attached to when prerequisites are available.")] - public class GlobalUpgradableInfo : ITraitInfo, Requires - { - [UpgradeGrantedReference, FieldLoader.Require] - [Desc("List of upgrades to apply.")] - public readonly string[] Upgrades = { }; - - [FieldLoader.Require] - [Desc("List of required prerequisites.")] - public readonly string[] Prerequisites = { }; - - public object Create(ActorInitializer init) { return new GlobalUpgradable(init.Self, this); } - } - - public class GlobalUpgradable : INotifyAddedToWorld, INotifyRemovedFromWorld - { - readonly GlobalUpgradableInfo info; - readonly GlobalUpgradeManager globalManager; - readonly UpgradeManager manager; - bool wasAvailable; - - public GlobalUpgradable(Actor self, GlobalUpgradableInfo info) - { - this.info = info; - globalManager = self.Owner.PlayerActor.Trait(); - manager = self.Trait(); - } - - public void AddedToWorld(Actor self) - { - if (info.Prerequisites.Any()) - globalManager.Register(self, this, info.Prerequisites); - } - - public void RemovedFromWorld(Actor self) - { - if (info.Prerequisites.Any()) - globalManager.Unregister(self, this, info.Prerequisites); - } - - public void PrerequisitesUpdated(Actor self, bool available) - { - if (available == wasAvailable) - return; - - if (available) - foreach (var u in info.Upgrades) - manager.GrantUpgrade(self, u, this); - else - foreach (var u in info.Upgrades) - manager.RevokeUpgrade(self, u, this); - - wasAvailable = available; - } - } -} diff --git a/OpenRA.Mods.Common/Traits/GrantConditionOnPrerequisite.cs b/OpenRA.Mods.Common/Traits/GrantConditionOnPrerequisite.cs new file mode 100644 index 0000000000..77b01d7f7c --- /dev/null +++ b/OpenRA.Mods.Common/Traits/GrantConditionOnPrerequisite.cs @@ -0,0 +1,78 @@ +#region Copyright & License Information +/* + * Copyright 2007-2016 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.Traits; + +namespace OpenRA.Mods.Common.Traits +{ + [Desc("Grants a condition to the actor this is attached to when prerequisites are available.")] + public class GrantConditionOnPrerequisiteInfo : ITraitInfo + { + [FieldLoader.Require] + [UpgradeGrantedReference] + [Desc("The condition to grant.")] + public readonly string Condition = null; + + [FieldLoader.Require] + [Desc("List of required prerequisites.")] + public readonly string[] Prerequisites = { }; + + public object Create(ActorInitializer init) { return new GrantConditionOnPrerequisite(init.Self, this); } + } + + public class GrantConditionOnPrerequisite : INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld + { + readonly GrantConditionOnPrerequisiteInfo info; + readonly GrantConditionOnPrerequisiteManager globalManager; + + UpgradeManager manager; + int conditionToken = UpgradeManager.InvalidConditionToken; + + bool wasAvailable; + + public GrantConditionOnPrerequisite(Actor self, GrantConditionOnPrerequisiteInfo info) + { + this.info = info; + globalManager = self.Owner.PlayerActor.Trait(); + } + + void INotifyCreated.Created(Actor self) + { + manager = self.TraitOrDefault(); + } + + void INotifyAddedToWorld.AddedToWorld(Actor self) + { + if (info.Prerequisites.Any()) + globalManager.Register(self, this, info.Prerequisites); + } + + void INotifyRemovedFromWorld.RemovedFromWorld(Actor self) + { + if (info.Prerequisites.Any()) + globalManager.Unregister(self, this, info.Prerequisites); + } + + public void PrerequisitesUpdated(Actor self, bool available) + { + if (available == wasAvailable || manager == null) + return; + + if (available && conditionToken == UpgradeManager.InvalidConditionToken) + conditionToken = manager.GrantCondition(self, info.Condition); + else if (!available && conditionToken != UpgradeManager.InvalidConditionToken) + conditionToken = manager.RevokeCondition(self, conditionToken); + + wasAvailable = available; + } + } +} diff --git a/OpenRA.Mods.Common/Traits/Player/GlobalUpgradeManager.cs b/OpenRA.Mods.Common/Traits/Player/GrantConditionOnPrerequisiteManager.cs similarity index 68% rename from OpenRA.Mods.Common/Traits/Player/GlobalUpgradeManager.cs rename to OpenRA.Mods.Common/Traits/Player/GrantConditionOnPrerequisiteManager.cs index 30159665b1..5328c3ec1b 100644 --- a/OpenRA.Mods.Common/Traits/Player/GlobalUpgradeManager.cs +++ b/OpenRA.Mods.Common/Traits/Player/GrantConditionOnPrerequisiteManager.cs @@ -17,18 +17,18 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Attach this to the player actor.")] - public class GlobalUpgradeManagerInfo : ITraitInfo, Requires + public class GrantConditionOnPrerequisiteManagerInfo : ITraitInfo, Requires { - public object Create(ActorInitializer init) { return new GlobalUpgradeManager(init); } + public object Create(ActorInitializer init) { return new GrantConditionOnPrerequisiteManager(init); } } - public class GlobalUpgradeManager : ITechTreeElement + public class GrantConditionOnPrerequisiteManager : ITechTreeElement { readonly Actor self; - readonly Dictionary>> upgradables = new Dictionary>>(); + readonly Dictionary>> upgradables = new Dictionary>>(); readonly TechTree techTree; - public GlobalUpgradeManager(ActorInitializer init) + public GrantConditionOnPrerequisiteManager(ActorInitializer init) { self = init.Self; techTree = self.Trait(); @@ -39,12 +39,12 @@ namespace OpenRA.Mods.Common.Traits return "upgrade_" + string.Join("_", prerequisites.OrderBy(a => a)); } - public void Register(Actor actor, GlobalUpgradable u, string[] prerequisites) + public void Register(Actor actor, GrantConditionOnPrerequisite u, string[] prerequisites) { var key = MakeKey(prerequisites); if (!upgradables.ContainsKey(key)) { - upgradables.Add(key, new List>()); + upgradables.Add(key, new List>()); techTree.Add(key, prerequisites, 0, this); } @@ -54,7 +54,7 @@ namespace OpenRA.Mods.Common.Traits u.PrerequisitesUpdated(actor, techTree.HasPrerequisites(prerequisites)); } - public void Unregister(Actor actor, GlobalUpgradable u, string[] prerequisites) + public void Unregister(Actor actor, GrantConditionOnPrerequisite u, string[] prerequisites) { var key = MakeKey(prerequisites); var list = upgradables[key]; @@ -69,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits public void PrerequisitesAvailable(string key) { - List> list; + List> list; if (!upgradables.TryGetValue(key, out list)) return; @@ -79,7 +79,7 @@ namespace OpenRA.Mods.Common.Traits public void PrerequisitesUnavailable(string key) { - List> list; + List> list; if (!upgradables.TryGetValue(key, out list)) return; diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 96dc5e1ad7..0404547e9f 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -659,6 +659,15 @@ namespace OpenRA.Mods.Common.UtilityCommands } } } + + if (node.Key.StartsWith("GlobalUpgradable", StringComparison.Ordinal)) + { + RenameNodeKey(node, "GrantConditionOnPrerequisite"); + ConvertUpgradesToCondition(parent, node, "Upgrades", "Condition"); + } + + if (node.Key.StartsWith("GlobalUpgradeManager", StringComparison.Ordinal)) + RenameNodeKey(node, "GrantConditionOnPrerequisiteManager"); } UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1); diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index e7a42283b4..dae11b0b0f 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -283,8 +283,8 @@ DamageInterval: 16 DamageTypes: TiberiumDeath RequiresCondition: !hazmatsuits - GlobalUpgradable@BIO: - Upgrades: hazmatsuits + GrantConditionOnPrerequisite@BIO: + Condition: hazmatsuits Prerequisites: bio WithDecoration@HAZMAT: Image: pips @@ -309,8 +309,8 @@ HealIfBelow: 100 DamageCooldown: 125 RequiresCondition: hospitalheal - GlobalUpgradable@HOSPITAL: - Upgrades: hospitalheal + GrantConditionOnPrerequisite@HOSPITAL: + Condition: hospitalheal Prerequisites: hosp WithDecoration@REDCROSS: Image: pips diff --git a/mods/cnc/rules/player.yaml b/mods/cnc/rules/player.yaml index 7ed7a2fa29..1abb134acd 100644 --- a/mods/cnc/rules/player.yaml +++ b/mods/cnc/rules/player.yaml @@ -32,6 +32,6 @@ Player: Name: Unrestricted Prerequisites: techlevel.low, techlevel.medium, techlevel.high, techlevel.superweapons Id: unrestricted - GlobalUpgradeManager: + GrantConditionOnPrerequisiteManager: ResourceStorageWarning: PlayerExperience: diff --git a/mods/d2k/rules/player.yaml b/mods/d2k/rules/player.yaml index 07953f32a6..3cab2f57e6 100644 --- a/mods/d2k/rules/player.yaml +++ b/mods/d2k/rules/player.yaml @@ -88,7 +88,7 @@ Player: Id: unrestricted EnemyWatcher: HarvesterInsurance: - GlobalUpgradeManager: + GrantConditionOnPrerequisiteManager: ResourceStorageWarning: AdviceInterval: 26 PlayerExperience: diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index c01f8d4b3d..4630126854 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -90,9 +90,9 @@ construction_yard: PrimaryBuilding: PrimaryCondition: primary ProvidesPrerequisite@buildingname: - GlobalUpgradable: + GrantConditionOnPrerequisite: Prerequisites: upgrade.conyard - Upgrades: stardecoration + Condition: stardecoration WithDecoration@upgraded: RequiresSelection: true Image: pips @@ -203,9 +203,9 @@ barracks: smuggler: barracks.ordos mercenary: barracks.ordos ProvidesPrerequisite@buildingname: - GlobalUpgradable: + GrantConditionOnPrerequisite: Prerequisites: upgrade.barracks - Upgrades: stardecoration + Condition: stardecoration WithDecoration@upgraded: RequiresSelection: true Image: pips @@ -383,9 +383,9 @@ light_factory: Sequence: idle-top Power: Amount: -125 - GlobalUpgradable: + GrantConditionOnPrerequisite: Prerequisites: upgrade.light - Upgrades: stardecoration + Condition: stardecoration WithDecoration@upgraded: RequiresSelection: true Image: pips @@ -463,9 +463,9 @@ heavy_factory: ProvidesPrerequisite@buildingname: SelectionDecorations: VisualBounds: 96,96 - GlobalUpgradable: + GrantConditionOnPrerequisite: Prerequisites: upgrade.heavy - Upgrades: stardecoration + Condition: stardecoration WithDecoration@upgraded: RequiresSelection: true Image: pips @@ -841,9 +841,9 @@ high_tech_factory: Amount: -75 SelectionDecorations: VisualBounds: 96,96 - GlobalUpgradable: + GrantConditionOnPrerequisite: Prerequisites: upgrade.hightech - Upgrades: stardecoration + Condition: stardecoration WithDecoration@upgraded: RequiresSelection: true Image: pips diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index c477179ba5..11fd6bb8e3 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -291,8 +291,8 @@ HealIfBelow: 100 DamageCooldown: 125 RequiresCondition: hospitalheal - GlobalUpgradable: - Upgrades: hospitalheal + GrantConditionOnPrerequisite: + Condition: hospitalheal Prerequisites: hosp DeathSounds@NORMAL: DeathTypes: DefaultDeath, BulletDeath, SmallExplosionDeath, ExplosionDeath diff --git a/mods/ra/rules/player.yaml b/mods/ra/rules/player.yaml index 6ef8a5fbff..366cafcc6f 100644 --- a/mods/ra/rules/player.yaml +++ b/mods/ra/rules/player.yaml @@ -69,7 +69,7 @@ Player: Name: Unrestricted Prerequisites: techlevel.infonly, techlevel.low, techlevel.medium, techlevel.high, techlevel.unrestricted Id: unrestricted - GlobalUpgradeManager: + GrantConditionOnPrerequisiteManager: EnemyWatcher: VeteranProductionIconOverlay: Image: iconchevrons diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index bb6595289c..870252e777 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -326,8 +326,8 @@ HealIfBelow: 100 DamageCooldown: 125 RequiresCondition: hospitalheal - GlobalUpgradable@HOSPITAL: - Upgrades: hospitalheal + GrantConditionOnPrerequisite@HOSPITAL: + Condition: hospitalheal Prerequisites: cahosp WithDecoration@REDCROSS: Image: pips diff --git a/mods/ts/rules/player.yaml b/mods/ts/rules/player.yaml index 738db4d503..61fa7f4d64 100644 --- a/mods/ts/rules/player.yaml +++ b/mods/ts/rules/player.yaml @@ -1,7 +1,7 @@ Player: AlwaysVisible: TechTree: - GlobalUpgradeManager: + GrantConditionOnPrerequisiteManager: ClassicProductionQueue@Building: Type: Building BuildDurationModifier: 120