Decompiled source of Repo Dynamic Menus v1.0.32

EmpressGeneratedLevelMenu.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.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Empress")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.32.0")]
[assembly: AssemblyInformationalVersion("1.0.32")]
[assembly: AssemblyProduct("EmpressGeneratedLevelMenu")]
[assembly: AssemblyTitle("EmpressGeneratedLevelMenu")]
[assembly: AssemblyVersion("1.0.32.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EmpressGeneratedLevelMenu
{
	[BepInPlugin("empress.repo.generatedlevelmenu", "EmpressGeneratedLevelMenu", "1.0.32")]
	public sealed class EmpressGeneratedLevelMenuPlugin : BaseUnityPlugin
	{
		internal const string PluginGuid = "empress.repo.generatedlevelmenu";

		internal const string PluginName = "EmpressGeneratedLevelMenu";

		internal const string PluginVersion = "1.0.32";

		internal const float EmpressDefaultPreviewPauseSeconds = 1.5f;

		internal const float EmpressDefaultPreviewFadeSeconds = 1.35f;

		internal const float EmpressDefaultPreviewCameraHeight = 1.5f;

		internal const float EmpressDefaultPreviewFieldOfView = 66f;

		internal const int EmpressDefaultMenuMusicVolume = 30;

		private Harmony? empressHarmony;

		internal ConfigEntry<bool> EmpressEnabled;

		internal ConfigEntry<int> EmpressMenuMusicVolume;

		internal static EmpressGeneratedLevelMenuPlugin? Instance { get; private set; }

		internal EmpressGeneratedLevelMenuRuntime? EmpressRuntime { get; set; }

		internal ManualLogSource EmpressLog => ((BaseUnityPlugin)this).Logger;

		internal void EmpressInternalTrace(string message)
		{
		}

		private void Awake()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			Instance = this;
			((Object)this).hideFlags = (HideFlags)(((Object)this).hideFlags | 0x3D);
			GameObject gameObject = ((Component)this).gameObject;
			((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags | 0x3D);
			EmpressEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Replaces the vanilla main-menu truck backdrop with looping generated level flythroughs.");
			EmpressMenuMusicVolume = ((BaseUnityPlugin)this).Config.Bind<int>("Audio", "MenuMusicVolume", 30, new ConfigDescription("Sets the Empress menu music volume from 0 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			EmpressEnsureRuntime();
			empressHarmony = new Harmony("empress.repo.generatedlevelmenu");
			empressHarmony.PatchAll();
		}

		private void OnDestroy()
		{
			Harmony? obj = empressHarmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if ((Object)(object)EmpressRuntime != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)EmpressRuntime).gameObject);
				EmpressRuntime = null;
			}
			if (Instance == this)
			{
				Instance = null;
			}
		}

		internal EmpressGeneratedLevelMenuRuntime? EmpressEnsureRuntime()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if ((Object)(object)EmpressRuntime != (Object)null)
			{
				return EmpressRuntime;
			}
			GameObject val = new GameObject("EmpressGeneratedLevelMenu.Runtime")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)(object)val);
			EmpressRuntime = val.AddComponent<EmpressGeneratedLevelMenuRuntime>();
			return EmpressRuntime;
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "Generate")]
	internal static class EmpressGeneratedLevelMenuPatchLevelGeneratorGenerate
	{
		private static bool Prefix(LevelGenerator __instance, ref IEnumerator __result)
		{
			if (EmpressGeneratedLevelMenuRuntime.EmpressTryUseMenuPreview(EmpressGeneratedLevelMenuPlugin.Instance?.EmpressEnsureRuntime(), __instance, out IEnumerator empressResult))
			{
				__result = empressResult;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "Awake")]
	internal static class EmpressGeneratedLevelMenuPatchLevelGeneratorAwake
	{
		private static void Postfix()
		{
			EmpressGeneratedLevelMenuPlugin.Instance?.EmpressEnsureRuntime()?.EmpressNotifyMenuLifecycle("LevelGenerator.Awake");
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "Start")]
	internal static class EmpressGeneratedLevelMenuPatchLevelGeneratorStart
	{
		private static void Postfix()
		{
			EmpressGeneratedLevelMenuPlugin.Instance?.EmpressEnsureRuntime()?.EmpressNotifyMenuLifecycle("LevelGenerator.Start");
		}
	}
	[HarmonyPatch(typeof(MainMenuOpen), "Awake")]
	internal static class EmpressGeneratedLevelMenuPatchMainMenuOpenAwake
	{
		private static void Postfix()
		{
			EmpressGeneratedLevelMenuPlugin.Instance?.EmpressEnsureRuntime()?.EmpressNotifyMenuLifecycle("MainMenuOpen.Awake");
		}
	}
	[HarmonyPatch(typeof(MainMenuOpen), "Start")]
	internal static class EmpressGeneratedLevelMenuPatchMainMenuOpenStart
	{
		private static void Postfix()
		{
			EmpressGeneratedLevelMenuPlugin.Instance?.EmpressEnsureRuntime()?.EmpressNotifyMenuLifecycle("MainMenuOpen.Start");
		}
	}
	[HarmonyPatch(typeof(MenuPageMain), "Start")]
	internal static class EmpressGeneratedLevelMenuPatchMenuPageMainStart
	{
		private static void Postfix()
		{
			EmpressGeneratedLevelMenuPlugin.Instance?.EmpressEnsureRuntime()?.EmpressNotifyMenuLifecycle("MenuPageMain.Start");
		}
	}
	[HarmonyPatch(typeof(TruckMenuAnimated), "Start")]
	internal static class EmpressGeneratedLevelMenuPatchTruckMenuAnimatedStart
	{
		private static void Postfix()
		{
			EmpressGeneratedLevelMenuPlugin.Instance?.EmpressEnsureRuntime()?.EmpressNotifyMenuLifecycle("TruckMenuAnimated.Start");
		}
	}
	[HarmonyPatch(typeof(LevelPoint), "NavMeshCheck")]
	internal static class EmpressGeneratedLevelMenuPatchLevelPointNavMeshCheck
	{
		private static bool Prefix(LevelPoint __instance, ref IEnumerator __result)
		{
			if (!EmpressGeneratedLevelMenuRuntime.EmpressShouldSuppressLevelPointValidation(__instance))
			{
				return true;
			}
			__result = EmpressGeneratedLevelMenuRuntime.EmpressEmptyCoroutine();
			return false;
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "Update")]
	internal static class EmpressGeneratedLevelMenuPatchExtractionPointUpdate
	{
		private static bool Prefix(ExtractionPoint __instance)
		{
			return !EmpressGeneratedLevelMenuRuntime.EmpressShouldSuppressPreviewExtraction(__instance);
		}
	}
	[HarmonyPatch(typeof(Sound), "Play")]
	internal static class EmpressGeneratedLevelMenuPatchSoundPlay
	{
		private static bool Prefix(Sound __instance, ref AudioSource? __result)
		{
			if (!EmpressGeneratedLevelMenuRuntime.EmpressShouldSuppressPreviewSound(__instance))
			{
				return true;
			}
			__result = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(Sound), "PlayLoop")]
	internal static class EmpressGeneratedLevelMenuPatchSoundPlayLoop
	{
		private static bool Prefix(Sound __instance)
		{
			return !EmpressGeneratedLevelMenuRuntime.EmpressShouldSuppressPreviewSound(__instance);
		}
	}
	[HarmonyPatch(typeof(LevelMusic), "Update")]
	internal static class EmpressGeneratedLevelMenuPatchLevelMusicUpdate
	{
		private static bool Prefix(LevelMusic __instance)
		{
			return !EmpressGeneratedLevelMenuRuntime.EmpressShouldSuppressOrRepairLevelMusic(__instance);
		}
	}
	[HarmonyPatch(typeof(ConstantMusic), "Update")]
	internal static class EmpressGeneratedLevelMenuPatchConstantMusicUpdate
	{
		private static bool Prefix(ConstantMusic __instance)
		{
			return !EmpressGeneratedLevelMenuRuntime.EmpressShouldSuppressConstantMusic(__instance);
		}
	}
	internal sealed class EmpressGeneratedLevelMenuRuntime : MonoBehaviour
	{
		private enum EmpressPreviewState
		{
			Idle,
			Building,
			Reveal,
			Travel,
			EndPause,
			FadeOut
		}

		private const string EmpressMenuMusicFileName = "EmpressMenuMusic.bin";

		private static readonly byte[] EmpressMenuMusicXorKey = Encoding.UTF8.GetBytes("empress.repo.generatedlevelmenu|menu-music|v1");

		private static readonly FieldRef<LevelMusic, AudioSource?> EmpressLevelMusicAudioSourceRef = AccessTools.FieldRefAccess<LevelMusic, AudioSource>("audioSource");

		private static readonly FieldRef<LevelMusic, bool> EmpressLevelMusicActiveRef = AccessTools.FieldRefAccess<LevelMusic, bool>("active");

		private static readonly FieldRef<LevelMusic, bool> EmpressLevelMusicActivePlayedRef = AccessTools.FieldRefAccess<LevelMusic, bool>("activePlayed");

		private static readonly FieldRef<LevelMusic, bool> EmpressLevelMusicInterruptRef = AccessTools.FieldRefAccess<LevelMusic, bool>("interrupt");

		private static readonly FieldRef<LevelMusic, float> EmpressLevelMusicInterruptVolumeRef = AccessTools.FieldRefAccess<LevelMusic, float>("interruptVolume");

		private static readonly FieldRef<LevelMusic, float> EmpressLevelMusicInterruptVolumeLerpRef = AccessTools.FieldRefAccess<LevelMusic, float>("interruptVolumeLerp");

		private static readonly FieldRef<LevelMusic, float> EmpressLevelMusicCooldownTimeRef = AccessTools.FieldRefAccess<LevelMusic, float>("cooldownTime");

		private static readonly FieldRef<LevelMusic, float> EmpressLevelMusicCooldownTimeMinRef = AccessTools.FieldRefAccess<LevelMusic, float>("cooldownTimeMin");

		private static readonly FieldRef<ConstantMusic, AudioSource?> EmpressConstantMusicAudioSourceRef = AccessTools.FieldRefAccess<ConstantMusic, AudioSource>("audioSource");

		private static readonly FieldRef<ConstantMusic, bool> EmpressConstantMusicSetupRef = AccessTools.FieldRefAccess<ConstantMusic, bool>("setup");

		private static readonly FieldRef<LevelPoint, bool> EmpressLevelPointTruckRef = AccessTools.FieldRefAccess<LevelPoint, bool>("Truck");

		private static readonly FieldRef<LevelPoint, bool> EmpressLevelPointModuleConnectRef = AccessTools.FieldRefAccess<LevelPoint, bool>("ModuleConnect");

		private static readonly FieldRef<LevelPoint, bool> EmpressLevelPointInStartRoomRef = AccessTools.FieldRefAccess<LevelPoint, bool>("inStartRoom");

		private static readonly FieldRef<LevelPoint, RoomVolume?> EmpressLevelPointRoomRef = AccessTools.FieldRefAccess<LevelPoint, RoomVolume>("Room");

		private static readonly FieldRef<LevelPoint, List<LevelPoint>> EmpressLevelPointConnectedPointsRef = AccessTools.FieldRefAccess<LevelPoint, List<LevelPoint>>("ConnectedPoints");

		private static readonly FieldRef<RoomVolume, bool> EmpressRoomVolumeTruckRef = AccessTools.FieldRefAccess<RoomVolume, bool>("Truck");

		private static readonly FieldRef<RoomVolume, bool> EmpressRoomVolumeExtractionRef = AccessTools.FieldRefAccess<RoomVolume, bool>("Extraction");

		private readonly List<Vector3> empressPreviewRoute = new List<Vector3>();

		private readonly List<LevelPoint> empressLastCameraPointRoute = new List<LevelPoint>();

		private LevelGenerator? empressActiveGenerator;

		private Level? empressLastPreviewLevel;

		private Level? empressCurrentPreviewLevel;

		private RawImage? empressFadeImage;

		private float empressFadeAlpha;

		private float empressTravelDistance;

		private float empressPreviewRouteLength;

		private Vector3 empressPreviewLookTarget;

		private bool empressRegenerateRequested;

		private bool empressBootstrapStarted;

		private bool empressHasShownFirstPreview;

		private bool empressLoggedUpdateMenuHeartbeat;

		private bool empressLoggedMenuProbe;

		private bool empressWasInMenuContext;

		private int empressNotifyLogCount;

		private string empressLastBootstrapWaitReason = string.Empty;

		private float empressBootstrapEarliestTime;

		private AudioSource? empressMenuMusicSource;

		private AudioClip? empressMenuMusicClip;

		private Coroutine? empressMenuMusicLoadCoroutine;

		private bool empressMenuMusicLoadFailed;

		private int empressLastCameraAnchorIndex = -1;

		private Vector3 empressLastCameraLookDirection = Vector3.forward;

		private float empressLastCameraLookDistance;

		private EmpressPreviewState empressPreviewState;

		internal static EmpressGeneratedLevelMenuRuntime? Instance { get; private set; }

		private static EmpressGeneratedLevelMenuPlugin? EmpressPlugin => EmpressGeneratedLevelMenuPlugin.Instance;

		private void Awake()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			((Object)this).hideFlags = (HideFlags)(((Object)this).hideFlags | 0x3D);
			GameObject gameObject = ((Component)this).gameObject;
			((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags | 0x3D);
			EmpressEnsureFadeOverlay();
			EmpressEnsureMenuMusicSource();
		}

		private void OnDestroy()
		{
			EmpressDisposeMenuMusic();
			if (Instance == this)
			{
				Instance = null;
			}
			if ((Object)(object)EmpressPlugin != (Object)null && EmpressPlugin.EmpressRuntime == this)
			{
				EmpressPlugin.EmpressRuntime = null;
			}
		}

		private void OnEnable()
		{
			SceneManager.sceneLoaded += EmpressOnSceneLoaded;
		}

		private void OnDisable()
		{
			SceneManager.sceneLoaded -= EmpressOnSceneLoaded;
		}

		private void Update()
		{
			bool flag = EmpressIsMenuPreviewContextActive();
			EmpressHandleDiagnosticHotkeys(flag);
			if (flag != empressWasInMenuContext)
			{
				EmpressResetPreviewState(stopRuntimeCoroutines: true, flag);
				empressWasInMenuContext = flag;
			}
			EmpressUpdateFadeVisual();
			EmpressUpdateMenuMusic(flag);
			if (flag)
			{
				EmpressHideGameplayUi();
			}
			if (!empressLoggedUpdateMenuHeartbeat && flag)
			{
				EmpressPlugin?.EmpressInternalTrace("EmpressGeneratedLevelMenu runtime update is alive inside the main menu.");
				empressLoggedUpdateMenuHeartbeat = true;
			}
			EmpressTryBootstrapExistingMenuGenerator();
			if (flag)
			{
				EmpressKeepMenuFrontEndAlive();
			}
			if ((Object)(object)empressActiveGenerator == (Object)null || !EmpressShouldUseMenuPreview(empressActiveGenerator) || !EmpressCanDriveMenuCamera())
			{
				return;
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			switch (empressPreviewState)
			{
			case EmpressPreviewState.Reveal:
				empressFadeAlpha = Mathf.MoveTowards(empressFadeAlpha, 0f, EmpressFadeSpeed(unscaledDeltaTime));
				EmpressApplyPreviewCamera(snapRotation: true);
				if (empressFadeAlpha <= 0f)
				{
					empressPreviewState = EmpressPreviewState.EndPause;
				}
				break;
			case EmpressPreviewState.Travel:
				empressPreviewState = EmpressPreviewState.EndPause;
				EmpressApplyPreviewCamera(snapRotation: true);
				break;
			case EmpressPreviewState.EndPause:
				EmpressApplyPreviewCamera(snapRotation: false);
				break;
			case EmpressPreviewState.FadeOut:
				empressPreviewState = EmpressPreviewState.EndPause;
				EmpressApplyPreviewCamera(snapRotation: true);
				break;
			case EmpressPreviewState.Building:
				empressFadeAlpha = 1f;
				break;
			}
		}

		private void LateUpdate()
		{
			if (!((Object)(object)empressActiveGenerator == (Object)null) && EmpressShouldUseMenuPreview(empressActiveGenerator) && EmpressCanDriveMenuCamera())
			{
				EmpressApplyPreviewCamera(snapRotation: true);
			}
		}

		internal static bool EmpressTryUseMenuPreview(EmpressGeneratedLevelMenuRuntime? runtime, LevelGenerator generator, out IEnumerator empressResult)
		{
			if ((Object)(object)runtime != (Object)null && runtime.EmpressCanTakeOverMenuGeneratorNow(generator, out string _))
			{
				empressResult = runtime.EmpressGenerateMenuPreview(generator);
				return true;
			}
			empressResult = null;
			return false;
		}

		internal static IEnumerator EmpressEmptyCoroutine()
		{
			yield break;
		}

		internal static bool EmpressShouldSuppressLevelPointValidation(LevelPoint? point)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance.EmpressIsPreviewObject(((Object)(object)point != (Object)null) ? ((Component)point).gameObject : null);
			}
			return false;
		}

		internal static bool EmpressShouldSuppressPreviewSound(Sound? sound)
		{
			GameObject candidate = (((Object)(object)sound?.Source != (Object)null) ? ((Component)sound.Source).gameObject : null);
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance.EmpressIsPreviewObject(candidate);
			}
			return false;
		}

		internal static bool EmpressShouldSuppressPreviewExtraction(ExtractionPoint? extractionPoint)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance.EmpressIsPreviewObject(((Object)(object)extractionPoint != (Object)null) ? ((Component)extractionPoint).gameObject : null);
			}
			return false;
		}

		internal static bool EmpressShouldSuppressOrRepairLevelMusic(LevelMusic? levelMusic)
		{
			if ((Object)(object)levelMusic == (Object)null)
			{
				return false;
			}
			if ((Object)(object)Instance != (Object)null && Instance.EmpressIsMenuPreviewContextActive())
			{
				EmpressResetLevelMusic(levelMusic);
				return true;
			}
			return false;
		}

		internal static bool EmpressShouldSuppressConstantMusic(ConstantMusic? constantMusic)
		{
			if ((Object)(object)constantMusic == (Object)null || (Object)(object)Instance == (Object)null || !Instance.EmpressIsMenuPreviewContextActive())
			{
				return false;
			}
			ref AudioSource reference = ref EmpressConstantMusicAudioSourceRef.Invoke(constantMusic);
			if ((Object)(object)reference == (Object)null)
			{
				reference = ((Component)constantMusic).GetComponent<AudioSource>();
			}
			if ((Object)(object)reference != (Object)null && reference.isPlaying)
			{
				reference.Stop();
			}
			EmpressConstantMusicSetupRef.Invoke(constantMusic) = false;
			return true;
		}

		private static void EmpressResetLevelMusic(LevelMusic levelMusic)
		{
			ref AudioSource reference = ref EmpressLevelMusicAudioSourceRef.Invoke(levelMusic);
			if ((Object)(object)reference == (Object)null)
			{
				reference = ((Component)levelMusic).GetComponent<AudioSource>();
			}
			ref bool reference2 = ref EmpressLevelMusicActiveRef.Invoke(levelMusic);
			ref bool reference3 = ref EmpressLevelMusicActivePlayedRef.Invoke(levelMusic);
			ref bool reference4 = ref EmpressLevelMusicInterruptRef.Invoke(levelMusic);
			ref float reference5 = ref EmpressLevelMusicInterruptVolumeRef.Invoke(levelMusic);
			ref float reference6 = ref EmpressLevelMusicInterruptVolumeLerpRef.Invoke(levelMusic);
			ref float reference7 = ref EmpressLevelMusicCooldownTimeRef.Invoke(levelMusic);
			ref float reference8 = ref EmpressLevelMusicCooldownTimeMinRef.Invoke(levelMusic);
			reference2 = false;
			reference3 = false;
			reference4 = false;
			reference5 = 0f;
			reference6 = 0f;
			reference7 = Mathf.Max(reference7, reference8);
			if ((Object)(object)reference != (Object)null)
			{
				reference.Stop();
				reference.clip = null;
			}
		}

		private static bool EmpressLevelPointTruck(LevelPoint? point)
		{
			if ((Object)(object)point != (Object)null)
			{
				return EmpressLevelPointTruckRef.Invoke(point);
			}
			return false;
		}

		private static bool EmpressLevelPointModuleConnect(LevelPoint? point)
		{
			if ((Object)(object)point != (Object)null)
			{
				return EmpressLevelPointModuleConnectRef.Invoke(point);
			}
			return false;
		}

		private static bool EmpressLevelPointInStartRoom(LevelPoint? point)
		{
			if ((Object)(object)point != (Object)null)
			{
				return EmpressLevelPointInStartRoomRef.Invoke(point);
			}
			return false;
		}

		private static RoomVolume? EmpressLevelPointRoom(LevelPoint? point)
		{
			if (!((Object)(object)point != (Object)null))
			{
				return null;
			}
			return EmpressLevelPointRoomRef.Invoke(point);
		}

		private static List<LevelPoint> EmpressLevelPointConnectedPoints(LevelPoint? point)
		{
			if (!((Object)(object)point != (Object)null))
			{
				return new List<LevelPoint>();
			}
			return EmpressLevelPointConnectedPointsRef.Invoke(point);
		}

		private static bool EmpressRoomVolumeTruck(RoomVolume? room)
		{
			if ((Object)(object)room != (Object)null)
			{
				return EmpressRoomVolumeTruckRef.Invoke(room);
			}
			return false;
		}

		private static bool EmpressRoomVolumeExtraction(RoomVolume? room)
		{
			if ((Object)(object)room != (Object)null)
			{
				return EmpressRoomVolumeExtractionRef.Invoke(room);
			}
			return false;
		}

		private static CameraNoPlayerTarget? EmpressResolveMenuCameraTarget()
		{
			CameraNoPlayerTarget instance = CameraNoPlayerTarget.instance;
			if ((Object)(object)instance != (Object)null)
			{
				return instance;
			}
			instance = ((IEnumerable<CameraNoPlayerTarget>)Object.FindObjectsOfType<CameraNoPlayerTarget>(true)).FirstOrDefault((Func<CameraNoPlayerTarget, bool>)((CameraNoPlayerTarget target) => (Object)(object)target != (Object)null));
			if ((Object)(object)instance != (Object)null)
			{
				CameraNoPlayerTarget.instance = instance;
			}
			return instance;
		}

		private static Camera? EmpressResolveLiveMenuCamera()
		{
			if ((Object)(object)GameDirector.instance?.MainCamera != (Object)null)
			{
				return GameDirector.instance.MainCamera;
			}
			if ((Object)(object)Camera.main != (Object)null)
			{
				return Camera.main;
			}
			return ((IEnumerable<Camera>)Object.FindObjectsOfType<Camera>(true)).FirstOrDefault((Func<Camera, bool>)((Camera camera) => (Object)(object)camera != (Object)null && ((Component)camera).CompareTag("MainCamera")));
		}

		private static bool EmpressCanDriveMenuCamera()
		{
			if (!((Object)(object)EmpressResolveMenuCameraTarget() != (Object)null) && !((Object)(object)CameraPosition.instance != (Object)null) && !((Object)(object)CameraAim.Instance != (Object)null))
			{
				return (Object)(object)EmpressResolveLiveMenuCamera() != (Object)null;
			}
			return true;
		}

		private void EmpressOnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			EmpressResetPreviewState(stopRuntimeCoroutines: true, resetFirstPreview: true);
			empressWasInMenuContext = EmpressIsMenuPreviewContextActive();
		}

		private bool EmpressIsMenuPreviewContextActive()
		{
			EmpressGeneratedLevelMenuPlugin? empressPlugin = EmpressPlugin;
			if (empressPlugin == null || !empressPlugin.EmpressEnabled.Value)
			{
				return false;
			}
			if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)RunManager.instance.levelCurrent == (Object)null)
			{
				return false;
			}
			return RunManager.instance.levelCurrent == RunManager.instance.levelMainMenu;
		}

		private void EmpressResetPreviewState(bool stopRuntimeCoroutines, bool resetFirstPreview)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (stopRuntimeCoroutines)
			{
				((MonoBehaviour)this).StopAllCoroutines();
			}
			EmpressRestoreVanillaMenuPresentation();
			empressActiveGenerator = null;
			empressCurrentPreviewLevel = null;
			empressRegenerateRequested = false;
			empressBootstrapStarted = false;
			empressLoggedMenuProbe = false;
			empressPreviewRoute.Clear();
			empressLastCameraPointRoute.Clear();
			empressLastCameraAnchorIndex = -1;
			empressLastCameraLookDirection = Vector3.forward;
			empressLastCameraLookDistance = 0f;
			empressPreviewRouteLength = 0f;
			empressTravelDistance = 0f;
			empressPreviewLookTarget = Vector3.zero;
			empressPreviewState = EmpressPreviewState.Idle;
			empressFadeAlpha = 0f;
			if (resetFirstPreview)
			{
				empressHasShownFirstPreview = false;
			}
			empressLoggedUpdateMenuHeartbeat = false;
			empressLastBootstrapWaitReason = string.Empty;
			empressBootstrapEarliestTime = 0f;
		}

		private AudioSource EmpressEnsureMenuMusicSource()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)empressMenuMusicSource != (Object)null)
			{
				return empressMenuMusicSource;
			}
			empressMenuMusicSource = ((Component)this).GetComponent<AudioSource>();
			if ((Object)(object)empressMenuMusicSource == (Object)null)
			{
				empressMenuMusicSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			}
			empressMenuMusicSource.playOnAwake = false;
			empressMenuMusicSource.loop = true;
			empressMenuMusicSource.spatialBlend = 0f;
			empressMenuMusicSource.priority = 64;
			empressMenuMusicSource.ignoreListenerPause = true;
			AudioSource? obj = empressMenuMusicSource;
			((Object)obj).hideFlags = (HideFlags)(((Object)obj).hideFlags | 0x3D);
			return empressMenuMusicSource;
		}

		private void EmpressUpdateMenuMusic(bool menuPreviewContext)
		{
			AudioSource val = EmpressEnsureMenuMusicSource();
			int num = Mathf.Clamp(EmpressPlugin?.EmpressMenuMusicVolume.Value ?? 30, 0, 100);
			val.volume = (float)num / 100f;
			if (menuPreviewContext)
			{
				EmpressGeneratedLevelMenuPlugin? empressPlugin = EmpressPlugin;
				if (empressPlugin != null && empressPlugin.EmpressEnabled.Value && num > 0)
				{
					if ((Object)(object)empressMenuMusicClip == (Object)null)
					{
						if (!empressMenuMusicLoadFailed && empressMenuMusicLoadCoroutine == null)
						{
							empressMenuMusicLoadCoroutine = ((MonoBehaviour)this).StartCoroutine(EmpressLoadMenuMusicClipCoroutine());
						}
						return;
					}
					if (val.clip != empressMenuMusicClip)
					{
						val.clip = empressMenuMusicClip;
					}
					if (!val.isPlaying)
					{
						val.Play();
					}
					return;
				}
			}
			if (val.isPlaying)
			{
				val.Stop();
			}
		}

		private IEnumerator EmpressLoadMenuMusicClipCoroutine()
		{
			string text = EmpressGetMenuMusicAssetPath();
			if (!File.Exists(text))
			{
				empressMenuMusicLoadFailed = true;
				empressMenuMusicLoadCoroutine = null;
				EmpressGeneratedLevelMenuPlugin? empressPlugin = EmpressPlugin;
				if (empressPlugin != null)
				{
					empressPlugin.EmpressLog.LogWarning((object)("EmpressGeneratedLevelMenu could not find the encrypted menu music asset at " + text + "."));
				}
				yield break;
			}
			string tempPath = Path.Combine(Path.GetTempPath(), "EmpressGeneratedLevelMenu_MenuMusic.mp3");
			try
			{
				byte[] array = File.ReadAllBytes(text);
				if (array.Length == 0)
				{
					empressMenuMusicLoadFailed = true;
					empressMenuMusicLoadCoroutine = null;
					EmpressGeneratedLevelMenuPlugin? empressPlugin2 = EmpressPlugin;
					if (empressPlugin2 != null)
					{
						empressPlugin2.EmpressLog.LogWarning((object)"EmpressGeneratedLevelMenu found an empty encrypted menu music asset.");
					}
					yield break;
				}
				File.WriteAllBytes(tempPath, EmpressXorDecrypt(array));
			}
			catch (Exception ex)
			{
				empressMenuMusicLoadFailed = true;
				empressMenuMusicLoadCoroutine = null;
				EmpressGeneratedLevelMenuPlugin? empressPlugin3 = EmpressPlugin;
				if (empressPlugin3 != null)
				{
					empressPlugin3.EmpressLog.LogWarning((object)("EmpressGeneratedLevelMenu failed to prepare the encrypted menu music: " + ex.Message));
				}
				yield break;
			}
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(tempPath).AbsoluteUri, (AudioType)13);
			try
			{
				DownloadHandler downloadHandler = request.downloadHandler;
				DownloadHandlerAudioClip val = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null);
				if (val != null)
				{
					val.streamAudio = false;
				}
				yield return request.SendWebRequest();
				if ((int)request.result != 1)
				{
					empressMenuMusicLoadFailed = true;
					empressMenuMusicLoadCoroutine = null;
					EmpressDeleteTempMenuMusic(tempPath);
					EmpressGeneratedLevelMenuPlugin? empressPlugin4 = EmpressPlugin;
					if (empressPlugin4 != null)
					{
						empressPlugin4.EmpressLog.LogWarning((object)("EmpressGeneratedLevelMenu failed to load the decrypted menu music: " + request.error));
					}
					yield break;
				}
				empressMenuMusicClip = DownloadHandlerAudioClip.GetContent(request);
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
			EmpressDeleteTempMenuMusic(tempPath);
			if ((Object)(object)empressMenuMusicClip == (Object)null)
			{
				empressMenuMusicLoadFailed = true;
				empressMenuMusicLoadCoroutine = null;
				EmpressGeneratedLevelMenuPlugin? empressPlugin5 = EmpressPlugin;
				if (empressPlugin5 != null)
				{
					empressPlugin5.EmpressLog.LogWarning((object)"EmpressGeneratedLevelMenu loaded the decrypted menu music request, but no AudioClip was returned.");
				}
			}
			else
			{
				((Object)empressMenuMusicClip).name = "EmpressGeneratedLevelMenu.CustomMusic";
				EmpressEnsureMenuMusicSource().clip = empressMenuMusicClip;
				empressMenuMusicLoadCoroutine = null;
			}
		}

		private void EmpressDisposeMenuMusic()
		{
			if (empressMenuMusicLoadCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(empressMenuMusicLoadCoroutine);
				empressMenuMusicLoadCoroutine = null;
			}
			if ((Object)(object)empressMenuMusicSource != (Object)null)
			{
				empressMenuMusicSource.Stop();
				empressMenuMusicSource.clip = null;
				empressMenuMusicSource = null;
			}
			if ((Object)(object)empressMenuMusicClip != (Object)null)
			{
				Object.Destroy((Object)(object)empressMenuMusicClip);
				empressMenuMusicClip = null;
			}
		}

		private static string EmpressGetMenuMusicAssetPath()
		{
			return Path.Combine(Path.GetDirectoryName(typeof(EmpressGeneratedLevelMenuPlugin).Assembly.Location) ?? AppDomain.CurrentDomain.BaseDirectory, "EmpressMenuMusic.bin");
		}

		private static byte[] EmpressXorDecrypt(byte[] encryptedBytes)
		{
			byte[] array = new byte[encryptedBytes.Length];
			for (int i = 0; i < encryptedBytes.Length; i++)
			{
				array[i] = (byte)(encryptedBytes[i] ^ EmpressMenuMusicXorKey[i % EmpressMenuMusicXorKey.Length]);
			}
			return array;
		}

		private static void EmpressDeleteTempMenuMusic(string tempPath)
		{
			try
			{
				if (File.Exists(tempPath))
				{
					File.Delete(tempPath);
				}
			}
			catch
			{
			}
		}

		private bool EmpressIsPreviewObject(GameObject? candidate)
		{
			if ((Object)(object)candidate == (Object)null || (Object)(object)empressActiveGenerator == (Object)null || !EmpressShouldUseMenuPreview(empressActiveGenerator))
			{
				return false;
			}
			if (!EmpressIsUnderRoot(candidate, empressActiveGenerator.LevelParent) && !EmpressIsUnderRoot(candidate, empressActiveGenerator.ItemParent))
			{
				return EmpressIsUnderRoot(candidate, empressActiveGenerator.EnemyParent);
			}
			return true;
		}

		private static bool EmpressIsUnderRoot(GameObject candidate, GameObject? root)
		{
			if ((Object)(object)root != (Object)null)
			{
				if (candidate != root)
				{
					return candidate.transform.IsChildOf(root.transform);
				}
				return true;
			}
			return false;
		}

		private bool EmpressShouldUseMenuPreview(LevelGenerator? generator)
		{
			EmpressGeneratedLevelMenuPlugin? empressPlugin = EmpressPlugin;
			if (empressPlugin == null || !empressPlugin.EmpressEnabled.Value)
			{
				return false;
			}
			if ((Object)(object)generator == (Object)null)
			{
				return false;
			}
			if (!EmpressIsMenuPreviewContextActive())
			{
				return false;
			}
			if (!((Object)(object)GameManager.instance == (Object)null))
			{
				return !GameManager.Multiplayer();
			}
			return true;
		}

		private void EmpressTryBootstrapExistingMenuGenerator()
		{
			if (empressBootstrapStarted || (Object)(object)empressActiveGenerator != (Object)null)
			{
				return;
			}
			LevelGenerator val = LevelGenerator.Instance;
			if ((Object)(object)val == (Object)null)
			{
				val = Object.FindObjectOfType<LevelGenerator>();
			}
			bool flag = EmpressIsMenuPreviewContextActive();
			if (!empressLoggedMenuProbe && (Object)(object)val != (Object)null && flag)
			{
				string text = (((Object)(object)RunManager.instance?.levelCurrent != (Object)null) ? ((Object)RunManager.instance.levelCurrent).name : "<null>");
				string text2 = (((Object)(object)GameManager.instance != (Object)null) ? GameManager.instance.gameMode.ToString() : "<no GameManager>");
				EmpressPlugin?.EmpressInternalTrace("EmpressGeneratedLevelMenu probe: menuContext=true, generatorFound=true, generated=" + val.Generated + ", level=" + text + ", gameMode=" + text2 + ".");
				empressLoggedMenuProbe = true;
			}
			if (!EmpressShouldUseMenuPreview(val))
			{
				return;
			}
			if (!EmpressCanTakeOverMenuGeneratorNow(val, out string waitReason))
			{
				if (!string.Equals(empressLastBootstrapWaitReason, waitReason, StringComparison.Ordinal))
				{
					EmpressPlugin?.EmpressInternalTrace("EmpressGeneratedLevelMenu is waiting for the live menu scene to finish booting before takeover: " + waitReason + ".");
					empressLastBootstrapWaitReason = waitReason;
				}
			}
			else
			{
				empressLastBootstrapWaitReason = string.Empty;
				LevelGenerator generator = val;
				empressBootstrapStarted = true;
				empressActiveGenerator = generator;
				((MonoBehaviour)this).StartCoroutine(EmpressBootstrapMenuPreview(generator));
			}
		}

		internal void EmpressNotifyMenuLifecycle(string source)
		{
			LevelGenerator val = LevelGenerator.Instance ?? Object.FindObjectOfType<LevelGenerator>();
			TruckMenuAnimated val2 = Object.FindObjectOfType<TruckMenuAnimated>();
			CameraMainMenu val3 = Object.FindObjectOfType<CameraMainMenu>();
			MainMenuOpen val4 = MainMenuOpen.instance ?? Object.FindObjectOfType<MainMenuOpen>();
			if (empressNotifyLogCount < 6)
			{
				string value = (((Object)(object)RunManager.instance?.levelCurrent != (Object)null) ? ((Object)RunManager.instance.levelCurrent).name : "<null>");
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("EmpressGeneratedLevelMenu signal from ");
				stringBuilder.Append(source);
				stringBuilder.Append(": mainMenu=");
				stringBuilder.Append((Object)(object)val4 != (Object)null);
				stringBuilder.Append(", generator=");
				stringBuilder.Append((Object)(object)val != (Object)null);
				stringBuilder.Append(", truck=");
				stringBuilder.Append((Object)(object)val2 != (Object)null);
				stringBuilder.Append(", cameraMainMenu=");
				stringBuilder.Append((Object)(object)val3 != (Object)null);
				stringBuilder.Append(", level=");
				stringBuilder.Append(value);
				stringBuilder.Append(", gameState=");
				stringBuilder.Append(((Object)(object)GameDirector.instance != (Object)null) ? ((object)(gameState)(ref GameDirector.instance.currentState)).ToString() : "<no GameDirector>");
				stringBuilder.Append(", gameMode=");
				stringBuilder.Append(((Object)(object)GameManager.instance != (Object)null) ? GameManager.instance.gameMode.ToString() : "<no GameManager>");
				EmpressPlugin?.EmpressInternalTrace(stringBuilder.ToString());
				empressNotifyLogCount++;
			}
			empressBootstrapEarliestTime = Mathf.Max(empressBootstrapEarliestTime, Time.unscaledTime + 0.05f);
			switch (source)
			{
			case "MainMenuOpen.Start":
			case "MenuPageMain.Start":
			case "TruckMenuAnimated.Start":
				if (source == "MainMenuOpen.Start")
				{
					EmpressForceLoadingOverlayOff();
					empressActiveGenerator = null;
					empressBootstrapStarted = false;
					empressLoggedMenuProbe = false;
					empressLastBootstrapWaitReason = string.Empty;
				}
				((MonoBehaviour)this).StartCoroutine(EmpressLifecycleBootstrapPulse(source));
				break;
			}
		}

		private IEnumerator EmpressLifecycleBootstrapPulse(string source)
		{
			EmpressPlugin?.EmpressInternalTrace("EmpressGeneratedLevelMenu queued a takeover pulse from " + source + ".");
			yield return null;
			EmpressTryBootstrapExistingMenuGenerator();
			yield return null;
			EmpressTryBootstrapExistingMenuGenerator();
		}

		private static T EmpressGetFieldValue<T>(object target, string fieldName)
		{
			return Traverse.Create(target).Field(fieldName).GetValue<T>();
		}

		private static void EmpressSetFieldValue(object target, string fieldName, object? value)
		{
			Traverse.Create(target).Field(fieldName).SetValue(value);
		}

		private static IEnumerator EmpressInvokeHiddenCoroutine(object target, string methodName)
		{
			return Traverse.Create(target).Method(methodName, Array.Empty<object>()).GetValue<IEnumerator>() ?? throw new MissingMethodException(target.GetType().FullName, methodName);
		}

		private bool EmpressCanTakeOverMenuGeneratorNow(LevelGenerator? generator, out string waitReason)
		{
			if (!EmpressShouldUseMenuPreview(generator))
			{
				waitReason = "not-in-menu-preview-context";
				return false;
			}
			if ((Object)(object)generator == (Object)null)
			{
				waitReason = "no-level-generator";
				return false;
			}
			if (!((Behaviour)generator).isActiveAndEnabled)
			{
				waitReason = "level-generator-inactive";
				return false;
			}
			if (Time.unscaledTime < empressBootstrapEarliestTime)
			{
				waitReason = "waiting-a-frame";
				return false;
			}
			if ((Object)(object)GameDirector.instance == (Object)null)
			{
				waitReason = "game-director-not-ready";
				return false;
			}
			if ((Object)(object)MenuManager.instance == (Object)null)
			{
				waitReason = "menu-manager-not-ready";
				return false;
			}
			if ((Object)(object)MainMenuOpen.instance == (Object)null && (Object)(object)Object.FindObjectOfType<MainMenuOpen>() == (Object)null)
			{
				waitReason = "main-menu-not-ready";
				return false;
			}
			if ((Object)(object)Object.FindObjectOfType<TruckMenuAnimated>() == (Object)null)
			{
				waitReason = "truck-menu-animation-not-ready";
				return false;
			}
			if (!EmpressCanDriveMenuCamera())
			{
				waitReason = "menu-camera-not-ready";
				return false;
			}
			waitReason = string.Empty;
			return true;
		}

		private IEnumerator EmpressBootstrapMenuPreview(LevelGenerator generator)
		{
			yield return null;
			if (!EmpressCanTakeOverMenuGeneratorNow(generator, out string waitReason))
			{
				EmpressGeneratedLevelMenuPlugin? empressPlugin = EmpressPlugin;
				if (empressPlugin != null)
				{
					empressPlugin.EmpressLog.LogWarning((object)("EmpressGeneratedLevelMenu bootstrap aborted before takeover because the menu scene changed: " + waitReason + "."));
				}
				empressActiveGenerator = null;
				empressBootstrapStarted = false;
			}
			else
			{
				((MonoBehaviour)generator).StopAllCoroutines();
				EmpressGeneratedLevelMenuPlugin? empressPlugin2 = EmpressPlugin;
				if (empressPlugin2 != null)
				{
					empressPlugin2.EmpressLog.LogInfo((object)"Empress took over your main menu LA LA LA");
				}
				yield return ((MonoBehaviour)this).StartCoroutine(EmpressGenerateMenuPreview(generator));
			}
		}

		private IEnumerator EmpressGenerateMenuPreview(LevelGenerator generator)
		{
			empressActiveGenerator = generator;
			EmpressEnsureFadeOverlay();
			EmpressDisableVanillaMenuCameraAnimations();
			EmpressEnsureMainMenuVisible();
			EmpressHideMenuBodies();
			while (EmpressShouldUseMenuPreview(generator))
			{
				yield return EmpressBuildPreviewCycle(generator);
				if (!EmpressShouldUseMenuPreview(generator))
				{
					break;
				}
				while (!empressRegenerateRequested && EmpressShouldUseMenuPreview(generator))
				{
					yield return null;
				}
				empressRegenerateRequested = false;
			}
			empressActiveGenerator = null;
			empressCurrentPreviewLevel = null;
			empressPreviewRoute.Clear();
			empressPreviewRouteLength = 0f;
			empressTravelDistance = 0f;
			empressPreviewState = EmpressPreviewState.Idle;
			empressFadeAlpha = 0f;
			empressBootstrapStarted = false;
		}

		private IEnumerator EmpressBuildPreviewCycle(LevelGenerator generator)
		{
			Level val = EmpressPickPreviewLevel();
			if ((Object)(object)val == (Object)null)
			{
				EmpressGeneratedLevelMenuPlugin? empressPlugin = EmpressPlugin;
				if (empressPlugin != null)
				{
					empressPlugin.EmpressLog.LogWarning((object)"EmpressGeneratedLevelMenu could not find a gameplay level to preview, so it will retry shortly.");
				}
				yield return (object)new WaitForSecondsRealtime(1f);
				yield break;
			}
			empressCurrentPreviewLevel = val;
			empressLastPreviewLevel = val;
			empressPreviewState = EmpressPreviewState.Building;
			empressFadeAlpha = (empressHasShownFirstPreview ? 1f : 0f);
			empressRegenerateRequested = false;
			EmpressPrepareGenerator(generator, val);
			EmpressClearPreviewContent(generator);
			yield return null;
			yield return ((MonoBehaviour)this).StartCoroutine(EmpressInvokeHiddenCoroutine(generator, "TileGeneration"));
			yield return ((MonoBehaviour)this).StartCoroutine(EmpressInvokeHiddenCoroutine(generator, "StartRoomGeneration"));
			yield return ((MonoBehaviour)this).StartCoroutine(EmpressInvokeHiddenCoroutine(generator, "GenerateConnectObjects"));
			yield return ((MonoBehaviour)this).StartCoroutine(EmpressInvokeHiddenCoroutine(generator, "ModuleGeneration"));
			yield return ((MonoBehaviour)this).StartCoroutine(EmpressInvokeHiddenCoroutine(generator, "GenerateBlockObjects"));
			int expectedModules = Mathf.Max(0, EmpressGetFieldValue<int>(generator, "ModuleAmount") - 1);
			float moduleWaitTimeout = Time.unscaledTime + 5f;
			while (EmpressGetFieldValue<int>(generator, "ModulesSpawned") < expectedModules && Time.unscaledTime < moduleWaitTimeout)
			{
				yield return null;
			}
			yield return (object)new WaitForSecondsRealtime(0.15f);
			EmpressRefreshLevelPoints(generator);
			if ((Object)(object)EnvironmentDirector.Instance != (Object)null)
			{
				EnvironmentDirector.Instance.Setup();
			}
			if ((Object)(object)PostProcessing.Instance != (Object)null)
			{
				PostProcessing.Instance.Setup();
			}
			generator.State = (LevelState)15;
			generator.Generated = true;
			SemiFunc.OnLevelGenDone();
			if ((Object)(object)GameDirector.instance != (Object)null && (int)GameDirector.instance.currentState < 2)
			{
				GameDirector.instance.SetStart();
			}
			yield return (object)new WaitForSecondsRealtime(0.15f);
			EmpressEnsureMainMenuVisible();
			EmpressRefreshLevelPoints(generator);
			EmpressStartCameraRoute(generator);
			EmpressSanitizePreviewWorld(generator);
			EmpressHideGameplayUi();
		}

		private void EmpressPrepareGenerator(LevelGenerator generator, Level previewLevel)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			generator.Generated = false;
			EmpressSetFieldValue(generator, "DebugNoEnemy", true);
			EmpressSetFieldValue(generator, "AllPlayersReady", true);
			EmpressSetFieldValue(generator, "waitingForSubCoroutine", false);
			generator.State = (LevelState)0;
			generator.Level = previewLevel;
			EmpressSetFieldValue(generator, "ModuleAmount", previewLevel.ModuleAmount);
			EmpressSetFieldValue(generator, "PassageAmount", 0);
			EmpressSetFieldValue(generator, "DeadEndAmount", 0);
			EmpressSetFieldValue(generator, "ExtractionAmount", 0);
			EmpressSetFieldValue(generator, "ModulesSpawned", 0);
			EmpressSetFieldValue(generator, "ModulesReadyPlayers", 0);
			EmpressSetFieldValue(generator, "EnemiesSpawned", 0);
			EmpressSetFieldValue(generator, "EnemiesSpawnTarget", 0);
			EmpressSetFieldValue(generator, "EnemyReadyPlayers", 0);
			EmpressSetFieldValue(generator, "EnemyReady", true);
			EmpressSetFieldValue(generator, "playerSpawned", 0);
			generator.LevelPathPoints.Clear();
			generator.LevelPathTruck = null;
			EmpressGetFieldValue<List<Player>>(generator, "ModulesReadyPlayerList").Clear();
			EmpressGetFieldValue<List<Player>>(generator, "EnemyReadyPlayerList").Clear();
			if ((Object)(object)ValuableDirector.instance != (Object)null)
			{
				EmpressSetFieldValue(ValuableDirector.instance, "valuableDebug", (object)(ValuableDebug)2);
				ValuableDirector.instance.setupComplete = true;
				EmpressSetFieldValue(ValuableDirector.instance, "valuableSpawnAmount", 0);
				EmpressSetFieldValue(ValuableDirector.instance, "valuableTargetAmount", 0);
				ValuableDirector.instance.valuableList.Clear();
			}
			if ((Object)(object)EnemyDirector.instance != (Object)null)
			{
				EnemyDirector.instance.enemiesSpawned?.Clear();
			}
			if ((Object)(object)RunManager.instance != (Object)null)
			{
				RunManager.instance.enemiesSpawned?.Clear();
			}
			if ((Object)(object)generator.ItemParent != (Object)null)
			{
				generator.ItemParent.SetActive(true);
			}
			if ((Object)(object)generator.EnemyParent != (Object)null)
			{
				generator.EnemyParent.SetActive(true);
			}
		}

		private void EmpressClearPreviewContent(LevelGenerator generator)
		{
			EmpressDestroyChildren(generator.LevelParent);
			EmpressDestroyChildren(generator.ItemParent);
			EmpressDestroyChildren(generator.EnemyParent);
			if ((Object)(object)Map.Instance != (Object)null && (Object)(object)Map.Instance.OverLayerParent != (Object)null)
			{
				EmpressDestroyChildren(((Component)Map.Instance.OverLayerParent).gameObject);
				Map.Instance.MapModules.Clear();
			}
		}

		private void EmpressDestroyChildren(GameObject? parent)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if ((Object)(object)parent == (Object)null)
			{
				return;
			}
			List<GameObject> list = new List<GameObject>();
			foreach (Transform item in parent.transform)
			{
				Transform val = item;
				if ((Object)(object)val != (Object)null)
				{
					list.Add(((Component)val).gameObject);
				}
			}
			foreach (GameObject item2 in list)
			{
				Object.Destroy((Object)(object)item2);
			}
		}

		private void EmpressRefreshLevelPoints(LevelGenerator generator)
		{
			if ((Object)(object)generator.LevelParent == (Object)null)
			{
				generator.LevelPathPoints.Clear();
				generator.LevelPathTruck = null;
				return;
			}
			generator.LevelPathPoints = (from point in generator.LevelParent.GetComponentsInChildren<LevelPoint>(true)
				where (Object)(object)point != (Object)null
				select point).Distinct().ToList();
			generator.LevelPathTruck = ((IEnumerable<LevelPoint>)generator.LevelPathPoints).FirstOrDefault((Func<LevelPoint, bool>)EmpressLevelPointTruck);
			if ((Object)(object)generator.LevelPathTruck != (Object)null)
			{
				return;
			}
			RoomVolume truckRoom = ((IEnumerable<RoomVolume>)generator.LevelParent.GetComponentsInChildren<RoomVolume>(true)).FirstOrDefault((Func<RoomVolume, bool>)EmpressRoomVolumeTruck);
			if (!((Object)(object)truckRoom == (Object)null))
			{
				generator.LevelPathTruck = generator.LevelPathPoints.OrderBy((LevelPoint point) => Vector3.Distance(((Component)point).transform.position, ((Component)truckRoom).transform.position)).FirstOrDefault();
			}
		}

		private void EmpressStartCameraRoute(LevelGenerator generator)
		{
			empressPreviewRoute.Clear();
			empressPreviewRoute.AddRange(EmpressBuildCameraRoute(generator));
			empressPreviewRouteLength = EmpressMeasureRoute(empressPreviewRoute);
			empressTravelDistance = 0f;
			empressPreviewState = (empressHasShownFirstPreview ? EmpressPreviewState.Reveal : EmpressPreviewState.EndPause);
			empressFadeAlpha = (empressHasShownFirstPreview ? 1f : 0f);
			empressHasShownFirstPreview = true;
			EmpressEnsureMainMenuVisible();
			EmpressApplyPreviewCamera(snapRotation: true);
		}

		private void EmpressEnsureMainMenuVisible()
		{
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)MenuManager.instance == (Object)null || ((Object)(object)MainMenuOpen.instance == (Object)null && (Object)(object)Object.FindObjectOfType<MainMenuOpen>() == (Object)null))
			{
				return;
			}
			MenuPageMain val = MenuPageMain.instance;
			if ((Object)(object)val == (Object)null)
			{
				MenuPage val2 = EmpressGetFieldValue<List<MenuPage>>(MenuManager.instance, "allPages")?.FirstOrDefault((Func<MenuPage, bool>)((MenuPage page) => (Object)(object)page != (Object)null && (int)page.menuPageIndex == 0));
				val = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<MenuPageMain>() : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
			}
			RectTransform component = ((Component)val).GetComponent<RectTransform>();
			MenuPage component2 = ((Component)val).GetComponent<MenuPage>();
			if ((Object)(object)component != (Object)null)
			{
				EmpressSetFieldValue(val, "rectTransform", component);
			}
			if ((Object)(object)component2 != (Object)null)
			{
				EmpressSetFieldValue(val, "menuPage", component2);
			}
			MenuManager.instance.StateSet((MenuState)0);
			if ((Object)(object)component2 != (Object)null)
			{
				MenuManager.instance.PageCloseAllExcept((MenuPageIndex)0);
				MenuManager.instance.PageSetCurrent((MenuPageIndex)0, component2);
				component2.disableIntroAnimation = true;
				component2.disableOutroAnimation = true;
				component2.PageStateSet((PageState)1);
			}
			EmpressSetFieldValue(val, "doIntroAnimation", false);
			EmpressSetFieldValue(val, "animateIn", false);
			EmpressSetFieldValue(val, "introDone", true);
			if ((Object)(object)component != (Object)null)
			{
				((Transform)component).localPosition = Vector3.zero;
			}
		}

		private void EmpressKeepMenuFrontEndAlive()
		{
			EmpressForceLoadingOverlayOff();
			if (!((Object)(object)MenuManager.instance == (Object)null) && (!MenuManager.instance.PageCheck((MenuPageIndex)0) || (Object)(object)MenuPageMain.instance == (Object)null))
			{
				EmpressEnsureMainMenuVisible();
			}
		}

		private void EmpressHandleDiagnosticHotkeys(bool menuPreviewContext)
		{
			if (Input.GetKeyDown((KeyCode)260))
			{
				EmpressLogCameraDiagnostic(menuPreviewContext, "GOOD");
			}
			if (Input.GetKeyDown((KeyCode)261))
			{
				EmpressLogCameraDiagnostic(menuPreviewContext, "BAD");
			}
		}

		private void EmpressLogCameraDiagnostic(bool menuPreviewContext, string label)
		{
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			if (EmpressPlugin?.EmpressLog != null)
			{
				CameraNoPlayerTarget val = EmpressResolveMenuCameraTarget();
				Camera val2 = EmpressResolveLiveMenuCamera();
				Transform val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).transform : (((Object)(object)val != (Object)null) ? ((Component)val).transform : (((Object)(object)CameraAim.Instance != (Object)null) ? ((Component)CameraAim.Instance).transform : null)));
				LevelGenerator val4 = empressActiveGenerator;
				List<LevelPoint> list = empressLastCameraPointRoute.Where((LevelPoint point) => (Object)(object)point != (Object)null).ToList();
				int num = ((list.Count > 0) ? Mathf.Clamp(empressLastCameraAnchorIndex, 0, list.Count - 1) : (-1));
				int index = ((num >= 0) ? EmpressFindAdjacentUsableRoutePointIndex(list, num, -1) : (-1));
				int index2 = ((num >= 0) ? EmpressFindAdjacentUsableRoutePointIndex(list, num, 1) : (-1));
				string text = (((Object)(object)empressCurrentPreviewLevel != (Object)null) ? ((Object)empressCurrentPreviewLevel).name : (((Object)(object)val4?.Level != (Object)null) ? ((Object)val4.Level).name : "<none>"));
				int valueOrDefault = (val4?.LevelPathPoints?.Count).GetValueOrDefault();
				int valueOrDefault2 = (val4?.LevelPathPoints?.Count(EmpressIsUsableCameraLevelPoint)).GetValueOrDefault();
				Vector3 val5 = (((Object)(object)val3 != (Object)null) ? val3.position : Vector3.zero);
				Vector3 val6 = (((Object)(object)val3 != (Object)null) ? val3.forward : Vector3.zero);
				string text2 = (((Object)(object)val3 != (Object)null) ? EmpressDescribeCameraOverlap(val5) : "no-camera");
				string text3 = (((Object)(object)val3 != (Object)null) ? EmpressDescribeRaycast(val5, val6, 200f) : "no-camera");
				Vector3 val7 = empressPreviewLookTarget - val5;
				string text4 = ((((Vector3)(ref val7)).sqrMagnitude > 0.0001f) ? EmpressDescribeRaycast(val5, ((Vector3)(ref val7)).normalized, ((Vector3)(ref val7)).magnitude) : "no-look-target");
				EmpressPlugin.EmpressLog.LogInfo((object)("EmpressCameraReport[" + label + "] level=" + text + " state=" + empressPreviewState.ToString() + " menuContext=" + menuPreviewContext + " routeCount=" + list.Count + " totalPoints=" + valueOrDefault + " usablePoints=" + valueOrDefault2 + " liveCamera=" + ((Object)(object)val3 != (Object)null) + " targetCamera=" + ((Object)(object)val != (Object)null) + " camPos=" + EmpressFormatVector3(val5) + " camForward=" + EmpressFormatVector3(val6) + " lookTarget=" + EmpressFormatVector3(empressPreviewLookTarget) + " overlap=" + text2 + " centerHit=" + text3 + " lookHit=" + text4));
				EmpressPlugin.EmpressLog.LogInfo((object)("EmpressCameraReport[" + label + "] anchor=" + EmpressDescribeLevelPoint(list, num) + " prev=" + EmpressDescribeLevelPoint(list, index) + " next=" + EmpressDescribeLevelPoint(list, index2) + " lookDir=" + EmpressFormatVector3(empressLastCameraLookDirection) + " lookDistance=" + empressLastCameraLookDistance.ToString("0.00")));
				string text5 = EmpressBuildAnchorCandidateSummary(list);
				if (!string.IsNullOrEmpty(text5))
				{
					EmpressPlugin.EmpressLog.LogInfo((object)("EmpressCameraReport[" + label + "] candidates=" + text5));
				}
			}
		}

		private static string EmpressFormatVector3(Vector3 value)
		{
			return "(" + value.x.ToString("0.00") + "," + value.y.ToString("0.00") + "," + value.z.ToString("0.00") + ")";
		}

		private static string EmpressDescribeRaycast(Vector3 origin, Vector3 direction, float maxDistance)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (((Vector3)(ref direction)).sqrMagnitude <= 0.0001f)
			{
				return "no-direction";
			}
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(origin, ((Vector3)(ref direction)).normalized, ref val, Mathf.Max(0.1f, maxDistance), -1, (QueryTriggerInteraction)1))
			{
				string text = LayerMask.LayerToName(((Component)((RaycastHit)(ref val)).collider).gameObject.layer);
				if (string.IsNullOrWhiteSpace(text))
				{
					text = ((Component)((RaycastHit)(ref val)).collider).gameObject.layer.ToString();
				}
				return ((Object)((Component)((RaycastHit)(ref val)).collider).gameObject).name + "@" + ((RaycastHit)(ref val)).distance.ToString("0.00") + " layer=" + text;
			}
			return "none<" + maxDistance.ToString("0.00") + ">";
		}

		private static string EmpressDescribeCameraOverlap(Vector3 cameraPosition)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(cameraPosition, 0.2f, -1, (QueryTriggerInteraction)1);
			if (array.Length == 0)
			{
				return "clear";
			}
			return string.Join(" | ", (from collider in array
				where (Object)(object)collider != (Object)null
				select ((Object)((Component)collider).gameObject).name).Distinct().Take(4));
		}

		private static string EmpressDescribeLevelPoint(List<LevelPoint> route, int index)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			if (index < 0 || index >= route.Count || (Object)(object)route[index] == (Object)null)
			{
				return "<none>";
			}
			LevelPoint val = route[index];
			RoomVolume val2 = EmpressLevelPointRoom(val);
			string text = (((Object)(object)val2 != (Object)null) ? ((Object)((Component)val2).gameObject).name : "<no-room>");
			return "#" + index + " " + ((Object)((Component)val).gameObject).name + " pos=" + EmpressFormatVector3(((Component)val).transform.position) + " room=" + text + " truck=" + EmpressLevelPointTruck(val) + " start=" + EmpressLevelPointInStartRoom(val) + " connect=" + EmpressLevelPointModuleConnect(val) + " straight=" + EmpressGetCameraAnchorStraightness(route, index).ToString("0.00");
		}

		private static string EmpressBuildAnchorCandidateSummary(List<LevelPoint> route)
		{
			List<LevelPoint> route2 = route;
			if (route2.Count == 0)
			{
				return string.Empty;
			}
			int preferredIndex = ((route2.Count != 1) ? Mathf.Clamp(Mathf.RoundToInt((float)(route2.Count - 1) * 0.55f), 1, route2.Count - 1) : 0);
			List<string> values = (from item in (from item in route2.Select((LevelPoint point, int index) => new
					{
						index = index,
						point = point,
						usable = EmpressIsUsableCameraAnchor(route2, index, requireBothSides: false),
						twoSided = EmpressIsUsableCameraAnchor(route2, index, requireBothSides: true),
						score = EmpressGetCameraAnchorScore(route2, index, preferredIndex)
					})
					where item.usable && (Object)(object)item.point != (Object)null
					orderby item.score descending
					select item).Take(5)
				select "#" + item.index + ":" + ((Object)((Component)item.point).gameObject).name + " score=" + item.score.ToString("0.00") + " twoSided=" + item.twoSided + " pos=" + EmpressFormatVector3(((Component)item.point).transform.position)).ToList();
			return string.Join(" || ", values);
		}

		private void EmpressForceLoadingOverlayOff()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)LoadingUI.instance == (Object)null))
			{
				LoadingUI.instance.StopLoading();
				if ((Object)(object)LoadingUI.instance.fadeImage != (Object)null)
				{
					((Graphic)LoadingUI.instance.fadeImage).color = new Color(0f, 0f, 0f, 0f);
				}
				if ((Object)(object)LoadingUI.instance.fadeBehindImage != (Object)null)
				{
					((Graphic)LoadingUI.instance.fadeBehindImage).color = new Color(0f, 0f, 0f, 0f);
					((Component)LoadingUI.instance.fadeBehindImage).gameObject.SetActive(false);
				}
				((Component)LoadingUI.instance).gameObject.SetActive(false);
			}
		}

		private void EmpressHideGameplayUi()
		{
			SemiFunc.UIHideAim();
			SemiFunc.UIHideCurrency();
			SemiFunc.UIHideEnergy();
			SemiFunc.UIHideGoal();
			SemiFunc.UIHideHaul();
			SemiFunc.UIHideHealth();
			SemiFunc.UIHideOvercharge();
			SemiFunc.UIHideInventory();
			SemiFunc.UIHideShopCost();
			SemiFunc.UIHideTumble();
			SemiFunc.UIHideWorldSpace();
			SemiFunc.UIHideValuableDiscover();
		}

		private void EmpressSanitizePreviewWorld(LevelGenerator generator)
		{
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			GameObject[] array = (GameObject[])(object)new GameObject[3] { generator.LevelParent, generator.ItemParent, generator.EnemyParent };
			foreach (GameObject val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Behaviour[] componentsInChildren = val.GetComponentsInChildren<Behaviour>(true);
				foreach (Behaviour val2 in componentsInChildren)
				{
					if ((Object)(object)val2 == (Object)null || !val2.enabled || val2 is Light)
					{
						continue;
					}
					AudioSource val3 = (AudioSource)(object)((val2 is AudioSource) ? val2 : null);
					if (val3 != null)
					{
						val3.Stop();
						val3.mute = true;
						continue;
					}
					MonoBehaviour val4 = (MonoBehaviour)(object)((val2 is MonoBehaviour) ? val2 : null);
					if (val4 != null)
					{
						val4.StopAllCoroutines();
					}
					val2.enabled = false;
				}
				ParticleSystem[] componentsInChildren2 = val.GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val5 in componentsInChildren2)
				{
					if (!((Object)(object)val5 == (Object)null))
					{
						val5.Stop(true, (ParticleSystemStopBehavior)0);
					}
				}
				Rigidbody[] componentsInChildren3 = val.GetComponentsInChildren<Rigidbody>(true);
				foreach (Rigidbody val6 in componentsInChildren3)
				{
					if (!((Object)(object)val6 == (Object)null) && !val6.isKinematic)
					{
						val6.velocity = Vector3.zero;
						val6.angularVelocity = Vector3.zero;
						val6.isKinematic = true;
					}
				}
			}
			if ((Object)(object)generator.ItemParent != (Object)null)
			{
				generator.ItemParent.SetActive(false);
			}
			if ((Object)(object)generator.EnemyParent != (Object)null)
			{
				generator.EnemyParent.SetActive(false);
			}
		}

		private List<Vector3> EmpressBuildCameraRoute(LevelGenerator generator)
		{
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			List<LevelPoint> list = generator.LevelPathPoints.Where((LevelPoint point) => (Object)(object)point != (Object)null).Distinct().ToList();
			if (list.Count == 0)
			{
				return new List<Vector3>();
			}
			LevelPoint val = generator.LevelPathTruck ?? list.First();
			Dictionary<LevelPoint, float> distances = new Dictionary<LevelPoint, float>();
			Dictionary<LevelPoint, LevelPoint> dictionary = new Dictionary<LevelPoint, LevelPoint>();
			List<LevelPoint> list2 = new List<LevelPoint>(list);
			foreach (LevelPoint item in list)
			{
				distances[item] = float.PositiveInfinity;
			}
			distances[val] = 0f;
			dictionary[val] = null;
			while (list2.Count > 0)
			{
				LevelPoint val2 = list2.OrderBy((LevelPoint point) => distances[point]).First();
				list2.Remove(val2);
				if (float.IsInfinity(distances[val2]))
				{
					break;
				}
				foreach (LevelPoint item2 in EmpressGetNeighbors(val2, list))
				{
					if (distances.ContainsKey(item2))
					{
						float num = distances[val2] + Vector3.Distance(((Component)val2).transform.position, ((Component)item2).transform.position);
						if (num + 0.001f < distances[item2])
						{
							distances[item2] = num;
							dictionary[item2] = val2;
						}
					}
				}
			}
			LevelPoint? obj = (from pair in distances
				where !float.IsInfinity(pair.Value)
				orderby pair.Value descending
				select pair.Key).FirstOrDefault() ?? val;
			List<LevelPoint> list3 = new List<LevelPoint>();
			LevelPoint val3 = obj;
			while ((Object)(object)val3 != (Object)null)
			{
				list3.Add(val3);
				if (val3 == val)
				{
					break;
				}
				val3 = (dictionary.TryGetValue(val3, out var value) ? value : null);
			}
			list3.Reverse();
			return EmpressConvertPointRouteToWorldRoute(list3, out empressPreviewLookTarget);
		}

		private List<LevelPoint> EmpressGetNeighbors(LevelPoint source, List<LevelPoint> allPoints)
		{
			LevelPoint source2 = source;
			HashSet<LevelPoint> hashSet = new HashSet<LevelPoint>();
			foreach (LevelPoint item in EmpressLevelPointConnectedPoints(source2))
			{
				if ((Object)(object)item != (Object)null && item != source2)
				{
					hashSet.Add(item);
				}
			}
			RoomVolume val = EmpressLevelPointRoom(source2);
			if (hashSet.Count == 0 && (Object)(object)val != (Object)null)
			{
				foreach (LevelPoint allPoint in allPoints)
				{
					if (allPoint != source2 && EmpressLevelPointRoom(allPoint) == val)
					{
						hashSet.Add(allPoint);
					}
				}
			}
			if (hashSet.Count == 0)
			{
				foreach (LevelPoint item2 in (from point in allPoints
					where point != source2
					orderby Vector3.Distance(((Component)point).transform.position, ((Component)source2).transform.position)
					select point).Take(2))
				{
					hashSet.Add(item2);
				}
			}
			return hashSet.ToList();
		}

		private List<Vector3> EmpressConvertPointRouteToWorldRoute(List<LevelPoint> pointRoute, out Vector3 lookTarget)
		{
			//IL_0019: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			empressLastCameraPointRoute.Clear();
			empressLastCameraAnchorIndex = -1;
			empressLastCameraLookDirection = Vector3.forward;
			empressLastCameraLookDistance = 0f;
			if (pointRoute.Count == 0)
			{
				lookTarget = Vector3.zero;
				return list;
			}
			empressLastCameraPointRoute.AddRange(pointRoute.Where((LevelPoint point) => (Object)(object)point != (Object)null));
			float num = 1.5f;
			int anchorIndex = EmpressChooseLevelPointCameraAnchorIndex(pointRoute);
			if (!EmpressTryBuildValidatedLevelPointShot(pointRoute, out anchorIndex, out var cameraPosition, out lookTarget, out var lookDirection, out var lookDistance))
			{
				cameraPosition = ((Component)pointRoute[anchorIndex]).transform.position + Vector3.up * num;
				lookDirection = EmpressGetLevelPointCameraLookDirection(pointRoute, anchorIndex);
				lookDistance = EmpressGetLevelPointCameraLookDistance(pointRoute, anchorIndex);
				lookTarget = cameraPosition + lookDirection * lookDistance;
			}
			empressLastCameraAnchorIndex = anchorIndex;
			empressLastCameraLookDirection = lookDirection;
			empressLastCameraLookDistance = lookDistance;
			list.Add(cameraPosition);
			return list;
		}

		private static bool EmpressTryBuildValidatedLevelPointShot(List<LevelPoint> pointRoute, out int anchorIndex, out Vector3 cameraPosition, out Vector3 lookTarget, out Vector3 lookDirection, out float lookDistance)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			List<LevelPoint> pointRoute2 = pointRoute;
			anchorIndex = ((pointRoute2.Count > 1) ? Mathf.Clamp(Mathf.RoundToInt((float)(pointRoute2.Count - 1) * 0.55f), 1, pointRoute2.Count - 1) : 0);
			cameraPosition = Vector3.zero;
			lookTarget = Vector3.zero;
			lookDirection = Vector3.forward;
			lookDistance = 0f;
			if (pointRoute2.Count == 0)
			{
				return false;
			}
			int preferredIndex = ((pointRoute2.Count != 1) ? Mathf.Clamp(Mathf.RoundToInt((float)(pointRoute2.Count - 1) * 0.55f), 1, pointRoute2.Count - 1) : 0);
			foreach (int item in (from item in pointRoute2.Select((LevelPoint point, int index) => new
				{
					index = index,
					point = point,
					score = EmpressGetCameraAnchorScore(pointRoute2, index, preferredIndex)
				})
				where (Object)(object)item.point != (Object)null && EmpressIsUsableCameraAnchor(pointRoute2, item.index, requireBothSides: false)
				orderby item.score descending, Mathf.Abs(item.index - preferredIndex)
				select item.index).ToList())
			{
				if (EmpressTryBuildValidatedLevelPointShotForAnchor(pointRoute2, item, out cameraPosition, out lookTarget, out lookDirection, out lookDistance))
				{
					anchorIndex = item;
					return true;
				}
			}
			return false;
		}

		private static bool EmpressTryBuildValidatedLevelPointShotForAnchor(List<LevelPoint> pointRoute, int anchorIndex, out Vector3 cameraPosition, out Vector3 lookTarget, out Vector3 lookDirection, out float lookDistance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			cameraPosition = Vector3.zero;
			lookTarget = Vector3.zero;
			lookDirection = Vector3.forward;
			lookDistance = 0f;
			if (anchorIndex < 0 || anchorIndex >= pointRoute.Count || (Object)(object)pointRoute[anchorIndex] == (Object)null)
			{
				return false;
			}
			LevelPoint val = pointRoute[anchorIndex];
			Vector3 val2 = ((Component)val).transform.position + Vector3.up * 1.5f;
			if (EmpressHasBlockingCameraOverlap(val2, val, null))
			{
				return false;
			}
			foreach (int item in EmpressEnumerateUsableNeighborIndices(pointRoute, anchorIndex).Take(8))
			{
				LevelPoint val3 = pointRoute[item];
				Vector3 val4 = ((Component)val3).transform.position + Vector3.up * 1.5f;
				Vector3 val5 = val4 - val2;
				if (!(((Vector3)(ref val5)).sqrMagnitude <= 4f))
				{
					float magnitude = ((Vector3)(ref val5)).magnitude;
					if (!EmpressHasBlockedSightLine(val2, val4, val, val3))
					{
						cameraPosition = val2;
						lookTarget = val4;
						lookDirection = ((Vector3)(ref val5)).normalized;
						lookDistance = magnitude;
						return true;
					}
				}
			}
			return false;
		}

		private static IEnumerable<int> EmpressEnumerateUsableNeighborIndices(List<LevelPoint> pointRoute, int anchorIndex)
		{
			for (int offset = 1; offset < pointRoute.Count; offset++)
			{
				int num = anchorIndex + offset;
				if (num < pointRoute.Count && EmpressIsUsableCameraLevelPoint(pointRoute[num]))
				{
					yield return num;
				}
				int num2 = anchorIndex - offset;
				if (num2 >= 0 && EmpressIsUsableCameraLevelPoint(pointRoute[num2]))
				{
					yield return num2;
				}
			}
		}

		private static int EmpressChooseLevelPointCameraAnchorIndex(List<LevelPoint> pointRoute)
		{
			if (pointRoute.Count == 1)
			{
				return 0;
			}
			int num = Mathf.Clamp(Mathf.RoundToInt((float)(pointRoute.Count - 1) * 0.55f), 1, pointRoute.Count - 1);
			int num2 = EmpressSearchForCameraAnchor(pointRoute, num, requireBothSides: true);
			if (num2 >= 0)
			{
				return num2;
			}
			num2 = EmpressSearchForCameraAnchor(pointRoute, num, requireBothSides: false);
			if (num2 >= 0)
			{
				return num2;
			}
			return num;
		}

		private static Vector3 EmpressGetLevelPointCameraLookDirection(List<LevelPoint> pointRoute, int anchorIndex)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			int num = EmpressFindAdjacentUsableRoutePointIndex(pointRoute, anchorIndex, 1);
			int num2 = EmpressFindAdjacentUsableRoutePointIndex(pointRoute, anchorIndex, -1);
			Vector3 val = Vector3.zero;
			if (num2 >= 0 && num >= 0)
			{
				val = ((Component)pointRoute[num]).transform.position - ((Component)pointRoute[num2]).transform.position;
			}
			else if (num >= 0)
			{
				val = ((Component)pointRoute[num]).transform.position - ((Component)pointRoute[anchorIndex]).transform.position;
			}
			else if (num2 >= 0)
			{
				val = ((Component)pointRoute[anchorIndex]).transform.position - ((Component)pointRoute[num2]).transform.position;
			}
			val = Vector3.ProjectOnPlane(val, Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude <= 0.001f)
			{
				val = Vector3.ProjectOnPlane(((Component)pointRoute[anchorIndex]).transform.forward, Vector3.up);
			}
			if (((Vector3)(ref val)).sqrMagnitude <= 0.001f)
			{
				val = Vector3.forward;
			}
			return ((Vector3)(ref val)).normalized;
		}

		private static float EmpressGetLevelPointCameraLookDistance(List<LevelPoint> pointRoute, int anchorIndex)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			int num2 = EmpressFindAdjacentUsableRoutePointIndex(pointRoute, anchorIndex, 1);
			if (num2 >= 0)
			{
				num = Mathf.Max(num, Vector3.Distance(((Component)pointRoute[anchorIndex]).transform.position, ((Component)pointRoute[num2]).transform.position));
			}
			int num3 = EmpressFindAdjacentUsableRoutePointIndex(pointRoute, anchorIndex, -1);
			if (num3 >= 0)
			{
				num = Mathf.Max(num, Vector3.Distance(((Component)pointRoute[anchorIndex]).transform.position, ((Component)pointRoute[num3]).transform.position));
			}
			return Mathf.Clamp(num * 2f, 4f, 8f);
		}

		private static int EmpressSearchForCameraAnchor(List<LevelPoint> pointRoute, int preferredIndex, bool requireBothSides)
		{
			int result = -1;
			float num = float.NegativeInfinity;
			for (int i = 0; i < pointRoute.Count; i++)
			{
				if (EmpressIsUsableCameraAnchor(pointRoute, i, requireBothSides))
				{
					float num2 = EmpressGetCameraAnchorScore(pointRoute, i, preferredIndex);
					if (num2 > num)
					{
						num = num2;
						result = i;
					}
				}
			}
			return result;
		}

		private static float EmpressGetCameraAnchorScore(List<LevelPoint> pointRoute, int anchorIndex, int preferredIndex)
		{
			float num = EmpressGetCameraAnchorStraightness(pointRoute, anchorIndex) - (float)Mathf.Abs(anchorIndex - preferredIndex) * 0.1f;
			if (anchorIndex < 0 || anchorIndex >= pointRoute.Count || (Object)(object)pointRoute[anchorIndex] == (Object)null)
			{
				return num;
			}
			string name = ((Object)((Component)pointRoute[anchorIndex]).gameObject).name;
			if (name.StartsWith("Level Point", StringComparison.OrdinalIgnoreCase))
			{
				num += 0.2f;
			}
			if (name.IndexOf("Level Path", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				num -= 0.25f;
			}
			if (name.IndexOf("Left", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Right", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Bot", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				num -= 0.1f;
			}
			return num;
		}

		private static bool EmpressIsUsableCameraAnchor(List<LevelPoint> pointRoute, int index, bool requireBothSides)
		{
			if (index < 0 || index >= pointRoute.Count || !EmpressIsUsableCameraLevelPoint(pointRoute[index]))
			{
				return false;
			}
			int num = EmpressFindAdjacentUsableRoutePointIndex(pointRoute, index, -1);
			int num2 = EmpressFindAdjacentUsableRoutePointIndex(pointRoute, index, 1);
			if (!requireBothSides)
			{
				if (num < 0)
				{
					return num2 >= 0;
				}
				return true;
			}
			if (num >= 0)
			{
				return num2 >= 0;
			}
			return false;
		}

		private static float EmpressGetCameraAnchorStraightness(List<LevelPoint> pointRoute, int anchorIndex)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			int num = EmpressFindAdjacentUsableRoutePointIndex(pointRoute, anchorIndex, -1);
			int num2 = EmpressFindAdjacentUsableRoutePointIndex(pointRoute, anchorIndex, 1);
			if (num < 0 || num2 < 0)
			{
				return 0f;
			}
			Vector3 val = Vector3.ProjectOnPlane(((Component)pointRoute[anchorIndex]).transform.position - ((Component)pointRoute[num]).transform.position, Vector3.up);
			Vector3 val2 = Vector3.ProjectOnPlane(((Component)pointRoute[num2]).transform.position - ((Component)pointRoute[anchorIndex]).transform.position, Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude <= 0.001f || ((Vector3)(ref val2)).sqrMagnitude <= 0.001f)
			{
				return 0f;
			}
			return Vector3.Dot(((Vector3)(ref val)).normalized, ((Vector3)(ref val2)).normalized);
		}

		private static int EmpressFindAdjacentUsableRoutePointIndex(List<LevelPoint> pointRoute, int originIndex, int direction)
		{
			for (int i = originIndex + direction; i >= 0 && i < pointRoute.Count; i += direction)
			{
				if (EmpressIsUsableCameraLevelPoint(pointRoute[i]))
				{
					return i;
				}
			}
			return -1;
		}

		private static bool EmpressIsUsableCameraLevelPoint(LevelPoint? point)
		{
			if ((Object)(object)point != (Object)null && !EmpressLevelPointTruck(point) && !EmpressLevelPointModuleConnect(point) && !EmpressLevelPointInStartRoom(point) && (Object)(object)EmpressLevelPointRoom(point) != (Object)null && !EmpressRoomVolumeTruck(EmpressLevelPointRoom(point)))
			{
				return !EmpressRoomVolumeExtraction(EmpressLevelPointRoom(point));
			}
			return false;
		}

		private static bool EmpressHasBlockingCameraOverlap(Vector3 cameraPosition, LevelPoint anchorPoint, LevelPoint? lookPoint)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(cameraPosition, 0.2f, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				if (EmpressShouldBlockCameraCollider(array[i], anchorPoint, lookPoint))
				{
					return true;
				}
			}
			return false;
		}

		private static bool EmpressHasBlockedSightLine(Vector3 cameraPosition, Vector3 lookTarget, LevelPoint anchorPoint, LevelPoint lookPoint)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = lookTarget - cameraPosition;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude <= 0.001f)
			{
				return true;
			}
			foreach (RaycastHit item in from hit in Physics.RaycastAll(cameraPosition, ((Vector3)(ref val)).normalized, magnitude, -1, (QueryTriggerInteraction)1)
				orderby ((RaycastHit)(ref hit)).distance
				select hit)
			{
				RaycastHit current = item;
				if (EmpressShouldBlockCameraCollider(((RaycastHit)(ref current)).collider, anchorPoint, lookPoint))
				{
					return true;
				}
			}
			return false;
		}

		private static bool EmpressShouldBlockCameraCollider(Collider? collider, LevelPoint anchorPoint, LevelPoint? lookPoint)
		{
			if ((Object)(object)collider == (Object)null || collider.isTrigger)
			{
				return false;
			}
			LevelPoint val = ((Component)collider).GetComponent<LevelPoint>() ?? ((Component)collider).GetComponentInParent<LevelPoint>();
			if (val == anchorPoint || val == lookPoint)
			{
				return false;
			}
			if ((Object)(object)((Component)collider).GetComponent<RoomVolume>() != (Object)null)
			{
				return false;
			}
			return true;
		}

		private void EmpressApplyPreviewCamera(bool snapRotation)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			CameraNoPlayerTarget val = EmpressResolveMenuCameraTarget();
			Camera val2 = EmpressResolveLiveMenuCamera();
			if (((Object)(object)val == (Object)null && (Object)(object)val2 == (Object)null && (Object)(object)CameraPosition.instance == (Object)null && (Object)(object)CameraAim.Instance == (Object)null) || empressPreviewRoute.Count == 0)
			{
				return;
			}
			Vector3 val3 = EmpressSampleRoutePosition(empressTravelDistance);
			Vector3 val4 = empressPreviewLookTarget - val3;
			if (((Vector3)(ref val4)).sqrMagnitude <= 0.0001f && empressPreviewRoute.Count > 1)
			{
				val4 = empressPreviewRoute[Mathf.Min(1, empressPreviewRoute.Count - 1)] - val3;
			}
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).transform.position = val3;
			}
			if ((Object)(object)CameraPosition.instance != (Object)null)
			{
				((Component)CameraPosition.instance).transform.position = val3;
			}
			Quaternion? val5 = null;
			if (((Vector3)(ref val4)).sqrMagnitude > 0.0001f)
			{
				Quaternion val6 = Quaternion.LookRotation(((Vector3)(ref val4)).normalized, Vector3.up);
				val5 = val6;
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).transform.rotation = (snapRotation ? val6 : Quaternion.Slerp(((Component)val).transform.rotation, val6, 5f * Time.unscaledDeltaTime));
				}
				if ((Object)(object)CameraAim.Instance != (Object)null)
				{
					((Component)CameraAim.Instance).transform.rotation = val6;
				}
				if ((Object)(object)val2 != (Object)null && (Object)(object)CameraAim.Instance == (Object)null)
				{
					((Component)val2).transform.rotation = val6;
				}
			}
			Camera val7 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Camera>() : val2);
			if ((Object)(object)val7 != (Object)null)
			{
				val7.fieldOfView = 66f;
			}
			if ((Object)(object)val2 != (Object)null && (Object)(object)CameraPosition.instance == (Object)null)
			{
				((Component)val2).transform.position = val3;
				if (val5.HasValue)
				{
					((Component)val2).transform.rotation = val5.Value;
				}
			}
			if (!((Object)(object)CameraZoom.Instance != (Object)null))
			{
				return;
			}
			foreach (Camera item in CameraZoom.Instance.cams.Where((Camera camera) => (Object)(object)camera != (Object)null))
			{
				item.fieldOfView = 66f;
			}
		}

		private Vector3 EmpressSampleRoutePosition(float distance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (empressPreviewRoute.Count == 0)
			{
				return Vector3.zero;
			}
			if (empressPreviewRoute.Count == 1)
			{
				return empressPreviewRoute[0];
			}
			float num = Mathf.Clamp(distance, 0f, empressPreviewRouteLength);
			for (int i = 1; i < empressPreviewRoute.Count; i++)
			{
				Vector3 val = empressPreviewRoute[i - 1];
				Vector3 val2 = empressPreviewRoute[i];
				float num2 = Vector3.Distance(val, val2);
				if (num <= num2 || i == empressPreviewRoute.Count - 1)
				{
					float num3 = ((num2 <= 0.0001f) ? 1f : (num / num2));
					return Vector3.LerpUnclamped(val, val2, num3);
				}
				num -= num2;
			}
			return empressPreviewRoute[empressPreviewRoute.Count - 1];
		}

		private float EmpressMeasureRoute(List<Vector3> route)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			for (int i = 1; i < route.Count; i++)
			{
				num += Vector3.Distance(route[i - 1], route[i]);
			}
			return num;
		}

		private float EmpressTravelSpeed(float deltaTime)
		{
			return empressPreviewRouteLength * deltaTime;
		}

		private float EmpressFadeSpeed(float deltaTime)
		{
			float num = 1.35f;
			return deltaTime / num;
		}

		private Level? EmpressPickPreviewLevel()
		{
			if ((Object)(object)RunManager.instance == (Object)null)
			{
				return null;
			}
			HashSet<Level> excludedLevels = new HashSet<Level>();
			if ((Object)(object)RunManager.instance.levelArena != (Object)null)
			{
				excludedLevels.Add(RunManager.instance.levelArena);
			}
			if ((Object)(object)RunManager.instance.levelLobby != (Object)null)
			{
				excludedLevels.Add(RunManager.instance.levelLobby);
			}
			if ((Object)(object)RunManager.instance.levelLobbyMenu != (Object)null)
			{
				excludedLevels.Add(RunManager.instance.levelLobbyMenu);
			}
			if ((Object)(object)RunManager.instance.levelMainMenu != (Object)null)
			{
				excludedLevels.Add(RunManager.instance.levelMainMenu);
			}
			if ((Object)(object)RunManager.instance.levelRecording != (Object)null)
			{
				excludedLevels.Add(RunManager.instance.levelRecording);
			}
			if ((Object)(object)RunManager.instance.levelShop != (Object)null)
			{
				excludedLevels.Add(RunManager.instance.levelShop);
			}
			if ((Object)(object)RunManager.instance.levelSplashScreen != (Object)null)
			{
				excludedLevels.Add(RunManager.instance.levelSplashScreen);
			}
			if ((Object)(object)RunManager.instance.levelTutorial != (Object)null)
			{
				excludedLevels.Add(RunManager.instance.levelTutorial);
			}
			List<Level> list = (from level in RunManager.instance.levels
				where (Object)(object)level != (Object)null
				where !excludedLevels.Contains(level)
				where level.StartRooms != null && level.StartRooms.Count > 0
				select level).Where(EmpressHasPreviewModules).Distinct().ToList();
			if (list.Count == 0)
			{
				return null;
			}
			if (list.Count > 1 && (Object)(object)empressLastPreviewLevel != (Object)null)
			{
				list.RemoveAll((Level level) => level == empressLastPreviewLevel);
			}
			if (list.Count == 0)
			{
				return empressLastPreviewLevel;
			}
			int index = Random.Range(0, list.Count);
			return list[index];
		}

		private static bool EmpressHasPreviewModules(Level level)
		{
			if ((level.ModulesNormal1 == null || level.ModulesNormal1.Count <= 0) && (level.ModulesNormal2 == null || level.ModulesNormal2.Count <= 0) && (level.ModulesNormal3 == null || level.ModulesNormal3.Count <= 0) && (level.ModulesPassage1 == null || level.ModulesPassage1.Count <= 0) && (level.ModulesPassage2 == null || level.ModulesPassage2.Count <= 0))
			{
				if (level.ModulesPassage3 != null)
				{
					return level.ModulesPassage3.Count > 0;
				}
				return false;
			}
			return true;
		}

		private void EmpressDisableVanillaMenuCameraAnimations()
		{
			if ((Object)(object)CameraNoPlayerTarget.instance != (Object)null)
			{
				((Behaviour)CameraNoPlayerTarget.instance).enabled = false;
			}
			if ((Object)(object)CameraNoPlayerTarget.instance != (Object)null)
			{
				((Behaviour)CameraNoPlayerTarget.instance).enabled = false;
			}
		}

		private void EmpressHideMenuBodies()
		{
			PlayerAvatarMenu[] array = Object.FindObjectsOfType<PlayerAvatarMenu>(true);
			foreach (PlayerAvatarMenu val in array)
			{
				Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					componentsInChildren[j].enabled = false;
				}
				if ((Object)(object)val.cameraAndStuff != (Object)null)
				{
					Camera[] componentsInChildren2 = ((Component)val.cameraAndStuff).GetComponentsInChildren<Camera>(true);
					for (int j = 0; j < componentsInChildren2.Length; j++)
					{
						((Behaviour)componentsInChildren2[j]).enabled = false;
					}
				}
			}
			if ((Object)(object)GameDirector.instance == (Object)null)
			{
				return;
			}
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (!((Object)(object)player == (Object)null))
				{
					Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(true);
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						componentsInChildren[i].enabled = false;
					}
				}
			}
		}

		private void EmpressRestoreVanillaMenuPresentation()
		{
			if ((Object)(object)CameraNoPlayerTarget.instance != (Object)null)
			{
				((Behaviour)CameraNoPlayerTarget.instance).enabled = true;
			}
			if ((Object)(object)CameraNoPlayerTarget.instance != (Object)null)
			{
				((Behaviour)CameraNoPlayerTarget.instance).enabled = true;
			}
			PlayerAvatarMenu[] array = Object.FindObjectsOfType<PlayerAvatarMenu>(true);
			foreach (PlayerAvatarMenu val in array)
			{
				Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						val2.enabled = true;
					}
				}
				if (!((Object)(object)val.cameraAndStuff != (Object)null))
				{
					continue;
				}
				Camera[] componentsInChildren2 = ((Component)val.cameraAndStuff).GetComponentsInChildren<Camera>(true);
				foreach (Camera val3 in componentsInChildren2)
				{
					if ((Object)(object)val3 != (Object)null)
					{
						((Behaviour)val3).enabled = true;
					}
				}
			}
			if ((Object)(object)GameDirector.instance == (Object)null)
			{
				return;
			}
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if ((Object)(object)player == (Object)null)
				{
					continue;
				}
				Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val4 in componentsInChildren)
				{
					if ((Object)(object)val4 != (Object)null)
					{
						val4.enabled = true;
					}
				}
			}
		}

		private void EmpressEnsureFadeOverlay()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invali