From bc1e2a70580e515ab277b6088cdaa74b64ae4a88 Mon Sep 17 00:00:00 2001 From: Zimmermann Gyula Date: Wed, 5 Oct 2016 17:01:01 +0200 Subject: [PATCH 1/3] Revamp CashTrickler. Added upgrade support. Decoupled the capture bonus to a separate trait. --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + OpenRA.Mods.Common/Traits/CashTrickler.cs | 21 ++---- .../Traits/GivesCashOnCapture.cs | 70 +++++++++++++++++++ .../UtilityCommands/UpgradeRules.cs | 23 ++++++ mods/ra/rules/civilian.yaml | 3 +- 5 files changed, 103 insertions(+), 15 deletions(-) create mode 100644 OpenRA.Mods.Common/Traits/GivesCashOnCapture.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index b4dc3ae87c..891e8c8839 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -331,6 +331,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/CashTrickler.cs b/OpenRA.Mods.Common/Traits/CashTrickler.cs index bbc181e704..741bbbc000 100644 --- a/OpenRA.Mods.Common/Traits/CashTrickler.cs +++ b/OpenRA.Mods.Common/Traits/CashTrickler.cs @@ -15,7 +15,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Lets the actor generate cash in a set periodic time.")] - class CashTricklerInfo : ITraitInfo + class CashTricklerInfo : ConditionalTraitInfo { [Desc("Number of ticks to wait between giving money.")] public readonly int Period = 50; @@ -23,23 +23,25 @@ namespace OpenRA.Mods.Common.Traits public readonly int Amount = 15; [Desc("Whether to show the cash tick indicators (+$15 rising from actor).")] public readonly bool ShowTicks = true; - [Desc("Amount of money awarded for capturing the actor.")] - public readonly int CaptureAmount = 0; - public object Create(ActorInitializer init) { return new CashTrickler(this); } + public override object Create(ActorInitializer init) { return new CashTrickler(this); } } - class CashTrickler : ITick, ISync, INotifyCapture + class CashTrickler : ConditionalTrait, ITick, ISync { readonly CashTricklerInfo info; [Sync] int ticks; public CashTrickler(CashTricklerInfo info) + : base(info) { this.info = info; } public void Tick(Actor self) { + if (IsTraitDisabled) + return; + if (--ticks < 0) { ticks = info.Period; @@ -48,15 +50,6 @@ namespace OpenRA.Mods.Common.Traits } } - public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner) - { - if (info.CaptureAmount > 0) - { - newOwner.PlayerActor.Trait().GiveCash(info.CaptureAmount); - MaybeAddCashTick(self, info.CaptureAmount); - } - } - void MaybeAddCashTick(Actor self, int amount) { if (info.ShowTicks) diff --git a/OpenRA.Mods.Common/Traits/GivesCashOnCapture.cs b/OpenRA.Mods.Common/Traits/GivesCashOnCapture.cs new file mode 100644 index 0000000000..3e6d572ac7 --- /dev/null +++ b/OpenRA.Mods.Common/Traits/GivesCashOnCapture.cs @@ -0,0 +1,70 @@ +#region Copyright & License Information +/* + * Copyright 2007-2017 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; +using OpenRA.Mods.Common.Effects; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Traits +{ + [Desc("Lets the actor grant cash when captured.")] + public class GivesCashOnCaptureInfo : ConditionalTraitInfo + { + [Desc("Whether to show the cash tick indicators rising from the actor.")] + public readonly bool ShowTicks = true; + + [Desc("How long to show the Amount tick indicator when enabled.")] + public readonly int DisplayDuration = 30; + + [Desc("Amount of money awarded for capturing the actor.")] + public readonly int Amount = 0; + + public override object Create(ActorInitializer init) { return new GivesCashOnCapture(this); } + } + + public class GivesCashOnCapture : ConditionalTrait, INotifyCapture + { + readonly GivesCashOnCaptureInfo info; + + public GivesCashOnCapture(GivesCashOnCaptureInfo info) + : base(info) + { + this.info = info; + } + + void INotifyCapture.OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner) + { + if (IsTraitDisabled) + return; + + var resources = newOwner.PlayerActor.Trait(); + var amount = info.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 + amount = Math.Min(resources.Cash + resources.Resources, -amount); + resources.TakeCash(amount); + + // For correct cash tick display + amount = -amount; + } + else + resources.GiveCash(amount); + + if (!info.ShowTicks) + return; + + self.World.AddFrameEndTask(w => w.Add( + new FloatingText(self.CenterPosition, self.Owner.Color.RGB, FloatingText.FormatCashTick(amount), info.DisplayDuration))); + } + } +} diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index b04f124f06..0f6a1dff81 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -720,6 +720,29 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + // Capture bonus was decoupled from CashTrickler to a separate trait. + if (engineVersion < 20170108 && depth == 0) + { + var trickler = node.Value.Nodes.FirstOrDefault(n => n.Key == "CashTrickler"); + if (trickler != null) + { + var capture = trickler.Value.Nodes.FirstOrDefault(n => n.Key == "CaptureAmount"); + if (capture != null) + { + var gcoc = new MiniYamlNode("GivesCashOnCapture", ""); + gcoc.Value.Nodes.Add(capture); + trickler.Value.Nodes.Remove(capture); + + var show = trickler.Value.Nodes.FirstOrDefault(n => n.Key == "ShowTicks"); + if (show != null) + gcoc.Value.Nodes.Add(show); + + node.Value.Nodes.Add(gcoc); + RenameNodeKey(capture, "Amount"); + } + } + } + UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1); } diff --git a/mods/ra/rules/civilian.yaml b/mods/ra/rules/civilian.yaml index ddad7f75cf..92b5a43b0e 100644 --- a/mods/ra/rules/civilian.yaml +++ b/mods/ra/rules/civilian.yaml @@ -366,13 +366,14 @@ OILB: CashTrickler: Period: 375 Amount: 100 - CaptureAmount: 100 Tooltip: Name: Oil Derrick Explodes: Weapon: BarrelExplode GpsDot: String: Oil + GivesCashOnCapture: + Amount: 100 BR1: Inherits: ^Bridge From 7dcda5db30de09da654864590b9249d8057f39e2 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sun, 6 Nov 2016 17:42:48 +0100 Subject: [PATCH 2/3] CashTrickler style fixes and Period -> Interval rename --- OpenRA.Mods.Common/Traits/CashTrickler.cs | 24 ++++++++++++------- .../UtilityCommands/UpgradeRules.cs | 4 ++++ mods/ra/maps/bomber-john/rules.yaml | 4 ++-- mods/ra/maps/fort-lonestar/rules.yaml | 2 +- mods/ra/rules/civilian.yaml | 2 +- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/CashTrickler.cs b/OpenRA.Mods.Common/Traits/CashTrickler.cs index 741bbbc000..3be8872a76 100644 --- a/OpenRA.Mods.Common/Traits/CashTrickler.cs +++ b/OpenRA.Mods.Common/Traits/CashTrickler.cs @@ -18,12 +18,17 @@ namespace OpenRA.Mods.Common.Traits class CashTricklerInfo : ConditionalTraitInfo { [Desc("Number of ticks to wait between giving money.")] - public readonly int Period = 50; + public readonly int Interval = 50; + [Desc("Amount of money to give each time.")] public readonly int Amount = 15; - [Desc("Whether to show the cash tick indicators (+$15 rising from actor).")] + + [Desc("Whether to show the cash tick indicators rising from the actor.")] public readonly bool ShowTicks = true; + [Desc("How long to show the cash tick indicator when enabled.")] + public readonly int DisplayDuration = 30; + public override object Create(ActorInitializer init) { return new CashTrickler(this); } } @@ -31,29 +36,32 @@ namespace OpenRA.Mods.Common.Traits { readonly CashTricklerInfo info; [Sync] int ticks; + public CashTrickler(CashTricklerInfo info) : base(info) { this.info = info; } - public void Tick(Actor self) + void ITick.Tick(Actor self) { if (IsTraitDisabled) return; if (--ticks < 0) { - ticks = info.Period; + ticks = info.Interval; self.Owner.PlayerActor.Trait().GiveCash(info.Amount); - MaybeAddCashTick(self, info.Amount); + + if (info.ShowTicks) + AddCashTick(self, info.Amount); } } - void MaybeAddCashTick(Actor self, int amount) + void AddCashTick(Actor self, int amount) { - if (info.ShowTicks) - self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, self.Owner.Color.RGB, FloatingText.FormatCashTick(amount), 30))); + self.World.AddFrameEndTask(w => w.Add( + new FloatingText(self.CenterPosition, self.Owner.Color.RGB, FloatingText.FormatCashTick(amount), info.DisplayDuration))); } } } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 0f6a1dff81..b97b4cd553 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -740,6 +740,10 @@ namespace OpenRA.Mods.Common.UtilityCommands node.Value.Nodes.Add(gcoc); RenameNodeKey(capture, "Amount"); } + + var period = trickler.Value.Nodes.FirstOrDefault(n => n.Key == "Period"); + if (period != null) + period.Key = "Interval"; } } diff --git a/mods/ra/maps/bomber-john/rules.yaml b/mods/ra/maps/bomber-john/rules.yaml index 2d92b36338..e4fd0104ac 100644 --- a/mods/ra/maps/bomber-john/rules.yaml +++ b/mods/ra/maps/bomber-john/rules.yaml @@ -91,7 +91,7 @@ MNLYR: Offset: 0,0 Facing: 96 CashTrickler: - Period: 150 + Interval: 150 Amount: 20 RenderSprites: Image: MNLY @@ -108,7 +108,7 @@ FTUR: MustBeDestroyed: RequiredForShortGame: true CashTrickler: - Period: 150 + Interval: 150 Amount: 30 ChronoshiftPower: Icon: chrono diff --git a/mods/ra/maps/fort-lonestar/rules.yaml b/mods/ra/maps/fort-lonestar/rules.yaml index 2c2183987f..7a6eb009b9 100644 --- a/mods/ra/maps/fort-lonestar/rules.yaml +++ b/mods/ra/maps/fort-lonestar/rules.yaml @@ -117,7 +117,7 @@ OILB: RevealsShroud: Range: 3c0 CashTrickler: - Period: 250 + Interval: 250 Amount: 50 MOBILETENT: diff --git a/mods/ra/rules/civilian.yaml b/mods/ra/rules/civilian.yaml index 92b5a43b0e..22c3ae0d59 100644 --- a/mods/ra/rules/civilian.yaml +++ b/mods/ra/rules/civilian.yaml @@ -364,7 +364,7 @@ OILB: ExternalCapturableBar: EngineerRepairable: CashTrickler: - Period: 375 + Interval: 375 Amount: 100 Tooltip: Name: Oil Derrick From 8699d0fca3531c9d73cdf2aa369fd7649eba8916 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sat, 12 Nov 2016 19:07:17 +0100 Subject: [PATCH 3/3] 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); + } + } } }