Decompiled source of NyxLib v0.4.0

NyxLib.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameConsole;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Nyxpiri.Collections.Generic;
using Nyxpiri.ULTRAKILL.NyxLib;
using Nyxpiri.ULTRAKILL.NyxLib.AnimScript;
using Nyxpiri.ULTRAKILL.NyxLib.Assets;
using Nyxpiri.ULTRAKILL.NyxLib.Diagnostics.Debug;
using TMPro;
using ULTRAKILL.Cheats;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Assertions;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class StackDebug
{
	public static string GetStackString()
	{
		StackTrace arg = new StackTrace(1, fNeedFileInfo: false);
		return $"{arg}";
	}

	public static void PrintStack(bool includeFileInfo = false)
	{
		StackTrace arg = new StackTrace(1, includeFileInfo);
		Log.Message($"Stack debug! {arg}");
	}
}
public class EnemyModifier : MonoBehaviour
{
}
public class EnemyComponents : MonoBehaviour
{
	public delegate void PreHurtEventHandler(EventMethodCanceler canceler, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, bool tryForExplode, float critMultiplier, GameObject sourceWeapon, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion);

	public delegate void PostHurtEventHandler(EventMethodCancelInfo cancelInfo, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, bool tryForExplode, float critMultiplier, GameObject sourceWeapon, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion);

	public delegate void PreAnyEnemyHurtEventHandler(EventMethodCanceler canceler, EnemyComponents enemy, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, bool tryForExplode, float critMultiplier, GameObject sourceWeapon, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion);

	public delegate void PostAnyEnemyHurtEventHandler(EventMethodCancelInfo cancelInfo, EnemyComponents enemy, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, bool tryForExplode, float critMultiplier, GameObject sourceWeapon, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion);

	public delegate void PreEnrageEventHandler(EventMethodCanceler canceler);

	public delegate void PostEnrageEventHandler(EventMethodCancelInfo cancelInfo);

	public delegate void PreUnEnrageEventHandler(EventMethodCanceler canceler);

	public delegate void PostUnEnrageEventHandler(EventMethodCancelInfo cancelInfo);

	public delegate void PreDeathEventHandler(EventMethodCanceler canceler, bool instakill);

	public delegate void PostDeathEventHandler(EventMethodCancelInfo cancelInfo, bool instakill);

	public static MonoRegistrar MonoRegistrar = new MonoRegistrar();

	[SerializeField]
	private EnemyCloning _Cloning = null;

	[SerializeField]
	private EnemyRadiance _Radiance = null;

	[SerializeField]
	private bool _hasDoneSetup = false;

	[SerializeField]
	private EnemyRoot _enemyRootMono;

	public bool AvoidHealthBasedSlowDown = false;

	[NonSerialized]
	public bool QueuedForDestruction = false;

	public EnemyIdentifier Eid = null;

	public Enemy Enemy = null;

	public static FieldAccess<EnemyIdentifier, string> OverrideFullNameFA;

	public Vector3 CollisionCenterOffset = Vector3.zero;

	[SerializeField]
	private Collider[] _colliders = null;

	[SerializeField]
	private List<MonoBehaviour> _monoBehaviours = null;

	private bool _isEnemyCompInitializer = false;

	private object DeathPatchCallerObject = null;

	private bool PreDeathCalled = false;

	private bool PostDeathCalled = false;

	private bool DeathCalled = false;

	private bool InTheProcessOfHurting = false;

	private object HurtPatchCallerObject = null;

	public EnemyCloning Cloning
	{
		get
		{
			return _Cloning;
		}
		private set
		{
			_Cloning = value;
		}
	}

	public EnemyRadiance Radiance
	{
		get
		{
			return _Radiance;
		}
		private set
		{
			_Radiance = value;
		}
	}

	public EnemyRoot EnemyRootMono => _enemyRootMono;

	public bool HasDoneSetup => _hasDoneSetup;

	public bool UniquelySolo { get; private set; } = false;

	public bool IsEnemyCompInitializer => _isEnemyCompInitializer;

	public bool EidStarted { get; internal set; } = false;

	[SerializeField]
	public float InitialHealth { get; private set; } = -1f;

	[SerializeField]
	public float HighestHealth { get; private set; } = -1f;

	public float Health
	{
		get
		{
			if ((Object)(object)Enemy != (Object)null)
			{
				return Enemy.health;
			}
			return Eid.health;
		}
		set
		{
			if ((Object)(object)Enemy != (Object)null)
			{
				Enemy.health = value;
			}
			else
			{
				Eid.health = value;
			}
		}
	}

	public GameObject RootGameObject => ((int)Eid.enemyType == 4) ? ((Component)((Component)this).transform.parent).gameObject : ((Component)this).gameObject;

	public bool InstaKilled { get; private set; } = false;

	public IReadOnlyList<Collider> Colliders => _colliders;

	public string OverrideFullName
	{
		get
		{
			return OverrideFullNameFA.GetValue(Eid);
		}
		set
		{
			OverrideFullNameFA.SetValue(Eid, value);
		}
	}

	public Vector3 CollisionCenter => ((Component)this).transform.TransformPoint(CollisionCenterOffset);

	public event PreHurtEventHandler PreHurt;

	public event PostHurtEventHandler PostHurt;

	public static event PreAnyEnemyHurtEventHandler PreAnyEnemyHurt;

	public static event PostAnyEnemyHurtEventHandler PostAnyEnemyHurt;

	public event PreEnrageEventHandler PreEnrage = null;

	public event PostEnrageEventHandler PostEnrage = null;

	public event PreUnEnrageEventHandler PreUnEnrage = null;

	public event PostUnEnrageEventHandler PostUnEnrage = null;

	public event PreDeathEventHandler PreDeath;

	public event PostDeathEventHandler PostDeath;

	public T GetMonoByIndex<T>(int idx) where T : MonoBehaviour
	{
		if (idx < 0)
		{
			throw new IndexOutOfRangeException($"Index {idx} was less than 0");
		}
		if (idx > _monoBehaviours.Count)
		{
			return default(T);
		}
		MonoBehaviour obj = _monoBehaviours[idx];
		return (T)(object)((obj is T) ? obj : null);
	}

	public void MarkAsUniquelySolo()
	{
		UniquelySolo = true;
	}

	public void InstaDestroy()
	{
		Object.Destroy((Object)(object)RootGameObject);
	}

	private void Awake()
	{
		Log.TraceExpectedInfo($"EnemyComponents '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' awakens...");
		Setup();
		EnemyRootMono.Enemy = this;
	}

	internal void Setup()
	{
		if (!HasDoneSetup)
		{
			Log.TraceExpectedInfo($"EnemyComponents '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' is setting up...");
			Eid = ((Component)this).GetComponent<EnemyIdentifier>();
			Enemy = ((Component)this).GetComponent<Enemy>();
			Assert.IsNotNull((Object)(object)Eid);
			_isEnemyCompInitializer = true;
			_hasDoneSetup = true;
			_enemyRootMono = GameObjectExtensions.GetOrAddComponent<EnemyRoot>(RootGameObject);
			CreateMods();
			Eid.ForceGetHealth();
			InitialHealth = Health;
			UpdateHighestHealth();
			_colliders = ((Component)this).GetComponentsInChildren<Collider>(true);
			Cloning?.StorePrefab();
		}
	}

	public void ResetHealthInfo()
	{
		Eid.ForceGetHealth();
		InitialHealth = Health;
		HighestHealth = -100f;
		UpdateHighestHealth();
	}

	private void UpdateHighestHealth()
	{
		if (Health > HighestHealth)
		{
			HighestHealth = Health;
		}
	}

	private void Start()
	{
		//IL_0090: 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_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' starts...");
		if (_isEnemyCompInitializer)
		{
			_colliders = ((Component)this).GetComponentsInChildren<Collider>();
		}
		if (InitialHealth <= 0f)
		{
			Eid.ForceGetHealth();
			InitialHealth = Health;
		}
		Cloning?.StorePrefab();
		UpdateHighestHealth();
		Transform transform = ((Component)this).transform;
		Bounds val = this.SolveEnemyBounds();
		CollisionCenterOffset = transform.InverseTransformPoint(((Bounds)(ref val)).center);
	}

	private void OnDestroy()
	{
		Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' gets instantaneously obliterated (destroyed)...");
	}

	protected void Update()
	{
		if (QueuedForDestruction)
		{
			Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' was queued for destruction, so its time has come.");
			Object.Destroy((Object)(object)RootGameObject);
		}
		if (InTheProcessOfHurting)
		{
			InTheProcessOfHurting = false;
			Log.UnexpectedInfo(((Object)this).name + ": InTheProcessOfHurting had to be set to false by Update");
		}
	}

	protected void FixedUpdate()
	{
		UpdateHighestHealth();
	}

	private void OnDisable()
	{
		Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' gets disabled...");
		if (QueuedForDestruction)
		{
			Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' was queued for destruction, so its time has come.");
			Object.Destroy((Object)(object)RootGameObject);
		}
	}

	private void OnEnable()
	{
		Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' gets enabled...");
	}

	private void CreateMods()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		Log.TraceExpectedInfo(((Object)this).name + ".EnemyAdditions is creating new modules...");
		_monoBehaviours = new List<MonoBehaviour>(MonoRegistrar.RegisteredTypes.Count);
		foreach (Type registeredType in MonoRegistrar.RegisteredTypes)
		{
			_monoBehaviours.Add((MonoBehaviour)((Component)this).gameObject.AddComponent(registeredType));
		}
		if (!Options.DontCreateEnemyRadianceComp.Value)
		{
			Radiance = GameObjectExtensions.GetOrAddComponent<EnemyRadiance>(((Component)this).gameObject);
		}
		if (!Options.DontCreateEnemyPrefabComp.Value)
		{
			Cloning = ((Component)this).gameObject.AddComponent<EnemyCloning>();
		}
	}

	internal void TryCallPreDeath(EventMethodCanceler canceler, bool instakill, object patchCallerObject)
	{
		if (!PreDeathCalled)
		{
			DeathPatchCallerObject = patchCallerObject;
			PreDeathCalled = true;
			InstaKilled = instakill;
			this.PreDeath?.Invoke(canceler, InstaKilled);
			EnemyEvents.PreDeath?.Invoke(this, InstaKilled);
		}
	}

	internal void TryCallPostDeath(EventMethodCancelInfo cancelInfo, object patchCallerObject)
	{
		if (!PostDeathCalled && DeathPatchCallerObject == patchCallerObject)
		{
			PostDeathCalled = true;
			this.PostDeath?.Invoke(cancelInfo, InstaKilled);
			EnemyEvents.PostDeath?.Invoke(this, InstaKilled);
		}
	}

	internal void TryCallDeath()
	{
		if (!DeathCalled)
		{
			DeathCalled = true;
			EnemyEvents.Death?.Invoke(this);
		}
	}

	internal void NotifyOfPreHurt(EventMethodCanceler canceler, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, float critMultiplier, GameObject sourceWeapon, bool tryForExplode, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion, object hurtPatchCallerObject)
	{
		//IL_005c: 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)
		if (InTheProcessOfHurting)
		{
			if (HurtPatchCallerObject == hurtPatchCallerObject)
			{
				Log.TraceExpectedInfo(((Object)this).name + ": had NotifyOfPreHurt called by the same hurtPatchCallerObject when we were in the process of hurting already? ignoring");
			}
			else
			{
				Log.TraceExpectedInfo(((Object)this).name + ": had NotifyOfPreHurt called by differing hurtPatchCallerObject when we were in the process of hurting already, ignoring");
			}
		}
		else
		{
			this.PreHurt?.Invoke(canceler, target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion);
			EnemyComponents.PreAnyEnemyHurt?.Invoke(canceler, this, target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion);
			HurtPatchCallerObject = hurtPatchCallerObject;
			InTheProcessOfHurting = true;
		}
	}

	internal void NotifyOfPostHurt(EventMethodCancelInfo cancellationInfo, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, float critMultiplier, GameObject sourceWeapon, bool tryForExplode, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion, object hurtPatchCallerObject)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		if (!InTheProcessOfHurting)
		{
			Log.TraceExpectedInfo(((Object)this).name + ": had NotifyOfPostHurt called when we were NOT in the process of hurting already, ignoring");
			return;
		}
		if (HurtPatchCallerObject != hurtPatchCallerObject)
		{
			Log.TraceExpectedInfo(((Object)this).name + ": had NotifyOfPostHurt called when we were in the process of hurting already BUT the hurtPatchCallerObject did not match, ignoring");
			return;
		}
		this.PostHurt?.Invoke(cancellationInfo, target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion);
		EnemyComponents.PostAnyEnemyHurt?.Invoke(cancellationInfo, this, target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion);
		HurtPatchCallerObject = null;
		InTheProcessOfHurting = false;
	}

	internal bool CallPreEnrage(EventMethodCancellationTracker cancellationTracker)
	{
		cancellationTracker.Reset();
		this.PreEnrage?.Invoke(cancellationTracker.GetCanceler());
		cancellationTracker.TryInvokeReimplementation();
		return cancellationTracker.ShouldRunMethod;
	}

	internal void CallPostEnrage(EventMethodCancellationTracker cancellationTracker)
	{
		this.PostEnrage?.Invoke(cancellationTracker.GetCancelInfo());
	}

	internal bool CallPreUnEnrage(EventMethodCancellationTracker cancellationTracker)
	{
		cancellationTracker.Reset();
		this.PreUnEnrage?.Invoke(cancellationTracker.GetCanceler());
		cancellationTracker.TryInvokeReimplementation();
		return cancellationTracker.ShouldRunMethod;
	}

	internal void CallPostUnEnrage(EventMethodCancellationTracker cancellationTracker)
	{
		this.PostUnEnrage?.Invoke(cancellationTracker.GetCancelInfo());
	}

	static EnemyComponents()
	{
		EnemyComponents.PreAnyEnemyHurt = null;
		EnemyComponents.PostAnyEnemyHurt = null;
		OverrideFullNameFA = new FieldAccess<EnemyIdentifier, string>("overrideFullName");
	}
}
public class EnemyRoot : MonoBehaviour
{
	public EnemyComponents Enemy { get; internal set; } = null;

	protected void Awake()
	{
	}
}
public static class GamePrefs
{
	[HarmonyPatch(typeof(PrefsManager), "Awake", new Type[] { })]
	private static class PrefsManagerAwakePatch
	{
		public static void Prefix(PrefsManager __instance)
		{
		}

		public static void Postfix(PrefsManager __instance)
		{
			_manager = __instance;
		}
	}

	private static PrefsManager _manager;

	public static PrefsManager Manager
	{
		get
		{
			if ((Object)(object)_manager == (Object)null && (Object)(object)MonoSingleton<PrefsManager>.Instance != (Object)null)
			{
				Log.ExpectedInfo("Had to get PrefsManager via PrefsManager.Instance (then cached the value)");
				_manager = MonoSingleton<PrefsManager>.Instance;
			}
			return _manager;
		}
	}
}
public class ToggleCheat : ICheat
{
	public Action<ToggleCheat> OnDisable = null;

	public Action<ToggleCheat, CheatsManager> OnEnable = null;

	private static Dictionary<string, bool> ToggleCheatStateStore = new Dictionary<string, bool>();

	public string LongName { get; private set; } = "Unnamed ToggleCheat";

	public string Identifier { get; private set; } = "ukaiw.unnamed-toggle-cheat";

	public string ButtonEnabledOverride { get; set; } = null;

	public string ButtonDisabledOverride { get; set; } = null;

	public string Icon => null;

	public bool DefaultState { get; private set; } = false;

	public StatePersistenceMode PersistenceMode => (StatePersistenceMode)1;

	public bool IsActive => ToggleCheatStateStore.GetValueOrDefault(Identifier, defaultValue: false);

	public ToggleCheat(string longName, string identifier, Action<ToggleCheat> onDisable, Action<ToggleCheat, CheatsManager> onEnable)
	{
		LongName = longName;
		Identifier = identifier;
		DefaultState = ToggleCheatStateStore.GetValueOrDefault(Identifier, defaultValue: false);
		OnDisable = onDisable;
		OnEnable = onEnable;
	}

	public void Disable()
	{
		ToggleCheatStateStore[Identifier] = false;
		OnDisable?.Invoke(this);
	}

	public void Enable(CheatsManager manager)
	{
		ToggleCheatStateStore[Identifier] = true;
		OnEnable?.Invoke(this, manager);
	}
}
namespace Nyxpiri
{
	public class ObjPool<T> where T : class, new()
	{
		public Func<T> ConstructObject = null;

		public Action<T> PrepareObject = delegate
		{
		};

		public Action<T> UnprepareObject = delegate
		{
		};

		public Action<T> DestructObject = delegate
		{
		};

		private Stack<int> _FreeList = new Stack<int>();

		private T[] Array = new T[0];

		public int Size => Array.Length;

		public int NumFree => _FreeList.Count;

		public int NumTaken => Array.Length - _FreeList.Count;

		public ObjPool(Func<T> constructObject, Action<T> destructObject)
		{
			Assert.IsNotNull((object)constructObject, "");
			DestructObject = destructObject;
			ConstructObject = constructObject;
		}

		public void Clear()
		{
			T[] array = Array;
			foreach (T obj in array)
			{
				DestructObject(obj);
			}
			Array = new T[0];
			_FreeList.Clear();
		}

		public void EnsureSize(int size)
		{
			if (Array.Length < size)
			{
				T[] array = Array;
				Array = new T[size];
				for (int i = 0; i < array.Length; i++)
				{
					Array[i] = array[i];
				}
				for (int j = array.Length; j < Array.Length; j++)
				{
					Array[j] = ConstructObject();
					_FreeList.Push(j);
					Assert.IsNotNull((object)Array[j], "");
				}
			}
		}

		public (T, int) TakeUnsafe()
		{
			if (_FreeList.Count == 0)
			{
				EnsureSize(Size * 2);
			}
			int num = _FreeList.Pop();
			T val = Array[num];
			PrepareObject?.Invoke(val);
			return (val, num);
		}

		public PoolObject<T> Take()
		{
			return new PoolObject<T>(this, TakeUnsafe());
		}

		public void Return((T, int) element)
		{
			UnprepareObject?.Invoke(element.Item1);
			_FreeList.Push(element.Item2);
		}

		public void Return(PoolObject<T> obj)
		{
			obj.Dispose();
		}

		~ObjPool()
		{
			Clear();
		}
	}
	public class PoolObject<T> : IDisposable where T : class, new()
	{
		private ObjPool<T> Pool;

		private (T, int) Element;

		public T Obj => Element.Item1;

		public T Value => Obj;

		public bool IsValid => Pool != null;

		internal PoolObject(ObjPool<T> pool, (T, int) element)
		{
			Pool = pool;
			Element = element;
		}

		public void Dispose()
		{
			if (IsValid)
			{
				Pool.Return(Element);
				Element = (null, -1);
				Pool = null;
			}
		}

		~PoolObject()
		{
			Dispose();
		}
	}
	public class RegistrationTracker
	{
		private bool _Registered = false;

		public Func<bool> RegisterAction { private get; set; } = null;

		public Func<bool> UnregisterAction { private get; set; } = null;

		public bool Registered
		{
			get
			{
				return _Registered;
			}
			private set
			{
				_Registered = value;
			}
		}

		public RegistrationTracker(Func<bool> registerAction, Func<bool> unregisterAction)
		{
			RegisterAction = registerAction;
			UnregisterAction = unregisterAction;
		}

		public void Register()
		{
			if (!Registered && (RegisterAction?.Invoke() ?? false))
			{
				_Registered = true;
			}
		}

		public void Unregister()
		{
			if (Registered && (UnregisterAction?.Invoke() ?? false))
			{
				_Registered = false;
			}
		}
	}
}
namespace Nyxpiri.Unity.Collections
{
	public static class CollectionSorting
	{
		public static void Shuffle<T>(this IList<T> list)
		{
			for (int i = 0; i < list.Count; i++)
			{
				int index = Random.Range(0, list.Count - 1);
				T item = list[i];
				list.RemoveAt(i);
				list.Insert(index, item);
			}
		}
	}
}
namespace Nyxpiri.Collections.Generic
{
	public class ReserveList<T> : IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
	{
		private struct ReserveListElem
		{
			public T Obj;

			public bool Free;

			public ReserveListElem(T obj, bool free)
			{
				Obj = obj;
				Free = free;
			}
		}

		private List<ReserveListElem> _List;

		private Stack<int> _FreeList;

		public int Count { get; private set; } = 0;

		public int SoftCapacity => _List.Count;

		public int Capacity => _List.Capacity;

		public T this[int index]
		{
			get
			{
				if (_List[index].Free)
				{
					throw new IndexOutOfRangeException("Attempt to access an index that was in the _FreeList");
				}
				return _List[index].Obj;
			}
			set
			{
				if (_List[index].Free)
				{
					throw new IndexOutOfRangeException("Attempt to access an index that was in the _FreeList");
				}
				ReserveListElem value2 = _List[index];
				value2.Obj = value;
				_List[index] = value2;
			}
		}

		~ReserveList()
		{
		}

		public ReserveList()
		{
			_List = new List<ReserveListElem>();
			_FreeList = new Stack<int>();
		}

		public ReserveList(int capacity)
		{
			_List = new List<ReserveListElem>(capacity);
			_FreeList = new Stack<int>(capacity);
		}

		public int Add(T elem)
		{
			Count++;
			int count;
			if (_FreeList.Count == 0)
			{
				count = _List.Count;
				_List.Add(new ReserveListElem(elem, free: false));
				return count;
			}
			count = _FreeList.Pop();
			_List[count] = new ReserveListElem(elem, free: false);
			return count;
		}

		public void RemoveAt(int idx)
		{
			if (_List[idx].Free)
			{
				throw new IndexOutOfRangeException("Attempt to free already freed index");
			}
			Count--;
			_List[idx] = new ReserveListElem(default(T), free: true);
			_FreeList.Push(idx);
		}

		public bool IsIndexValid(int idx)
		{
			if (idx < 0)
			{
				return false;
			}
			if (_List.Count <= idx)
			{
				return false;
			}
			if (_List[idx].Free)
			{
				return false;
			}
			return true;
		}

		public IEnumerator<T> GetEnumerator()
		{
			foreach (ReserveListElem elem in _List)
			{
				if (!elem.Free)
				{
					yield return elem.Obj;
				}
			}
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
}
namespace Nyxpiri.ULTRAKILL.NyxLib
{
	public class ExternalAssetManager(string path)
	{
		public string Path = path;

		private Dictionary<string, ExternalAsset> _assets = new Dictionary<string, ExternalAsset>();

		public T GetAsset<T>(string subPath) where T : ExternalAsset, new()
		{
			if (_assets.TryGetValue(subPath, out var value) && value is T result)
			{
				return result;
			}
			T val = new T();
			if (val is IManagerAwareAsset managerAwareAsset)
			{
				managerAwareAsset.AssetManager = this;
			}
			val.Path = path + "/" + subPath;
			_assets[subPath] = val;
			return val;
		}

		public void Reload()
		{
			List<ExternalAsset> list = _assets.Values.ToList();
			foreach (ExternalAsset item in list)
			{
				item.MarkUnloaded();
			}
			foreach (ExternalAsset item2 in list)
			{
				if (item2.TryLoad())
				{
					Log.Message($"Reloaded asset {item2}");
				}
				else
				{
					Log.Error($"Reload asset {item2} failed!");
				}
			}
		}
	}
	public interface IManagerAwareAsset
	{
		ExternalAssetManager AssetManager { get; internal set; }
	}
	public abstract class ExternalAsset
	{
		public string Path = null;

		private bool _loaded = false;

		public bool Loaded => _loaded;

		public void MarkUnloaded()
		{
			_loaded = false;
		}

		public bool TryLoad()
		{
			if (Loaded)
			{
				return Loaded;
			}
			_loaded = Load();
			return Loaded;
		}

		public override string ToString()
		{
			return "(" + GetType().Name + " @ '" + Path + "')";
		}

		public abstract bool Load();
	}
	public class TextureAsset : ExternalAsset
	{
		private Texture2D _texture = null;

		private FilterMode FilterMode = (FilterMode)0;

		public Texture2D Texture
		{
			get
			{
				if (!TryLoad())
				{
					Log.Error("Loading Texture at '" + Path + "' failed");
				}
				return _texture;
			}
		}

		public override bool Load()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_texture == (Object)null)
			{
				ImageLoader.TryLoadImageOrDefault(Path, out _texture, out var successfullyLoaded);
				if (!successfullyLoaded)
				{
					return false;
				}
			}
			if ((Object)(object)_texture == (Object)null)
			{
				return false;
			}
			((Texture)_texture).filterMode = FilterMode;
			return ImageLoader.TryLoadImage(_texture, Path);
		}
	}
	public class AnimScriptAsset : ExternalAsset
	{
		private Animation _animation = null;

		public Animation Animation
		{
			get
			{
				TryLoad();
				return _animation;
			}
		}

		public override bool Load()
		{
			if ((Object)(object)_animation == (Object)null)
			{
				_animation = ScriptableObject.CreateInstance<Animation>();
			}
			if ((Object)(object)_animation == (Object)null)
			{
				return false;
			}
			if (!File.Exists(Path))
			{
				Log.Error("failed to load animscript asset due file at " + Path + " not existing");
				return false;
			}
			try
			{
				_animation.ParseScript(File.ReadAllText(Path));
			}
			catch (FormatException ex)
			{
				Log.Error($"failed to parse animscript due to format exception: {ex.Message}\nfull exception info{ex}");
				return false;
			}
			return true;
		}
	}
	public class ObjAsset : ExternalAsset
	{
		private List<Mesh> _meshes = new List<Mesh>();

		public IReadOnlyList<Mesh> Meshes
		{
			get
			{
				TryLoad();
				return _meshes;
			}
		}

		public Mesh FindMesh(string meshName)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			foreach (Mesh mesh in Meshes)
			{
				if (((Object)mesh).name == meshName)
				{
					return mesh;
				}
			}
			Log.Message("ExternalAsset making a new " + meshName);
			Mesh val = new Mesh();
			((Object)val).name = meshName;
			_meshes.Add(val);
			return val;
		}

		public override bool Load()
		{
			if (!File.Exists(Path))
			{
				Log.Error("Failed to load mesh at path " + Path + " due to file not existing");
				ClearMeshes();
				return false;
			}
			try
			{
				ObjLoader.LoadMeshes(File.ReadAllText(Path), _meshes);
				return true;
			}
			catch (Exception arg)
			{
				ClearMeshes();
				Log.Error($"failed to load mesh at '{Path}', exception: {arg}");
				return false;
			}
		}

		private void ClearMeshes()
		{
			foreach (Mesh mesh in _meshes)
			{
				Object.Destroy((Object)(object)mesh);
			}
			_meshes.Clear();
		}
	}
	public class MaterialAsset : ExternalAsset, IManagerAwareAsset
	{
		private Material _material = null;

		public Material Material
		{
			get
			{
				if (!base.Loaded)
				{
					TryLoad();
				}
				return _material;
			}
		}

		public ExternalAssetManager AssetManager { get; set; }

		public override bool Load()
		{
			if ((Object)(object)_material == (Object)null)
			{
				_material = Materials.CreateLitMaterial();
			}
			if ((Object)(object)_material == (Object)null)
			{
				return false;
			}
			if (!File.Exists(Path))
			{
				Log.Error("Failed to load material at path " + Path + " due to file not existing");
				return false;
			}
			try
			{
				string jsonText = File.ReadAllText(Path);
				if (!JsonMaterial.ApplyTo(_material, AssetManager, jsonText))
				{
					return false;
				}
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to load material at path {Path}, exception caught {arg}");
			}
			return true;
		}
	}
	public class BalanceComposite
	{
		public const string DefaultSheetID = "default";

		private List<string> SheetPriorities = new List<string>();

		private Dictionary<string, BalanceSheet> _sheets = new Dictionary<string, BalanceSheet>();

		private Dictionary<string, BalanceEntry> _entries = new Dictionary<string, BalanceEntry>();

		private BalanceSheet _defaultSheet = null;

		public SerializerSet Serializers { protected get; set; } = null;

		public IReadOnlyDictionary<string, BalanceSheet> Sheets => _sheets;

		public BalanceComposite(SerializerSet serializers)
		{
			_defaultSheet = CreateSheet("default");
			Serializers = serializers;
		}

		public BalanceEntryRef<T> AddEntry<T>(string id, T defaultValue, string description) where T : struct
		{
			BalanceEntry balanceEntry = new BalanceEntry(id, description, defaultValue);
			BalanceEntryRef<T> result = new BalanceEntryRef<T>(balanceEntry);
			_entries.Add(id, balanceEntry);
			_defaultSheet.SetValue<T>(id, defaultValue);
			return result;
		}

		public BalanceEntryRef<T> GetEntry<T>(string id)
		{
			return new BalanceEntryRef<T>(_entries[id]);
		}

		public BalanceSheet CreateSheet(string id)
		{
			BalanceSheet balanceSheet = new BalanceSheet(_entries);
			_sheets.Add(id, balanceSheet);
			foreach (KeyValuePair<string, BalanceEntry> entry in _entries)
			{
				balanceSheet.SetValue(typeof(object), entry.Key, null);
			}
			SheetPriorities.Add(id);
			EvaluatePriorities();
			return balanceSheet;
		}

		private void EvaluatePriorities()
		{
			foreach (KeyValuePair<string, BalanceEntry> entry in _entries)
			{
				BalanceSheet sheet = null;
				string text = null;
				for (int i = 0; i < SheetPriorities.Count; i++)
				{
					text = SheetPriorities[i];
					sheet = _sheets[text];
					if (sheet.GetValue(entry.Key, out var value) && value != null)
					{
						break;
					}
				}
				Assert.IsNotNull((object)sheet, "");
				entry.Value.GetterFunc = () => sheet.GetValue(entry.Key);
				entry.Value.ValueSource = text;
			}
		}
	}
	public class BalanceDirectory
	{
		public BalanceComposite Composite = null;

		public string Path = null;

		public BalanceDirectory(BalanceComposite composite, string path)
		{
			Assert.IsFalse(string.IsNullOrWhiteSpace(path));
			Assert.IsNotNull((object)Composite, "");
			Composite = composite;
			Path = path;
		}

		public void Load()
		{
			if (!Directory.Exists(Path))
			{
				Directory.CreateDirectory(Path);
			}
			IEnumerable<string> enumerable = Directory.EnumerateFiles(Path);
			foreach (string item in enumerable)
			{
				if (!item.EndsWith(".balancesheet"))
				{
					continue;
				}
				string text = item.Substring(item.LastIndexOf('.') - 1, item.Length).Substring(item.LastIndexOfAny(new char[2] { '/', '\\' }));
				if (!string.IsNullOrWhiteSpace(text))
				{
					string data = File.ReadAllText(item);
					string text2 = "custom." + text;
					if (!Composite.Sheets.TryGetValue(text2, out var value))
					{
						value = Composite.CreateSheet(text2);
					}
					try
					{
						value.Deserialize(data);
					}
					catch (Exception arg)
					{
						Log.Error($"exception thrown whilst parsing BalanceSheet! {arg}");
					}
				}
			}
		}
	}
	[Serializable]
	public class BalanceEntry
	{
		public string Description;

		public Func<object> GetterFunc = null;

		public string ValueSource = "";

		public string ID { get; private set; }

		public object DefaultValue { get; private set; }

		public Type Type
		{
			get
			{
				Assert.IsNotNull(DefaultValue);
				return DefaultValue.GetType();
			}
		}

		public object Value => GetterFunc?.Invoke();

		public bool IsValid => GetterFunc != null;

		public BalanceEntry(string id, string description, object defaultValue)
		{
			ID = id;
			Description = description;
			DefaultValue = defaultValue;
			ResetToDefaultValue();
		}

		public void ResetToDefaultValue()
		{
			GetterFunc = GetDefaultValue;
		}

		private object GetDefaultValue()
		{
			return DefaultValue;
		}
	}
	public struct BalanceEntryRef<T>
	{
		private BalanceEntryRef _rawRef;

		public bool IsValid => _rawRef.IsValid;

		public readonly T Value => (T)_rawRef.Value;

		public BalanceEntryRef(BalanceEntry entry)
		{
			_rawRef = default(BalanceEntryRef);
			Assert.IsTrue(entry.Type == typeof(T));
			_rawRef = new BalanceEntryRef(entry);
		}

		public readonly BalanceEntryRef ToRawReference()
		{
			return _rawRef;
		}
	}
	[Serializable]
	public struct BalanceEntryRef
	{
		[SerializeField]
		[SerializeReference]
		private readonly BalanceEntry _entry;

		public readonly bool IsValid => _entry != null && _entry.IsValid;

		public readonly object Value
		{
			get
			{
				object value = _entry.Value;
				Assert.IsNotNull(value);
				return value;
			}
		}

		public BalanceEntryRef(BalanceEntry entry)
		{
			_entry = entry;
		}
	}
	public class BalanceSheet
	{
		public SerializerSet Serializers = null;

		private IReadOnlyDictionary<string, BalanceEntry> Entries = null;

		private Dictionary<string, object> _values = new Dictionary<string, object>();

		public BalanceSheet(IReadOnlyDictionary<string, BalanceEntry> entries)
		{
			Entries = entries;
		}

		public void SetValue(Type type, string id, object value)
		{
			if (!Entries.TryGetValue(id, out var value2))
			{
				throw new KeyNotFoundException();
			}
			Assert.IsTrue(value2.Type == type || value == null);
			_values[id] = value;
		}

		public void SetValue<T>(string id, T? value) where T : struct
		{
			if (!Entries.TryGetValue(id, out var value2))
			{
				throw new KeyNotFoundException();
			}
			Assert.IsTrue(value2.Type == typeof(T) || !value.HasValue);
			_values[id] = value;
		}

		public object GetValue(string id)
		{
			if (!_values.TryGetValue(id, out var value))
			{
				return null;
			}
			return value;
		}

		public bool GetValue(string id, out object value)
		{
			if (!_values.TryGetValue(id, out value))
			{
				return false;
			}
			return true;
		}

		public string Serialize()
		{
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = new StringBuilder();
			foreach (KeyValuePair<string, object> value2 in _values)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append("\n");
				}
				object value = value2.Value;
				BalanceEntry balanceEntry = Entries[value2.Key];
				Type type = balanceEntry.Type;
				string text = Serializers.Serialize(value);
				stringBuilder2.Clear();
				stringBuilder2.Append("# " + balanceEntry.Description + "\n");
				stringBuilder2.Append("# type: " + balanceEntry.Type.FullName);
				if (text == null)
				{
					throw new NotImplementedException();
				}
				stringBuilder.Append($"{stringBuilder2}\n{balanceEntry.ID} = {text}\n");
			}
			return stringBuilder.ToString();
		}

		public void Deserialize(string data)
		{
			StringQueue stringQueue = new StringQueue(data);
			char[] spaces = new char[2] { ' ', '\t' };
			while (!stringQueue.Finished)
			{
				string text = stringQueue.PopUntil(new <>z__ReadOnlySingleElementList<char>('\n'), out var _);
				text = text.TrimStart(spaces);
				if (text.StartsWith('#'))
				{
					continue;
				}
				StringQueue stringQueue2 = new StringQueue(text);
				char? stopper2;
				string text2 = stringQueue2.PopUntil(new <>z__ReadOnlySingleElementList<char>('='), out stopper2).Trim(spaces);
				if (text2.Any((char c) => spaces.Contains(c)))
				{
					Log.Warning("BalanceSheet line '" + text + "' seemingly contains invalid variable id due to spaces being in the variable.");
					continue;
				}
				string text3 = stringQueue2.GetRemaining().Trim(spaces);
				if (!Entries.TryGetValue(text2, out var value))
				{
					Log.Warning("Unknown BalanceSheet entry '" + text2 + "' with value '" + text3 + "'");
					continue;
				}
				object value2;
				try
				{
					value2 = Serializers.Deserialize(value.Type, text3);
				}
				catch (Exception ex)
				{
					Log.Error($"Error reading value string: '{text3}' for variable named: '{text2}'. {ex.Message}\nFull Line: {text}\nFull Exception: {ex}");
					continue;
				}
				SetValue(value.Type, text2, value2);
			}
		}
	}
	[Serializable]
	public struct BalanceFloat
	{
		public bool UseBase;

		public float BaseValue;

		[SerializeField]
		private BalanceEntryRef _ref;

		public float Value => (UseBase || !_ref.IsValid) ? BaseValue : ((float)_ref.Value);

		public BalanceFloat(BalanceEntryRef<float> reference)
		{
			UseBase = false;
			BaseValue = 0f;
			_ref = reference.ToRawReference();
		}
	}
	[Serializable]
	public struct BalanceBool
	{
		public bool UseBase;

		public bool BaseValue;

		[SerializeField]
		private readonly BalanceEntryRef _ref;

		public readonly bool Value => (UseBase || !_ref.IsValid) ? BaseValue : ((bool)_ref.Value);

		public BalanceBool(BalanceEntryRef<bool> reference)
		{
			UseBase = false;
			BaseValue = false;
			_ref = reference.ToRawReference();
		}
	}
	public class SerializerSet
	{
		private Dictionary<Type, Func<object, string>> _serializers = new Dictionary<Type, Func<object, string>>();

		private Dictionary<Type, Func<string, object>> _deserializers = new Dictionary<Type, Func<string, object>>();

		public string Serialize(object value)
		{
			if (!_serializers.TryGetValue(value.GetType(), out var value2))
			{
				return null;
			}
			return value2(value);
		}

		public object Deserialize(Type type, string data)
		{
			if (!_deserializers.TryGetValue(type, out var value))
			{
				return null;
			}
			return value(data);
		}

		public void Add<T>(Func<T, string> serializer, Func<string, T?> deserializer) where T : struct
		{
			Assert.IsFalse(ContainsType<T>());
			Assert.IsNotNull((object)serializer, "");
			Assert.IsNotNull((object)deserializer, "");
			Add(typeof(T), (object obj) => (obj != null) ? serializer((T)obj) : "null", (string data) => (data != "null") ? deserializer(data) : ((T?)null));
		}

		public void Add(Type type, Func<object, string> serializer, Func<string, object> deserializer)
		{
			Assert.IsFalse(ContainsType(type));
			Assert.IsNotNull((object)type, "");
			Assert.IsNotNull((object)serializer, "");
			Assert.IsNotNull((object)deserializer, "");
			_serializers.Add(type, serializer);
			_deserializers.Add(type, deserializer);
		}

		public bool ContainsType<T>()
		{
			return ContainsType(typeof(T));
		}

		public bool ContainsType(Type type)
		{
			if (!_serializers.TryGetValue(type, out var value))
			{
				return false;
			}
			if (value == null)
			{
				return false;
			}
			return true;
		}
	}
	public static class CompositeManager
	{
		public static SerializerSet Serializers = new SerializerSet();

		private static Dictionary<string, BalanceComposite> _composites = new Dictionary<string, BalanceComposite>();

		public static T CreateComposite<T>(string id) where T : BalanceComposite, new()
		{
			T val = new T();
			_composites[id] = val;
			val.Serializers = Serializers;
			return val;
		}
	}
	public static class StandardSerializerSet
	{
		public static void AddStandardSerializers(this SerializerSet set)
		{
			set.Add((float val) => val.ToString(CultureInfo.InvariantCulture).TrimEnd('0'), delegate(string data)
			{
				if (!float.TryParse(data, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					throw new FormatException("malformed float format '" + data + "'");
				}
				return result;
			});
			set.Add((bool val) => val ? "true" : "false", delegate(string data)
			{
				if (data == "true")
				{
					return true;
				}
				if (!(data == "false"))
				{
					throw new ArgumentException();
				}
				return false;
			});
		}
	}
	public static class Cheats
	{
		public delegate void ReadyForCheatRegistrationEventHandler(CheatsManager cheatsManager);

		[HarmonyPatch(typeof(CheatsManager), "Start", new Type[] { })]
		private static class CheatsManagerStartPatch
		{
			public static void Prefix(CheatsManager __instance)
			{
				_manager = __instance;
				MaybeWaitForCheatRegistration();
			}

			public static void Postfix(CheatsManager __instance)
			{
				TryRegisterCheats();
			}
		}

		[HarmonyPatch(typeof(TeleportCheat), "Teleport")]
		private static class TeleportCheatTeleportPatch
		{
			public static void Prefix(TeleportCheat __instance, Transform target)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				if (Enabled)
				{
					PlayerActivator val = Object.FindAnyObjectByType<PlayerActivator>();
					if ((Object)(object)val != (Object)null)
					{
						((Component)val).transform.position = target.position;
					}
				}
			}

			public static void Postfix(TeleportCheat __instance, Transform target)
			{
			}
		}

		private static CheatsManager _manager;

		public const string RadiantAllEnemies = "nyxpiri.radiant-all-enemies";

		public const string Immortality = "nyxpiri.immortality";

		public const string SandAllEnemies = "nyxpiri.sand-all-enemies";

		public const string OverrideCybergrindStartingWave = "nyxpiri.override-cybergrind-starting-wave";

		public const string DisableStops = "nyxpiri.disable-stops";

		public const string DisableSlowdown = "nyxpiri.disable-slowdown";

		public const string UltraStop = "nyxpiri.ultra-stop";

		public const string ShortHitStop = "nyxpiri.short-hit-stop";

		public const string PlayCleanMusicWithBattle = "nyxpiri.clean-music-with-battle";

		public const string AlwaysBattleMusic = "nyxpiri.always-battle-music";

		public const string LogEIDInfo = "nyxpiri.dev.log-eid-info";

		private static bool WaitingForCheatRegistration;

		public static CheatsManager Manager
		{
			get
			{
				if ((Object)(object)_manager == (Object)null && (Object)(object)MonoSingleton<CheatsManager>.Instance != (Object)null)
				{
					Log.ExpectedInfo("Had to get CheatsManager via CheatsManager.Instance (then cached the value)");
					_manager = MonoSingleton<CheatsManager>.Instance;
				}
				return _manager;
			}
		}

		public static bool Enabled => MonoSingleton<CheatsController>.Instance?.cheatsEnabled ?? false;

		public static event ReadyForCheatRegistrationEventHandler ReadyForCheatRegistration;

		public static bool IsCheatEnabled(string cheatID)
		{
			if (!Enabled)
			{
				return false;
			}
			return Manager.GetCheatState(cheatID);
		}

		public static bool IsCheatDisabled(string cheatID)
		{
			return !IsCheatEnabled(cheatID);
		}

		public static void Initialize()
		{
			SceneEvents.OnSceneLoad += OnSceneWasLoaded;
			UpdateEvents.OnUpdate += LateUpdate;
			PlayerEvents.PredictedDeath += PlayerPredictedDeath;
		}

		private static void PlayerPredictedDeath(EventMethodCanceler canceler, PlayerComponents player, int damage)
		{
			if (IsCheatEnabled("nyxpiri.immortality"))
			{
				canceler.CancelMethod();
			}
		}

		private static void LateUpdate()
		{
			TryRegisterCheats();
		}

		private static void TryRegisterCheats()
		{
			if (!((Object)(object)MonoSingleton<CheatsController>.Instance == (Object)null) && WaitingForCheatRegistration && !((Object)(object)Manager == (Object)null))
			{
				if (Manager.GetCheatState("nyxpiri.radiant-all-enemies"))
				{
					OptionsManager.forceRadiance = true;
				}
				if (Manager.GetCheatState("nyxpiri.sand-all-enemies"))
				{
					OptionsManager.forceSand = true;
				}
				WaitingForCheatRegistration = false;
				RegisterCheats();
			}
		}

		private static void OnSceneWasLoaded(Scene scene, string levelName, string unitySceneName)
		{
			MaybeWaitForCheatRegistration();
		}

		private static void MaybeWaitForCheatRegistration()
		{
			if (!((Object)(object)Manager == (Object)null))
			{
				WaitingForCheatRegistration = Manager.GetCheatInstance<ToggleCheat>() == null;
			}
		}

		private static void RegisterCheats()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			if (Options.RegisterHideCheatsStatusCheat.Value)
			{
				Manager.RegisterCheat((ICheat)new HideCheatsStatus(), "meta");
			}
			if (Options.RegisterForceNextWaveCheat.Value)
			{
				Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Force Next Wave", "nyxpiri.force-next-cybergrind-wave", delegate
				{
				}, delegate
				{
					Manager.DisableCheat("nyxpiri.force-next-cybergrind-wave");
					if (Cybergrind.IsActive && Cybergrind.IsInCybergrindLevel)
					{
						((Component)Cybergrind.EndlessGrid).GetComponent<ActivateNextWave>().deadEnemies = 99999;
					}
				}), "CYBERGRIND");
			}
			if (Options.RegisterOverrideCybergrindStartingWaveCheat.Value)
			{
				Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Override Starting Wave", "nyxpiri.override-cybergrind-starting-wave", delegate
				{
				}, delegate
				{
				}), "CYBERGRIND");
			}
			Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Radiant All Enemies", "nyxpiri.radiant-all-enemies", delegate
			{
			}, delegate
			{
			}), "SELF SABOTAGE");
			if (Options.RegisterSandAllEnemiesCheat.Value)
			{
				Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Sand All Enemies", "nyxpiri.sand-all-enemies", delegate
				{
					OptionsManager.forceSand = false;
				}, delegate
				{
					OptionsManager.forceSand = true;
				}), "SELF SABOTAGE");
			}
			if (Options.RegisterImmortalityCheat.Value)
			{
				Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Immortality", "nyxpiri.immortality", delegate
				{
				}, delegate
				{
				}), "I FORGOT");
			}
			Cheats.ReadyForCheatRegistration?.Invoke(Manager);
			Manager.RebuildMenu();
		}
	}
	[HarmonyPatch(typeof(CheckPoint), "ActivateCheckPoint", new Type[] { })]
	internal static class CheckpointGetPatch
	{
		public static void Prefix(CheckPoint __instance)
		{
		}

		public static void Postfix(CheckPoint __instance)
		{
		}
	}
	public class StringQueue
	{
		private int Index = 0;

		private string Str = null;

		public bool Finished => Str.Length <= Index;

		public StringQueue(string str)
		{
			Str = str;
		}

		public char Peek()
		{
			return Str[Index];
		}

		public char Pop()
		{
			char result = Str[Index];
			Index++;
			return result;
		}

		public string PopUntil(IReadOnlyCollection<char> chars, out char? stopper)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stopper = null;
			while (!Finished)
			{
				char value = Peek();
				if (chars.Contains(value))
				{
					stopper = value;
					break;
				}
				stringBuilder.Append(Pop());
			}
			return stringBuilder.ToString();
		}

		public void Reset(string str)
		{
			Str = str;
		}

		public string GetRemaining()
		{
			string str = Str;
			int index = Index;
			return str.Substring(index, str.Length - index);
		}
	}
	public struct CommandScope
	{
		private HashSet<char> _Flags;

		private Dictionary<string, CommandScope> _Scopes;

		private List<string> _Parameters;

		public string Name { get; private set; }

		public IReadOnlyCollection<char> Flags => _Flags;

		public IReadOnlyDictionary<string, CommandScope> Scopes => _Scopes;

		public IReadOnlyList<string> Parameters => _Parameters;

		public bool HasFlag(char flag)
		{
			return Flags.Contains(flag);
		}

		public bool HasScope(string scopeName)
		{
			return Scopes.ContainsKey(scopeName);
		}

		public void HaveScopeOrThrow(string scopeName, Exception e)
		{
			if (!HasScope(scopeName))
			{
				throw e;
			}
		}

		public bool HasParam(string paramStr)
		{
			return Parameters.Contains(paramStr);
		}

		public bool HasNumParams(int num)
		{
			return Parameters.Count >= num;
		}

		public void HaveNumParamsOrThrow(int num, Exception e)
		{
			if (!HasNumParams(num))
			{
				throw e;
			}
		}

		public bool HasChain(string chainStr)
		{
			StringQueue stringQueue = new StringQueue(chainStr);
			bool flag = false;
			CommandScope commandScope = this;
			while (!stringQueue.Finished)
			{
				char? stopper;
				string text = stringQueue.PopUntil(new <>z__ReadOnlyArray<char>(new char[2] { '/', ':' }), out stopper);
				if (text.Length > 0)
				{
					if (!flag)
					{
						if (int.TryParse(text, out var result))
						{
							if (!commandScope.HasNumParams(result))
							{
								return false;
							}
							return true;
						}
						throw new FormatException("invalid int formatting on '" + text + "', in chainStr " + chainStr);
					}
					if (!commandScope.Scopes.TryGetValue(text, out var value))
					{
						return false;
					}
					commandScope = value;
				}
				flag = stopper.HasValue && stopper.Value == '/';
				stringQueue.Pop();
			}
			return true;
		}

		public void HaveChainOrThrow(string chainStr, Exception e)
		{
			if (!HasChain(chainStr))
			{
				throw e;
			}
		}

		public CommandScope(string name)
		{
			Name = null;
			_Flags = null;
			_Scopes = null;
			_Parameters = null;
			Name = name;
			_Parameters = new List<string>();
			_Flags = new HashSet<char>();
			_Scopes = new Dictionary<string, CommandScope>();
		}

		public CommandScope(StringQueue strQueue, string name)
		{
			Name = null;
			_Flags = null;
			_Scopes = null;
			_Parameters = null;
			Name = name;
			_Parameters = new List<string>();
			_Flags = new HashSet<char>();
			_Scopes = new Dictionary<string, CommandScope>();
			ParseScope(strQueue);
		}

		public void ParseScope(StringQueue strQueue)
		{
			bool buildingFlags = false;
			bool flag = false;
			StringBuilder currentToken = new StringBuilder();
			CommandScope self = this;
			Action addFlags = delegate
			{
				string text = currentToken.ToString();
				string text2 = text;
				foreach (char item in text2)
				{
					self._Flags.Add(item);
				}
			};
			Action action = delegate
			{
				if (currentToken.Length != 0)
				{
					StringBuilder stringBuilder = currentToken;
					if (stringBuilder[stringBuilder.Length - 1] == ':')
					{
						currentToken.Remove(currentToken.Length - 1, 1);
						if (!self._Scopes.ContainsKey(currentToken.ToString()))
						{
							self._Scopes[currentToken.ToString()] = new CommandScope(strQueue, currentToken.ToString());
						}
						else
						{
							self._Scopes[currentToken.ToString()].ParseScope(strQueue);
						}
						currentToken.Clear();
					}
					else
					{
						if (!buildingFlags)
						{
							self._Parameters.Add(currentToken.ToString());
						}
						else
						{
							buildingFlags = false;
							addFlags();
						}
						currentToken.Clear();
					}
				}
			};
			while (!strQueue.Finished)
			{
				char c = strQueue.Peek();
				switch (c)
				{
				case '\t':
				case '\n':
				case ' ':
					strQueue.Pop();
					action();
					if (!flag && (_Parameters.Count > 0 || Scopes.Count > 0 || _Flags.Count > 0))
					{
						return;
					}
					break;
				case '{':
					if (currentToken.Length > 0)
					{
						throw new FormatException("Unexpected '{' after first character of token in CommandScope string");
					}
					flag = true;
					strQueue.Pop();
					break;
				case '}':
					if (flag)
					{
						strQueue.Pop();
						action();
						return;
					}
					strQueue.Pop();
					action();
					if (_Parameters.Count > 0 || Scopes.Count > 0 || _Flags.Count > 0)
					{
						return;
					}
					throw new FormatException("Unexpected '}' in non-bracket-scope CommandScope by name '" + Name + "'");
				case '~':
					strQueue.Pop();
					if (currentToken.Length == 0)
					{
						buildingFlags = true;
					}
					else
					{
						currentToken.Append(c);
					}
					break;
				default:
					strQueue.Pop();
					currentToken.Append(c);
					break;
				}
			}
			action();
		}

		public string ToDebugString(int depth = 0)
		{
			StringBuilder stringBuilder = new StringBuilder(512);
			StringBuilder stringBuilder2 = new StringBuilder(depth + 1);
			stringBuilder2.Append('\n');
			for (int i = 0; i < depth; i++)
			{
				stringBuilder2.Append('\t');
			}
			string text = stringBuilder2.ToString();
			stringBuilder.Append("Flags: -");
			foreach (char flag in Flags)
			{
				stringBuilder.Append(flag);
			}
			stringBuilder.Append(text);
			stringBuilder.Append("Parameters:");
			foreach (string parameter in Parameters)
			{
				stringBuilder.Append(text);
				stringBuilder.Append("\t" + parameter);
			}
			stringBuilder.Append(text);
			stringBuilder.Append("Scopes:");
			foreach (CommandScope value in Scopes.Values)
			{
				stringBuilder.Append(text);
				stringBuilder.Append("\t" + value.Name + ": {");
				stringBuilder.Append(text + "\t\t");
				stringBuilder.Append(value.ToDebugString(depth + 2) ?? "");
				stringBuilder.Append(text + "\t}");
			}
			return stringBuilder.ToString();
		}
	}
	public class Command
	{
		public IReadOnlyCollection<char> Flags => MainScope.Flags;

		public IReadOnlyList<string> Parameters => MainScope.Parameters;

		public bool HasParams => Parameters.Count > 0;

		public bool HasNoParams => !HasParams;

		public IReadOnlyDictionary<string, CommandScope> Scopes => MainScope.Scopes;

		public CommandScope MainScope { get; private set; }

		public bool HasFlag(char flag)
		{
			return MainScope.HasFlag(flag);
		}

		public bool HasScope(string scopeName)
		{
			return MainScope.HasScope(scopeName);
		}

		public void HaveScopeOrThrow(string scopeName, Exception e)
		{
			MainScope.HaveScopeOrThrow(scopeName, e);
		}

		public bool HasParam(string paramStr)
		{
			return MainScope.HasParam(paramStr);
		}

		public bool HasNumParams(int num)
		{
			return MainScope.HasNumParams(num);
		}

		public void HaveNumParamsOrThrow(int count, Exception e)
		{
			MainScope.HaveNumParamsOrThrow(count, e);
		}

		public bool HasChain(string chainStr)
		{
			return MainScope.HasChain(chainStr);
		}

		public void HaveChainOrThrow(string chainStr, Exception e)
		{
			MainScope.HaveChainOrThrow(chainStr, e);
		}

		public Command()
		{
			MainScope = default(CommandScope);
		}

		public Command(string command)
		{
			ParseCommand(command);
		}

		public void ParseCommand(string command)
		{
			StringQueue stringQueue = new StringQueue("{" + command + "}");
			MainScope = new CommandScope(stringQueue, null);
			if (!stringQueue.Finished)
			{
				string remaining = stringQueue.GetRemaining();
				throw new FormatException("Unexpected continuation of command from where it seemingly should've ended, remaining string is '" + remaining + "'");
			}
		}

		public string ToDebugString()
		{
			return MainScope.ToDebugString();
		}
	}
	public static class Cybergrind
	{
		public delegate void CybergrindPreBeginEventHandler(EventMethodCanceler canceler, EndlessGrid endlessGrid);

		public delegate void CybergrindPostBeginEventHandler(EventMethodCancelInfo cancelInfo, EndlessGrid endlessGrid);

		public delegate void CybergrindPreNextWaveEventHandler(EventMethodCanceler canceler, EndlessGrid endlessGrid);

		public delegate void CybergrindPostNextWaveEventHandler(EventMethodCancelInfo cancelInfo, EndlessGrid endlessGrid);

		[HarmonyPatch(typeof(EndlessGrid), "OnTriggerEnter", new Type[] { typeof(Collider) })]
		private static class CybergrindStartPatch
		{
			private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

			public static bool Prefix(EndlessGrid __instance, Collider other)
			{
				if (!((Component)other).CompareTag("Player"))
				{
					return true;
				}
				_cancellationTracker.Reset();
				Cybergrind.PreCybergrindBegin?.Invoke(_cancellationTracker.GetCanceler(), __instance);
				_cancellationTracker.TryInvokeReimplementation();
				return !_cancellationTracker.Cancelled;
			}

			public static void Postfix(EndlessGrid __instance, Collider other)
			{
				if (((Component)other).CompareTag("Player"))
				{
					Cybergrind.PostCybergrindBegin?.Invoke(_cancellationTracker.GetCancelInfo(), __instance);
					IsActive = true;
				}
			}
		}

		[HarmonyPatch(typeof(EndlessGrid), "Start")]
		private static class EndlessGridStartPatch
		{
			public static void Prefix(EndlessGrid __instance)
			{
			}

			public static void Postfix(EndlessGrid __instance)
			{
				EndlessGrid = __instance;
			}
		}

		[HarmonyPatch(typeof(EndlessGrid), "NextWave", null)]
		private static class EndlessGridNextWavePatch
		{
			private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

			public static bool Prefix(EndlessGrid __instance)
			{
				_cancellationTracker.Reset();
				Cybergrind.PreCybergrindNextWave?.Invoke(_cancellationTracker.GetCanceler(), __instance);
				_cancellationTracker.TryInvokeReimplementation();
				return !_cancellationTracker.Cancelled;
			}

			public static void Postfix(EndlessGrid __instance)
			{
				Cybergrind.PostCybergrindNextWave?.Invoke(_cancellationTracker.GetCancelInfo(), __instance);
			}
		}

		private static EndlessGrid _endlessGrid;

		public static EndlessGrid EndlessGrid
		{
			get
			{
				if ((Object)(object)_endlessGrid != (Object)null)
				{
					return _endlessGrid;
				}
				_endlessGrid = MonoSingleton<EndlessGrid>.Instance;
				return _endlessGrid;
			}
			set
			{
				_endlessGrid = value;
			}
		}

		public static bool IsActive { get; private set; }

		public static bool IsInCybergrindLevel => (Object)(object)EndlessGrid != (Object)null;

		public static event CybergrindPreBeginEventHandler PreCybergrindBegin;

		public static event CybergrindPostBeginEventHandler PostCybergrindBegin;

		public static event CybergrindPreNextWaveEventHandler PreCybergrindNextWave;

		public static event CybergrindPostNextWaveEventHandler PostCybergrindNextWave;

		public static void Initialize()
		{
			UpdateEvents.OnFixedUpdate += OnFixedUpdate;
			SceneEvents.OnSceneLoad += OnSceneWasLoaded;
			SceneEvents.OnSceneUnload += OnSceneWasUnloaded;
			PreCybergrindBegin += PreBegin;
		}

		private static void PreBegin(EventMethodCanceler canceler, EndlessGrid endlessGrid)
		{
			if (Cheats.Enabled && Cheats.IsCheatEnabled("nyxpiri.override-cybergrind-starting-wave"))
			{
				endlessGrid.startWave = Options.CybergrindStartingWaveOverride.Value;
			}
		}

		private static void OnSceneWasUnloaded(Scene scene, string levelName, string unitySceneName)
		{
			IsActive = false;
		}

		private static void OnSceneWasLoaded(Scene scene, string levelName, string unitySceneName)
		{
			IsActive = false;
		}

		private static void OnFixedUpdate()
		{
		}
	}
	public static class Assert
	{
		public static void IsTrue(bool condition, string additionalMsg = "")
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!condition)
			{
				throw new AssertionException("Assertion Failed: Condition was false :c; " + additionalMsg, "Assertion Failed: Condition was false :c; " + additionalMsg);
			}
		}

		public static void IsFalse(bool condition, string additionalMsg = "")
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (condition)
			{
				throw new AssertionException("Assertion Failed: Condition was true :c; " + additionalMsg, "Assertion Failed: Condition was false :c; " + additionalMsg);
			}
		}

		public static void IsNotNull(object obj, string additionalMsg = "")
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (obj == null)
			{
				if (obj == null)
				{
					throw new AssertionException("Assertion Failed: Object was null :c; " + additionalMsg, "Assertion Failed: Object was null :c; " + additionalMsg);
				}
				throw new AssertionException("Assertion Failed: Object equals null but *'is' not* null :c; " + additionalMsg, "Assertion Failed: Object was null :c; " + additionalMsg);
			}
		}

		public static void IsNull(object obj, string additionalMsg = "")
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (obj != null)
			{
				throw new AssertionException("Assertion Failed: Object is not null :c; " + additionalMsg, "Assertion Failed: Object is not null :c; " + additionalMsg);
			}
		}

		public static void IsNotNull(Object obj, string additionalMsg = "")
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (obj == (Object)null)
			{
				if (obj == null)
				{
					throw new AssertionException("Assertion Failed: Object was null :c; " + additionalMsg, "Assertion Failed: Object was null :c; " + additionalMsg);
				}
				throw new AssertionException("Assertion Failed: Object equals null but *'is' not* null :c; " + additionalMsg, "Assertion Failed: Object was null :c; " + additionalMsg);
			}
		}
	}
	public static class AssetInspecting
	{
		public unsafe static void DebugPrintMaterialProperties(this Material material)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0097: 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_00bc: Expected I4, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			Log.Message("----------========== Material Debug Print of properties for " + ((Object)material).name + " (shader: " + ((Object)material.shader).name + ") start! ==========----------");
			StringBuilder stringBuilder = new StringBuilder();
			foreach (object value in Enum.GetValues(typeof(MaterialPropertyType)))
			{
				string[] propertyNames = material.GetPropertyNames((MaterialPropertyType)value);
				foreach (string text in propertyNames)
				{
					string text2 = null;
					string text3 = null;
					MaterialPropertyType val = (MaterialPropertyType)value;
					MaterialPropertyType val2 = val;
					switch ((int)val2)
					{
					case 0:
						text2 = material.GetFloat(text).ToString();
						text3 = text2;
						break;
					case 1:
						text2 = material.GetInt(text).ToString();
						text3 = text2;
						break;
					case 2:
					{
						Vector4 vector = material.GetVector(text);
						text2 = ((object)(*(Vector4*)(&vector))/*cast due to .constrained prefix*/).ToString();
						text3 = $"[{vector.x}, {vector.y}, {vector.z}, {vector.w}]";
						break;
					}
					case 3:
						text2 = ((object)material.GetMatrix(text)/*cast due to .constrained prefix*/).ToString();
						break;
					case 4:
					{
						Texture texture = material.GetTexture(text);
						text2 = ((texture != null) ? ((Object)texture).name : null) ?? "null";
						break;
					}
					case 5:
						text2 = $"{material.GetConstantBuffer(text)}";
						break;
					case 6:
						text2 = $"{material.GetBuffer(text)}";
						break;
					}
					Log.Message($"Material Debug! There's a {value} named {text}, with a value of {text2}");
					if (text3 != null)
					{
						stringBuilder.AppendLine("\"" + text + "\": " + text3 + ",");
					}
				}
			}
			stringBuilder.Remove(stringBuilder.Length - 2, 1);
			Log.Message("------ FORMATTED VERSION START! -------");
			Log.Message($"{stringBuilder}");
			Log.Message("------ FORMATTED VERSION END! -------");
			Log.Message("----------========== Material Debug Print of properties for " + ((Object)material).name + " END! ==========----------");
		}

		public static void DebugPrintMaterialKeywords(this Material material)
		{
			//IL_0047: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Log.Message("----------========== Material Debug Print of keywords for " + ((Object)material).name + " (shader: " + ((Object)material.shader).name + ") start! ==========----------");
			LocalKeywordSpace keywordSpace = material.shader.keywordSpace;
			int num = ((LocalKeywordSpace)(ref keywordSpace)).keywordNames.Length;
			for (int i = 0; i < num; i++)
			{
				keywordSpace = material.shader.keywordSpace;
				string text = ((LocalKeywordSpace)(ref keywordSpace)).keywordNames[i];
				if (material.IsKeywordEnabled(text))
				{
					Log.Message("\"" + text + "\": true" + ((i == num - 1) ? "" : ","));
				}
				else
				{
					Log.Message("\"" + text + "\": false" + ((i == num - 1) ? "" : ","));
				}
			}
			Log.Message("----------========== Material Debug Print of keywords for " + ((Object)material).name + " END! ==========----------");
		}

		public static void DebugPrintMaterialShaderPasses(this Material material)
		{
			Log.Message("----------========== Material Debug Print of passes for " + ((Object)material).name + " (shader: " + ((Object)material.shader).name + ") start! ==========----------");
			for (int i = 0; i < material.passCount; i++)
			{
				string passName = material.GetPassName(i);
				if (material.GetShaderPassEnabled(passName))
				{
					Log.Message($"{passName} [{i}] is ENABLED");
				}
				else
				{
					Log.Message($"{passName} [{i}] is DISABLED");
				}
			}
			Log.Message($"{material.shader.passCount} shader passes");
			Log.Message("----------========== Material Debug Print of passes for " + ((Object)material).name + " END! ==========----------");
		}
	}
	public static class TryLog
	{
		public static void Action(Action action)
		{
			try
			{
				action();
			}
			catch (Exception arg)
			{
				Log.Error($"Exception caught! :c\n{arg}");
				throw;
			}
		}
	}
	[HarmonyPatch(typeof(ActivateNextWave), "AddDeadEnemy")]
	internal static class CybergrindStartPatch
	{
		public static void Prefix()
		{
		}

		public static void Postfix()
		{
		}
	}
	public enum EnemyGameplayRank
	{
		Normal,
		Miniboss,
		Boss,
		Ultraboss
	}
	public enum EnemySpeciesType
	{
		Husk,
		Machine,
		Demon,
		Angel,
		Soul,
		OrganicMachine,
		Puppet,
		Unknown,
		UltraUnknown
	}
	public enum EnemySpeciesRank
	{
		NotApplicable,
		Lesser,
		Greater,
		Supreme,
		Prime
	}
	public static class EnemyUtils
	{
		public static int NumGameplayRanks = 4;

		public static bool IsEnraged(this EnemyIdentifier eid)
		{
			if (eid.Dead)
			{
				return false;
			}
			IEnrage component = ((Component)eid).GetComponent<IEnrage>();
			return ((component != null) ? new bool?(component.isEnraged) : ((bool?)null)) ?? false;
		}

		public static bool TryEnrage(this EnemyIdentifier eid)
		{
			//IL_0064: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected I4, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Invalid comparison between Unknown and I4
			if (eid.Dead)
			{
				return false;
			}
			IEnrage component = ((Component)eid).GetComponent<IEnrage>();
			if (((component != null) ? new bool?(component.isEnraged) : ((bool?)null)) ?? false)
			{
				return false;
			}
			if (component != null)
			{
				component.Enrage();
				return true;
			}
			EnemyType enemyType = eid.enemyType;
			EnemyType val = enemyType;
			switch ((int)val)
			{
			default:
				if ((int)val != 33)
				{
					break;
				}
				if (!eid.dead)
				{
					Gutterman component4 = ((Component)eid).GetComponent<Gutterman>();
					if (component4 != null)
					{
						component4.Enrage();
					}
					return true;
				}
				return false;
			case 7:
			{
				SwordsMachine component10 = ((Component)eid).GetComponent<SwordsMachine>();
				if (component10 != null)
				{
					component10.Enrage();
				}
				return true;
			}
			case 0:
			{
				StatueBoss component7 = ((Component)eid).GetComponent<StatueBoss>();
				if (component7 != null)
				{
					component7.Enrage();
				}
				return true;
			}
			case 1:
			case 9:
			{
				Drone component3 = ((Component)eid).GetComponent<Drone>();
				if (component3 != null)
				{
					component3.Enrage();
				}
				return true;
			}
			case 8:
			{
				V2 component8 = ((Component)eid).GetComponent<V2>();
				if (component8 != null)
				{
					component8.Enrage();
				}
				return true;
			}
			case 5:
			{
				Mindflayer component9 = ((Component)eid).GetComponent<Mindflayer>();
				if (component9 != null)
				{
					component9.Enrage();
				}
				return true;
			}
			case 2:
			{
				Mass component5 = ((Component)eid).GetComponent<Mass>();
				if (!(((component5 == null) ? ((bool?)null) : ((Component)component5).GetComponentInChildren<EnemySimplifier>()?.enraged) ?? true))
				{
					Mass component6 = ((Component)eid).GetComponent<Mass>();
					if (component6 != null)
					{
						component6.Enrage();
					}
					return true;
				}
				return false;
			}
			case 4:
			{
				SpiderBody component2 = ((Component)eid).GetComponent<SpiderBody>();
				if (component2 != null)
				{
					component2.Enrage();
				}
				return true;
			}
			case 3:
			case 6:
				break;
			}
			return false;
		}

		public static bool TryUnenrage(this EnemyIdentifier eid)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected I4, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			if (eid.Dead)
			{
				return false;
			}
			EnemyType enemyType = eid.enemyType;
			EnemyType val = enemyType;
			switch ((int)val)
			{
			default:
				if ((int)val != 33)
				{
					break;
				}
				if (!eid.dead)
				{
					Gutterman component2 = ((Component)eid).GetComponent<Gutterman>();
					if (component2 != null)
					{
						component2.UnEnrage();
					}
					return true;
				}
				return false;
			case 7:
			{
				SwordsMachine component5 = ((Component)eid).GetComponent<SwordsMachine>();
				if (component5 != null)
				{
					component5.UnEnrage();
				}
				return true;
			}
			case 0:
			{
				StatueBoss component3 = ((Component)eid).GetComponent<StatueBoss>();
				if (component3 != null)
				{
					component3.UnEnrage();
				}
				return true;
			}
			case 1:
			case 9:
			{
				Drone component6 = ((Component)eid).GetComponent<Drone>();
				if (component6 != null)
				{
					component6.UnEnrage();
				}
				return true;
			}
			case 8:
			{
				V2 component7 = ((Component)eid).GetComponent<V2>();
				if (component7 != null)
				{
					component7.UnEnrage();
				}
				return true;
			}
			case 5:
			{
				Mindflayer component4 = ((Component)eid).GetComponent<Mindflayer>();
				if (component4 != null)
				{
					component4.UnEnrage();
				}
				return true;
			}
			case 4:
			{
				SpiderBody component = ((Component)eid).GetComponent<SpiderBody>();
				if (component != null)
				{
					component.UnEnrage();
				}
				return true;
			}
			case 2:
			case 3:
			case 6:
				break;
			}
			return false;
		}

		public static void ApplyDamage(this EnemyIdentifier eid, Vector3 force, Vector3 hitPoint, float multiplier, float critMultiplier, GameObject sourceWeapon, bool fromExplosion)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			eid.DeliverDamage(((Component)eid).gameObject, force, hitPoint, multiplier, false, critMultiplier, sourceWeapon, false, fromExplosion);
		}

		public static EnemyGameplayRank GetEnemyGameplayRank(this EnemyIdentifier eid)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected I4, but got Unknown
			EnemyType enemyType = eid.enemyType;
			if (1 == 0)
			{
			}
			EnemyGameplayRank result = (int)enemyType switch
			{
				37 => EnemyGameplayRank.Ultraboss, 
				23 => EnemyGameplayRank.Normal, 
				35 => EnemyGameplayRank.Boss, 
				0 => eid.isBoss ? EnemyGameplayRank.Boss : EnemyGameplayRank.Normal, 
				1 => EnemyGameplayRank.Normal, 
				26 => EnemyGameplayRank.Miniboss, 
				3 => EnemyGameplayRank.Normal, 
				30 => EnemyGameplayRank.Ultraboss, 
				17 => EnemyGameplayRank.Ultraboss, 
				16 => EnemyGameplayRank.Boss, 
				28 => EnemyGameplayRank.Boss, 
				33 => EnemyGameplayRank.Normal, 
				34 => EnemyGameplayRank.Normal, 
				2 => (!eid.isBoss) ? EnemyGameplayRank.Miniboss : EnemyGameplayRank.Boss, 
				21 => EnemyGameplayRank.Normal, 
				27 => EnemyGameplayRank.Boss, 
				4 => eid.isBoss ? EnemyGameplayRank.Boss : EnemyGameplayRank.Normal, 
				25 => EnemyGameplayRank.Ultraboss, 
				31 => EnemyGameplayRank.Normal, 
				5 => (!eid.isBoss) ? EnemyGameplayRank.Miniboss : EnemyGameplayRank.Boss, 
				11 => EnemyGameplayRank.Ultraboss, 
				18 => EnemyGameplayRank.Ultraboss, 
				32 => EnemyGameplayRank.Boss, 
				36 => EnemyGameplayRank.Normal, 
				14 => EnemyGameplayRank.Normal, 
				19 => EnemyGameplayRank.Miniboss, 
				29 => EnemyGameplayRank.Ultraboss, 
				15 => EnemyGameplayRank.Normal, 
				12 => EnemyGameplayRank.Normal, 
				13 => EnemyGameplayRank.Normal, 
				6 => EnemyGameplayRank.Normal, 
				7 => (!eid.isBoss) ? EnemyGameplayRank.Miniboss : EnemyGameplayRank.Boss, 
				20 => EnemyGameplayRank.Normal, 
				8 => EnemyGameplayRank.Boss, 
				22 => EnemyGameplayRank.Boss, 
				24 => EnemyGameplayRank.Boss, 
				9 => EnemyGameplayRank.Normal, 
				10 => EnemyGameplayRank.Ultraboss, 
				38 => EnemyGameplayRank.Normal, 
				40 => EnemyGameplayRank.Normal, 
				41 => EnemyGameplayRank.Miniboss, 
				42 => EnemyGameplayRank.Boss, 
				39 => EnemyGameplayRank.Normal, 
				_ => throw new NotImplementedException(), 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static EnemySpeciesType GetSpeciesType(this EnemyType enemyType)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected I4, but got Unknown
			if (1 == 0)
			{
			}
			EnemySpeciesType result = (int)enemyType switch
			{
				3 => EnemySpeciesType.Husk, 
				37 => EnemySpeciesType.UltraUnknown, 
				23 => EnemySpeciesType.UltraUnknown, 
				35 => EnemySpeciesType.Machine, 
				0 => EnemySpeciesType.Demon, 
				1 => EnemySpeciesType.Machine, 
				26 => EnemySpeciesType.Husk, 
				30 => EnemySpeciesType.OrganicMachine, 
				17 => EnemySpeciesType.OrganicMachine, 
				16 => EnemySpeciesType.Angel, 
				28 => EnemySpeciesType.Angel, 
				33 => EnemySpeciesType.Machine, 
				34 => EnemySpeciesType.Machine, 
				2 => EnemySpeciesType.Demon, 
				21 => EnemySpeciesType.Demon, 
				27 => EnemySpeciesType.Demon, 
				4 => EnemySpeciesType.Demon, 
				25 => EnemySpeciesType.UltraUnknown, 
				31 => EnemySpeciesType.Demon, 
				5 => EnemySpeciesType.Machine, 
				11 => EnemySpeciesType.Husk, 
				18 => EnemySpeciesType.Soul, 
				32 => EnemySpeciesType.Demon, 
				36 => EnemySpeciesType.Puppet, 
				14 => EnemySpeciesType.Husk, 
				19 => EnemySpeciesType.Husk, 
				29 => EnemySpeciesType.Soul, 
				15 => EnemySpeciesType.Husk, 
				12 => EnemySpeciesType.Husk, 
				13 => EnemySpeciesType.Husk, 
				6 => EnemySpeciesType.Machine, 
				7 => EnemySpeciesType.Machine, 
				20 => EnemySpeciesType.Machine, 
				8 => EnemySpeciesType.Machine, 
				22 => EnemySpeciesType.Machine, 
				24 => EnemySpeciesType.UltraUnknown, 
				9 => EnemySpeciesType.Angel, 
				38 => EnemySpeciesType.Angel, 
				40 => EnemySpeciesType.Angel, 
				41 => EnemySpeciesType.Husk, 
				42 => EnemySpeciesType.Demon, 
				39 => EnemySpeciesType.Demon, 
				10 => EnemySpeciesType.Unknown, 
				_ => throw new NotImplementedException(), 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static EnemySpeciesRank GetSpeciesRank(this EnemyType enemyType)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected I4, but got Unknown
			if (1 == 0)
			{
			}
			EnemySpeciesRank result = (int)enemyType switch
			{
				37 => EnemySpeciesRank.NotApplicable, 
				23 => EnemySpeciesRank.Supreme, 
				35 => EnemySpeciesRank.Supreme, 
				0 => EnemySpeciesRank.Lesser, 
				1 => EnemySpeciesRank.Lesser, 
				26 => EnemySpeciesRank.Supreme, 
				3 => EnemySpeciesRank.Lesser, 
				30 => EnemySpeciesRank.Greater, 
				17 => EnemySpeciesRank.Lesser, 
				16 => EnemySpeciesRank.Supreme, 
				28 => EnemySpeciesRank.Supreme, 
				33 => EnemySpeciesRank.Greater, 
				34 => EnemySpeciesRank.Greater, 
				2 => EnemySpeciesRank.Greater, 
				21 => EnemySpeciesRank.Lesser, 
				27 => EnemySpeciesRank.Supreme, 
				4 => EnemySpeciesRank.Lesser, 
				25 => EnemySpeciesRank.NotApplicable, 
				31 => EnemySpeciesRank.Lesser, 
				5 => EnemySpeciesRank.Greater, 
				11 => EnemySpeciesRank.Supreme, 
				18 => EnemySpeciesRank.Prime, 
				32 => EnemySpeciesRank.Supreme, 
				36 => EnemySpeciesRank.NotApplicable, 
				14 => EnemySpeciesRank.Greater, 
				19 => EnemySpeciesRank.Supreme, 
				29 => EnemySpeciesRank.Prime, 
				15 => EnemySpeciesRank.Greater, 
				12 => EnemySpeciesRank.Lesser, 
				13 => EnemySpeciesRank.Lesser, 
				6 => EnemySpeciesRank.Lesser, 
				7 => EnemySpeciesRank.Greater, 
				20 => EnemySpeciesRank.Greater, 
				8 => EnemySpeciesRank.Supreme, 
				22 => EnemySpeciesRank.Supreme, 
				24 => EnemySpeciesRank.Prime, 
				9 => EnemySpeciesRank.Lesser, 
				41 => EnemySpeciesRank.Supreme, 
				39 => EnemySpeciesRank.Lesser, 
				42 => EnemySpeciesRank.Supreme, 
				38 => EnemySpeciesRank.Lesser, 
				40 => EnemySpeciesRank.Greater, 
				10 => EnemySpeciesRank.NotApplicable, 
				_ => throw new NotImplementedException(), 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static EnemySpeciesRank GetSpeciesRank(this EnemyIdentifier eid)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return eid.enemyType.GetSpeciesRank();
		}

		public static EnemySpeciesType GetSpeciesType(this EnemyIdentifier eid)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return eid.enemyType.GetSpeciesType();
		}

		public static Bounds SolveEnemyBounds(this EnemyComponents enemy)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)enemy).gameObject.SolveEnemyBounds();
		}

		public static Bounds SolveEnemyBounds(this GameObject enemyGo)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			Collider component = enemyGo.GetComponent<Collider>();
			Collider[] componentsInChildren = enemyGo.GetComponentsInChildren<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				result = component.bounds;
			}
			Vector3 extents = ((Bounds)(ref result)).extents;
			if (((Vector3)(ref extents)).magnitude > 2f)
			{
				return result;
			}
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				Vector3 min = ((Bounds)(ref result)).min;
				Vector3 max = ((Bounds)(ref result)).max;
				float x = min.x;
				Bounds bounds = val.bounds;
				if (x > ((Bounds)(ref bounds)).min.x)
				{
					bounds = val.bounds;
					min.x = ((Bounds)(ref bounds)).min.x;
				}
				float y = min.y;
				bounds = val.bounds;
				if (y > ((Bounds)(ref bounds)).min.y)
				{
					bounds = val.bounds;
					min.y = ((Bounds)(ref bounds)).min.y;
				}
				float z = min.z;
				bounds = val.bounds;
				if (z > ((Bounds)(ref bounds)).min.z)
				{
					bounds = val.bounds;
					min.z = ((Bounds)(ref bounds)).min.z;
				}
				float x2 = max.x;
				bounds = val.bounds;
				if (x2 < ((Bounds)(ref bounds)).max.x)
				{
					bounds = val.bounds;
					max.x = ((Bounds)(ref bounds)).max.x;
				}
				float y2 = max.y;
				bounds = val.bounds;
				if (y2 < ((Bounds)(ref bounds)).max.y)
				{
					bounds = val.bounds;
					max.y = ((Bounds)(ref bounds)).max.y;
				}
				float z2 = max.z;
				bounds = val.bounds;
				if (z2 < ((Bounds)(ref bounds)).max.z)
				{
					bounds = val.bounds;
					max.z = ((Bounds)(ref bounds)).max.z;
				}
				((Bounds)(ref result)).SetMinMax(min, max);
			}
			return result;
		}
	}
	[HarmonyPatch(typeof(EnemyIdentifier), "Awake")]
	internal static class EnemyPreSpawnPatch
	{
		public static void Prefix(EnemyIdentifier __instance)
		{
			GameObject gameObject = ((Component)__instance).gameObject;
			try
			{
				EnemyComponents orAddComponent = GameObjectExtensions.GetOrAddComponent<EnemyComponents>(gameObject);
			}
			catch (Exception arg)
			{
				Log.Error($"{arg}");
			}
		}

		public static void Postfix(EnemyIdentifier __instance)
		{
			GameObject gameObject = ((Component)__instance).gameObject;
		}
	}
	[HarmonyPatch(typeof(EnemyIdentifier), "Start")]
	internal static class EnemyStartPatch
	{
		public static void Prefix(EnemyIdentifier __instance)
		{
			GameObject gameObject = ((Component)__instance).gameObject;
			TryLog.Action(delegate
			{
				EnemyEvents.PreStart?.Invoke(((Component)__instance).GetComponent<EnemyComponents>());
			});
		}

		public static void Postfix(EnemyIdentifier __instance)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)__instance).gameObject;
			EnemyComponents ec = ((Component)__instance).GetComponent<EnemyComponents>();
			TryLog.Action(delegate
			{
				EnemyEvents.PostStart?.Invoke(ec);
			});
			if (Cheats.IsCheatEnabled("nyxpiri.dev.log-eid-info"))
			{
				ec.RootGameObject.DebugPrintChildren();
			}
			ec.EidStarted = true;
			if (Options.LogEnemyTypeOnStart.Value)
			{
				Log.Message($"{((Object)gameObject).name}: enemy type is: {__instance.enemyType}");
			}
		}
	}
	[HarmonyPatch(typeof(EnemyComponents), "OnDisable")]
	internal static class EnemyDisablePatch
	{
		public static void Prefix(EnemyComponents __instance)
		{
			EnemyComponents enemyComponents = __instance;
			GameObject gameObject = ((Component)enemyComponents).gameObject;
			TryLog.Action(delegate
			{
				EnemyEvents.PreDisabled?.Invoke(__instance);
			});
		}

		public static void Postfix(EnemyComponents __instance)
		{
			GameObject gameObject = ((Component)__instance).gameObject;
		}
	}
	[HarmonyPatch(typeof(EnemyComponents), "OnDestroy")]
	internal static class EnemyDestroyPatch
	{
		public static void Prefix(EnemyComponents __instance)
		{
			EnemyComponents enemyComponents = __instance;
			GameObject gameObject = ((Component)enemyComponents).gameObject;
			TryLog.Action(delegate
			{
				EnemyEvents.PreDestroy?.Invoke(__instance);
			});
		}

		public static void Postfix(EnemyComponents __instance)
		{
			GameObject gameObject = ((Component)__instance).gameObject;
		}
	}
	[HarmonyPatch(typeof(SpiderBody), "Die", new Type[] { })]
	internal static class SpiderDiePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static bool Prefix(SpiderBody __instance)
		{
			return EidDeathPatch.PreDeath(((Component)__instance).gameObject.GetComponent<EnemyIdentifier>(), instakill: false, typeof(SpiderDiePatch), _cancellationTracker);
		}

		public static void Postfix(SpiderBody __instance)
		{
			EidDeathPatch.PostDeath(((Component)__instance).gameObject.GetComponent<EnemyIdentifier>(), typeof(SpiderDiePatch), _cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(Enemy), "GoLimp", new Type[] { typeof(bool) })]
	internal static class EnemyLimpPatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static bool Prefix(Enemy __instance, bool fromExplosion)
		{
			return EidDeathPatch.PreDeath(__instance.EID, instakill: false, typeof(EnemyLimpPatch), _cancellationTracker);
		}

		public static void Postfix(Enemy __instance, bool fromExplosion)
		{
			EidDeathPatch.PostDeath(__instance.EID, typeof(EnemyLimpPatch), _cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(Drone), "Death", new Type[] { typeof(bool) })]
	internal static class DroneDeathPatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static bool Prefix(Drone __instance, bool fromExplosion)
		{
			return EidDeathPatch.PreDeath(((Component)__instance).gameObject.GetComponent<EnemyIdentifier>(), instakill: false, typeof(DroneDeathPatch), _cancellationTracker);
		}

		public static void Postfix(Drone __instance, bool fromExplosion)
		{
			EidDeathPatch.PostDeath(((Component)__instance).gameObject.GetComponent<EnemyIdentifier>(), typeof(DroneDeathPatch), _cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(EnemyIdentifier), "InstaKill")]
	internal static class EnemyIdentifierInstakill
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static bool Prefix(EnemyIdentifier __instance)
		{
			_cancellationTracker.Reset();
			EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>();
			component.NullInvalid<EnemyComponents>()?.TryCallPreDeath(_cancellationTracker.GetCanceler(), instakill: true, typeof(EnemyIdentifierInstakill));
			_cancellationTracker.TryInvokeReimplementation();
			return _cancellationTracker.ShouldRunMethod;
		}

		public static void Postfix(EnemyIdentifier __instance)
		{
			EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>();
			component.NullInvalid<EnemyComponents>()?.TryCallPostDeath(_cancellationTracker.GetCancelInfo(), typeof(EnemyIdentifierInstakill));
		}
	}
	[HarmonyPatch(typeof(EnemyIdentifier), "Explode")]
	internal static class EnemyIdentifierExplodePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static bool Prefix(EnemyIdentifier __instance)
		{
			_cancellationTracker.Reset();
			EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>();
			component.NullInvalid<EnemyComponents>()?.TryCallPreDeath(_cancellationTracker.GetCanceler(), instakill: true, typeof(EnemyIdentifierExplodePatch));
			_cancellationTracker.TryInvokeReimplementation();
			return _cancellationTracker.ShouldRunMethod;
		}

		public static void Postfix(EnemyIdentifier __instance)
		{
			EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>();
			component.NullInvalid<EnemyComponents>()?.TryCallPostDeath(_cancellationTracker.GetCancelInfo(), typeof(EnemyIdentifierExplodePatch));
		}
	}
	[HarmonyPatch(typeof(EnemyIdentifier), "ProcessDeath", new Type[] { typeof(bool) })]
	internal static class EidDeathPatch
	{
		public static GameObject[] ActivateOnDeath;

		public static bool CalledPreDeath = false;

		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static bool PreDeath(EnemyIdentifier eid, bool instakill, object callerObj, EventMethodCancellationTracker cancellationTracker)
		{
			cancellationTracker.Reset();
			EnemyComponents component = ((Component)eid).GetComponent<EnemyComponents>();
			component.NullInvalid<EnemyComponents>()?.TryCallPreDeath(cancellationTracker.GetCanceler(), instakill, callerObj);
			cancellationTracker.TryInvokeReimplementation();
			return cancellationTracker.ShouldRunMethod;
		}

		public static void PostDeath(EnemyIdentifier eid, object callerObj, EventMethodCancellationTracker cancellationTracker)
		{
			EnemyComponents component = ((Component)eid).GetComponent<EnemyComponents>();
			component.NullInvalid<EnemyComponents>()?.TryCallPostDeath(cancellationTracker.GetCancelInfo(), callerObj);
		}

		public static bool Prefix(EnemyIdentifier __instance, bool fromExplosion)
		{
			_cancellationTracker.Reset();
			EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>();
			component.NullInvalid<EnemyComponents>()?.TryCallPreDeath(_cancellationTracker.GetCanceler(), instakill: false, typeof(EidDeathPatch));
			_cancellationTracker.TryInvokeReimplementation();
			component.NullInvalid<EnemyComponents>()?.TryCallDeath();
			return _cancellationTracker.ShouldRunMethod;
		}

		public static void Postfix(EnemyIdentifier __instance, bool fromExplosion)
		{
			EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>();
			component.NullInvalid<EnemyComponents>()?.TryCallPostDeath(_cancellationTracker.GetCancelInfo(), typeof(EidDeathPatch));
		}
	}
	[HarmonyPatch(typeof(StatueBoss), "Enrage")]
	internal static class StatueEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(StatueBoss __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker);
		}

		public static void Postfix(StatueBoss __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(StatueBoss), "UnEnrage")]
	internal static class StatueBossUnEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(StatueBoss __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker);
		}

		public static void Postfix(StatueBoss __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(SwordsMachine), "Enrage")]
	internal static class SwordsMachineEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(SwordsMachine __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker);
		}

		public static void Postfix(SwordsMachine __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(SwordsMachine), "UnEnrage")]
	internal static class SwordsMachineUnEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(SwordsMachine __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker);
		}

		public static void Postfix(SwordsMachine __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(Drone), "Enrage")]
	internal static class DroneEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(Drone __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker);
		}

		public static void Postfix(Drone __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(Drone), "UnEnrage")]
	internal static class DroneUnEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(Drone __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker);
		}

		public static void Postfix(Drone __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(V2), "Enrage", new Type[] { typeof(string) })]
	internal static class V2EnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(V2 __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker);
		}

		public static void Postfix(V2 __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(V2), "UnEnrage")]
	internal static class V2UnEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(V2 __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker);
		}

		public static void Postfix(V2 __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(Mindflayer), "Enrage")]
	internal static class MindflayerEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(Mindflayer __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker);
		}

		public static void Postfix(Mindflayer __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(Mindflayer), "UnEnrage")]
	internal static class MindflayerUnEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(Mindflayer __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker);
		}

		public static void Postfix(Mindflayer __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(SpiderBody), "Enrage")]
	internal static class SpiderBodyEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(SpiderBody __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker);
		}

		public static void Postfix(SpiderBody __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker);
		}
	}
	[HarmonyPatch(typeof(SpiderBody), "UnEnrage")]
	internal static class SpiderBodyUnEnragePatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		public static void Prefix(SpiderBody __instance)
		{
			((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker);
		}

		public static void Postfix(SpiderBody __instanc