Decompiled source of Bunject v1.1.1

Bunject.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using Bunburrows;
using Bunject.Internal;
using Bunject.Levels;
using Bunject.Monitoring;
using Bunject.Patches.PaqueretteActionResolverPatches;
using Bunject.Tiling;
using Bunject.Utility;
using Characters.Bunny;
using Characters.Bunny.Data;
using Dialogue;
using HarmonyLib;
using Levels;
using Misc;
using Newtonsoft.Json;
using PlatformSpecific;
using Saving;
using Saving.Architecture;
using Tiling.Behaviour;
using UnityEngine;
using UnityEngine.Tilemaps;
using VisualEffects;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Bunject")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Bunject")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2cdf8a36-d56d-43fc-a1a4-2e64ac6b8d90")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Bunject
{
	public interface IBunjectorPlugin
	{
		void OnAssetsLoaded();

		void OnProgressionLoaded(GeneralProgression progression);
	}
	public class BunjectAPI
	{
		private List<IBunjectorPlugin> bunjectors;

		public static string SaveFolder { get; set; }

		internal static BunjectAPI Instance { get; private set; }

		internal static ForwardingBunjector Forward { get; private set; }

		internal static IReadOnlyList<IBunjectorPlugin> Bunjectors => Instance.bunjectors;

		internal static IEnumerable<ITileSource> TileSources => Instance.bunjectors.OfType<ITileSource>();

		internal static IEnumerable<IMonitor> Monitors => Instance.bunjectors.OfType<IMonitor>();

		static BunjectAPI()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			SaveFolder = null;
			Forward = new ForwardingBunjector();
			Instance = new BunjectAPI();
			new Harmony("bunject.API").PatchAll(Assembly.GetAssembly(typeof(BunjectAPI)));
		}

		public static void RegisterPlugin(IBunjectorPlugin bunjector)
		{
			Instance.bunjectors.Add(bunjector);
		}

		public static void RegisterBunburrow(IModBunburrow modBunburrow)
		{
			BunburrowManager.RegisterBurrow(modBunburrow);
		}

		public static void RegisterElevator(int bunburrowID, int depth)
		{
			BunburrowManager.RegisterElevator(bunburrowID, depth);
		}

		private BunjectAPI()
		{
			bunjectors = new List<IBunjectorPlugin>();
		}
	}
}
namespace Bunject.Utility
{
	internal class InjectionDictionary<K, V> : Dictionary<K, V>, IDictionary<K, V>, ICollection<KeyValuePair<K, V>>, IEnumerable<KeyValuePair<K, V>>, IEnumerable where V : class
	{
		private Func<K, V, V> injector;

		public new V this[K key]
		{
			get
			{
				V value;
				V val = ((!base.TryGetValue(key, out value)) ? injector(key, null) : injector(key, value));
				if (val == null)
				{
					throw new KeyNotFoundException();
				}
				return val;
			}
			set
			{
				base[key] = value;
			}
		}

		public InjectionDictionary(Func<K, V, V> injector, IDictionary<K, V> source)
			: base(source)
		{
			this.injector = injector;
		}

		public new bool TryGetValue(K key, out V result)
		{
			result = null;
			if (base.TryGetValue(key, out result))
			{
				result = injector(key, result);
			}
			else
			{
				result = injector(key, null);
			}
			return result == null;
		}
	}
}
namespace Bunject.Tiling
{
	public abstract class BaseTileSourcePlugin : BaseUnityPlugin, ITileSource, IBunjectorPlugin
	{
		public abstract void Awake();

		public virtual void OnAssetsLoaded()
		{
		}

		public virtual void OnProgressionLoaded(GeneralProgression progression)
		{
		}

		public virtual LevelsList LoadEmergencyLevelsList(LevelsList original)
		{
			return original;
		}

		public abstract bool SupportsTile(string tile);

		public abstract Tile LoadTile(LevelObject levelObject, string tile, Vector2Int position);
	}
	public interface ITileSource : IBunjectorPlugin
	{
		bool SupportsTile(string tile);

		Tile LoadTile(LevelObject levelObject, string tile, Vector2Int position);
	}
	public interface IUpdateTileSprite
	{
		void UpdateTileSprite();
	}
	public sealed class Tile
	{
		public TileLevelData Instance { get; set; }

		public bool IsBunnyTile { get; set; }

		public bool IsStartTile { get; set; }

		public bool IsHoleTile { get; set; }

		public bool HasStartTrap { get; set; }

		public bool HasStartCarrot { get; set; }

		public Tile(TileLevelData instance)
		{
			Instance = instance;
		}
	}
	public static class TileValidator
	{
		private const string VALID_TILES = "^(S(?:{K})?|B(?:{[KB]*})?|E|F|D[0-9]|P[0-9]|N[0-9]+|\\!|Oph|X|C|T(?:{[URLDCTKBPS]+})?|W(?:{[URLD]*[0-9]?})?|R(?:{[URLD]*[0-9]?})?|EW|ER|PU|A|Y(?:{K})?)$";

		private static readonly Regex ValidTileRegex = new Regex("^(S(?:{K})?|B(?:{[KB]*})?|E|F|D[0-9]|P[0-9]|N[0-9]+|\\!|Oph|X|C|T(?:{[URLDCTKBPS]+})?|W(?:{[URLD]*[0-9]?})?|R(?:{[URLD]*[0-9]?})?|EW|ER|PU|A|Y(?:{K})?)$");

		private static readonly string[] Separators = new string[4] { ",", "\r\n", "\r", "\n" };

		public static List<string> GetTilesFromContent(string content)
		{
			return content.Split(Separators, StringSplitOptions.RemoveEmptyEntries).ToList();
		}

		public static bool ValidateTiles(string content)
		{
			return ValidateTiles(GetTilesFromContent(content));
		}

		public static bool ValidateTiles(IEnumerable<string> tiles)
		{
			bool flag = true;
			foreach (string tile in tiles)
			{
				flag &= ValidateTiles(tile);
			}
			return flag;
		}

		public static bool ValidateTile(string tile)
		{
			if (!ValidTileRegex.IsMatch(tile))
			{
				return BunjectAPI.Forward.SupportsTile(tile);
			}
			return true;
		}
	}
}
namespace Bunject.Patches
{
	[HarmonyPatch(typeof(BunniesReleaseAnimator), "StartRelease")]
	internal class BunniesReleaseAnimatorPatches
	{
		private static void Prefix()
		{
		}

		private static void Postfix()
		{
		}
	}
}
namespace Bunject.Patches.SettingsManagerPatches
{
	[HarmonyPatch(typeof(SettingsManager), "HandleBoot")]
	internal class HandleBootPatches
	{
		private static void Postfix()
		{
			BunjectAPI.Forward.OnAssetsLoaded();
		}
	}
}
namespace Bunject.Patches.SaveFileManipulationUtilityPatches
{
	[HarmonyPatch(typeof(SaveFileManipulationUtility), "GetRootSaveDataPath")]
	internal class GetRootSaveDataPathPatches
	{
		private static string Postfix(string __result)
		{
			if (!string.IsNullOrEmpty(BunjectAPI.SaveFolder))
			{
				return Path.Combine(__result, BunjectAPI.SaveFolder);
			}
			return __result;
		}
	}
}
namespace Bunject.Patches.ReleasedBunnyControllerPatches
{
	[HarmonyPatch(typeof(ReleasedBunnyController), "Initialize")]
	internal class InitializePatch
	{
		private static bool Prefix(ReleasedBunnyController __instance, BunnyIdentity bunnyIdentity, BunniesReleaseAnimator bunniesReleaseAnimator)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			if ((int)bunnyIdentity.Bunburrow < BunburrowManager.CustomBunburrowThreshold)
			{
				return true;
			}
			bunniesReleaseAnimator.NotifyBunnyInHole(__instance);
			Object.Destroy((Object)(object)((Component)__instance).gameObject);
			return false;
		}
	}
}
namespace Bunject.Patches.PlatformSpecificManagerPatches
{
	[HarmonyPatch(typeof(PlatformSpecificManager), "UnlockAchievement")]
	internal class UnlockAchievementPatches
	{
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(PlatformSpecificManager), "CheckAchievementsOnStart")]
	internal class CheckAchievementsOnStartPatches
	{
		private static bool Prefix()
		{
			return false;
		}
	}
}
namespace Bunject.Patches.PaqueretteActionResolverPatches
{
	[HarmonyPatch(typeof(PaqueretteActionResolver), "HandleTalkButtonPress")]
	internal class HandleTalkButtonPressPatches
	{
		public static Bunburrow? targetBurrow;

		private static MethodInfo GetBunburrowUnlockStatus = typeof(GeneralProgression).GetProperty("BunburrowsUnlockStatus").GetGetMethod();

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			int detectionState = 0;
			Label? label = default(Label?);
			foreach (CodeInstruction instruction in instructions)
			{
				switch (detectionState)
				{
				case 0:
					if (CodeInstructionExtensions.Calls(instruction, GetBunburrowUnlockStatus))
					{
						detectionState++;
					}
					break;
				case 1:
					if (CodeInstructionExtensions.Branches(instruction, ref label))
					{
						yield return instruction;
						yield return new CodeInstruction(OpCodes.Ldloc_3, (object)null);
						yield return CodeInstruction.Call(typeof(BunburrowSignController), "get_Bunburrow", (Type[])null, (Type[])null);
						yield return CodeInstruction.Call(typeof(HandleTalkButtonPressPatches), "ExtractBurrow", (Type[])null, (Type[])null);
						detectionState++;
						continue;
					}
					break;
				}
				yield return instruction;
			}
		}

		private static void ExtractBurrow(Bunburrow bunburrow)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			targetBurrow = bunburrow;
		}
	}
}
namespace Bunject.Patches.LevelsListPatches
{
	[HarmonyPatch]
	internal class IndexerPatch
	{
		private static MethodBase TargetMethod()
		{
			return typeof(LevelsList).GetProperties().First((PropertyInfo pi) => pi.GetIndexParameters().Length == 1).GetGetMethod();
		}

		private static Exception Finalizer(Exception __exception, ref LevelObject __result, LevelsList __instance, int depth)
		{
			if (__instance is ModLevelsList modLevelsList)
			{
				__result = modLevelsList.LoadLevel(depth, CurrentLoadingContext.Value);
			}
			if ((Object)(object)__result == (Object)null)
			{
				Console.WriteLine("Level Load Failure!  Deferring to Emergency Level");
				LevelsList val = BunjectAPI.Forward.LoadEmergencyLevelsList(null);
				if ((Object)(object)val != (Object)(object)__instance)
				{
					__result = val[depth];
				}
			}
			return null;
		}
	}
}
namespace Bunject.Patches.LevelLoaderPatches
{
	[HarmonyPatch(typeof(LevelLoader), "LoadLevel")]
	internal class LoadLevelPatch
	{
		private static bool Prefix(LevelObject levelObject, out List<string> __result)
		{
			List<string> tilesFromContent = TileValidator.GetTilesFromContent(levelObject.Content);
			foreach (string item in tilesFromContent)
			{
				if (!TileValidator.ValidateTile(item))
				{
					Debug.LogWarning((object)("Invalid tile string: " + item));
				}
			}
			__result = tilesFromContent;
			return false;
		}
	}
}
namespace Bunject.Patches.LevelIndicatorGeneratorPatches
{
	[HarmonyPatch(typeof(LevelIndicatorGenerator), "GetLongLevelIndicator")]
	internal class GetLongLevelIndicatorPatches
	{
		private static string Postfix(string __result, bool useWhite)
		{
			//IL_000a: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			LevelIdentity levelIdentity = GameManager.LevelStates.CurrentLevelState.LevelIdentity;
			if (levelIdentity.Bunburrow.IsCustomBunburrow())
			{
				string text = LevelIndicatorGenerator.GetShortLevelIndicator() + Traverse.Create(typeof(LevelIndicatorGenerator)).Method("GenerateBunniesStringForLevelIndicator", new object[1] { useWhite }).GetValue<string>() + " ";
				string customNameKey = GameManager.CurrentLevel.BaseData.CustomNameKey;
				return text + ((BunburrowExtension.IsVoidBunburrow(levelIdentity.Bunburrow) && string.IsNullOrWhiteSpace(customNameKey)) ? LevelIndicatorGenerator.GenerateVoidLevelName("") : customNameKey);
			}
			return __result;
		}
	}
	[HarmonyPatch(typeof(LevelIndicatorGenerator), "GetLevelBunburrowStyle")]
	internal class GetLevelBunburrowStylePatch
	{
		public static BunburrowStyle Postfix(BunburrowStyle __result, LevelIdentity levelIdentity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (levelIdentity.Bunburrow.IsCustomBunburrow())
			{
				return AssetsManager.LevelsLists[BunburrowExtension.ToBunburrowName(levelIdentity.Bunburrow)][levelIdentity.Depth].BunburrowStyle;
			}
			return __result;
		}
	}
}
namespace Bunject.Patches.LevelBuilderPatches
{
	[HarmonyPatch]
	internal class BuildNewLevelPatch_SupportMoreSurfaceEntries
	{
		private static MethodInfo TargetMethod()
		{
			return typeof(LevelBuilder).GetMethod("BuildNewLevel", new Type[3]
			{
				typeof(LevelObject),
				typeof(BunburrowStyle),
				typeof(bool)
			});
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo startsWith = typeof(string).GetMethod("StartsWith", new Type[1] { typeof(string) });
			MethodInfo get_Chars = typeof(string).GetProperty("Chars").GetGetMethod();
			MethodInfo char_ToString = typeof(char).GetMethod("ToString", new Type[0]);
			int detectionStage = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				CodeInstruction val = instruction;
				switch (detectionStage)
				{
				case 0:
					if (val.opcode == OpCodes.Ldstr && (string)val.operand == "N")
					{
						detectionStage = 1;
					}
					break;
				case 1:
					detectionStage = (CodeInstructionExtensions.Calls(val, startsWith) ? 2 : 0);
					break;
				case 2:
					if (CodeInstructionExtensions.Calls(val, get_Chars))
					{
						detectionStage = 3;
						val = CodeInstruction.Call(typeof(string), "Substring", new Type[1] { typeof(int) }, (Type[])null);
					}
					break;
				case 3:
					if (CodeInstructionExtensions.Calls(val, char_ToString))
					{
						detectionStage = 4;
					}
					continue;
				}
				yield return val;
			}
		}
	}
}
namespace Bunject.Patches.GeneralProgressionPatches
{
	[HarmonyPatch(typeof(GeneralProgression), "GetVoidlessPillarsProgress")]
	internal class GetVoidlesssPillarsProgressPatch
	{
		private static MethodInfo IsVoidBunburrow = typeof(BunburrowExtension).GetMethod("IsVoidBunburrow");

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, IsVoidBunburrow))
				{
					yield return CodeInstruction.Call(typeof(CustomBunburrowExtension), "IsVoidOrCustomBunburrow", (Type[])null, (Type[])null);
				}
				else
				{
					yield return instruction;
				}
			}
		}
	}
	[HarmonyPatch(typeof(GeneralProgression), "GetNonVoidBunniesCount")]
	internal class GetNonVoidBunniesCountPatches
	{
		private static MethodInfo IsNonVoidBunburrow = typeof(BunburrowExtension).GetMethod("IsNonVoidBunburrow");

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, IsNonVoidBunburrow))
				{
					yield return CodeInstruction.Call(typeof(CustomBunburrowExtension), "IsCoreBunburrow", (Type[])null, (Type[])null);
				}
				else
				{
					yield return instruction;
				}
			}
		}
	}
	[HarmonyPatch(typeof(GeneralProgression), "FreeAllNonVoidBunnies")]
	internal class FreeAllNonVoidBunniesPatches
	{
		private static void Postfix()
		{
			BunnyReleaser.NotifyReleased();
		}
	}
	[HarmonyPatch(typeof(GeneralProgression), "FreeBunniesFromBunburrow")]
	internal class FreeBunniesFromBunburrowPatches
	{
		private static void Postfix()
		{
			BunnyReleaser.NotifyReleased();
		}
	}
	[HarmonyPatch(typeof(GeneralProgression), "HandleElevatorUnlock")]
	internal class HandleElevatorUnlockPatch
	{
		public static void Postfix(GeneralProgression __instance)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (ElevatorManager.ElevatorUnlock(GameManager.LevelStates.CurrentLevelState.LevelIdentity, out var elevatorData) && !CollectionExtension.ContainsEquatable<string>((IEnumerable<string>)__instance.UnlockedElevators, elevatorData))
			{
				Traverse.Create((object)__instance).Field<List<string>>("unlockedElevators").Value.Add(elevatorData);
			}
		}
	}
}
namespace Bunject.Patches.GameManagerPatches
{
	[HarmonyPatch(typeof(GameManager), "HandleDialogueEvent")]
	internal class HandleDialogueEventPatches
	{
		private static void Prefix(string eventKey, ref Bunburrow? bunburrowInfo)
		{
			if (eventKey == "release")
			{
				bunburrowInfo = HandleTalkButtonPressPatches.targetBurrow;
				HandleTalkButtonPressPatches.targetBurrow = null;
			}
		}
	}
	[HarmonyPatch(typeof(GameManager), "HandleRappelling")]
	internal class HandleRappellingPatches
	{
		private static MethodInfo StartLevelTransition = typeof(GameManager).GetMethod("StartLevelTransition", BindingFlags.Static | BindingFlags.NonPublic);

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			int state = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				switch (state)
				{
				case 0:
					if (CodeInstructionExtensions.Calls(instruction, StartLevelTransition))
					{
						state++;
					}
					break;
				case 1:
					if (CodeInstructionExtensions.Calls(instruction, StartLevelTransition))
					{
						yield return CodeInstruction.Call(typeof(HandleRappellingPatches), "StartLevelRappellingTransition", (Type[])null, (Type[])null);
						state++;
						continue;
					}
					break;
				}
				yield return instruction;
			}
		}

		private static void StartLevelRappellingTransition(LevelObject surfaceLevel, LevelTransitionType levelTransitionType, LevelIdentity levelIdentity, LevelIdentity? elevatorTargetLevelIdentity)
		{
			//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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Bunburrow value = Traverse.Create<GameManager>().Field<Bunburrow>("previousBunburrow").Value;
			LevelObject val = BunjectAPI.Forward.LoadBurrowSurfaceLevel(((Object)AssetsManager.LevelsLists[BunburrowExtension.ToBunburrowName(value)]).name, surfaceLevel);
			StartLevelTransition.Invoke(null, new object[4] { val, levelTransitionType, levelIdentity, elevatorTargetLevelIdentity });
		}
	}
	[HarmonyPatch(typeof(GameManager), "StartLevelTransition")]
	internal class StartLevelTransitionPatches
	{
		private static void Prefix(ref LevelObject levelObject, LevelIdentity levelIdentity)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			levelObject = BunjectAPI.Forward.StartLevelTransition(levelObject, levelIdentity);
		}
	}
	[HarmonyPatch(typeof(GameManager), "set_GeneralProgression")]
	internal class SetGeneralProgressionPatches
	{
		private static void Prefix(GeneralProgression value)
		{
			BunjectAPI.Forward.OnProgressionLoaded(value);
		}
	}
	[HarmonyPatch(typeof(GameManager), "HandleSurfaceElevatorUse")]
	internal class HandleSurfaceElevatorUsePatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo TryGetValue = AccessTools.Method(typeof(IReadOnlyDictionary<string, LevelIdentity>), "TryGetValue", (Type[])null, (Type[])null);
			int num = list.FindIndex((CodeInstruction x) => CodeInstructionExtensions.Calls(x, TryGetValue));
			Label? label = default(Label?);
			if (num >= 0 && num + 2 < list.Count && CodeInstructionExtensions.Branches(list[num + 1], ref label))
			{
				Label label2 = il.DefineLabel();
				list.Insert(num + 2, CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Nop, (object)null), new Label[1] { label2 }));
				list.InsertRange(num + 1, new List<CodeInstruction>
				{
					new CodeInstruction(OpCodes.Brtrue, (object)label2),
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Ldloca, (object)0),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(HandleSurfaceElevatorUsePatch), "Infix", (Type[])null, (Type[])null))
				});
			}
			return list;
		}

		private static bool Infix(string elevatorName, out LevelIdentity level)
		{
			return ElevatorManager.IsElevatorUnlock(elevatorName, out level);
		}
	}
	[HarmonyPatch(typeof(GameManager), "Init")]
	internal class Init
	{
		public static IEnumerator Postfix(IEnumerator __result)
		{
			while (__result.MoveNext())
			{
				yield return __result.Current;
			}
			yield return ElevatorManager.ExtractElevatorProgression();
		}
	}
	[HarmonyPatch(typeof(GameManager), "InstantiateBunburrowEntrySigns")]
	internal class InstantiateBunburrowEntrySignsPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			MethodInfo tileLevelData_LeftTile = AccessTools.PropertyGetter(typeof(TileLevelData), "LeftTile");
			int state = 0;
			foreach (CodeInstruction code in instructions)
			{
				yield return code;
				switch (state)
				{
				case 0:
					if (CodeInstructionExtensions.Calls(code, tileLevelData_LeftTile))
					{
						state = 1;
					}
					break;
				case 1:
					if (CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null))
					{
						yield return new CodeInstruction(OpCodes.Ldloc_2, (object)null);
						yield return new CodeInstruction(OpCodes.Ldloc_3, (object)null);
						yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(InstantiateBunburrowEntrySignsPatch), "GetSignTile", (Type[])null, (Type[])null));
						yield return new CodeInstruction(OpCodes.Stloc_3, (object)null);
						state = 2;
					}
					break;
				}
			}
		}

		private static FloorTile GetSignTile(BunburrowEntryTile currentHole, FloorTile otherwise)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			FloorTile val = otherwise;
			Bunburrow? bunburrow = currentHole.Bunburrow;
			if (bunburrow.HasValue)
			{
				Bunburrow valueOrDefault = bunburrow.GetValueOrDefault();
				if (valueOrDefault.IsCustomBunburrow())
				{
					IModBunburrow modBunburrow = valueOrDefault.GetModBunburrow();
					if (modBunburrow != null)
					{
						if (!modBunburrow.HasSign)
						{
							val = null;
						}
						else if (!modBunburrow.HasEntrance)
						{
							val = (FloorTile)(object)currentHole;
						}
						else
						{
							Vector2Int? val2 = modBunburrow.OverrideSignCoordinate();
							if (val2.HasValue)
							{
								Vector2Int valueOrDefault2 = val2.GetValueOrDefault();
								TileLevelData tileInListByCoordinates = LevelBuilderExtensions.GetTileInListByCoordinates(GameManager.CurrentLevel.Tiles.ToList(), ((Vector2Int)(ref valueOrDefault2)).y, ((Vector2Int)(ref valueOrDefault2)).x);
								val = (FloorTile)(((object)((tileInListByCoordinates is FloorTile) ? tileInListByCoordinates : null)) ?? ((object)val));
							}
						}
					}
				}
			}
			return val;
		}
	}
	[HarmonyPatch(typeof(GameManager), "LoadLevel")]
	internal class LoadLevelPatches
	{
		public static void Prefix(ref LevelObject levelObject, LevelIdentity levelIdentity, LevelTransitionType levelTransitionType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if ((int)levelTransitionType == 3 || !levelIdentity.Bunburrow.IsCustomBunburrow())
			{
				return;
			}
			IModBunburrow modBunburrow = levelIdentity.Bunburrow.GetModBunburrow();
			if (modBunburrow == null)
			{
				return;
			}
			LevelsList levels = modBunburrow.GetLevels();
			if (levels == null)
			{
				return;
			}
			LoadingContext value = CurrentLoadingContext.Value;
			try
			{
				CurrentLoadingContext.Value = LoadingContext.LevelTransition;
				levelObject = levels[levelIdentity.Depth];
			}
			finally
			{
				CurrentLoadingContext.Value = value;
			}
		}
	}
}
namespace Bunject.Patches.TileLevelDataPatches
{
	[HarmonyPatch(typeof(TileLevelData), "UpdateTileSprite")]
	internal class UpdateTileSpritePatch
	{
		private static bool Prefix(TileLevelData __instance)
		{
			if (__instance is IUpdateTileSprite updateTileSprite)
			{
				updateTileSprite.UpdateTileSprite();
				return false;
			}
			return true;
		}
	}
}
namespace Bunject.Patches.ChoiceSelectorPatches
{
	[HarmonyPatch(typeof(ChoiceSelector), "StartListeningToInputs")]
	internal class StartListeningToInputsPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo GeneralInputManager = AccessTools.Property(typeof(GameManager), "GeneralInputManager").GetGetMethod();
			List<Label> labels = list.FindLast((CodeInstruction x) => CodeInstructionExtensions.Calls(x, GeneralInputManager))?.labels;
			if (labels != null)
			{
				int num = list.FindIndex((CodeInstruction x) => labels.Any((Label y) => y.Equals(x.operand)));
				if (num >= 0)
				{
					list.InsertRange(num, new List<CodeInstruction>
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(StartListeningToInputsPatch), "Infix", (Type[])null, (Type[])null))
					});
				}
			}
			return list;
		}

		private static void Infix(ChoiceSelector @this)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00e5: 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)
			List<ChoiceObject> list = new List<ChoiceObject>();
			List<LevelIdentity> list2 = new List<LevelIdentity>();
			foreach (string unlockedElevator in GameManager.GeneralProgression.UnlockedElevators)
			{
				if (ElevatorManager.IsElevatorUnlock(unlockedElevator, out var level))
				{
					list2.Add(level);
					list.Add(new ChoiceObject(unlockedElevator, unlockedElevator, false));
				}
			}
			IReadOnlyList<ChoiceObject> readOnlyList = list;
			Traverse obj = Traverse.Create((object)@this);
			List<ChoiceLineController> value = obj.Field<List<ChoiceLineController>>("choicesLineControllers").Value;
			RectTransform value2 = obj.Field<RectTransform>("contentRectTransform").Value;
			for (int i = 0; i < readOnlyList.Count; i++)
			{
				LevelIdentity val = list2[i];
				BunburrowStyle levelBunburrowStyle = LevelIndicatorGenerator.GetLevelBunburrowStyle(val);
				ChoiceLineController component = Object.Instantiate<GameObject>(AssetsManager.ChoiceLinePrefab, (Transform)(object)value2).GetComponent<ChoiceLineController>();
				value.Add(component);
				component.Init(readOnlyList[i], LevelIndicatorGenerator.GetShortLevelIndicator(val));
				component.UpdateStyle(Color.black, levelBunburrowStyle.SkyboxColor, levelBunburrowStyle.UIWhiteColor, levelBunburrowStyle.ButtonDefaultColor, levelBunburrowStyle.FlowerSprite);
			}
		}
	}
}
namespace Bunject.Patches.BunburrowSignControllerPatches
{
	[HarmonyPatch(typeof(BunburrowSignController), "Init")]
	internal class InitPatch
	{
		public static void Postfix(BunburrowSignController __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			Bunburrow bunburrow = __instance.Bunburrow;
			if (bunburrow.IsCustomBunburrow() && !BunburrowExtension.IsVoidBunburrow(__instance.Bunburrow) && AssetsManager.LevelsLists[BunburrowExtension.ToBunburrowName(bunburrow)].Length > 0)
			{
				BunburrowStyle bunburrowStyle = AssetsManager.LevelsLists[BunburrowExtension.ToBunburrowName(bunburrow)][1].BunburrowStyle;
				Traverse val = Traverse.Create((object)__instance);
				val.Field<SpriteRenderer>("progressFirstDigitSpriteRenderer").Value.color = bunburrowStyle.SkyboxColor;
				val.Field<SpriteRenderer>("progressSecondDigitSpriteRenderer").Value.color = bunburrowStyle.SkyboxColor;
				val.Field<SpriteRenderer>("progressPercentSpriteRenderer").Value.color = bunburrowStyle.SkyboxColor;
				val.Field<SpriteRenderer>("requirementFirstDigitSpriteRenderer").Value.color = bunburrowStyle.SkyboxColor;
				val.Field<SpriteRenderer>("requirementSecondDigitSpriteRenderer").Value.color = bunburrowStyle.SkyboxColor;
				val.Field<SpriteRenderer>("completeIconSpriteRenderer").Value.color = bunburrowStyle.SignCompleteIconColor;
				val.Field<SpriteRenderer>("homeIconSpriteRenderer").Value.color = bunburrowStyle.SignHomeIconColor;
				((Renderer)val.Field<SpriteRenderer>("sign").Value).material.SetInt(val.Field<int>("ShouldGlitchHash").Value, 0);
				__instance.UpdateContent();
			}
		}
	}
}
namespace Bunject.Patches.BunburrowExtensionPatches
{
	[HarmonyPatch(typeof(BunburrowExtension), "ToBunburrow", new Type[] { typeof(string) })]
	internal class ToBunburrowStringPatch
	{
		public static Bunburrow Postfix(Bunburrow __result, string bunburrowName)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			return ((Bunburrow?)BunburrowManager.Bunburrows.FirstOrDefault((BunburrowMetadata bb) => bb.ModBunburrow?.Name == bunburrowName)?.ID).GetValueOrDefault(__result);
		}
	}
	[HarmonyPatch(typeof(BunburrowExtension), "ToBunburrow", new Type[] { typeof(int) })]
	internal class ToBunburrowIntPatch
	{
		private static Bunburrow Postfix(Bunburrow __result, int bunburrowID)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (((Bunburrow)bunburrowID).IsCustomBunburrow())
			{
				return (Bunburrow)bunburrowID;
			}
			return __result;
		}
	}
	[HarmonyPatch(typeof(BunburrowExtension), "ToBunburrowName")]
	internal class ToBunburrowNamePatch
	{
		private static string Postfix(string __result, Bunburrow bunburrow)
		{
			//IL_0007: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			if (bunburrow.IsCustomBunburrow())
			{
				return BunburrowManager.Bunburrows.FirstOrDefault((BunburrowMetadata bb) => bb.ID == (int)bunburrow)?.ModBunburrow.Name;
			}
			return __result;
		}
	}
	[HarmonyPatch(typeof(BunburrowExtension), "ToComparisonIndex")]
	internal class ToComparisonIndexPatch
	{
		private static int Postfix(int __result, Bunburrow bunburrow)
		{
			//IL_0007: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			if (bunburrow.IsCustomBunburrow())
			{
				return BunburrowManager.Bunburrows.FirstOrDefault((BunburrowMetadata bb) => bb.ID == (int)bunburrow)?.ComparisonIndex ?? __result;
			}
			return __result;
		}
	}
	[HarmonyPatch(typeof(BunburrowExtension), "ToIndicator")]
	internal class ToIndicatorPatch
	{
		private static string Postfix(string __result, Bunburrow bunburrow)
		{
			//IL_0007: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			if (bunburrow.IsCustomBunburrow())
			{
				return BunburrowManager.Bunburrows.FirstOrDefault((BunburrowMetadata bb) => bb.ID == (int)bunburrow)?.ModBunburrow?.Indicator;
			}
			return __result;
		}
	}
	[HarmonyPatch(typeof(BunburrowExtension), "IsNonVoidBunburrow")]
	internal class IsNonVoidBunburrowPatch
	{
		private static bool Postfix(bool __result, Bunburrow bunburrow)
		{
			//IL_0000: 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)
			if (bunburrow.IsCustomBunburrow())
			{
				return !BunburrowExtension.IsVoidBunburrow(bunburrow);
			}
			return __result;
		}
	}
	[HarmonyPatch(typeof(BunburrowExtension), "IsVoidBunburrow")]
	internal class IsVoidBunburrowPatch
	{
		private static bool Postfix(bool __result, Bunburrow bunburrow)
		{
			//IL_0007: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			if (bunburrow.IsCustomBunburrow())
			{
				return (BunburrowManager.Bunburrows.FirstOrDefault((BunburrowMetadata bb) => bb.ID == (int)bunburrow)?.ModBunburrow?.IsVoid).GetValueOrDefault(__result);
			}
			return __result;
		}
	}
}
namespace Bunject.Patches.BunburrowEntryTilePatches
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal class ConstructorPatch
	{
		private static void Postfix(BunburrowEntryTile __instance)
		{
			Traverse val = Traverse.Create((object)__instance);
			Traverse<int> val2 = val.Field<int>("specialIndex");
			if (val2.Value > 10)
			{
				val.Field<Bunburrow?>("Bunburrow").Value = (Bunburrow)val2.Value;
				val.Field("isUnlocked").SetValue((object)true);
				val2.Value = -1;
			}
		}
	}
	[HarmonyPatch(typeof(BunburrowEntryTile), "HandleLevelReset")]
	internal class HandleLevelResetPatch
	{
		private static void Postfix(BunburrowEntryTile __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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)
			if (__instance.Bunburrow.HasValue && __instance.Bunburrow.Value.IsCustomBunburrow())
			{
				IModBunburrow modBunburrow = __instance.Bunburrow.Value.GetModBunburrow();
				if (modBunburrow != null && !modBunburrow.HasEntrance)
				{
					GameManager.TileMaps.ExitsTileMap.SetTile(VectorConversions.ToVector3Int(((TileLevelData)__instance).Position), (TileBase)null);
				}
			}
		}
	}
}
namespace Bunject.Patches.AssetsManagerPatches
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal class LevelsListsPatch
	{
		private static void Prefix(ref ReadOnlyDictionary<string, LevelsList> value)
		{
			value = new ReadOnlyDictionary<string, LevelsList>(new InjectionDictionary<string, LevelsList>(AssetsManagerRewiring.LoadLevelsList, value));
		}
	}
}
namespace Bunject.Patches.VisualEffectsPatches
{
	[HarmonyPatch(typeof(VisualEffectsController), "UpdateVisualEffects", new Type[] { typeof(VisualEffectsInfo) })]
	internal class UpdateVisualEffectsPatch
	{
		[HarmonyPriority(600)]
		private static void Prefix(ref VisualEffectsInfo visualEffectsInfo)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Bunburrow? bunburrow = visualEffectsInfo.Bunburrow;
			if (bunburrow.HasValue)
			{
				Bunburrow valueOrDefault = bunburrow.GetValueOrDefault();
				if (valueOrDefault.IsCustomBunburrow())
				{
					LevelObject val = AssetsManager.LevelsLists[BunburrowExtension.ToBunburrowName(valueOrDefault)][visualEffectsInfo.Depth];
					visualEffectsInfo = new VisualEffectsInfo((Bunburrow?)val.BunburrowStyle.Bunburrow, visualEffectsInfo.Depth, val.IsHell, val.IsTemple, false);
				}
			}
		}
	}
}
namespace Bunject.Patches.BunburrowsListOfStylesPatches
{
	[HarmonyPatch]
	internal class IndexerPatch
	{
		private static MethodBase TargetMethod()
		{
			return typeof(BunburrowsListOfStyles).GetProperties().First((PropertyInfo pi) => pi.GetIndexParameters().Length == 1).GetGetMethod();
		}

		private static BunburrowStyle Postfix(BunburrowStyle __result, Bunburrow bunburrow)
		{
			//IL_0007: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			if (bunburrow.IsCustomBunburrow())
			{
				return BunburrowManager.Bunburrows.FirstOrDefault((BunburrowMetadata bb) => bb.ID == (int)bunburrow)?.ModBunburrow?.Style ?? __result;
			}
			return __result;
		}
	}
}
namespace Bunject.Monitoring
{
	public interface IMonitor : IBunjectorPlugin
	{
		LevelObject StartLevelTransition(LevelObject level, LevelIdentity identity);

		LevelsList LoadEmergencyLevelsList(LevelsList original);
	}
}
namespace Bunject.Levels
{
	internal class CoreBunburrow : IModBunburrow
	{
		private LevelsList levels;

		public string Name { get; }

		public string Indicator { get; }

		public bool IsVoid { get; }

		public int ID { get; set; }

		public BunburrowStyle Style { get; }

		public bool HasEntrance => true;

		public bool HasSign => true;

		public CoreBunburrow(string name, string indicator, bool isVoid)
		{
			Name = name;
			Indicator = indicator;
			IsVoid = isVoid;
		}

		public Vector2Int? OverrideSignCoordinate()
		{
			return null;
		}

		public LevelsList GetLevels()
		{
			if ((Object)(object)levels == (Object)null)
			{
				levels = AssetsManager.LevelsLists[Name];
			}
			return levels;
		}

		public LevelObject GetLevel(int depth)
		{
			return GetLevels()[depth];
		}

		public LevelObject GetSurfaceLevel()
		{
			return AssetsManager.SurfaceRightLevel;
		}
	}
	public interface IModBunburrow
	{
		int ID { get; set; }

		string Name { get; }

		string Indicator { get; }

		bool IsVoid { get; }

		BunburrowStyle Style { get; }

		bool HasEntrance { get; }

		bool HasSign { get; }

		Vector2Int? OverrideSignCoordinate();

		LevelsList GetLevels();

		LevelObject GetSurfaceLevel();
	}
	public enum LoadingContext
	{
		Metadata,
		LevelTransition
	}
	internal static class CurrentLoadingContext
	{
		public static LoadingContext Value { get; set; }
	}
	public class ModLevelObject : LevelObject
	{
		private Traverse traverse;

		public string BunburrowName { get; set; }

		public int Depth { get; set; }

		private Traverse Traverse
		{
			get
			{
				if (traverse == null)
				{
					traverse = Traverse.Create((object)this);
				}
				return traverse;
			}
		}

		public string CustomNameKey
		{
			get
			{
				return ((LevelObject)this).CustomNameKey;
			}
			set
			{
				Traverse.Field<string>("customNameKey").Value = value;
			}
		}

		public string Content
		{
			get
			{
				return ((LevelObject)this).Content;
			}
			set
			{
				Traverse.Field<string>("content").Value = value;
			}
		}

		public int NumberOfTraps
		{
			get
			{
				return ((LevelObject)this).NumberOfTraps;
			}
			set
			{
				Traverse.Field<int>("numberOfTraps").Value = value;
			}
		}

		public int NumberOfPickaxes
		{
			get
			{
				return ((LevelObject)this).NumberOfPickaxes;
			}
			set
			{
				Traverse.Field<int>("numberOfPickaxes").Value = value;
			}
		}

		public int NumberOfShovels
		{
			get
			{
				return ((LevelObject)this).NumberOfShovels;
			}
			set
			{
				Traverse.Field<int>("numberOfShovels").Value = value;
			}
		}

		public int NumberOfCarrots
		{
			get
			{
				return ((LevelObject)this).NumberOfCarrots;
			}
			set
			{
				Traverse.Field<int>("numberOfCarrots").Value = value;
			}
		}

		public BunburrowStyle BunburrowStyle
		{
			get
			{
				return ((LevelObject)this).BunburrowStyle;
			}
			set
			{
				Traverse.Field<BunburrowStyle>("bunburrowStyle").Value = value;
			}
		}

		public Sprite SpecificBackground
		{
			get
			{
				return ((LevelObject)this).SpecificBackground;
			}
			set
			{
				Traverse.Field<Sprite>("specificBackground").Value = value;
			}
		}

		public bool IsTemple
		{
			get
			{
				return ((LevelObject)this).IsTemple;
			}
			set
			{
				Traverse.Field<bool>("isTemple").Value = value;
			}
		}

		public bool IsHell
		{
			get
			{
				return ((LevelObject)this).IsHell;
			}
			set
			{
				Traverse.Field<bool>("isHell").Value = value;
			}
		}

		public bool IsSurface
		{
			get
			{
				return ((LevelObject)this).IsSurface;
			}
			set
			{
				Traverse.Field<bool>("isSurface").Value = value;
			}
		}

		public DirectionsListOf<LevelObject> SideLevels
		{
			get
			{
				return ((LevelObject)this).SideLevels;
			}
			set
			{
				Traverse.Field<DirectionsListOf<LevelObject>>("sideLevels").Value = value;
			}
		}

		public ModLevelObject()
		{
			Traverse.Field("dialogues").SetValue((object)new List<DialogueObject>());
			Traverse.Field("contextualDialogues").SetValue((object)new List<ContextualDialogueInfo>());
			SideLevels = new DirectionsListOf<LevelObject>((LevelObject)null, (LevelObject)null, (LevelObject)null, (LevelObject)null);
		}
	}
	public class ModLevelsList : LevelsList
	{
		private Traverse traverse;

		private Traverse<List<LevelObject>> traverseList;

		protected Traverse Traverse
		{
			get
			{
				if (traverse == null)
				{
					traverse = Traverse.Create((object)this);
				}
				return traverse;
			}
		}

		public int NumberOfRegularBunnies
		{
			get
			{
				return ((LevelsList)this).NumberOfRegularBunnies;
			}
			set
			{
				Traverse.Field<int>("numberOfRegularBunnies").Value = value;
			}
		}

		public int NumberOfTempleBunnies
		{
			get
			{
				return ((LevelsList)this).NumberOfTempleBunnies;
			}
			set
			{
				Traverse.Field<int>("numberOfTempleBunnies").Value = value;
			}
		}

		public int NumberOfHellBunnies
		{
			get
			{
				return ((LevelsList)this).NumberOfHellBunnies;
			}
			set
			{
				Traverse.Field<int>("numberOfHellBunnies").Value = value;
			}
		}

		public DirectionsListOf<LevelsList> AdjacentBunburrows
		{
			get
			{
				return ((LevelsList)this).AdjacentBunburrows;
			}
			set
			{
				Traverse.Field<DirectionsListOf<LevelsList>>("adjacentBunburrows").Value = value;
			}
		}

		public int TempleStartDepth
		{
			get
			{
				return ((LevelsList)this).TempleStartDepth;
			}
			set
			{
				Traverse.Field<int>("templeStartDepth").Value = value;
			}
		}

		public int HellStartDepth
		{
			get
			{
				return ((LevelsList)this).HellStartDepth;
			}
			set
			{
				Traverse.Field<int>("hellStartDepth").Value = value;
			}
		}

		private Traverse<List<LevelObject>> TraverseList
		{
			get
			{
				if (traverseList == null)
				{
					traverseList = Traverse.Field<List<LevelObject>>("list");
				}
				return traverseList;
			}
		}

		protected List<LevelObject> List => traverseList.Value;

		public int MaximumDepth
		{
			get
			{
				return TraverseList.Value.Count;
			}
			set
			{
				List<LevelObject> value2 = TraverseList.Value;
				if (value < value2.Count)
				{
					value2.RemoveRange(value, value2.Count - value);
				}
				else
				{
					value2.AddRange((IEnumerable<LevelObject>)(object)new LevelObject[value - value2.Count]);
				}
			}
		}

		public ModLevelObject this[int depth]
		{
			get
			{
				return TraverseList.Value[depth - 1] as ModLevelObject;
			}
			set
			{
				TraverseList.Value[depth - 1] = (LevelObject)(object)value;
			}
		}

		public ModLevelsList()
		{
			TraverseList.Value = new List<LevelObject>();
			AdjacentBunburrows = new DirectionsListOf<LevelsList>((LevelsList)null, (LevelsList)null, (LevelsList)null, (LevelsList)null);
		}

		public virtual LevelObject LoadLevel(int depth, LoadingContext loadingContext)
		{
			return (LevelObject)(object)this[depth];
		}
	}
}
namespace Bunject.Internal
{
	internal class AssetsManagerRewiring
	{
		internal static LevelsList LoadLevelsList(string name, LevelsList original)
		{
			LevelsList val = original;
			if ((Object)(object)original == (Object)null || original is ModLevelsList)
			{
				val = (LevelsList)(object)BunjectAPI.Forward.LoadLevelsList(name, original as ModLevelsList);
			}
			if ((Object)(object)val == (Object)null)
			{
				return BunjectAPI.Forward.LoadEmergencyLevelsList(null);
			}
			return val;
		}
	}
	internal static class BunnyReleaser
	{
		public static void NotifyReleased()
		{
			Delegate[] invocationList = Traverse.Create((object)GameManager.BunniesReleaseAnimator).Field<MulticastDelegate>("OnBunnyReleased").Value.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				@delegate.Method.Invoke(@delegate.Target, new object[1] { false });
			}
		}
	}
	internal class BunburrowMetadata
	{
		public int ID { get; set; }

		public int ComparisonIndex { get; set; }

		public bool IsCustom { get; set; }

		public IModBunburrow ModBunburrow { get; set; }

		public List<int> Elevators { get; set; } = new List<int>();

	}
	internal class BunburrowManager
	{
		private static BunburrowManager instance;

		private List<BunburrowMetadata> bunburrows;

		private int maxID;

		internal static bool IsInitialized => instance != null;

		internal static IReadOnlyList<BunburrowMetadata> Bunburrows
		{
			get
			{
				if (!IsInitialized)
				{
					instance = new BunburrowManager();
				}
				return instance.bunburrows;
			}
		}

		public static int CustomBunburrowThreshold => 50;

		internal static void RegisterBurrow(IModBunburrow modBunburrow)
		{
			if (Bunburrows.Any((BunburrowMetadata bb) => bb.ModBunburrow.Name == modBunburrow.Name))
			{
				throw new ArgumentException("Bunburrow name " + modBunburrow.Name + " is already in use!  Please use a unique name.");
			}
			int num = ++instance.maxID;
			modBunburrow.ID = num;
			BunburrowMetadata item = new BunburrowMetadata
			{
				ID = num,
				ComparisonIndex = num,
				IsCustom = true,
				ModBunburrow = modBunburrow
			};
			instance.bunburrows.Add(item);
		}

		internal static void RegisterElevator(int bunburrowID, int depth)
		{
			BunburrowMetadata? obj = Bunburrows.FirstOrDefault((BunburrowMetadata x) => x.ID == bunburrowID) ?? throw new ArgumentException($"Bunburrow id {bunburrowID} does not exist!  Please use an existing id.");
			if (obj.Elevators.Contains(depth))
			{
				throw new ArgumentException($"Bunburrow depth {depth} already contains elevator!  Please use a depth without one.");
			}
			obj.Elevators.Add(depth);
		}

		private BunburrowManager()
		{
			bunburrows = (from burrowEnum in Enum.GetValues(typeof(Bunburrow)).OfType<Bunburrow>()
				select new BunburrowMetadata
				{
					ID = (int)burrowEnum,
					ComparisonIndex = BunburrowExtension.ToComparisonIndex(burrowEnum),
					IsCustom = false,
					ModBunburrow = new CoreBunburrow(BunburrowExtension.ToBunburrowName(burrowEnum), BunburrowExtension.ToIndicator(burrowEnum), BunburrowExtension.IsVoidBunburrow(burrowEnum))
				}).ToList();
			maxID = bunburrows.Max((BunburrowMetadata bb) => bb.ID) + CustomBunburrowThreshold;
		}
	}
	public static class CustomBunburrowExtension
	{
		public static bool IsVoidOrCustomBunburrow(this Bunburrow bunburrow)
		{
			//IL_0000: 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)
			if (!bunburrow.IsCustomBunburrow())
			{
				return BunburrowExtension.IsVoidBunburrow(bunburrow);
			}
			return true;
		}

		public static bool IsCoreBunburrow(this Bunburrow bunburrow)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return !bunburrow.IsVoidOrCustomBunburrow();
		}

		public static bool IsCustomBunburrow(this Bunburrow bunburrow)
		{
			//IL_0007: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			if ((int)bunburrow > BunburrowManager.CustomBunburrowThreshold)
			{
				return BunburrowManager.Bunburrows.Any((BunburrowMetadata x) => x.ID == (int)bunburrow);
			}
			return false;
		}

		public static IModBunburrow GetModBunburrow(this Bunburrow bunburrow)
		{
			//IL_0007: 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)
			return BunburrowManager.Bunburrows.FirstOrDefault((BunburrowMetadata x) => x.ID == (int)bunburrow)?.ModBunburrow;
		}

		public static IEnumerable<Bunburrow> GetRegularAndCustomBunbrrowEnumerator()
		{
			foreach (BunburrowMetadata bunburrow in BunburrowManager.Bunburrows)
			{
				yield return (Bunburrow)bunburrow.ID;
			}
		}
	}
	internal class ForwardingBunjector : IBunjectorPlugin, ITileSource, IMonitor
	{
		public void OnAssetsLoaded()
		{
			foreach (IBunjectorPlugin bunjector in BunjectAPI.Bunjectors)
			{
				bunjector.OnAssetsLoaded();
			}
		}

		public void OnProgressionLoaded(GeneralProgression progression)
		{
			foreach (IBunjectorPlugin bunjector in BunjectAPI.Bunjectors)
			{
				bunjector.OnProgressionLoaded(progression);
			}
		}

		public ModLevelsList LoadLevelsList(string name, ModLevelsList original)
		{
			BunburrowMetadata bunburrowMetadata = BunburrowManager.Bunburrows.FirstOrDefault((BunburrowMetadata mb) => mb.ModBunburrow.Name == name);
			if (bunburrowMetadata != null && bunburrowMetadata.IsCustom)
			{
				return (ModLevelsList)(object)bunburrowMetadata.ModBunburrow.GetLevels();
			}
			return original;
		}

		public LevelObject LoadBurrowSurfaceLevel(string listName, LevelObject otherwise)
		{
			return BunburrowManager.Bunburrows.FirstOrDefault((BunburrowMetadata mb) => mb.ModBunburrow.Name == listName)?.ModBunburrow?.GetSurfaceLevel() ?? otherwise;
		}

		public LevelObject StartLevelTransition(LevelObject target, LevelIdentity identity)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			LevelObject val = target;
			foreach (IMonitor monitor in BunjectAPI.Monitors)
			{
				val = monitor.StartLevelTransition(val, identity);
			}
			return val;
		}

		public LevelsList LoadEmergencyLevelsList(LevelsList original)
		{
			LevelsList val = original;
			foreach (IMonitor monitor in BunjectAPI.Monitors)
			{
				val = monitor.LoadEmergencyLevelsList(val);
			}
			return val;
		}

		public bool SupportsTile(string tile)
		{
			return BunjectAPI.TileSources.Any((ITileSource ts) => ts.SupportsTile(tile));
		}

		public Tile LoadTile(LevelObject levelObject, string tile, Vector2Int position)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return BunjectAPI.TileSources.FirstOrDefault((ITileSource ts) => ts.SupportsTile(tile))?.LoadTile(levelObject, tile, position);
		}
	}
	[HarmonyPatch]
	internal static class LevelBuilderExtensions
	{
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(LevelBuilder), "GetTileInListByCoordinates")]
		public static TileLevelData GetTileInListByCoordinates(List<TileLevelData> tiles, int row, int col)
		{
			throw new NotImplementedException("Implementation overwritten by harmony reverse patch");
		}
	}
	internal class ElevatorManager
	{
		private static ElevatorManager instance;

		private readonly Dictionary<LevelIdentity, string> elevatorCache;

		internal static bool IsInitialized => instance != null;

		internal static IReadOnlyDictionary<LevelIdentity, string> Elevators
		{
			get
			{
				if (!IsInitialized)
				{
					instance = new ElevatorManager();
				}
				return instance.elevatorCache;
			}
		}

		private static bool IsValidSave(string elevatorData)
		{
			return !string.IsNullOrWhiteSpace(elevatorData);
		}

		public static bool IsElevatorUnlock(LevelIdentity level, out string elevatorData)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Elevators.TryGetValue(level, out elevatorData))
			{
				return IsValidSave(elevatorData);
			}
			return false;
		}

		public static bool IsElevatorUnlock(string elevatorData, out LevelIdentity level)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (IsValidSave(elevatorData) && Elevators.Values.Contains(elevatorData))
			{
				level = Elevators.Keys.First((LevelIdentity l) => Elevators[l] == elevatorData);
				return true;
			}
			level = default(LevelIdentity);
			return false;
		}

		public static bool UnlockElevator(Bunburrow burrow, int depth, out string elevatorData)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return ElevatorUnlock(new LevelIdentity(burrow, depth), out elevatorData);
		}

		public static bool ElevatorUnlock(LevelIdentity level, out string elevatorData)
		{
			//IL_0007: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			if (IsElevatorUnlock(level, out elevatorData))
			{
				return false;
			}
			if (!level.Bunburrow.IsCustomBunburrow() || !BunburrowManager.Bunburrows.Any((BunburrowMetadata burrow) => burrow.ID == (int)level.Bunburrow && burrow.Elevators.Contains(level.Depth)))
			{
				elevatorData = "";
				instance.elevatorCache.Add(level, elevatorData);
				return false;
			}
			elevatorData = JsonConvert.SerializeObject((object)((LevelIdentity)(ref level)).ProduceSaveData());
			instance.elevatorCache.Add(level, elevatorData);
			return true;
		}

		public static IEnumerator ExtractElevatorProgression()
		{
			if (IsInitialized)
			{
				instance.elevatorCache.Clear();
			}
			foreach (string unlockedElevator in GameManager.GeneralProgression.UnlockedElevators)
			{
				if (IsValidSave(unlockedElevator) && !IsElevatorUnlock(unlockedElevator, out var _))
				{
					LevelIdentity key;
					try
					{
						key = JsonConvert.DeserializeObject<LevelIdentitySaveData>(unlockedElevator).BuildLevelIdentity();
					}
					catch
					{
						continue;
					}
					instance.elevatorCache.Add(key, unlockedElevator);
				}
			}
			yield break;
		}

		private ElevatorManager()
		{
			elevatorCache = new Dictionary<LevelIdentity, string>();
		}
	}
	public static class SaveFileModUtility
	{
		private static Func<string> getRootSaveDataPathLambda;

		private static bool initialized;

		public static string GetRootSaveDataPath()
		{
			Initialize();
			return getRootSaveDataPathLambda();
		}

		private static void Initialize()
		{
			if (!initialized)
			{
				getRootSaveDataPathLambda = Expression.Lambda<Func<string>>(Expression.Call(typeof(SaveFileManipulationUtility).GetMethod("GetRootSaveDataPath", BindingFlags.Static | BindingFlags.NonPublic), Expression.Constant(true)), Array.Empty<ParameterExpression>()).Compile();
				initialized = true;
			}
		}
	}
}