• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

First Machine Age's Mods (Combined repo.)


Commit MetaInfo

修订版1f65f75ca5890e969fed72656ff44ab551e83486 (tree)
时间2022-07-25 09:41:19
作者melchior <melchior@user...>
Commitermelchior

Log Message

W.I.P. extra Effects II: Almost...

更改概述

差异

--- a/AnvilMetalRecovery/AnvilMetalRecovery.csproj
+++ b/AnvilMetalRecovery/AnvilMetalRecovery.csproj
@@ -86,7 +86,7 @@
8686 <Compile Include="Harmony\GenericItemMortalityDetector.cs" />
8787 <Compile Include="Data\AMR_Config.cs" />
8888 <Compile Include="Data\RecoveryEntryTable.cs" />
89- <Compile Include="CollectableBehaviors\DirectSprayCooler_Behavior.cs" />
89+ <Compile Include="Blocks\BlockWateringCanPlus.cs" />
9090 </ItemGroup>
9191 <ItemGroup>
9292 <None Include="modinfo.json">
@@ -127,7 +127,6 @@
127127 <CopyToOutputDirectory>Always</CopyToOutputDirectory>
128128 </None>
129129 <None Include="assets\fma\patches\wateringcan_behavior.json">
130- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
131130 </None>
132131 </ItemGroup>
133132 <ItemGroup>
@@ -151,6 +150,9 @@
151150 <Folder Include="Items\" />
152151 <Folder Include="Harmony\" />
153152 <Folder Include="CollectableBehaviors\" />
153+ <Folder Include="Blocks\" />
154+ <Folder Include="assets\fma\sounds\" />
155+ <Folder Include="assets\fma\sounds\sfx\" />
154156 </ItemGroup>
155157 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
156158 </Project>
\ No newline at end of file
--- /dev/null
+++ b/AnvilMetalRecovery/Blocks/BlockWateringCanPlus.cs
@@ -0,0 +1,124 @@
1+using System;
2+using System.Text;
3+
4+using Vintagestory.API.Client;
5+using Vintagestory.API.Common;
6+using Vintagestory.API.Common.Entities;
7+using Vintagestory.API.Config;
8+using Vintagestory.API.MathTools;
9+using Vintagestory.API.Server;
10+using Vintagestory.GameContent;
11+
12+namespace AnvilMetalRecovery
13+{
14+ public class BlockWateringCanPlus : BlockWateringCan
15+ {
16+ private const float coolRateDefault = 5.0f;
17+
18+ protected ICoreAPI CoreAPI { get { return this.api; } }
19+ protected ICoreServerAPI ServerAPI { get { return this.api as ICoreServerAPI; } }
20+ protected ICoreClientAPI ClientAPI { get { return this.api as ICoreClientAPI; } }
21+
22+ public readonly AssetLocation CoolSoundEffect = new AssetLocation(@"game", @"sounds/sizzle");
23+ public static readonly string BlockClassName = @"BlockWateringCan";
24+ public static readonly AssetLocation TargetCode = new AssetLocation(@"game", @"wateringcan-burned");
25+
26+ /// <summary>
27+ /// DO OnHeldInteractStep
28+ /// </summary>
29+ /// <returns>The held interact step.</returns>
30+ /// <param name="secondsUsed">Seconds used.</param>
31+ /// <param name="slot">Slot.</param>
32+ /// <param name="byEntity">By entity.</param>
33+ /// <param name="blockSel">Block sel.</param>
34+ /// <param name="entitySel">Entity sel.</param>
35+ /// <remarks>
36+ /// Had to do it this way the base class _NEVER_ invokes the block-behavior virtual...
37+ /// </remarks>
38+ public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
39+ {
40+ this.api.Logger.VerboseDebug("BlockWateringCanPlus::OnHeldInteractStep");
41+ var result = base.OnHeldInteractStep(secondsUsed, slot, byEntity, blockSel, entitySel);
42+
43+ PerformBlockCooling(secondsUsed, slot, byEntity, blockSel, entitySel);
44+
45+ return result;
46+ }
47+
48+ private void PerformBlockCooling(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
49+ {
50+ if (blockSel == null) return;
51+ if (byEntity.Controls.Sneak) return;
52+
53+ BlockPos targetPos = blockSel.Position;
54+
55+ if (this.GetRemainingWateringSeconds(slot.Itemstack) >= 0.1f)
56+ {
57+ var server = (CoreAPI.World.Side.IsServer());
58+
59+ var someBlock = CoreAPI.World.BlockAccessor.GetBlock(targetPos);
60+
61+ if (someBlock != null
62+ && someBlock.BlockMaterial == EnumBlockMaterial.Ceramic
63+ && (someBlock.Class == @"BlockIngotMold" || someBlock.Class == @"BlockToolMold"))
64+ {
65+ var someBlockEntity = CoreAPI.World.BlockAccessor.GetBlockEntity(targetPos);
66+
67+ if (someBlockEntity is BlockEntityIngotMold) {
68+ var ingotMold = someBlockEntity as BlockEntityIngotMold;
69+ if (ingotMold.fillSide && ingotMold.fillLevelRight > 0 && ingotMold.IsLiquidRight) {
70+ if (server) CoolContents(ingotMold.contentsRight); else GenerateSpecialEffects(blockSel.HitPosition);
71+ }
72+ else if (ingotMold.fillLevelLeft > 0 && ingotMold.IsLiquidLeft) {
73+ if (server) CoolContents(ingotMold.contentsLeft); else GenerateSpecialEffects(blockSel.HitPosition);
74+ }
75+ return;
76+ }
77+
78+ if (someBlockEntity is BlockEntityToolMold) {
79+ var toolMold = someBlockEntity as BlockEntityToolMold;
80+ if (toolMold.fillLevel > 0 && toolMold.IsLiquid) {
81+ if (server) CoolContents(toolMold.metalContent); else GenerateSpecialEffects(blockSel.HitPosition);
82+ }
83+ return;
84+ }
85+ }
86+ }
87+ }
88+
89+ internal void GenerateSpecialEffects(Vec3d here)
90+ {
91+ var steamParticles = new SimpleParticleProperties {
92+ MinPos = here,
93+ AddPos = here.AddCopy(0.1,0.1,0.1),
94+ MinQuantity = 8,
95+ AddQuantity = 24,
96+ Color = ColorUtil.ToRgba(100, 225, 225, 225),
97+ GravityEffect = -0.015f,
98+ WithTerrainCollision = true,
99+ ParticleModel = EnumParticleModel.Quad,
100+ LifeLength = 2.0f,
101+ MinVelocity = new Vec3f(-0.25f, 0.1f, -0.25f),
102+ AddVelocity = new Vec3f(0.25f, 0.1f, 0.25f),
103+ MinSize = 0.075f,
104+ MaxSize = 0.1f,
105+ //VertexFlags = 32
106+ };
107+ ClientAPI.World.SpawnParticles(steamParticles );
108+ ClientAPI.World.PlaySoundAt(CoolSoundEffect, here.X,here.Y,here.Z, null, false, 16 );
109+ }
110+
111+ internal void CoolContents(ItemStack itemStack)
112+ {
113+ var temperature = itemStack.Collectible.GetTemperature(CoreAPI.World, itemStack);
114+ if (temperature > 25f)//TODO: USE local AMBIENT Temp
115+ itemStack.Collectible.SetTemperature(CoreAPI.World, itemStack, (temperature - coolRateDefault), false);
116+ #if DEBUG
117+ CoreAPI.Logger.VerboseDebug("Reduced Molten metal temp: {0:F1} ", temperature);
118+ #endif
119+ }
120+
121+
122+ }
123+}
124+
--- a/AnvilMetalRecovery/CollectableBehaviors/DirectSprayCooler_Behavior.cs
+++ b/AnvilMetalRecovery/CollectableBehaviors/DirectSprayCooler_Behavior.cs
@@ -1,8 +1,10 @@
11 using System;
22
33 using Vintagestory.API.Common;
4+using Vintagestory.API.Config;
45 using Vintagestory.API.Datastructures;
56 using Vintagestory.API.MathTools;
7+using Vintagestory.API.Server;
68 using Vintagestory.GameContent;
79 using Vintagestory.Server;
810
@@ -13,77 +15,90 @@ namespace AnvilMetalRecovery
1315 /// Direct spray cooler collectable behavior.
1416 /// </summary>
1517 /// <remarks>*TSSSSS!*</remarks>
16- public class DirectSprayCooler_Behavior : BlockBehavior
18+ public class DirectSprayCooler_Behavior : CollectibleBehavior
1719 {
18- public const string ClassName = @"directspraycooler";
1920 private const string coolRateKey = @"coolRate";
2021 private const float coolRateDefault = 0.5f;
2122 private BlockWateringCan WateringCan;
22- protected ICoreAPI CoreAPI { get; set; }
23+ protected ICoreAPI CoreAPI { get; private set;}
24+ protected ICoreServerAPI ServerAPI { get; private set;}
25+
26+ public const string ClassName = @"directspraycooler";
2327 public float CoolRate { get; private set;}
2428
25- public DirectSprayCooler_Behavior(Block block) : base(block)
26- {
27-
29+ public DirectSprayCooler_Behavior(CollectibleObject collecta) : base(collecta)
30+ {
31+ }
32+
33+ public override void Initialize(JsonObject properties)
34+ {
35+ base.Initialize(properties);
36+
37+ CoolRate = properties[coolRateKey].AsFloat(coolRateDefault);
2838 }
2939
3040 public override void OnLoaded(ICoreAPI api)
3141 {
42+ base.OnLoaded(api);
43+ CoreAPI = api;
44+
3245 #if DEBUG
3346 api.Logger.VerboseDebug("DirectSprayCooler_Behavior::OnLoaded...");
3447 #endif
35- base.OnLoaded(api);
36- CoreAPI = api;
48+
49+ WateringCan = this.collObj as BlockWateringCan;
50+ if (WateringCan == null) { throw new InvalidOperationException(string.Format("Block with code '{0}' does not inherit from BlockWateringCan, which is required", collObj.Code)); }
3751
38- WateringCan = block as BlockWateringCan;
39- if (WateringCan == null) { throw new InvalidOperationException(string.Format("Block with code '{0}' does not inherit from BlockWateringCan, which is required", block.Code)); }
52+ }
4053
54+ public override void GetHeldItemInfo(ItemSlot inSlot, System.Text.StringBuilder dsc, IWorldAccessor world, bool withDebugInfo)
55+ {
56+ dsc.Append(Lang.Get("fma:spray_cooler_text"));
4157 }
4258
4359
44- public override void Initialize(JsonObject properties)
60+
61+ public override void OnHeldInteractStart(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handHandling, ref EnumHandling handling)
4562 {
4663 #if DEBUG
47- CoreAPI.Logger.VerboseDebug("DirectSprayCooler_Behavior::Initialize...");
64+ byEntity.World.Logger.VerboseDebug("DirectSprayCooler_Behavior::OnHeldInteractStart...");
4865 #endif
4966
50- CoolRate = properties[coolRateKey].AsFloat(coolRateDefault);
51-
52- base.Initialize(properties);
67+ handHandling = EnumHandHandling.PreventDefault;
68+ handling = EnumHandling.PassThrough; //EnumHandling.PreventDefault;
5369 }
5470
55-
56- internal void coolContents(ItemStack itemStack)
71+ public override void OnHeldInteractStop(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, ref EnumHandling handling)
5772 {
58- var temperature = itemStack.Collectible.GetTemperature(CoreAPI.World, itemStack);
59- if (temperature > 25f)//TODO: USE local AMBIENT Temp
60- itemStack.Collectible.SetTemperature(CoreAPI.World, itemStack, (temperature - CoolRate), false);
6173 #if DEBUG
62- CoreAPI.Logger.VerboseDebug("Reduced Molten metal temp: {0:F1} ", temperature);
74+ byEntity.World.Logger.VerboseDebug("DirectSprayCooler_Behavior::OnHeldInteractStop...");
6375 #endif
76+ handling = EnumHandling.PassThrough;
77+
6478 }
6579
66-
6780 public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, ref EnumHandling handling)
6881 {
6982 #if DEBUG
70- CoreAPI.Logger.VerboseDebug("DirectSprayCooler_Behavior::OnHeldInteractStep...");
83+ byEntity.World.Logger.VerboseDebug("DirectSprayCooler_Behavior::OnHeldInteractStep...");
7184 #endif
72-
73- handling = EnumHandling.PassThrough;
85+ CoreAPI = byEntity.World.Api;
86+
7487 if (blockSel == null) return false;
88+ if (byEntity.Controls.Sneak) return false;
7589
7690 if (CoreAPI.World.Side.IsServer( ))
77- {
91+ {
92+ ServerAPI = byEntity.World.Api as ICoreServerAPI;;
7893 if (WateringCan.GetRemainingWateringSeconds(slot.Itemstack) >= 0.5f) {
7994 BlockPos targetPos = blockSel.Position;
80- var someBlock = CoreAPI.World.BlockAccessor.GetBlock(targetPos);
95+ var someBlock = ServerAPI.World.BlockAccessor.GetBlock(targetPos);
8196
8297 if (someBlock != null
8398 && someBlock.BlockMaterial == EnumBlockMaterial.Ceramic
8499 && (someBlock.Class == @"BlockIngotMold" || someBlock.Class == @"BlockToolMold"))
85100 {
86- BlockEntityIngotMold ingotBE = CoreAPI.World.BlockAccessor.GetBlockEntity(targetPos) as BlockEntityIngotMold;
101+ BlockEntityIngotMold ingotBE = ServerAPI.World.BlockAccessor.GetBlockEntity(targetPos) as BlockEntityIngotMold;
87102
88103 if (ingotBE != null)
89104 {
@@ -91,11 +106,11 @@ namespace AnvilMetalRecovery
91106 { coolContents(ingotBE.contentsRight); }
92107 else if (ingotBE.IsLiquidLeft)
93108 { coolContents(ingotBE.contentsLeft); }
94-
95- return false;
109+ handling = EnumHandling.PreventDefault;//?
110+ return true;
96111 }
97112
98- BlockEntityToolMold toolBE = CoreAPI.World.BlockAccessor.GetBlockEntity(targetPos) as BlockEntityToolMold;
113+ BlockEntityToolMold toolBE = ServerAPI.World.BlockAccessor.GetBlockEntity(targetPos) as BlockEntityToolMold;
99114 if (toolBE != null)
100115 {
101116 if (toolBE.IsLiquid) { coolContents(toolBE.metalContent); }
@@ -104,13 +119,24 @@ namespace AnvilMetalRecovery
104119 }
105120 }
106121 }
107-
108122 }
109-
123+
124+ handling = EnumHandling.PassThrough;
110125 return false;
111126 }
112127
113128
129+ internal void coolContents(ItemStack itemStack)
130+ {
131+
132+ var temperature = itemStack.Collectible.GetTemperature(CoreAPI.World, itemStack);
133+ if (temperature > 25f)//TODO: USE local AMBIENT Temp
134+ itemStack.Collectible.SetTemperature(CoreAPI.World, itemStack, (temperature - CoolRate), false);
135+ #if DEBUG
136+ CoreAPI.Logger.VerboseDebug("Reduced Molten metal temp: {0:F1} ", temperature);
137+ #endif
138+ }
139+
114140
115141 }
116142 }
--- a/AnvilMetalRecovery/Helpers.cs
+++ b/AnvilMetalRecovery/Helpers.cs
@@ -4,6 +4,7 @@ using System.Linq;
44 using Vintagestory.API.Common;
55 using Vintagestory.API.Common.Entities;
66 using Vintagestory.API.Server;
7+using Vintagestory.API.Util;
78 using Vintagestory.Common;
89 using Vintagestory.Server;
910
@@ -11,6 +12,39 @@ namespace AnvilMetalRecovery
1112 {
1213 internal static class Helpers
1314 {
15+ internal static void AddBlockBehavior(this ICoreAPI coreAPI, AssetLocation assetName, string behaviorCode, Type blockBehaviorType)
16+ {
17+ if (assetName.Valid && assetName.IsWildCard == false)
18+ {
19+ var targetBlock = coreAPI.World.GetBlock(assetName);
20+ var newBlockBehavior = coreAPI.ClassRegistry.CreateBlockBehavior(targetBlock, behaviorCode);
21+
22+ if (targetBlock != null && newBlockBehavior != null)
23+ {
24+ targetBlock.BlockBehaviors = targetBlock.BlockBehaviors.Append(newBlockBehavior);
25+ targetBlock.CollectibleBehaviors = targetBlock.CollectibleBehaviors.Append(newBlockBehavior);
26+ }
27+ else {
28+ coreAPI.Logger.Warning($"Could not append new BLOCK BEHAVIOR ({blockBehaviorType.Name}): '{behaviorCode}' to block [{assetName}]!");
29+ }
30+ }
31+ }
32+
33+ internal static void AddCollectableBehavior(this ICoreAPI coreAPI, AssetLocation assetName, string behaviorCode, Type blockBehaviorType)
34+ {
35+ if (assetName.Valid && assetName.IsWildCard == false) {
36+ var targetBlock = coreAPI.World.GetBlock(assetName);
37+ var newCollectableBehavior = coreAPI.ClassRegistry.CreateCollectibleBehavior(targetBlock, behaviorCode);
38+
39+ if (targetBlock != null && newCollectableBehavior != null) {
40+ targetBlock.CollectibleBehaviors = targetBlock.CollectibleBehaviors.Append(newCollectableBehavior);
41+ }
42+ else {
43+ coreAPI.Logger.Warning($"Could not append new COLLECTABLE BEHAVIOR ({blockBehaviorType.Name}): '{behaviorCode}' to something [{assetName}]!");
44+ }
45+ }
46+ }
47+
1448 internal static void ReplaceBlockEntityType(this ClassRegistry registry, string className, Type blockentity)
1549 {
1650 if (registry.blockEntityClassnameToTypeMapping.ContainsKey(className)) {
@@ -28,6 +62,14 @@ namespace AnvilMetalRecovery
2862 }
2963 }
3064
65+ internal static void ReplaceBlockClassType(this ClassRegistry registry, string className, Type replacer)
66+ {
67+ if (registry.BlockClassToTypeMapping.ContainsKey(className)) {
68+ //replace it
69+ registry.BlockClassToTypeMapping[className] = replacer;
70+ }
71+ }
72+
3173 internal static int? Hitpoints(this ItemStack itemStack)
3274 {
3375 if (itemStack == null || itemStack.Attributes == null) return null;
--- a/AnvilMetalRecovery/MetalRecoverySystem.cs
+++ b/AnvilMetalRecovery/MetalRecoverySystem.cs
@@ -30,8 +30,6 @@ namespace AnvilMetalRecovery
3030 public const float IngotVoxelDefault = 2.38f;
3131 public const string ItemDamageChannelName = @"ItemDamageEvents";
3232
33-
34-
3533 internal IServerNetworkChannel _ConfigDownlink;
3634 internal IClientNetworkChannel _ConfigUplink;
3735
@@ -110,7 +108,8 @@ namespace AnvilMetalRecovery
110108 this.CoreAPI = api;
111109
112110 RegisterItemMappings( );
113- RegisterBlockBehaviors( );
111+ //RegisterBlockBehaviors( );
112+
114113
115114 #if DEBUG
116115 //Harmony.DEBUG = true;
@@ -137,10 +136,11 @@ namespace AnvilMetalRecovery
137136 PrepareDownlinkChannel( );
138137 ServerAPI.Event.PlayerJoin += SendClientConfigMessage;
139138 ServerAPI.Event.ServerRunPhase(EnumServerRunPhase.Shutdown, PersistServersideConfig);
140- ServerAPI.Event.ServerRunPhase(EnumServerRunPhase.GameReady, MaterialDataGathering);
141- ServerAPI.Event.ServerRunPhase(EnumServerRunPhase.RunGame, CacheRecoveryDataTable);
139+ ServerAPI.Event.ServerRunPhase(EnumServerRunPhase.GameReady, MaterialDataGathering);
140+ PerformBlockClassSwaps();
141+ ServerAPI.Event.ServerRunPhase(EnumServerRunPhase.RunGame, CacheRecoveryDataTable);
142142
143- SetupGeneralObservers( );
143+ SetupGeneralObservers( );
144144
145145 Mod.Logger.VerboseDebug("Anvil Metal Recovery - should be installed...");
146146
@@ -163,6 +163,9 @@ namespace AnvilMetalRecovery
163163 }
164164
165165 ListenForServerConfigMessage( );
166+ //ClientCore.Event.RegisterCallback(PerformBlockClassSwaps, 0);
167+ PerformBlockClassSwaps();
168+
166169 Mod.Logger.VerboseDebug("Anvil Metal Recovery - should be installed...");
167170 }
168171
@@ -178,7 +181,21 @@ namespace AnvilMetalRecovery
178181 #if DEBUG
179182 Mod.Logger.Debug("RegisterBlockBehaviors");
180183 #endif
181- this.CoreAPI.RegisterBlockBehaviorClass(DirectSprayCooler_Behavior.ClassName, typeof(DirectSprayCooler_Behavior));
184+ //this.CoreAPI.RegisterBlockBehaviorClass(DirectSprayCooler_Behavior.ClassName, typeof(DirectSprayCooler_Behavior));
185+ //this.CoreAPI.RegisterCollectibleBehaviorClass(DirectSprayCooler_Behavior.ClassName, typeof(DirectSprayCooler_Behavior));
186+ }
187+
188+ private void PerformBlockClassSwaps(float delta = 0.0f)
189+ {
190+ PerformBlockClassSwaps( );
191+ }
192+
193+ private void PerformBlockClassSwaps()
194+ {
195+ if (CoreAPI.Side == EnumAppSide.Server)
196+ this.ServerCore.ClassRegistryNative.ReplaceBlockClassType(BlockWateringCanPlus.BlockClassName, typeof(BlockWateringCanPlus));
197+ else
198+ this.ClientCore.ClassRegistryNative.ReplaceBlockClassType(BlockWateringCanPlus.BlockClassName, typeof(BlockWateringCanPlus));
182199 }
183200
184201 private void SetupGeneralObservers( ){
@@ -247,7 +264,7 @@ namespace AnvilMetalRecovery
247264 #endif
248265
249266 if (networkMessage != null) {
250- Mod.Logger.Debug("Message value; Recover Broken Tools:{0}, VoxelEquiv#{1:F2}, Blacklist #{2}", networkMessage.ToolFragmentRecovery, networkMessage.VoxelEquivalentValue, networkMessage.BlackList.Count);
267+ Mod.Logger.Debug("Message value; Recover Broken Tools:{0}, VoxelEquiv:{1:F2}, Tool Recovery {3:P0}, Blacklisted:{2}", networkMessage.ToolFragmentRecovery, networkMessage.VoxelEquivalentValue, networkMessage.BlackList.Count, networkMessage.ToolRecoveryRate);
251268 this.CachedConfiguration = networkMessage;
252269 }
253270 }
--- a/AnvilMetalRecovery/MetalRecoverySystem_Components.cs
+++ b/AnvilMetalRecovery/MetalRecoverySystem_Components.cs
@@ -127,7 +127,7 @@ namespace AnvilMetalRecovery
127127
128128 RecoveryEntry rec = itemToVoxelLookup[hotbarData.ItemCode];
129129 #if DEBUG
130- Mod.Logger.VerboseDebug("broken-item {0} WORTH: {1:F1}*{2} units", hotbarData.ItemCode.ToString( ), (rec.Quantity * CachedConfiguration.VoxelEquivalentValue), rec.IngotCode.ToShortString( ));
130+ Mod.Logger.VerboseDebug("broken-item {0} abs. WORTH: {1:F1}*{2} units", hotbarData.ItemCode.ToString( ), (rec.Quantity * CachedConfiguration.VoxelEquivalentValue), rec.IngotCode.ToShortString( ));
131131 #endif
132132
133133 if (String.IsNullOrEmpty(hotbarData.PlayerUID) || String.IsNullOrEmpty(hotbarData.InventoryID)) return;
--- a/AnvilMetalRecovery/assets/fma/lang/en.json
+++ b/AnvilMetalRecovery/assets/fma/lang/en.json
@@ -26,4 +26,5 @@
2626 "fma:item-metal_fragments":"Broken metal fragments.",
2727 "fma:itemdesc-item-metal_fragments": "Try, chopping it apart with a Chisel...",
2828 "fma:metal_worth":"Worth {0} units of {1}.",
29+ "fma:spray_cooler_text":"\n...mabey it can cool off hot things, too?",
2930 }
\ No newline at end of file
--- a/AnvilMetalRecovery/assets/fma/patches/wateringcan_behavior.json
+++ b/AnvilMetalRecovery/assets/fma/patches/wateringcan_behavior.json
@@ -4,7 +4,7 @@
44 "path": "/behaviorsByType/*-burned",
55 "value": [
66 {
7- name: "directspraycooler", properties: { coolRate: 1.0 }
7+ name: "directspraycooler", properties: { "coolRate": 1.0 }
88 }
99 ],
1010 "file": "game:blocktypes/clay/wateringcan.json"