From d427072cc9c0961d2712d85fc9a5d4a3dde27db5 Mon Sep 17 00:00:00 2001
From: Gustas <37534529+PunkPun@users.noreply.github.com>
Date: Wed, 22 Mar 2023 22:31:05 +0200
Subject: [PATCH] Extract StoresResources from Harvester
---
OpenRA.Game/Traits/TraitsInterfaces.cs | 26 +++++-
.../Activities/HarvestResource.cs | 2 +-
OpenRA.Mods.Common/Traits/Harvester.cs | 68 ++++++--------
.../Traits/Player/PlayerResources.cs | 4 +-
...s => WithStoresResourcesPipsDecoration.cs} | 18 ++--
.../Traits/StoresPlayerResources.cs | 67 ++++++++++++++
OpenRA.Mods.Common/Traits/StoresResources.cs | 90 +++++++++++++------
.../ExtractResourceStorageFromHarvester.cs | 49 ++++++++++
OpenRA.Mods.Common/UpdateRules/UpdatePath.cs | 1 +
mods/cnc/rules/defaults.yaml | 2 +-
mods/cnc/rules/structures.yaml | 4 +-
mods/cnc/rules/vehicles.yaml | 6 +-
mods/d2k/rules/structures.yaml | 4 +-
mods/d2k/rules/vehicles.yaml | 6 +-
mods/ra/rules/structures.yaml | 4 +-
mods/ra/rules/vehicles.yaml | 6 +-
mods/ts/rules/nod-structures.yaml | 2 +-
mods/ts/rules/nod-vehicles.yaml | 6 +-
mods/ts/rules/shared-structures.yaml | 4 +-
mods/ts/rules/shared-vehicles.yaml | 6 +-
20 files changed, 276 insertions(+), 99 deletions(-)
rename OpenRA.Mods.Common/Traits/Render/{WithHarvesterPipsDecoration.cs => WithStoresResourcesPipsDecoration.cs} (78%)
create mode 100644 OpenRA.Mods.Common/Traits/StoresPlayerResources.cs
create mode 100644 OpenRA.Mods.Common/UpdateRules/Rules/20230801/ExtractResourceStorageFromHarvester.cs
diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs
index b0923d3c635e..7bb928dea14d 100644
--- a/OpenRA.Game/Traits/TraitsInterfaces.cs
+++ b/OpenRA.Game/Traits/TraitsInterfaces.cs
@@ -173,7 +173,31 @@ public interface IVoiced
}
[RequireExplicitImplementation]
- public interface IStoreResources { int Capacity { get; } }
+ public interface IStoresResourcesInfo : ITraitInfoInterface
+ {
+ string[] ResourceTypes { get; }
+ }
+
+ public interface IStoresResources
+ {
+ bool HasType(string resourceType);
+
+ /// The amount of resources that can be stored.
+ int Capacity { get; }
+
+ /// Stored resources.
+ /// Dictionary key refers to resourceType, value refers to resource amount.
+ IReadOnlyDictionary Contents { get; }
+
+ /// A performance cheap method of getting the total sum of contents.
+ int ContentsSum { get; }
+
+ /// Returns the amount of that was not added.
+ int AddResource(string resourceType, int value);
+
+ /// Returns the amount of that was not removed.
+ int RemoveResource(string resourceType, int value);
+ }
public interface IEffectiveOwner
{
diff --git a/OpenRA.Mods.Common/Activities/HarvestResource.cs b/OpenRA.Mods.Common/Activities/HarvestResource.cs
index 92f1fb34afb4..85537bdb6158 100644
--- a/OpenRA.Mods.Common/Activities/HarvestResource.cs
+++ b/OpenRA.Mods.Common/Activities/HarvestResource.cs
@@ -87,7 +87,7 @@ public override bool Tick(Actor self)
if (resource.Type == null || resourceLayer.RemoveResource(resource.Type, self.Location) != 1)
return true;
- harv.AcceptResource(self, resource.Type);
+ harv.AddResource(self, resource.Type);
foreach (var t in notifyHarvestActions)
t.Harvested(self, resource.Type);
diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs
index 1df1c284b7d2..eac5a1e91d2a 100644
--- a/OpenRA.Mods.Common/Traits/Harvester.cs
+++ b/OpenRA.Mods.Common/Traits/Harvester.cs
@@ -11,7 +11,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Linq;
using OpenRA.Mods.Common.Activities;
using OpenRA.Primitives;
@@ -19,7 +18,7 @@
namespace OpenRA.Mods.Common.Traits
{
- public class HarvesterInfo : DockClientBaseInfo, Requires
+ public class HarvesterInfo : DockClientBaseInfo, Requires, Requires, IRulesetLoaded
{
[Desc("Docking type")]
public readonly BitSet Type = new("Unload");
@@ -27,9 +26,6 @@ public class HarvesterInfo : DockClientBaseInfo, Requires
[Desc("Cell to move to when automatically unblocking DeliveryBuilding.")]
public readonly CVec UnblockCell = new(0, 4);
- [Desc("How much resources it can carry.")]
- public readonly int Capacity = 28;
-
public readonly int BaleLoadDelay = 4;
[Desc("How fast it can dump its bales.")]
@@ -41,7 +37,7 @@ public class HarvesterInfo : DockClientBaseInfo, Requires
public readonly int HarvestFacings = 0;
[Desc("Which resources it can harvest.")]
- public readonly HashSet Resources = new();
+ public readonly string[] Resources = Array.Empty();
[Desc("Percentage of maximum speed when fully loaded.")]
public readonly int FullyLoadedSpeed = 85;
@@ -79,17 +75,25 @@ public class HarvesterInfo : DockClientBaseInfo, Requires
public readonly string HarvestCursor = "harvest";
public override object Create(ActorInitializer init) { return new Harvester(init.Self, this); }
+
+ void IRulesetLoaded.RulesetLoaded(Ruleset rules, ActorInfo info)
+ {
+ if (Resources.Length == 0)
+ throw new YamlException($"Harvester.{nameof(Resources)} is empty.");
+
+ var resourceTypes = Resources.Except(info.TraitInfos().SelectMany(sr => sr.ResourceTypes)).ToArray();
+ if (resourceTypes.Length != 0)
+ throw new YamlException($"Invalid Harvester.{nameof(Resources)} types: {string.Join(',', resourceTypes)}.");
+ }
}
public class Harvester : DockClientBase, IIssueOrder, IResolveOrder, IOrderVoice,
ISpeedModifier, ISync, INotifyCreated
{
- public readonly IReadOnlyDictionary Contents;
-
readonly Mobile mobile;
readonly IResourceLayer resourceLayer;
readonly ResourceClaimLayer claimLayer;
- readonly Dictionary contents = new();
+ readonly IStoresResources[] storesResources;
int conditionToken = Actor.InvalidConditionToken;
public override BitSet GetDockType => Info.Type;
@@ -97,23 +101,11 @@ public class Harvester : DockClientBase, IIssueOrder, IResolveOrd
[Sync]
int currentUnloadTicks;
- [Sync]
- public int ContentHash
- {
- get
- {
- var value = 0;
- foreach (var c in contents)
- value += c.Value << c.Key.Length;
- return value;
- }
- }
-
public Harvester(Actor self, HarvesterInfo info)
: base(self, info)
{
- Contents = new ReadOnlyDictionary(contents);
mobile = self.Trait();
+ storesResources = self.TraitsImplementing().Where(sr => info.Resources.Any(r => sr.HasType(r))).ToArray();
resourceLayer = self.World.WorldActor.Trait();
claimLayer = self.World.WorldActor.Trait();
}
@@ -129,9 +121,9 @@ protected override void Created(Actor self)
base.Created(self);
}
- public bool IsFull => contents.Values.Sum() == Info.Capacity;
- public bool IsEmpty => contents.Values.Sum() == 0;
- public int Fullness => contents.Values.Sum() * 100 / Info.Capacity;
+ public bool IsFull => storesResources.All(sr => sr.ContentsSum >= sr.Capacity);
+ public bool IsEmpty => storesResources.All(sr => sr.ContentsSum == 0);
+ public int Fullness => storesResources.Sum(sr => sr.ContentsSum * 100 / sr.Capacity) / storesResources.Length;
protected override bool CanDock()
{
@@ -151,12 +143,11 @@ void UpdateCondition(Actor self)
conditionToken = self.RevokeCondition(conditionToken);
}
- public void AcceptResource(Actor self, string resourceType)
+ public void AddResource(Actor self, string resourceType)
{
- if (!contents.ContainsKey(resourceType))
- contents[resourceType] = 1;
- else
- contents[resourceType]++;
+ foreach (var sr in storesResources)
+ if (sr.AddResource(resourceType, 1) == 0)
+ break;
UpdateCondition(self);
}
@@ -177,27 +168,23 @@ public override bool OnDockTick(Actor self, Actor hostActor, IDockHost host)
if (--currentUnloadTicks > 0)
return false;
- if (contents.Keys.Count > 0)
+ foreach (var sr in storesResources)
{
- foreach (var c in contents)
+ foreach (var c in sr.Contents)
{
- var resourceType = c.Key;
var count = Math.Min(c.Value, Info.BaleUnloadAmount);
- var accepted = acceptResources.AcceptResources(hostActor, resourceType, count);
+ var accepted = acceptResources.AcceptResources(hostActor, c.Key, count);
if (accepted == 0)
continue;
- contents[resourceType] -= accepted;
- if (contents[resourceType] <= 0)
- contents.Remove(resourceType);
-
+ sr.RemoveResource(c.Key, accepted);
currentUnloadTicks = Info.BaleUnloadDelay;
UpdateCondition(self);
return false;
}
}
- return contents.Count == 0;
+ return IsEmpty;
}
public override void OnDockCompleted(Actor self, Actor hostActor, IDockHost dock)
@@ -279,13 +266,12 @@ void IResolveOrder.ResolveOrder(Actor self, Order order)
int ISpeedModifier.GetSpeedModifier()
{
- return 100 - (100 - Info.FullyLoadedSpeed) * contents.Values.Sum() / Info.Capacity;
+ return 100 - (100 - Info.FullyLoadedSpeed) * Fullness / 100;
}
protected override void TraitDisabled(Actor self)
{
base.TraitDisabled(self);
- contents.Clear();
if (conditionToken != Actor.InvalidConditionToken)
conditionToken = self.RevokeCondition(conditionToken);
diff --git a/OpenRA.Mods.Common/Traits/Player/PlayerResources.cs b/OpenRA.Mods.Common/Traits/Player/PlayerResources.cs
index d6d29dcf5297..2e6bf78bb8c8 100644
--- a/OpenRA.Mods.Common/Traits/Player/PlayerResources.cs
+++ b/OpenRA.Mods.Common/Traits/Player/PlayerResources.cs
@@ -206,12 +206,12 @@ public bool TakeCash(int num, bool notifyLowFunds = false)
return true;
}
- public void AddStorage(int capacity)
+ public void AddStorageCapacity(int capacity)
{
ResourceCapacity += capacity;
}
- public void RemoveStorage(int capacity)
+ public void RemoveStorageCapacity(int capacity)
{
ResourceCapacity -= capacity;
diff --git a/OpenRA.Mods.Common/Traits/Render/WithHarvesterPipsDecoration.cs b/OpenRA.Mods.Common/Traits/Render/WithStoresResourcesPipsDecoration.cs
similarity index 78%
rename from OpenRA.Mods.Common/Traits/Render/WithHarvesterPipsDecoration.cs
rename to OpenRA.Mods.Common/Traits/Render/WithStoresResourcesPipsDecoration.cs
index 3534ecd6e6c1..167578f66209 100644
--- a/OpenRA.Mods.Common/Traits/Render/WithHarvesterPipsDecoration.cs
+++ b/OpenRA.Mods.Common/Traits/Render/WithStoresResourcesPipsDecoration.cs
@@ -10,12 +10,13 @@
#endregion
using System.Collections.Generic;
+using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render
{
- public class WithHarvesterPipsDecorationInfo : WithDecorationBaseInfo, Requires
+ public class WithStoresResourcesPipsDecorationInfo : WithDecorationBaseInfo, Requires
{
[FieldLoader.Require]
[Desc("Number of pips to display how filled unit is.")]
@@ -42,26 +43,27 @@ public class WithHarvesterPipsDecorationInfo : WithDecorationBaseInfo, Requires<
[PaletteReference]
public readonly string Palette = "chrome";
- public override object Create(ActorInitializer init) { return new WithHarvesterPipsDecoration(init.Self, this); }
+ public override object Create(ActorInitializer init) { return new WithStoresResourcesPipsDecoration(init.Self, this); }
}
- public class WithHarvesterPipsDecoration : WithDecorationBase
+ public class WithStoresResourcesPipsDecoration : WithDecorationBase
{
- readonly Harvester harvester;
+ readonly IStoresResources storesResources;
readonly Animation pips;
- public WithHarvesterPipsDecoration(Actor self, WithHarvesterPipsDecorationInfo info)
+ public WithStoresResourcesPipsDecoration(Actor self, WithStoresResourcesPipsDecorationInfo info)
: base(self, info)
{
- harvester = self.Trait();
+ // TODO: allow to choose which stores resources trait to target.
+ storesResources = self.TraitsImplementing().First();
pips = new Animation(self.World, info.Image);
}
string GetPipSequence(int i)
{
- var n = i * harvester.Info.Capacity / Info.PipCount;
+ var n = i * storesResources.Capacity / Info.PipCount;
- foreach (var rt in harvester.Contents)
+ foreach (var rt in storesResources.Contents)
{
if (n < rt.Value)
{
diff --git a/OpenRA.Mods.Common/Traits/StoresPlayerResources.cs b/OpenRA.Mods.Common/Traits/StoresPlayerResources.cs
new file mode 100644
index 000000000000..fa659c165bc0
--- /dev/null
+++ b/OpenRA.Mods.Common/Traits/StoresPlayerResources.cs
@@ -0,0 +1,67 @@
+#region Copyright & License Information
+/*
+ * Copyright (c) The OpenRA Developers and Contributors
+ * 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 OpenRA.Primitives;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.Common.Traits
+{
+ [Desc("Adds capacity to a player's harvested resource limit.")]
+ public class StoresPlayerResourcesInfo : TraitInfo
+ {
+ [FieldLoader.Require]
+ public readonly int Capacity = 0;
+
+ public override object Create(ActorInitializer init) { return new StoresPlayerResources(init.Self, this); }
+ }
+
+ public class StoresPlayerResources : INotifyOwnerChanged, INotifyCapture, INotifyKilled, INotifyAddedToWorld, INotifyRemovedFromWorld
+ {
+ readonly StoresPlayerResourcesInfo info;
+ PlayerResources player;
+
+ public int Stored => player.ResourceCapacity == 0 ? 0 : (int)((long)info.Capacity * player.Resources / player.ResourceCapacity);
+
+ public StoresPlayerResources(Actor self, StoresPlayerResourcesInfo info)
+ {
+ this.info = info;
+ player = self.Owner.PlayerActor.Trait();
+ }
+
+ void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
+ {
+ player = newOwner.PlayerActor.Trait();
+ }
+
+ void INotifyCapture.OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner, BitSet captureTypes)
+ {
+ var resources = Stored;
+ oldOwner.PlayerActor.Trait().TakeResources(resources);
+ newOwner.PlayerActor.Trait().GiveResources(resources);
+ }
+
+ void INotifyKilled.Killed(Actor self, AttackInfo e)
+ {
+ // Lose the stored resources.
+ player.TakeResources(Stored);
+ }
+
+ void INotifyAddedToWorld.AddedToWorld(Actor self)
+ {
+ player.AddStorageCapacity(info.Capacity);
+ }
+
+ void INotifyRemovedFromWorld.RemovedFromWorld(Actor self)
+ {
+ player.RemoveStorageCapacity(info.Capacity);
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/Traits/StoresResources.cs b/OpenRA.Mods.Common/Traits/StoresResources.cs
index 6faf1c7b93fc..9fbba002b2f3 100644
--- a/OpenRA.Mods.Common/Traits/StoresResources.cs
+++ b/OpenRA.Mods.Common/Traits/StoresResources.cs
@@ -9,62 +9,100 @@
*/
#endregion
-using OpenRA.Primitives;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
- [Desc("Adds capacity to a player's harvested resource limit.")]
- public class StoresResourcesInfo : TraitInfo
+ [Desc("Allows the storage of resources.")]
+ public class StoresResourcesInfo : TraitInfo, IStoresResourcesInfo
{
[FieldLoader.Require]
- public readonly int Capacity = 0;
+ [Desc("The amounts of resources that can be stored.")]
+ public readonly int Capacity = 28;
+
+ [Desc("Which resources can be stored.")]
+ public readonly string[] Resources = Array.Empty();
+
+ string[] IStoresResourcesInfo.ResourceTypes => Resources;
public override object Create(ActorInitializer init) { return new StoresResources(init.Self, this); }
}
- public class StoresResources : INotifyOwnerChanged, INotifyCapture, IStoreResources, ISync, INotifyKilled, INotifyAddedToWorld, INotifyRemovedFromWorld
+ public class StoresResources : IStoresResources, ISync
{
+ readonly Dictionary contents = new();
readonly StoresResourcesInfo info;
- PlayerResources player;
[Sync]
- public int Stored => player.ResourceCapacity == 0 ? 0 : (int)((long)info.Capacity * player.Resources / player.ResourceCapacity);
+ public int ContentHash
+ {
+ get
+ {
+ var value = 0;
+ foreach (var c in contents)
+ value += c.Value << c.Key.Length;
+
+ return value;
+ }
+ }
+
+ public int ContentsSum { get; private set; } = 0;
+ public IReadOnlyDictionary Contents { get; }
+ int IStoresResources.Capacity => info.Capacity;
public StoresResources(Actor self, StoresResourcesInfo info)
{
this.info = info;
- player = self.Owner.PlayerActor.Trait();
- }
- int IStoreResources.Capacity => info.Capacity;
+ foreach (var r in info.Resources)
+ contents[r] = 0;
- void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
- {
- player = newOwner.PlayerActor.Trait();
+ Contents = new ReadOnlyDictionary(contents);
}
- void INotifyCapture.OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner, BitSet captureTypes)
+ public bool HasType(string resourceType)
{
- var resources = Stored;
- oldOwner.PlayerActor.Trait().TakeResources(resources);
- newOwner.PlayerActor.Trait().GiveResources(resources);
+ return info.Resources.Contains(resourceType);
}
- void INotifyKilled.Killed(Actor self, AttackInfo e)
+ int IStoresResources.AddResource(string resourceType, int value)
{
- // Lose the stored resources
- player.TakeResources(Stored);
- }
+ if (!HasType(resourceType))
+ return value;
- void INotifyAddedToWorld.AddedToWorld(Actor self)
- {
- player.AddStorage(info.Capacity);
+ if (ContentsSum + value > info.Capacity)
+ {
+ var added = info.Capacity - ContentsSum;
+ contents[resourceType] += added;
+ ContentsSum = info.Capacity;
+ return value - added;
+ }
+
+ contents[resourceType] += value;
+ ContentsSum += value;
+ return 0;
}
- void INotifyRemovedFromWorld.RemovedFromWorld(Actor self)
+ int IStoresResources.RemoveResource(string resourceType, int value)
{
- player.RemoveStorage(info.Capacity);
+ if (!HasType(resourceType))
+ return value;
+
+ if (contents[resourceType] < value)
+ {
+ var leftover = value - contents[resourceType];
+ ContentsSum -= contents[resourceType];
+ contents[resourceType] = 0;
+ return leftover;
+ }
+
+ contents[resourceType] -= value;
+ ContentsSum -= value;
+ return 0;
}
}
}
diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/20230801/ExtractResourceStorageFromHarvester.cs b/OpenRA.Mods.Common/UpdateRules/Rules/20230801/ExtractResourceStorageFromHarvester.cs
new file mode 100644
index 000000000000..c7f66be92869
--- /dev/null
+++ b/OpenRA.Mods.Common/UpdateRules/Rules/20230801/ExtractResourceStorageFromHarvester.cs
@@ -0,0 +1,49 @@
+#region Copyright & License Information
+/*
+ * Copyright (c) The OpenRA Developers and Contributors
+ * 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.Collections.Generic;
+
+namespace OpenRA.Mods.Common.UpdateRules.Rules
+{
+ public class ExtractResourceStorageFromHarvester : UpdateRule
+ {
+ public override string Name => "Renames StoresResources to StoresPlayerResources and extracts StoresResources from Harvester.";
+
+ public override string Description =>
+ "Resource storage was extracted from Harvester. WithHarvesterPipsDecoration was also renamed to WithStoresResourcesPipsDecoration.";
+
+ public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
+ {
+ actorNode.RenameChildrenMatching("StoresResources", "StoresPlayerResources");
+ actorNode.RenameChildrenMatching("WithHarvesterPipsDecoration", "WithStoresResourcesPipsDecoration");
+
+ var harvester = actorNode.LastChildMatching("Harvester", false);
+ if (harvester == null)
+ yield break;
+
+ var storesResources = new MiniYamlNodeBuilder("StoresResources", "");
+ var capacity = harvester.LastChildMatching("Capacity", false);
+ if (capacity != null)
+ {
+ storesResources.AddNode(capacity);
+ harvester.RemoveNode(capacity);
+ }
+
+ var resources = harvester.LastChildMatching("Resources", false);
+ if (resources != null)
+ storesResources.AddNode(resources);
+
+ actorNode.AddNode(storesResources);
+
+ yield break;
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
index 17c7c01a2418..7c8970e450b5 100644
--- a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
+++ b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
@@ -109,6 +109,7 @@ public class UpdatePath
{
// bleed only changes here.
new RemoveValidRelationsFromCapturable(),
+ new ExtractResourceStorageFromHarvester(),
// Execute these rules last to avoid premature yaml merge crashes.
new AbstractDocking(),
diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml
index 68cfd06c6794..b1b82337d009 100644
--- a/mods/cnc/rules/defaults.yaml
+++ b/mods/cnc/rules/defaults.yaml
@@ -219,7 +219,7 @@
red: pip-red
^StoresResources:
- StoresResources:
+ StoresPlayerResources:
WithResourceStoragePipsDecoration:
Position: BottomLeft
Margin: 4, 3
diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml
index 7450e14395a2..1b7dd4aaa81c 100644
--- a/mods/cnc/rules/structures.yaml
+++ b/mods/cnc/rules/structures.yaml
@@ -247,7 +247,7 @@ PROC:
IsDragRequired: True
DragOffset: -554,512,0
DragLength: 12
- StoresResources:
+ StoresPlayerResources:
Capacity: 1000
Selectable:
Bounds: 3072, 2389
@@ -291,7 +291,7 @@ SILO:
-WithSpriteBody:
WithResourceLevelSpriteBody:
Sequence: stages
- StoresResources:
+ StoresPlayerResources:
Capacity: 3000
-SpawnActorsOnSell:
Power:
diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml
index 2c66ad347888..922cb31fc163 100644
--- a/mods/cnc/rules/vehicles.yaml
+++ b/mods/cnc/rules/vehicles.yaml
@@ -56,13 +56,15 @@ HARV:
DecorationBounds: 1536, 1536
Harvester:
Resources: Tiberium, BlueTiberium
- Capacity: 20
BaleLoadDelay: 12
BaleUnloadDelay: 6
SearchFromProcRadius: 15
SearchFromHarvesterRadius: 8
HarvestFacings: 8
EmptyCondition: no-tiberium
+ StoresResources:
+ Capacity: 20
+ Resources: Tiberium, BlueTiberium
DockClientManager:
Mobile:
Speed: 72
@@ -89,7 +91,7 @@ HARV:
Explodes:
RequiresCondition: !no-tiberium
Weapon: TiberiumExplosion
- WithHarvesterPipsDecoration:
+ WithStoresResourcesPipsDecoration:
Position: BottomLeft
Margin: 4, 3
RequiresSelection: true
diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml
index 249d438dcd68..caa61cca50e8 100644
--- a/mods/d2k/rules/structures.yaml
+++ b/mods/d2k/rules/structures.yaml
@@ -287,7 +287,7 @@ refinery:
Type: Unload
DockAngle: 640
DockOffset: 1c0,512,0
- StoresResources:
+ StoresPlayerResources:
Capacity: 2000
CustomSellValue:
Value: 500
@@ -357,7 +357,7 @@ silo:
-WithSpriteBody:
WithResourceLevelSpriteBody:
Sequence: stages
- StoresResources:
+ StoresPlayerResources:
Capacity: 2000
-SpawnActorsOnSell:
Power:
diff --git a/mods/d2k/rules/vehicles.yaml b/mods/d2k/rules/vehicles.yaml
index b22efa8b7acc..46043ac19f5d 100644
--- a/mods/d2k/rules/vehicles.yaml
+++ b/mods/d2k/rules/vehicles.yaml
@@ -70,12 +70,14 @@ harvester:
Class: harvester
DecorationBounds: 1344, 1344
Harvester:
- Capacity: 28
HarvestFacings: 8
Resources: Spice
BaleUnloadDelay: 5
SearchFromProcRadius: 30
SearchFromHarvesterRadius: 15
+ StoresResources:
+ Capacity: 28
+ Resources: Spice
DockClientManager:
CarryableHarvester:
Health:
@@ -107,7 +109,7 @@ harvester:
Delay: 3
StartIfBelow: 50
-RevealOnFire:
- WithHarvesterPipsDecoration:
+ WithStoresResourcesPipsDecoration:
Position: BottomLeft
Margin: 1, 4
RequiresSelection: true
diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml
index 0c4c9d5a72d8..210a81d4b3f8 100644
--- a/mods/ra/rules/structures.yaml
+++ b/mods/ra/rules/structures.yaml
@@ -1290,7 +1290,7 @@ PROC:
Type: Unload
DockAngle: 256
DockOffset: 0, 1c0, 0
- StoresResources:
+ StoresPlayerResources:
Capacity: 2000
CustomSellValue:
Value: 300
@@ -1375,7 +1375,7 @@ SILO:
-WithSpriteBody:
WithResourceLevelSpriteBody:
Sequence: stages
- StoresResources:
+ StoresPlayerResources:
Capacity: 3000
-SpawnActorsOnSell:
Power:
diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml
index ff2cf7ef78fb..4a0850cbbd9f 100644
--- a/mods/ra/rules/vehicles.yaml
+++ b/mods/ra/rules/vehicles.yaml
@@ -320,13 +320,15 @@ HARV:
Selectable:
DecorationBounds: 1792, 1792
Harvester:
- Capacity: 20
Resources: Ore,Gems
BaleUnloadDelay: 1
SearchFromProcRadius: 15
SearchFromHarvesterRadius: 8
HarvestFacings: 8
EmptyCondition: no-ore
+ StoresResources:
+ Capacity: 20
+ Resources: Ore,Gems
DockClientManager:
Health:
HP: 60000
@@ -357,7 +359,7 @@ HARV:
WithHarvesterSpriteBody:
ImageByFullness: harvempty, harvhalf, harv
-WithFacingSpriteBody:
- WithHarvesterPipsDecoration:
+ WithStoresResourcesPipsDecoration:
Position: BottomLeft
Margin: 4, 3
RequiresSelection: true
diff --git a/mods/ts/rules/nod-structures.yaml b/mods/ts/rules/nod-structures.yaml
index 6b89e3e0a97f..ad90d5d95d30 100644
--- a/mods/ts/rules/nod-structures.yaml
+++ b/mods/ts/rules/nod-structures.yaml
@@ -593,7 +593,7 @@ NAWAST:
Type: UnloadWeed
DockAngle: 640
DockOffset: 724,724,0
- StoresResources:
+ StoresPlayerResources:
Capacity: 56
Power:
Amount: -40
diff --git a/mods/ts/rules/nod-vehicles.yaml b/mods/ts/rules/nod-vehicles.yaml
index 336d3a45a0d2..23a72ff9d90d 100644
--- a/mods/ts/rules/nod-vehicles.yaml
+++ b/mods/ts/rules/nod-vehicles.yaml
@@ -352,13 +352,15 @@ WEED:
Description: Collects veins for processing.\n Unarmed
Harvester:
Type: UnloadWeed
- Capacity: 7
Resources: Veins
BaleUnloadDelay: 20
BaleLoadDelay: 40
SearchFromProcRadius: 72
SearchFromHarvesterRadius: 36
HarvestVoice: Attack
+ StoresResources:
+ Capacity: 7
+ Resources: Veins
DockClientManager:
Voice: Move
Mobile:
@@ -381,7 +383,7 @@ WEED:
WithVoxelUnloadBody:
-DamagedByTerrain@VEINS:
-LeavesTrails@VEINS:
- WithHarvesterPipsDecoration:
+ WithStoresResourcesPipsDecoration:
Position: BottomLeft
RequiresSelection: true
Margin: 5, 2
diff --git a/mods/ts/rules/shared-structures.yaml b/mods/ts/rules/shared-structures.yaml
index 1b58dae996cc..75de2476e276 100644
--- a/mods/ts/rules/shared-structures.yaml
+++ b/mods/ts/rules/shared-structures.yaml
@@ -125,7 +125,7 @@ PROC:
Type: Unload
DockAngle: 640
DockOffset: 362,362,0
- StoresResources:
+ StoresPlayerResources:
Capacity: 2000
CustomSellValue:
Value: 600
@@ -211,7 +211,7 @@ GASILO:
RequiresCondition: !build-incomplete
Sequence: idle-lights-bright
Palette: bright
- StoresResources:
+ StoresPlayerResources:
Capacity: 1500
Power:
Amount: -10
diff --git a/mods/ts/rules/shared-vehicles.yaml b/mods/ts/rules/shared-vehicles.yaml
index bc588bf76a6c..163e17a06816 100644
--- a/mods/ts/rules/shared-vehicles.yaml
+++ b/mods/ts/rules/shared-vehicles.yaml
@@ -59,7 +59,6 @@ HARV:
Bounds: 1086, 2172
DecorationBounds: 1086, 2172
Harvester:
- Capacity: 28
Resources: Tiberium, BlueTiberium
BaleLoadDelay: 15
BaleUnloadDelay: 15
@@ -68,6 +67,9 @@ HARV:
SearchFromHarvesterRadius: 18
HarvestVoice: Attack
EmptyCondition: no-tiberium
+ StoresResources:
+ Capacity: 28
+ Resources: Tiberium, BlueTiberium
DockClientManager:
Voice: Move
Mobile:
@@ -100,7 +102,7 @@ HARV:
nod: harv.nod
-DamagedByTerrain@VEINS:
-LeavesTrails@VEINS:
- WithHarvesterPipsDecoration:
+ WithStoresResourcesPipsDecoration:
Position: BottomLeft
RequiresSelection: true
Margin: 5, 2