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 Pain Killers v0.1.0
BepInEx/plugins/Pain_Killers/FirstAid.dll
Decompiled 5 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using Microsoft.CodeAnalysis; using PEAKLib.Core; using PEAKLib.Items.UnityEditor; using PEAKLib.Stats; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("FirstAid")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("FirstAid")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("D5DF341F-804A-43C0-86C9-D3B2F89589B9")] [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 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; } } } public class Action_PainKillers : ItemAction { public FirstAid firstAidHost; public override void RunAction() { if (Object.op_Implicit((Object)(object)((ItemActionBase)this).character)) { if (Random.Range(1, 100) == 5) { ((MonoBehaviour)((ItemActionBase)this).character).Invoke("DieInstantly", 0.02f); } else if (firstAidHost.PainKillersOn < 3) { firstAidHost.PainKillerEffects(((ItemActionBase)this).character.refs.afflictions); } else { firstAidHost.Overdose(((ItemActionBase)this).character.refs.afflictions); } } } } public static class FirstAidAfflictions { public static STATUSTYPE Overdose; public static STATUSTYPE Bacteria; public static void RegisterAfflictions() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) Sprite icon = SpriteLoader.FromEmbedded("FirstAid.Sprites.pill.png"); Status val = new Status { Name = "Overdose", Color = new Color(0.48f, 1f, 0.196f), MaxAmount = 2f, AllowClear = true, ReductionCooldown = 0f, ReductionPerSecond = 0f, Icon = icon }; new StatusContent(val).Register(FirstAid.Definition); Overdose = val.Type; SpriteLoader.FromEmbedded("FirstAid.Sprites.bacteria.png"); Status val2 = new Status { Name = "Bacteria", Color = new Color(1f, 0.576f, 0.196f), MaxAmount = 2f, AllowClear = true, ReductionCooldown = 0f, ReductionPerSecond = -0.1f, Icon = icon }; new StatusContent(val2).Register(FirstAid.Definition); Bacteria = val2.Type; } } [BepInPlugin("com.khakixd.firstaid", "FirstAid", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class FirstAid : BaseUnityPlugin { [CompilerGenerated] private sealed class <OverdosePlayer>d__15 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CharacterAfflictions afflicts; private float <x>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OverdosePlayer>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <x>5__2 = 0f; break; case 1: <>1__state = -1; <x>5__2 += Time.deltaTime * 0.05f; afflicts.AddStatus(FirstAidAfflictions.Overdose, Time.deltaTime * 0.05f, false); break; } if (<x>5__2 < 2f) { <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; } 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 <PainKillerCoroutine>d__17 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public FirstAid <>4__this; public CharacterAfflictions afflicts; private float[] <removedPhase1>5__2; private float[] <suppressedPhase2>5__3; private float <suppressTimer>5__4; private float[] <remaining>5__5; private float <restoreTimer>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PainKillerCoroutine>d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <removedPhase1>5__2 = null; <suppressedPhase2>5__3 = null; <remaining>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; FirstAid firstAid = <>4__this; float num4; switch (num) { default: return false; case 0: <>1__state = -1; firstAid.PainKillersOn++; <removedPhase1>5__2 = new float[PainKillerAfflictions.Length]; <suppressedPhase2>5__3 = new float[PainKillerAfflictions.Length]; goto IL_005f; case 1: { <>1__state = -1; bool flag2 = false; for (int l = 0; l < PainKillerAfflictions.Length; l++) { STATUSTYPE val2 = PainKillerAfflictions[l]; float currentStatus5 = afflicts.GetCurrentStatus(val2); if (currentStatus5 > 0.001f) { float num6 = 0.05f * Time.deltaTime; num6 = Mathf.Min(num6, currentStatus5); afflicts.SubtractStatus(val2, num6, false); float currentStatus6 = afflicts.GetCurrentStatus(val2); float num7 = Mathf.Max(0f, currentStatus5 - currentStatus6); if (num7 > 0f) { <removedPhase1>5__2[l] += num7; } if (currentStatus6 > 0.001f) { flag2 = true; } } } if (flag2) { goto IL_005f; } <suppressTimer>5__4 = 0f; goto IL_01f2; } case 2: { <>1__state = -1; <suppressTimer>5__4 += Time.deltaTime; for (int k = 0; k < PainKillerAfflictions.Length; k++) { STATUSTYPE val = PainKillerAfflictions[k]; float currentStatus3 = afflicts.GetCurrentStatus(val); if (currentStatus3 > 0.001f) { afflicts.SubtractStatus(val, currentStatus3, false); float currentStatus4 = afflicts.GetCurrentStatus(val); float num5 = Mathf.Max(0f, currentStatus3 - currentStatus4); if (num5 > 0f) { <suppressedPhase2>5__3[k] += num5; } } } goto IL_01f2; } case 3: { <>1__state = -1; <restoreTimer>5__6 += Time.deltaTime; bool flag = true; for (int i = 0; i < <remaining>5__5.Length; i++) { if (<remaining>5__5[i] > 0.001f) { flag = false; float num2 = Mathf.Min(0.01f * Time.deltaTime, <remaining>5__5[i]); float currentStatus = afflicts.GetCurrentStatus(PainKillerAfflictions[i]); afflicts.AddStatus(PainKillerAfflictions[i], num2, false); float currentStatus2 = afflicts.GetCurrentStatus(PainKillerAfflictions[i]); float num3 = Mathf.Max(0f, currentStatus2 - currentStatus); if (num3 > 0f) { <remaining>5__5[i] -= num3; } } } if (flag) { break; } if (<restoreTimer>5__6 > 180f) { Debug.LogWarning((object)"[FirstAid] Restore phase exceeded safety time; finishing early to avoid infinite loop."); break; } goto IL_0283; } IL_0283: <>2__current = firstAid._wfeof; <>1__state = 3; return true; IL_005f: <>2__current = firstAid._wfeof; <>1__state = 1; return true; IL_01f2: if (<suppressTimer>5__4 < 25f) { <>2__current = firstAid._wfeof; <>1__state = 2; return true; } <remaining>5__5 = new float[PainKillerAfflictions.Length]; num4 = 0f; for (int j = 0; j < <remaining>5__5.Length; j++) { <remaining>5__5[j] = <removedPhase1>5__2[j] + <suppressedPhase2>5__3[j]; num4 += <remaining>5__5[j]; } if (num4 <= 0.001f) { firstAid.PainKillersOn--; firstAid._painKillerRoutine = null; return false; } <restoreTimer>5__6 = 0f; goto IL_0283; } firstAid.PainKillersOn--; firstAid._painKillerRoutine = null; 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(); } } public int PainKillersOn; private const float EPSILON = 0.001f; private const float LOWER_RATE_PER_SEC = 0.05f; private const float SUPPRESS_DURATION = 25f; private const float RESTORE_RATE_PER_SEC = 0.01f; private const float MAX_RESTORE_TIME = 180f; private Coroutine _painKillerRoutine; private readonly WaitForEndOfFrame _wfeof = new WaitForEndOfFrame(); private static readonly STATUSTYPE[] PainKillerAfflictions; public static ModDefinition Definition { get; set; } = null; public void Awake() { Definition = ModDefinition.GetOrCreate(((BaseUnityPlugin)this).Info.Metadata); FirstAidAfflictions.RegisterAfflictions(); Debug.Log((object)"FirstAid plugin is loaded!"); BundleLoader.LoadBundleWithName((BaseUnityPlugin)(object)this, "firstaid.peakbundle", (Action<PeakBundle>)delegate(PeakBundle bundle) { Action_PainKillers action_PainKillers = bundle.LoadAsset<UnityItemContent>("Pills").ItemPrefab.AddComponent<Action_PainKillers>(); action_PainKillers.firstAidHost = this; ((ItemAction)action_PainKillers).OnCastFinished = true; bundle.Mod.RegisterContent(); }); PatchLocalization(); SceneManager.sceneLoaded += delegate { if (_painKillerRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_painKillerRoutine); _painKillerRoutine = null; } PainKillersOn = 0; }; } public void Overdose(CharacterAfflictions afflicts) { ((MonoBehaviour)this).StartCoroutine(OverdosePlayer(afflicts)); } [IteratorStateMachine(typeof(<OverdosePlayer>d__15))] private IEnumerator OverdosePlayer(CharacterAfflictions afflicts) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OverdosePlayer>d__15(0) { afflicts = afflicts }; } public void PainKillerEffects(CharacterAfflictions afflicts) { if (!((Object)(object)afflicts == (Object)null)) { if (_painKillerRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_painKillerRoutine); } _painKillerRoutine = ((MonoBehaviour)this).StartCoroutine(PainKillerCoroutine(afflicts)); } } [IteratorStateMachine(typeof(<PainKillerCoroutine>d__17))] private IEnumerator PainKillerCoroutine(CharacterAfflictions afflicts) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PainKillerCoroutine>d__17(0) { <>4__this = this, afflicts = afflicts }; } private void PatchLocalization() { LocalizedText.mainTable["NAME_PAIN KILLERS"] = new List<string> { "Pain Killers" }; LocalizedText.mainTable["NAME_MELATONIN"] = new List<string> { "Melatonin" }; } static FirstAid() { STATUSTYPE[] array = new STATUSTYPE[4]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); PainKillerAfflictions = (STATUSTYPE[])(object)array; } } internal static class SpriteLoader { public static Sprite FromEmbedded(string resourceName, float pixelsPerUnit = 100f) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { Debug.LogError((object)("[FirstAid] Embedded resource not found: " + resourceName)); return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false); if (!ImageConversion.LoadImage(val, memoryStream.ToArray())) { Debug.LogError((object)("[FirstAid] Failed to load image data for: " + resourceName)); return null; } ((Object)val).name = Path.GetFileNameWithoutExtension(resourceName); ((Texture)val).filterMode = (FilterMode)1; return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), pixelsPerUnit); } }