diff --git a/OpenRA.Game/Traits/Player/PlayerResources.cs b/OpenRA.Game/Traits/Player/PlayerResources.cs index 604c0e2f3a..1b32342a2c 100644 --- a/OpenRA.Game/Traits/Player/PlayerResources.cs +++ b/OpenRA.Game/Traits/Player/PlayerResources.cs @@ -25,6 +25,12 @@ namespace OpenRA.Traits [Desc("Force the DefaultCash option by disabling changes in the lobby.")] public readonly bool DefaultCashLocked = false; + [Desc("Speech notification to play when the player does not have any funds.")] + public readonly string InsufficientFundsNotification = null; + + [Desc("Delay (in ticks) during which warnings will be muted.")] + public readonly int InsufficientFundsNotificationDelay = 750; + public object Create(ActorInitializer init) { return new PlayerResources(init.Self, this); } } @@ -32,10 +38,12 @@ namespace OpenRA.Traits { const float DisplayCashFracPerFrame = .07f; const int DisplayCashDeltaPerFrame = 37; + readonly PlayerResourcesInfo info; readonly Player owner; public PlayerResources(Actor self, PlayerResourcesInfo info) { + this.info = info; owner = self.Owner; Cash = self.World.LobbyInfo.GlobalSettings.StartingCash; @@ -52,6 +60,8 @@ namespace OpenRA.Traits public int Earned; public int Spent; + int lastNotificationTick; + public bool CanGiveResources(int amount) { return Resources + amount <= ResourceCapacity; @@ -111,9 +121,19 @@ namespace OpenRA.Traits } } - public bool TakeCash(int num) + public bool TakeCash(int num, bool notifyLowFunds = false) { - if (Cash + Resources < num) return false; + if (Cash + Resources < num) + { + if (notifyLowFunds && !string.IsNullOrEmpty(info.InsufficientFundsNotification) && + owner.World.WorldTick - lastNotificationTick >= info.InsufficientFundsNotificationDelay) + { + lastNotificationTick = owner.World.WorldTick; + Game.Sound.PlayNotification(owner.World.Map.Rules, owner, "Speech", info.InsufficientFundsNotification, owner.Faction.InternalName); + } + + return false; + } // Spend ore before cash Resources -= num; diff --git a/OpenRA.Mods.Common/Activities/Repair.cs b/OpenRA.Mods.Common/Activities/Repair.cs index 289ba0e5da..1eb37fd904 100644 --- a/OpenRA.Mods.Common/Activities/Repair.cs +++ b/OpenRA.Mods.Common/Activities/Repair.cs @@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Activities Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", repairsUnits.StartRepairingNotification, self.Owner.Faction.InternalName); } - if (!self.Owner.PlayerActor.Trait().TakeCash(cost)) + if (!self.Owner.PlayerActor.Trait().TakeCash(cost, true)) { remainingTicks = 1; return this; diff --git a/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs b/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs index ea89b45ea1..ea2d860345 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs @@ -115,7 +115,7 @@ namespace OpenRA.Mods.Common.Traits var cost = Math.Max(1, (hpToRepair * Info.RepairPercent * buildingValue) / (health.MaxHP * 100)); // TakeCash will return false if the player can't pay, and will stop him from contributing this Tick - var activePlayers = Repairers.Count(player => player.PlayerActor.Trait().TakeCash(cost)); + var activePlayers = Repairers.Count(player => player.PlayerActor.Trait().TakeCash(cost, true)); RepairActive = activePlayers > 0; diff --git a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs index 197c11eebe..594ce5d707 100644 --- a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs +++ b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs @@ -458,7 +458,7 @@ namespace OpenRA.Mods.Common.Traits } var costThisFrame = RemainingCost / RemainingTime; - if (costThisFrame != 0 && !pr.TakeCash(costThisFrame)) + if (costThisFrame != 0 && !pr.TakeCash(costThisFrame, true)) return; RemainingCost -= costThisFrame;