Decompiled source of UltraChaos v3.3.0

Ultrachaos.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Fields;
using PluginConfig.API.Functionals;
using SettingsMenu.Components;
using SettingsMenu.Models;
using TMPro;
using Ultrachaos.Randomizers;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.Events;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
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: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Ultrachaos")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+516431c20606d55a68f1e4d99d6cd58418035ce4")]
[assembly: AssemblyProduct("My first plugin")]
[assembly: AssemblyTitle("Ultrachaos")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
namespace Ultrachaos
{
	[BepInPlugin("com.yourname.pluginname", "My first plugin", "2.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static OnClick <0>__Plugin_onClick_LVL;

			public static OnClick <1>__Plugin_onClick_Mapping;

			public static OnClick <2>__Plugin_onClick_Enable_All_Enemies;

			public static OnClick <3>__Plugin_onClick_Disable_All_Enemies;
		}

		private Harmony Harmony = new Harmony("com.yourname.pluginname");

		public static ConfigFile C;

		public static RandomConfig<RandomConfigValue> ChangeMaterials;

		public static RandomConfig<RandomConfigValue> ChangeSounds;

		public static RandomConfig<RandomConfigValue> ChangeEnemies;

		public static RandomConfig<RandomConfigValue> ChangeMeshes;

		public static RandomConfig<RandomConfigValue> ChangeProjectiles;

		public static RandomConfig<RandomConfigValue> ChangeHitscans;

		public static RandomConfig<RandomConfigValue> ChangeMusic;

		public static RandomConfig<RandomConfigValue> ChangeImages;

		public static RandomConfig<RandomConfigValue> ChangeText;

		public static RandomConfig<RandomConfigValue> ChangeItems;

		public static RandomConfig<RandomConfigValue> RandomizeLevels;

		public static RandomConfig<RandomConfigValue> RandomizGrenades;

		public static RandomConfig<RandomConfigValue> RandomizNails;

		public static RandomConfig<RandomConfigValue> RandomizExplosions;

		public static RandomConfig<bool> ChangeAnimator;

		public static RandomConfig<bool> OriginalHealthEID;

		public static ConfigPanel ChaosPanel;

		public static ConfigPanel NormalPanel;

		public static ConfigPanel PlayerPanel;

		public static ConfigPanel EnemyRNGList;

		private static PluginConfigurator config;

		public static List<Action<GameObject>> OnInstantiateMethod = new List<Action<GameObject>>();

		internal static ManualLogSource Logger { get; private set; } = null;


		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Plugin com.yourname.pluginname is loaded!");
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)4;
			Harmony.PatchAll();
			C = ((BaseUnityPlugin)this).Config;
			config = PluginConfigurator.Create("ULTRACHAOS", "com.yourname.pluginname");
			ChaosPanel = new ConfigPanel(config.rootPanel, "C H A O S", "panel.chaos");
			NormalPanel = new ConfigPanel(config.rootPanel, "Normal", "panel.normal");
			PlayerPanel = new ConfigPanel(config.rootPanel, "Player", "panel.player");
			EnemyRNGList = new ConfigPanel(config.rootPanel, "Enemies", "panel.enemies");
			SetupConfigs();
			SceneManager.sceneLoaded += SceneManager_sceneLoaded;
			SoundRandomizer.Init();
			Type icCheatType = typeof(ICheat);
			IEnumerable<Type> enumerable = from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany((Assembly a) => a.GetTypes())
				where icCheatType.IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract
				select t;
			MethodInfo method = typeof(TextRandomizer).GetMethod("CheatName");
			foreach (Type item in enumerable)
			{
				MethodInfo methodInfo = item.GetProperty("LongName")?.GetGetMethod();
				if (methodInfo != null)
				{
					Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			LevelRandomizer.Init();
			((MonoBehaviour)this).StartCoroutine(EnemyRandomizer.Init());
		}

		public static bool CanChangeObj(GameObject obj)
		{
			return !isConfiggyChild(obj.transform) && !isOptionsChild(obj.transform);
		}

		public static bool isConfiggyChild(Transform obj)
		{
			if (((Object)((Component)obj).gameObject).name.Contains("Configuration"))
			{
				return true;
			}
			if ((Object)(object)obj.parent != (Object)null)
			{
				return isConfiggyChild(obj.parent);
			}
			return false;
		}

		public static bool isOptionsChild(Transform obj)
		{
			if (((Object)((Component)obj).gameObject).name.Contains("OptionsMenu"))
			{
				return true;
			}
			if ((Object)(object)obj.parent != (Object)null)
			{
				return isOptionsChild(obj.parent);
			}
			return false;
		}

		public static bool isPlayerChild(Transform obj)
		{
			if (Object.op_Implicit((Object)(object)((Component)obj).GetComponent<NewMovement>()))
			{
				return true;
			}
			if (((Object)((Component)obj).gameObject).name.Contains("Player"))
			{
				return true;
			}
			if ((Object)(object)obj.parent != (Object)null)
			{
				return isPlayerChild(obj.parent);
			}
			return false;
		}

		public static bool isEnemyChild(Transform obj)
		{
			if (Object.op_Implicit((Object)(object)((Component)obj).GetComponent<EnemyIdentifier>()))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)((Component)obj).GetComponent<EnemyIdentifierIdentifier>()))
			{
				return true;
			}
			if ((Object)(object)obj.parent != (Object)null)
			{
				return isEnemyChild(obj.parent);
			}
			return false;
		}

		public static bool isFirstRoomChild(Transform obj)
		{
			if (((Object)((Component)obj).gameObject).name.ToLower().Contains("firstroom"))
			{
				return true;
			}
			if ((Object)(object)obj.parent != (Object)null)
			{
				return isFirstRoomChild(obj.parent);
			}
			return false;
		}

		public static bool isFinalRoomChild(Transform obj)
		{
			if (((Object)((Component)obj).gameObject).name.ToLower().Contains("finalroom"))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)((Component)obj).gameObject.GetComponent<FinalRoom>()))
			{
				return true;
			}
			if ((Object)(object)obj.parent != (Object)null)
			{
				return isFinalRoomChild(obj.parent);
			}
			return false;
		}

		public static void SetupConfigs()
		{
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Expected O, but got Unknown
			ChangeMaterials = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Materials", RandomConfigValue.Disabled);
			ChangeSounds = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Sounds", RandomConfigValue.Disabled);
			ChangeMeshes = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Meshes", RandomConfigValue.Disabled);
			ChangeProjectiles = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Projectiles", RandomConfigValue.Disabled);
			ChangeHitscans = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Hitscans", RandomConfigValue.Disabled);
			ChangeText = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Texts", RandomConfigValue.Disabled);
			RandomizGrenades = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Grenades", RandomConfigValue.Disabled);
			RandomizNails = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Nails", RandomConfigValue.Disabled);
			RandomizExplosions = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Explosions", RandomConfigValue.Disabled);
			ChangeImages = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Images", RandomConfigValue.Disabled);
			ChangeItems = new RandomConfig<RandomConfigValue>(ChaosPanel, "Change Items", RandomConfigValue.Disabled);
			ChangeAnimator = new RandomConfig<bool>(ChaosPanel, "Change Animator", defaultVal: false);
			ChangeEnemies = new RandomConfig<RandomConfigValue>(NormalPanel, "Change Enemies", RandomConfigValue.Disabled);
			OriginalHealthEID = new RandomConfig<bool>(NormalPanel, "Keep original enemys health", defaultVal: false);
			ChangeMusic = new RandomConfig<RandomConfigValue>(NormalPanel, "Change Music", RandomConfigValue.Disabled);
			RandomizeLevels = new RandomConfig<RandomConfigValue>(NormalPanel, "Randomize Levels", RandomConfigValue.Disabled);
			ButtonField val = new ButtonField(NormalPanel, "Go To Random Level", "button.normal.random.level");
			object obj = <>O.<0>__Plugin_onClick_LVL;
			if (obj == null)
			{
				OnClick val2 = Plugin_onClick_LVL;
				<>O.<0>__Plugin_onClick_LVL = val2;
				obj = (object)val2;
			}
			val.onClick += (OnClick)obj;
			ButtonField val3 = new ButtonField(config.rootPanel, "Reset Mapping", "button.reset.mapping");
			object obj2 = <>O.<1>__Plugin_onClick_Mapping;
			if (obj2 == null)
			{
				OnClick val4 = Plugin_onClick_Mapping;
				<>O.<1>__Plugin_onClick_Mapping = val4;
				obj2 = (object)val4;
			}
			val3.onClick += (OnClick)obj2;
			ButtonField val5 = new ButtonField(EnemyRNGList, "Enable All", "button.enemies.enable.all");
			object obj3 = <>O.<2>__Plugin_onClick_Enable_All_Enemies;
			if (obj3 == null)
			{
				OnClick val6 = Plugin_onClick_Enable_All_Enemies;
				<>O.<2>__Plugin_onClick_Enable_All_Enemies = val6;
				obj3 = (object)val6;
			}
			val5.onClick += (OnClick)obj3;
			ButtonField val7 = new ButtonField(EnemyRNGList, "Disable All", "button.enemies.disable.all");
			object obj4 = <>O.<3>__Plugin_onClick_Disable_All_Enemies;
			if (obj4 == null)
			{
				OnClick val8 = Plugin_onClick_Disable_All_Enemies;
				<>O.<3>__Plugin_onClick_Disable_All_Enemies = val8;
				obj4 = (object)val8;
			}
			val7.onClick += (OnClick)obj4;
			PlayerRandomizers.GenerateConfigs();
			ScaleRandomizer.GenerateConfigs();
		}

		private static void Plugin_onClick_Enable_All_Enemies()
		{
			foreach (RandomConfig<bool> value in EnemyRandomizer.CanUse.Values)
			{
				value.Value = true;
			}
		}

		private static void Plugin_onClick_Disable_All_Enemies()
		{
			foreach (RandomConfig<bool> value in EnemyRandomizer.CanUse.Values)
			{
				value.Value = false;
			}
		}

		private static void Plugin_onClick_Mapping()
		{
			EnemyRandomizer.Instance.ResetMappings();
			ExplosionRandomizer.Instance.ResetMappings();
			GrenadeRandomizer.Instance.ResetMappings();
			HitscanRandomizer.Instance.ResetMappings();
			ImageRandomizer.Instance.ResetMappings();
			ItemRandomizer.Instance.ResetMappings();
			LevelRandomizer.Instance.ResetMappings();
			MaterialRandomizer.Instance.ResetMappings();
			MeshRandomizer.Instance.ResetMappings();
			MusicRandomizer.Instance.ResetMappings();
			NailRandomizer.Instance.ResetMappings();
			ProjectileRandomizer.Instance.ResetMappings();
			SoundRandomizer.Instance.ResetMappings();
			TextRandomizer._randomizer.ResetMappings();
		}

		private static void Plugin_onClick_LVL()
		{
			LevelRandomizer.LoadRandomScene();
		}

		public static string GetPrefabName(string objName)
		{
			if (string.IsNullOrEmpty(objName))
			{
				return objName;
			}
			return Regex.Replace(objName, "\\s*\\((Clone|\\d+)\\)$", "");
		}

		public static bool IsGameplayScene()
		{
			string[] source = new string[6] { "Intro", "Bootstrap", "Main Menu", "Level 2-S", "Intermission1", "Intermission2" };
			return !source.Contains(SceneHelper.CurrentScene);
		}

		private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
		{
			((MonoBehaviour)this).StartCoroutine(EnemyRandomizer.Init());
			MusicRandomizer.FillPool();
			LevelRandomizer.Init();
			SoundRandomizer.Init();
			ProjectileRandomizer.Init();
			HitscanRandomizer.Init();
			GrenadeRandomizer.GetGrenades();
			NailRandomizer.GetNails();
			ExplosionRandomizer.GetExplosions();
			if (SceneHelper.CurrentScene == "Main Menu")
			{
				SoundRandomizer.Instance.Initialize();
				MaterialRandomizer.Instance.Initialize();
				ImageRandomizer.Instance.Initialize();
				HitscanRandomizer.Instance.Initialize();
				ProjectileRandomizer.Instance.Initialize();
				MeshRandomizer.Instance.Initialize();
				MusicRandomizer.Instance.Initialize();
			}
			if (IsGameplayScene())
			{
				TextRandomizer.SearchTexts();
				if (ChangeMaterials.Value != 0)
				{
					((MonoBehaviour)this).StartCoroutine(MaterialRandomizer.ApplyChanges());
				}
				((MonoBehaviour)this).StartCoroutine(ItemRandomizer.ApplyChanges());
				if (ChangeImages.Value != 0)
				{
					ImageRandomizer.ApplyChanges();
				}
				if (ChangeSounds.Value != 0)
				{
					SoundRandomizer.Init();
				}
				if (ChangeMeshes.Value != 0)
				{
					MeshRandomizer.Init();
				}
				MusicRandomizer.Init();
				ScaleRandomizer.Init();
			}
		}
	}
	[HarmonyPatch]
	public class InstantiatePatches
	{
		private static void ProcessInstantiatedObject(Object obj)
		{
			if (obj == (Object)null)
			{
				return;
			}
			GameObject val = null;
			GameObject val2 = (GameObject)(object)((obj is GameObject) ? obj : null);
			if (val2 != null)
			{
				val = val2;
			}
			else
			{
				Component val3 = (Component)(object)((obj is Component) ? obj : null);
				if (val3 != null)
				{
					val = val3.gameObject;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			foreach (Action<GameObject> item in Plugin.OnInstantiateMethod)
			{
				item(val);
			}
		}

		[HarmonyPatch(typeof(Object), "Instantiate", new Type[] { typeof(Object) })]
		[HarmonyPostfix]
		private static void InstantiatePostfix1(Object __result)
		{
			ProcessInstantiatedObject(__result);
		}

		[HarmonyPatch(typeof(Object), "Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Transform)
		})]
		[HarmonyPostfix]
		private static void InstantiatePostfix2(Object __result)
		{
			ProcessInstantiatedObject(__result);
		}

		[HarmonyPatch(typeof(Object), "Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Transform),
			typeof(bool)
		})]
		[HarmonyPostfix]
		private static void InstantiatePostfix3(Object __result)
		{
			ProcessInstantiatedObject(__result);
		}

		[HarmonyPatch(typeof(Object), "Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Vector3),
			typeof(Quaternion)
		})]
		[HarmonyPostfix]
		private static void InstantiatePostfix4(Object __result)
		{
			ProcessInstantiatedObject(__result);
		}

		[HarmonyPatch(typeof(Object), "Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Vector3),
			typeof(Quaternion),
			typeof(Transform)
		})]
		[HarmonyPostfix]
		private static void InstantiatePostfix5(Object __result)
		{
			ProcessInstantiatedObject(__result);
		}
	}
	public class RandomConfig<T>
	{
		private ConfigField field;

		public T Value
		{
			get
			{
				return (T)((object)field).GetType().GetProperty("value").GetValue(field);
			}
			set
			{
				((object)field).GetType().GetProperty("value").SetValue(field, value);
			}
		}

		public RandomConfig(ConfigPanel panel, string name, T defaultVal)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			string text = "guid." + ((ConfigField)panel).guid + "." + name;
			if (typeof(T) == typeof(float))
			{
				field = (ConfigField)new FloatField(panel, name, text, (float)(object)defaultVal);
				return;
			}
			if (typeof(T) == typeof(int))
			{
				field = (ConfigField)new IntField(panel, name, text, (int)(object)defaultVal);
				return;
			}
			if (typeof(T) == typeof(bool))
			{
				field = (ConfigField)new BoolField(panel, name, text, (bool)(object)defaultVal);
				return;
			}
			if (typeof(T) == typeof(string))
			{
				field = (ConfigField)new StringField(panel, name, text, (string)(object)defaultVal);
				return;
			}
			if (typeof(T) == typeof(RandomConfigValue))
			{
				field = (ConfigField)(object)new EnumField<RandomConfigValue>(panel, name, text, (RandomConfigValue)(object)defaultVal);
				return;
			}
			throw new Exception($"Unsupported config type: {typeof(T)}");
		}
	}
	public enum RandomConfigValue
	{
		Disabled,
		UniquePerKind,
		UniquePerKindWithDuplicates,
		AlwaysUnique
	}
	internal static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.yourname.pluginname";

		public const string PLUGIN_NAME = "My first plugin";

		public const string PLUGIN_VERSION = "2.0.0";
	}
}
namespace Ultrachaos.Randomizers
{
	[HarmonyPatch]
	public class AnimatorRandomizer
	{
		[HarmonyPatch(typeof(Animator), "SetTrigger", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		public static void TriggerRandomizer(ref string name, Animator __instance)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			if (!Plugin.ChangeAnimator.Value)
			{
				return;
			}
			List<string> list = new List<string>();
			AnimatorControllerParameter[] parameters = __instance.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if ((int)val.type == 9)
				{
					list.Add(val.name);
				}
			}
			name = list[Random.Range(0, list.Count)];
		}

		[HarmonyPatch(typeof(Animator), "SetInteger", new Type[]
		{
			typeof(string),
			typeof(int)
		})]
		[HarmonyPrefix]
		public static void IntegerRandomizer(ref string name, Animator __instance)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			if (!Plugin.ChangeAnimator.Value)
			{
				return;
			}
			List<string> list = new List<string>();
			AnimatorControllerParameter[] parameters = __instance.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if ((int)val.type == 3)
				{
					list.Add(val.name);
				}
			}
			name = list[Random.Range(0, list.Count)];
		}

		[HarmonyPatch(typeof(Animator), "SetBool", new Type[]
		{
			typeof(string),
			typeof(bool)
		})]
		[HarmonyPrefix]
		public static void BoolRandomizer(ref string name, Animator __instance)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			if (!Plugin.ChangeAnimator.Value)
			{
				return;
			}
			List<string> list = new List<string>();
			AnimatorControllerParameter[] parameters = __instance.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if ((int)val.type == 4)
				{
					list.Add(val.name);
				}
			}
			name = list[Random.Range(0, list.Count)];
		}

		[HarmonyPatch(typeof(Animator), "SetFloat", new Type[]
		{
			typeof(string),
			typeof(float)
		})]
		[HarmonyPrefix]
		public static void FloatRandomizer(ref string name, Animator __instance)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			if (!Plugin.ChangeAnimator.Value)
			{
				return;
			}
			List<string> list = new List<string>();
			AnimatorControllerParameter[] parameters = __instance.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if ((int)val.type == 1)
				{
					list.Add(val.name);
				}
			}
			name = list[Random.Range(0, list.Count)];
		}
	}
	[HarmonyPatch]
	public class EnemyRandomizer : Randomizer<SpawnableObject>
	{
		[HarmonyPatch(typeof(EnemySpawnRadius), "SpawnEnemy")]
		internal class SpawnEnemiesRandom
		{
			private static bool Prefix(EnemySpawnRadius __instance, ref List<GameObject> ___spawnedObjects, ref List<EnemyIdentifier> ___currentEnemies, ref float ___cooldown, ref GoreZone ___gz)
			{
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_0145: Unknown result type (might be due to invalid IL or missing references)
				//IL_014d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0152: 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_016f: Unknown result type (might be due to invalid IL or missing references)
				//IL_017c: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
				if (Plugin.ChangeEnemies.Value == RandomConfigValue.Disabled)
				{
					return true;
				}
				GameObject val = __instance.spawnables[Random.Range(0, __instance.spawnables.Length)];
				EnemyIdentifier val2 = val.GetComponent<EnemyIdentifier>() ?? val.GetComponentInChildren<EnemyIdentifier>();
				if ((Object)(object)val2 == (Object)null)
				{
					Plugin.Logger.LogWarning((object)("Spawnable '" + ((Object)val).name + "' has no EnemyIdentifier."));
					return true;
				}
				SpawnableObject val3 = FindBestMatch(val2);
				if ((Object)(object)val3 == (Object)null)
				{
					Plugin.Logger.LogWarning((object)("No match for spawner '" + ((Object)((Component)__instance).gameObject).name + "'"));
					return true;
				}
				List<SpawnableObject> list = Instance.Pool.Where((SpawnableObject x) => CanUse.ContainsKey(x) && CanUse[x].Value).ToList();
				if (list.Count == 0)
				{
					return true;
				}
				SpawnableObject random = Instance.GetRandom(val3, list);
				Vector3 val4 = new Vector3(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f));
				Vector3 normalized = ((Vector3)(ref val4)).normalized;
				RaycastHit val5 = default(RaycastHit);
				if (Physics.Raycast(((Component)__instance).transform.position + normalized * Random.Range(__instance.minimumDistance, __instance.maximumDistance), Vector3.down, ref val5, 25f, LayerMask.op_Implicit(LayerMaskDefaults.Get((LMD)1))))
				{
					___cooldown = __instance.spawnCooldown;
					GameObject val6 = Object.Instantiate<GameObject>(random.gameObject, ((RaycastHit)(ref val5)).point, Quaternion.identity);
					_replacementInstanceIds.Add(((Object)val6).GetInstanceID());
					val6.transform.SetParent(((Component)___gz).transform, true);
					___spawnedObjects.Add(val6);
					EnemyIdentifier componentInChildren = val6.GetComponentInChildren<EnemyIdentifier>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						___currentEnemies.Add(componentInChildren);
						if (__instance.spawnAsPuppets)
						{
							componentInChildren.puppet = true;
						}
					}
					else
					{
						___currentEnemies.Add(null);
					}
					val6.SetActive(true);
					return false;
				}
				___cooldown = 1f;
				return false;
			}
		}

		[CompilerGenerated]
		private sealed class <GetAllSpawnables>d__15 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public EnemyRandomizer <>4__this;

			private AsyncOperationHandle<IResourceLocator> <initHandle>5__1;

			private List<IResourceLocation> <allLocations>5__2;

			private IEnumerator<IResourceLocator> <>s__3;

			private IResourceLocator <locator>5__4;

			private List<object> <keys>5__5;

			private AsyncOperationHandle<IList<IResourceLocation>> <locHandle>5__6;

			private List<IResourceLocation>.Enumerator <>s__7;

			private IResourceLocation <location>5__8;

			private AsyncOperationHandle<SpawnableObject> <loadHandle>5__9;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetAllSpawnables>d__15(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				case -3:
				case 2:
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
					break;
				case -4:
				case 3:
					try
					{
					}
					finally
					{
						<>m__Finally2();
					}
					break;
				}
				<initHandle>5__1 = default(AsyncOperationHandle<IResourceLocator>);
				<allLocations>5__2 = null;
				<>s__3 = null;
				<locator>5__4 = null;
				<keys>5__5 = null;
				<locHandle>5__6 = default(AsyncOperationHandle<IList<IResourceLocation>>);
				<>s__7 = default(List<IResourceLocation>.Enumerator);
				<location>5__8 = null;
				<loadHandle>5__9 = default(AsyncOperationHandle<SpawnableObject>);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0134: Invalid comparison between Unknown and I4
				//IL_0285: Unknown result type (might be due to invalid IL or missing references)
				//IL_028b: Invalid comparison between Unknown and I4
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_0154: Unknown result type (might be due to invalid IL or missing references)
				//IL_016d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0298: Unknown result type (might be due to invalid IL or missing references)
				//IL_029e: Invalid comparison between Unknown and I4
				//IL_00f7: 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_0103: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_024e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0253: Unknown result type (might be due to invalid IL or missing references)
				//IL_025a: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						if (alreadyAddressed)
						{
							return false;
						}
						<initHandle>5__1 = Addressables.InitializeAsync();
						<>2__current = <initHandle>5__1;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<allLocations>5__2 = new List<IResourceLocation>();
						<>s__3 = Addressables.ResourceLocators.GetEnumerator();
						<>1__state = -3;
						goto IL_017a;
					case 2:
						<>1__state = -3;
						if ((int)<locHandle>5__6.Status == 1)
						{
							<allLocations>5__2.AddRange(<locHandle>5__6.Result);
						}
						Addressables.Release<IList<IResourceLocation>>(<locHandle>5__6);
						<keys>5__5 = null;
						<locHandle>5__6 = default(AsyncOperationHandle<IList<IResourceLocation>>);
						<locator>5__4 = null;
						goto IL_017a;
					case 3:
						{
							<>1__state = -4;
							if ((int)<loadHandle>5__9.Status == 1 && (int)<loadHandle>5__9.Result.spawnableObjectType == 1)
							{
								<>4__this.AddToPool(<loadHandle>5__9.Result);
							}
							<loadHandle>5__9 = default(AsyncOperationHandle<SpawnableObject>);
							<location>5__8 = null;
							break;
						}
						IL_017a:
						while (<>s__3.MoveNext())
						{
							<locator>5__4 = <>s__3.Current;
							<keys>5__5 = <locator>5__4.Keys.ToList();
							if (<keys>5__5.Count == 0)
							{
								continue;
							}
							<locHandle>5__6 = Addressables.LoadResourceLocationsAsync((IList<object>)<keys>5__5, (MergeMode)1, typeof(SpawnableObject));
							<>2__current = <locHandle>5__6;
							<>1__state = 2;
							return true;
						}
						<>m__Finally1();
						<>s__3 = null;
						<allLocations>5__2 = (from l in <allLocations>5__2
							group l by l.InternalId into g
							select g.First()).ToList();
						Plugin.Logger.LogInfo((object)$"Found {<allLocations>5__2.Count} SpawnableObject locations");
						<>s__7 = <allLocations>5__2.GetEnumerator();
						<>1__state = -4;
						break;
					}
					if (<>s__7.MoveNext())
					{
						<location>5__8 = <>s__7.Current;
						<loadHandle>5__9 = Addressables.LoadAssetAsync<SpawnableObject>(<location>5__8);
						<>2__current = <loadHandle>5__9;
						<>1__state = 3;
						return true;
					}
					<>m__Finally2();
					<>s__7 = default(List<IResourceLocation>.Enumerator);
					alreadyAddressed = true;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

			private void <>m__Finally2()
			{
				<>1__state = -1;
				((IDisposable)<>s__7).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <Init>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Init>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					_replacementInstanceIds.Clear();
					Plugin.Logger.LogInfo((object)"Getting addressables!!!");
					<>2__current = Instance.GetAllSpawnables();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (Instance.Pool.Count > PrevCount)
					{
						CreateConfigs();
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static bool SeededRandom = true;

		public static EnemyRandomizer Instance = new EnemyRandomizer();

		private static int PrevCount = 0;

		private static bool _sceneListenerRegistered = false;

		public static Dictionary<SpawnableObject, RandomConfig<bool>> CanUse = new Dictionary<SpawnableObject, RandomConfig<bool>>();

		private static List<string> DefaultBlacklistedEnemies = new List<string> { "Leviathan", "The Corpse of King Minos", "Earthmover" };

		private static bool alreadyAddressed = false;

		private static readonly HashSet<int> _replacementInstanceIds = new HashSet<int>();

		private static bool _isSpawningReplacement = false;

		[IteratorStateMachine(typeof(<Init>d__4))]
		public static IEnumerator Init()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Init>d__4(0);
		}

		public static void CreateConfigs()
		{
			foreach (SpawnableObject item in Instance.Pool)
			{
				if (!CanUse.ContainsKey(item))
				{
					Plugin.Logger.LogInfo((object)("Creating config for " + item.objectName));
					CanUse.Add(item, new RandomConfig<bool>(Plugin.EnemyRNGList, item.objectName, !DefaultBlacklistedEnemies.Contains(item.objectName)));
				}
			}
		}

		protected override void Log(string message)
		{
			Plugin.Logger.LogInfo((object)message);
		}

		private static string CleanGoName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return string.Empty;
			}
			int num = name.IndexOf('(');
			if (num > 0)
			{
				name = name.Substring(0, num);
			}
			return name.Trim().ToLowerInvariant();
		}

		private static int GetNameSimilarity(string spawnableName, string goName)
		{
			if (string.IsNullOrEmpty(spawnableName) || string.IsNullOrEmpty(goName))
			{
				return 0;
			}
			string text = spawnableName.ToLowerInvariant().Trim();
			string text2 = CleanGoName(goName);
			if (text == text2)
			{
				return int.MaxValue;
			}
			if (text2.Contains(text))
			{
				return text.Length * 2;
			}
			string[] array = text.Split(new char[3] { ' ', '-', '_' }, StringSplitOptions.RemoveEmptyEntries);
			int num = 0;
			string[] array2 = array;
			foreach (string value in array2)
			{
				if (text2.Contains(value))
				{
					num++;
				}
			}
			return num;
		}

		private static SpawnableObject FindBestMatch(EnemyIdentifier eid)
		{
			EnemyIdentifier eid2 = eid;
			string goName = ((Object)((Component)eid2).gameObject).name;
			List<(SpawnableObject, int)> list = (from x in Instance.Pool
				where x.enemyType == eid2.enemyType
				select (x, GetNameSimilarity(x.objectName, goName)) into t
				orderby t.score descending
				select t).ToList();
			if (list.Count == 0)
			{
				return null;
			}
			string text = $"{list[0].Item1.objectName} (score {list[0].Item2})";
			string text2 = ((list.Count > 1) ? $", runner-up: {list[1].Item1.objectName} (score {list[1].Item2})" : string.Empty);
			Plugin.Logger.LogInfo((object)("FindBestMatch '" + goName + "' -> " + text + text2));
			return list[0].Item1;
		}

		private static void ApplyRequiredThings(EnemyIdentifier eid, EnemyIdentifier randomedEID)
		{
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Expected O, but got Unknown
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Invalid comparison between Unknown and I4
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			randomedEID.dontCountAsKills = eid.dontCountAsKills;
			randomedEID.destroyOnDeath.AddRange(eid.destroyOnDeath);
			randomedEID.activateOnDeath = eid.activateOnDeath;
			randomedEID.sandified = eid.sandified;
			randomedEID.usingDoor = eid.usingDoor;
			randomedEID.madness = eid.madness;
			randomedEID.ignorePlayer = eid.ignorePlayer;
			randomedEID.ignoredByEnemies = eid.ignoredByEnemies;
			randomedEID.attackEnemies = eid.attackEnemies;
			if (Plugin.OriginalHealthEID.Value)
			{
				randomedEID.health = eid.health;
				Enemy val = FindEnemyComponent(((Component)eid).gameObject);
				Enemy val2 = FindEnemyComponent(((Component)randomedEID).gameObject);
				if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
				{
					val2.health = val.health;
					val2.originalHealth = val.originalHealth;
				}
			}
			BossHealthBar val3 = default(BossHealthBar);
			if (((Component)eid).TryGetComponent<BossHealthBar>(ref val3))
			{
				Plugin.Logger.LogInfo((object)("Replacing name " + val3.bossName));
				BossHealthBar val4 = ((Component)randomedEID).gameObject.AddComponent<BossHealthBar>();
				if (val3.bossName.ToLower().Contains("judge of hell"))
				{
					val4.bossName += ", JUDGE OF HELL";
				}
				else if (val3.bossName.ToLower().Contains("apostate of hate"))
				{
					val4.bossName += ", THE APOSTATE OF HATE";
				}
				else if (val3.bossName.ToLower().Contains("guardian of hell"))
				{
					val4.bossName += ", GUARDIAN OF HELL";
				}
				else if (val3.bossName.ToLower().Contains("prime"))
				{
					val4.bossName += " PRIME";
				}
				float num = randomedEID.health / eid.health;
				val4.healthLayers = val3.healthLayers;
				if (val4.healthLayers != null)
				{
					HealthLayer[] healthLayers = val4.healthLayers;
					foreach (HealthLayer val5 in healthLayers)
					{
						if (!Plugin.OriginalHealthEID.Value)
						{
							val5.health *= num;
						}
					}
				}
				val4.secondaryBar = val3.secondaryBar;
				if (val4.secondaryBar)
				{
					val4.secondaryBarColor = val3.secondaryBarColor;
					val4.secondaryBarValue = val3.secondaryBarValue;
				}
			}
			Enemy val6 = FindEnemyComponent(((Component)eid).gameObject);
			Enemy val7 = FindEnemyComponent(((Component)randomedEID).gameObject);
			if (Object.op_Implicit((Object)(object)val6) && Object.op_Implicit((Object)(object)val7))
			{
				val7.dontDie = val6.dontDie;
			}
			UnityEvent eventtt = eid.onDeath;
			randomedEID.onDeath.AddListener((UnityAction)delegate
			{
				eventtt.Invoke();
			});
			if ((int)randomedEID.enemyType == 12)
			{
				randomedEID.sandified = true;
			}
			Idol component = ((Component)eid).GetComponent<Idol>();
			Idol component2 = ((Component)randomedEID).GetComponent<Idol>();
			if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
			{
				component2.target = component.target;
			}
			else if ((Object)(object)component != (Object)null && (Object)(object)component2 == (Object)null)
			{
				component2 = ((Component)randomedEID).gameObject.AddComponent<Idol>();
				component2.target = component.target;
			}
			Idol[] array = Object.FindObjectsByType<Idol>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			foreach (Idol val8 in array)
			{
				if ((Object)(object)val8.target == (Object)(object)eid)
				{
					val8.target = randomedEID;
				}
				if ((Object)(object)val8.overrideTarget == (Object)(object)eid)
				{
					val8.overrideTarget = randomedEID;
				}
			}
		}

		private static Enemy FindEnemyComponent(GameObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return null;
			}
			Enemy component = obj.GetComponent<Enemy>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			component = obj.GetComponentInChildren<Enemy>(true);
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			return obj.GetComponentInParent<Enemy>();
		}

		[IteratorStateMachine(typeof(<GetAllSpawnables>d__15))]
		private IEnumerator GetAllSpawnables()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetAllSpawnables>d__15(0)
			{
				<>4__this = this
			};
		}

		[HarmonyPatch(typeof(EnemyIdentifier), "Start")]
		[HarmonyPrefix]
		public static bool ReplaceEnemy(EnemyIdentifier __instance)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Invalid comparison between Unknown and I4
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Invalid comparison between Unknown and I4
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Invalid comparison between Unknown and I4
			//IL_01c8: 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_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Invalid comparison between Unknown and I4
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.ChangeEnemies.Value == RandomConfigValue.Disabled)
			{
				return true;
			}
			if ((Object)(object)((Component)__instance).transform.parent != (Object)null && ((Object)((Component)((Component)__instance).transform.parent).gameObject).name == "4 - Swordsmachine Hallway")
			{
				return true;
			}
			if (_replacementInstanceIds.Contains(((Object)((Component)__instance).gameObject).GetInstanceID()))
			{
				return true;
			}
			if ((int)__instance.enemyType == 21)
			{
				return true;
			}
			if ((int)__instance.enemyType == 39)
			{
				return true;
			}
			if (__instance.dead)
			{
				return true;
			}
			if (!((Behaviour)__instance).enabled)
			{
				return true;
			}
			SpawnableObject val = FindBestMatch(__instance);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Logger.LogWarning((object)$"No matching SpawnableObject for '{((Object)((Component)__instance).gameObject).name}' (type: {__instance.enemyType}), skipping.");
				return true;
			}
			List<SpawnableObject> list = Instance.Pool.Where((SpawnableObject x) => CanUse.ContainsKey(x) && CanUse[x].Value).ToList();
			if (list.Count == 0)
			{
				return true;
			}
			SpawnableObject random = Instance.GetRandom(val, list);
			if ((Object)(object)random == (Object)null)
			{
				return true;
			}
			GameObject gameObject = random.gameObject;
			Vector3 position = ((Component)__instance).transform.position;
			if ((int)__instance.enemyType == 4)
			{
				position = ((Component)__instance).transform.parent.position;
			}
			GameObject val2 = Object.Instantiate<GameObject>(gameObject, position, gameObject.transform.rotation);
			_replacementInstanceIds.Add(((Object)val2).GetInstanceID());
			Plugin.Logger.LogInfo((object)("Spawned " + ((Object)gameObject).name + " instead of " + ((Object)((Component)__instance).gameObject).name));
			_isSpawningReplacement = false;
			val2.transform.parent = (((int)__instance.enemyType != 4) ? ((Component)__instance).transform.parent : ((Component)__instance).transform.parent.parent);
			EnemyIdentifier val3 = val2.GetComponent<EnemyIdentifier>() ?? val2.GetComponentInChildren<EnemyIdentifier>();
			if ((Object)(object)val3 == (Object)null)
			{
				Object.Destroy((Object)(object)val2);
				return true;
			}
			ActivateArena[] array = Object.FindObjectsByType<ActivateArena>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			foreach (ActivateArena val4 in array)
			{
				for (int j = 0; j < val4.enemies.Length; j++)
				{
					if ((Object)(object)val4.enemies[j] == (Object)(object)((Component)__instance).gameObject)
					{
						val4.enemies[j] = val2;
					}
				}
			}
			ApplyRequiredThings(__instance, val3);
			Object.Destroy((Object)(object)((Component)__instance).gameObject);
			return false;
		}

		protected override int GetInstanceID(SpawnableObject item)
		{
			return ((Object)item).GetInstanceID();
		}

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.ChangeEnemies.Value;
		}
	}
	public class RandomizerSpawnedEnemy : MonoBehaviour
	{
	}
	[HarmonyPatch]
	public class ExplosionRandomizer : Randomizer<ExplosionController>
	{
		public static ExplosionRandomizer Instance = new ExplosionRandomizer();

		private static bool replacing;

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.RandomizExplosions.Value;
		}

		public static void GetExplosions()
		{
			ExplosionController[] array = Resources.FindObjectsOfTypeAll<ExplosionController>();
			Instance.AddRangeToPool(array);
			Plugin.Logger.LogInfo((object)$"Adding {array.Length} to the pool, pool length of grenade randomizer is now {Instance.Pool.Count}");
		}

		protected override int GetInstanceID(ExplosionController item)
		{
			if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null || ((Object)((Component)item).gameObject).name == null)
			{
				return 0;
			}
			string text = ((Object)((Component)item).gameObject).name.ToLower().Replace(" (clone)", "").Replace("(clone)", "");
			return text.GetHashCode();
		}

		[HarmonyPatch(typeof(ExplosionController), "Start")]
		[HarmonyPrefix]
		public static bool GrenadeRNG(ExplosionController __instance)
		{
			//IL_0064: 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)
			if (Instance.GetConfigValue() == RandomConfigValue.Disabled)
			{
				return true;
			}
			if (replacing)
			{
				return true;
			}
			if (((Object)((Component)__instance).gameObject).name.Contains("RNG"))
			{
				return true;
			}
			ExplosionController random = Instance.GetRandom(__instance);
			replacing = true;
			ExplosionController val = Object.Instantiate<ExplosionController>(random, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation);
			GameObject gameObject = ((Component)val).gameObject;
			((Object)gameObject).name = ((Object)gameObject).name + "RNG";
			replacing = false;
			Object.Destroy((Object)(object)((Component)__instance).gameObject);
			return false;
		}
	}
	[HarmonyPatch]
	public class GrenadeRandomizer : Randomizer<Grenade>
	{
		public static GrenadeRandomizer Instance = new GrenadeRandomizer();

		private static bool replacing;

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.RandomizGrenades.Value;
		}

		public static void GetGrenades()
		{
			Grenade[] array = Resources.FindObjectsOfTypeAll<Grenade>();
			Instance.AddRangeToPool(array);
			Plugin.Logger.LogInfo((object)$"Adding {array.Length} to the pool, pool length of grenade randomizer is now {Instance.Pool.Count}");
		}

		protected override int GetInstanceID(Grenade item)
		{
			string text = ((Object)((Component)item).gameObject).name.ToLower().Replace(" (Clone)", "");
			text = text.Replace("(Clone)", "");
			return text.GetHashCode();
		}

		public static void ApplyThings(Grenade org, Grenade newG)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			newG.enemy = org.enemy;
			newG.originEnemy = org.originEnemy;
			newG.ignoreEnemyType = org.ignoreEnemyType;
			newG.sourceWeapon = org.sourceWeapon;
			newG.hitterWeapon = org.hitterWeapon;
			Rigidbody val = default(Rigidbody);
			Rigidbody val2 = default(Rigidbody);
			if (((Component)newG).gameObject.TryGetComponent<Rigidbody>(ref val) && ((Component)org).gameObject.TryGetComponent<Rigidbody>(ref val2))
			{
				val.velocity = val2.velocity;
				val.angularVelocity = val2.angularVelocity;
				if (org.rocket && !newG.rocket)
				{
					val.AddForce(((Component)org).transform.forward * 70f, (ForceMode)2);
				}
			}
			if (newG.rocket && !org.rocket)
			{
				((Component)newG).transform.forward = ((Component)MonoSingleton<CameraController>.Instance).transform.forward;
			}
		}

		[HarmonyPatch(typeof(Grenade), "Awake")]
		[HarmonyPrefix]
		public static bool GrenadeRNG(Grenade __instance)
		{
			//IL_003f: 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)
			if (Instance.GetConfigValue() == RandomConfigValue.Disabled)
			{
				return true;
			}
			if (replacing)
			{
				return true;
			}
			Grenade random = Instance.GetRandom(__instance);
			replacing = true;
			Grenade newG = Object.Instantiate<Grenade>(random, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation);
			replacing = false;
			ApplyThings(__instance, newG);
			Object.Destroy((Object)(object)((Component)__instance).gameObject);
			return false;
		}
	}
	[HarmonyPatch]
	public class HitscanRandomizer : Randomizer<RevolverBeam>
	{
		public static HitscanRandomizer Instance = new HitscanRandomizer();

		public static bool isReplacing = false;

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.ChangeHitscans.Value;
		}

		protected override int GetInstanceID(RevolverBeam item)
		{
			string text = ((Object)((Component)item).gameObject).name.ToLower().Replace(" (Clone)", "");
			text = text.Replace("(Clone)", "");
			return text.GetHashCode();
		}

		public static void Init()
		{
			RevolverBeam[] items = Resources.FindObjectsOfTypeAll<RevolverBeam>();
			Instance.AddRangeToPool(items);
		}

		public static void ApplyCorrectThings(RevolverBeam random, RevolverBeam orig)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			random.beamType = orig.beamType;
			random.ignoreEnemyType = orig.ignoreEnemyType;
			random.quickDraw = orig.quickDraw;
		}

		[HarmonyPatch(typeof(RevolverBeam), "Start")]
		[HarmonyPrefix]
		public static bool Randomize(RevolverBeam __instance)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (Instance.GetConfigValue() == RandomConfigValue.Disabled)
			{
				return true;
			}
			if (((Object)((Component)__instance).gameObject).name.Contains("Randomized"))
			{
				return true;
			}
			if (isReplacing)
			{
				return true;
			}
			RevolverBeam random = Instance.GetRandom(__instance);
			if ((Object)(object)random == (Object)null)
			{
				return true;
			}
			isReplacing = true;
			RevolverBeam val = Object.Instantiate<RevolverBeam>(random, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation);
			GameObject gameObject = ((Component)val).gameObject;
			((Object)gameObject).name = ((Object)gameObject).name + "Randomized";
			isReplacing = false;
			ApplyCorrectThings(val, __instance);
			Object.Destroy((Object)(object)((Component)__instance).gameObject);
			return false;
		}
	}
	[HarmonyPatch]
	public class ImageRandomizer : Randomizer<Sprite>
	{
		public static readonly ImageRandomizer Instance = new ImageRandomizer();

		protected override int GetInstanceID(Sprite item)
		{
			return ((Object)item).GetInstanceID();
		}

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.ChangeImages.Value;
		}

		public override void Initialize()
		{
			Plugin.OnInstantiateMethod.Add(delegate(GameObject obj)
			{
				Image[] componentsInChildren = obj.GetComponentsInChildren<Image>();
				foreach (Image rend in componentsInChildren)
				{
					ReplaceRenderer(rend);
				}
			});
		}

		public static void ApplyChanges()
		{
			Instance.ChangeMats();
		}

		public void ChangeMats()
		{
			AddRangeToPool(Resources.FindObjectsOfTypeAll<Sprite>());
			Image[] array = Object.FindObjectsByType<Image>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			Plugin.Logger.LogInfo((object)"Randomizing images...");
			Image[] array2 = array;
			foreach (Image val in array2)
			{
				if (((Component)val).gameObject.layer != 19)
				{
					ReplaceRenderer(val);
				}
			}
		}

		public void ReplaceRenderer(Image rend)
		{
			try
			{
				if (!((Object)(object)rend == (Object)null) && Plugin.ChangeImages.Value != 0 && Plugin.CanChangeObj(((Component)rend).gameObject))
				{
					rend.sprite = ReplaceMaterial(rend.sprite);
				}
			}
			catch (Exception)
			{
			}
		}

		public Sprite ReplaceMaterial(Sprite mat)
		{
			try
			{
				AddToPool(mat);
				return GetRandom(mat);
			}
			catch (Exception)
			{
				return mat;
			}
		}
	}
	public class ItemRandomizer : Randomizer<ItemIdentifier>
	{
		[CompilerGenerated]
		private sealed class <ApplyChanges>d__3 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ApplyChanges>d__3(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Expected O, but got Unknown
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Instance.AddRangeToPool(from x in Resources.FindObjectsOfTypeAll<ItemIdentifier>()
						where ((Component)x).gameObject.scene != SceneManager.GetActiveScene()
						select x);
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					Instance.ChangeMats();
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					Instance.ChangeMats();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static ItemRandomizer Instance = new ItemRandomizer();

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.ChangeItems.Value;
		}

		protected override int GetInstanceID(ItemIdentifier item)
		{
			if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null)
			{
				return 0;
			}
			return Plugin.GetPrefabName(((Object)((Component)item).gameObject).name).GetHashCode();
		}

		[IteratorStateMachine(typeof(<ApplyChanges>d__3))]
		public static IEnumerator ApplyChanges()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyChanges>d__3(0);
		}

		public void ChangeMats()
		{
			if (GetConfigValue() != 0)
			{
				ReplaceItems();
			}
		}

		private void ReplaceItems()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			if (GetConfigValue() == RandomConfigValue.Disabled)
			{
				return;
			}
			List<ItemIdentifier> list = Object.FindObjectsByType<ItemIdentifier>((FindObjectsInactive)1, (FindObjectsSortMode)0).ToList();
			foreach (ItemIdentifier item in list)
			{
				ItemIdentifier val = Object.Instantiate<ItemIdentifier>(GetRandom(item), ((Component)item).transform.position, ((Component)item).transform.rotation);
				val.pickedUp = item.pickedUp;
				val.infiniteSource = item.infiniteSource;
				val.onPickUp = item.onPickUp;
				val.onPutDown = item.onPutDown;
				val.ipz = item.ipz;
				val.itemType = item.itemType;
				((Component)val).transform.parent = ((Component)item).transform.parent;
				((Component)val).gameObject.SetActive(((Component)item).gameObject.activeSelf);
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
		}
	}
	[HarmonyPatch(typeof(SceneHelper))]
	public class LevelRandomizer : Randomizer<string>
	{
		[CompilerGenerated]
		private sealed class <InitAddressables>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private List<IResourceLocation> <allLocations>5__1;

			private IEnumerator<IResourceLocator> <>s__2;

			private IResourceLocator <locator>5__3;

			private List<object> <keys>5__4;

			private AsyncOperationHandle<IList<IResourceLocation>> <locHandle>5__5;

			private List<IResourceLocation>.Enumerator <>s__6;

			private IResourceLocation <location>5__7;

			private string <sceneName>5__8;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InitAddressables>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if (num == -3 || num == 2)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<allLocations>5__1 = null;
				<>s__2 = null;
				<locator>5__3 = null;
				<keys>5__4 = null;
				<locHandle>5__5 = default(AsyncOperationHandle<IList<IResourceLocation>>);
				<>s__6 = default(List<IResourceLocation>.Enumerator);
				<location>5__7 = null;
				<sceneName>5__8 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Invalid comparison between Unknown and I4
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0146: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = Addressables.InitializeAsync();
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<allLocations>5__1 = new List<IResourceLocation>();
						<>s__2 = Addressables.ResourceLocators.GetEnumerator();
						<>1__state = -3;
						break;
					case 2:
						<>1__state = -3;
						if ((int)<locHandle>5__5.Status == 1)
						{
							<allLocations>5__1.AddRange(<locHandle>5__5.Result);
						}
						Addressables.Release<IList<IResourceLocation>>(<locHandle>5__5);
						<keys>5__4 = null;
						<locHandle>5__5 = default(AsyncOperationHandle<IList<IResourceLocation>>);
						<locator>5__3 = null;
						break;
					}
					while (<>s__2.MoveNext())
					{
						<locator>5__3 = <>s__2.Current;
						<keys>5__4 = <locator>5__3.Keys.ToList();
						if (<keys>5__4.Count == 0)
						{
							continue;
						}
						<locHandle>5__5 = Addressables.LoadResourceLocationsAsync((IList<object>)<keys>5__4, (MergeMode)1, typeof(SceneInstance));
						<>2__current = <locHandle>5__5;
						<>1__state = 2;
						return true;
					}
					<>m__Finally1();
					<>s__2 = null;
					<allLocations>5__1 = (from l in <allLocations>5__1
						group l by l.InternalId into g
						select g.First()).ToList();
					Plugin.Logger.LogInfo((object)$"[LevelRandomizer] Found {<allLocations>5__1.Count} scene locations");
					<>s__6 = <allLocations>5__1.GetEnumerator();
					try
					{
						while (<>s__6.MoveNext())
						{
							<location>5__7 = <>s__6.Current;
							<sceneName>5__8 = SceneHelper.SanitizeLevelPath(<location>5__7.InternalId);
							if (!(<sceneName>5__8 == "Main Menu") && !(<sceneName>5__8 == "Bootstrap") && !(<sceneName>5__8 == "Intro"))
							{
								Instance.AddToPool(<sceneName>5__8);
								Plugin.Logger.LogInfo((object)("[LevelRandomizer] Registered: " + <sceneName>5__8));
								<sceneName>5__8 = null;
								<location>5__7 = null;
							}
						}
					}
					finally
					{
						((IDisposable)<>s__6).Dispose();
					}
					<>s__6 = default(List<IResourceLocation>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__2 != null)
				{
					<>s__2.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static LevelRandomizer Instance = new LevelRandomizer();

		public static void Init()
		{
			((MonoBehaviour)Plugin.Instance).StartCoroutine(InitAddressables());
		}

		[IteratorStateMachine(typeof(<InitAddressables>d__2))]
		public static IEnumerator InitAddressables()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InitAddressables>d__2(0);
		}

		public static void LoadRandomScene()
		{
			SceneHelper.LoadScene(Instance.Pool[Random.Range(0, Instance.Pool.Count)], false);
		}

		[HarmonyPatch(typeof(SceneHelper), "LoadScene")]
		[HarmonyPrefix]
		public static void RandomizeScene(ref string sceneName)
		{
			if (!(sceneName == "Main Menu") && !(sceneName == "Bootstrap") && !(sceneName == "Intro"))
			{
				sceneName = Instance.GetRandom(sceneName);
			}
		}

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.RandomizeLevels.Value;
		}

		protected override int GetInstanceID(string item)
		{
			return item.GetHashCode();
		}
	}
	[HarmonyPatch]
	public class MaterialRandomizer : Randomizer<Material>
	{
		[CompilerGenerated]
		private sealed class <ApplyChanges>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ApplyChanges>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					Instance.ChangeMats();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static readonly MaterialRandomizer Instance = new MaterialRandomizer();

		protected override int GetInstanceID(Material item)
		{
			return ((Object)item).GetInstanceID();
		}

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.ChangeMaterials.Value;
		}

		public override void Initialize()
		{
			Plugin.OnInstantiateMethod.Add(delegate(GameObject obj)
			{
				Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>();
				foreach (Renderer rend in componentsInChildren)
				{
					ReplaceRenderer(rend);
				}
			});
		}

		[IteratorStateMachine(typeof(<ApplyChanges>d__4))]
		public static IEnumerator ApplyChanges()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyChanges>d__4(0);
		}

		public void ChangeMats()
		{
			if (Plugin.ChangeMaterials.Value == RandomConfigValue.Disabled)
			{
				return;
			}
			AddRangeToPool(Resources.FindObjectsOfTypeAll<Material>());
			Renderer[] array = Object.FindObjectsByType<Renderer>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			foreach (Renderer val in array)
			{
				if (!Object.op_Implicit((Object)(object)((Component)val).gameObject.GetComponent<ParticleSystem>()) && ((Component)val).gameObject.layer != 19)
				{
					ReplaceRenderer(val);
				}
			}
		}

		public void ReplaceRenderer(Renderer rend)
		{
			try
			{
				if ((Object)(object)rend == (Object)null || Plugin.ChangeMaterials.Value == RandomConfigValue.Disabled)
				{
					return;
				}
				rend.SetPropertyBlock((MaterialPropertyBlock)null);
				Material[] sharedMaterials = rend.sharedMaterials;
				for (int i = 0; i < sharedMaterials.Length; i++)
				{
					if ((Object)(object)sharedMaterials[i] != (Object)null)
					{
						sharedMaterials[i] = GetRandom(sharedMaterials[i]);
					}
				}
				rend.sharedMaterials = sharedMaterials;
			}
			catch (Exception)
			{
			}
		}

		public Material ReplaceMaterial(Material mat)
		{
			try
			{
				AddToPool(mat);
				return GetRandom(mat);
			}
			catch (Exception)
			{
				return mat;
			}
		}
	}
	public class MeshRandomizer : Randomizer<Mesh>
	{
		[CompilerGenerated]
		private sealed class <Inititit>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MeshRandomizer <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Inititit>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					Instance.ChangeMeshes();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private List<Mesh> cachedMeshes;

		public static MeshRandomizer Instance = new MeshRandomizer();

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.ChangeMeshes.Value;
		}

		protected override int GetInstanceID(Mesh item)
		{
			return ((Object)item).GetInstanceID();
		}

		public override void Initialize()
		{
			cachedMeshes = Resources.FindObjectsOfTypeAll<Mesh>().ToList();
			Plugin.OnInstantiateMethod.Add(delegate(GameObject obj)
			{
				MeshFilter[] componentsInChildren = obj.GetComponentsInChildren<MeshFilter>();
				foreach (MeshFilter rend in componentsInChildren)
				{
					ReplaceRenderer(rend, cachedMeshes);
				}
			});
		}

		public static void Init()
		{
			((MonoBehaviour)Plugin.Instance).StartCoroutine(Instance.Inititit());
		}

		[IteratorStateMachine(typeof(<Inititit>d__6))]
		public IEnumerator Inititit()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Inititit>d__6(0)
			{
				<>4__this = this
			};
		}

		public void ChangeMeshes()
		{
			if (GetConfigValue() == RandomConfigValue.Disabled)
			{
				return;
			}
			MeshFilter[] array = Object.FindObjectsByType<MeshFilter>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			MeshFilter[] array2 = array;
			foreach (MeshFilter val in array2)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.mesh == (Object)null) && ((Component)val).gameObject.layer != 19 && !((Object)(object)((Component)val).GetComponent<ParticleSystem>() != (Object)null))
				{
					ReplaceRenderer(val, cachedMeshes);
				}
			}
		}

		public void ReplaceRenderer(MeshFilter rend, List<Mesh> pool)
		{
			try
			{
				if (!((Object)(object)rend == (Object)null) && GetConfigValue() != 0)
				{
					rend.mesh = GetRandom(rend.mesh, pool);
				}
			}
			catch (Exception)
			{
			}
		}
	}
	public class MusicRandomizer : Randomizer<AudioClip>
	{
		[CompilerGenerated]
		private sealed class <GetAllMusic>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MusicRandomizer <>4__this;

			private AsyncOperationHandle<IResourceLocator> <initHandle>5__1;

			private List<IResourceLocation> <allLocations>5__2;

			private IEnumerator<IResourceLocator> <>s__3;

			private IResourceLocator <locator>5__4;

			private List<object> <keys>5__5;

			private AsyncOperationHandle<IList<IResourceLocation>> <locHandle>5__6;

			private List<IResourceLocation>.Enumerator <>s__7;

			private IResourceLocation <location>5__8;

			private AsyncOperationHandle<SoundtrackSong> <loadHandle>5__9;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetAllMusic>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				case -3:
				case 2:
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
					break;
				case -4:
				case 3:
					try
					{
					}
					finally
					{
						<>m__Finally2();
					}
					break;
				}
				<initHandle>5__1 = default(AsyncOperationHandle<IResourceLocator>);
				<allLocations>5__2 = null;
				<>s__3 = null;
				<locator>5__4 = null;
				<keys>5__5 = null;
				<locHandle>5__6 = default(AsyncOperationHandle<IList<IResourceLocation>>);
				<>s__7 = default(List<IResourceLocation>.Enumerator);
				<location>5__8 = null;
				<loadHandle>5__9 = default(AsyncOperationHandle<SoundtrackSong>);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: 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_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0124: Invalid comparison between Unknown and I4
				//IL_0270: Unknown result type (might be due to invalid IL or missing references)
				//IL_0276: Invalid comparison between Unknown and I4
				//IL_0142: Unknown result type (might be due to invalid IL or missing references)
				//IL_015b: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_023c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0241: Unknown result type (might be due to invalid IL or missing references)
				//IL_0248: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<initHandle>5__1 = Addressables.InitializeAsync();
						<>2__current = <initHandle>5__1;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<allLocations>5__2 = new List<IResourceLocation>();
						<>s__3 = Addressables.ResourceLocators.GetEnumerator();
						<>1__state = -3;
						goto IL_0168;
					case 2:
						<>1__state = -3;
						if ((int)<locHandle>5__6.Status == 1)
						{
							<allLocations>5__2.AddRange(<locHandle>5__6.Result);
						}
						Addressables.Release<IList<IResourceLocation>>(<locHandle>5__6);
						<keys>5__5 = null;
						<locHandle>5__6 = default(AsyncOperationHandle<IList<IResourceLocation>>);
						<locator>5__4 = null;
						goto IL_0168;
					case 3:
						{
							<>1__state = -4;
							if ((int)<loadHandle>5__9.Status == 1)
							{
								<>4__this.AddRangeToPool(<loadHandle>5__9.Result.clips);
							}
							<loadHandle>5__9 = default(AsyncOperationHandle<SoundtrackSong>);
							<location>5__8 = null;
							break;
						}
						IL_0168:
						while (<>s__3.MoveNext())
						{
							<locator>5__4 = <>s__3.Current;
							<keys>5__5 = <locator>5__4.Keys.ToList();
							if (<keys>5__5.Count == 0)
							{
								continue;
							}
							<locHandle>5__6 = Addressables.LoadResourceLocationsAsync((IList<object>)<keys>5__5, (MergeMode)1, typeof(SoundtrackSong));
							<>2__current = <locHandle>5__6;
							<>1__state = 2;
							return true;
						}
						<>m__Finally1();
						<>s__3 = null;
						<allLocations>5__2 = (from l in <allLocations>5__2
							group l by l.InternalId into g
							select g.First()).ToList();
						Plugin.Logger.LogInfo((object)$"Found {<allLocations>5__2.Count} Songs locations");
						<>s__7 = <allLocations>5__2.GetEnumerator();
						<>1__state = -4;
						break;
					}
					if (<>s__7.MoveNext())
					{
						<location>5__8 = <>s__7.Current;
						<loadHandle>5__9 = Addressables.LoadAssetAsync<SoundtrackSong>(<location>5__8);
						<>2__current = <loadHandle>5__9;
						<>1__state = 3;
						return true;
					}
					<>m__Finally2();
					<>s__7 = default(List<IResourceLocation>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

			private void <>m__Finally2()
			{
				<>1__state = -1;
				((IDisposable)<>s__7).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <ReplaceEveryhtingPlease>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MusicRandomizer <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ReplaceEveryhtingPlease>d__5(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSecondsRealtime(0.1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					ReplaceThings();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static MusicRandomizer Instance = new MusicRandomizer();

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.ChangeMusic.Value;
		}

		protected override int GetInstanceID(AudioClip item)
		{
			return ((Object)item).GetInstanceID();
		}

		public static void Init()
		{
			ReplaceThings();
			((MonoBehaviour)Plugin.Instance).StartCoroutine(Instance.ReplaceEveryhtingPlease());
		}

		public static void FillPool()
		{
			if (Instance.Pool.Count <= 0)
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine(Instance.GetAllMusic());
			}
		}

		[IteratorStateMachine(typeof(<ReplaceEveryhtingPlease>d__5))]
		public IEnumerator ReplaceEveryhtingPlease()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ReplaceEveryhtingPlease>d__5(0)
			{
				<>4__this = this
			};
		}

		public static void ReplaceThings()
		{
			MusicManager instance = MonoSingleton<MusicManager>.Instance;
			if ((Object)(object)instance.bossTheme.clip != (Object)null)
			{
				instance.bossTheme.clip = Instance.GetRandom(instance.bossTheme.clip);
			}
			if ((Object)(object)instance.cleanTheme.clip != (Object)null)
			{
				instance.cleanTheme.clip = Instance.GetRandom(instance.cleanTheme.clip);
			}
			if ((Object)(object)instance.battleTheme.clip != (Object)null)
			{
				instance.battleTheme.clip = Instance.GetRandom(instance.battleTheme.clip);
			}
			MusicChanger[] array = Object.FindObjectsByType<MusicChanger>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			MusicChanger[] array2 = array;
			foreach (MusicChanger val in array2)
			{
				val.battle = Instance.GetRandom(val.battle);
				val.boss = Instance.GetRandom(val.boss);
				val.clean = Instance.GetRandom(val.clean);
			}
			HashSet<AudioSource> hashSet = new HashSet<AudioSource>();
			hashSet.Add(instance.bossTheme);
			hashSet.Add(instance.cleanTheme);
			hashSet.Add(instance.battleTheme);
			MusicChanger[] array3 = array;
			foreach (MusicChanger val2 in array3)
			{
				AudioSource component = ((Component)val2).GetComponent<AudioSource>();
				if ((Object)(object)component != (Object)null)
				{
					hashSet.Add(component);
				}
			}
			AudioSource[] array4 = Object.FindObjectsByType<AudioSource>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			AudioSource[] array5 = array4;
			foreach (AudioSource val3 in array5)
			{
				if (!hashSet.Contains(val3) && !((Object)(object)val3.clip == (Object)null) && IsMusic(val3))
				{
					val3.clip = Instance.GetRandom(val3.clip);
				}
			}
		}

		private static bool IsMusic(AudioSource source)
		{
			return (Object)(object)source.outputAudioMixerGroup != (Object)null && ((Object)source.outputAudioMixerGroup.audioMixer).name == "MusicAudio";
		}

		[IteratorStateMachine(typeof(<GetAllMusic>d__8))]
		public IEnumerator GetAllMusic()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetAllMusic>d__8(0)
			{
				<>4__this = this
			};
		}
	}
	[HarmonyPatch]
	public class NailRandomizer : Randomizer<Nail>
	{
		public static NailRandomizer Instance = new NailRandomizer();

		private static bool replacing;

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.RandomizNails.Value;
		}

		public static void GetNails()
		{
			Nail[] array = Resources.FindObjectsOfTypeAll<Nail>();
			Instance.AddRangeToPool(array);
			Plugin.Logger.LogInfo((object)$"Adding {array.Length} to the pool, pool length of nail randomizer is now {Instance.Pool.Count}");
		}

		protected override int GetInstanceID(Nail item)
		{
			int num = (item.sawblade ? 2 : 4);
			int num2 = (item.heated ? 1 : 3);
			string text = ((Object)((Component)item).gameObject).name.ToLower().Replace(" (Clone)", "");
			text = text.Replace("(Clone)", "");
			return text.GetHashCode() + num + num2;
		}

		public static void ApplyThings(Nail org, Nail newG)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			newG.enemy = org.enemy;
			newG.safeEnemyType = org.safeEnemyType;
			newG.sourceWeapon = org.sourceWeapon;
			Rigidbody val = default(Rigidbody);
			Rigidbody val2 = default(Rigidbody);
			if (((Component)newG).gameObject.TryGetComponent<Rigidbody>(ref val) && ((Component)org).gameObject.TryGetComponent<Rigidbody>(ref val2))
			{
				val.velocity = val2.velocity;
				val.angularVelocity = val2.angularVelocity;
			}
		}

		[HarmonyPatch(typeof(Nail), "Start")]
		[HarmonyPrefix]
		public static bool GrenadeRNG(Nail __instance)
		{
			//IL_0064: 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)
			if (Instance.GetConfigValue() == RandomConfigValue.Disabled)
			{
				return true;
			}
			if (replacing)
			{
				return true;
			}
			if (((Object)((Component)__instance).gameObject).name.Contains("RNG"))
			{
				return true;
			}
			Nail random = Instance.GetRandom(__instance);
			replacing = true;
			Nail val = Object.Instantiate<Nail>(random, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation);
			GameObject gameObject = ((Component)val).gameObject;
			((Object)gameObject).name = ((Object)gameObject).name + "RNG";
			replacing = false;
			ApplyThings(__instance, val);
			Object.Destroy((Object)(object)((Component)__instance).gameObject);
			return false;
		}
	}
	[HarmonyPatch]
	public class PlayerRandomizers
	{
		[HarmonyPatch(typeof(NewMovement), "GetHealth")]
		public class CheckPatch
		{
			private static int HealthBefore;

			private static bool Prefix(ref NewMovement __instance, int health)
			{
				HealthBefore = __instance.hp;
				return true;
			}

			private static void Postfix(int health)
			{
				if (HealthBefore + health <= MaxHealth)
				{
					NewMovement instance = MonoSingleton<NewMovement>.Instance;
					instance.hp += health;
				}
				if (MonoSingleton<NewMovement>.Instance.hp > MaxHealth)
				{
					MonoSingleton<NewMovement>.Instance.hp = MaxHealth;
				}
			}
		}

		public static int MaxHealth;

		private static MinMaxConfig WalkSpeedMult;

		private static MinMaxConfig Health;

		public static void GenerateConfigs()
		{
			WalkSpeedMult = new MinMaxConfig("Walk Speed", 1f, Plugin.PlayerPanel);
			Health = new MinMaxConfig("Health", 100f, Plugin.PlayerPanel);
		}

		[HarmonyPatch(typeof(NewMovement), "Start")]
		[HarmonyPostfix]
		public static void ApplyChanges(NewMovement __instance)
		{
			__instance.walkSpeed *= WalkSpeedMult.GetRand;
			MonoSingleton<NewMovement>.Instance.hp = (int)Health.GetRand;
			MaxHealth = MonoSingleton<NewMovement>.Instance.hp;
		}

		[HarmonyPatch(typeof(NewMovement), "Respawn")]
		[HarmonyPostfix]
		private static void HealthChange()
		{
			MonoSingleton<NewMovement>.Instance.hp = (int)Health.GetRand;
			MaxHealth = MonoSingleton<NewMovement>.Instance.hp;
		}
	}
	public class MinMaxConfig
	{
		private RandomConfig<float> _min;

		private RandomConfig<float> _max;

		public float Min => _min.Value;

		public float Max => _max.Value;

		public float GetRand => Random.Range(Min, Max);

		public MinMaxConfig(string name, float defaultVal, ConfigPanel panel)
		{
			_min = new RandomConfig<float>(panel, "Min " + name, defaultVal);
			_max = new RandomConfig<float>(panel, "Max " + name, defaultVal);
		}
	}
	[HarmonyPatch]
	public class ProjectileRandomizer : Randomizer<Projectile>
	{
		public static ProjectileRandomizer Instance = new ProjectileRandomizer();

		public static bool isReplacing = false;

		protected override RandomConfigValue GetConfigValue()
		{
			return Plugin.ChangeProjectiles.Value;
		}

		protected override int GetInstanceID(Projectile item)
		{
			string text = ((Object)((Component)item).gameObject).name.ToLower().Replace(" (Clone)", "");
			text = text.Replace("(Clone)", "");
			return text.GetHashCode();
		}

		public static void Init()
		{
			Projectile[] source = Resources.FindObjectsOfTypeAll<Projectile>();
			source = source.Where((Projectile x) => !x.decorative).ToArray();
			Instance.AddRangeToPool(source);
		}

		public static void ApplyCorrectThings(Projectile random, Projectile orig)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			random.safeEnemyType = orig.safeEnemyType;
			random.playerBullet = orig.playerBullet;
			random.target = orig.target;
			random.targetHandle = orig.targetHandle;
			random.friendly = orig.friendly;
		}

		[HarmonyPatch(typeof(Projectile), "Awake")]
		[HarmonyPrefix]
		public static bool Randomize(Projectile __instance)
		{
			//IL_0060: 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)
			if (Instance.GetConfigValue() == RandomConfigValue.Disabled)
			{
				return true;
			}
			if (isReplacing)
			{
				return true;
			}
			if (__instance.decorative)
			{
				return true;
			}
			Projectile random = Instance.GetRandom(__instance);
			if ((Object)(object)random == (Object)null)
			{
				return true;
			}
			isReplacing = true;
			Projectile random2 = Object.Instantiate<Projectile>(random, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation);
			isReplacing = false;
			ApplyCorrectThings(random2, __instance);
			Object.Destroy((Object)(object)((Component)__instance).gameObject);
			return false;
		}
	}
	public abstract class Randomizer<T> where T : class
	{
		private readonly Dictionary<int, T> _map = new Dictionary<int, T>();

		private readonly HashSet<int> _usedIds = new HashSet<int>();

		public List<T> Pool { get; } = new List<T>();


		protected virtual int NextIndex(int count)
		{
			return Random.Range(0, count);
		}

		protected abstract int GetInstanceID(T item);

		protected abstract RandomConfigValue GetConfigValue();

		protected virtual void Log(string message)
		{
		}

		public void ResetMappings()
		{
			_map.Clear();
			_usedIds.Clear();
		}

		public void AddToPool(T item)
		{
			if (item != null)
			{
				int id = GetInstanceID(item);
				if (Pool.All((T p) => GetInstanceID(p) != id))
				{
					Pool.Add(item);
				}
			}
		}

		public virtual void Initialize()
		{
		}

		public void AddRangeToPool(IEnumerable<T> items)
		{
			foreach (T item in items)
			{
				AddToPool(item);
			}
		}

		public T GetRandom(T original = null, List<T> CPool = null)
		{
			if (CPool == null)
			{
				CPool = Pool;
			}
			if (CPool.Count == 0)
			{
				return original;
			}
			switch (GetConfigValue())
			{
			case RandomConfigValue.Disabled:
				return original;
			case RandomConfigValue.AlwaysUnique:
				return CPool[NextIndex(CPool.Count)];
			case RandomConfigValue.UniquePerKindWithDuplicates:
			{
				int key2 = ((original != null) ? GetInstanceID(original) : 0);
				if (!_map.TryGetValue(key2, out var value2))
				{
					value2 = CPool[NextIndex(CPool.Count)];
					_map[key2] = value2;
				}
				return value2;
			}
			case RandomConfigValue.UniquePerKind:
			{
				int key = ((original != null) ? GetInstanceID(original) : 0);
				if (!_map.TryGetValue(key, out var value))
				{
					List<T> list = CPool.Where((T item) => !_usedIds.Contains(GetInstanceID(item)) && GetInstanceID(item) != key).ToList();
					Log(string.Format("[UniquePerKind] key={0} | pool={1} | usedIds=[{2}] | available={3}", key, CPool.Count, string.Join(",", _usedIds), list.Count));
					if (list.Count == 0)
					{
						list = CPool.Where((T item) => GetInstanceID(item) != key).ToList();
						Log($"[UniquePerKind] key={key} | pool exhausted, falling back to {list.Count} candidates");
					}
					if (list.Count == 0)
					{
						return original;
					}
					value = list[NextIndex(list.Count)];
					_usedIds.Add(GetInstanceID(value));
					_map[key] = value;
					Log(string.Format("[UniquePerKind] key={0} -> assigned id={1} | usedIds now=[{2}]", key, GetInstanceID(value), string.Join(",", _usedIds)));
				}
				else
				{
					Log($"[UniquePerKind] key={key} -> already mapped to id={GetInstanceID(value)} (cache hit)");
				}
				return value;
			}
			default:
				return original;
			}
		}
	}
	public class ScaleRandomizer
	{
		public static MinMaxConfig ScaleMult;

		public static void GenerateConfigs()
		{
			ScaleMult = new MinMaxConfig("Scale Mult", 1f, Plugin.ChaosPanel);
		}

		public static void Init()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			Transform[] array = Object.FindObjectsByType<Transform>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			Transform[] array2 = array;
			foreach (Transform val in array2)
			{
				if (Plugin.CanChangeObj(((Component)val).gameObject) && !(val is RectTransform) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<Canvas>()) && !Plugin.isPlayerChild(val) && !Plugin.isFirstRoomChild(val) && !Plugin.isFinalRoomChild(val) && !Plugin.isEnemyChild(val) && !Object.op_Implicit((Object)(object)((Component)val).gameObject.GetComponent<PlayerActivator>()))
				{
					val.localScale *= ScaleMult.GetRand;
				}
			}
		}
	}
	internal class SoundRandomizer : Randomizer<AudioClip>
	{
		[CompilerGenerated]
		private sealed class <GetAllAddressableClips>d__11 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public SoundRandomizer <>4__this;

			private List<IResourceLocation> <allLocations>5__1;

			private IEnumerator<IResourceLocator> <>s__2;

			private IResourceLocator <locator>5__3;

			private List<object> <keys>5__4;

			private AsyncOperationHandle<IList<IResourceLocation>> <locHandle>5__5;

			private List<IResourceLocation>.Enumerator <>s__6;

			private IResourceLocation <location>5__7;

			private AsyncOperationHandle<AudioClip> <loadHandle>5__8;

			private Exception <ex>5__9;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetAllAddressableClips>d__11(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				//IL_0060: 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)
				switch (<>1__state)
				{
				case -3:
				case 2:
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
					break;
				case -4:
				case 3:
					try
					{
					}
					finally
					{
						<>m__Finally2();
					}
					break;
				}
				<allLocations>5__1 = null;
				<>s__2 = null;
				<locator>5__3 = null;
				<keys>5__4 = null;
				<locHandle>5__5 = default(AsyncOperationHandle<IList<IResourceLocation>>);
				<>s__6 = default(List<IResourceLocation>.Enumerator);
				<location>5__7 = null;
				<loadHandle>5__8 = default(AsyncOperationHandle<AudioClip>);
				<ex>5__9 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_0118: Invalid comparison between Unknown and I4
				//IL_022f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_014f: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0299: Unknown result type (might be due to invalid IL or missing references)
				//IL_029f: Invalid comparison between Unknown and I4
				//IL_023d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0242: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_025c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = Addressables.InitializeAsync();
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<allLocations>5__1 = new List<IResourceLocation>();
						<>s__2 = Addressables.ResourceLocators.GetEnumerator();
						<>1__state = -3;
						goto IL_015c;
					case 2:
						<>1__state = -3;
						if ((int)<locHandle>5__5.Status == 1)
						{
							<allLocations>5__1.AddRange(<locHandle>5__5.Result);
						}
						Addressables.Release<IList<IResourceLocation>>(<locHandle>5__5);
						<keys>5__4 = null;
						<locHandle>5__5 = default(AsyncOperationHandle<IList<IResourceLocation>>);
						<locator>5__3 = null;
						goto IL_015c;
					case 3:
						{
							<>1__state = -4;
							if (<loadHandle>5__8.IsValid())
							{
								if ((int)<loadHandle>5__8.Status == 1)
								{
									<>4__this.AddToPool(<loadHandle>5__8.Result);
								}
								Addressables.Release<AudioClip>(<loadHandle>5__8);
							}
							<loadHandle>5__8 = default(AsyncOperationHandle<AudioClip>);
							<location>5__7 = null;
							break;
						}
						IL_015c:
						while (<>s__2.MoveNext())
						{
							<locator>5__3 = <>s__2.Current;
							<keys>5__4 = <locator>5__3.Keys.ToList();
							if (<keys>5__4.Count == 0)
							{
								continue;
							}
							<locHandle>5__5 = Addressables.LoadResourceLocationsAsync((IList<object>)<keys>5__4, (MergeMode)1, typeof(AudioClip));
							<>2__current = <locHandle>5__5;
							<>1__state = 2;
							return true;
						}
						<>m__Finally1();
						<>s__2 = null;
						<allLocations>5__1 = (from l in <allLocations>5__1
							group l by l.InternalId into g
							select g.First()).ToList();
						Plugin.Logger.LogInfo((object)$"[SoundRandomizer] Addressable clip locations: {<allLocations>5__1.Count}");
						<>s__6 = <allLocations>5__1.GetEnumerator();
						<>1__state = -4;
						break;
					}
					while (<>s__6.MoveNext())
					{
						<location>5__7 = <>s__6.Current;
						<loadHandle>5__8 = default(AsyncOperationHandle<AudioClip>);
						try
						{
							<loadHandle>5__8 = Addressables.LoadAssetAsync<AudioClip>(<location>5__7);
						}
						catch (Exception ex)
						{
							<ex>5__9 = ex;
							continue;
						}
						<>2__current = <loadHandle>5__8;
						<>1__state = 3;
						return true;
					}
					<>m__Finally2();
					<>s__6 = default(List<IResourceLocation>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__2 != null)
				{
					<>s__2.Dispose();
				}
			}

			private void <>m__Finally2()
			{
				<>1__state = -1;
				((IDisposable)<>s__6).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <InitCoroutine>d__7 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public SoundRandomizer <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InitCoroutine>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: Expected O, but got Unknown
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this.AddRangeToPool(Resources.FindObjectsOfTypeAll<AudioClip>());
					Plugin.Logger.LogInfo((object)$"[SoundRandomizer] Resources clips: {<>4__this.Pool.Count}");
					<>2__current = <>4__this.GetAllAddressableClips();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this.ResetMappings();
					Plugin.Logger.LogInfo((object)$"[SoundRandomizer] Total clips: {<>4__this.Pool.Count}");
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>4__this.RandomizeAllExistingAudioSources();
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					<>4__this.RandomizeAllExistingAudioSourc