using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ScalingStaminaRegen")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+ab4e320644da49c929ad1d249e41b59763aeca26")] [assembly: AssemblyProduct("ScalingStaminaRegen")] [assembly: AssemblyTitle("ScalingStaminaRegen")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace ScalingStaminaRegen { public static class MyPluginInfo { public const string PLUGIN_GUID = "ScalingStaminaRegen"; public const string PLUGIN_NAME = "ScalingStaminaRegen"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace MyMod { [BepInPlugin("scoutcraft.ScalingStaminaRegen", "Scaling Stamina Regen", "1.0.0")] public class Plugin : BaseUnityPlugin { private const string MOD_GUID = "scoutcraft.ScalingStaminaRegen"; private const string MOD_Name = "Scaling Stamina Regen"; private const string MOD_Version = "1.0.0"; private readonly Harmony _harmony = new Harmony("scoutcraft.ScalingStaminaRegen"); internal static ManualLogSource mls = Logger.CreateLogSource("scoutcraft.ScalingStaminaRegen"); internal static ConfigEntry BaseStaminaRegen = null; internal static ConfigEntry SprintRechargeTime = null; internal static ConfigEntry AgilityPerUpgrade = null; internal static ConfigEntry MaxAgilityCap = null; internal static ConfigEntry ToggleAgilityTimer = null; internal static ConfigEntry ToggleDisableAgility = null; internal static ConfigEntry ToggleRecalculatePerFrame = null; internal static ConfigEntry ToggleRecalculateInfo = null; internal static ConfigEntry ToggleAgilityUncapped = null; private void Awake() { BindConfiguration(); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } public void BindConfiguration() { BaseStaminaRegen = ((BaseUnityPlugin)this).Config.Bind("Stamina Regen.Values", "BaseStaminaRegen", 3f, "What the base stamina regen is. (vanilla is 2 btw)"); SprintRechargeTime = ((BaseUnityPlugin)this).Config.Bind("Stamina Regen.Values", "SprintRechargeTime", 1f, "How long it takes after sprinting for base stamina regen to reactivate."); AgilityPerUpgrade = ((BaseUnityPlugin)this).Config.Bind("Stamina Regen.Values", "AgilityPerUpgrade", 0.2f, "Additional stamina regeneration per second for each combined level of Stamina + Crouch Rest + Speed upgrades."); MaxAgilityCap = ((BaseUnityPlugin)this).Config.Bind("Stamina Regen.Values", "MaxAgilityCap", 50f, "What AgilityPerUpgrade will be capped at."); ToggleDisableAgility = ((BaseUnityPlugin)this).Config.Bind("Stamina Regen.Toggle", "ToggleDisableAgility", false, "Disables the Agility bonus by fixing AgilityPerUpgrade at 0."); ToggleAgilityTimer = ((BaseUnityPlugin)this).Config.Bind("Stamina Regen.Toggle", "ToggleAgilityTimer", false, "Whether Agility should activate during the Sprint timer."); ToggleRecalculatePerFrame = ((BaseUnityPlugin)this).Config.Bind("Stamina Regen.Toggle", "ToggleRecalculatePerFrame", false, "If Agility should be recalculated every frame. (suppresses most Agility debug logs)"); ToggleRecalculateInfo = ((BaseUnityPlugin)this).Config.Bind("Stamina Regen.Toggle", "ToggleRecalculateInfo", false, "If Agility info should be printed in info level Logger. (it's Debug by default)"); ToggleAgilityUncapped = ((BaseUnityPlugin)this).Config.Bind("Stamina Regen.Toggle", "ToggleAgilityUncapped", false, "If Agility should cap out at MaxAgilityCap"); } public static void SendLog(string msg) { mls.LogInfo((object)msg); } } } namespace MyMod.Patches { [HarmonyPatch] public static class AgilityPatch { [CompilerGenerated] private sealed class d__18 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_004f; case 1: <>1__state = -1; goto IL_004f; case 2: { <>1__state = -1; Plugin.mls.LogDebug((object)"Is Level or Shop, done WaitAndActivate()"); RecalculateAgility(); if (ToggleDisableAgility) { printAgility(); } return false; } IL_004f: if (!SemiFunc.LevelGenDone()) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } if (!SemiFunc.RunIsLevel() && !SemiFunc.RunIsShop()) { return false; } <>2__current = (object)new WaitForSeconds(1f); <>1__state = 2; 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(); } } internal static float BaseStaminaRegen; internal static float SprintRechargeTime; internal static float AgilityPerUpgrade; internal static float MaxAgilityCap; internal static bool ToggleDisableAgility; internal static bool ToggleAgilityTimer; internal static bool ToggleRecalculatePerFrame; internal static bool ToggleRecalculateInfo; internal static bool ToggleAgilityUncapped; private static float agilityRechargeTimer = 0f; private static float agilityRechargeTimerStart = 0.2f; internal static float AgilityRegenBuff = 0f; internal static string? localSteamID; private static bool checkIDObtained = false; private static void SetValueConfig() { BaseStaminaRegen = Plugin.BaseStaminaRegen.Value; SprintRechargeTime = Plugin.SprintRechargeTime.Value; AgilityPerUpgrade = Plugin.AgilityPerUpgrade.Value; MaxAgilityCap = Plugin.MaxAgilityCap.Value; ToggleDisableAgility = Plugin.ToggleDisableAgility.Value; ToggleAgilityTimer = Plugin.ToggleAgilityTimer.Value; ToggleRecalculatePerFrame = Plugin.ToggleRecalculatePerFrame.Value; ToggleRecalculateInfo = Plugin.ToggleRecalculateInfo.Value; ToggleAgilityUncapped = Plugin.ToggleAgilityUncapped.Value; } [HarmonyPatch(typeof(PlayerController), "Start")] [HarmonyPostfix] public static void GetSteamID() { if (!checkIDObtained) { Plugin.mls.LogDebug((object)"Running GetSteamID()"); PlayerAvatar val = SemiFunc.PlayerAvatarLocal(); try { localSteamID = SemiFunc.PlayerGetSteamID(val); } catch (NullReferenceException) { Plugin.mls.LogDebug((object)"playerAvatar is (probably) null, aborting GetSteamID()"); return; } if (localSteamID == null) { Plugin.mls.LogDebug((object)"localSteamID is null, aborting GetSteamID()"); return; } Plugin.mls.LogDebug((object)("Success! GetSteamID() Player is " + localSteamID)); checkIDObtained = true; } } [HarmonyPatch(typeof(PlayerController), "Awake")] [HarmonyPostfix] public static void SetControllerValues(PlayerController __instance, ref float ___sprintRechargeAmount, ref float ___sprintRechargeTime) { BaseStaminaRegen = Plugin.BaseStaminaRegen.Value; SprintRechargeTime = Plugin.SprintRechargeTime.Value; ___sprintRechargeAmount = BaseStaminaRegen; ___sprintRechargeTime = SprintRechargeTime; Plugin.mls.LogDebug((object)"PlayerController values patched."); } [HarmonyPatch(typeof(GameDirector), "Start")] [HarmonyPostfix] private static void GameDirector_Start_Postfix() { Object.FindAnyObjectByType().StartCoroutine(WaitAndActivate()); } [IteratorStateMachine(typeof(d__18))] private static IEnumerator WaitAndActivate() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__18(0); } public static void RecalculateAgility() { SetValueConfig(); if (ToggleDisableAgility) { return; } if (localSteamID == null) { if (!ToggleRecalculatePerFrame) { Plugin.mls.LogDebug((object)"localSteamID is null, aborting RecalculateAgility()"); } return; } int valueOrDefault = StatsManager.instance.playerUpgradeCrouchRest.GetValueOrDefault(localSteamID, 0); int valueOrDefault2 = StatsManager.instance.playerUpgradeSpeed.GetValueOrDefault(localSteamID, 0); int valueOrDefault3 = StatsManager.instance.playerUpgradeStamina.GetValueOrDefault(localSteamID, 0); AgilityRegenBuff = Mathf.Min((float)(valueOrDefault + valueOrDefault2 + valueOrDefault3) * AgilityPerUpgrade, ToggleAgilityUncapped ? float.MaxValue : MaxAgilityCap); if (!ToggleRecalculatePerFrame) { printAgility(); } } private static void printAgility() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) int valueOrDefault = StatsManager.instance.playerUpgradeCrouchRest.GetValueOrDefault(localSteamID, 0); int valueOrDefault2 = StatsManager.instance.playerUpgradeSpeed.GetValueOrDefault(localSteamID, 0); int valueOrDefault3 = StatsManager.instance.playerUpgradeStamina.GetValueOrDefault(localSteamID, 0); LogLevel val = (LogLevel)(ToggleRecalculateInfo ? 16 : 32); Plugin.mls.Log(val, (object)$"AgilityRegenBuff has been recaluated: AgilityRegenBuff: {AgilityRegenBuff} + BaseStaminaRegen: {BaseStaminaRegen} = {AgilityRegenBuff + BaseStaminaRegen}"); Plugin.mls.LogDebug((object)$"Player {localSteamID} CrouchRest: {valueOrDefault}, Speed: {valueOrDefault2}, Stamina: {valueOrDefault3}"); } [HarmonyPatch(typeof(PlayerController), "Update")] [HarmonyPostfix] public static void PatchAgility(PlayerController __instance, ref float ___sprintRechargeTimer) { if (ToggleDisableAgility) { return; } if (ToggleRecalculatePerFrame) { RecalculateAgility(); } float energyCurrent = __instance.EnergyCurrent; float energyStart = __instance.EnergyStart; if (__instance.sprinting) { if (ToggleAgilityTimer) { agilityRechargeTimer = agilityRechargeTimerStart; } } else if (!(energyCurrent >= energyStart) && (!(___sprintRechargeTimer > 0f) || ToggleAgilityTimer)) { if (ToggleAgilityTimer && agilityRechargeTimer > 0f) { agilityRechargeTimer -= Time.deltaTime; } else { __instance.EnergyCurrent = Mathf.Min(energyCurrent + AgilityRegenBuff * Time.deltaTime, energyStart); } } } [HarmonyPatch(typeof(PunManager), "UpdateCrouchRestRightAway")] [HarmonyPostfix] public static void CheckUpdatePlayerCrouchRest() { RecalculateAgility(); int valueOrDefault = StatsManager.instance.playerUpgradeCrouchRest.GetValueOrDefault(localSteamID, 0); Plugin.mls.LogDebug((object)$"Player {localSteamID} changed CrouchRest to {valueOrDefault} total."); } [HarmonyPatch(typeof(PunManager), "UpdateSprintSpeedRightAway")] [HarmonyPostfix] public static void CheckUpdateSprintSpeed() { RecalculateAgility(); int valueOrDefault = StatsManager.instance.playerUpgradeSpeed.GetValueOrDefault(localSteamID, 0); Plugin.mls.LogDebug((object)$"Player {localSteamID} changed SprintSpeed to {valueOrDefault} total."); } [HarmonyPatch(typeof(PunManager), "UpdateEnergyRightAway")] [HarmonyPostfix] public static void CheckUpdatePlayerEnergy() { RecalculateAgility(); int valueOrDefault = StatsManager.instance.playerUpgradeStamina.GetValueOrDefault(localSteamID, 0); Plugin.mls.LogDebug((object)$"Player {localSteamID} changed Stamina to {valueOrDefault} total."); } } }