Decompiled source of LethalLevelLoader v1.3.13

LethalLevelLoader.dll

Decompiled 3 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.Bootstrap;
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 TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("LethalLevelLoader")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A Custom API to support the manual and dynamic integration of custom levels and dungeons in Lethal Company.")]
[assembly: AssemblyFileVersion("1.3.12.0")]
[assembly: AssemblyInformationalVersion("1.3.12+30b4da4268be47c98607ff1b17bcf9fd054c1216")]
[assembly: AssemblyProduct("LethalLevelLoader")]
[assembly: AssemblyTitle("LethalLevelLoader")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/IAmBatby/LethalLevelLoader/")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Expected O, but got Unknown
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Expected O, but got Unknown
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: 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_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0032: 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_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0032: 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_0004: Unknown result type (might be due to invalid IL or missing references)
		bool flag = orig(self, sceneIndex, sceneName, loadSceneMode);
		return true;
	}
}
namespace LethalLevelLoader
{
	[CreateAssetMenu(fileName = "ExtendedBuyableVehicle", menuName = "Lethal Level Loader/Extended Content/ExtendedBuyableVehicle", order = 21)]
	public class ExtendedBuyableVehicle : ExtendedContent
	{
		[field: SerializeField]
		public BuyableVehicle BuyableVehicle { get; set; }

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


		public int VehicleID { get; set; }

		public TerminalNode VehicleBuyNode { get; set; }

		public TerminalNode VehicleBuyConfirmNode { get; set; }

		public TerminalNode VehicleInfoNode { get; set; }

		internal static ExtendedBuyableVehicle Create(BuyableVehicle newBuyableVehicle)
		{
			ExtendedBuyableVehicle extendedBuyableVehicle = ScriptableObject.CreateInstance<ExtendedBuyableVehicle>();
			((Object)extendedBuyableVehicle).name = ((Object)newBuyableVehicle.vehiclePrefab).name;
			extendedBuyableVehicle.BuyableVehicle = newBuyableVehicle;
			return extendedBuyableVehicle;
		}
	}
	public class ExtendedContent : ScriptableObject
	{
		public ExtendedMod ExtendedMod { get; internal set; }

		public ContentType ContentType { get; internal set; }

		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;

		public string UniqueIdentificationName => AuthorName.ToLowerInvariant() + "." + ModName.ToLowerInvariant() + "." + ((Object)this).name.ToLowerInvariant();

		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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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(5f)]
		[Tooltip("Overrides vanilla camera Far Plane Clip Distance, The highest value between current Level and Interior will be used.")]
		[Range(0f, 10000f)]
		[SerializeField]
		public float OverrideCameraMaxDistance = 400f;

		[Space(25f)]
		[Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")]
		[Obsolete]
		public bool generateAutomaticConfigurationOptions = true;

		[Obsolete]
		public bool enableDynamicDungeonSizeRestriction;

		[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];
			}
		}

		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_00fa: 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;
	}
	[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;
	}
	[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;

		[Space(5f)]
		[Tooltip("Overrides vanilla camera Far Plane Clip Distance, The highest value between current Level and Interior will be used.")]
		[Range(0f, 10000f)]
		[SerializeField]
		public float OverrideCameraMaxDistance = 400f;

		[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; }

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

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

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

		[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("Weather Fog Distance Override Settings")]
		[field: SerializeField]
		public Vector3 OverrideDustStormVolumeSize { get; set; } = Vector3.zero;


		[field: SerializeField]
		public Vector3 OverrideFoggyVolumeSize { get; set; } = Vector3.zero;


		[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 TerminalNode SimulateNode { 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; }

		[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>();


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


		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);
				}
				foreach (ExtendedStoryLog extendedStoryLog in ExtendedStoryLogs)
				{
					list.Add(extendedStoryLog);
				}
				foreach (ExtendedBuyableVehicle extendedBuyableVehicle in ExtendedBuyableVehicles)
				{
					list.Add(extendedBuyableVehicle);
				}
				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;
					}
					if (newExtendedContent is ExtendedBuyableVehicle extendedBuyableVehicle)
					{
						RegisterExtendedContent(extendedBuyableVehicle);
						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 RegisterExtendedContent(ExtendedBuyableVehicle extendedBuyableVehicle)
		{
			TryThrowInvalidContentException(extendedBuyableVehicle, Validators.ValidateExtendedContent(extendedBuyableVehicle));
			ExtendedBuyableVehicles.Add(extendedBuyableVehicle);
			extendedBuyableVehicle.ContentTags.Add(ContentTag.Create("Custom"));
			extendedBuyableVehicle.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();
			ExtendedStoryLogs.Clear();
			ExtendedBuyableVehicles.Clear();
		}

		internal void SortRegisteredContent()
		{
			ExtendedLevels.Sort((ExtendedLevel s1, ExtendedLevel s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			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));
			ExtendedStoryLogs.Sort((ExtendedStoryLog s1, ExtendedStoryLog s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			ExtendedBuyableVehicles.Sort((ExtendedBuyableVehicle s1, ExtendedBuyableVehicle 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_0000: 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_0024: 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 List<ExtendedLevelData> extendedLevelSaveData = new List<ExtendedLevelData>();

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


		public void Reset()
		{
			CurrentLevelName = string.Empty;
			parityStepsTaken = 0;
			itemSaveData = new Dictionary<int, AllItemsListItemData>();
			extendedLevelSaveData = new List<ExtendedLevelData>();
		}
	}
	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;
		}
	}
	public struct ExtendedLevelData : INetworkSerializable
	{
		public string uniqueIdentifier;

		public bool isHidden;

		public bool isLocked;

		public string UniqueIdentifier => uniqueIdentifier;

		public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			serializer.SerializeValue(ref uniqueIdentifier, false);
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref isHidden, default(ForPrimitives));
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref isLocked, default(ForPrimitives));
		}

		public ExtendedLevelData(ExtendedLevel extendedLevel)
		{
			uniqueIdentifier = string.Empty;
			uniqueIdentifier = extendedLevel.UniqueIdentificationName;
			isHidden = extendedLevel.IsRouteHidden;
			isLocked = extendedLevel.IsRouteLocked;
		}

		public void ApplySavedValues(ExtendedLevel extendedLevel)
		{
			extendedLevel.IsRouteHidden = isHidden;
			extendedLevel.IsRouteLocked = isLocked;
		}
	}
	[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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			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_0001: 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
	{
		internal static Dictionary<string, ExtendedContent> UniqueIdentifiersDictionary = new Dictionary<string, ExtendedContent>();

		internal static Dictionary<SelectableLevel, ExtendedLevel> ExtendedLevelDictionary = new Dictionary<SelectableLevel, ExtendedLevel>();

		internal static Dictionary<DungeonFlow, ExtendedDungeonFlow> ExtendedDungeonFlowDictionary = new Dictionary<DungeonFlow, ExtendedDungeonFlow>();

		internal static Dictionary<Item, ExtendedItem> ExtendedItemDictionary = new Dictionary<Item, ExtendedItem>();

		internal static Dictionary<EnemyType, ExtendedEnemyType> ExtendedEnemyTypeDictionary = new Dictionary<EnemyType, ExtendedEnemyType>();

		internal static Dictionary<BuyableVehicle, ExtendedBuyableVehicle> ExtendedBuyableVehicleDictionary = new Dictionary<BuyableVehicle, ExtendedBuyableVehicle>();

		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;
			}
		}

		[Obsolete("Use PatchedContent.SelectableLevels instead.")]
		public static List<SelectableLevel> SeletectableLevels => SelectableLevels;

		public static List<SelectableLevel> SelectableLevels
		{
			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<ExtendedBuyableVehicle> ExtendedBuyableVehicles { get; internal set; } = new List<ExtendedBuyableVehicle>();


		public static List<ExtendedBuyableVehicle> CustomExtendedBuyableVehicles
		{
			get
			{
				List<ExtendedBuyableVehicle> list = new List<ExtendedBuyableVehicle>();
				foreach (ExtendedBuyableVehicle extendedBuyableVehicle in ExtendedBuyableVehicles)
				{
					if (extendedBuyableVehicle.ContentType == ContentType.Custom)
					{
						list.Add(extendedBuyableVehicle);
					}
				}
				return list;
			}
		}

		public static List<ExtendedBuyableVehicle> VanillaExtendedBuyableVehicles
		{
			get
			{
				List<ExtendedBuyableVehicle> list = new List<ExtendedBuyableVehicle>();
				foreach (ExtendedBuyableVehicle extendedBuyableVehicle in ExtendedBuyableVehicles)
				{
					if (extendedBuyableVehicle.ContentType == ContentType.Vanilla)
					{
						list.Add(extendedBuyableVehicle);
					}
				}
				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();
			}
		}

		internal static void PopulateContentDictionaries()
		{
			foreach (ExtendedLevel extendedLevel in ExtendedLevels)
			{
				TryAdd(ExtendedLevelDictionary, extendedLevel.SelectableLevel, extendedLevel);
				TryAddUUID(extendedLevel);
			}
			foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows)
			{
				TryAdd(ExtendedDungeonFlowDictionary, extendedDungeonFlow.DungeonFlow, extendedDungeonFlow);
				TryAddUUID(extendedDungeonFlow);
			}
			foreach (ExtendedItem extendedItem in ExtendedItems)
			{
				TryAdd(ExtendedItemDictionary, extendedItem.Item, extendedItem);
				TryAddUUID(extendedItem);
			}
			foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes)
			{
				TryAdd(ExtendedEnemyTypeDictionary, extendedEnemyType.EnemyType, extendedEnemyType);
				TryAddUUID(extendedEnemyType);
			}
			foreach (ExtendedBuyableVehicle extendedBuyableVehicle in ExtendedBuyableVehicles)
			{
				TryAdd(ExtendedBuyableVehicleDictionary, extendedBuyableVehicle.BuyableVehicle, extendedBuyableVehicle);
				TryAddUUID(extendedBuyableVehicle);
			}
		}

		internal static void TryAddUUID(ExtendedContent extendedContent)
		{
			TryAdd(UniqueIdentifiersDictionary, extendedContent.UniqueIdentificationName, extendedContent);
		}

		internal static bool TryAdd<T1, T2>(Dictionary<T1, T2> dict, T1 key, T2 value)
		{
			if (!dict.ContainsKey(key))
			{
				dict.Add(key, value);
				return true;
			}
			DebugHelper.LogError("Could not add " + key.ToString() + " to dictionary.", DebugType.Developer);
			return false;
		}

		public static bool TryGetExtendedContent(SelectableLevel selectableLevel, out ExtendedLevel extendedLevel)
		{
			return ExtendedLevelDictionary.TryGetValue(selectableLevel, out extendedLevel);
		}

		public static bool TryGetExtendedContent(DungeonFlow dungeonFlow, out ExtendedDungeonFlow extendedDungeonFlow)
		{
			return ExtendedDungeonFlowDictionary.TryGetValue(dungeonFlow, out extendedDungeonFlow);
		}

		public static bool TryGetExtendedContent(Item item, out ExtendedItem extendedItem)
		{
			return ExtendedItemDictionary.TryGetValue(item, out extendedItem);
		}

		public static bool TryGetExtendedContent(EnemyType enemyType, out ExtendedEnemyType extendedEnemyType)
		{
			return ExtendedEnemyTypeDictionary.TryGetValue(enemyType, out extendedEnemyType);
		}

		public static bool TryGetExtendedContent(BuyableVehicle buyableVehicle, out ExtendedBuyableVehicle extendedBuyableVehicle)
		{
			return ExtendedBuyableVehicleDictionary.TryGetValue(buyableVehicle, out extendedBuyableVehicle);
		}

		public static bool TryGetExtendedContent<T>(string uniqueIdentifierName, out T extendedContent) where T : ExtendedContent
		{
			extendedContent = null;
			if (UniqueIdentifiersDictionary.TryGetValue(uniqueIdentifierName, out var value))
			{
				extendedContent = value as T;
			}
			return (Object)(object)extendedContent != (Object)null;
		}
	}
	public static class OriginalContent
	{
		public static StartOfRound StartOfRound => Patches.StartOfRound;

		public static RoundManager RoundManager => Patches.RoundManager;

		public static Terminal Terminal => Patches.Terminal;

		public static TimeOfDay TimeOfDay => Patches.TimeOfDay;

		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_001a: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_Prefix(LungProp __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer && __instance.isLungDocked)
			{
				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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_001f: 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)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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;

		private event Action onEvent;

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

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

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

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

		public void RemoveListener(ParameterEvent listener)
		{
			onParameterEvent -= listener;
			Listeners--;
		}

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

		public bool Has