The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of Stamina Panic v1.0.2
tony4twentys-Stamina_Panic.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Networking; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Stamina Panic")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Stamina Panic")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f3d2d2cf-e3bd-4b0f-a0ba-2082998aceb8")] [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")] namespace StaminaPanic; [BepInPlugin("tony4twentys.Stamina_Panic", "Stamina Panic", "1.0.6")] [HarmonyPatch(typeof(RunManager), "Awake")] public class StaminaPanic : BaseUnityPlugin { [CompilerGenerated] private sealed class <CheckStaminaLoop>d__20 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public StaminaPanic <>4__this; private CharacterData <playerData>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CheckStaminaLoop>d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <playerData>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; case 3: <>1__state = -1; <playerData>5__1 = null; break; } if (!<>4__this.inGameScene) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } <playerData>5__1 = ((IEnumerable<CharacterData>)Object.FindObjectsByType<CharacterData>((FindObjectsSortMode)0)).FirstOrDefault((Func<CharacterData, bool>)delegate(CharacterData cd) { Character component = ((Component)cd).GetComponent<Character>(); return component != null && component.IsLocal; }); if ((Object)(object)<playerData>5__1 == (Object)null) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 2; return true; } <>4__this.audioSource.volume = Mathf.Clamp(<>4__this.volumeConfig.Value, 0f, 100f) / 100f; if (<playerData>5__1.TotalStamina <= <>4__this.thresholdConfig.Value) { if (!<>4__this.isBelowThreshold) { if (<>4__this.fadeOutCoroutine != null) { ((MonoBehaviour)<>4__this).StopCoroutine(<>4__this.fadeOutCoroutine); } <>4__this.audioSource.volume = Mathf.Clamp(<>4__this.volumeConfig.Value, 0f, 100f) / 100f; <>4__this.audioSource.Play(); <>4__this.isBelowThreshold = true; } } else if (<>4__this.isBelowThreshold) { if (<>4__this.fadeOutCoroutine != null) { ((MonoBehaviour)<>4__this).StopCoroutine(<>4__this.fadeOutCoroutine); } <>4__this.fadeOutCoroutine = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.FadeOutAndStop()); <>4__this.isBelowThreshold = false; } <>2__current = (object)new WaitForSeconds(1f); <>1__state = 3; 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(); } } [CompilerGenerated] private sealed class <DelayedStartup>d__16 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public StaminaPanic <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedStartup>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(30f); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = <>4__this.LoadFirstAvailableAudioClip_UWR(<>4__this.soundFolderPathConfig.Value); <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <FadeOutAndStop>d__19 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public StaminaPanic <>4__this; private float <startVolume>5__1; private float <time>5__2; private float <duration>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FadeOutAndStop>d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <startVolume>5__1 = <>4__this.audioSource.volume; <time>5__2 = 0f; <duration>5__3 = <>4__this.fadeOutTimeConfig.Value; break; case 1: <>1__state = -1; break; } if (<time>5__2 < <duration>5__3) { <time>5__2 += Time.deltaTime; <>4__this.audioSource.volume = Mathf.Lerp(<startVolume>5__1, 0f, <time>5__2 / <duration>5__3); <>2__current = null; <>1__state = 1; return true; } <>4__this.audioSource.Stop(); <>4__this.audioSource.volume = Mathf.Clamp(<>4__this.volumeConfig.Value, 0f, 100f) / 100f; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadFirstAvailableAudioClip_UWR>d__18 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string folderPath; public StaminaPanic <>4__this; private string[] <files>5__1; private string <path>5__2; private string <url>5__3; private AudioType <audioType>5__4; private UnityWebRequest <www>5__5; private AudioMixerGroup <grp>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadFirstAvailableAudioClip_UWR>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <files>5__1 = null; <path>5__2 = null; <url>5__3 = null; <www>5__5 = null; <grp>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Invalid comparison between Unknown and I4 //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) bool result; try { switch (<>1__state) { default: result = false; break; case 0: <>1__state = -1; if (!Directory.Exists(folderPath)) { result = false; break; } <files>5__1 = (from f in Directory.GetFiles(folderPath) where f.EndsWith(".wav") || f.EndsWith(".ogg") select f).ToArray(); if (<files>5__1.Length == 0) { result = false; break; } <path>5__2 = <files>5__1[0]; <url>5__3 = "file://" + Path.GetFullPath(<path>5__2).Replace("\\", "/"); <audioType>5__4 = (AudioType)(<path>5__2.EndsWith(".ogg") ? 14 : 20); <www>5__5 = UnityWebRequestMultimedia.GetAudioClip(<url>5__3, <audioType>5__4); <>1__state = -3; <>2__current = <www>5__5.SendWebRequest(); <>1__state = 1; result = true; break; case 1: <>1__state = -3; if ((int)<www>5__5.result != 1) { result = false; } else { <>4__this.cueClip = DownloadHandlerAudioClip.GetContent(<www>5__5); if (!((Object)(object)<>4__this.cueClip == (Object)null)) { <>4__this.audioHost = new GameObject("StaminaPanicAudioHost"); <>4__this.audioSource = <>4__this.audioHost.AddComponent<AudioSource>(); <>4__this.audioSource.clip = <>4__this.cueClip; <>4__this.audioSource.loop = true; <>4__this.audioSource.playOnAwake = false; <>4__this.audioSource.spatialBlend = 0f; <>4__this.audioSource.dopplerLevel = 0f; <>4__this.audioSource.rolloffMode = (AudioRolloffMode)1; <>4__this.audioSource.minDistance = 1f; <>4__this.audioSource.maxDistance = 500f; <>4__this.audioSource.ignoreListenerPause = true; <>4__this.audioSource.bypassEffects = false; <>4__this.audioSource.bypassListenerEffects = false; <>4__this.audioSource.bypassReverbZones = true; <grp>5__6 = TryGetGameMixerGroup(); if ((Object)(object)<grp>5__6 != (Object)null) { <>4__this.audioSource.outputAudioMixerGroup = <grp>5__6; } Object.DontDestroyOnLoad((Object)(object)<>4__this.audioHost); if (<>4__this.staminaCoroutine != null) { ((MonoBehaviour)<>4__this).StopCoroutine(<>4__this.staminaCoroutine); } <>4__this.staminaCoroutine = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.CheckStaminaLoop()); <grp>5__6 = null; <>m__Finally1(); <www>5__5 = null; result = false; break; } result = false; } <>m__Finally1(); break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<www>5__5 != null) { ((IDisposable)<www>5__5).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static StaminaPanic instance; private GameObject audioHost; private AudioSource audioSource; private AudioClip cueClip; private ConfigEntry<float> thresholdConfig; private ConfigEntry<string> soundFolderPathConfig; private ConfigEntry<float> volumeConfig; private ConfigEntry<float> fadeOutTimeConfig; private bool isBelowThreshold = false; private bool inGameScene = false; private Coroutine staminaCoroutine; private Coroutine startCoroutine; private Coroutine fadeOutCoroutine; private void Awake() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) instance = this; string text = Path.Combine(Paths.PluginPath, "tony4twentys-Stamina_Panic", "audio"); thresholdConfig = ((BaseUnityPlugin)this).Config.Bind<float>("General", "StaminaThreshold", 0.2f, "Value of TotalStamina that triggers the sound (0.0 to 1.0)"); soundFolderPathConfig = ((BaseUnityPlugin)this).Config.Bind<string>("General", "SoundFolderPath", text, "Folder path containing a .wav or .ogg sound file to play"); volumeConfig = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CueVolume", 100f, "Volume level for the audio cue (0 to 100)"); fadeOutTimeConfig = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FadeOutTime", 1.5f, "Time in seconds to fade out the audio when stamina recovers"); SceneManager.activeSceneChanged += OnSceneChanged; new Harmony("tony4twentys.Stamina_Panic").PatchAll(); } private void OnSceneChanged(Scene oldScene, Scene newScene) { inGameScene = ((Scene)(ref newScene)).name.StartsWith("Level_"); if (!inGameScene) { ((MonoBehaviour)this).StopAllCoroutines(); if ((Object)(object)audioSource != (Object)null && audioSource.isPlaying) { audioSource.Stop(); } isBelowThreshold = false; } } [HarmonyPostfix] private static void RunManager_Awake_Postfix() { if (instance.startCoroutine != null) { ((MonoBehaviour)instance).StopCoroutine(instance.startCoroutine); } instance.startCoroutine = ((MonoBehaviour)instance).StartCoroutine(instance.DelayedStartup()); } [IteratorStateMachine(typeof(<DelayedStartup>d__16))] private IEnumerator DelayedStartup() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedStartup>d__16(0) { <>4__this = this }; } private static AudioMixerGroup TryGetGameMixerGroup() { AudioSource val = ((IEnumerable<AudioSource>)Object.FindObjectsByType<AudioSource>((FindObjectsSortMode)0)).FirstOrDefault((Func<AudioSource, bool>)((AudioSource a) => (Object)(object)a != (Object)null && ((Behaviour)a).isActiveAndEnabled && (Object)(object)a.outputAudioMixerGroup != (Object)null)); return ((Object)(object)val != (Object)null) ? val.outputAudioMixerGroup : null; } [IteratorStateMachine(typeof(<LoadFirstAvailableAudioClip_UWR>d__18))] private IEnumerator LoadFirstAvailableAudioClip_UWR(string folderPath) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadFirstAvailableAudioClip_UWR>d__18(0) { <>4__this = this, folderPath = folderPath }; } [IteratorStateMachine(typeof(<FadeOutAndStop>d__19))] private IEnumerator FadeOutAndStop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FadeOutAndStop>d__19(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<CheckStaminaLoop>d__20))] private IEnumerator CheckStaminaLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CheckStaminaLoop>d__20(0) { <>4__this = this }; } }