diff --git a/OpenRA.Game/Traits/Player/PlayerResources.cs b/OpenRA.Game/Traits/Player/PlayerResources.cs index 64f9f9b059..e6a7f9f698 100644 --- a/OpenRA.Game/Traits/Player/PlayerResources.cs +++ b/OpenRA.Game/Traits/Player/PlayerResources.cs @@ -17,7 +17,6 @@ namespace OpenRA.Traits { public readonly int[] SelectableCash = { 2500, 5000, 10000, 20000 }; public readonly int DefaultCash = 5000; - public readonly int AdviceInterval = 250; public object Create(ActorInitializer init) { return new PlayerResources(init.Self, this); } } @@ -27,14 +26,12 @@ namespace OpenRA.Traits const float DisplayCashFracPerFrame = .07f; const int DisplayCashDeltaPerFrame = 37; readonly Player owner; - int adviceInterval; public PlayerResources(Actor self, PlayerResourcesInfo info) { owner = self.Owner; Cash = self.World.LobbyInfo.GlobalSettings.StartingCash; - adviceInterval = info.AdviceInterval; } [Sync] public int Cash; @@ -44,7 +41,6 @@ namespace OpenRA.Traits public int DisplayCash; public int DisplayResources; - public bool AlertSilo; public int Earned; public int Spent; @@ -61,8 +57,6 @@ namespace OpenRA.Traits if (Resources > ResourceCapacity) { - nextSiloAdviceTime = 0; - Earned -= Resources - ResourceCapacity; Resources = ResourceCapacity; } @@ -126,7 +120,6 @@ namespace OpenRA.Traits return true; } - int nextSiloAdviceTime = 0; int nextCashTickTime = 0; public void Tick(Actor self) @@ -141,19 +134,6 @@ namespace OpenRA.Traits if (Resources > ResourceCapacity) Resources = ResourceCapacity; - if (--nextSiloAdviceTime <= 0) - { - if (Resources > 0.8 * ResourceCapacity) - { - Game.Sound.PlayNotification(self.World.Map.Rules, owner, "Speech", "SilosNeeded", owner.Faction.InternalName); - AlertSilo = true; - } - else - AlertSilo = false; - - nextSiloAdviceTime = adviceInterval; - } - var diff = Math.Abs(Cash - DisplayCash); var move = Math.Min(Math.Max((int)(diff * DisplayCashFracPerFrame), DisplayCashDeltaPerFrame), diff); diff --git a/OpenRA.Mods.Common/AI/BaseBuilder.cs b/OpenRA.Mods.Common/AI/BaseBuilder.cs index babe172c87..ae7e359276 100644 --- a/OpenRA.Mods.Common/AI/BaseBuilder.cs +++ b/OpenRA.Mods.Common/AI/BaseBuilder.cs @@ -272,7 +272,7 @@ namespace OpenRA.Mods.Common.AI } // Create some head room for resource storage if we really need it - if (playerResources.AlertSilo) + if (playerResources.Resources > 0.8 * playerResources.ResourceCapacity) { var silo = GetProducibleBuilding("Silo", buildableThings); if (silo != null && HasSufficientPowerForActor(silo)) diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index ee5846cd43..b77937ff83 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -382,6 +382,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/Player/ResourceStorageWarning.cs b/OpenRA.Mods.Common/Traits/Player/ResourceStorageWarning.cs new file mode 100644 index 0000000000..4c15151ca1 --- /dev/null +++ b/OpenRA.Mods.Common/Traits/Player/ResourceStorageWarning.cs @@ -0,0 +1,56 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 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. For more information, + * see COPYING. + */ +#endregion + +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Traits +{ + [Desc("Provides the player with an audible warning when their storage is nearing full.")] + public class ResourceStorageWarningInfo : ITraitInfo, Requires + { + [Desc("Interval, in seconds, at which to check if more storage is needed.")] + public readonly int AdviceInterval = 10; + + [Desc("The percentage threshold above which a warning is played.")] + public readonly int Threshold = 80; + + [Desc("The speech to play for the warning.")] + public readonly string Notification = "SilosNeeded"; + + public object Create(ActorInitializer init) { return new ResourceStorageWarning(init.Self, this); } + } + + public class ResourceStorageWarning : ITick + { + readonly ResourceStorageWarningInfo info; + readonly PlayerResources resources; + + int nextSiloAdviceTime = 0; + + public ResourceStorageWarning(Actor self, ResourceStorageWarningInfo info) + { + this.info = info; + resources = self.Trait(); + } + + public void Tick(Actor self) + { + if (--nextSiloAdviceTime <= 0) + { + var owner = self.Owner; + + if (resources.Resources > info.Threshold * resources.ResourceCapacity / 100) + Game.Sound.PlayNotification(self.World.Map.Rules, owner, "Speech", info.Notification, owner.Faction.InternalName); + + nextSiloAdviceTime = info.AdviceInterval * 1000 / self.World.Timestep; + } + } + } +} diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 3391274d74..68a1d504ea 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -2764,6 +2764,30 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + // Refactored the low resources notification to a separate trait + if (engineVersion < 20151227 && node.Key == "Player") + { + var resourcesNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "PlayerResources"); + + if (resourcesNode != null) + { + var intervalNode = resourcesNode.Value.Nodes.FirstOrDefault(x => x.Key == "AdviceInterval"); + var storageNode = new MiniYamlNode("ResourceStorageWarning", ""); + + if (intervalNode != null) + { + // The time value is now in seconds, not ticks. We + // divide by 25 ticks per second at Normal. + int oldInterval; + if (int.TryParse(intervalNode.Value.Value, out oldInterval)) + storageNode.Value.Nodes.Add(new MiniYamlNode("AdviceInterval", (oldInterval / 25).ToString())); + resourcesNode.Value.Nodes.Remove(intervalNode); + } + + node.Value.Nodes.Add(storageNode); + } + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/mods/cnc/rules/player.yaml b/mods/cnc/rules/player.yaml index 972385a259..ac5a01793d 100644 --- a/mods/cnc/rules/player.yaml +++ b/mods/cnc/rules/player.yaml @@ -29,4 +29,5 @@ Player: Name: Unrestricted Prerequisites: techlevel.low, techlevel.medium, techlevel.high, techlevel.superweapons GlobalUpgradeManager: + ResourceStorageWarning: diff --git a/mods/d2k/rules/player.yaml b/mods/d2k/rules/player.yaml index ffec06eb29..436efe1869 100644 --- a/mods/d2k/rules/player.yaml +++ b/mods/d2k/rules/player.yaml @@ -61,7 +61,6 @@ Player: AllyRepair: PlayerResources: SelectableCash: 2500, 5000, 7000, 10000, 20000 - AdviceInterval: 650 ActorGroupProxy: DeveloperMode: BaseAttackNotifier: @@ -85,4 +84,6 @@ Player: EnemyWatcher: HarvesterInsurance: GlobalUpgradeManager: + ResourceStorageWarning: + AdviceInterval: 26 diff --git a/mods/ra/rules/player.yaml b/mods/ra/rules/player.yaml index 9361dd786e..4968a597e0 100644 --- a/mods/ra/rules/player.yaml +++ b/mods/ra/rules/player.yaml @@ -68,4 +68,5 @@ Player: VeteranProductionIconOverlay: Image: iconchevrons Sequence: veteran + ResourceStorageWarning: diff --git a/mods/ts/rules/player.yaml b/mods/ts/rules/player.yaml index 970e388ca5..71db70ee03 100644 --- a/mods/ts/rules/player.yaml +++ b/mods/ts/rules/player.yaml @@ -48,4 +48,5 @@ Player: HarvesterAttackNotifier: PlayerStatistics: PlaceBeacon: + ResourceStorageWarning: