Decompiled source of Pain Killers v0.1.0

BepInEx/plugins/Pain_Killers/FirstAid.dll

Decompiled 5 days ago
using 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);
	}
}