using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("MoyaGzHealthRegeneration")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("MoyaGzHealthRegeneration")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0bc74804-81fc-42bc-802b-f80d914b4657")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace MoyaGzHealthRegen; public enum RegenType { MaxHealth, RegenAmount } [BepInPlugin("com.MoyaGz.repo.healthregen", "Health Regeneration Mod", "1.0.0")] public class HealthRegenPlugin : BaseUnityPlugin { public class PlayerRegenData { public float RegenTimer = 0f; public float TimeSinceLastDamage = 0f; public int LastKnownHealth = -1; public float AccumulatedHeal = 0f; } public static ConditionalWeakTable PlayerData = new ConditionalWeakTable(); public static ConfigEntry ModEnabled; public static ConfigEntry RegenMode; public static ConfigEntry PercentAmount; public static ConfigEntry RegenInterval; public static ConfigEntry OutOfCombatTime; public static ConfigEntry RegenAmountConfig; private void Awake() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) ModEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enable Mod", true, "Enables or disables health regeneration."); RegenMode = ((BaseUnityPlugin)this).Config.Bind("Regen Settings", "Regen Type", RegenType.MaxHealth, "Choose whether to regenerate a percentage of max health or a fixed amount."); PercentAmount = ((BaseUnityPlugin)this).Config.Bind("Regen Settings", "Max Health Percent Amount", 1.5f, new ConfigDescription("Percentage of maximum health recovered per tick (Supports decimals like 0.15).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); RegenInterval = ((BaseUnityPlugin)this).Config.Bind("Regen Settings", "Regen Interval", 0.5f, new ConfigDescription("How often health regenerates (in seconds).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 60f), Array.Empty())); OutOfCombatTime = ((BaseUnityPlugin)this).Config.Bind("Combat Settings", "Out Of Combat Time", 8f, new ConfigDescription("Time without taking damage (in seconds) required to start healing.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 60f), Array.Empty())); RegenAmountConfig = ((BaseUnityPlugin)this).Config.Bind("Regen Settings", "Regen Amount", 1, new ConfigDescription("Amount of health recovered per tick.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); new Harmony("com.MoyaGz.repo.healthregen").PatchAll(); Debug.Log((object)"Health Regeneration Mod v1.1.0 Loaded successfully!"); } } [HarmonyPatch(typeof(PlayerHealth), "Update")] public class PlayerHealthUpdatePatch { private static void Postfix(PlayerHealth __instance, ref int ___health, ref int ___maxHealth) { if (!HealthRegenPlugin.ModEnabled.Value || (Object)(object)__instance == (Object)null || ___health <= 0) { return; } if (___health >= ___maxHealth) { if (HealthRegenPlugin.PlayerData.TryGetValue(__instance, out var value)) { value.LastKnownHealth = ___health; value.RegenTimer = 0f; value.AccumulatedHeal = 0f; } return; } HealthRegenPlugin.PlayerRegenData orCreateValue = HealthRegenPlugin.PlayerData.GetOrCreateValue(__instance); if (orCreateValue.LastKnownHealth < 0) { orCreateValue.LastKnownHealth = ___health; } if (___health < orCreateValue.LastKnownHealth) { orCreateValue.TimeSinceLastDamage = 0f; orCreateValue.RegenTimer = 0f; orCreateValue.AccumulatedHeal = 0f; } else { orCreateValue.TimeSinceLastDamage += Time.deltaTime; } orCreateValue.LastKnownHealth = ___health; if (!(orCreateValue.TimeSinceLastDamage >= HealthRegenPlugin.OutOfCombatTime.Value)) { return; } orCreateValue.RegenTimer += Time.deltaTime; if (orCreateValue.RegenTimer >= HealthRegenPlugin.RegenInterval.Value) { orCreateValue.RegenTimer = 0f; float num = 0f; num = ((HealthRegenPlugin.RegenMode.Value != RegenType.MaxHealth) ? ((float)HealthRegenPlugin.RegenAmountConfig.Value) : ((float)___maxHealth * (HealthRegenPlugin.PercentAmount.Value / 100f))); orCreateValue.AccumulatedHeal += num; if (orCreateValue.AccumulatedHeal >= 1f) { int num2 = Mathf.FloorToInt(orCreateValue.AccumulatedHeal); orCreateValue.AccumulatedHeal -= num2; __instance.Heal(num2, false); orCreateValue.LastKnownHealth = ___health; } } } } [HarmonyPatch(typeof(RoundDirector), "Awake")] public class RoundStartPatch { private static void Postfix() { HealthRegenPlugin.PlayerData = new ConditionalWeakTable(); Debug.Log((object)"[HealthRegen] Data table cleared for the new round."); } }