Decompiled source of Empress Mausoleum Compat Patch v3.5.0

MausoleumCompatPatch.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using REPOLib;
using REPOLib.Modules;
using Unity.AI.Navigation;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
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.15.0")]
[assembly: AssemblyInformationalVersion("1.0.15")]
[assembly: AssemblyProduct("MausoleumCompatPatch")]
[assembly: AssemblyTitle("MausoleumCompatPatch")]
[assembly: AssemblyVersion("1.0.15.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 MausoleumCompatPatch
{
	[BepInPlugin("empress.repo.mausoleumcompatpatch", "Empress Mausoleum Compat Patch", "1.0.15")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class MausoleumCompatPatchPlugin : BaseUnityPlugin
	{
		private sealed class MausoleumLoadingGraphic
		{
			public AssetBundle Bundle { get; }

			public Sprite Sprite { get; }

			public string ResourcePath { get; }

			public bool CanUsePrefabRef { get; }

			public MausoleumLoadingGraphic(AssetBundle bundle, Sprite sprite, string resourcePath, bool canUsePrefabRef)
			{
				Bundle = bundle;
				Sprite = sprite;
				ResourcePath = resourcePath;
				CanUsePrefabRef = canUsePrefabRef;
			}
		}

		private sealed class MausoleumPrefabBuckets
		{
			public List<GameObject> StartRooms { get; set; } = new List<GameObject>();


			public List<GameObject> Normal1 { get; set; } = new List<GameObject>();


			public List<GameObject> Passage1 { get; set; } = new List<GameObject>();


			public List<GameObject> DeadEnd1 { get; set; } = new List<GameObject>();


			public List<GameObject> Extraction1 { get; set; } = new List<GameObject>();


			public List<GameObject> Normal2 { get; set; } = new List<GameObject>();


			public List<GameObject> Passage2 { get; set; } = new List<GameObject>();


			public List<GameObject> DeadEnd2 { get; set; } = new List<GameObject>();


			public List<GameObject> Extraction2 { get; set; } = new List<GameObject>();


			public List<GameObject> Normal3 { get; set; } = new List<GameObject>();


			public List<GameObject> Passage3 { get; set; } = new List<GameObject>();


			public List<GameObject> DeadEnd3 { get; set; } = new List<GameObject>();


			public List<GameObject> Extraction3 { get; set; } = new List<GameObject>();


			public int TotalModuleCount => Normal1.Count + Passage1.Count + DeadEnd1.Count + Extraction1.Count + Normal2.Count + Passage2.Count + DeadEnd2.Count + Extraction2.Count + Normal3.Count + Passage3.Count + DeadEnd3.Count + Extraction3.Count;
		}

		internal const string PluginGuid = "empress.repo.mausoleumcompatpatch";

		internal const string PluginName = "Empress Mausoleum Compat Patch";

		internal const string PluginVersion = "1.0.15";

		private const string MausoleumBundleFileName = "melanierepointeriors.repobundle";

		private const string MausoleumLevelName = "Mel Mausoleum";

		private const string MausoleumLevelResourcePath = "Mausoleum";

		private const float MausoleumLevelPointCheckRadius = 0.5f;

		private const float MausoleumLevelPointRepairRadius = 2f;

		private const float MausoleumLevelPointConnectDistance = 15f;

		private const float MausoleumLevelPointConnectForwardDot = -0.8f;

		private const float MausoleumLevelPointConnectApproachDot = 0.8f;

		private const float MausoleumLevelPointValidationDelay = 0.5f;

		private const int MausoleumVehicleVolumeCount = 4;

		private const float MausoleumVehicleVolumeSideOffset = 2f;

		private const float MausoleumVehicleVolumeForwardOffset = 2.5f;

		private const float MausoleumVehicleVolumeForwardSpacing = 2f;

		private const float MausoleumChargingStationForwardOffset = 6.5f;

		private static readonly string[] MausoleumLoadingGraphicFieldNames = new string[3] { "LoadingGraphic01", "LoadingGraphic02", "LoadingGraphic03" };

		private static readonly string[] MausoleumPreferredLoadingGraphicNames = new string[3] { "MausoleumLoad0", "MausoleumLoad1", "MausoleumLoad2" };

		private static readonly List<Sprite> MausoleumLoadingSprites = new List<Sprite>();

		private static readonly string[] MausoleumStartRoomNames = new string[1] { "MausoleumStart0" };

		private static readonly string[] MausoleumNormal1Names = new string[3] { "MausoleumNorm0", "MausoleumNorm1", "MausoleumNorm2" };

		private static readonly string[] MausoleumPassage1Names = new string[2] { "MausoleumPass0", "MausoleumPass1" };

		private static readonly string[] MausoleumDeadEnd1Names = new string[2] { "MausoleumEnd0", "MausoleumEnd1" };

		private static readonly string[] MausoleumExtraction1Names = new string[1] { "MausoleumExt0" };

		private static readonly string[] MausoleumNormal2Names = new string[2] { "MausoleumNorm3", "MausoleumNorm5" };

		private static readonly string[] MausoleumPassage2Names = new string[1] { "MausoleumPass2" };

		private static readonly string[] MausoleumDeadEnd2Names = Array.Empty<string>();

		private static readonly string[] MausoleumExtraction2Names = Array.Empty<string>();

		private static readonly string[] MausoleumNormal3Names = new string[2] { "MausoleumNorm4", "MausoleumNorm6" };

		private static readonly string[] MausoleumPassage3Names = Array.Empty<string>();

		private static readonly string[] MausoleumDeadEnd3Names = Array.Empty<string>();

		private static readonly string[] MausoleumExtraction3Names = Array.Empty<string>();

		private readonly Harmony _mausoleumHarmony = new Harmony("empress.repo.mausoleumcompatpatch");

		private AssetBundle? _mausoleumBundle;

		private bool _mausoleumRepairApplied;

		private bool _mausoleumRepairQueued;

		private bool _mausoleumLoggedMissingBundle;

		private bool _mausoleumLoggedMissingPrefabs;

		private bool _mausoleumLoggedDoorMapFallback;

		private bool _mausoleumLoggedRepairAttempt;

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

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			BundleLoader.OnAllBundlesLoaded += MausoleumHandleBundlesLoaded;
			SceneManager.activeSceneChanged += MausoleumOnActiveSceneChanged;
			_mausoleumHarmony.PatchAll();
			if ((Object)(object)RunManager.instance != (Object)null)
			{
				((MonoBehaviour)this).StartCoroutine(MausoleumRepairWhenReady());
			}
		}

		private void MausoleumOnActiveSceneChanged(Scene current, Scene next)
		{
			_mausoleumRepairApplied = false;
			_mausoleumRepairQueued = false;
			_mausoleumLoggedRepairAttempt = false;
			if ((Object)(object)RunManager.instance != (Object)null)
			{
				((MonoBehaviour)this).StartCoroutine(MausoleumRepairWhenReady());
			}
		}

		private void MausoleumHandleBundlesLoaded()
		{
			if (_mausoleumRepairQueued || _mausoleumRepairApplied)
			{
				return;
			}
			_mausoleumRepairQueued = true;
			try
			{
				MausoleumTryRepairLevel();
			}
			finally
			{
				_mausoleumRepairQueued = false;
			}
		}

		private IEnumerator MausoleumRepairWhenReady()
		{
			yield return null;
			for (int attempt = 0; attempt < 120; attempt++)
			{
				if (_mausoleumRepairApplied)
				{
					break;
				}
				if (MausoleumTryRepairLevel())
				{
					break;
				}
				yield return null;
			}
			_mausoleumRepairQueued = false;
		}

		internal bool MausoleumTryRepairCurrentLevel()
		{
			List<Level> list = new List<Level>();
			if ((Object)(object)LevelGenerator.Instance != (Object)null && (Object)(object)LevelGenerator.Instance.Level != (Object)null)
			{
				list.Add(LevelGenerator.Instance.Level);
			}
			if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent != (Object)null)
			{
				list.Add(RunManager.instance.levelCurrent);
			}
			return MausoleumTryRepairLevel((IEnumerable<Level>?)list);
		}

		internal bool MausoleumTryRepairLevel(Level? level)
		{
			if (!MausoleumIsMausoleumLevel(level))
			{
				return false;
			}
			if (MausoleumHasValidLevelData(level))
			{
				AssetBundle val = MausoleumGetBundle();
				if ((Object)(object)val != (Object)null)
				{
					MausoleumEnsureLevelLoadingGraphics(level, val);
				}
				_mausoleumRepairApplied = true;
				return true;
			}
			return MausoleumTryRepairSpecificLevel(level);
		}

		private bool MausoleumTryRepairLevel(IEnumerable<Level>? candidates = null)
		{
			Level val = MausoleumFindLevel(candidates) ?? MausoleumFindLevel(Levels.AllLevels);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (MausoleumHasValidLevelData(val))
			{
				AssetBundle val2 = MausoleumGetBundle();
				if ((Object)(object)val2 != (Object)null)
				{
					MausoleumEnsureLevelLoadingGraphics(val, val2);
				}
				_mausoleumRepairApplied = true;
				return true;
			}
			AssetBundle val3 = MausoleumGetBundle();
			if ((Object)(object)val3 == (Object)null)
			{
				if (!_mausoleumLoggedMissingBundle)
				{
					_mausoleumLoggedMissingBundle = true;
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Empress Mausoleum Compat Patch could not locate the Mausoleum bundle.");
				}
				return false;
			}
			_mausoleumLoggedMissingBundle = false;
			MausoleumPrefabBuckets mausoleumPrefabBuckets = MausoleumCollectPrefabs(val3);
			if (mausoleumPrefabBuckets.StartRooms.Count == 0 || mausoleumPrefabBuckets.TotalModuleCount == 0)
			{
				if (!_mausoleumLoggedMissingPrefabs)
				{
					_mausoleumLoggedMissingPrefabs = true;
					((BaseUnityPlugin)this).Logger.LogError((object)"Empress Mausoleum Compat Patch could not rebuild the Mausoleum prefab lists from the original bundle.");
				}
				return false;
			}
			_mausoleumLoggedMissingPrefabs = false;
			MausoleumApplyHideFlags((Object)(object)val3);
			MausoleumApplyHideFlags((Object)(object)val);
			MausoleumEnsureLevelFallbackData(val);
			MausoleumEnsureLevelLoadingGraphics(val, val3);
			MausoleumRegisterLevelObjects(val);
			MausoleumApplyPrefabBuckets(val, mausoleumPrefabBuckets);
			_mausoleumRepairApplied = (val.StartRooms?.Count ?? 0) > 0 && MausoleumCountModules(val) > 0;
			if (_mausoleumRepairApplied)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch repaired {((Object)val).name} with {val.StartRooms?.Count ?? 0} start rooms and {MausoleumCountModules(val)} modules.");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Empress Mausoleum Compat Patch found Mausoleum assets but only rebuilt {val.StartRooms?.Count ?? 0} start rooms and {MausoleumCountModules(val)} modules.");
			}
			return _mausoleumRepairApplied;
		}

		private bool MausoleumTryRepairSpecificLevel(Level level)
		{
			if (!MausoleumIsMausoleumLevel(level))
			{
				return false;
			}
			if (MausoleumHasValidLevelData(level))
			{
				AssetBundle val = MausoleumGetBundle();
				if ((Object)(object)val != (Object)null)
				{
					MausoleumEnsureLevelLoadingGraphics(level, val);
				}
				_mausoleumRepairApplied = true;
				return true;
			}
			if (!_mausoleumLoggedRepairAttempt)
			{
				_mausoleumLoggedRepairAttempt = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Empress Mausoleum Compat Patch is rebuilding " + ((Object)level).name + " from the original bundle."));
			}
			AssetBundle val2 = MausoleumGetBundle();
			if ((Object)(object)val2 == (Object)null)
			{
				if (!_mausoleumLoggedMissingBundle)
				{
					_mausoleumLoggedMissingBundle = true;
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Empress Mausoleum Compat Patch could not locate the Mausoleum bundle.");
				}
				return false;
			}
			_mausoleumLoggedMissingBundle = false;
			MausoleumPrefabBuckets mausoleumPrefabBuckets = MausoleumCollectPrefabs(val2);
			if (mausoleumPrefabBuckets.StartRooms.Count == 0 || mausoleumPrefabBuckets.TotalModuleCount == 0)
			{
				if (!_mausoleumLoggedMissingPrefabs)
				{
					_mausoleumLoggedMissingPrefabs = true;
					((BaseUnityPlugin)this).Logger.LogError((object)"Empress Mausoleum Compat Patch could not rebuild the Mausoleum prefab lists from the original bundle.");
				}
				return false;
			}
			_mausoleumLoggedMissingPrefabs = false;
			MausoleumApplyHideFlags((Object)(object)val2);
			MausoleumApplyHideFlags((Object)(object)level);
			MausoleumEnsureLevelFallbackData(level);
			MausoleumEnsureLevelLoadingGraphics(level, val2);
			MausoleumRegisterLevelObjects(level);
			MausoleumApplyPrefabBuckets(level, mausoleumPrefabBuckets);
			_mausoleumRepairApplied = (level.StartRooms?.Count ?? 0) > 0 && MausoleumCountModules(level) > 0;
			if (_mausoleumRepairApplied)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch repaired {((Object)level).name} with {level.StartRooms?.Count ?? 0} start rooms and {MausoleumCountModules(level)} modules.");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Empress Mausoleum Compat Patch found Mausoleum assets but only rebuilt {level.StartRooms?.Count ?? 0} start rooms and {MausoleumCountModules(level)} modules.");
			}
			return _mausoleumRepairApplied;
		}

		private static Level? MausoleumFindLevel(IEnumerable<Level>? candidates)
		{
			if (candidates == null)
			{
				return null;
			}
			foreach (Level candidate in candidates)
			{
				if (MausoleumIsMausoleumLevel(candidate))
				{
					return candidate;
				}
			}
			return null;
		}

		private AssetBundle? MausoleumGetBundle()
		{
			if ((Object)(object)_mausoleumBundle != (Object)null)
			{
				return _mausoleumBundle;
			}
			foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles())
			{
				try
				{
					if (MausoleumBundleMatches(allLoadedAssetBundle))
					{
						_mausoleumBundle = allLoadedAssetBundle;
						return _mausoleumBundle;
					}
				}
				catch
				{
				}
			}
			string text = Directory.GetFiles(Paths.PluginPath, "melanierepointeriors.repobundle", SearchOption.AllDirectories).FirstOrDefault();
			if (string.IsNullOrWhiteSpace(text))
			{
				return null;
			}
			_mausoleumBundle = AssetBundle.LoadFromFile(text);
			return _mausoleumBundle;
		}

		private static MausoleumPrefabBuckets MausoleumCollectPrefabs(AssetBundle bundle)
		{
			Dictionary<string, GameObject> prefabsByName = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);
			StartRoom[] array = bundle.LoadAllAssets<StartRoom>();
			foreach (StartRoom val in array)
			{
				MausoleumAddAssetByName(prefabsByName, ((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null);
			}
			Module[] array2 = bundle.LoadAllAssets<Module>();
			foreach (Module val2 in array2)
			{
				MausoleumAddAssetByName(prefabsByName, ((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null);
			}
			GameObject[] array3 = bundle.LoadAllAssets<GameObject>();
			foreach (GameObject prefab in array3)
			{
				MausoleumAddAssetByName(prefabsByName, prefab);
			}
			MausoleumPopulatePrefabLookupFromResources(prefabsByName);
			return new MausoleumPrefabBuckets
			{
				StartRooms = MausoleumResolvePrefabs(prefabsByName, MausoleumStartRoomNames),
				Normal1 = MausoleumResolvePrefabs(prefabsByName, MausoleumNormal1Names),
				Passage1 = MausoleumResolvePrefabs(prefabsByName, MausoleumPassage1Names),
				DeadEnd1 = MausoleumResolvePrefabs(prefabsByName, MausoleumDeadEnd1Names),
				Extraction1 = MausoleumResolvePrefabs(prefabsByName, MausoleumExtraction1Names),
				Normal2 = MausoleumResolvePrefabs(prefabsByName, MausoleumNormal2Names),
				Passage2 = MausoleumResolvePrefabs(prefabsByName, MausoleumPassage2Names),
				DeadEnd2 = MausoleumResolvePrefabs(prefabsByName, MausoleumDeadEnd2Names),
				Extraction2 = MausoleumResolvePrefabs(prefabsByName, MausoleumExtraction2Names),
				Normal3 = MausoleumResolvePrefabs(prefabsByName, MausoleumNormal3Names),
				Passage3 = MausoleumResolvePrefabs(prefabsByName, MausoleumPassage3Names),
				DeadEnd3 = MausoleumResolvePrefabs(prefabsByName, MausoleumDeadEnd3Names),
				Extraction3 = MausoleumResolvePrefabs(prefabsByName, MausoleumExtraction3Names)
			};
		}

		private static void MausoleumApplyPrefabBuckets(Level level, MausoleumPrefabBuckets prefabs)
		{
			level.StartRooms = MausoleumRegisterPrefabs(level, "StartRoom", prefabs.StartRooms);
			level.ModulesNormal1 = MausoleumRegisterPrefabs(level, "Normal", prefabs.Normal1);
			level.ModulesPassage1 = MausoleumRegisterPrefabs(level, "Passage", prefabs.Passage1);
			level.ModulesDeadEnd1 = MausoleumRegisterPrefabs(level, "DeadEnd", prefabs.DeadEnd1);
			level.ModulesExtraction1 = MausoleumRegisterPrefabs(level, "Extraction", prefabs.Extraction1);
			level.ModulesNormal2 = MausoleumRegisterPrefabs(level, "Normal", prefabs.Normal2);
			level.ModulesPassage2 = MausoleumRegisterPrefabs(level, "Passage", prefabs.Passage2);
			level.ModulesDeadEnd2 = MausoleumRegisterPrefabs(level, "DeadEnd", prefabs.DeadEnd2);
			level.ModulesExtraction2 = MausoleumRegisterPrefabs(level, "Extraction", prefabs.Extraction2);
			level.ModulesNormal3 = MausoleumRegisterPrefabs(level, "Normal", prefabs.Normal3);
			level.ModulesPassage3 = MausoleumRegisterPrefabs(level, "Passage", prefabs.Passage3);
			level.ModulesDeadEnd3 = MausoleumRegisterPrefabs(level, "DeadEnd", prefabs.DeadEnd3);
			level.ModulesExtraction3 = MausoleumRegisterPrefabs(level, "Extraction", prefabs.Extraction3);
		}

		private static void MausoleumPopulatePrefabLookupFromResources(IDictionary<string, GameObject> prefabsByName)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//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)
			StartRoom[] array = Resources.FindObjectsOfTypeAll<StartRoom>();
			Scene scene;
			foreach (StartRoom val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					scene = ((Component)val).gameObject.scene;
					if (!((Scene)(ref scene)).IsValid())
					{
						MausoleumAddAssetByName(prefabsByName, ((Component)val).gameObject);
					}
				}
			}
			Module[] array2 = Resources.FindObjectsOfTypeAll<Module>();
			foreach (Module val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					scene = ((Component)val2).gameObject.scene;
					if (!((Scene)(ref scene)).IsValid())
					{
						MausoleumAddAssetByName(prefabsByName, ((Component)val2).gameObject);
					}
				}
			}
			GameObject[] array3 = Resources.FindObjectsOfTypeAll<GameObject>();
			foreach (GameObject val3 in array3)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					scene = val3.scene;
					if (!((Scene)(ref scene)).IsValid())
					{
						MausoleumAddAssetByName(prefabsByName, val3);
					}
				}
			}
		}

		private static void MausoleumAddAssetByName(IDictionary<string, GameObject> prefabsByName, GameObject? prefab)
		{
			if (!((Object)(object)prefab == (Object)null) && !string.IsNullOrWhiteSpace(((Object)prefab).name) && !prefabsByName.ContainsKey(((Object)prefab).name))
			{
				prefabsByName[((Object)prefab).name] = prefab;
			}
		}

		private static List<GameObject> MausoleumResolvePrefabs(IReadOnlyDictionary<string, GameObject> prefabsByName, IEnumerable<string> names)
		{
			List<GameObject> list = new List<GameObject>();
			foreach (string name in names)
			{
				if (prefabsByName.TryGetValue(name, out GameObject value))
				{
					list.Add(value);
				}
			}
			return list;
		}

		private static void MausoleumRegisterLevelObjects(Level level)
		{
			if (level.ConnectObject != null)
			{
				GameObject val = MausoleumResolvePrefab(level.ConnectObject);
				if ((Object)(object)val != (Object)null)
				{
					MausoleumRegisterNetworkPrefab("Level/" + MausoleumGetLevelPath(level) + "/Other/" + MausoleumGetPrefabName(level.ConnectObject, val), val);
				}
			}
			if (level.BlockObject != null)
			{
				GameObject val2 = MausoleumResolvePrefab(level.BlockObject);
				if ((Object)(object)val2 != (Object)null)
				{
					MausoleumRegisterNetworkPrefab("Level/" + MausoleumGetLevelPath(level) + "/Other/" + MausoleumGetPrefabName(level.BlockObject, val2), val2);
				}
			}
		}

		private static string MausoleumGetLevelPath(Level level)
		{
			if (!string.IsNullOrWhiteSpace(((Object)level).name))
			{
				return ((Object)level).name;
			}
			return "Mausoleum";
		}

		private static string MausoleumGetPrefabName(PrefabRef prefabRef, GameObject prefab)
		{
			if (!string.IsNullOrWhiteSpace(prefabRef.PrefabName))
			{
				return prefabRef.PrefabName;
			}
			return ((Object)prefab).name;
		}

		private static GameObject? MausoleumResolvePrefab(PrefabRef? prefabRef)
		{
			if (prefabRef == null)
			{
				return null;
			}
			if (prefabRef.IsValid())
			{
				return prefabRef.Prefab;
			}
			AssetBundle bundle = prefabRef.Bundle;
			if ((Object)(object)bundle == (Object)null || string.IsNullOrWhiteSpace(prefabRef.PrefabName))
			{
				return null;
			}
			GameObject[] array = bundle.LoadAllAssets<GameObject>();
			foreach (GameObject val in array)
			{
				if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, prefabRef.PrefabName, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
			}
			return null;
		}

		private static bool MausoleumBundleMatches(AssetBundle bundle)
		{
			if ((Object)(object)bundle == (Object)null)
			{
				return false;
			}
			try
			{
				Level[] array = bundle.LoadAllAssets<Level>();
				foreach (Level val in array)
				{
					if (!((Object)(object)val == (Object)null) && MausoleumIsMausoleumLevel(val))
					{
						return true;
					}
				}
			}
			catch
			{
			}
			try
			{
				if (bundle.GetAllAssetNames().Any((string assetName) => assetName.Contains("mausoleum", StringComparison.OrdinalIgnoreCase)))
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				GameObject[] array2 = bundle.LoadAllAssets<GameObject>();
				foreach (GameObject val2 in array2)
				{
					if (!((Object)(object)val2 == (Object)null) && !string.IsNullOrWhiteSpace(((Object)val2).name) && (((Object)val2).name.StartsWith("MausoleumStart", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("MausoleumNorm", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("MausoleumPass", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("MausoleumEnd", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("MausoleumExt", StringComparison.OrdinalIgnoreCase) || string.Equals(((Object)val2).name, "MausoleumDoor", StringComparison.OrdinalIgnoreCase) || string.Equals(((Object)val2).name, "MausoleumBlock", StringComparison.OrdinalIgnoreCase)))
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static List<PrefabRef> MausoleumRegisterPrefabs(Level level, string moduleTypeName, IEnumerable<GameObject> prefabs)
		{
			List<PrefabRef> list = new List<PrefabRef>();
			foreach (GameObject item in prefabs.OrderBy<GameObject, string>((GameObject gameObject) => ((Object)gameObject).name, StringComparer.OrdinalIgnoreCase))
			{
				PrefabRef val = MausoleumRegisterNetworkPrefab("Level/" + ((Object)level).name + "/" + moduleTypeName + "/" + ((Object)item).name, item);
				if (val != null)
				{
					list.Add(val);
				}
			}
			return list;
		}

		private static PrefabRef? MausoleumRegisterNetworkPrefab(string prefabId, GameObject prefab)
		{
			PrefabRef val = MausoleumGetRegisteredPrefabRef(prefabId, prefab);
			if (val != null)
			{
				return val;
			}
			MausoleumPreparePrefab(prefab);
			Utilities.FixAudioMixerGroups(prefab);
			return NetworkPrefabs.RegisterNetworkPrefab(prefabId, prefab);
		}

		private static PrefabRef? MausoleumGetRegisteredPrefabRef(string prefabId, GameObject prefab)
		{
			if (!NetworkPrefabs.PrefabRefs.TryGetValue(prefabId, out var value) || value == null)
			{
				return null;
			}
			if ((Object)(object)value.Prefab == (Object)null || (Object)(object)value.Prefab == (Object)(object)prefab)
			{
				return value;
			}
			return null;
		}

		private static void MausoleumPreparePrefab(GameObject prefab)
		{
			MausoleumApplyHideFlags((Object)(object)prefab);
			MausoleumEnsureVehicleSupport(prefab);
			MausoleumNormalizeBoxColliderSizes(prefab);
			MausoleumIgnoreUnreadableMeshesForNavMesh(prefab);
			MausoleumAssignFallbackAudioMixerGroups(prefab);
			MausoleumAssignFallbackPhysAttributes(prefab);
			MausoleumAssignFallbackHingeData(prefab);
		}

		private static void MausoleumEnsureVehicleSupport(GameObject prefab)
		{
			if (!((Object)(object)prefab == (Object)null) && MausoleumIsStartRoomPrefab(prefab))
			{
				MausoleumEnsureVehicleItemVolumes(prefab);
				MausoleumEnsureVehicleChargingStation(prefab);
			}
		}

		private static bool MausoleumIsStartRoomPrefab(GameObject prefab)
		{
			GameObject prefab2 = prefab;
			if (!((Object)(object)prefab2.GetComponentInChildren<StartRoom>(true) != (Object)null))
			{
				return MausoleumStartRoomNames.Any((string name) => string.Equals(((Object)prefab2).name, name, StringComparison.OrdinalIgnoreCase));
			}
			return true;
		}

		private static void MausoleumEnsureVehicleItemVolumes(GameObject prefab)
		{
			int num = prefab.GetComponentsInChildren<ItemVolume>(true).Count(MausoleumIsVehicleItemVolume);
			if (num < 4)
			{
				Transform parent = MausoleumFindOrCreateVehicleSupportRoot(prefab);
				Transform anchor = MausoleumFindTruckAnchor(prefab);
				for (int i = num; i < 4; i++)
				{
					MausoleumCreateVehicleItemVolume(parent, anchor, i);
				}
			}
		}

		private static bool MausoleumIsVehicleItemVolume(ItemVolume itemVolume)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			return (int)MausoleumGetComponentField<itemVolume>((Component)(object)itemVolume, "itemVolume", (itemVolume)0) == 9;
		}

		private static void MausoleumCreateVehicleItemVolume(Transform parent, Transform anchor, int index)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_003c: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject((index == 0) ? "Item Volume vehicle" : $"Item Volume vehicle ({index})");
			val.SetActive(false);
			val.transform.SetParent(parent, false);
			val.transform.SetPositionAndRotation(MausoleumGetVehicleVolumePosition(anchor, index), anchor.rotation);
			ItemVolume target = val.AddComponent<ItemVolume>();
			MausoleumSetComponentField((Component)(object)target, "itemVolume", (object)(itemVolume)9);
			GameObject val2 = new GameObject("Vehicle");
			val2.transform.SetParent(val.transform, false);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = new Vector3(2.6f, 1.4f, 4f);
			MausoleumSetComponentField((Component)(object)target, "volumes", new List<GameObject> { val2 });
			MausoleumApplyHideFlags((Object)(object)val);
		}

		private static Vector3 MausoleumGetVehicleVolumePosition(Transform anchor, int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//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)
			float num = ((index % 2 == 0) ? (-2f) : 2f);
			float num2 = 2.5f + (float)(index / 2) * 2f;
			return anchor.position + anchor.right * num + anchor.forward * num2 + Vector3.up * 0.25f;
		}

		private static Transform MausoleumFindTruckAnchor(GameObject prefab)
		{
			LevelPoint[] componentsInChildren = prefab.GetComponentsInChildren<LevelPoint>(true);
			foreach (LevelPoint val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && MausoleumGetComponentField((Component)(object)val, "Truck", fallback: false))
				{
					return ((Component)val).transform;
				}
			}
			RoomVolume[] componentsInChildren2 = prefab.GetComponentsInChildren<RoomVolume>(true);
			foreach (RoomVolume val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null && MausoleumGetComponentField((Component)(object)val2, "Truck", fallback: false))
				{
					return ((Component)val2).transform;
				}
			}
			return prefab.transform;
		}

		private static Transform MausoleumFindOrCreateVehicleSupportRoot(GameObject prefab)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			Transform val = ((IEnumerable<Transform>)prefab.GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform child) => (Object)(object)child != (Object)null && string.Equals(((Object)child).name, "Empress Vehicle Support", StringComparison.OrdinalIgnoreCase)));
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			GameObject val2 = new GameObject("Empress Vehicle Support");
			val2.transform.SetParent(prefab.transform, false);
			MausoleumApplyHideFlags((Object)val2);
			return val2.transform;
		}

		private static void MausoleumEnsureVehicleChargingStation(GameObject prefab)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			if (prefab.GetComponentsInChildren<ChargingStation>(true).Any(MausoleumIsVehicleChargingStation))
			{
				return;
			}
			ChargingStation val = MausoleumFindFallbackChargingStationTemplate();
			if (!((Object)(object)val == (Object)null) && MausoleumIsVehicleChargingStation(val))
			{
				ChargingStation val2 = MausoleumFindLegacyChargingStation(prefab);
				Transform val3 = MausoleumFindOrCreateVehicleSupportRoot(prefab);
				Transform val4 = MausoleumFindTruckAnchor(prefab);
				GameObject val5 = MausoleumCloneInactiveChargingStationTemplate(val);
				((Object)val5).name = "Charging Station New";
				val5.transform.SetParent(val3, false);
				if ((Object)(object)val2 != (Object)null)
				{
					val5.transform.SetPositionAndRotation(((Component)val2).transform.position, ((Component)val2).transform.rotation);
					((Component)val2).gameObject.SetActive(false);
				}
				else
				{
					val5.transform.SetPositionAndRotation(val4.position + val4.forward * 6.5f + Vector3.up * 0.05f, Quaternion.LookRotation(-val4.forward, Vector3.up));
				}
				Transform val6 = MausoleumFindChildByExactName(val5.transform, "Charge Area");
				if ((Object)(object)val6 != (Object)null)
				{
					val6.localScale = new Vector3(Mathf.Max(val6.localScale.x, 4f), Mathf.Max(val6.localScale.y, 2f), Mathf.Max(val6.localScale.z, 4f));
				}
				MausoleumApplyHideFlags((Object)(object)val5);
				Utilities.FixAudioMixerGroups(val5);
			}
		}

		private static GameObject MausoleumCloneInactiveChargingStationTemplate(ChargingStation template)
		{
			GameObject gameObject = ((Component)template).gameObject;
			bool activeSelf = gameObject.activeSelf;
			try
			{
				if (activeSelf)
				{
					gameObject.SetActive(false);
				}
				GameObject obj = Object.Instantiate<GameObject>(gameObject);
				obj.SetActive(false);
				return obj;
			}
			finally
			{
				if ((Object)(object)gameObject != (Object)null && activeSelf)
				{
					gameObject.SetActive(true);
				}
			}
		}

		internal static void MausoleumActivateVehicleChargingStation(StartRoom? startRoom)
		{
			if ((Object)(object)startRoom == (Object)null || !MausoleumIsCurrentLevel() || !MausoleumIsStartRoomPrefab(((Component)startRoom).gameObject))
			{
				return;
			}
			ChargingStation[] componentsInChildren = ((Component)startRoom).GetComponentsInChildren<ChargingStation>(true);
			foreach (ChargingStation val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && MausoleumIsVehicleChargingStation(val) && string.Equals(((Object)((Component)val).gameObject).name, "Charging Station New", StringComparison.OrdinalIgnoreCase) && !((Component)val).gameObject.activeSelf)
				{
					((Component)val).gameObject.SetActive(true);
				}
			}
			ItemVolume[] componentsInChildren2 = ((Component)startRoom).GetComponentsInChildren<ItemVolume>(true);
			foreach (ItemVolume val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null && MausoleumIsVehicleItemVolume(val2) && !((Component)val2).gameObject.activeSelf)
				{
					((Component)val2).gameObject.SetActive(true);
				}
			}
		}

		private static ChargingStation? MausoleumFindFallbackChargingStationTemplate()
		{
			ChargingStation val = MausoleumFindChargingStationTemplateFromLevels();
			if ((Object)(object)val != (Object)null && MausoleumIsVehicleChargingStation(val))
			{
				return val;
			}
			return Resources.FindObjectsOfTypeAll<ChargingStation>().Where(delegate(ChargingStation candidate)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)candidate != (Object)null)
				{
					Scene scene = ((Component)candidate).gameObject.scene;
					return !((Scene)(ref scene)).IsValid();
				}
				return false;
			}).OrderByDescending(MausoleumIsVehicleChargingStation)
				.FirstOrDefault() ?? val;
		}

		private static ChargingStation? MausoleumFindChargingStationTemplateFromLevels()
		{
			ChargingStation val = null;
			if (RunManager.instance?.levels == null)
			{
				return val;
			}
			foreach (Level level in RunManager.instance.levels)
			{
				if ((Object)(object)level == (Object)null || MausoleumIsMausoleumLevel(level) || level.StartRooms == null)
				{
					continue;
				}
				foreach (PrefabRef startRoom in level.StartRooms)
				{
					GameObject val2 = null;
					try
					{
						val2 = MausoleumResolvePrefab(startRoom);
					}
					catch
					{
					}
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					ChargingStation[] componentsInChildren = val2.GetComponentsInChildren<ChargingStation>(true);
					foreach (ChargingStation val3 in componentsInChildren)
					{
						if (!((Object)(object)val3 == (Object)null))
						{
							if (MausoleumIsVehicleChargingStation(val3))
							{
								return val3;
							}
							if (val == null)
							{
								val = val3;
							}
						}
					}
				}
			}
			return val;
		}

		private static ChargingStation? MausoleumFindLegacyChargingStation(GameObject prefab)
		{
			return ((IEnumerable<ChargingStation>)prefab.GetComponentsInChildren<ChargingStation>(true)).FirstOrDefault((Func<ChargingStation, bool>)((ChargingStation candidate) => (Object)(object)candidate != (Object)null && !MausoleumIsVehicleChargingStation(candidate)));
		}

		private static bool MausoleumIsVehicleChargingStation(ChargingStation? chargingStation)
		{
			if ((Object)(object)chargingStation == (Object)null)
			{
				return false;
			}
			Transform transform = ((Component)chargingStation).transform;
			if ((Object)(object)MausoleumFindChildByExactName(transform, "Charge Area") != (Object)null)
			{
				return (Object)(object)MausoleumFindChildByExactName(transform, "Line Between Two Points") != (Object)null;
			}
			return false;
		}

		private static Transform? MausoleumFindChildByExactName(Transform root, string name)
		{
			string name2 = name;
			return ((IEnumerable<Transform>)((Component)root).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform child) => (Object)(object)child != (Object)null && string.Equals(((Object)child).name, name2, StringComparison.OrdinalIgnoreCase)));
		}

		private static T MausoleumGetComponentField<T>(Component target, string fieldName, T fallback)
		{
			if ((Object)(object)target == (Object)null)
			{
				return fallback;
			}
			try
			{
				if (AccessTools.Field(((object)target).GetType(), fieldName) == null)
				{
					return fallback;
				}
				return (T)((Traverse.Create((object)target).Field(fieldName).GetValue() is T val) ? ((object)val) : ((object)fallback));
			}
			catch
			{
				return fallback;
			}
		}

		private static void MausoleumSetComponentField(Component target, string fieldName, object value)
		{
			if ((Object)(object)target == (Object)null)
			{
				return;
			}
			try
			{
				if (!(AccessTools.Field(((object)target).GetType(), fieldName) == null))
				{
					Traverse.Create((object)target).Field(fieldName).SetValue(value);
				}
			}
			catch
			{
			}
		}

		private static void MausoleumNormalizeBoxColliderSizes(GameObject prefab)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0037: 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_0052: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			BoxCollider[] componentsInChildren = prefab.GetComponentsInChildren<BoxCollider>(true);
			Vector3 val2 = default(Vector3);
			foreach (BoxCollider val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Vector3 size = val.size;
					((Vector3)(ref val2))..ctor(Mathf.Abs(size.x), Mathf.Abs(size.y), Mathf.Abs(size.z));
					if (size != val2)
					{
						val.size = val2;
					}
				}
			}
		}

		private static void MausoleumIgnoreUnreadableMeshesForNavMesh(GameObject prefab)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			MeshFilter[] componentsInChildren = prefab.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if (!((Object)(object)((val != null) ? val.sharedMesh : null) == (Object)null) && !MausoleumMeshIsReadable(val.sharedMesh))
				{
					MausoleumIgnoreObjectFromNavMeshBuild(((Component)val).gameObject);
				}
			}
			SkinnedMeshRenderer[] componentsInChildren2 = prefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
			{
				if (!((Object)(object)((val2 != null) ? val2.sharedMesh : null) == (Object)null) && !MausoleumMeshIsReadable(val2.sharedMesh))
				{
					MausoleumIgnoreObjectFromNavMeshBuild(((Component)val2).gameObject);
				}
			}
		}

		private static bool MausoleumMeshIsReadable(Mesh mesh)
		{
			try
			{
				return mesh.isReadable;
			}
			catch
			{
				return false;
			}
		}

		private static void MausoleumIgnoreObjectFromNavMeshBuild(GameObject gameObject)
		{
			if (!((Object)(object)gameObject == (Object)null))
			{
				NavMeshModifier obj = gameObject.GetComponent<NavMeshModifier>() ?? gameObject.AddComponent<NavMeshModifier>();
				obj.ignoreFromBuild = true;
				obj.applyToChildren = false;
			}
		}

		private static void MausoleumAssignFallbackAudioMixerGroups(GameObject prefab)
		{
			AudioMixerGroup val = MausoleumGetFallbackAudioMixerGroup();
			if ((Object)(object)prefab == (Object)null || (Object)(object)val == (Object)null)
			{
				return;
			}
			AudioSource[] componentsInChildren = prefab.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.outputAudioMixerGroup != (Object)null))
				{
					val2.outputAudioMixerGroup = val;
				}
			}
		}

		private static void MausoleumAssignFallbackPhysAttributes(GameObject prefab)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			NotValuableObject[] componentsInChildren = prefab.GetComponentsInChildren<NotValuableObject>(true);
			foreach (NotValuableObject val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.physAttributePreset != (Object)null))
				{
					Rigidbody component = ((Component)val).GetComponent<Rigidbody>();
					float mass = (((Object)(object)component != (Object)null && component.mass > 0f) ? component.mass : 1f);
					val.physAttributePreset = MausoleumCreateFallbackPhysAttribute(mass);
				}
			}
		}

		private static void MausoleumAssignFallbackHingeData(GameObject prefab)
		{
			if (!((Object)(object)prefab == (Object)null))
			{
				PhysGrabHinge[] componentsInChildren = prefab.GetComponentsInChildren<PhysGrabHinge>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					MausoleumEnsurePhysGrabHingeCompatibility(componentsInChildren[i]);
				}
			}
		}

		internal static void MausoleumEnsurePhysGrabHingeCompatibility(PhysGrabHinge? hinge)
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)hinge == (Object)null))
			{
				PhysGrabHinge val = hinge;
				if (val.moveLoop == null)
				{
					val.moveLoop = MausoleumCreateFallbackSound();
				}
				if ((Object)(object)hinge.hingeAudio == (Object)null)
				{
					hinge.hingeAudio = MausoleumCreateFallbackHingeAudio();
				}
				else
				{
					MausoleumNormalizeSound(hinge.hingeAudio.moveLoop);
					MausoleumNormalizeSound(hinge.hingeAudio.moveLoopEnd);
					MausoleumNormalizeSound(hinge.hingeAudio.Close);
					MausoleumNormalizeSound(hinge.hingeAudio.CloseHeavy);
					MausoleumNormalizeSound(hinge.hingeAudio.Open);
					MausoleumNormalizeSound(hinge.hingeAudio.OpenHeavy);
					MausoleumNormalizeSound(hinge.hingeAudio.HingeBreak);
				}
				val = hinge;
				if (val.audioSource == null)
				{
					val.audioSource = ((Component)hinge).GetComponent<AudioSource>() ?? ((Component)hinge).gameObject.AddComponent<AudioSource>();
				}
				hinge.audioSource.playOnAwake = false;
				if ((Object)(object)hinge.audioSource.outputAudioMixerGroup == (Object)null)
				{
					hinge.audioSource.outputAudioMixerGroup = MausoleumGetFallbackAudioMixerGroup();
				}
				if (MausoleumShouldReplaceHingePoint(hinge))
				{
					hinge.hingePoint = MausoleumFindOrCreateBestHingePoint(hinge);
				}
				HingeJoint val2 = ((Component)hinge).GetComponent<HingeJoint>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)hinge).gameObject.AddComponent<HingeJoint>();
				}
				((Joint)val2).autoConfigureConnectedAnchor = true;
				((Joint)val2).axis = Vector3.right;
				if ((Object)(object)((Component)hinge).GetComponent<PhysGrabObjectImpactDetector>() == (Object)null)
				{
					((Component)hinge).gameObject.AddComponent<PhysGrabObjectImpactDetector>();
				}
				if (MausoleumShouldReplaceHingePoint(hinge))
				{
					hinge.hingePoint = MausoleumFindOrCreateBestHingePoint(hinge);
				}
				if ((Object)(object)hinge.hingePoint != (Object)null && (Object)(object)val2 != (Object)null)
				{
					((Joint)val2).anchor = hinge.hingePoint.localPosition;
				}
				val = hinge;
				if (val.wallTagHinges == null)
				{
					val.wallTagHinges = Array.Empty<PhysGrabHinge>();
				}
				val = hinge;
				if (val.wallTagObjects == null)
				{
					val.wallTagObjects = Array.Empty<GameObject>();
				}
				val = hinge;
				if (val.lowPassTriggers == null)
				{
					val.lowPassTriggers = Array.Empty<LowPassTrigger>();
				}
			}
		}

		private static bool MausoleumShouldReplaceHingePoint(PhysGrabHinge hinge)
		{
			if ((Object)(object)hinge == (Object)null)
			{
				return false;
			}
			if ((Object)(object)hinge.hingePoint == (Object)null)
			{
				return true;
			}
			if (!MausoleumIsCoffinLidHinge(hinge))
			{
				return false;
			}
			if (!((Object)(object)hinge.hingePoint == (Object)(object)((Component)hinge).transform) && !string.Equals(((Object)hinge.hingePoint).name, "Mesh", StringComparison.OrdinalIgnoreCase) && !string.Equals(((Object)hinge.hingePoint).name, "Collision", StringComparison.OrdinalIgnoreCase))
			{
				return string.Equals(((Object)hinge.hingePoint).name, "Mausoleum Patch Hinge Point", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static bool MausoleumIsCoffinLidHinge(PhysGrabHinge hinge)
		{
			if ((Object)(object)hinge == (Object)null)
			{
				return false;
			}
			if (!string.Equals(((Object)((Component)hinge).transform).name, "Hinge Template", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			Transform parent = ((Component)hinge).transform.parent;
			if ((Object)(object)parent == (Object)null)
			{
				return false;
			}
			if (((Object)parent).name.IndexOf("Coffin", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return ((Object)parent).name.IndexOf("Lid", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		private static Transform MausoleumFindOrCreateBestHingePoint(PhysGrabHinge hinge)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			PhysGrabHinge hinge2 = hinge;
			if ((Object)(object)hinge2 == (Object)null)
			{
				throw new ArgumentNullException("hinge");
			}
			Transform val = MausoleumFindDirectChildByExactName(((Component)hinge2).transform, "Hinge");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			Transform val2 = MausoleumFindDirectChildContaining(((Component)hinge2).transform, "Hinge", "Audio");
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
			if (MausoleumIsCoffinLidHinge(hinge2))
			{
				Transform val3 = MausoleumFindDirectChildByExactName(((Component)hinge2).transform, "Collision");
				if ((Object)(object)val3 != (Object)null)
				{
					Vector3 localPosition = default(Vector3);
					((Vector3)(ref localPosition))..ctor(val3.localPosition.x + val3.localScale.x * 0.5f, val3.localPosition.y + val3.localScale.y, val3.localPosition.z - 0.05f);
					return MausoleumCreateHingePoint(((Component)hinge2).transform, "Hinge", localPosition);
				}
			}
			Rigidbody val4 = ((IEnumerable<Rigidbody>)((Component)hinge2).GetComponentsInChildren<Rigidbody>(true)).FirstOrDefault((Func<Rigidbody, bool>)((Rigidbody rigidbody) => (Object)(object)rigidbody != (Object)null && (Object)(object)((Component)rigidbody).transform != (Object)(object)((Component)hinge2).transform));
			if ((Object)(object)val4 != (Object)null)
			{
				return ((Component)val4).transform;
			}
			if (((Component)hinge2).transform.childCount > 0)
			{
				return ((Component)hinge2).transform.GetChild(0);
			}
			return MausoleumCreateHingePoint(((Component)hinge2).transform, "Mausoleum Patch Hinge Point", Vector3.zero);
		}

		private static Transform? MausoleumFindDirectChildByExactName(Transform parent, string name)
		{
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				if ((Object)(object)child != (Object)null && string.Equals(((Object)child).name, name, StringComparison.OrdinalIgnoreCase))
				{
					return child;
				}
			}
			return null;
		}

		private static Transform? MausoleumFindDirectChildContaining(Transform parent, string value, string? excludeValue = null)
		{
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				if (!((Object)(object)child == (Object)null) && ((Object)child).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0 && (string.IsNullOrWhiteSpace(excludeValue) || ((Object)child).name.IndexOf(excludeValue, StringComparison.OrdinalIgnoreCase) < 0))
				{
					return child;
				}
			}
			return null;
		}

		private static Transform MausoleumCreateHingePoint(Transform parent, string name, Vector3 localPosition)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_005f: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Transform val = MausoleumFindDirectChildByExactName(parent, name);
			if ((Object)(object)val != (Object)null)
			{
				val.localPosition = localPosition;
				val.localRotation = Quaternion.identity;
				val.localScale = Vector3.one;
				return val;
			}
			GameObject val2 = new GameObject(name);
			val2.transform.SetParent(parent, false);
			val2.transform.localPosition = localPosition;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			MausoleumApplyHideFlags((Object)val2);
			return val2.transform;
		}

		private static HingeAudio MausoleumCreateFallbackHingeAudio()
		{
			HingeAudio obj = ScriptableObject.CreateInstance<HingeAudio>();
			obj.moveLoopEnabled = false;
			obj.moveLoop = MausoleumCreateFallbackSound();
			obj.moveLoopEnd = MausoleumCreateFallbackSound();
			obj.Close = MausoleumCreateFallbackSound();
			obj.CloseHeavy = MausoleumCreateFallbackSound();
			obj.Open = MausoleumCreateFallbackSound();
			obj.OpenHeavy = MausoleumCreateFallbackSound();
			obj.HingeBreak = MausoleumCreateFallbackSound();
			MausoleumApplyHideFlags((Object)(object)obj);
			return obj;
		}

		private static Sound MausoleumCreateFallbackSound()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_000c: Expected O, but got Unknown
			Sound val = new Sound();
			MausoleumNormalizeSound(val);
			return val;
		}

		private static void MausoleumNormalizeSound(Sound? sound)
		{
			if (sound != null)
			{
				Sound val = sound;
				if (val.Sounds == null)
				{
					val.Sounds = Array.Empty<AudioClip>();
				}
				val = sound;
				if (val.LowPassIgnoreColliders == null)
				{
					val.LowPassIgnoreColliders = new List<Collider>();
				}
			}
		}

		private static PhysAttribute MausoleumCreateFallbackPhysAttribute(float mass)
		{
			PhysAttribute obj = ScriptableObject.CreateInstance<PhysAttribute>();
			obj.mass = Mathf.Max(0.01f, mass);
			MausoleumApplyHideFlags((Object)(object)obj);
			return obj;
		}

		private static AudioMixerGroup? MausoleumGetFallbackAudioMixerGroup()
		{
			if ((Object)(object)AudioManager.instance == (Object)null)
			{
				return null;
			}
			return AudioManager.instance.SoundMasterGroup ?? AudioManager.instance.PersistentSoundGroup ?? AudioManager.instance.MusicMasterGroup ?? AudioManager.instance.MicrophoneSoundGroup ?? AudioManager.instance.MicrophoneSpectateGroup ?? AudioManager.instance.TTSSoundGroup ?? AudioManager.instance.TTSSpectateGroup;
		}

		private static int MausoleumCountModules(Level level)
		{
			return (level.ModulesNormal1?.Count ?? 0) + (level.ModulesPassage1?.Count ?? 0) + (level.ModulesDeadEnd1?.Count ?? 0) + (level.ModulesExtraction1?.Count ?? 0) + (level.ModulesNormal2?.Count ?? 0) + (level.ModulesPassage2?.Count ?? 0) + (level.ModulesDeadEnd2?.Count ?? 0) + (level.ModulesExtraction2?.Count ?? 0) + (level.ModulesNormal3?.Count ?? 0) + (level.ModulesPassage3?.Count ?? 0) + (level.ModulesDeadEnd3?.Count ?? 0) + (level.ModulesExtraction3?.Count ?? 0);
		}

		private static bool MausoleumHasValidLevelData(Level? level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (MausoleumCountValidPrefabRefs(level.StartRooms) > 0)
			{
				return MausoleumCountValidModules(level) > 0;
			}
			return false;
		}

		private static int MausoleumCountValidModules(Level level)
		{
			return MausoleumCountValidPrefabRefs(level.ModulesNormal1) + MausoleumCountValidPrefabRefs(level.ModulesPassage1) + MausoleumCountValidPrefabRefs(level.ModulesDeadEnd1) + MausoleumCountValidPrefabRefs(level.ModulesExtraction1) + MausoleumCountValidPrefabRefs(level.ModulesNormal2) + MausoleumCountValidPrefabRefs(level.ModulesPassage2) + MausoleumCountValidPrefabRefs(level.ModulesDeadEnd2) + MausoleumCountValidPrefabRefs(level.ModulesExtraction2) + MausoleumCountValidPrefabRefs(level.ModulesNormal3) + MausoleumCountValidPrefabRefs(level.ModulesPassage3) + MausoleumCountValidPrefabRefs(level.ModulesDeadEnd3) + MausoleumCountValidPrefabRefs(level.ModulesExtraction3);
		}

		private static int MausoleumCountValidPrefabRefs(IEnumerable<PrefabRef>? prefabRefs)
		{
			if (prefabRefs == null)
			{
				return 0;
			}
			int num = 0;
			foreach (PrefabRef prefabRef in prefabRefs)
			{
				if (prefabRef != null && prefabRef.IsValid())
				{
					num++;
				}
			}
			return num;
		}

		internal static bool MausoleumIsCurrentLevel()
		{
			if (!MausoleumIsMausoleumLevel(((Object)(object)LevelGenerator.Instance != (Object)null) ? LevelGenerator.Instance.Level : null))
			{
				return MausoleumIsMausoleumLevel(((Object)(object)RunManager.instance != (Object)null) ? RunManager.instance.levelCurrent : null);
			}
			return true;
		}

		internal static bool MausoleumIsMausoleumLevel(Level? level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (!string.Equals(((Object)level).name, "Mel Mausoleum", StringComparison.OrdinalIgnoreCase) && (string.IsNullOrWhiteSpace(((Object)level).name) || ((Object)level).name.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) < 0))
			{
				if (!string.IsNullOrWhiteSpace(level.NarrativeName))
				{
					return level.NarrativeName.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) >= 0;
				}
				return false;
			}
			return true;
		}

		internal static void MausoleumEnsureLevelFallbackData(Level? level)
		{
			if (MausoleumIsMausoleumLevel(level))
			{
				Level val = level;
				if (val.ValuablePresets == null)
				{
					val.ValuablePresets = new List<LevelValuables>();
				}
				val = level;
				if (val.AmbiencePresets == null)
				{
					val.AmbiencePresets = new List<LevelAmbience>();
				}
				if (level.ValuablePresets.Count == 0 && (Object)(object)ValuablePresets.GenericValuablePreset != (Object)null)
				{
					level.ValuablePresets.Add(ValuablePresets.GenericValuablePreset);
				}
				if (level.AmbiencePresets.Count == 0 && MausoleumTryGetFallbackAmbience(out LevelAmbience ambience))
				{
					level.AmbiencePresets.Add(ambience);
				}
			}
		}

		private static void MausoleumEnsureLevelLoadingGraphics(Level level, AssetBundle bundle)
		{
			List<MausoleumLoadingGraphic> list = MausoleumCollectLoadingGraphics(bundle);
			MausoleumCacheLoadingSprites(list);
			string[] mausoleumLoadingGraphicFieldNames = MausoleumLoadingGraphicFieldNames;
			foreach (string text in mausoleumLoadingGraphicFieldNames)
			{
				if (list.Count != 0 || !MausoleumLevelLoadingGraphicValid(level, text))
				{
					MausoleumLoadingGraphic mausoleumLoadingGraphic = ((list.Count > 0) ? list[Math.Min(Array.IndexOf(MausoleumLoadingGraphicFieldNames, text), list.Count - 1)] : null);
					if (mausoleumLoadingGraphic == null || !MausoleumSetLevelLoadingGraphic(level, text, mausoleumLoadingGraphic))
					{
						MausoleumCopyFallbackLevelLoadingGraphic(level, text);
					}
				}
			}
		}

		private static List<MausoleumLoadingGraphic> MausoleumCollectLoadingGraphics(AssetBundle bundle)
		{
			List<MausoleumLoadingGraphic> list = new List<MausoleumLoadingGraphic>();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			List<Sprite> source = (from sprite in bundle.LoadAllAssets<Sprite>()
				where (Object)(object)sprite != (Object)null && !string.IsNullOrWhiteSpace(((Object)sprite).name)
				select sprite).ToList();
			string[] mausoleumPreferredLoadingGraphicNames = MausoleumPreferredLoadingGraphicNames;
			foreach (string preferredName in mausoleumPreferredLoadingGraphicNames)
			{
				Sprite val = ((IEnumerable<Sprite>)source).FirstOrDefault((Func<Sprite, bool>)((Sprite candidate) => string.Equals(((Object)candidate).name, preferredName, StringComparison.OrdinalIgnoreCase)));
				if (!((Object)(object)val == (Object)null) && hashSet.Add(((Object)val).name))
				{
					bool canUsePrefabRef = (Object)(object)bundle.LoadAsset<Sprite>(((Object)val).name) != (Object)null;
					list.Add(new MausoleumLoadingGraphic(bundle, val, ((Object)val).name, canUsePrefabRef));
				}
			}
			foreach (string item in bundle.GetAllAssetNames().OrderBy(MausoleumLoadingGraphicRank).ThenBy<string, string>((string name) => name, StringComparer.OrdinalIgnoreCase))
			{
				Sprite val2 = bundle.LoadAsset<Sprite>(item);
				if (!((Object)(object)val2 == (Object)null) && hashSet.Add(item))
				{
					list.Add(new MausoleumLoadingGraphic(bundle, val2, item, canUsePrefabRef: true));
				}
			}
			foreach (Sprite item2 in source.OrderBy((Sprite sprite) => MausoleumLoadingGraphicRank(((Object)sprite).name)).ThenBy<Sprite, string>((Sprite sprite) => ((Object)sprite).name, StringComparer.OrdinalIgnoreCase))
			{
				if (!((Object)(object)item2 == (Object)null) && !string.IsNullOrWhiteSpace(((Object)item2).name) && hashSet.Add(((Object)item2).name))
				{
					bool canUsePrefabRef2 = (Object)(object)bundle.LoadAsset<Sprite>(((Object)item2).name) != (Object)null;
					list.Add(new MausoleumLoadingGraphic(bundle, item2, ((Object)item2).name, canUsePrefabRef2));
				}
			}
			return list;
		}

		private static void MausoleumCacheLoadingSprites(IEnumerable<MausoleumLoadingGraphic> graphics)
		{
			MausoleumLoadingSprites.Clear();
			foreach (MausoleumLoadingGraphic graphic in graphics)
			{
				if ((Object)(object)graphic.Sprite != (Object)null && !MausoleumLoadingSprites.Contains(graphic.Sprite))
				{
					MausoleumLoadingSprites.Add(graphic.Sprite);
				}
				if (MausoleumLoadingSprites.Count >= MausoleumLoadingGraphicFieldNames.Length)
				{
					break;
				}
			}
		}

		internal static void MausoleumApplyLoadingGraphics(LoadingUI? loadingUI)
		{
			if (!((Object)(object)loadingUI == (Object)null) && MausoleumIsCurrentLevel() && MausoleumLoadingSprites.Count != 0)
			{
				MausoleumApplyLoadingGraphic(loadingUI.loadingGraphic01, 0);
				MausoleumApplyLoadingGraphic(loadingUI.loadingGraphic02, 1);
				MausoleumApplyLoadingGraphic(loadingUI.loadingGraphic03, 2);
			}
		}

		private static void MausoleumApplyLoadingGraphic(Image? image, int index)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)image == (Object)null))
			{
				Sprite sprite = MausoleumLoadingSprites[Math.Min(index, MausoleumLoadingSprites.Count - 1)];
				image.sprite = sprite;
				((Graphic)image).color = Color.white;
			}
		}

		private static int MausoleumLoadingGraphicRank(string value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return 1000;
			}
			string text = value.ToLowerInvariant();
			int num = 0;
			if (text.Contains("loading") || text.Contains("load"))
			{
				num -= 100;
			}
			if (text.Contains("graphic"))
			{
				num -= 50;
			}
			if (text.Contains("mausoleum"))
			{
				num -= 25;
			}
			if (text.Contains("icon") || text.Contains("emoji"))
			{
				num += 100;
			}
			return num;
		}

		private static bool MausoleumLevelLoadingGraphicValid(Level level, string fieldName)
		{
			try
			{
				if (AccessTools.Field(((object)level).GetType(), fieldName) == null)
				{
					return false;
				}
				object value = Traverse.Create((object)level).Field(fieldName).GetValue();
				if (value == null)
				{
					return false;
				}
				Sprite val = (Sprite)((value is Sprite) ? value : null);
				if (val != null)
				{
					return (Object)(object)val != (Object)null;
				}
				return AccessTools.Method(value.GetType(), "IsValid", Type.EmptyTypes, (Type[])null) != null && Traverse.Create(value).Method("IsValid", Array.Empty<object>()).GetValue<bool>();
			}
			catch
			{
				return false;
			}
		}

		private static bool MausoleumSetLevelLoadingGraphic(Level level, string fieldName, MausoleumLoadingGraphic graphic)
		{
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(((object)level).GetType(), fieldName);
				if (fieldInfo == null)
				{
					return false;
				}
				if (typeof(Sprite).IsAssignableFrom(fieldInfo.FieldType))
				{
					Traverse.Create((object)level).Field(fieldName).SetValue((object)graphic.Sprite);
					return true;
				}
				if (!fieldInfo.FieldType.Name.StartsWith("PrefabRef", StringComparison.Ordinal))
				{
					return false;
				}
				if (!graphic.CanUsePrefabRef)
				{
					return false;
				}
				object obj = Traverse.Create((object)level).Field(fieldName).GetValue() ?? AccessTools.CreateInstance(fieldInfo.FieldType);
				if (obj == null)
				{
					return false;
				}
				if (AccessTools.Method(fieldInfo.FieldType, "SetPrefab", new Type[2]
				{
					typeof(AssetBundle),
					typeof(string)
				}, (Type[])null) != null)
				{
					Traverse.Create(obj).Method("SetPrefab", new object[2] { graphic.Bundle, graphic.ResourcePath }).GetValue();
				}
				else
				{
					if (AccessTools.Field(fieldInfo.FieldType, "bundle") != null)
					{
						Traverse.Create(obj).Field("bundle").SetValue((object)graphic.Bundle);
					}
					if (AccessTools.Field(fieldInfo.FieldType, "resourcePath") != null)
					{
						Traverse.Create(obj).Field("resourcePath").SetValue((object)graphic.ResourcePath);
					}
					if (AccessTools.Field(fieldInfo.FieldType, "prefabName") != null)
					{
						Traverse.Create(obj).Field("prefabName").SetValue((object)Path.GetFileNameWithoutExtension(graphic.ResourcePath));
					}
				}
				Traverse.Create((object)level).Field(fieldName).SetValue(obj);
				return MausoleumLevelLoadingGraphicValid(level, fieldName);
			}
			catch
			{
				return false;
			}
		}

		private static bool MausoleumCopyFallbackLevelLoadingGraphic(Level level, string fieldName)
		{
			if (RunManager.instance?.levels == null)
			{
				return false;
			}
			foreach (Level level2 in RunManager.instance.levels)
			{
				if ((Object)(object)level2 == (Object)null || (Object)(object)level2 == (Object)(object)level)
				{
					continue;
				}
				try
				{
					FieldInfo fieldInfo = AccessTools.Field(((object)level2).GetType(), fieldName);
					FieldInfo fieldInfo2 = AccessTools.Field(((object)level).GetType(), fieldName);
					if (fieldInfo == null || fieldInfo2 == null)
					{
						continue;
					}
					object value = Traverse.Create((object)level2).Field(fieldName).GetValue();
					if (value != null)
					{
						Traverse.Create((object)level).Field(fieldName).SetValue(value);
						if (MausoleumLevelLoadingGraphicValid(level, fieldName))
						{
							return true;
						}
					}
				}
				catch
				{
				}
			}
			return false;
		}

		private static bool MausoleumTryGetFallbackAmbience(out LevelAmbience ambience)
		{
			ambience = null;
			if ((Object)(object)AudioManager.instance != (Object)null && AudioManager.instance.levelAmbiences != null)
			{
				foreach (LevelAmbience levelAmbience in AudioManager.instance.levelAmbiences)
				{
					if (!((Object)(object)levelAmbience == (Object)null))
					{
						ambience = levelAmbience;
						return true;
					}
				}
			}
			if ((Object)(object)RunManager.instance != (Object)null && RunManager.instance.levels != null)
			{
				foreach (Level level in RunManager.instance.levels)
				{
					if (level?.AmbiencePresets == null)
					{
						continue;
					}
					foreach (LevelAmbience ambiencePreset in level.AmbiencePresets)
					{
						if (!((Object)(object)ambiencePreset == (Object)null))
						{
							ambience = ambiencePreset;
							return true;
						}
					}
				}
			}
			return false;
		}

		internal static bool MausoleumShouldSuppressUnityLog(LogType logType, string? format, object[]? args)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_002f: 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)
			if (!MausoleumIsCurrentLevel())
			{
				return false;
			}
			string text = MausoleumFormatUnityLogMessage(format, args);
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			if ((int)logType == 2 && text.StartsWith("BoxCollider does not support negative scale or size.", StringComparison.Ordinal))
			{
				return true;
			}
			if ((int)logType == 0 && text.StartsWith("RuntimeNavMeshBuilder: Source mesh ", StringComparison.Ordinal) && text.IndexOf("does not allow read access", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			if ((int)logType == 0)
			{
				if (!text.StartsWith("Level Point: ", StringComparison.Ordinal))
				{
					return text.StartsWith("          Point Name: ", StringComparison.Ordinal);
				}
				return true;
			}
			return false;
		}

		private static string MausoleumFormatUnityLogMessage(string? format, object[]? args)
		{
			if (format == null)
			{
				return string.Empty;
			}
			if (args == null || args.Length == 0)
			{
				return format;
			}
			try
			{
				return string.Format(format, args);
			}
			catch
			{
				return format;
			}
		}

		internal static void MausoleumEnsureExtractionPointCompatibility(ExtractionPoint extractionPoint)
		{
			//IL_004c: 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)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			if ((Object)(object)extractionPoint == (Object)null || !MausoleumIsCurrentLevel())
			{
				return;
			}
			if ((Object)(object)extractionPoint.extractionArea == (Object)null)
			{
				GameObject val = GameObject.CreatePrimitive((PrimitiveType)2);
				((Object)val).name = "Mausoleum Patch Extraction Area";
				val.transform.SetParent(((Component)extractionPoint).transform, false);
				val.transform.localPosition = Vector3.zero;
				val.transform.localRotation = Quaternion.identity;
				val.transform.localScale = Vector3.one * 0.1f;
				MeshRenderer component = val.GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					((Renderer)component).enabled = false;
				}
				Collider component2 = val.GetComponent<Collider>();
				if ((Object)(object)component2 != (Object)null)
				{
					Object.Destroy((Object)(object)component2);
				}
				val.SetActive(false);
				MausoleumApplyHideFlags((Object)(object)val);
				extractionPoint.extractionArea = val;
			}
			MausoleumHideExtractionAreaVisual(extractionPoint.extractionArea);
			if ((Object)(object)extractionPoint.grossUp == (Object)null)
			{
				GameObject val2 = new GameObject("Mausoleum Patch GrossUp");
				val2.transform.SetParent(((Component)extractionPoint).transform, false);
				val2.SetActive(false);
				MausoleumApplyHideFlags((Object)(object)val2);
				extractionPoint.grossUp = val2;
			}
		}

		private static void MausoleumHideExtractionAreaVisual(GameObject? extractionArea)
		{
			if ((Object)(object)extractionArea == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = extractionArea.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.enabled = false;
				}
			}
		}

		internal void MausoleumRepairLevelPoints(LevelGenerator levelGenerator)
		{
			if ((Object)(object)levelGenerator == (Object)null || !MausoleumIsMausoleumLevel(levelGenerator.Level) || levelGenerator.LevelPathPoints == null)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (LevelPoint levelPathPoint in levelGenerator.LevelPathPoints)
			{
				if (MausoleumRepairLevelPoint(levelPathPoint))
				{
					num++;
				}
				if (MausoleumRepairLevelPointRoom(levelPathPoint))
				{
					num2++;
				}
			}
			if (num > 0 || num2 > 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch repaired {num} Mausoleum level points onto the navmesh and restored {num2} room links.");
			}
		}

		internal void MausoleumEnsureStartRoomList(LevelGenerator? levelGenerator)
		{
			if ((Object)(object)levelGenerator?.Level == (Object)null || (levelGenerator.Level.StartRooms != null && levelGenerator.Level.StartRooms.Count > 0))
			{
				return;
			}
			MausoleumTryRepairLevel(levelGenerator.Level);
			if (levelGenerator.Level.StartRooms != null && levelGenerator.Level.StartRooms.Count > 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch populated {levelGenerator.Level.StartRooms.Count} start rooms for {((Object)levelGenerator.Level).name} before generation.");
				return;
			}
			AssetBundle val = MausoleumGetBundle();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			MausoleumPrefabBuckets mausoleumPrefabBuckets = MausoleumCollectPrefabs(val);
			if (mausoleumPrefabBuckets.StartRooms.Count != 0)
			{
				MausoleumEnsureLevelFallbackData(levelGenerator.Level);
				MausoleumRegisterLevelObjects(levelGenerator.Level);
				MausoleumApplyPrefabBuckets(levelGenerator.Level, mausoleumPrefabBuckets);
				if (levelGenerator.Level.StartRooms != null && levelGenerator.Level.StartRooms.Count > 0)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch force-filled {levelGenerator.Level.StartRooms.Count} start rooms for {((Object)levelGenerator.Level).name} from the original bundle.");
				}
			}
		}

		internal static PrefabRef MausoleumGetSafeStartRoomRef(List<PrefabRef> startRooms, int index, object? stateMachine)
		{
			if (startRooms != null && index >= 0 && index < startRooms.Count)
			{
				PrefabRef val = startRooms[index];
				if (val != null && val.IsValid())
				{
					return val;
				}
			}
			MausoleumCompatPatchPlugin instance = Instance;
			LevelGenerator val2 = MausoleumGetLevelGeneratorFromStateMachine(stateMachine);
			instance?.MausoleumEnsureStartRoomList(val2);
			if (val2?.Level?.StartRooms != null)
			{
				List<PrefabRef> list = val2.Level.StartRooms.Where((PrefabRef prefabRef) => prefabRef != null && prefabRef.IsValid()).ToList();
				if (index >= 0 && index < list.Count)
				{
					return list[index];
				}
				if (list.Count > 0)
				{
					return list[0];
				}
			}
			if ((Object)(object)instance != (Object)null && (Object)(object)val2?.Level != (Object)null)
			{
				AssetBundle val3 = instance.MausoleumGetBundle();
				if ((Object)(object)val3 != (Object)null)
				{
					GameObject val4 = MausoleumCollectPrefabs(val3).StartRooms.FirstOrDefault();
					if ((Object)(object)val4 != (Object)null)
					{
						PrefabRef val5 = MausoleumRegisterNetworkPrefab("Level/" + ((Object)val2.Level).name + "/StartRoom/" + ((Object)val4).name, val4);
						if (val5 != null)
						{
							return val5;
						}
					}
				}
			}
			throw new ArgumentOutOfRangeException("index", "Empress Mausoleum Compat Patch could not recover a valid start room.");
		}

		internal static bool MausoleumTryRecoverStartRoomFromListAccess(List<PrefabRef> startRooms, int index, ref PrefabRef __result)
		{
			if (startRooms == null || (index >= 0 && index < startRooms.Count))
			{
				return true;
			}
			Level val = (((Object)(object)RunManager.instance != (Object)null) ? RunManager.instance.levelCurrent : null);
			if (!MausoleumIsMausoleumLevel(val))
			{
				return true;
			}
			MausoleumCompatPatchPlugin? instance = Instance;
			LevelGenerator instance2 = LevelGenerator.Instance;
			instance?.MausoleumEnsureStartRoomList(instance2);
			instance?.MausoleumTryRepairLevel(val);
			Level val2 = instance2?.Level ?? val;
			if (val2?.StartRooms != null)
			{
				foreach (PrefabRef startRoom in val2.StartRooms)
				{
					if (startRoom != null && startRoom.IsValid())
					{
						MausoleumCompatPatchPlugin? instance3 = Instance;
						if (instance3 != null)
						{
							((BaseUnityPlugin)instance3).Logger.LogInfo((object)("Empress Mausoleum Compat Patch recovered start room access for " + ((Object)val2).name + " during generation."));
						}
						__result = startRoom;
						return false;
					}
				}
			}
			return true;
		}

		internal static LevelGenerator? MausoleumGetLevelGeneratorFromStateMachine(object? stateMachine)
		{
			if (stateMachine == null)
			{
				return null;
			}
			Type type = stateMachine.GetType();
			while (type != null)
			{
				foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(type))
				{
					if (typeof(LevelGenerator).IsAssignableFrom(declaredField.FieldType))
					{
						LevelGenerator value = Traverse.Create(stateMachine).Field(declaredField.Name).GetValue<LevelGenerator>();
						if ((Object)(object)value != (Object)null)
						{
							return value;
						}
					}
				}
				type = type.BaseType;
			}
			return null;
		}

		internal bool MausoleumTryStartSilentLevelPoint(LevelPoint levelPoint)
		{
			if (!MausoleumIsMausoleumLevelPoint(levelPoint))
			{
				return false;
			}
			if ((Object)(object)LevelGenerator.Instance != (Object)null)
			{
				LevelGenerator instance = LevelGenerator.Instance;
				if (instance.LevelPathPoints == null)
				{
					instance.LevelPathPoints = new List<LevelPoint>();
				}
				if (!LevelGenerator.Instance.LevelPathPoints.Contains(levelPoint))
				{
					LevelGenerator.Instance.LevelPathPoints.Add(levelPoint);
				}
				if (levelPoint.Truck)
				{
					LevelGenerator.Instance.LevelPathTruck = levelPoint;
				}
			}
			if ((Object)(object)((Component)levelPoint).GetComponentInParent<StartRoom>() != (Object)null)
			{
				MausoleumSetLevelPointBool(levelPoint, "inStartRoom", value: true);
			}
			((MonoBehaviour)this).StartCoroutine(MausoleumSilentLevelPointCheck(levelPoint));
			return true;
		}

		private static void MausoleumSetLevelPointBool(LevelPoint levelPoint, string fieldName, bool value)
		{
			try
			{
				if (AccessTools.Field(((object)levelPoint).GetType(), fieldName) != null)
				{
					Traverse.Create((object)levelPoint).Field(fieldName).SetValue((object)value);
				}
			}
			catch
			{
			}
		}

		private static bool MausoleumIsMausoleumLevelPoint(LevelPoint? levelPoint)
		{
			if ((Object)(object)levelPoint == (Object)null)
			{
				return false;
			}
			if (MausoleumIsCurrentLevel())
			{
				return true;
			}
			Module componentInParent = ((Component)levelPoint).GetComponentInParent<Module>();
			if ((Object)(object)componentInParent != (Object)null && !string.IsNullOrWhiteSpace(((Object)componentInParent).name) && ((Object)componentInParent).name.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			StartRoom componentInParent2 = ((Component)levelPoint).GetComponentInParent<StartRoom>();
			if ((Object)(object)componentInParent2 != (Object)null && !string.IsNullOrWhiteSpace(((Object)componentInParent2).name) && ((Object)componentInParent2).name.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			Transform val = ((Component)levelPoint).transform;
			while ((Object)(object)val != (Object)null)
			{
				if (!string.IsNullOrWhiteSpace(((Object)val).name) && ((Object)val).name.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static bool MausoleumRepairLevelPoint(LevelPoint? levelPoint)
		{
			//IL_0011: 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)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			if ((Object)(object)levelPoint == (Object)null)
			{
				return false;
			}
			Vector3 position = ((Component)levelPoint).transform.position;
			NavMeshHit val = default(NavMeshHit);
			if (NavMesh.SamplePosition(position, ref val, 0.5f, -1))
			{
				return false;
			}
			NavMeshHit val2 = default(NavMeshHit);
			if (!NavMesh.SamplePosition(position, ref val2, 2f, -1))
			{
				return false;
			}
			((Component)levelPoint).transform.position = ((NavMeshHit)(ref val2)).position;
			MausoleumRepairLevelPointRoom(levelPoint);
			return true;
		}

		private static bool MausoleumRepairLevelPointRoom(LevelPoint? levelPoint)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)levelPoint == (Object)null || (Object)(object)levelPoint.Room != (Object)null)
			{
				return false;
			}
			RoomVolume room = default(RoomVolume);
			Vector3 val = default(Vector3);
			if (!SemiFunc.GetRoomVolumeAtPosition(((Component)levelPoint).transform.position, ref room, ref val))
			{
				return false;
			}
			levelPoint.Room = room;
			return true;
		}

		internal IEnumerator MausoleumSilentLevelPointCheck(LevelPoint levelPoint)
		{
			if ((Object)(object)levelPoint == (Object)null)
			{
				yield break;
			}
			while ((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
			{
				yield return (object)new WaitForSeconds(0.1f);
			}
			yield return (object)new WaitForSeconds(0.5f);
			if (MausoleumIsCurrentLevel())
			{
				MausoleumRepairLevelPoint(levelPoint);
				MausoleumRepairLevelPointRoom(levelPoint);
				MausoleumRepairLevelPointConnections(levelPoint, LevelGenerator.Instance?.LevelPathPoints);
				if (levelPoint.ModuleConnect)
				{
					MausoleumSetLevelPointBool(levelPoint, "ModuleConnected", value: true);
				}
			}
		}

		private static void MausoleumRepairLevelPointConnections(LevelPoint? levelPoint, IList<LevelPoint>? allLevelPoints)
		{
			if ((Object)(object)levelPoint == (Object)null)
			{
				return;
			}
			if (levelPoint.ConnectedPoints == null)
			{
				levelPoint.ConnectedPoints = new List<LevelPoint>();
			}
			levelPoint.ConnectedPoints.RemoveAll((LevelPoint connectedPoint) => (Object)(object)connectedPoint == (Object)null);
			LevelPoint[] array = levelPoint.ConnectedPoints.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				MausoleumAddLevelPointConnection(array[i], levelPoint);
			}
			if (!levelPoint.ModuleConnect || allLevelPoints == null || levelPoint.ConnectedPoints.Count > 0)
			{
				return;
			}
			LevelPoint val = null;
			float currentBestDistance = float.MaxValue;
			foreach (LevelPoint allLevelPoint in allLevelPoints)
			{
				if (MausoleumCanConnectLevelPoints(levelPoint, allLevelPoint, currentBestDistance, out var distance))
				{
					val = allLevelPoint;
					currentBestDistance = distance;
				}
			}
			MausoleumAddLevelPointConnection(levelPoint, val);
			MausoleumAddLevelPointConnection(val, levelPoint);
		}

		private static bool MausoleumCanConnectLevelPoints(LevelPoint source, LevelPoint? candidate, float currentBestDistance, out float distance)
		{
			//IL_0032: 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_0077: 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)
			//IL_009b: 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)
			distance = 0f;
			if ((Object)(object)source == (Object)null || (Object)(object)candidate == (Object)null || (Object)(object)source == (Object)(object)candidate || !candidate.ModuleConnect)
			{
				return false;
			}
			Vector3 val = ((Component)source).transform.position - ((Component)candidate).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude <= Mathf.Epsilon)
			{
				return false;
			}
			distance = ((Vector3)(ref val)).magnitude;
			if (distance >= 15f || distance >= currentBestDistance)
			{
				return false;
			}
			if (Vector3.Dot(((Component)candidate).transform.forward, ((Component)source).transform.forward) > -0.8f)
			{
				return false;
			}
			return Vector3.Dot(((Component)candidate).transform.forward, ((Vector3)(ref val)).normalized) > 0.8f;
		}

		private static void MausoleumAddLevelPointConnection(LevelPoint? source, LevelPoint? target)
		{
			if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null))
			{
				if (source.ConnectedPoints == null)
				{
					source.ConnectedPoints = new List<LevelPoint>();
				}
				if (!source.ConnectedPoints.Contains(target))
				{
					source.ConnectedPoints.Add(target);
				}
			}
		}

		internal GameObject MausoleumCreateFallbackDoorMapObject(Map map, DirtFinderMapDoor door)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			MapLayer layerParent = map.GetLayerParent(((Component)door).transform.position.y);
			GameObject val = MausoleumInstantiateFallbackDoorMapObject(map, ((Component)layerParent).transform);
			((Object)val).name = ((Object)((Component)door).gameObject).name;
			door.Target = val.transform;
			DirtFinderMapDoorTarget val2 = val.GetComponent<DirtFinderMapDoorTarget>() ?? val.AddComponent<DirtFinderMapDoorTarget>();
			val2.Target = ((Component)door).transform;
			val2.Layer = layerParent;
			DirtFinderMapDoorTarget val3 = val2;
			if (val3.HingeTransform == null)
			{
				val3.HingeTransform = val.transform;
			}
			map.DoorUpdate(val2.HingeTransform, ((Component)door).transform, layerParent);
			if (!_mausoleumLoggedDoorMapFallback)
			{
				_mausoleumLoggedDoorMapFallback = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Empress Mausoleum Compat Patch injected fallback minimap door markers for missing Mausoleum door prefabs.");
			}
			return val;
		}

		private static GameObject MausoleumInstantiateFallbackDoorMapObject(Map map, Transform parent)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val;
			if ((Object)(object)map.Door1x1Object != (Object)null)
			{
				val = Object.Instantiate<GameObject>(map.Door1x1Object, parent);
				Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren[i]);
				}
			}
			else
			{
				val = GameObject.CreatePrimitive((PrimitiveType)3);
				val.transform.SetParent(parent, false);
				val.transform.localScale = new Vector3(0.12f, 0.12f, 0.3f);
				Collider component = val.GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
			}
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			DirtFinderMapDoorTarget val2 = val.GetComponent<DirtFinderMapDoorTarget>() ?? val.AddComponent<DirtFinderMapDoorTarget>();
			if (val2.HingeTransform == null)
			{
				val2.HingeTransform = val.transform;
			}
			MausoleumApplyHideFlags((Object)(object)val);
			return val;
		}

		private static void MausoleumApplyHideFlags(Object obj)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			if (obj == (Object)null)
			{
				return;
			}
			obj.hideFlags = (HideFlags)(obj.hideFlags | 0x23);
			GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
			if (val == null)
			{
				return;
			}
			Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
			foreach (Transform obj2 in componentsInChildren)
			{
				((Object)obj2).hideFlags = (HideFlags)(((Object)obj2).hideFlags | 0x23);
				GameObject gameObject = ((Component)obj2).gameObject;
				((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags | 0x23);
				Component[] components = ((Component)obj2).GetComponents<Component>();
				foreach (Component val2 in components)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x23);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(LevelPoint), "Start")]
	internal static class MausoleumCompatPatchLevelPointStartPatch
	{
		[HarmonyPrefix]
		private static bool MausoleumPrefix(LevelPoint __instance)
		{
			MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.MausoleumTryStartSilentLevelPoint(__instance))
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(LoadingUI), "LevelAnimationStart")]
	internal static class MausoleumCompatPatchLoadingUILevelAnimationStartPatch
	{
		[HarmonyPostfix]
		private static void MausoleumPostfix(LoadingUI __instance)
		{
			MausoleumCompatPatchPlugin.MausoleumApplyLoadingGraphics(__instance);
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "StartRoomGeneration")]
	internal static class MausoleumCompatPatchStartRoomGenerationPatch
	{
		[HarmonyPrefix]
		private static void MausoleumPrefix()
		{
			if (MausoleumCompatPatchPlugin.MausoleumIsCurrentLevel())
			{
				MausoleumCompatPatchPlugin.Instance?.MausoleumTryRepairCurrentLevel();
			}
		}
	}
	[HarmonyPatch(typeof(StartRoom), "Start")]
	internal static class MausoleumCompatPatchStartRoomStartPatch
	{
		[HarmonyPostfix]
		private static void MausoleumPostfix(StartRoom __instance)
		{
			MausoleumCompatPatchPlugin.MausoleumActivateVehicleChargingStation(__instance);
		}
	}
	[HarmonyPatch]
	internal static class MausoleumCompatPatchStartRoomGenerationMoveNextPatch
	{
		private static MethodBase? TargetMethod()
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(LevelGenerator), "StartRoomGeneration", (Type[])null, (Type[])null);
			if (!(methodInfo != null))
			{
				return null;
			}
			return AccessTools.EnumeratorMoveNext((MethodBase)methodInfo);
		}

		[HarmonyPrefix]
		private static void MausoleumPrefix(object __instance)
		{
			MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				LevelGenerator levelGenerator = MausoleumCompatPatchPlugin.MausoleumGetLevelGeneratorFromStateMachine(__instance);
				instance.MausoleumEnsureStartRoomList(levelGenerator);
			}
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> MausoleumTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(List<PrefabRef>), "get_Item", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(MausoleumCompatPatchPlugin), "MausoleumGetSafeStartRoomRef", (Type[])null, (Type[])null);
			if (methodInfo == null || methodInfo2 == null)
			{
				return instructions;
			}
			List<CodeInstruction> list = new List<CodeInstruction>();
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, methodInfo))
				{
					list.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null));
					list.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo2));
				}
				else
				{
					list.Add(instruction);
				}
			}
			return list;
		}
	}
	[HarmonyPatch]
	internal static class MausoleumCompatPatchGenerateMoveNextPatch
	{
		private static MethodBase? TargetMethod()
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(LevelGenerator), "Generate", (Type[])null, (Type[])null);
			if (!(methodInfo != null))
			{
				return null;
			}
			return AccessTools.EnumeratorMoveNext((MethodBase)methodInfo);
		}

		[HarmonyPrefix]
		private static void MausoleumPrefix(object __instance)
		{
			MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				LevelGenerator levelGenerator = MausoleumCompatPatchPlugin.MausoleumGetLevelGeneratorFromStateMachine(__instance);
				instance.MausoleumEnsureStartRoomList(levelGenerator);
			}
		}
	}
	[HarmonyPatch]
	internal static class MausoleumCompatPatchPrefabRefListGetItemPatch
	{
		private static MethodBase? TargetMethod()
		{
			return AccessTools.PropertyGetter(typeof(List<PrefabRef>), "Item");
		}

		[HarmonyPrefix]
		private static bool MausoleumPrefix(List<PrefabRef> __instance, int index, ref PrefabRef __result)
		{
			return MausoleumCompatPatchPlugin.MausoleumTryRecoverStartRoomFromListAccess(__instance, index, ref __result);
		}
	}
	[HarmonyPatch(typeof(PhysGrabHinge), "Awake")]
	internal static class MausoleumCompatPatchPhysGrabHingeAwakePatch
	{
		[HarmonyPrefix]
		private static void MausoleumPrefix(PhysGrabHinge __instance)
		{
			if (MausoleumCompatPatchPlugin.MausoleumIsCurrentLevel())
			{
				MausoleumCompatPatchPlugin.MausoleumEnsurePhysGrabHingeCompatibility(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "Start")]
	internal static class MausoleumCompatPatchExtractionPointStartPatch
	{
		[HarmonyPostfix]
		private static void MausoleumPostfix(ExtractionPoint __instance)
		{
			MausoleumCompatPatchPlugin.MausoleumEnsureExtractionPointCompatibility(__instance);
		}
	}
	[HarmonyPatch(typeof(Levels), "RegisterLevelWithGame")]
	internal static class MausoleumCompatPatchRegisterLevelPatch
	{
		[HarmonyPrefix]
		private static void MausoleumPrefix(Level level)
		{
			MausoleumCompatPatchPlugin.MausoleumEnsureLevelFallbackData(level);
			MausoleumCompatPatchPlugin.Instance?.MausoleumTryRepairLevel(level);
		}
	}
	[HarmonyPatch(typeof(Map), "AddDoor")]
	internal static class MausoleumCompatPatchMapAddDoorPatch
	{
		[HarmonyPrefix]
		private static bool MausoleumPrefix(Map __instance, DirtFinderMapDoor door, GameObject doorPrefab, ref GameObject __result)
		{
			if (!MausoleumCompatPatchPlugin.MausoleumIsCurrentLevel() || (Object)(object)door == (Object)null || (Object)(object)doorPrefab != (Object)null)
			{
				return true;
			}
			MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			__result = instance.MausoleumCreateFallbackDoorMapObject(__instance, door);
			return false;
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "NavMeshSetupRPC")]
	internal static class MausoleumCompatPatchNavMeshSetupPatch
	{
		[HarmonyPostfix]
		private static void MausoleumPostfix(LevelGenerator __instance)
		{
			MausoleumCompatPatchPlugin.Instance?.MausoleumRepairLevelPoints(__instance);
		}
	}
	[HarmonyPatch(typeof(LevelPoint), "NavMeshCheck")]
	internal static class MausoleumCompatPatchLevelPointNavMeshCheckPatch
	{
		[HarmonyPrefix]
		private static bool MausoleumPrefix(LevelPoint __instance, ref IEnumerator __result)
		{
			if (!MausoleumCompatPatchPlugin.MausoleumIsCurrentLevel())
			{
				return true;
			}
			MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			__result = instance.MausoleumSilentLevelPointCheck(__instance);
			return false;
		}
	}
	[HarmonyPatch]
	internal static class MausoleumCompatPatchUnityLogPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type type = AccessTools.TypeByName("UnityEngine.DebugLogHandler");
			if (!(type == null))
			{
				return from method in AccessTools.GetDeclaredMethods(type)
					where method.Name == "LogFormat"
					select method;
			}
			return Enumerable.Empty<MethodBase>();
		}

		[HarmonyPrefix]
		private static bool MausoleumPrefix(LogType logType, string format, object[] args)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return !MausoleumCompatPatchPlugin.MausoleumShouldSuppressUnityLog(logType, format, args);
		}
	}
}