using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using GlobalSettings; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ReplenishTools")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ReplenishTools")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ba5967c0-621d-4db8-8523-bd8b2f748c2f")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("com.NarrowsProjects.ReplenishTools", "Replenish tools over time", "1.0.0")] public class ReplenishTools : BaseUnityPlugin { [HarmonyPatch(typeof(EnemyHitEffectsRegular), "ReceiveHitEffect", new Type[] { typeof(HitInstance), typeof(Vector2) })] private static class PatchNailHitBoost { private static void Postfix() { BoostEndTime = Time.time + 1.5f; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static class PatchToolCapacity { private static void Postfix(ToolItem __instance, ref int __result) { if (IsRedTool(__instance)) { __result = Mathf.Max(1, Mathf.CeilToInt((float)__result * 0.5f)); } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static class PatchReplenishMultiplier { private static void Postfix(ToolItem __instance, ref float __result) { if (IsRedTool(__instance) && IsPercentageReplenish(__instance)) { __result *= 0.5f; } } } [CompilerGenerated] private sealed class d__15 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ReplenishTools <>4__this; private float 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ReplenishTools replenishTools = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; float time = Time.time; float deltaTime = time - 5__2; 5__2 = time; replenishTools.TryRegenRedTools(deltaTime); } else { <>1__state = -1; 5__2 = Time.time; } <>2__current = null; <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const float BaseRegenSeconds = 90f; private const float ReplenishBoostDuration = 1.5f; private const float ReplenishBoost = 2f; internal static float BoostEndTime = -1f; private readonly Dictionary _regenAccumulator = new Dictionary(); internal static bool IsRedTool(ToolItem tool) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if (tool == null) { return false; } return (int)tool.Type == 0; } internal static bool IsPercentageReplenish(ToolItem tool) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if (tool == null) { return false; } return (int)tool.ReplenishUsage == 0; } internal static bool CurrencyIsDeductable(ReplenishResources currencyType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 return (int)currencyType != -1; } public void Awake() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading ReplenishTools mod"); new Harmony("com.NarrowsProjects.ReplenishTools").PatchAll(); } public void Start() { ((MonoBehaviour)this).StartCoroutine(RegenLoop()); } private int AccumulateRegen(ToolItem tool, float deltaTime) { float num = (float)ToolItemManager.GetToolStorageAmount(tool) / 90f; if (Time.time <= BoostEndTime) { num *= 2f; } if (!_regenAccumulator.TryGetValue(tool.name, out var value)) { value = 0f; } value += num * deltaTime; int num2 = Mathf.FloorToInt(value); _regenAccumulator[tool.name] = value - (float)num2; return num2; } internal bool ReplenishTool(ToolItem tool, int toolReplenishCount) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!IsRedTool(tool) || toolReplenishCount <= 0) { return false; } Data toolData = PlayerData.instance.GetToolData(tool.name); int toolStorageAmount = ToolItemManager.GetToolStorageAmount(tool); if (toolData.AmountLeft >= toolStorageAmount) { _regenAccumulator[tool.name] = 0f; return false; } int num = Mathf.Min(toolReplenishCount, toolStorageAmount - toolData.AmountLeft); for (int i = 0; i < num; i++) { if (!CanAffordReplenish(tool)) { break; } DeductReplenishCost(tool); toolData.AmountLeft++; } PlayerData.instance.SetToolData(tool.name, toolData); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Regen] {tool.name}: {toolData.AmountLeft}/{toolStorageAmount}"); return true; } internal int ComputeReplenishCost(ToolItem tool) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected I4, but got Unknown ReplenishUsages replenishUsage = tool.ReplenishUsage; return Mathf.RoundToInt((int)replenishUsage switch { 0 => 1f / (float)tool.BaseStorageAmount * (float)Gameplay.ToolReplenishCost, 1 => 1f, 2 => 0f, _ => 0f, } * tool.ReplenishUsageMultiplier); } internal bool CanAffordReplenish(ToolItem tool) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!CurrencyIsDeductable(tool.ReplenishResource)) { return true; } int num = ComputeReplenishCost(tool); return (float)(CurrencyManager.GetCurrencyAmount((CurrencyType)tool.ReplenishResource) - num) > -0.5f; } internal void DeductReplenishCost(ToolItem tool) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) int num = ComputeReplenishCost(tool); if (num > 0 && CurrencyIsDeductable(tool.ReplenishResource)) { CurrencyManager.TakeCurrency(num, (CurrencyType)tool.ReplenishResource, true); } } [IteratorStateMachine(typeof(d__15))] private IEnumerator RegenLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(0) { <>4__this = this }; } private void TryRegenRedTools(float deltaTime) { if (PlayerData.instance == null) { return; } List equippedToolsForCrest = ToolItemManager.GetEquippedToolsForCrest(PlayerData.instance.CurrentCrestID); if (equippedToolsForCrest == null) { return; } bool flag = false; foreach (ToolItem item in equippedToolsForCrest) { if (IsRedTool(item)) { int toolReplenishCount = AccumulateRegen(item, deltaTime); flag |= ReplenishTool(item, toolReplenishCount); } } if (flag) { ToolItemManager.ReportAllBoundAttackToolsUpdated(); ToolItemManager.SendEquippedChangedEvent(true); } } }