From 8699d0fca3531c9d73cdf2aa369fd7649eba8916 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sat, 12 Nov 2016 19:07:17 +0100 Subject: [PATCH] Safeguard CashTrickler negative values By making sure to never remove more cash than the player has. --- OpenRA.Mods.Common/Traits/CashTrickler.cs | 40 +++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/CashTrickler.cs b/OpenRA.Mods.Common/Traits/CashTrickler.cs index 3be8872a76..34df31a95a 100644 --- a/OpenRA.Mods.Common/Traits/CashTrickler.cs +++ b/OpenRA.Mods.Common/Traits/CashTrickler.cs @@ -9,13 +9,14 @@ */ #endregion +using System; using OpenRA.Mods.Common.Effects; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Lets the actor generate cash in a set periodic time.")] - class CashTricklerInfo : ConditionalTraitInfo + public class CashTricklerInfo : ConditionalTraitInfo { [Desc("Number of ticks to wait between giving money.")] public readonly int Interval = 50; @@ -32,9 +33,10 @@ namespace OpenRA.Mods.Common.Traits public override object Create(ActorInitializer init) { return new CashTrickler(this); } } - class CashTrickler : ConditionalTrait, ITick, ISync + public class CashTrickler : ConditionalTrait, ITick, ISync, INotifyCreated, INotifyOwnerChanged { readonly CashTricklerInfo info; + PlayerResources resources; [Sync] int ticks; public CashTrickler(CashTricklerInfo info) @@ -43,6 +45,16 @@ namespace OpenRA.Mods.Common.Traits this.info = info; } + void INotifyCreated.Created(Actor self) + { + resources = self.Owner.PlayerActor.Trait(); + } + + void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) + { + resources = newOwner.PlayerActor.Trait(); + } + void ITick.Tick(Actor self) { if (IsTraitDisabled) @@ -51,10 +63,7 @@ namespace OpenRA.Mods.Common.Traits if (--ticks < 0) { ticks = info.Interval; - self.Owner.PlayerActor.Trait().GiveCash(info.Amount); - - if (info.ShowTicks) - AddCashTick(self, info.Amount); + ModifyCash(self, self.Owner, info.Amount); } } @@ -63,5 +72,24 @@ namespace OpenRA.Mods.Common.Traits self.World.AddFrameEndTask(w => w.Add( new FloatingText(self.CenterPosition, self.Owner.Color.RGB, FloatingText.FormatCashTick(amount), info.DisplayDuration))); } + + void ModifyCash(Actor self, Player newOwner, int amount) + { + if (amount < 0) + { + // Check whether the amount of cash to be removed would exceed available player cash, in that case only remove all the player cash + var drain = Math.Min(resources.Cash + resources.Resources, -amount); + resources.TakeCash(drain); + + if (info.ShowTicks) + AddCashTick(self, -drain); + } + else + { + resources.GiveCash(amount); + if (info.ShowTicks) + AddCashTick(self, amount); + } + } } }