Decompiled source of Woodland Mansion Fix v1.0.1

WoodlandMansionCompatPatch.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using REPOLib;
using REPOLib.Modules;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;

[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.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WoodlandMansionCompatPatch")]
[assembly: AssemblyTitle("WoodlandMansionCompatPatch")]
[assembly: AssemblyVersion("1.0.0.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 WoodlandMansionCompatPatch
{
	[BepInPlugin("empress.repo.woodlandmansioncompatpatch", "Empress Woodland Mansion Compat Patch", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class WoodlandMansionCompatPatchPlugin : BaseUnityPlugin
	{
		private sealed class WoodlandPrefabBuckets
		{
			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.woodlandmansioncompatpatch";

		internal const string PluginName = "Empress Woodland Mansion Compat Patch";

		internal const string PluginVersion = "1.0.0";

		private const string WoodlandBundleFileName = "Woodland_Mansion.repobundle";

		private const string WoodlandLevelName = "Level - Woodland Mansion";

		private const string WoodlandLevelResourcePath = "Woodland Mansion";

		private const float WoodlandLevelPointCheckRadius = 0.5f;

		private const float WoodlandLevelPointRepairRadius = 2f;

		private const float WoodlandLevelPointConnectDistance = 15f;

		private const float WoodlandLevelPointConnectForwardDot = -0.8f;

		private const float WoodlandLevelPointConnectApproachDot = 0.8f;

		private const float WoodlandLevelPointValidationDelay = 0.5f;

		private static readonly string[] WoodlandStartRoomNames = new string[1] { "Module - Woodland Mansion - SR - 1 - Entrance" };

		private static readonly string[] WoodlandNormal1Names = new string[10] { "Module - Woodland Mansion - N - 1 - Allium Room", "Module - Woodland Mansion - N - 1 - Birch Arch Room", "Module - Woodland Mansion - N - 1 - Birch Pillar Room", "Module - Woodland Mansion - N - 1 - Checkerboard Room", "Module - Woodland Mansion - N - 1 - Office", "Module - Woodland Mansion - N - 1 - Sapling Farm Room", "Module - Woodland Mansion - N - 1 - Small Dining Room", "Module - Woodland Mansion - N - 1 - Small Library Room", "Module - Woodland Mansion - N - 1 - Spider Room", "Module - Woodland Mansion - N - 1 - X-Room" };

		private static readonly string[] WoodlandPassage1Names = new string[1] { "Module - Woodland Mansion - DE - 1 - Small Storage Room" };

		private static readonly string[] WoodlandDeadEnd1Names = new string[7] { "Module - Woodland Mansion - DE - 1 - Flower Room", "Module - Woodland Mansion - DE - 1 - Forge Room", "Module - Woodland Mansion - DE - 1 - Gray Banner Room", "Module - Woodland Mansion - DE - 1 - Pumpkin King Room", "Module - Woodland Mansion - DE - 1 - Single Bed Bedroom", "Module - Woodland Mansion - DE - 1 - Wheat Farm", "Module - Woodland Mansion - DE - 1 - White Tulip Room" };

		private static readonly string[] WoodlandExtraction1Names = new string[1] { "Module - Woodland Mansion - E - 1 - Arena Room" };

		private readonly Harmony _woodlandHarmony = new Harmony("empress.repo.woodlandmansioncompatpatch");

		private AssetBundle? _woodlandBundle;

		private bool _woodlandRepairApplied;

		private bool _woodlandRepairQueued;

		private bool _woodlandLoggedMissingBundle;

		private bool _woodlandLoggedMissingPrefabs;

		private bool _woodlandLoggedDoorMapFallback;

		private bool _woodlandLoggedRepairAttempt;

		internal static WoodlandMansionCompatPatchPlugin? 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 += WoodlandHandleBundlesLoaded;
			SceneManager.activeSceneChanged += WoodlandOnActiveSceneChanged;
			_woodlandHarmony.PatchAll();
			WoodlandPatchUnityWarningFilter();
			if ((Object)(object)RunManager.instance != (Object)null)
			{
				((MonoBehaviour)this).StartCoroutine(WoodlandRepairWhenReady());
			}
		}

		private void OnDestroy()
		{
			BundleLoader.OnAllBundlesLoaded -= WoodlandHandleBundlesLoaded;
			SceneManager.activeSceneChanged -= WoodlandOnActiveSceneChanged;
			_woodlandHarmony.UnpatchSelf();
			if (Instance == this)
			{
				Instance = null;
			}
		}

		private void WoodlandOnActiveSceneChanged(Scene current, Scene next)
		{
			_woodlandRepairApplied = false;
			_woodlandRepairQueued = false;
			_woodlandLoggedRepairAttempt = false;
			if ((Object)(object)RunManager.instance != (Object)null)
			{
				((MonoBehaviour)this).StartCoroutine(WoodlandRepairWhenReady());
			}
		}

		private void WoodlandHandleBundlesLoaded()
		{
			if (!_woodlandRepairQueued && !_woodlandRepairApplied)
			{
				_woodlandRepairQueued = true;
				((MonoBehaviour)this).StartCoroutine(WoodlandRepairWhenReady());
			}
		}

		private void WoodlandPatchUnityWarningFilter()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("UnityEngine.DebugLogHandler");
			if (!(type == null))
			{
				MethodInfo methodInfo = AccessTools.Method(type, "LogFormat", new Type[4]
				{
					typeof(LogType),
					typeof(Object),
					typeof(string),
					typeof(object[])
				}, (Type[])null);
				if (methodInfo != null)
				{
					_woodlandHarmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(WoodlandMansionCompatPatchPlugin), "WoodlandSuppressMissingScriptWarningPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				MethodInfo methodInfo2 = AccessTools.Method(type, "LogFormat", new Type[5]
				{
					typeof(LogType),
					typeof(LogOption),
					typeof(Object),
					typeof(string),
					typeof(object[])
				}, (Type[])null);
				if (methodInfo2 != null)
				{
					_woodlandHarmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(WoodlandMansionCompatPatchPlugin), "WoodlandSuppressMissingScriptWarningPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		private IEnumerator WoodlandRepairWhenReady()
		{
			yield return null;
			for (int attempt = 0; attempt < 120; attempt++)
			{
				if (_woodlandRepairApplied)
				{
					break;
				}
				if (WoodlandTryRepairLevel())
				{
					break;
				}
				yield return null;
			}
			_woodlandRepairQueued = false;
		}

		internal bool WoodlandTryRepairCurrentLevel()
		{
			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 WoodlandTryRepairLevel(list);
		}

		private bool WoodlandTryRepairLevel(IEnumerable<Level>? candidates = null)
		{
			if (_woodlandRepairApplied)
			{
				return true;
			}
			Level val = WoodlandFindLevel(candidates) ?? WoodlandFindLevel(Levels.AllLevels);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (!_woodlandLoggedRepairAttempt)
			{
				_woodlandLoggedRepairAttempt = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Empress Woodland Mansion Compat Patch is rebuilding Level - Woodland Mansion from the original bundle.");
			}
			AssetBundle val2 = WoodlandGetBundle();
			if ((Object)(object)val2 == (Object)null)
			{
				if (!_woodlandLoggedMissingBundle)
				{
					_woodlandLoggedMissingBundle = true;
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Empress Woodland Mansion Compat Patch could not locate the Woodland Mansion bundle.");
				}
				return false;
			}
			_woodlandLoggedMissingBundle = false;
			WoodlandPrefabBuckets woodlandPrefabBuckets = WoodlandCollectPrefabs(val2);
			if (woodlandPrefabBuckets.StartRooms.Count == 0 || woodlandPrefabBuckets.TotalModuleCount == 0)
			{
				if (!_woodlandLoggedMissingPrefabs)
				{
					_woodlandLoggedMissingPrefabs = true;
					((BaseUnityPlugin)this).Logger.LogError((object)"Empress Woodland Mansion Compat Patch could not rebuild the Woodland Mansion prefab lists from the original bundle.");
				}
				return false;
			}
			_woodlandLoggedMissingPrefabs = false;
			WoodlandApplyHideFlags((Object)(object)val2);
			WoodlandApplyHideFlags((Object)(object)val);
			WoodlandEnsureLevelFallbackData(val);
			WoodlandRegisterLevelObjects(val);
			val.StartRooms = WoodlandRegisterPrefabs(val, "StartRoom", woodlandPrefabBuckets.StartRooms);
			val.ModulesNormal1 = WoodlandRegisterPrefabs(val, "Normal", woodlandPrefabBuckets.Normal1);
			val.ModulesPassage1 = WoodlandRegisterPrefabs(val, "Passage", woodlandPrefabBuckets.Passage1);
			val.ModulesDeadEnd1 = WoodlandRegisterPrefabs(val, "DeadEnd", woodlandPrefabBuckets.DeadEnd1);
			val.ModulesExtraction1 = WoodlandRegisterPrefabs(val, "Extraction", woodlandPrefabBuckets.Extraction1);
			val.ModulesNormal2 = WoodlandRegisterPrefabs(val, "Normal", woodlandPrefabBuckets.Normal2);
			val.ModulesPassage2 = WoodlandRegisterPrefabs(val, "Passage", woodlandPrefabBuckets.Passage2);
			val.ModulesDeadEnd2 = WoodlandRegisterPrefabs(val, "DeadEnd", woodlandPrefabBuckets.DeadEnd2);
			val.ModulesExtraction2 = WoodlandRegisterPrefabs(val, "Extraction", woodlandPrefabBuckets.Extraction2);
			val.ModulesNormal3 = WoodlandRegisterPrefabs(val, "Normal", woodlandPrefabBuckets.Normal3);
			val.ModulesPassage3 = WoodlandRegisterPrefabs(val, "Passage", woodlandPrefabBuckets.Passage3);
			val.ModulesDeadEnd3 = WoodlandRegisterPrefabs(val, "DeadEnd", woodlandPrefabBuckets.DeadEnd3);
			val.ModulesExtraction3 = WoodlandRegisterPrefabs(val, "Extraction", woodlandPrefabBuckets.Extraction3);
			_woodlandRepairApplied = WoodlandCountValidPrefabRefs(val.StartRooms) > 0 && WoodlandCountValidModules(val) > 0;
			if (_woodlandRepairApplied)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Woodland Mansion Compat Patch repaired {((Object)val).name} with {WoodlandCountValidPrefabRefs(val.StartRooms)} start rooms and {WoodlandCountValidModules(val)} modules.");
			}
			return _woodlandRepairApplied;
		}

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

		private AssetBundle? WoodlandGetBundle()
		{
			if ((Object)(object)_woodlandBundle != (Object)null)
			{
				return _woodlandBundle;
			}
			foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles())
			{
				if (WoodlandBundleMatches(allLoadedAssetBundle))
				{
					_woodlandBundle = allLoadedAssetBundle;
					return _woodlandBundle;
				}
			}
			string text = Directory.GetFiles(Paths.PluginPath, "Woodland_Mansion.repobundle", SearchOption.AllDirectories).FirstOrDefault();
			if (string.IsNullOrWhiteSpace(text))
			{
				return null;
			}
			_woodlandBundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)_woodlandBundle != (Object)null)
			{
				return _woodlandBundle;
			}
			foreach (AssetBundle allLoadedAssetBundle2 in AssetBundle.GetAllLoadedAssetBundles())
			{
				if (WoodlandBundleMatches(allLoadedAssetBundle2))
				{
					_woodlandBundle = allLoadedAssetBundle2;
					return _woodlandBundle;
				}
			}
			return _woodlandBundle;
		}

		private static bool WoodlandBundleMatches(AssetBundle? bundle)
		{
			if ((Object)(object)bundle == (Object)null)
			{
				return false;
			}
			try
			{
				if (!string.IsNullOrWhiteSpace(((Object)bundle).name) && (((Object)bundle).name.IndexOf("woodland", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)bundle).name.IndexOf("mansion", StringComparison.OrdinalIgnoreCase) >= 0))
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				if (bundle.GetAllAssetNames().Any((string assetName) => assetName.IndexOf("woodland mansion", StringComparison.OrdinalIgnoreCase) >= 0 || assetName.IndexOf("repolib level.asset", StringComparison.OrdinalIgnoreCase) >= 0))
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				Level[] array = bundle.LoadAllAssets<Level>();
				for (int i = 0; i < array.Length; i++)
				{
					if (WoodlandIsWoodlandLevel(array[i]))
					{
						return true;
					}
				}
			}
			catch
			{
			}
			try
			{
				GameObject[] array2 = bundle.LoadAllAssets<GameObject>();
				foreach (GameObject val in array2)
				{
					if (!((Object)(object)val == (Object)null) && ((Object)val).name.StartsWith("Module - Woodland Mansion -", StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static WoodlandPrefabBuckets WoodlandCollectPrefabs(AssetBundle bundle)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);
			StartRoom[] array = bundle.LoadAllAssets<StartRoom>();
			foreach (StartRoom val in array)
			{
				WoodlandAddAssetByName(dictionary, ((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null);
			}
			Module[] array2 = bundle.LoadAllAssets<Module>();
			foreach (Module val2 in array2)
			{
				WoodlandAddAssetByName(dictionary, ((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null);
			}
			GameObject[] array3 = bundle.LoadAllAssets<GameObject>();
			foreach (GameObject prefab in array3)
			{
				WoodlandAddAssetByName(dictionary, prefab);
			}
			if (!dictionary.Keys.Any((string name) => name.StartsWith("Module - Woodland Mansion -", StringComparison.OrdinalIgnoreCase)))
			{
				array = Resources.FindObjectsOfTypeAll<StartRoom>();
				Scene scene;
				foreach (StartRoom val3 in array)
				{
					if (!((Object)(object)val3 == (Object)null))
					{
						scene = ((Component)val3).gameObject.scene;
						if (!((Scene)(ref scene)).IsValid())
						{
							WoodlandAddAssetByName(dictionary, ((Component)val3).gameObject);
						}
					}
				}
				array2 = Resources.FindObjectsOfTypeAll<Module>();
				foreach (Module val4 in array2)
				{
					if (!((Object)(object)val4 == (Object)null))
					{
						scene = ((Component)val4).gameObject.scene;
						if (!((Scene)(ref scene)).IsValid())
						{
							WoodlandAddAssetByName(dictionary, ((Component)val4).gameObject);
						}
					}
				}
				array3 = Resources.FindObjectsOfTypeAll<GameObject>();
				foreach (GameObject val5 in array3)
				{
					if (!((Object)(object)val5 == (Object)null))
					{
						scene = val5.scene;
						if (!((Scene)(ref scene)).IsValid())
						{
							WoodlandAddAssetByName(dictionary, val5);
						}
					}
				}
			}
			return new WoodlandPrefabBuckets
			{
				StartRooms = WoodlandResolvePrefabs(dictionary, WoodlandStartRoomNames),
				Normal1 = WoodlandResolvePrefabs(dictionary, WoodlandNormal1Names),
				Passage1 = WoodlandResolvePrefabs(dictionary, WoodlandPassage1Names),
				DeadEnd1 = WoodlandResolvePrefabs(dictionary, WoodlandDeadEnd1Names),
				Extraction1 = WoodlandResolvePrefabs(dictionary, WoodlandExtraction1Names),
				Normal2 = new List<GameObject>(),
				Passage2 = new List<GameObject>(),
				DeadEnd2 = new List<GameObject>(),
				Extraction2 = new List<GameObject>(),
				Normal3 = new List<GameObject>(),
				Passage3 = new List<GameObject>(),
				DeadEnd3 = new List<GameObject>(),
				Extraction3 = new List<GameObject>()
			};
		}

		private static void WoodlandAddAssetByName(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> WoodlandResolvePrefabs(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 WoodlandRegisterLevelObjects(Level level)
		{
			if ((Object)(object)level.ConnectObject != (Object)null)
			{
				WoodlandRegisterNetworkPrefab("Level/" + (level.ResourcePath ?? "Woodland Mansion") + "/Other/" + ((Object)level.ConnectObject).name, level.ConnectObject);
			}
			if ((Object)(object)level.BlockObject != (Object)null)
			{
				WoodlandRegisterNetworkPrefab("Level/" + (level.ResourcePath ?? "Woodland Mansion") + "/Other/" + ((Object)level.BlockObject).name, level.BlockObject);
			}
		}

		private static List<PrefabRef> WoodlandRegisterPrefabs(Level level, string moduleTypeName, IEnumerable<GameObject> prefabs)
		{
			List<PrefabRef> list = new List<PrefabRef>();
			foreach (GameObject prefab in prefabs)
			{
				PrefabRef val = WoodlandRegisterNetworkPrefab("Level/" + ((Object)level).name + "/" + moduleTypeName + "/" + ((Object)prefab).name, prefab);
				if (val != null)
				{
					list.Add(val);
				}
			}
			return list;
		}

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

		private static PrefabRef? WoodlandGetRegisteredPrefabRef(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 WoodlandPreparePrefab(GameObject prefab)
		{
			WoodlandApplyHideFlags((Object)(object)prefab);
			WoodlandAssignFallbackAudioMixerGroups(prefab);
			WoodlandAssignFallbackPhysAttributes(prefab);
			WoodlandAssignFallbackHingeData(prefab);
		}

		private static void WoodlandAssignFallbackAudioMixerGroups(GameObject prefab)
		{
			AudioMixerGroup val = WoodlandGetFallbackAudioMixerGroup();
			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 WoodlandAssignFallbackPhysAttributes(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 = WoodlandCreateFallbackPhysAttribute(mass);
				}
			}
		}

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

		internal static void WoodlandEnsurePhysGrabHingeCompatibility(PhysGrabHinge? hinge)
		{
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Expected O, but got Unknown
			PhysGrabHinge hinge2 = hinge;
			if ((Object)(object)hinge2 == (Object)null)
			{
				return;
			}
			PhysGrabHinge val = hinge2;
			if (val.moveLoop == null)
			{
				val.moveLoop = WoodlandCreateFallbackSound();
			}
			if ((Object)(object)hinge2.hingeAudio == (Object)null)
			{
				hinge2.hingeAudio = WoodlandCreateFallbackHingeAudio();
			}
			else
			{
				WoodlandNormalizeSound(hinge2.hingeAudio.moveLoop);
				WoodlandNormalizeSound(hinge2.hingeAudio.moveLoopEnd);
				WoodlandNormalizeSound(hinge2.hingeAudio.Close);
				WoodlandNormalizeSound(hinge2.hingeAudio.CloseHeavy);
				WoodlandNormalizeSound(hinge2.hingeAudio.Open);
				WoodlandNormalizeSound(hinge2.hingeAudio.OpenHeavy);
				WoodlandNormalizeSound(hinge2.hingeAudio.HingeBreak);
			}
			val = hinge2;
			if (val.audioSource == null)
			{
				val.audioSource = ((Component)hinge2).GetComponent<AudioSource>() ?? ((Component)hinge2).gameObject.AddComponent<AudioSource>();
			}
			hinge2.audioSource.playOnAwake = false;
			if ((Object)(object)hinge2.audioSource.outputAudioMixerGroup == (Object)null)
			{
				hinge2.audioSource.outputAudioMixerGroup = WoodlandGetFallbackAudioMixerGroup();
			}
			if ((Object)(object)((Component)hinge2).GetComponent<HingeJoint>() == (Object)null)
			{
				((Component)hinge2).gameObject.AddComponent<HingeJoint>();
			}
			if ((Object)(object)((Component)hinge2).GetComponent<PhysGrabObjectImpactDetector>() == (Object)null)
			{
				((Component)hinge2).gameObject.AddComponent<PhysGrabObjectImpactDetector>();
			}
			if ((Object)(object)hinge2.hingePoint == (Object)null)
			{
				Rigidbody val2 = ((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)val2 != (Object)null)
				{
					hinge2.hingePoint = ((Component)val2).transform;
				}
				else if (((Component)hinge2).transform.childCount > 0)
				{
					hinge2.hingePoint = ((Component)hinge2).transform.GetChild(0);
				}
				else
				{
					GameObject val3 = new GameObject("Woodland Mansion Patch Hinge Point");
					val3.transform.SetParent(((Component)hinge2).transform, false);
					WoodlandApplyHideFlags((Object)(object)val3);
					hinge2.hingePoint = val3.transform;
				}
			}
			val = hinge2;
			if (val.wallTagHinges == null)
			{
				val.wallTagHinges = Array.Empty<PhysGrabHinge>();
			}
			val = hinge2;
			if (val.wallTagObjects == null)
			{
				val.wallTagObjects = Array.Empty<GameObject>();
			}
			val = hinge2;
			if (val.lowPassTriggers == null)
			{
				val.lowPassTriggers = Array.Empty<LowPassTrigger>();
			}
		}

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

		private static Sound WoodlandCreateFallbackSound()
		{
			//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();
			WoodlandNormalizeSound(val);
			return val;
		}

		private static void WoodlandNormalizeSound(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 WoodlandCreateFallbackPhysAttribute(float mass)
		{
			PhysAttribute obj = ScriptableObject.CreateInstance<PhysAttribute>();
			obj.mass = Mathf.Max(0.01f, mass);
			WoodlandApplyHideFlags((Object)(object)obj);
			return obj;
		}

		private static AudioMixerGroup? WoodlandGetFallbackAudioMixerGroup()
		{
			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 WoodlandCountModules(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 int WoodlandCountValidModules(Level level)
		{
			return WoodlandCountValidPrefabRefs(level.ModulesNormal1) + WoodlandCountValidPrefabRefs(level.ModulesPassage1) + WoodlandCountValidPrefabRefs(level.ModulesDeadEnd1) + WoodlandCountValidPrefabRefs(level.ModulesExtraction1) + WoodlandCountValidPrefabRefs(level.ModulesNormal2) + WoodlandCountValidPrefabRefs(level.ModulesPassage2) + WoodlandCountValidPrefabRefs(level.ModulesDeadEnd2) + WoodlandCountValidPrefabRefs(level.ModulesExtraction2) + WoodlandCountValidPrefabRefs(level.ModulesNormal3) + WoodlandCountValidPrefabRefs(level.ModulesPassage3) + WoodlandCountValidPrefabRefs(level.ModulesDeadEnd3) + WoodlandCountValidPrefabRefs(level.ModulesExtraction3);
		}

		private static int WoodlandCountValidPrefabRefs(IEnumerable<PrefabRef>? prefabRefs)
		{
			if (prefabRefs == null)
			{
				return 0;
			}
			int num = 0;
			foreach (PrefabRef prefabRef in prefabRefs)
			{
				if (prefabRef != null && (!string.IsNullOrWhiteSpace(prefabRef.ResourcePath) || (Object)(object)prefabRef.Prefab != (Object)null))
				{
					num++;
				}
			}
			return num;
		}

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

		internal static bool WoodlandShouldSuppressMissingScriptWarning(LogType logType, string? format, object[]? args)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)logType != 2 || !WoodlandIsCurrentLevel())
			{
				return false;
			}
			if (WoodlandIsMissingScriptWarning(format))
			{
				return true;
			}
			if (args == null || args.Length == 0 || string.IsNullOrWhiteSpace(format))
			{
				return false;
			}
			try
			{
				return WoodlandIsMissingScriptWarning(string.Format(format, args));
			}
			catch
			{
				return false;
			}
		}

		internal static bool WoodlandShouldSuppressMissingScriptWarning(LogEventArgs? eventArgs)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			if (eventArgs == null || (int)eventArgs.Level != 4 || !WoodlandIsCurrentLevel())
			{
				return false;
			}
			if (!WoodlandIsUnityLogSource(eventArgs.Source))
			{
				return false;
			}
			if (eventArgs.Data is string message)
			{
				return WoodlandIsMissingScriptWarning(message);
			}
			return WoodlandIsMissingScriptWarning(eventArgs.Data?.ToString());
		}

		private static bool WoodlandIsUnityLogSource(ILogSource? source)
		{
			if (source != null)
			{
				return string.Equals(source.SourceName, "Unity Log", StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private static bool WoodlandIsMissingScriptWarning(string? message)
		{
			if (string.IsNullOrWhiteSpace(message))
			{
				return false;
			}
			if (message.IndexOf("The referenced script", StringComparison.Ordinal) >= 0)
			{
				return message.IndexOf("missing", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

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

		internal static bool WoodlandIsWoodlandLevel(Level? level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (!string.Equals(((Object)level).name, "Level - Woodland Mansion", StringComparison.OrdinalIgnoreCase) && !string.Equals(level.ResourcePath, "Woodland Mansion", StringComparison.OrdinalIgnoreCase) && (string.IsNullOrWhiteSpace(((Object)level).name) || ((Object)level).name.IndexOf("woodland", StringComparison.OrdinalIgnoreCase) < 0 || ((Object)level).name.IndexOf("mansion", StringComparison.OrdinalIgnoreCase) < 0))
			{
				if (!string.IsNullOrWhiteSpace(level.ResourcePath) && level.ResourcePath.IndexOf("woodland", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return level.ResourcePath.IndexOf("mansion", StringComparison.OrdinalIgnoreCase) >= 0;
				}
				return false;
			}
			return true;
		}

		internal static void WoodlandEnsureLevelFallbackData(Level? level)
		{
			if (WoodlandIsWoodlandLevel(level))
			{
				level.ResourcePath = (string.IsNullOrWhiteSpace(level.ResourcePath) ? "Woodland Mansion" : level.ResourcePath);
				level.NarrativeName = (string.IsNullOrWhiteSpace(level.NarrativeName) ? "Woodland Mansion" : level.NarrativeName);
				level.ModuleAmount = Mathf.Max(level.ModuleAmount, 8);
				level.PassageMaxAmount = Mathf.Max(level.PassageMaxAmount, 2);
				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 && WoodlandTryGetFallbackAmbience(out LevelAmbience ambience))
				{
					level.AmbiencePresets.Add(ambience);
				}
			}
		}

		private static bool WoodlandTryGetFallbackAmbience(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 void WoodlandEnsureExtractionPointCompatibility(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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			if ((Object)(object)extractionPoint == (Object)null || !WoodlandIsCurrentLevel())
			{
				return;
			}
			if ((Object)(object)extractionPoint.extractionArea == (Object)null)
			{
				GameObject val = GameObject.CreatePrimitive((PrimitiveType)2);
				((Object)val).name = "Woodland Mansion 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);
				WoodlandApplyHideFlags((Object)(object)val);
				extractionPoint.extractionArea = val;
			}
			if ((Object)(object)extractionPoint.grossUp == (Object)null)
			{
				GameObject val2 = new GameObject("Woodland Mansion Patch GrossUp");
				val2.transform.SetParent(((Component)extractionPoint).transform, false);
				val2.SetActive(false);
				WoodlandApplyHideFlags((Object)(object)val2);
				extractionPoint.grossUp = val2;
			}
		}

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

		private static bool WoodlandRepairLevelPoint(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;
			WoodlandRepairLevelPointRoom(levelPoint);
			return true;
		}

		private static bool WoodlandRepairLevelPointRoom(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 WoodlandSilentLevelPointCheck(LevelPoint levelPoint)
		{
			if (!((Object)(object)levelPoint == (Object)null))
			{
				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 (WoodlandIsCurrentLevel())
				{
					WoodlandRepairLevelPoint(levelPoint);
					WoodlandRepairLevelPointRoom(levelPoint);
					WoodlandRepairLevelPointConnections(levelPoint, LevelGenerator.Instance?.LevelPathPoints);
				}
			}
		}

		private static void WoodlandRepairLevelPointConnections(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++)
			{
				WoodlandAddLevelPointConnection(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 (WoodlandCanConnectLevelPoints(levelPoint, allLevelPoint, currentBestDistance, out var distance))
				{
					val = allLevelPoint;
					currentBestDistance = distance;
				}
			}
			WoodlandAddLevelPointConnection(levelPoint, val);
			WoodlandAddLevelPointConnection(val, levelPoint);
		}

		private static bool WoodlandCanConnectLevelPoints(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 WoodlandAddLevelPointConnection(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 WoodlandCreateFallbackDoorMapObject(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 = WoodlandInstantiateFallbackDoorMapObject(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 (!_woodlandLoggedDoorMapFallback)
			{
				_woodlandLoggedDoorMapFallback = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Empress Woodland Mansion Compat Patch injected fallback minimap door markers for missing Woodland Mansion door prefabs.");
			}
			return val;
		}

		private static GameObject WoodlandInstantiateFallbackDoorMapObject(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;
			}
			WoodlandApplyHideFlags((Object)(object)val);
			return val;
		}

		private static void WoodlandApplyHideFlags(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(LevelGenerator), "StartRoomGeneration")]
	internal static class WoodlandMansionCompatPatchStartRoomGenerationPatch
	{
		[HarmonyPrefix]
		private static void WoodlandPrefix()
		{
			WoodlandMansionCompatPatchPlugin.Instance?.WoodlandTryRepairCurrentLevel();
		}
	}
	[HarmonyPatch(typeof(PhysGrabHinge), "Awake")]
	internal static class WoodlandMansionCompatPatchPhysGrabHingeAwakePatch
	{
		[HarmonyPrefix]
		private static void WoodlandPrefix(PhysGrabHinge __instance)
		{
			if (WoodlandMansionCompatPatchPlugin.WoodlandIsCurrentLevel())
			{
				WoodlandMansionCompatPatchPlugin.WoodlandEnsurePhysGrabHingeCompatibility(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "Start")]
	internal static class WoodlandMansionCompatPatchExtractionPointStartPatch
	{
		[HarmonyPostfix]
		private static void WoodlandPostfix(ExtractionPoint __instance)
		{
			WoodlandMansionCompatPatchPlugin.WoodlandEnsureExtractionPointCompatibility(__instance);
		}
	}
	[HarmonyPatch(typeof(Levels), "RegisterLevelWithGame")]
	internal static class WoodlandMansionCompatPatchRegisterLevelPatch
	{
		[HarmonyPrefix]
		private static void WoodlandPrefix(Level level)
		{
			WoodlandMansionCompatPatchPlugin.WoodlandEnsureLevelFallbackData(level);
		}
	}
	[HarmonyPatch(typeof(Map), "AddDoor")]
	internal static class WoodlandMansionCompatPatchMapAddDoorPatch
	{
		[HarmonyPrefix]
		private static bool WoodlandPrefix(Map __instance, DirtFinderMapDoor door, GameObject doorPrefab, ref GameObject __result)
		{
			if (!WoodlandMansionCompatPatchPlugin.WoodlandIsCurrentLevel() || (Object)(object)door == (Object)null || (Object)(object)doorPrefab != (Object)null)
			{
				return true;
			}
			WoodlandMansionCompatPatchPlugin instance = WoodlandMansionCompatPatchPlugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			__result = instance.WoodlandCreateFallbackDoorMapObject(__instance, door);
			return false;
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "NavMeshSetupRPC")]
	internal static class WoodlandMansionCompatPatchNavMeshSetupPatch
	{
		[HarmonyPostfix]
		private static void WoodlandPostfix(LevelGenerator __instance)
		{
			WoodlandMansionCompatPatchPlugin.Instance?.WoodlandRepairLevelPoints(__instance);
		}
	}
	[HarmonyPatch(typeof(LevelPoint), "NavMeshCheck")]
	internal static class WoodlandMansionCompatPatchLevelPointNavMeshCheckPatch
	{
		[HarmonyPrefix]
		private static bool WoodlandPrefix(LevelPoint __instance, ref IEnumerator __result)
		{
			if (!WoodlandMansionCompatPatchPlugin.WoodlandIsCurrentLevel())
			{
				return true;
			}
			WoodlandMansionCompatPatchPlugin instance = WoodlandMansionCompatPatchPlugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			__result = instance.WoodlandSilentLevelPointCheck(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(UnityLogListener), "LogEvent")]
	internal static class WoodlandMansionCompatPatchUnityLogListenerPatch
	{
		[HarmonyPrefix]
		private static bool WoodlandPrefix(LogEventArgs eventArgs)
		{
			return !WoodlandMansionCompatPatchPlugin.WoodlandShouldSuppressMissingScriptWarning(eventArgs);
		}
	}
	[HarmonyPatch(typeof(UnityLogSource), "UnityLogMessageHandler")]
	internal static class WoodlandMansionCompatPatchUnityLogSourcePatch
	{
		[HarmonyPrefix]
		private static bool WoodlandPrefix(LogEventArgs eventArgs)
		{
			return !WoodlandMansionCompatPatchPlugin.WoodlandShouldSuppressMissingScriptWarning(eventArgs);
		}
	}
	[HarmonyPatch(typeof(Logger), "InternalLogEvent")]
	internal static class WoodlandMansionCompatPatchInternalLogEventPatch
	{
		[HarmonyPrefix]
		private static bool WoodlandPrefix(LogEventArgs eventArgs)
		{
			return !WoodlandMansionCompatPatchPlugin.WoodlandShouldSuppressMissingScriptWarning(eventArgs);
		}
	}
}