Decompiled source of LethalLevelLoader v1.2.4

plugins/LethalLevelLoader.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Graph;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLevelLoader;
using LethalLevelLoader.NetcodePatcher;
using LethalLevelLoader.Tools;
using LethalLib.Modules;
using LethalModDataLib.Base;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;

[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-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("LethalLevelLoader")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A Custom API to support the manual and dynamic integration of custom levels and dungeons in Lethal Company.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+56c63f23a250f07a0f6f37bbf22fd42c356669a8")]
[assembly: AssemblyProduct("LethalLevelLoader")]
[assembly: AssemblyTitle("LethalLevelLoader")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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;
		}
	}
}
public enum ContentType
{
	Vanilla,
	Custom,
	Any
}
internal static class HookHelper
{
	public class DisposableHookCollection
	{
		private List<ILHook> ilHooks = new List<ILHook>();

		private List<Hook> hooks = new List<Hook>();

		public void Clear()
		{
			foreach (Hook hook in hooks)
			{
				hook.Dispose();
			}
			hooks.Clear();
			foreach (ILHook ilHook in ilHooks)
			{
				ilHook.Dispose();
			}
			ilHooks.Clear();
		}

		public void ILHook<T>(string methodName, Manipulator to, Type[] parameters = null)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			ilHooks.Add(new ILHook((MethodBase)EzGetMethod<T>(methodName, parameters), to));
		}

		public void Hook<T>(string methodName, Delegate to, Type[] parameters = null)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			hooks.Add(new Hook((MethodBase)EzGetMethod<T>(methodName, parameters), to));
		}
	}

	public static MethodInfo methodof(Delegate method)
	{
		return method.Method;
	}

	public static MethodInfo EzGetMethod(Type type, string name, Type[] parameters = null)
	{
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
		if (parameters == null)
		{
			return type.GetMethod(name, bindingAttr);
		}
		return type.GetMethod(name, bindingAttr, null, parameters, null);
	}

	public static MethodInfo EzGetMethod<T>(string name, Type[] parameters = null)
	{
		return EzGetMethod(typeof(T), name, parameters);
	}
}
public static class NetworkScenePatcher
{
	[CompilerGenerated]
	private static class <>O
	{
		public static Action<Action<NetworkSceneManager>, NetworkSceneManager> <0>__GenerateScenesInBuild_Hook;

		public static Func<Func<NetworkSceneManager, uint, string>, NetworkSceneManager, uint, string> <1>__SceneNameFromHash_Hook;

		public static Func<Func<NetworkSceneManager, int, string, LoadSceneMode, bool>, NetworkSceneManager, int, string, LoadSceneMode, bool> <2>__ValidateSceneBeforeLoading_Hook;

		public static Manipulator <3>__ReplaceBuildIndexByScenePath;

		public static Manipulator <4>__ReplaceScenePathByBuildIndex;

		public static Func<int, string> <5>__GetScenePathByBuildIndex;

		public static Func<string, int> <6>__GetBuildIndexByScenePath;
	}

	private static List<string> scenePaths = new List<string>();

	private static Dictionary<string, int> scenePathToBuildIndex = new Dictionary<string, int>();

	private static Dictionary<int, string> buildIndexToScenePath = new Dictionary<int, string>();

	private static Dictionary<uint, string> sceneHashToScenePath = new Dictionary<uint, string>();

	private static HookHelper.DisposableHookCollection hooks = new HookHelper.DisposableHookCollection();

	internal static bool patched { get; private set; }

	public static void AddScenePath(string scenePath)
	{
		if (!scenePaths.Contains(scenePath))
		{
			DebugHelper.Log("Adding ScenePath: " + scenePath, DebugType.User);
			scenePaths.Add(scenePath);
		}
	}

	internal static void Patch()
	{
		//IL_00e0: 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_00eb: Expected O, but got Unknown
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Expected O, but got Unknown
		if (!patched)
		{
			patched = true;
			hooks.Hook<NetworkSceneManager>("GenerateScenesInBuild", new Action<Action<NetworkSceneManager>, NetworkSceneManager>(GenerateScenesInBuild_Hook));
			hooks.Hook<NetworkSceneManager>("SceneNameFromHash", new Func<Func<NetworkSceneManager, uint, string>, NetworkSceneManager, uint, string>(SceneNameFromHash_Hook));
			hooks.Hook<NetworkSceneManager>("ValidateSceneBeforeLoading", new Func<Func<NetworkSceneManager, int, string, LoadSceneMode, bool>, NetworkSceneManager, int, string, LoadSceneMode, bool>(ValidateSceneBeforeLoading_Hook), new Type[3]
			{
				typeof(int),
				typeof(string),
				typeof(LoadSceneMode)
			});
			HookHelper.DisposableHookCollection disposableHookCollection = hooks;
			object obj = <>O.<3>__ReplaceBuildIndexByScenePath;
			if (obj == null)
			{
				Manipulator val = ReplaceBuildIndexByScenePath;
				<>O.<3>__ReplaceBuildIndexByScenePath = val;
				obj = (object)val;
			}
			disposableHookCollection.ILHook<NetworkSceneManager>("SceneHashFromNameOrPath", (Manipulator)obj);
			HookHelper.DisposableHookCollection disposableHookCollection2 = hooks;
			object obj2 = <>O.<3>__ReplaceBuildIndexByScenePath;
			if (obj2 == null)
			{
				Manipulator val2 = ReplaceBuildIndexByScenePath;
				<>O.<3>__ReplaceBuildIndexByScenePath = val2;
				obj2 = (object)val2;
			}
			disposableHookCollection2.ILHook<NetworkSceneManager>("ValidateSceneEvent", (Manipulator)obj2);
			HookHelper.DisposableHookCollection disposableHookCollection3 = hooks;
			object obj3 = <>O.<4>__ReplaceScenePathByBuildIndex;
			if (obj3 == null)
			{
				Manipulator val3 = ReplaceScenePathByBuildIndex;
				<>O.<4>__ReplaceScenePathByBuildIndex = val3;
				obj3 = (object)val3;
			}
			disposableHookCollection3.ILHook<NetworkSceneManager>("ScenePathFromHash", (Manipulator)obj3);
		}
	}

	internal static void Unpatch()
	{
		if (patched)
		{
			patched = false;
			hooks.Clear();
		}
	}

	private static void ReplaceScenePathByBuildIndex(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		MethodInfo methodInfo = HookHelper.methodof(new Func<int, string>(GetScenePathByBuildIndex));
		while (val.TryGotoNext(new Func<Instruction, bool>[1]
		{
			(Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(SceneUtility), "GetScenePathByBuildIndex")
		}))
		{
			val.Remove();
			val.Emit(OpCodes.Call, (MethodBase)methodInfo);
		}
	}

	private static void ReplaceBuildIndexByScenePath(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		MethodInfo methodInfo = HookHelper.methodof(new Func<string, int>(GetBuildIndexByScenePath));
		while (val.TryGotoNext(new Func<Instruction, bool>[1]
		{
			(Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(SceneUtility), "GetBuildIndexByScenePath")
		}))
		{
			val.Remove();
			val.Emit(OpCodes.Call, (MethodBase)methodInfo);
		}
	}

	private static string GetScenePathByBuildIndex(int buildIndex)
	{
		if (buildIndexToScenePath.ContainsKey(buildIndex))
		{
			return buildIndexToScenePath[buildIndex];
		}
		return SceneUtility.GetScenePathByBuildIndex(buildIndex);
	}

	private static int GetBuildIndexByScenePath(string scenePath)
	{
		int num = SceneUtility.GetBuildIndexByScenePath(scenePath);
		if (num == -1 && scenePathToBuildIndex.ContainsKey(scenePath))
		{
			num = scenePathToBuildIndex[scenePath];
		}
		return num;
	}

	private static void GenerateScenesInBuild_Hook(Action<NetworkSceneManager> orig, NetworkSceneManager self)
	{
		scenePathToBuildIndex.Clear();
		buildIndexToScenePath.Clear();
		sceneHashToScenePath.Clear();
		orig(self);
		int sceneCountInBuildSettings = SceneManager.sceneCountInBuildSettings;
		for (int i = 0; i < scenePaths.Count; i++)
		{
			int num = sceneCountInBuildSettings + i;
			string text = scenePaths[i];
			uint num2 = XXHash.Hash32(text);
			self.HashToBuildIndex.Add(num2, num);
			self.BuildIndexToHash.Add(num, num2);
			scenePathToBuildIndex.Add(text, num);
			buildIndexToScenePath.Add(num, text);
			sceneHashToScenePath.Add(num2, text);
		}
	}

	private static string SceneNameFromHash_Hook(Func<NetworkSceneManager, uint, string> orig, NetworkSceneManager self, uint sceneHash)
	{
		if (sceneHash == 0)
		{
			return "No Scene";
		}
		if (sceneHashToScenePath.ContainsKey(sceneHash))
		{
			return sceneHashToScenePath[sceneHash];
		}
		return orig(self, sceneHash);
	}

	private static bool ValidateSceneBeforeLoading_Hook(Func<NetworkSceneManager, int, string, LoadSceneMode, bool> orig, NetworkSceneManager self, int sceneIndex, string sceneName, LoadSceneMode loadSceneMode)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		bool flag = orig(self, sceneIndex, sceneName, loadSceneMode);
		return true;
	}
}
namespace LethalLevelLoader
{
	public class ExtendedContent : ScriptableObject
	{
		public ExtendedMod ExtendedMod { get; internal set; }

		public ContentType ContentType { get; internal set; } = ContentType.Vanilla;


		public List<string> ContentTagStrings { get; internal set; } = new List<string>();


		[field: SerializeField]
		public List<ContentTag> ContentTags { get; internal set; } = new List<ContentTag>();


		public string ModName => ExtendedMod.ModName;

		public string AuthorName => ExtendedMod.AuthorName;

		internal virtual void TryCreateMatchingProperties()
		{
		}

		public bool TryGetTag(string tag)
		{
			foreach (ContentTag contentTag in ContentTags)
			{
				if (contentTag.contentTagName == tag)
				{
					return true;
				}
			}
			return false;
		}

		public bool TryGetTag(string tag, out ContentTag returnTag)
		{
			returnTag = null;
			foreach (ContentTag contentTag in ContentTags)
			{
				if (contentTag.contentTagName == tag)
				{
					returnTag = contentTag;
					return true;
				}
			}
			return false;
		}

		public bool TryAddTag(string tag)
		{
			if (!TryGetTag(tag))
			{
				ContentTags.Add(ContentTag.Create(tag));
				return true;
			}
			return false;
		}
	}
	[Serializable]
	public class StringWithRarity
	{
		[SerializeField]
		private string _name;

		[SerializeField]
		[Range(0f, 300f)]
		private int _rarity;

		[HideInInspector]
		public string Name
		{
			get
			{
				return _name;
			}
			set
			{
				_name = value;
			}
		}

		[HideInInspector]
		public int Rarity
		{
			get
			{
				return _rarity;
			}
			set
			{
				_rarity = value;
			}
		}

		[HideInInspector]
		public StringWithRarity(string newName, int newRarity)
		{
			_name = newName;
			_rarity = newRarity;
		}
	}
	[Serializable]
	public class Vector2WithRarity
	{
		[SerializeField]
		private Vector2 _minMax;

		[SerializeField]
		private int _rarity;

		[HideInInspector]
		public float Min
		{
			get
			{
				return _minMax.x;
			}
			set
			{
				_minMax.x = value;
			}
		}

		[HideInInspector]
		public float Max
		{
			get
			{
				return _minMax.y;
			}
			set
			{
				_minMax.y = value;
			}
		}

		[HideInInspector]
		public int Rarity
		{
			get
			{
				return _rarity;
			}
			set
			{
				_rarity = value;
			}
		}

		public Vector2WithRarity(Vector2 vector2, int newRarity)
		{
			//IL_000e: 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)
			_minMax.x = vector2.x;
			_minMax.y = vector2.y;
			_rarity = newRarity;
		}

		public Vector2WithRarity(float newMin, float newMax, int newRarity)
		{
			_minMax.x = newMin;
			_minMax.y = newMax;
			_rarity = newRarity;
		}
	}
	[CreateAssetMenu(fileName = "ExtendedDungeonFlow", menuName = "Lethal Level Loader/Extended Content/ExtendedDungeonFlow", order = 21)]
	public class ExtendedDungeonFlow : ExtendedContent
	{
		[Space(25f)]
		[Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")]
		[Obsolete]
		public bool generateAutomaticConfigurationOptions = true;

		[Obsolete]
		public bool enableDynamicDungeonSizeRestriction = false;

		[Obsolete]
		public float dungeonSizeMin = 1f;

		[Obsolete]
		public float dungeonSizeMax = 1f;

		[Obsolete]
		[Range(0f, 1f)]
		public float dungeonSizeLerpPercentage = 1f;

		[Obsolete]
		public AudioClip dungeonFirstTimeAudio;

		[Obsolete]
		public DungeonFlow dungeonFlow;

		[Obsolete]
		public string dungeonDisplayName = string.Empty;

		[Obsolete]
		public string contentSourceName = string.Empty;

		[Obsolete]
		public List<StringWithRarity> dynamicLevelTagsList = new List<StringWithRarity>();

		[Obsolete]
		public List<Vector2WithRarity> dynamicRoutePricesList = new List<Vector2WithRarity>();

		[Obsolete]
		public List<StringWithRarity> dynamicCurrentWeatherList = new List<StringWithRarity>();

		[Obsolete]
		public List<StringWithRarity> manualPlanetNameReferenceList = new List<StringWithRarity>();

		[Obsolete]
		public List<StringWithRarity> manualContentSourceNameReferenceList = new List<StringWithRarity>();

		[Obsolete]
		[HideInInspector]
		public int dungeonDefaultRarity;

		[field: Header("General Settings")]
		[field: SerializeField]
		public DungeonFlow DungeonFlow { get; set; }

		[field: SerializeField]
		public string DungeonName { get; set; } = string.Empty;


		[field: SerializeField]
		public float MapTileSize { get; set; } = 1f;


		[field: SerializeField]
		public AudioClip FirstTimeDungeonAudio { get; set; }

		[field: Space(5f)]
		[field: Header("Dynamic Injection Matching Settings")]
		[field: SerializeField]
		public LevelMatchingProperties LevelMatchingProperties { get; set; }

		[field: Space(5f)]
		[field: Header("Extended Feature Settings")]
		[field: SerializeField]
		public GameObject OverrideKeyPrefab { get; set; }

		[field: SerializeField]
		public List<SpawnableMapObject> SpawnableMapObjects { get; set; } = new List<SpawnableMapObject>();


		[field: SerializeField]
		public List<GlobalPropCountOverride> GlobalPropCountOverridesList { get; set; } = new List<GlobalPropCountOverride>();


		[field: Space(5f)]
		[field: SerializeField]
		public bool IsDynamicDungeonSizeRestrictionEnabled { get; set; }

		[field: SerializeField]
		public Vector2 DynamicDungeonSizeMinMax { get; set; } = new Vector2(1f, 1f);


		[field: SerializeField]
		[field: Range(0f, 1f)]
		public float DynamicDungeonSizeLerpRate { get; set; } = 1f;


		[field: Space(10f)]
		[field: Header("Misc. Settings")]
		[field: SerializeField]
		public bool GenerateAutomaticConfigurationOptions { get; set; } = true;


		public int DungeonID { get; internal set; }

		public bool IsCurrentDungeon => (Object)(object)DungeonManager.CurrentExtendedDungeonFlow == (Object)(object)this;

		[HideInInspector]
		public DungeonEvents DungeonEvents { get; internal set; } = new DungeonEvents();


		internal static ExtendedDungeonFlow Create(DungeonFlow newDungeonFlow, AudioClip newFirstTimeDungeonAudio)
		{
			ExtendedDungeonFlow extendedDungeonFlow = ScriptableObject.CreateInstance<ExtendedDungeonFlow>();
			extendedDungeonFlow.DungeonFlow = newDungeonFlow;
			extendedDungeonFlow.FirstTimeDungeonAudio = newFirstTimeDungeonAudio;
			if ((Object)(object)extendedDungeonFlow.LevelMatchingProperties == (Object)null)
			{
				extendedDungeonFlow.LevelMatchingProperties = LevelMatchingProperties.Create(extendedDungeonFlow);
			}
			return extendedDungeonFlow;
		}

		internal void Initialize()
		{
			if ((Object)(object)LevelMatchingProperties == (Object)null)
			{
				LevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			GetDungeonFlowID();
			if (DungeonName == null || DungeonName == string.Empty)
			{
				DungeonName = ((Object)DungeonFlow).name;
			}
			((Object)this).name = ((Object)DungeonFlow).name.Replace("Flow", "") + "ExtendedDungeonFlow";
			if ((Object)(object)FirstTimeDungeonAudio == (Object)null)
			{
				DebugHelper.LogWarning("Custom Dungeon: " + DungeonName + " Is Missing A DungeonFirstTimeAudio Reference! Assigning Facility Audio To Prevent Errors.", DebugType.Developer);
				FirstTimeDungeonAudio = Patches.RoundManager.firstTimeDungeonAudios[0];
			}
			if ((Object)(object)OverrideKeyPrefab == (Object)null)
			{
				OverrideKeyPrefab = DungeonLoader.defaultKeyPrefab;
			}
		}

		private void GetDungeonFlowID()
		{
			if (base.ContentType == ContentType.Custom)
			{
				DungeonID = PatchedContent.ExtendedDungeonFlows.Count;
			}
			if (base.ContentType != 0)
			{
				return;
			}
			IndoorMapType[] dungeonFlowTypes = Patches.RoundManager.dungeonFlowTypes;
			foreach (IndoorMapType val in dungeonFlowTypes)
			{
				if ((Object)(object)val.dungeonFlow == (Object)(object)DungeonFlow)
				{
					DungeonID = Patches.RoundManager.dungeonFlowTypes.ToList().IndexOf(val);
				}
			}
		}

		internal override void TryCreateMatchingProperties()
		{
			if ((Object)(object)LevelMatchingProperties == (Object)null)
			{
				LevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			LevelMatchingProperties.ApplyValues(null, manualContentSourceNameReferenceList, newPlanetNames: manualPlanetNameReferenceList, newLevelTags: dynamicLevelTagsList, newRoutePrices: dynamicRoutePricesList, newCurrentWeathers: dynamicCurrentWeatherList);
		}

		internal void ConvertObsoleteValues()
		{
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)DungeonFlow == (Object)null && (Object)(object)dungeonFlow != (Object)null)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonFlow is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DungeonFlow instead.", DebugType.Developer);
				DungeonFlow = dungeonFlow;
				dungeonFlow = null;
			}
			if (string.IsNullOrEmpty(DungeonName) && !string.IsNullOrEmpty(dungeonDisplayName))
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonDisplayName is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DungeonName instead.", DebugType.Developer);
				DungeonName = dungeonDisplayName;
				dungeonDisplayName = string.Empty;
			}
			if ((Object)(object)FirstTimeDungeonAudio == (Object)null && (Object)(object)dungeonFirstTimeAudio != (Object)null)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonFirstTimeAudio is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.FirstTimeDungeonAudio instead.", DebugType.Developer);
				FirstTimeDungeonAudio = dungeonFirstTimeAudio;
				dungeonFirstTimeAudio = null;
			}
			if (dungeonSizeLerpPercentage != 1f)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonSizeLerpPercentage is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DynamicDungeonSizeLerpRate instead.", DebugType.Developer);
			}
			if (dungeonSizeMax != 1f || dungeonSizeMin != 1f)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonSizeMin and ExtendedDungeonFlow.dungeonSizeMax are Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DynamicSungeonSizeMinMax instead.", DebugType.Developer);
				DynamicDungeonSizeMinMax = new Vector2(dungeonSizeMin, dungeonSizeMax);
			}
			if (!string.IsNullOrEmpty(contentSourceName))
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.contentSourceName is Obsolete and will be removed in following releases, Please use ExtendedMod.AuthorName instead.", DebugType.Developer);
			}
			if ((Object)(object)LevelMatchingProperties == (Object)null && (dynamicLevelTagsList.Count > 0 || dynamicRoutePricesList.Count > 0 || dynamicCurrentWeatherList.Count > 0 || manualContentSourceNameReferenceList.Count > 0 || manualContentSourceNameReferenceList.Count > 0))
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow dynamic and manual match reference lists are Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.LevelMatchingProperties instead.", DebugType.Developer);
				TryCreateMatchingProperties();
			}
			if (enableDynamicDungeonSizeRestriction || IsDynamicDungeonSizeRestrictionEnabled != enableDynamicDungeonSizeRestriction)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.enableDynamicDungeonSizeRestriction Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.IsDynamicDungeonRestrictionEnabled instead.", DebugType.Developer);
				IsDynamicDungeonSizeRestrictionEnabled = enableDynamicDungeonSizeRestriction;
			}
			if (!generateAutomaticConfigurationOptions || GenerateAutomaticConfigurationOptions != generateAutomaticConfigurationOptions)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.generateAutomaticConfigurationOptions Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.GenerateAutomaticConfigurationOptions instead.", DebugType.Developer);
				GenerateAutomaticConfigurationOptions = generateAutomaticConfigurationOptions;
			}
		}
	}
	[Serializable]
	public class GlobalPropCountOverride
	{
		public int globalPropID;

		[Range(0f, 1f)]
		public float globalPropCountScaleRate = 0f;
	}
	[Serializable]
	public class DungeonEvents
	{
		public ExtendedEvent<RoundManager> onBeforeDungeonGenerate = new ExtendedEvent<RoundManager>();

		public ExtendedEvent onShipLand = new ExtendedEvent();

		public ExtendedEvent onShipLeave = new ExtendedEvent();

		public ExtendedEvent<List<GameObject>> onSpawnedSyncedObjects = new ExtendedEvent<List<GameObject>>();

		public ExtendedEvent<List<GameObject>> onSpawnedMapObjects = new ExtendedEvent<List<GameObject>>();

		public ExtendedEvent<List<GrabbableObject>> onSpawnedScrapObjects = new ExtendedEvent<List<GrabbableObject>>();

		public ExtendedEvent<(EnemyVent, EnemyAI)> onEnemySpawnedFromVent = new ExtendedEvent<(EnemyVent, EnemyAI)>();

		public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerEnterDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>();

		public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerExitDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>();

		public ExtendedEvent<bool> onPowerSwitchToggle = new ExtendedEvent<bool>();

		public ExtendedEvent<LungProp> onApparatusTaken = new ExtendedEvent<LungProp>();
	}
	[CreateAssetMenu(fileName = "ExtendedEnemyType", menuName = "Lethal Level Loader/Extended Content/ExtendedEnemyType", order = 24)]
	public class ExtendedEnemyType : ExtendedContent
	{
		[field: Header("General Settings")]
		[field: SerializeField]
		public EnemyType EnemyType { get; set; }

		[field: SerializeField]
		public string EnemyDisplayName { get; set; }

		[field: Space(5f)]
		[field: Header("Dynamic Injection Matching Settings")]
		[field: SerializeField]
		public LevelMatchingProperties OutsideLevelMatchingProperties { get; set; }

		[field: SerializeField]
		public LevelMatchingProperties DaytimeLevelMatchingProperties { get; set; }

		[field: SerializeField]
		public LevelMatchingProperties InsideLevelMatchingProperties { get; set; }

		[field: SerializeField]
		public DungeonMatchingProperties InsideDungeonMatchingProperties { get; set; }

		[field: Space(5f)]
		[field: Header("Terminal Bestiary Override Settings")]
		[field: SerializeField]
		[field: TextArea(2, 20)]
		public string InfoNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		public VideoClip InfoNodeVideoClip { get; set; }

		public ScanNodeProperties ScanNodeProperties { get; internal set; }

		public int EnemyID { get; internal set; }

		public TerminalNode EnemyInfoNode { get; internal set; }

		public static ExtendedEnemyType Create(EnemyType enemyType, ExtendedMod extendedMod, ContentType contentType)
		{
			ExtendedEnemyType extendedEnemyType = ScriptableObject.CreateInstance<ExtendedEnemyType>();
			extendedEnemyType.EnemyType = enemyType;
			((Object)extendedEnemyType).name = enemyType.enemyName.SkipToLetters().RemoveWhitespace() + "ExtendedEnemyType";
			extendedEnemyType.ContentType = contentType;
			extendedMod.RegisterExtendedContent(extendedEnemyType);
			extendedEnemyType.TryCreateMatchingProperties();
			return extendedEnemyType;
		}

		public void Initalize()
		{
			DebugHelper.Log("Initializing Custom Enemy: " + EnemyType.enemyName, DebugType.Developer);
			TryCreateMatchingProperties();
		}

		internal override void TryCreateMatchingProperties()
		{
			if ((Object)(object)InsideLevelMatchingProperties == (Object)null)
			{
				InsideLevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			if ((Object)(object)InsideDungeonMatchingProperties == (Object)null)
			{
				InsideDungeonMatchingProperties = DungeonMatchingProperties.Create(this);
			}
			if ((Object)(object)OutsideLevelMatchingProperties == (Object)null)
			{
				OutsideLevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			if ((Object)(object)DaytimeLevelMatchingProperties == (Object)null)
			{
				DaytimeLevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
		}
	}
	[CreateAssetMenu(fileName = "ExtendedFootstepSurface", menuName = "Lethal Level Loader/Extended Content/ExtendedFootstepSurface", order = 27)]
	public class ExtendedFootstepSurface : ExtendedContent
	{
		public FootstepSurface footstepSurface;

		public List<Material> associatedMaterials;

		public List<GameObject> associatedGameObjects;

		internal int arrayIndex;
	}
	[CreateAssetMenu(fileName = "ExtendedItem", menuName = "Lethal Level Loader/Extended Content/ExtendedItem", order = 23)]
	public class ExtendedItem : ExtendedContent
	{
		[field: Header("General Settings")]
		[field: SerializeField]
		public Item Item { get; set; }

		[field: SerializeField]
		public string PluralisedItemName { get; set; } = string.Empty;


		[field: SerializeField]
		public bool IsBuyableItem { get; set; }

		[field: Space(5f)]
		[field: Header("Dynamic Injection Matching Settings")]
		[field: SerializeField]
		public LevelMatchingProperties LevelMatchingProperties { get; set; }

		[field: SerializeField]
		public DungeonMatchingProperties DungeonMatchingProperties { get; set; }

		[field: Space(5f)]
		[field: Header("Terminal Store & Info Override Settings")]
		[field: SerializeField]
		public string OverrideInfoNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		public string OverrideBuyNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		public string OverrideBuyConfirmNodeDescription { get; set; } = string.Empty;


		public TerminalNode BuyNode { get; internal set; }

		public TerminalNode BuyConfirmNode { get; internal set; }

		public TerminalNode BuyInfoNode { get; internal set; }

		public int CreditsWorth
		{
			get
			{
				if ((Object)(object)BuyNode != (Object)null && (Object)(object)BuyConfirmNode != (Object)null)
				{
					BuyNode.itemCost = Item.creditsWorth;
					BuyConfirmNode.itemCost = Item.creditsWorth;
				}
				else
				{
					Debug.LogWarning((object)"BuyNode And/Or BuyConfirm Node Missing!");
				}
				return Item.creditsWorth;
			}
			set
			{
				if (value >= 0)
				{
					if ((Object)(object)BuyNode != (Object)null && (Object)(object)BuyConfirmNode != (Object)null)
					{
						BuyNode.itemCost = value;
						BuyConfirmNode.itemCost = value;
					}
					else
					{
						Debug.LogWarning((object)"BuyNode And/Or BuyConfirm Node Missing!");
					}
					Item.creditsWorth = value;
				}
			}
		}

		public static ExtendedItem Create(Item newItem, ExtendedMod extendedMod, ContentType contentType)
		{
			ExtendedItem extendedItem = ScriptableObject.CreateInstance<ExtendedItem>();
			extendedItem.Item = newItem;
			((Object)extendedItem).name = newItem.itemName.SkipToLetters().RemoveWhitespace() + "ExtendedItem";
			extendedItem.ContentType = contentType;
			extendedMod.RegisterExtendedContent(extendedItem);
			extendedItem.TryCreateMatchingProperties();
			return extendedItem;
		}

		public void Initialize()
		{
			DebugHelper.Log("Initializing Custom Item: " + Item.itemName + ". Is Buyable: " + IsBuyableItem + ". Is Scrap: " + Item.isScrap, DebugType.Developer);
			TryCreateMatchingProperties();
			Patches.StartOfRound.allItemsList.itemsList.Add(Item);
			if (IsBuyableItem)
			{
				TerminalManager.CreateItemTerminalData(this);
			}
		}

		internal override void TryCreateMatchingProperties()
		{
			if ((Object)(object)LevelMatchingProperties == (Object)null)
			{
				LevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			if ((Object)(object)DungeonMatchingProperties == (Object)null)
			{
				DungeonMatchingProperties = DungeonMatchingProperties.Create(this);
			}
		}

		public void SetLevelMatchingProperties(LevelMatchingProperties newLevelMatchingProperties)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				Debug.LogError((object)"SetLevelMatchingProperties() Should Only Be Used In Editor!");
			}
			LevelMatchingProperties = newLevelMatchingProperties;
		}
	}
	[CreateAssetMenu(fileName = "ExtendedLevel", menuName = "Lethal Level Loader/Extended Content/ExtendedLevel", order = 20)]
	public class ExtendedLevel : ExtendedContent
	{
		[Space(5f)]
		[SerializeField]
		private int routePrice = 0;

		[Space(25f)]
		[Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")]
		[Obsolete]
		public SelectableLevel selectableLevel;

		[Obsolete]
		[Space(5f)]
		public string contentSourceName = string.Empty;

		[Obsolete]
		[Space(5f)]
		public List<string> levelTags = new List<string>();

		[field: Header("General Settings")]
		[field: SerializeField]
		public SelectableLevel SelectableLevel { get; set; }

		[field: Header("Extended Feature Settings")]
		[field: SerializeField]
		public bool OverrideDynamicRiskLevelAssignment { get; set; } = false;


		[field: Space(5f)]
		[field: SerializeField]
		public GameObject OverrideQuicksandPrefab { get; set; }

		[field: Space(5f)]
		[field: SerializeField]
		public bool IsRouteHidden { get; set; } = false;


		[field: SerializeField]
		public bool IsRouteLocked { get; set; } = false;


		[field: SerializeField]
		public string LockedRouteNodeText { get; set; } = string.Empty;


		[field: Space(5f)]
		[field: SerializeField]
		public AnimationClip ShipFlyToMoonClip { get; set; }

		[field: SerializeField]
		public AnimationClip ShipFlyFromMoonClip { get; set; }

		[field: Space(5f)]
		[field: SerializeField]
		public List<StringWithRarity> SceneSelections { get; set; } = new List<StringWithRarity>();


		[field: Space(5f)]
		[field: Header("Terminal Route Override Settings")]
		[field: SerializeField]
		[field: TextArea(2, 20)]
		public string OverrideInfoNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		[field: TextArea(2, 20)]
		public string OverrideRouteNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		[field: TextArea(2, 20)]
		public string OverrideRouteConfirmNodeDescription { get; set; } = string.Empty;


		[field: Space(10f)]
		[field: Header("Misc. Settings")]
		[field: Space(5f)]
		[field: SerializeField]
		public bool GenerateAutomaticConfigurationOptions { get; set; } = true;


		public int RoutePrice
		{
			get
			{
				if ((Object)(object)RouteNode != (Object)null)
				{
					routePrice = RouteNode.itemCost;
					RouteConfirmNode.itemCost = routePrice;
					return RouteNode.itemCost;
				}
				DebugHelper.LogWarning("routeNode Is Missing! Using internal value!", DebugType.Developer);
				return routePrice;
			}
			set
			{
				if ((Object)(object)RouteNode != (Object)null && (Object)(object)RouteConfirmNode != (Object)null)
				{
					RouteNode.itemCost = value;
					RouteConfirmNode.itemCost = value;
				}
				else
				{
					DebugHelper.LogWarning("routeNode Is Missing! Only setting internal value!", DebugType.Developer);
				}
				routePrice = value;
			}
		}

		public string NumberlessPlanetName => GetNumberlessPlanetName(SelectableLevel);

		public int CalculatedDifficultyRating => LevelManager.CalculateExtendedLevelDifficultyRating(this);

		public bool IsCurrentLevel => (Object)(object)LevelManager.CurrentExtendedLevel == (Object)(object)this;

		public bool IsLevelLoaded
		{
			get
			{
				//IL_000b: 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)
				Scene sceneByName = SceneManager.GetSceneByName(SelectableLevel.sceneName);
				return ((Scene)(ref sceneByName)).isLoaded;
			}
		}

		[HideInInspector]
		public LevelEvents LevelEvents { get; internal set; } = new LevelEvents();


		public TerminalNode RouteNode { get; internal set; }

		public TerminalNode RouteConfirmNode { get; internal set; }

		public TerminalNode InfoNode { get; internal set; }

		public List<ExtendedWeatherEffect> EnabledExtendedWeatherEffects { get; set; } = new List<ExtendedWeatherEffect>();


		public ExtendedWeatherEffect CurrentExtendedWeatherEffect { get; set; }

		internal static ExtendedLevel Create(SelectableLevel newSelectableLevel)
		{
			ExtendedLevel extendedLevel = ScriptableObject.CreateInstance<ExtendedLevel>();
			extendedLevel.SelectableLevel = newSelectableLevel;
			return extendedLevel;
		}

		internal void Initialize(string newContentSourceName, bool generateTerminalAssets)
		{
			bool flag = false;
			foreach (StringWithRarity sceneSelection in SceneSelections)
			{
				if (sceneSelection.Name == SelectableLevel.sceneName)
				{
					flag = true;
				}
			}
			if (!flag)
			{
				StringWithRarity item = new StringWithRarity(SelectableLevel.sceneName, 300);
				SceneSelections.Add(item);
			}
			foreach (StringWithRarity item2 in new List<StringWithRarity>(SceneSelections))
			{
				if (!PatchedContent.AllLevelSceneNames.Contains(item2.Name))
				{
					DebugHelper.LogWarning("Removing SceneSelection From: " + SelectableLevel.PlanetName + " As SceneName: " + item2.Name + " Is Not Loaded!", DebugType.Developer);
					SceneSelections.Remove(item2);
				}
			}
			if ((Object)(object)ShipFlyToMoonClip == (Object)null)
			{
				ShipFlyToMoonClip = LevelLoader.defaultShipFlyToMoonClip;
			}
			if ((Object)(object)ShipFlyFromMoonClip == (Object)null)
			{
				ShipFlyFromMoonClip = LevelLoader.defaultShipFlyFromMoonClip;
			}
			if ((Object)(object)OverrideQuicksandPrefab == (Object)null)
			{
				OverrideQuicksandPrefab = LevelLoader.defaultQuicksandPrefab;
			}
			if (base.ContentType == ContentType.Custom)
			{
				((Object)this).name = NumberlessPlanetName.StripSpecialCharacters() + "ExtendedLevel";
				((Object)SelectableLevel).name = NumberlessPlanetName.StripSpecialCharacters() + "Level";
				if (generateTerminalAssets)
				{
					TerminalManager.CreateLevelTerminalData(this, routePrice);
				}
			}
			if (base.ContentType == ContentType.Vanilla)
			{
				GetVanillaInfoNode();
			}
			SetExtendedDungeonFlowMatches();
		}

		internal void ConvertObsoleteValues()
		{
			if (levelTags.Count > 0 && base.ContentTags.Count == 0)
			{
				DebugHelper.LogWarning("ExtendedLevel.levelTags Is Obsolete and will be removed in following releases, Please use .ContentTags instead.", DebugType.Developer);
				foreach (ContentTag item in ContentTagManager.CreateNewContentTags(levelTags))
				{
					base.ContentTags.Add(item);
				}
			}
			levelTags.Clear();
			if ((Object)(object)SelectableLevel == (Object)null && (Object)(object)selectableLevel != (Object)null)
			{
				DebugHelper.LogWarning("ExtendedLevel.selectableLevel Is Obsolete and will be removed in following releases, Please use .SelectableLevel instead.", DebugType.Developer);
				SelectableLevel = selectableLevel;
			}
			if (!string.IsNullOrEmpty(contentSourceName))
			{
				DebugHelper.LogWarning("ExtendedLevel.contentSourceName is Obsolete and will be removed in following releases, Please use ExtendedMod.AuthorName instead.", DebugType.Developer);
			}
		}

		internal static string GetNumberlessPlanetName(SelectableLevel selectableLevel)
		{
			if ((Object)(object)selectableLevel != (Object)null)
			{
				return new string(selectableLevel.PlanetName.SkipWhile((char c) => !char.IsLetter(c)).ToArray());
			}
			return string.Empty;
		}

		internal void SetLevelID()
		{
			if (base.ContentType == ContentType.Custom)
			{
				SelectableLevel.levelID = PatchedContent.ExtendedLevels.IndexOf(this);
				if ((Object)(object)RouteNode != (Object)null)
				{
					RouteNode.displayPlanetInfo = SelectableLevel.levelID;
				}
				if ((Object)(object)RouteConfirmNode != (Object)null)
				{
					RouteConfirmNode.buyRerouteToMoon = SelectableLevel.levelID;
				}
			}
		}

		internal void SetExtendedDungeonFlowMatches()
		{
			IntWithRarity[] dungeonFlowTypes = SelectableLevel.dungeonFlowTypes;
			foreach (IntWithRarity val in dungeonFlowTypes)
			{
				if (DungeonManager.TryGetExtendedDungeonFlow(Patches.RoundManager.dungeonFlowTypes[val.id].dungeonFlow, out var returnExtendedDungeonFlow))
				{
					returnExtendedDungeonFlow.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, val.rarity));
				}
			}
			if (!(SelectableLevel.sceneName == "Level4March"))
			{
				return;
			}
			IndoorMapType[] dungeonFlowTypes2 = Patches.RoundManager.dungeonFlowTypes;
			foreach (IndoorMapType val2 in dungeonFlowTypes2)
			{
				if (((Object)val2.dungeonFlow).name == "Level1Flow3Exits" && DungeonManager.TryGetExtendedDungeonFlow(val2.dungeonFlow, out var returnExtendedDungeonFlow2))
				{
					returnExtendedDungeonFlow2.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, 300));
				}
			}
		}

		internal void GetVanillaInfoNode()
		{
			CompatibleNoun[] compatibleNouns = TerminalManager.routeInfoKeyword.compatibleNouns;
			foreach (CompatibleNoun val in compatibleNouns)
			{
				if (val.noun.word == NumberlessPlanetName.ToLower())
				{
					InfoNode = val.result;
					break;
				}
			}
		}

		public void ForceSetRoutePrice(int newValue)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				Debug.LogWarning((object)"ForceSetRoutePrice Should Only Be Used In Editor! Consider Using RoutePrice Property To Sync TerminalNode's With New Value.");
			}
			routePrice = newValue;
		}
	}
	[Serializable]
	public class LevelEvents
	{
		public ExtendedEvent onLevelLoaded = new ExtendedEvent();

		public ExtendedEvent onShipLand = new ExtendedEvent();

		public ExtendedEvent onShipLeave = new ExtendedEvent();

		public ExtendedEvent<EnemyAI> onDaytimeEnemySpawn = new ExtendedEvent<EnemyAI>();

		public ExtendedEvent<EnemyAI> onNighttimeEnemySpawn = new ExtendedEvent<EnemyAI>();

		public ExtendedEvent<StoryLog> onStoryLogCollected = new ExtendedEvent<StoryLog>();

		public ExtendedEvent<LungProp> onApparatusTaken = new ExtendedEvent<LungProp>();

		public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerEnterDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>();

		public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerExitDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>();

		public ExtendedEvent<bool> onPowerSwitchToggle = new ExtendedEvent<bool>();

		public ExtendedEvent<DayMode> onDayModeToggle = new ExtendedEvent<DayMode>();
	}
	public enum ModMergeSetting
	{
		MatchingAuthorName,
		MatchingModName,
		Disabled
	}
	[CreateAssetMenu(fileName = "ExtendedMod", menuName = "Lethal Level Loader/ExtendedMod", order = 30)]
	public class ExtendedMod : ScriptableObject
	{
		[field: SerializeField]
		public string ModName { get; internal set; } = "Unspecified";


		[field: SerializeField]
		public string AuthorName { get; internal set; } = "Unknown";


		public List<string> ModNameAliases { get; internal set; } = new List<string>();


		[field: SerializeField]
		public ModMergeSetting ModMergeSetting { get; internal set; } = ModMergeSetting.MatchingAuthorName;


		[field: SerializeField]
		public List<ExtendedLevel> ExtendedLevels { get; private set; } = new List<ExtendedLevel>();


		[field: SerializeField]
		public List<ExtendedDungeonFlow> ExtendedDungeonFlows { get; private set; } = new List<ExtendedDungeonFlow>();


		[field: SerializeField]
		public List<ExtendedItem> ExtendedItems { get; private set; } = new List<ExtendedItem>();


		[field: SerializeField]
		public List<ExtendedEnemyType> ExtendedEnemyTypes { get; private set; } = new List<ExtendedEnemyType>();


		[field: SerializeField]
		public List<ExtendedWeatherEffect> ExtendedWeatherEffects { get; private set; } = new List<ExtendedWeatherEffect>();


		[field: SerializeField]
		public List<ExtendedFootstepSurface> ExtendedFootstepSurfaces { get; private set; } = new List<ExtendedFootstepSurface>();


		[field: SerializeField]
		public List<ExtendedStoryLog> ExtendedStoryLogs { get; private set; } = new List<ExtendedStoryLog>();


		public List<ExtendedContent> ExtendedContents
		{
			get
			{
				List<ExtendedContent> list = new List<ExtendedContent>();
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					list.Add(extendedLevel);
				}
				foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows)
				{
					list.Add(extendedDungeonFlow);
				}
				foreach (ExtendedItem extendedItem in ExtendedItems)
				{
					list.Add(extendedItem);
				}
				foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes)
				{
					list.Add(extendedEnemyType);
				}
				foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects)
				{
					list.Add(extendedWeatherEffect);
				}
				foreach (ExtendedFootstepSurface extendedFootstepSurface in ExtendedFootstepSurfaces)
				{
					list.Add(extendedFootstepSurface);
				}
				return list;
			}
		}

		internal static ExtendedMod Create(string modName)
		{
			ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>();
			extendedMod.ModName = modName;
			((Object)extendedMod).name = modName.Sanitized() + "Mod";
			DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName, DebugType.Developer);
			return extendedMod;
		}

		public static ExtendedMod Create(string modName, string authorName)
		{
			ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>();
			extendedMod.ModName = modName;
			((Object)extendedMod).name = modName.SkipToLetters().RemoveWhitespace() + "Mod";
			extendedMod.AuthorName = authorName;
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName + " by " + authorName, DebugType.Developer);
			}
			return extendedMod;
		}

		public static ExtendedMod Create(string modName, string authorName, ExtendedContent[] extendedContents)
		{
			ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>();
			extendedMod.ModName = modName;
			((Object)extendedMod).name = modName.SkipToLetters().RemoveWhitespace() + "Mod";
			extendedMod.AuthorName = authorName;
			foreach (ExtendedContent newExtendedContent in extendedContents)
			{
				extendedMod.RegisterExtendedContent(newExtendedContent);
			}
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName + " by " + authorName, DebugType.Developer);
			}
			return extendedMod;
		}

		internal void RegisterExtendedContent(ExtendedContent newExtendedContent)
		{
			if ((Object)(object)newExtendedContent != (Object)null)
			{
				if (!ExtendedContents.Contains(newExtendedContent))
				{
					if (newExtendedContent is ExtendedLevel extendedLevel)
					{
						RegisterExtendedContent(extendedLevel);
						return;
					}
					if (newExtendedContent is ExtendedDungeonFlow extendedDungeonFlow)
					{
						RegisterExtendedContent(extendedDungeonFlow);
						return;
					}
					if (newExtendedContent is ExtendedItem extendedItem)
					{
						RegisterExtendedContent(extendedItem);
						return;
					}
					if (newExtendedContent is ExtendedEnemyType extendedEnemyType)
					{
						RegisterExtendedContent(extendedEnemyType);
						return;
					}
					if (newExtendedContent is ExtendedWeatherEffect extendedWeatherEffect)
					{
						RegisterExtendedContent(extendedWeatherEffect);
						return;
					}
					if (newExtendedContent is ExtendedFootstepSurface extendedFootstepSurface)
					{
						RegisterExtendedContent(extendedFootstepSurface);
						return;
					}
					if (newExtendedContent is ExtendedStoryLog extendedStoryLog)
					{
						RegisterExtendedContent(extendedStoryLog);
						return;
					}
					throw new ArgumentException("newExtendedContent", ((Object)newExtendedContent).name + " (" + ((object)newExtendedContent).GetType().Name + ")  Could Not Be Registered To ExtendedMod: " + ModName + " Due To Unimplemented Registration Check!");
				}
				throw new ArgumentException("newExtendedContent", ((Object)newExtendedContent).name + " (" + ((object)newExtendedContent).GetType().Name + ")  Could Not Be Registered To ExtendedMod: " + ModName + " Due To Already Being Registered To This Mod!");
			}
			throw new ArgumentNullException("newExtendedContent", "Null ExtendedContent Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check!");
		}

		internal void RegisterExtendedContent(ExtendedLevel extendedLevel)
		{
			extendedLevel.ConvertObsoleteValues();
			TryThrowInvalidContentException(extendedLevel, Validators.ValidateExtendedContent(extendedLevel));
			ExtendedLevels.Add(extendedLevel);
			extendedLevel.ContentTags.Add(ContentTag.Create("Custom"));
			extendedLevel.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedDungeonFlow extendedDungeonFlow)
		{
			extendedDungeonFlow.ConvertObsoleteValues();
			TryThrowInvalidContentException(extendedDungeonFlow, Validators.ValidateExtendedContent(extendedDungeonFlow));
			ExtendedDungeonFlows.Add(extendedDungeonFlow);
			extendedDungeonFlow.ContentTags.Add(ContentTag.Create("Custom"));
			extendedDungeonFlow.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedItem extendedItem)
		{
			TryThrowInvalidContentException(extendedItem, Validators.ValidateExtendedContent(extendedItem));
			ExtendedItems.Add(extendedItem);
			extendedItem.ContentTags.Add(ContentTag.Create("Custom"));
			extendedItem.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedEnemyType extendedEnemyType)
		{
			TryThrowInvalidContentException(extendedEnemyType, Validators.ValidateExtendedContent(extendedEnemyType));
			ExtendedEnemyTypes.Add(extendedEnemyType);
			extendedEnemyType.ContentTags.Add(ContentTag.Create("Custom"));
			extendedEnemyType.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedWeatherEffect extendedWeatherEffect)
		{
			TryThrowInvalidContentException(extendedWeatherEffect, Validators.ValidateExtendedContent(extendedWeatherEffect));
			ExtendedWeatherEffects.Add(extendedWeatherEffect);
			extendedWeatherEffect.ContentTags.Add(ContentTag.Create("Custom"));
			extendedWeatherEffect.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedFootstepSurface extendedFootstepSurface)
		{
			TryThrowInvalidContentException(extendedFootstepSurface, Validators.ValidateExtendedContent(extendedFootstepSurface));
			ExtendedFootstepSurfaces.Add(extendedFootstepSurface);
			extendedFootstepSurface.ContentTags.Add(ContentTag.Create("Custom"));
			extendedFootstepSurface.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedStoryLog extendedStoryLog)
		{
			TryThrowInvalidContentException(extendedStoryLog, Validators.ValidateExtendedContent(extendedStoryLog));
			ExtendedStoryLogs.Add(extendedStoryLog);
			extendedStoryLog.ContentTags.Add(ContentTag.Create("Custom"));
			extendedStoryLog.ExtendedMod = this;
		}

		internal void TryThrowInvalidContentException(ExtendedContent extendedContent, (bool, string) result)
		{
			if (!result.Item1)
			{
				if ((Object)(object)extendedContent == (Object)null)
				{
					throw new ArgumentNullException("extendedContent", "Null ExtendedContent Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check! " + result.Item2);
				}
				throw new ArgumentException("extendedContent", ((Object)extendedContent).name + " (" + ((object)extendedContent).GetType().Name + ")  Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check! " + result.Item2);
			}
		}

		internal void UnregisterExtendedContent(ExtendedContent currentExtendedContent)
		{
			if (currentExtendedContent is ExtendedLevel item)
			{
				ExtendedLevels.Remove(item);
			}
			else if (currentExtendedContent is ExtendedDungeonFlow item2)
			{
				ExtendedDungeonFlows.Remove(item2);
			}
			else if (currentExtendedContent is ExtendedItem item3)
			{
				ExtendedItems.Remove(item3);
			}
			currentExtendedContent.ExtendedMod = null;
			DebugHelper.LogWarning("Unregistered ExtendedContent: " + ((Object)currentExtendedContent).name + " In ExtendedMod: " + ModName, DebugType.Developer);
		}

		internal void UnregisterAllExtendedContent()
		{
			ExtendedLevels.Clear();
			ExtendedDungeonFlows.Clear();
			ExtendedItems.Clear();
			ExtendedEnemyTypes.Clear();
			ExtendedWeatherEffects.Clear();
			ExtendedFootstepSurfaces.Clear();
		}

		internal void SortRegisteredContent()
		{
			ExtendedDungeonFlows.Sort((ExtendedDungeonFlow s1, ExtendedDungeonFlow s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			ExtendedItems.Sort((ExtendedItem s1, ExtendedItem s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			ExtendedEnemyTypes.Sort((ExtendedEnemyType s1, ExtendedEnemyType s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			ExtendedWeatherEffects.Sort((ExtendedWeatherEffect s1, ExtendedWeatherEffect s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			ExtendedFootstepSurfaces.Sort((ExtendedFootstepSurface s1, ExtendedFootstepSurface s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
		}

		internal void Example()
		{
			AssetBundle val = null;
			ExtendedDungeonFlow extendedDungeonFlow = val.LoadAsset<ExtendedDungeonFlow>("Assets/CoolDungeonFlow");
			ExtendedEnemyType extendedEnemyType = val.LoadAsset<ExtendedEnemyType>("Assets/Ghost");
			ExtendedMod extendedMod = Create("BatbysMod", "IAmBatby", new ExtendedContent[2] { extendedDungeonFlow, extendedEnemyType });
			PatchedContent.RegisterExtendedMod(extendedMod);
		}
	}
	[CreateAssetMenu(fileName = "ExtendedStoryLog", menuName = "Lethal Level Loader/Extended Content/ExtendedStoryLog", order = 26)]
	public class ExtendedStoryLog : ExtendedContent
	{
		public string sceneName = string.Empty;

		public int storyLogID;

		[Space(5f)]
		public string terminalKeywordNoun = string.Empty;

		[Space(5f)]
		public string storyLogTitle = string.Empty;

		[TextArea]
		public string storyLogDescription = string.Empty;

		[HideInInspector]
		internal int newStoryLogID;
	}
	[CreateAssetMenu(fileName = "ExtendedWeatherEffect", menuName = "Lethal Level Loader/Extended Content/ExtendedWeatherEffect", order = 25)]
	public class ExtendedWeatherEffect : ExtendedContent
	{
		public ContentType contentType;

		[field: Header("General Settings")]
		[field: SerializeField]
		public LevelWeatherType BaseWeatherType { get; set; } = (LevelWeatherType)(-1);


		[field: SerializeField]
		public string WeatherDisplayName { get; set; } = string.Empty;


		[field: SerializeField]
		public GameObject WorldObject { get; set; }

		[field: SerializeField]
		public GameObject GlobalObject { get; set; }

		internal static ExtendedWeatherEffect Create(LevelWeatherType levelWeatherType, WeatherEffect weatherEffect, string weatherDisplayName, ContentType newContentType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Create(levelWeatherType, weatherEffect.effectObject, weatherEffect.effectPermanentObject, weatherDisplayName, newContentType);
		}

		internal static ExtendedWeatherEffect Create(LevelWeatherType levelWeatherType, GameObject worldObject, GameObject globalObject, string newWeatherDisplayName, ContentType newContentType)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			ExtendedWeatherEffect extendedWeatherEffect = ScriptableObject.CreateInstance<ExtendedWeatherEffect>();
			extendedWeatherEffect.WeatherDisplayName = newWeatherDisplayName;
			((Object)extendedWeatherEffect).name = extendedWeatherEffect.WeatherDisplayName + "ExtendedWeatherEffect";
			extendedWeatherEffect.BaseWeatherType = levelWeatherType;
			extendedWeatherEffect.WorldObject = worldObject;
			extendedWeatherEffect.GlobalObject = globalObject;
			return extendedWeatherEffect;
		}
	}
	public class LLLSaveFile : ModDataContainer
	{
		public int parityStepsTaken;

		public Dictionary<int, AllItemsListItemData> itemSaveData = new Dictionary<int, AllItemsListItemData>();

		public string CurrentLevelName { get; internal set; } = string.Empty;


		public void Reset()
		{
			CurrentLevelName = string.Empty;
			parityStepsTaken = 0;
			itemSaveData = new Dictionary<int, AllItemsListItemData>();
		}
	}
	public struct AllItemsListItemData
	{
		public string itemObjectName;

		public string itemName;

		public string modName;

		public string modAuthor;

		public int allItemsListIndex;

		public int modItemsListIndex;

		public int itemNameDuplicateIndex;

		public bool isScrap;

		public bool saveItemVariable;

		public AllItemsListItemData(string newItemObjectName, string newItemName, string newModName, string newModAuthor, int newAllItemsListIndex, int newModItemsListIndex, int newItemNameDuplicateIndex, bool newIsScrap, bool newSaveItemVariable)
		{
			itemObjectName = newItemObjectName;
			itemName = newItemName;
			modName = newModName;
			modAuthor = newModAuthor;
			allItemsListIndex = newAllItemsListIndex;
			modItemsListIndex = newModItemsListIndex;
			itemNameDuplicateIndex = newItemNameDuplicateIndex;
			isScrap = newIsScrap;
			saveItemVariable = newSaveItemVariable;
		}
	}
	[CreateAssetMenu(fileName = "ContentTag", menuName = "Lethal Level Loader/Utility/ContentTag", order = 11)]
	public class ContentTag : ScriptableObject
	{
		public string contentTagName;

		public Color contentTagColor;

		public static ContentTag Create(string tag, Color color)
		{
			//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)
			ContentTag contentTag = ScriptableObject.CreateInstance<ContentTag>();
			contentTag.contentTagName = tag;
			contentTag.contentTagColor = color;
			((Object)contentTag).name = tag + "ContentTag";
			return contentTag;
		}

		public static ContentTag Create(string tag)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Create(tag, Color.white);
		}
	}
	[CreateAssetMenu(fileName = "DungeonMatchingProperties", menuName = "Lethal Level Loader/Utility/DungeonMatchingProperties", order = 13)]
	public class DungeonMatchingProperties : MatchingProperties
	{
		[Space(5f)]
		public List<StringWithRarity> dungeonTags = new List<StringWithRarity>();

		[Space(5f)]
		public List<StringWithRarity> dungeonNames = new List<StringWithRarity>();

		public new static DungeonMatchingProperties Create(ExtendedContent extendedContent)
		{
			DungeonMatchingProperties dungeonMatchingProperties = ScriptableObject.CreateInstance<DungeonMatchingProperties>();
			((Object)dungeonMatchingProperties).name = ((Object)extendedContent).name + "DungeonMatchingProperties";
			return dungeonMatchingProperties;
		}

		public int GetDynamicRarity(ExtendedDungeonFlow extendedDungeonFlow)
		{
			int currentValue = 0;
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedTags(extendedDungeonFlow.ContentTags, dungeonNames), ((Object)extendedDungeonFlow).name, "Content Tags");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(extendedDungeonFlow.AuthorName, authorNames), ((Object)extendedDungeonFlow).name, "Author Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedStrings(extendedDungeonFlow.ExtendedMod.ModNameAliases, modNames), ((Object)extendedDungeonFlow).name, "Mod Name Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(((Object)extendedDungeonFlow.DungeonFlow).name, dungeonNames), ((Object)extendedDungeonFlow).name, "Dungeon Name");
			return currentValue;
		}

		public void ApplyValues(List<StringWithRarity> newModNames = null, List<StringWithRarity> newAuthorNames = null, List<StringWithRarity> newDungeonTags = null, List<StringWithRarity> newDungeonNames = null)
		{
			if (newModNames != null && newModNames.Count != 0)
			{
				modNames = new List<StringWithRarity>(newModNames);
			}
			if (newAuthorNames != null && newAuthorNames.Count != 0)
			{
				authorNames = new List<StringWithRarity>(newAuthorNames);
			}
			if (newDungeonTags != null && newDungeonTags.Count != 0)
			{
				dungeonTags = new List<StringWithRarity>(newDungeonTags);
			}
			if (newDungeonNames != null && newDungeonNames.Count != 0)
			{
				dungeonNames = new List<StringWithRarity>(newDungeonNames);
			}
		}
	}
	[CreateAssetMenu(fileName = "LevelMatchingProperties", menuName = "Lethal Level Loader/Utility/LevelMatchingProperties", order = 12)]
	public class LevelMatchingProperties : MatchingProperties
	{
		[Space(5f)]
		public List<StringWithRarity> levelTags = new List<StringWithRarity>();

		[Space(5f)]
		public List<Vector2WithRarity> currentRoutePrice = new List<Vector2WithRarity>();

		[Space(5f)]
		public List<StringWithRarity> currentWeather = new List<StringWithRarity>();

		[Space(5f)]
		public List<StringWithRarity> planetNames = new List<StringWithRarity>();

		public new static LevelMatchingProperties Create(ExtendedContent extendedContent)
		{
			LevelMatchingProperties levelMatchingProperties = ScriptableObject.CreateInstance<LevelMatchingProperties>();
			((Object)levelMatchingProperties).name = ((Object)extendedContent).name + "LevelMatchingProperties";
			return levelMatchingProperties;
		}

		public int GetDynamicRarity(ExtendedLevel extendedLevel)
		{
			int currentValue = 0;
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedTags(extendedLevel.ContentTags, levelTags), ((Object)extendedLevel).name, "Content Tags");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(extendedLevel.AuthorName, authorNames), ((Object)extendedLevel).name, "Author Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedStrings(extendedLevel.ExtendedMod.ModNameAliases, modNames), ((Object)extendedLevel).name, "Mod Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingWithinRanges(extendedLevel.RoutePrice, currentRoutePrice), ((Object)extendedLevel).name, "Route Price");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(extendedLevel.NumberlessPlanetName, planetNames), ((Object)extendedLevel).name, "Planet Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(((object)(LevelWeatherType)(ref extendedLevel.SelectableLevel.currentWeather)).ToString(), currentWeather), ((Object)extendedLevel).name, "Current Weather");
			return currentValue;
		}

		public void ApplyValues(List<StringWithRarity> newModNames = null, List<StringWithRarity> newAuthorNames = null, List<StringWithRarity> newLevelTags = null, List<Vector2WithRarity> newRoutePrices = null, List<StringWithRarity> newCurrentWeathers = null, List<StringWithRarity> newPlanetNames = null)
		{
			if (newModNames != null && newModNames.Count != 0)
			{
				modNames = new List<StringWithRarity>(newModNames);
			}
			if (newAuthorNames != null && newAuthorNames.Count != 0)
			{
				authorNames = new List<StringWithRarity>(newAuthorNames);
			}
			if (newLevelTags != null && newLevelTags.Count != 0)
			{
				levelTags = new List<StringWithRarity>(newLevelTags);
			}
			if (newRoutePrices != null && newRoutePrices.Count != 0)
			{
				currentRoutePrice = new List<Vector2WithRarity>(newRoutePrices);
			}
			if (newCurrentWeathers != null && newCurrentWeathers.Count != 0)
			{
				currentWeather = new List<StringWithRarity>(newCurrentWeathers);
			}
			if (newPlanetNames != null && newPlanetNames.Count != 0)
			{
				planetNames = new List<StringWithRarity>(newPlanetNames);
			}
		}
	}
	public class MatchingProperties : ScriptableObject
	{
		[Space(5f)]
		public List<StringWithRarity> modNames = new List<StringWithRarity>();

		[Space(5f)]
		public List<StringWithRarity> authorNames = new List<StringWithRarity>();

		public static MatchingProperties Create(ExtendedContent extendedContent)
		{
			MatchingProperties matchingProperties = ScriptableObject.CreateInstance<MatchingProperties>();
			((Object)matchingProperties).name = ((Object)extendedContent).name + "MatchingProperties";
			return matchingProperties;
		}

		internal static bool UpdateRarity(ref int currentValue, int newValue, string debugActionObject = null, string debugActionReason = null)
		{
			if (newValue > currentValue)
			{
				if (!string.IsNullOrEmpty(debugActionReason))
				{
					if (!string.IsNullOrEmpty(debugActionObject))
					{
						DebugHelper.Log("Raised Rarity Of: " + debugActionObject + " From (" + currentValue + ") To (" + newValue + ") Due To Matching " + debugActionReason, DebugType.Developer);
					}
					else
					{
						DebugHelper.Log("Raised Rarity From (" + currentValue + ") To (" + newValue + ") Due To Matching " + debugActionReason, DebugType.Developer);
					}
				}
				currentValue = newValue;
				return true;
			}
			return false;
		}

		internal static int GetHighestRarityViaMatchingWithinRanges(int comparingValue, List<Vector2WithRarity> matchingVectors)
		{
			int num = 0;
			foreach (Vector2WithRarity matchingVector in matchingVectors)
			{
				if (matchingVector.Rarity >= num && (float)comparingValue >= matchingVector.Min && (float)comparingValue <= matchingVector.Max)
				{
					num = matchingVector.Rarity;
				}
			}
			return num;
		}

		internal static int GetHighestRarityViaMatchingNormalizedString(string comparingString, List<StringWithRarity> matchingStrings)
		{
			return GetHighestRarityViaMatchingNormalizedStrings(new List<string> { comparingString }, matchingStrings);
		}

		internal static int GetHighestRarityViaMatchingNormalizedTags(List<ContentTag> comparingTags, List<StringWithRarity> matchingStrings)
		{
			List<string> comparingStrings = comparingTags.Select((ContentTag t) => t.contentTagName).ToList();
			return GetHighestRarityViaMatchingNormalizedStrings(comparingStrings, matchingStrings);
		}

		internal static int GetHighestRarityViaMatchingNormalizedStrings(List<string> comparingStrings, List<StringWithRarity> matchingStrings)
		{
			int num = 0;
			foreach (StringWithRarity matchingString in matchingStrings)
			{
				foreach (string item in new List<string>(comparingStrings))
				{
					if (matchingString.Rarity >= num && (matchingString.Name.Sanitized().Contains(item.Sanitized()) || item.Sanitized().Contains(matchingString.Name.Sanitized())))
					{
						num = matchingString.Rarity;
					}
				}
			}
			return num;
		}
	}
	public class MoonsCataloguePage
	{
		private List<ExtendedLevelGroup> extendedLevelGroups;

		public List<ExtendedLevelGroup> ExtendedLevelGroups => extendedLevelGroups;

		public List<ExtendedLevel> ExtendedLevels
		{
			get
			{
				List<ExtendedLevel> list = new List<ExtendedLevel>();
				foreach (ExtendedLevelGroup extendedLevelGroup in extendedLevelGroups)
				{
					foreach (ExtendedLevel extendedLevels in extendedLevelGroup.extendedLevelsList)
					{
						list.Add(extendedLevels);
					}
				}
				return list;
			}
		}

		public MoonsCataloguePage(List<ExtendedLevelGroup> newExtendedLevelGroupList)
		{
			extendedLevelGroups = new List<ExtendedLevelGroup>();
			extendedLevelGroups.Clear();
			foreach (ExtendedLevelGroup newExtendedLevelGroup in newExtendedLevelGroupList)
			{
				extendedLevelGroups.Add(new ExtendedLevelGroup(newExtendedLevelGroup.extendedLevelsList));
			}
		}

		public void RebuildLevelGroups(List<ExtendedLevelGroup> newExtendedLevelGroups, int splitCount)
		{
			List<ExtendedLevel> list = new List<ExtendedLevel>();
			foreach (ExtendedLevelGroup extendedLevelGroup in extendedLevelGroups)
			{
				foreach (ExtendedLevel extendedLevels in extendedLevelGroup.extendedLevelsList)
				{
					list.Add(extendedLevels);
				}
			}
			RebuildLevelGroups(list.ToArray(), splitCount);
		}

		public void RebuildLevelGroups(List<ExtendedLevel> newExtendedLevels, int splitCount)
		{
			RebuildLevelGroups(newExtendedLevels.ToArray(), splitCount);
		}

		public void RebuildLevelGroups(IOrderedEnumerable<ExtendedLevel> orderedExtendedLevels, int splitCount)
		{
			RebuildLevelGroups(orderedExtendedLevels.ToArray(), splitCount);
		}

		public void RebuildLevelGroups(ExtendedLevel[] newExtendedLevels, int splitCount)
		{
			extendedLevelGroups = TerminalManager.GetExtendedLevelGroups(newExtendedLevels, splitCount);
		}

		public void RefreshLevelGroups(List<ExtendedLevelGroup> newLevelGroups)
		{
			extendedLevelGroups.Clear();
			foreach (ExtendedLevelGroup newLevelGroup in newLevelGroups)
			{
				if (newLevelGroup.extendedLevelsList.Count != 0)
				{
					extendedLevelGroups.Add(new ExtendedLevelGroup(newLevelGroup.extendedLevelsList));
				}
			}
		}
	}
	[Serializable]
	public class ExtendedLevelGroup
	{
		public List<ExtendedLevel> extendedLevelsList;

		public int AverageCalculatedDifficulty => GetAverageCalculatedDifficulty();

		public ExtendedLevelGroup(List<ExtendedLevel> newExtendedLevelsList)
		{
			extendedLevelsList = new List<ExtendedLevel>(newExtendedLevelsList);
		}

		public ExtendedLevelGroup(List<SelectableLevel> newSelectableLevelsList)
		{
			extendedLevelsList = new List<ExtendedLevel>();
			foreach (SelectableLevel newSelectableLevels in newSelectableLevelsList)
			{
				extendedLevelsList.Add(LevelManager.GetExtendedLevel(newSelectableLevels));
			}
		}

		public int GetAverageCalculatedDifficulty()
		{
			List<int> list = new List<int>();
			foreach (ExtendedLevel extendedLevels in extendedLevelsList)
			{
				list.Add(extendedLevels.CalculatedDifficultyRating);
			}
			return (int)list.Average();
		}
	}
	public static class PatchedContent
	{
		public static ExtendedMod VanillaMod { get; internal set; }

		public static List<string> AllLevelSceneNames { get; internal set; } = new List<string>();


		public static List<ExtendedMod> ExtendedMods { get; internal set; } = new List<ExtendedMod>();


		public static List<ExtendedLevel> ExtendedLevels { get; internal set; } = new List<ExtendedLevel>();


		public static List<ExtendedLevel> VanillaExtendedLevels
		{
			get
			{
				List<ExtendedLevel> list = new List<ExtendedLevel>();
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					if (extendedLevel.ContentType == ContentType.Vanilla)
					{
						list.Add(extendedLevel);
					}
				}
				return list;
			}
		}

		public static List<ExtendedLevel> CustomExtendedLevels
		{
			get
			{
				List<ExtendedLevel> list = new List<ExtendedLevel>();
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					if (extendedLevel.ContentType == ContentType.Custom)
					{
						list.Add(extendedLevel);
					}
				}
				return list;
			}
		}

		public static List<SelectableLevel> SeletectableLevels
		{
			get
			{
				List<SelectableLevel> list = new List<SelectableLevel>();
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					list.Add(extendedLevel.SelectableLevel);
				}
				return list;
			}
		}

		public static List<SelectableLevel> MoonsCatalogue
		{
			get
			{
				List<SelectableLevel> list = new List<SelectableLevel>();
				foreach (SelectableLevel item in OriginalContent.MoonsCatalogue)
				{
					list.Add(item);
				}
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					if (extendedLevel.ContentType == ContentType.Custom)
					{
						list.Add(extendedLevel.SelectableLevel);
					}
				}
				return list;
			}
		}

		public static List<ExtendedDungeonFlow> ExtendedDungeonFlows { get; internal set; } = new List<ExtendedDungeonFlow>();


		public static List<ExtendedDungeonFlow> VanillaExtendedDungeonFlows
		{
			get
			{
				List<ExtendedDungeonFlow> list = new List<ExtendedDungeonFlow>();
				foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows)
				{
					if (extendedDungeonFlow.ContentType == ContentType.Vanilla)
					{
						list.Add(extendedDungeonFlow);
					}
				}
				return list;
			}
		}

		public static List<ExtendedDungeonFlow> CustomExtendedDungeonFlows
		{
			get
			{
				List<ExtendedDungeonFlow> list = new List<ExtendedDungeonFlow>();
				foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows)
				{
					if (extendedDungeonFlow.ContentType == ContentType.Custom)
					{
						list.Add(extendedDungeonFlow);
					}
				}
				return list;
			}
		}

		public static List<ExtendedWeatherEffect> ExtendedWeatherEffects { get; internal set; } = new List<ExtendedWeatherEffect>();


		public static List<ExtendedWeatherEffect> VanillaExtendedWeatherEffects
		{
			get
			{
				List<ExtendedWeatherEffect> list = new List<ExtendedWeatherEffect>();
				foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects)
				{
					if (extendedWeatherEffect.contentType == ContentType.Vanilla)
					{
						list.Add(extendedWeatherEffect);
					}
				}
				return list;
			}
		}

		public static List<ExtendedWeatherEffect> CustomExtendedWeatherEffects
		{
			get
			{
				List<ExtendedWeatherEffect> list = new List<ExtendedWeatherEffect>();
				foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects)
				{
					if (extendedWeatherEffect.contentType == ContentType.Custom)
					{
						list.Add(extendedWeatherEffect);
					}
				}
				return list;
			}
		}

		public static List<ExtendedItem> ExtendedItems { get; internal set; } = new List<ExtendedItem>();


		public static List<ExtendedItem> CustomExtendedItems
		{
			get
			{
				List<ExtendedItem> list = new List<ExtendedItem>();
				foreach (ExtendedItem extendedItem in ExtendedItems)
				{
					if (extendedItem.ContentType == ContentType.Custom)
					{
						list.Add(extendedItem);
					}
				}
				return list;
			}
		}

		public static List<ExtendedEnemyType> ExtendedEnemyTypes { get; internal set; } = new List<ExtendedEnemyType>();


		public static List<ExtendedEnemyType> CustomExtendedEnemyTypes
		{
			get
			{
				List<ExtendedEnemyType> list = new List<ExtendedEnemyType>();
				foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes)
				{
					if (extendedEnemyType.ContentType == ContentType.Custom)
					{
						list.Add(extendedEnemyType);
					}
				}
				return list;
			}
		}

		public static List<ExtendedEnemyType> VanillaExtendedEnemyTypes
		{
			get
			{
				List<ExtendedEnemyType> list = new List<ExtendedEnemyType>();
				foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes)
				{
					if (extendedEnemyType.ContentType == ContentType.Vanilla)
					{
						list.Add(extendedEnemyType);
					}
				}
				return list;
			}
		}

		public static List<AudioMixer> AudioMixers { get; internal set; } = new List<AudioMixer>();


		public static List<AudioMixerGroup> AudioMixerGroups { get; internal set; } = new List<AudioMixerGroup>();


		public static List<AudioMixerSnapshot> AudioMixerSnapshots { get; internal set; } = new List<AudioMixerSnapshot>();


		public static List<Item> Items { get; internal set; } = new List<Item>();


		public static List<EnemyType> Enemies { get; internal set; } = new List<EnemyType>();


		public static void RegisterExtendedDungeonFlow(ExtendedDungeonFlow extendedDungeonFlow)
		{
			extendedDungeonFlow.ConvertObsoleteValues();
			if (string.IsNullOrEmpty(((Object)extendedDungeonFlow).name))
			{
				DebugHelper.LogWarning("Tried to register ExtendedDungeonFlow with missing name! Setting to DungeonFlow name for safety!", DebugType.Developer);
				((Object)extendedDungeonFlow).name = ((Object)extendedDungeonFlow.DungeonFlow).name;
			}
			AssetBundleLoader.RegisterNewExtendedContent(extendedDungeonFlow, ((Object)extendedDungeonFlow).name);
		}

		public static void RegisterExtendedLevel(ExtendedLevel extendedLevel)
		{
			AssetBundleLoader.RegisterNewExtendedContent(extendedLevel, ((Object)extendedLevel).name);
		}

		public static void RegisterExtendedMod(ExtendedMod extendedMod)
		{
			DebugHelper.Log("Registering ExtendedMod: " + extendedMod.ModName + " Manually.", DebugType.Developer);
			AssetBundleLoader.RegisterExtendedMod(extendedMod);
		}

		internal static void SortExtendedMods()
		{
			ExtendedMods = new List<ExtendedMod>(ExtendedMods.OrderBy((ExtendedMod o) => o.ModName).ToList());
			foreach (ExtendedMod extendedMod in ExtendedMods)
			{
				extendedMod.SortRegisteredContent();
			}
		}
	}
	public static class OriginalContent
	{
		public static List<SelectableLevel> SelectableLevels { get; internal set; } = new List<SelectableLevel>();


		public static List<SelectableLevel> MoonsCatalogue { get; internal set; } = new List<SelectableLevel>();


		public static List<DungeonFlow> DungeonFlows { get; internal set; } = new List<DungeonFlow>();


		public static List<Item> Items { get; internal set; } = new List<Item>();


		public static List<ItemGroup> ItemGroups { get; internal set; } = new List<ItemGroup>();


		public static List<EnemyType> Enemies { get; internal set; } = new List<EnemyType>();


		public static List<SpawnableOutsideObject> SpawnableOutsideObjects { get; internal set; } = new List<SpawnableOutsideObject>();


		public static List<GameObject> SpawnableMapObjects { get; internal set; } = new List<GameObject>();


		public static List<AudioMixer> AudioMixers { get; internal set; } = new List<AudioMixer>();


		public static List<AudioMixerGroup> AudioMixerGroups { get; internal set; } = new List<AudioMixerGroup>();


		public static List<AudioMixerSnapshot> AudioMixerSnapshots { get; internal set; } = new List<AudioMixerSnapshot>();


		public static List<LevelAmbienceLibrary> LevelAmbienceLibraries { get; internal set; } = new List<LevelAmbienceLibrary>();


		public static List<ReverbPreset> ReverbPresets { get; internal set; } = new List<ReverbPreset>();


		public static List<TerminalKeyword> TerminalKeywords { get; internal set; } = new List<TerminalKeyword>();


		public static List<TerminalNode> TerminalNodes { get; internal set; } = new List<TerminalNode>();

	}
	internal class EventPatches
	{
		internal static DayMode previousDayMode = (DayMode)(-1);

		internal static bool firedDawnEvent = false;

		private static EnemyVent cachedSelectedVent;

		internal static void InvokeExtendedEvent<T>(ExtendedEvent<T> extendedEvent, T eventParameter)
		{
			extendedEvent.Invoke(eventParameter);
		}

		internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null && LevelManager.CurrentExtendedLevel.IsLevelLoaded)
			{
				previousDayMode = (DayMode)(-1);
				LevelManager.CurrentExtendedLevel.LevelEvents.onLevelLoaded.Invoke();
				LevelManager.GlobalLevelEvents.onLevelLoaded.Invoke();
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(StoryLog), "CollectLog")]
		[HarmonyPrefix]
		internal static void StoryLogCollectLog_Prefix(StoryLog __instance)
		{
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null && ((NetworkBehaviour)__instance).IsServer)
			{
				LevelManager.CurrentExtendedLevel.LevelEvents.onStoryLogCollected.Invoke(__instance);
				LevelManager.GlobalLevelEvents.onStoryLogCollected.Invoke(__instance);
			}
		}

		[HarmonyPriority(201)]
		[HarmonyPatch(typeof(DungeonGenerator), "Generate")]
		[HarmonyPrefix]
		internal static void DungeonGeneratorGenerate_Prefix()
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onBeforeDungeonGenerate.Invoke(Patches.RoundManager);
				DungeonManager.GlobalDungeonEvents.onBeforeDungeonGenerate.Invoke(Patches.RoundManager);
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SwitchPower")]
		[HarmonyPrefix]
		internal static void RoundManagerSwitchPower_Prefix(bool on)
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onPowerSwitchToggle.Invoke(on);
				DungeonManager.GlobalDungeonEvents.onPowerSwitchToggle.Invoke(on);
			}
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null)
			{
				LevelManager.CurrentExtendedLevel.LevelEvents.onPowerSwitchToggle.Invoke(on);
				LevelManager.GlobalLevelEvents.onPowerSwitchToggle.Invoke(on);
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
		[HarmonyPostfix]
		internal static void RoundManagerSpawnScrapInLevel_Postfix()
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				List<GrabbableObject> param = Object.FindObjectsOfType<GrabbableObject>().ToList();
				DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onSpawnedScrapObjects.Invoke(param);
				DungeonManager.GlobalDungeonEvents.onSpawnedScrapObjects.Invoke(param);
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnSyncedProps")]
		[HarmonyPostfix]
		internal static void RoundManagerSpawnSyncedProps_Postfix()
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onSpawnedSyncedObjects.Invoke(Patches.RoundManager.spawnedSyncedObjects);
				DungeonManager.GlobalDungeonEvents.onSpawnedSyncedObjects.Invoke(Patches.RoundManager.spawnedSyncedObjects);
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnEnemyFromVent")]
		[HarmonyPrefix]
		internal static void RoundManagerSpawnEventFromVent_Prefix(EnemyVent vent)
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				cachedSelectedVent = vent;
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnEnemyGameObject")]
		[HarmonyPostfix]
		internal static void RoundManagerSpawnEventFromVent_Postfix()
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null && (Object)(object)cachedSelectedVent != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onEnemySpawnedFromVent.Invoke((cachedSelectedVent, Patches.RoundManager.SpawnedEnemies.Last()));
				DungeonManager.GlobalDungeonEvents.onEnemySpawnedFromVent.Invoke((cachedSelectedVent, Patches.RoundManager.SpawnedEnemies.Last()));
				cachedSelectedVent = null;
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnMapObjects")]
		[HarmonyPostfix]
		internal static void RoundManagerSpawnMapObjects_Postfix()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null))
			{
				return;
			}
			List<GameObject> list = new List<GameObject>();
			Scene sceneByName = SceneManager.GetSceneByName(LevelManager.CurrentExtendedLevel.SelectableLevel.sceneName);
			GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects();
			foreach (GameObject val in rootGameObjects)
			{
				SpawnableMapObject[] spawnableMapObjects = LevelManager.CurrentExtendedLevel.SelectableLevel.spawnableMapObjects;
				foreach (SpawnableMapObject val2 in spawnableMapObjects)
				{
					if (((Object)val).name.Sanitized().Contains(((Object)val2.prefabToSpawn).name.Sanitized()))
					{
						list.Add(val);
					}
				}
			}
			DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onSpawnedMapObjects.Invoke(list);
			DungeonManager.GlobalDungeonEvents.onSpawnedMapObjects.Invoke(list);
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")]
		[HarmonyPrefix]
		internal static void StartOfRoundOnShipLandedMiscEvents_Prefix()
		{
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null)
			{
				LevelManager.CurrentExtendedLevel.LevelEvents.onShipLand.Invoke();
				LevelManager.GlobalLevelEvents.onShipLand.Invoke();
			}
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onShipLand.Invoke();
				DungeonManager.GlobalDungeonEvents.onShipLand.Invoke();
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
		[HarmonyPrefix]
		internal static void StartOfRoundShipLeave_Prefix()
		{
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null)
			{
				LevelManager.CurrentExtendedLevel.LevelEvents.onShipLeave.Invoke();
				LevelManager.GlobalLevelEvents.onShipLeave.Invoke();
			}
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onShipLeave.Invoke();
				DungeonManager.GlobalDungeonEvents.onShipLeave.Invoke();
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayerServerRpc")]
		[HarmonyPrefix]
		internal static void EntranceTeleportTeleportPlayerServerRpc_Prefix(EntranceTeleport __instance, int playerObj)
		{
			if (!((NetworkBehaviour)__instance).IsHost)
			{
				return;
			}
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				PlayerControllerB item = Patches.StartOfRound.allPlayerScripts[playerObj];
				if (__instance.isEntranceToBuilding)
				{
					DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onPlayerEnterDungeon.Invoke((__instance, item));
					DungeonManager.GlobalDungeonEvents.onPlayerEnterDungeon.Invoke((__instance, item));
				}
				else
				{
					DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onPlayerExitDungeon.Invoke((__instance, item));
					DungeonManager.GlobalDungeonEvents.onPlayerExitDungeon.Invoke((__instance, item));
				}
			}
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null)
			{
				PlayerControllerB item2 = Patches.StartOfRound.allPlayerScripts[playerObj];
				if (__instance.isEntranceToBuilding)
				{
					LevelManager.CurrentExtendedLevel.LevelEvents.onPlayerEnterDungeon.Invoke((__instance, item2));
					LevelManager.GlobalLevelEvents.onPlayerEnterDungeon.Invoke((__instance, item2));
				}
				else
				{
					LevelManager.CurrentExtendedLevel.LevelEvents.onPlayerExitDungeon.Invoke((__instance, item2));
					LevelManager.GlobalLevelEvents.onPlayerExitDungeon.Invoke((__instance, item2));
				}
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(LungProp), "EquipItem")]
		[HarmonyPrefix]
		internal static void LungPropEquipItem_Postfix(LungProp __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer)
			{
				if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
				{
					DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onApparatusTaken.Invoke(__instance);
					DungeonManager.GlobalDungeonEvents.onApparatusTaken.Invoke(__instance);
				}
				if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null)
				{
					LevelManager.CurrentExtendedLevel.LevelEvents.onApparatusTaken.Invoke(__instance);
					LevelManager.GlobalLevelEvents.onApparatusTaken.Invoke(__instance);
				}
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(TimeOfDay), "GetDayPhase")]
		[HarmonyPostfix]
		internal static void TimeOfDayGetDayPhase_Postfix(DayMode __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if ((int)previousDayMode == -1 || previousDayMode != __result)
			{
				LevelManager.CurrentExtendedLevel.LevelEvents.onDayModeToggle.Invoke(__result);
				LevelManager.GlobalLevelEvents.onDayModeToggle.Invoke(__result);
			}
			previousDayMode = __result;
		}
	}
	public class ExtendedEvent<T>
	{
		public delegate void ParameterEvent(T param);

		public bool HasListeners => Listeners != 0;

		public int Listeners { get; internal set; }

		private event ParameterEvent onParameterEvent;

		public void Invoke(T param)
		{
			this.onParameterEvent?.Invoke(param);
		}

		public void AddListener(ParameterEvent listener)
		{
			onParameterEvent += listener;
			Listeners++;
		}

		public void RemoveListener(ParameterEvent listener)
		{
			onParameterEvent -= listener;
			Listeners--;
		}
	}
	public class ExtendedEvent
	{
		public delegate void Event();

		public bool HasListeners => Listeners != 0;

		public int Listeners { get; internal set; }

		private event Event onEvent;

		public void Invoke()
		{
			this.onEvent?.Invoke();
		}

		public void AddListener(Event listener)
		{
			onEvent += listener;
			Listeners++;
		}

		public void RemoveListener(Event listener)
		{
			onEvent -= listener;
			Listeners--;
		}
	}
	public static class Extensions
	{
		public static List<Tile> GetTiles(this DungeonFlow dungeonFlow)
		{
			List<Tile> list = new List<Tile>();
			foreach (GraphNode node in dungeonFlow.Nodes)
			{
				foreach (TileSet tileSet in node.TileSets)
				{
					list.AddRange(GetTilesInTileSet(tileSet));
				}
			}
			foreach (GraphLine line in dungeonFlow.Lines)
			{
				foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes)
				{
					foreach (TileSet branchCapTileSet in dungeonArchetype.BranchCapTileSets)
					{
						list.AddRange(GetTilesInTileSet(branchCapTileSet));
					}
					foreach (TileSet tileSet2 in dungeonArchetype.TileSets)
					{
						list.AddRange(GetTilesInTileSet(tileSet2));
					}
				}
			}
			foreach (Tile item in new List<Tile>(list))
			{
				if ((Object)(object)item == (Object)null)
				{
					list.Remove(item);
				}
			}
			return list;
		}

		public static List<Tile> GetTilesInTileSet(TileSet tileSet)
		{
			List<Tile> list = new List<Tile>();
			if (tileSet.TileWeights != null && tileSet.TileWeights.Weights != null)
			{
				foreach (GameObjectChance weight in tileSet.TileWeights.Weights)
				{
					Tile[] componentsInChildren = weight.Value.GetComponentsInChildren<Tile>();
					foreach (Tile item in componentsInChildren)
					{
						list.Add(item);
					}
				}
			}
			return list;
		}

		public static List<RandomMapObject> GetRandomMapObjects(this DungeonFlow dungeonFlow)
		{
			List<RandomMapObject> list = new List<RandomMapObject>();
			foreach (Tile tile in dungeonFlow.GetTiles())
			{
				RandomMapObject[] componentsInChildren = ((Component)tile).gameObject.GetComponentsInChildren<RandomMapObject>();
				foreach (RandomMapObject item in componentsInChildren)
				{
					list.Add(item);
				}
			}
			return list;
		}

		public static List<SpawnSyncedObject> GetSpawnSyncedObjects(this DungeonFlow dungeonFlow)
		{
			List<SpawnSyncedObject> list = new List<SpawnSyncedObject>();
			foreach (Tile tile in dungeonFlow.GetTiles())
			{
				Doorway[] componentsInChildren = ((Component)tile).gameObject.GetComponentsInChildren<Doorway>();
				foreach (Doorway val in componentsInChildren)
				{
					foreach (GameObjectWeight connectorPrefabWeight in val.ConnectorPrefabWeights)
					{
						SpawnSyncedObject[] componentsInChildren2 = connectorPrefabWeight.GameObject.GetComponentsInChildren<SpawnSyncedObject>();
						foreach (SpawnSyncedObject item in componentsInChildren2)
						{
							list.Add(item);
						}
					}
					foreach (GameObjectWeight blockerPrefabWeight in val.BlockerPrefabWeights)
					{
						SpawnSyncedObject[] componentsInChildren3 = blockerPrefabWeight.GameObject.GetComponentsInChildren<SpawnSyncedObject>();
						foreach (SpawnSyncedObject item2 in componentsInChildren3)
						{
							list.Add(item2);
						}
					}
				}
				SpawnSyncedObject[] componentsInChildren4 = ((Component)tile).gameObject.GetComponentsInChildren<SpawnSyncedObject>();
				foreach (SpawnSyncedObject item3 in componentsInChildren4)
				{
					list.Add(item3);
				}
			}
			return list;
		}

		public static void AddReferences(this CompatibleNoun compatibleNoun, TerminalKeyword firstNoun, TerminalNode firstResult)
		{
			compatibleNoun.noun = firstNoun;
			compatibleNoun.result = firstResult;
		}

		public static void AddCompatibleNoun(this TerminalKeyword terminalKeyword, TerminalKeyword newNoun, TerminalNode newResult)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (terminalKeyword.compatibleNouns == null)
			{
				terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[0];
			}
			CompatibleNoun val = new CompatibleNoun();
			val.noun = newNoun;
			val.result = newResult;
			terminalKeyword.compatibleNouns = CollectionExtensions.AddItem<CompatibleNoun>((IEnumerable<CompatibleNoun>)terminalKeyword.compatibleNouns, val).ToArray();
		}

		public static void AddCompatibleNoun(this TerminalNode terminalNode, TerminalKeyword newNoun, TerminalNode newResult)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (terminalNode.terminalOptions == null)
			{
				terminalNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[0];
			}
			CompatibleNoun val = new CompatibleNoun();
			val.noun = newNoun;
			val.result = newResult;
			terminalNode.terminalOptions = CollectionExtensions.AddItem<CompatibleNoun>((IEnumerable<CompatibleNoun>)terminalNode.terminalOptions, val).ToArray();
		}

		public static void Add(this IntWithRarity intWithRarity, int id, int rarity)
		{
			intWithRarity.id = id;
			intWithRarity.rarity = rarity;
		}

		public static string Sanitized(this string currentString)
		{
			return new string(currentString.SkipToLetters().RemoveWhitespace().ToLowerInvariant());
		}

		public static string RemoveWhitespace(this string input)
		{
			return new string((from c in input.ToCharArray()
				where !char.IsWhiteSpace(c)
				select c).ToArray());
		}

		public static string SkipToLetters(this string input)
		{
			return new string(input.SkipWhile((char c) => !char.IsLetter(c)).ToArray());
		}

		public static string StripSpecialCharacters(this string input)
		{
			string text = string.Empty;
			for (int i = 0; i < input.Length; i++)
			{
				char c = input[i];
				if ((!".,?!@#$%^&*()_+-=';:'\"".ToCharArray().Contains(c) && char.IsLetterOrDigit(c)) || c.ToString() == " ")
				{
					text += c;
				}
			}
			return text;
		}

		public static List<DungeonFlow> GetDungeonFlows(this RoundManager roundManager)
		{
			return roundManager.dungeonFlowTypes.Select((IndoorMapType i) => i.dungeonFlow).ToList();
		}
	}
	internal static class Patches
	{
		private class DoorwayPairComparer : IComparer<DoorwayPair>
		{
			public int Compare(DoorwayPair x, DoorwayPair y)
			{
				int num = ((DoorwayPair)(ref y)).TileWeight.CompareTo(((DoorwayPair)(ref x)).TileWeight);
				if (num == 0)
				{
					return ((DoorwayPair)(ref y)).DoorwayWeight.CompareTo(((DoorwayPair)(ref x)).DoorwayWeight);
				}
				return num;
			}
		}

		internal const int harmonyPriority = 200;

		internal static string delayedSceneLoadingName = string.Empty;

		internal static List<string> allSceneNamesCalledToLoad = new List<string>();

		public static bool hasInitiallyChangedLevel;

		internal static bool ranLethalLevelLoaderTerminalEvent;

		private static List<SpawnableMapObject> tempoarySpawnableMapObjectList = new List<SpawnableMapObject>();

		internal static GameObject previousHit;

		internal static FootstepSurface previouslyAssignedFootstepSurface;

		public static StartOfRound StartOfRound { get; internal set; }

		public static RoundManager RoundManager { get; internal set; }

		public static Terminal Terminal { get; internal set; }

		public static TimeOfDay TimeOfDay { get; internal set; }

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPrefix]
		internal static void PreInitSceneScriptAwake_Prefix(PreInitSceneScript __instance)
		{
			if (!Plugin.IsSetupComplete)
			{
				AudioSource val = default(AudioSource);
				if (((Component)__instance).TryGetComponent<AudioSource>(ref val))
				{
					OriginalContent.AudioMixers.Add(val.outputAudioMixerGroup.audioMixer);
				}
				if (AssetBundleLoader.noBundlesFound)
				{
					AssetBundleLoader.CurrentLoadingStatus = AssetBundleLoader.LoadingStatus.Complete;
					AssetBundleLoader.OnBundlesFinishedLoadingInvoke();
				}
				ContentTagParser.ImportVanillaContentTags();
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(PreInitSceneScript), "ChooseLaunchOption")]
		[HarmonyPrefix]
		internal static bool PreInitSceneScriptChooseLaunchOption_Prefix()
		{
			return true;
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(SceneManager), "LoadScene", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		internal static bool SceneManagerLoadScene(string sceneName)
		{
			//IL_002b: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			if (allSceneNamesCalledToLoad.Count == 0)
			{
				List<string> list = allSceneNamesCalledToLoad;
				Scene activeScene = SceneManager.GetActiveScene();
				list.Add(((Scene)(ref activeScene)).name);
			}
			SceneManager.GetSceneByName(sceneName);
			if (true)
			{
				allSceneNamesCalledToLoad.Add(sceneName);
			}
			if (sceneName == "MainMenu" && !allSceneNamesCalledToLoad.Contains("InitSceneLaunchOptions"))
			{
				DebugHelper.LogError("SceneManager has been told to load Main Menu without ever loading InitSceneLaunchOptions. This will break LethalLevelLoader. This is likely due to a \"Skip to Main Menu\" mod.", DebugType.User);
				return false;
			}
			if (AssetBundleLoader.CurrentLoadingStatus == AssetBundleLoader.LoadingStatus.Loading)
			{
				DebugHelper.LogWarning("SceneManager has attempted to load " + sceneName + " Scene before AssetBundles have finished loading. Pausing request until LethalLeveLoader is ready to proceed.", DebugType.User);
				delayedSceneLoadingName = sceneName;
				AssetBundleLoader.onBundlesFinishedLoading -= LoadMainMenu;
				AssetBundleLoader.onBundlesFinishedLoading += LoadMainMenu;
				return false;
			}
			return true;
		}

		internal static void LoadMainMenu()
		{
			DebugHelper.LogWarning("Proceeding with the loading of " + delayedSceneLoadingName + " Scene as LethalLevelLoader has finished loading AssetBundles.", DebugType.User);
			if (delayedSceneLoadingName != string.Empty)
			{
				SceneManager.LoadScene(delayedSceneLoadingName);
			}
			delayedSceneLoadingName = string.Empty;
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPrefix]
		internal static void GameNetworkManagerStart_Prefix(GameNetworkManager __instance)
		{
			if (Plugin.IsSetupComplete)
			{
				return;
			}
			LethalLevelLoaderNetworkManager.networkManager = ((Component)__instance).GetComponent<NetworkManager>();
			foreach (NetworkPrefab prefab in ((Component)__instance).GetComponent<NetworkManager>().NetworkConfig.Prefabs.m_Prefabs)
			{
				if (((Object)prefab.Prefab).name.Contains("EntranceTeleport") && (Object)(object)prefab.Prefab.GetComponent<AudioSource>() != (Object)null)
				{
					OriginalContent.AudioMixers.Add(prefab.Prefab.GetComponent<AudioSource>().outputAudioMixerGroup.audioMixer);
				}
			}
			GameObject val = PrefabHelper.CreateNetworkPrefab("LethalLevelLoaderNetworkManagerTest");
			val.AddComponent<LethalLevelLoaderNetworkManager>();
			val.GetComponent<NetworkObject>().DontDestroyWithOwner = true;
			val.GetComponent<NetworkObject>().SceneMigrationSynchronization = true;
			val.GetComponent<NetworkObject>().DestroyWithScene = false;
			Object.DontDestroyOnLoad((Object)(object)val);
			LethalLevelLoaderNetworkManager.networkingManagerPrefab = val;
			LethalLevelLoaderNetworkManager.RegisterNetworkPrefab(val);
			AssetBundleLoader.NetworkRegisterCustomContent(((Component)__instance).GetComponent<NetworkManager>());
			LethalLevelLoaderNetworkManager.RegisterPrefabs(((Component)__instance).GetComponent<NetworkManager>());
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(GameNetworkManager), "SaveGameValues")]
		[HarmonyPostfix]
		internal static void GameNetworkManagerSaveGameValues_Postfix(GameNetworkManager __instance)
		{
			if (__instance.isHostingGame && StartOfRound.Instance.inShipPhase && !StartOfRound.Instance.isChallengeFile)
			{
				SaveManager.SaveGameValues();
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		internal static void StartOfRoundAwake_Prefix(StartOfRound __instance)
		{
			Plugin.OnBeforeSetupInvoke();
			StartOfRound = __instance;
			RoundManager = Object.FindFirstObjectByType<RoundManager>();
			Terminal = Object.FindFirstObjectByType<Terminal>();
			TimeOfDay = Object.FindFirstObjectByType<TimeOfDay>();
			SceneManager.sceneLoaded += OnSceneLoaded;
			SceneManager.sceneLoaded += EventPatches.OnSceneLoaded;
			if (!Plugin.IsSetupComplete)
			{
				StartOfRound.allItemsList.itemsList.RemoveAt(2);
				DebugStopwatch.StartStopWatch("Scrape Vanilla Content");
				ContentExtractor.TryScrapeVanillaItems(StartOfRound);
				ContentExtractor.TryScrapeVanillaContent(StartOfRound, RoundManager);
				ContentExtractor.ObtainSpecialItemReferences();
			}
			if (((Component)GameNetworkManager.Instance).GetComponent<NetworkManager>().IsServer)
			{
				Object.Instantiate<GameObject>(LethalLevelLoaderNetworkManager.networkingManagerPrefab).GetComponent<NetworkObject>().Spawn(false);
			}
			RoundManager.firstTimeDungeonAudios = CollectionExtensions.AddItem<AudioClip>((IEnumerable<AudioClip>)RoundManager.firstTimeDungeonAudios.ToList(), RoundManager.firstTimeDungeonAudios[0]).ToArray();
			DebugStopwatch.StartStopWatch("Fix AudioSource Settings");
			AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>();
			foreach (AudioSource val in array)
			{
				val.spatialize = false;
			}
			if (!Plugin.IsSetupComplete)
			{
				TerminalManager.CacheTerminalReferences();
				LevelManager.InitalizeShipAnimatorOverrideController();
				DungeonLoader.defaultKeyPrefab = RoundManager.keyPrefab;
				LevelLoader.defaultQuicksandPrefab = RoundManager.quicksandPrefab;
				DebugStopwatch.StartStopWatch("Create Vanilla ExtendedContent");
				AssetBundleLoader.CreateVanillaExtendedDungeonFlows();
				AssetBundleLoader.Cre