Decompiled source of EntranceDoorUpgrader v1.0.0

BepInEx/plugins/EntranceDoorUpgrader/EntranceDoorUpgrader.dll

Decompiled 5 hours ago
using System;
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 GameNetcodeStuff;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EntranceDoorUpgrader")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EntranceDoorUpgrader")]
[assembly: AssemblyTitle("EntranceDoorUpgrader")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 EntranceDoorUpgrader
{
	internal enum MatchKind
	{
		StaticDoorByName,
		StaticDoorByStructure
	}
	internal sealed class DoorSite
	{
		internal EntranceTeleport Teleport;

		internal MatchKind Kind;

		internal readonly List<Transform> OldLeaves = new List<Transform>();

		internal readonly Dictionary<Transform, Transform> SlabOf = new Dictionary<Transform, Transform>();

		internal string Describe()
		{
			return $"'{((Object)((Component)Teleport).gameObject).name}' ({Kind}, {OldLeaves.Count} leaf/leaves)";
		}
	}
	internal static class DoorDetector
	{
		private const float AssociationRadius = 25f;

		internal static List<DoorSite> Find(Scene scene)
		{
			List<DoorSite> list = new List<DoorSite>();
			List<Transform> list2 = ((Scene)(ref scene)).GetRootGameObjects().SelectMany((GameObject r) => r.GetComponentsInChildren<Transform>(true)).ToList();
			List<EntranceTeleport> list3 = (from t in list2
				select ((Component)t).GetComponent<EntranceTeleport>() into e
				where (Object)(object)e != (Object)null && e.entranceId == 0 && e.isEntranceToBuilding
				select e).ToList();
			if (list3.Count == 0)
			{
				return list;
			}
			foreach (EntranceTeleport item in list3)
			{
				if ((Object)(object)item.thisEntranceAnimator != (Object)null)
				{
					continue;
				}
				DoorSite doorSite = new DoorSite
				{
					Teleport = item
				};
				bool byName;
				List<Transform> list4 = FindStaticLeaves(list2, item, out byName);
				if (list4.Count == 0)
				{
					continue;
				}
				doorSite.Kind = ((!byName) ? MatchKind.StaticDoorByStructure : MatchKind.StaticDoorByName);
				foreach (Transform item2 in list4)
				{
					Transform val = FindSlab(item2);
					if ((Object)(object)val == (Object)null)
					{
						Plugin.Log.LogWarning((object)("Static leaf '" + ((Object)item2).name + "' has no mesh child to align to; ignoring it."));
						continue;
					}
					doorSite.OldLeaves.Add(item2);
					doorSite.SlabOf[item2] = val;
				}
				if (doorSite.OldLeaves.Count != 0)
				{
					list.Add(doorSite);
				}
			}
			return list;
		}

		private static List<Transform> FindStaticLeaves(List<Transform> all, EntranceTeleport entrance, out bool byName)
		{
			byName = true;
			List<Transform> list = (from t in all
				where IsStaticLeafName(((Object)t).name)
				where IsStandaloneStatic(t)
				where NearEntrance(t, entrance)
				select t).ToList();
			if (list.Count > 0)
			{
				return list;
			}
			byName = false;
			return (from t in all
				where IsStandaloneStatic(t)
				where LooksLikeDoorLeaf(t)
				where NearEntrance(t, entrance)
				select t).ToList();
		}

		private static bool IsStaticLeafName(string name)
		{
			return name == "SteelDoorFake" || name.StartsWith("SteelDoorFake ", StringComparison.Ordinal);
		}

		private static bool IsStandaloneStatic(Transform t)
		{
			if (DoorUpgrader.IsOurs(t))
			{
				return false;
			}
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)((Component)val).GetComponent<Animator>() != (Object)null)
				{
					return false;
				}
				val = val.parent;
			}
			return (Object)(object)((Component)t).GetComponentInChildren<Animator>(true) == (Object)null;
		}

		private static bool LooksLikeDoorLeaf(Transform leaf)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			List<Transform> list = new List<Transform>();
			foreach (Transform item in leaf)
			{
				Transform val = item;
				if ((Object)(object)((Component)val).GetComponent<MeshFilter>() != (Object)null)
				{
					list.Add(val);
				}
			}
			if (list.Count < 2)
			{
				return false;
			}
			bool flag = false;
			bool flag2 = false;
			foreach (Transform item2 in list)
			{
				int num = 0;
				foreach (Transform item3 in item2)
				{
					Transform val2 = item3;
					if ((Object)(object)((Component)val2).GetComponent<MeshFilter>() != (Object)null)
					{
						num++;
					}
				}
				if (num >= 2)
				{
					flag2 = true;
				}
				else if (num == 1)
				{
					flag = true;
				}
			}
			return flag && flag2;
		}

		private static Transform FindSlab(Transform leaf)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_00b1: 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)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			Transform result = null;
			int num = -1;
			float num2 = -1f;
			foreach (Transform item in leaf)
			{
				Transform val = item;
				MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
				Mesh val2 = (((Object)(object)component != (Object)null) ? component.sharedMesh : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				int num3 = 0;
				foreach (Transform item2 in val)
				{
					Transform val3 = item2;
					if ((Object)(object)((Component)val3).GetComponent<MeshFilter>() != (Object)null)
					{
						num3++;
					}
				}
				Bounds bounds = val2.bounds;
				Vector3 extents = ((Bounds)(ref bounds)).extents;
				float num4 = extents.x * extents.y * extents.z;
				if (num3 > num || (num3 == num && num4 > num2))
				{
					num = num3;
					num2 = num4;
					result = val;
				}
			}
			return result;
		}

		private static bool NearEntrance(Transform leaf, EntranceTeleport entrance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Transform val = FindSlab(leaf);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			float num = Vector3.Distance(DoorUpgrader.MeshWorldCentre(val), ((Component)entrance).transform.position);
			if (num > 25f)
			{
				return false;
			}
			return true;
		}
	}
	internal static class DoorTemplate
	{
		internal const string BundleFileName = "hingesdoor.assetbundle";

		internal const string ContainerName = "OutsideEntranceVisualDoorsContainer";

		private static GameObject prefab;

		internal static bool HasTemplate => (Object)(object)prefab != (Object)null;

		internal static string Source { get; private set; } = "not loaded";

		internal static void Load()
		{
			try
			{
				string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				string text = Path.Combine(directoryName ?? ".", "hingesdoor.assetbundle");
				if (!File.Exists(text))
				{
					Plugin.Log.LogError((object)("'hingesdoor.assetbundle' is missing from " + directoryName + ". Nothing can be upgraded without it — it ships beside this DLL and holds the animated door. Rebuild it with 'Lethal Trudge/4. Export the animated door for EntranceDoorUpgrader'."));
					return;
				}
				AssetBundle val = AssetBundle.LoadFromFile(text);
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogError((object)("'" + text + "' could not be loaded as an AssetBundle. If it was built for a different platform or Unity version, rebuild it against the game's."));
					return;
				}
				GameObject[] source = val.LoadAllAssets<GameObject>();
				prefab = ((IEnumerable<GameObject>)source).FirstOrDefault((Func<GameObject, bool>)((GameObject g) => ((Object)g).name == "OutsideEntranceVisualDoorsContainer")) ?? source.FirstOrDefault();
				val.Unload(false);
				if ((Object)(object)prefab == (Object)null)
				{
					Plugin.Log.LogError((object)"'hingesdoor.assetbundle' contains no GameObject. Expected a prefab named 'OutsideEntranceVisualDoorsContainer'.");
					return;
				}
				Source = "hingesdoor.assetbundle";
				Animator component = prefab.GetComponent<Animator>();
				ManualLogSource log = Plugin.Log;
				string[] obj = new string[5]
				{
					"Loaded the animated door from hingesdoor.assetbundle: '",
					((Object)prefab).name,
					"', controller '",
					null,
					null
				};
				object obj2;
				if (component == null)
				{
					obj2 = null;
				}
				else
				{
					RuntimeAnimatorController runtimeAnimatorController = component.runtimeAnimatorController;
					obj2 = ((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null);
				}
				if (obj2 == null)
				{
					obj2 = "MISSING";
				}
				obj[3] = (string)obj2;
				obj[4] = "'.";
				log.LogInfo((object)string.Concat(obj));
				if ((Object)(object)component == (Object)null)
				{
					Plugin.Log.LogError((object)"The loaded door has no Animator, so it cannot be driven. The export is wrong; re-run step 4 in the Unity project.");
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)string.Format("Loading {0} threw; no door will be upgraded. {1}", "hingesdoor.assetbundle", arg));
			}
		}

		internal static GameObject Clone()
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(prefab);
			((Object)val).name = "OutsideEntranceVisualDoorsContainer";
			val.SetActive(true);
			return val;
		}
	}
	internal static class DoorUpgrader
	{
		internal const string AnchorName = "EntranceDoorUpgraderDoorAnchor";

		private const string InnerAnchorName = "EntranceDoorUpgraderDoorSlabAnchor";

		private const float MaxResidual = 0.5f;

		internal static bool IsOurs(Transform t)
		{
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name == "EntranceDoorUpgraderDoorAnchor" || ((Object)val).name == "EntranceDoorUpgraderDoorSlabAnchor")
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		internal static Vector3 MeshWorldCentre(Transform t)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			MeshFilter component = ((Component)t).GetComponent<MeshFilter>();
			Mesh val = (((Object)(object)component != (Object)null) ? component.sharedMesh : null);
			Vector3 result;
			if (!((Object)(object)val == (Object)null))
			{
				Matrix4x4 localToWorldMatrix = t.localToWorldMatrix;
				Bounds bounds = val.bounds;
				result = ((Matrix4x4)(ref localToWorldMatrix)).MultiplyPoint3x4(((Bounds)(ref bounds)).center);
			}
			else
			{
				result = t.position;
			}
			return result;
		}

		internal static bool TryUpgradeScene(Scene scene)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Scene)(ref scene)).IsValid() || !((Scene)(ref scene)).isLoaded)
			{
				return false;
			}
			List<DoorSite> list = DoorDetector.Find(scene);
			if (list.Count == 0)
			{
				return false;
			}
			foreach (DoorSite item in list)
			{
				try
				{
					if (!DoorTemplate.HasTemplate)
					{
						Plugin.Log.LogWarning((object)(item.Describe() + " in '" + ((Scene)(ref scene)).name + "' could take an animated door, but 'hingesdoor.assetbundle' was not loaded — see the error at startup. It ships beside the DLL; rebuild it with 'Lethal Trudge/4. Export the animated door for EntranceDoorUpgrader'."));
					}
					else
					{
						Upgrade(item, scene);
					}
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Upgrading {item.Describe()} threw; that entrance is unchanged. {arg}");
				}
			}
			return true;
		}

		private static void Upgrade(DoorSite site, Scene scene)
		{
			GameObject val = DoorTemplate.Clone();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			List<Transform> list = ContainerLeaves(val.transform);
			if (list.Count == 0)
			{
				Plugin.Log.LogError((object)"The acquired door has no leaf children; cannot seat it.");
				Object.Destroy((Object)(object)val);
				return;
			}
			Transform val2 = list.OrderBy(delegate(Transform leaf)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				Vector3 localPosition = leaf.localPosition;
				return ((Vector3)(ref localPosition)).sqrMagnitude;
			}).First();
			Transform val3 = SlabOfContainerLeaf(val2);
			if ((Object)(object)val3 == (Object)null)
			{
				Plugin.Log.LogError((object)("The acquired door's leaf '" + ((Object)val2).name + "' has no mesh child."));
				Object.Destroy((Object)(object)val);
				return;
			}
			Dictionary<Transform, Transform> dictionary = SeatOnStaticDoor(val.transform, list, val2, site);
			if (dictionary == null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			Animator component = val.GetComponent<Animator>();
			if ((Object)(object)component != (Object)null)
			{
				component.cullingMode = (AnimatorCullingMode)0;
			}
			int num = TransplantColliders(dictionary);
			foreach (Transform oldLeaf in site.OldLeaves)
			{
				((Component)oldLeaf).gameObject.SetActive(false);
			}
			WireEntrance(site.Teleport, component);
			ManualLogSource log = Plugin.Log;
			string[] obj = new string[11]
			{
				"Upgraded ",
				site.Describe(),
				" in '",
				((Scene)(ref scene)).name,
				"': ",
				$"{site.OldLeaves.Count} static leaf/leaves hidden, {num} collider(s) on the ",
				"animated door, animator '",
				null,
				null,
				null,
				null
			};
			object obj2;
			if (component == null)
			{
				obj2 = null;
			}
			else
			{
				RuntimeAnimatorController runtimeAnimatorController = component.runtimeAnimatorController;
				obj2 = ((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null);
			}
			if (obj2 == null)
			{
				obj2 = "MISSING";
			}
			obj[7] = (string)obj2;
			obj[8] = "' wired. Door from ";
			obj[9] = DoorTemplate.Source;
			obj[10] = ".";
			log.LogInfo((object)string.Concat(obj));
		}

		private static Dictionary<Transform, Transform> SeatOnStaticDoor(Transform clone, List<Transform> containerLeaves, Transform pivotLeaf, DoorSite site)
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			float num = float.MaxValue;
			foreach (Transform oldLeaf in site.OldLeaves)
			{
				Apply(clone, pivotLeaf, oldLeaf, site.SlabOf[oldLeaf]);
				float num2 = Residual(containerLeaves, site);
				if (num2 < num)
				{
					num = num2;
					val = oldLeaf;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("No usable alignment for " + site.Describe() + "; moon unchanged."));
				return null;
			}
			Apply(clone, pivotLeaf, val, site.SlabOf[val]);
			Dictionary<Transform, Transform> dictionary = PairLeaves(site, containerLeaves);
			float num3 = Residual(containerLeaves, site);
			float num4 = NeutraliseInheritedScale(clone);
			if (!Mathf.Approximately(num4, 1f))
			{
				num3 = Residual(containerLeaves, site);
			}
			Vector3 val2 = Vector3.zero;
			int num5 = 0;
			foreach (KeyValuePair<Transform, Transform> item in dictionary)
			{
				Transform val3 = SlabOfContainerLeaf(item.Key);
				if (!((Object)(object)val3 == (Object)null))
				{
					val2 += MeshWorldCentre(site.SlabOf[item.Value]) - MeshWorldCentre(val3);
					num5++;
				}
			}
			if (num5 > 0 && ((Vector3)(ref val2)).sqrMagnitude > 1E-06f)
			{
				val2 /= (float)num5;
				clone.position += val2;
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<Transform, Transform> item2 in dictionary)
			{
				Transform val4 = SlabOfContainerLeaf(item2.Key);
				if (!((Object)(object)val4 == (Object)null))
				{
					float num6 = Quaternion.Angle(site.SlabOf[item2.Value].rotation, val4.rotation);
					if (num6 > 15f)
					{
						Plugin.Log.LogWarning((object)($"Animated leaf '{((Object)item2.Key).name}' sits {num6:F0}° from the static leaf it " + "replaces, so it may hinge from the wrong side. Its position is correct."));
					}
				}
			}
			float num7 = Residual(containerLeaves, site);
			if (num7 > 0.5f)
			{
				Plugin.Log.LogWarning((object)("Could not seat an animated door on " + site.Describe() + ": after per-leaf alignment a " + $"door slab is still {num7:F3} m from the static one (limit {0.5f} m). The " + $"moon is unchanged. Rigid fit was {num3:F3} m; {dictionary.Count} of " + $"{containerLeaves.Count} animated leaf/leaves paired with {site.OldLeaves.Count} " + $"static one(s); {list.Count} moved. An unchanged residual means a leaf was never " + "paired, not that the alignment failed."));
				return null;
			}
			return dictionary;
		}

		private static float NeutraliseInheritedScale(Transform clone)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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)
			Vector3 val = (((Object)(object)clone.parent == (Object)null) ? Vector3.one : clone.parent.lossyScale);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(Mathf.Abs(val.x), Mathf.Abs(val.y), Mathf.Abs(val.z));
			if (val2.x < 0.0001f || val2.y < 0.0001f || val2.z < 0.0001f)
			{
				Plugin.Log.LogWarning((object)($"The static door's chain has a degenerate scale {val}; leaving the door's own " + "scale alone. It may render at the wrong size."));
				return 1f;
			}
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(1f / val2.x, 1f / val2.y, 1f / val2.z);
			float x = val3.x;
			if (Mathf.Abs(x - 1f) < 0.01f && Mathf.Abs(val3.y - 1f) < 0.01f && Mathf.Abs(val3.z - 1f) < 0.01f)
			{
				return 1f;
			}
			clone.localScale = val3;
			return x;
		}

		private static void Apply(Transform clone, Transform pivotLeaf, Transform oldLeaf, Transform oldSlab)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Transform val = EnsureAnchor(clone, "EntranceDoorUpgraderDoorAnchor", oldLeaf.parent);
			Copy(val, oldLeaf);
			Transform val2 = EnsureAnchor(clone, "EntranceDoorUpgraderDoorSlabAnchor", val);
			Copy(val2, oldSlab);
			clone.SetParent(val2, false);
			clone.localPosition = Vector3.zero;
			clone.localRotation = Quaternion.Inverse(pivotLeaf.localRotation);
			clone.localScale = Vector3.one;
		}

		private static Transform EnsureAnchor(Transform clone, string name, Transform parent)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			Transform parent2 = clone.parent;
			while ((Object)(object)parent2 != (Object)null)
			{
				if (!(((Object)parent2).name != name))
				{
					if ((Object)(object)parent2.parent != (Object)(object)parent)
					{
						parent2.SetParent(parent, false);
					}
					return parent2;
				}
				parent2 = parent2.parent;
			}
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			return val.transform;
		}

		private static void Copy(Transform destination, Transform source)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			destination.localPosition = source.localPosition;
			destination.localRotation = source.localRotation;
			destination.localScale = source.localScale;
		}

		private static float Residual(List<Transform> containerLeaves, DoorSite site)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			foreach (Transform containerLeaf in containerLeaves)
			{
				Transform val = SlabOfContainerLeaf(containerLeaf);
				if (!((Object)(object)val == (Object)null))
				{
					Vector3 here = MeshWorldCentre(val);
					float num2 = site.OldLeaves.Select((Transform old) => Vector3.Distance(here, MeshWorldCentre(site.SlabOf[old]))).DefaultIfEmpty(float.MaxValue).Min();
					num = Mathf.Max(num, num2);
				}
			}
			return num;
		}

		private static int TransplantColliders(Dictionary<Transform, Transform> pairing)
		{
			int num = 0;
			foreach (KeyValuePair<Transform, Transform> item in pairing)
			{
				Collider[] componentsInChildren = ((Component)item.Value).GetComponentsInChildren<Collider>(true);
				foreach (Collider val in componentsInChildren)
				{
					string relative = RelativePath(item.Value, ((Component)val).transform);
					Transform val2 = EnsurePath(item.Key, item.Value, relative);
					if (!((Object)(object)val2 == (Object)null) && CopyCollider(val, ((Component)val2).gameObject))
					{
						num++;
					}
				}
			}
			return num;
		}

		private static Dictionary<Transform, Transform> PairLeaves(DoorSite site, List<Transform> containerLeaves)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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)
			Dictionary<Transform, Transform> dictionary = new Dictionary<Transform, Transform>();
			HashSet<Transform> hashSet = new HashSet<Transform>();
			foreach (Transform containerLeaf in containerLeaves)
			{
				Transform val = SlabOfContainerLeaf(containerLeaf);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Vector3 val2 = MeshWorldCentre(val);
				Transform val3 = null;
				float num = float.MaxValue;
				foreach (Transform oldLeaf in site.OldLeaves)
				{
					if (!hashSet.Contains(oldLeaf))
					{
						float num2 = Vector3.Distance(val2, MeshWorldCentre(site.SlabOf[oldLeaf]));
						if (num2 < num)
						{
							num = num2;
							val3 = oldLeaf;
						}
					}
				}
				if (!((Object)(object)val3 == (Object)null))
				{
					hashSet.Add(val3);
					dictionary[containerLeaf] = val3;
				}
			}
			return dictionary;
		}

		private static bool CopyCollider(Collider source, GameObject destination)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			BoxCollider val = (BoxCollider)(object)((source is BoxCollider) ? source : null);
			if (val == null)
			{
				SphereCollider val2 = (SphereCollider)(object)((source is SphereCollider) ? source : null);
				if (val2 == null)
				{
					CapsuleCollider val3 = (CapsuleCollider)(object)((source is CapsuleCollider) ? source : null);
					if (val3 == null)
					{
						MeshCollider val4 = (MeshCollider)(object)((source is MeshCollider) ? source : null);
						if (val4 != null)
						{
							MeshCollider val5 = destination.AddComponent<MeshCollider>();
							val5.sharedMesh = val4.sharedMesh;
							val5.convex = val4.convex;
							Finish((Collider)(object)val5, (Collider)(object)val4);
							return true;
						}
						Plugin.Log.LogWarning((object)("Collider type " + ((object)source).GetType().Name + " on '" + ((Object)source).name + "' is not handled and was not copied; that part of the doorway will not collide."));
						return false;
					}
					CapsuleCollider val6 = destination.AddComponent<CapsuleCollider>();
					val6.center = val3.center;
					val6.radius = val3.radius;
					val6.height = val3.height;
					val6.direction = val3.direction;
					Finish((Collider)(object)val6, (Collider)(object)val3);
					return true;
				}
				SphereCollider val7 = destination.AddComponent<SphereCollider>();
				val7.center = val2.center;
				val7.radius = val2.radius;
				Finish((Collider)(object)val7, (Collider)(object)val2);
				return true;
			}
			BoxCollider val8 = destination.AddComponent<BoxCollider>();
			val8.center = val.center;
			val8.size = val.size;
			Finish((Collider)(object)val8, (Collider)(object)val);
			return true;
			static void Finish(Collider copy, Collider original)
			{
				copy.isTrigger = original.isTrigger;
				copy.sharedMaterial = original.sharedMaterial;
				copy.enabled = original.enabled;
			}
		}

		private static void WireEntrance(EntranceTeleport entrance, Animator animator)
		{
			entrance.thisEntranceAnimator = animator;
			InteractTrigger component = ((Component)entrance).GetComponent<InteractTrigger>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogWarning((object)("'" + ((Object)((Component)entrance).gameObject).name + "' has no InteractTrigger, so nothing can tell the door to open. It will be placed and silent."));
				return;
			}
			EntranceTeleport teleport = entrance;
			((UnityEvent<PlayerControllerB>)(object)component.onInteractEarly).AddListener((UnityAction<PlayerControllerB>)delegate
			{
				Guarded(delegate
				{
					teleport.StartOpeningEntrance();
				});
			});
			((UnityEvent<PlayerControllerB>)(object)component.onStopInteract).AddListener((UnityAction<PlayerControllerB>)delegate
			{
				Guarded(delegate
				{
					teleport.FinishOpeningEntrance(true);
				});
			});
		}

		private static void Guarded(Action action)
		{
			try
			{
				action();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Door listener threw: {arg}");
			}
		}

		private static List<Transform> ContainerLeaves(Transform container)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			List<Transform> list = new List<Transform>();
			foreach (Transform item in container)
			{
				Transform val = item;
				if (val.childCount > 0 && (Object)(object)((Component)val).GetComponentInChildren<MeshFilter>(true) != (Object)null)
				{
					list.Add(val);
				}
			}
			return list;
		}

		private static Transform SlabOfContainerLeaf(Transform leaf)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_00b1: 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)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			Transform result = null;
			int num = -1;
			float num2 = -1f;
			foreach (Transform item in leaf)
			{
				Transform val = item;
				MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
				Mesh val2 = (((Object)(object)component != (Object)null) ? component.sharedMesh : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				int num3 = 0;
				foreach (Transform item2 in val)
				{
					Transform val3 = item2;
					if ((Object)(object)((Component)val3).GetComponent<MeshFilter>() != (Object)null)
					{
						num3++;
					}
				}
				Bounds bounds = val2.bounds;
				Vector3 extents = ((Bounds)(ref bounds)).extents;
				float num4 = extents.x * extents.y * extents.z;
				if (num3 > num || (num3 == num && num4 > num2))
				{
					num = num3;
					num2 = num4;
					result = val;
				}
			}
			return result;
		}

		private static string RelativePath(Transform root, Transform node)
		{
			List<string> list = new List<string>();
			Transform val = node;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}

		private static Transform EnsurePath(Transform newRoot, Transform oldRoot, string relative)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(relative))
			{
				return newRoot;
			}
			Transform val = oldRoot;
			Transform val2 = newRoot;
			string[] array = relative.Split('/');
			foreach (string text in array)
			{
				Transform val3 = val.Find(text);
				if ((Object)(object)val3 == (Object)null)
				{
					return null;
				}
				Transform val4 = val2.Find(text);
				if ((Object)(object)val4 == (Object)null)
				{
					float num = ScaleRatio(val, val2);
					GameObject val5 = new GameObject(text);
					val5.transform.SetParent(val2, false);
					val5.transform.localPosition = val3.localPosition * num;
					val5.transform.localRotation = val3.localRotation;
					val5.transform.localScale = val3.localScale * num;
					val5.layer = ((Component)val3).gameObject.layer;
					try
					{
						val5.tag = ((Component)val3).gameObject.tag;
					}
					catch (UnityException)
					{
					}
					val4 = val5.transform;
				}
				val = val3;
				val2 = val4;
			}
			return val2;
		}

		private static float ScaleRatio(Transform source, Transform destination)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Vector3 lossyScale = source.lossyScale;
			float magnitude = ((Vector3)(ref lossyScale)).magnitude;
			lossyScale = destination.lossyScale;
			float magnitude2 = ((Vector3)(ref lossyScale)).magnitude;
			if (magnitude2 < 1E-06f || magnitude < 1E-06f)
			{
				return 1f;
			}
			return magnitude / magnitude2;
		}
	}
	[BepInPlugin("com.luth.entrancedoorupgrader", "EntranceDoorUpgrader", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "com.luth.entrancedoorupgrader";

		public const string Name = "EntranceDoorUpgrader";

		public const string Version = "1.0.0";

		private static readonly HashSet<int> seenScenes = new HashSet<int>();

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			DoorTemplate.Load();
			SceneManager.sceneLoaded += OnSceneLoaded;
			int sceneCount = SceneManager.sceneCount;
			for (int i = 0; i < sceneCount; i++)
			{
				Consider(SceneManager.GetSceneAt(i));
			}
			Log.LogInfo((object)("EntranceDoorUpgrader 1.0.0 loaded. No Harmony patches. Door: " + DoorTemplate.Source + "."));
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Consider(scene);
		}

		private static void Consider(Scene scene)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!((Scene)(ref scene)).IsValid() || !((Scene)(ref scene)).isLoaded || !seenScenes.Add(((Scene)(ref scene)).handle))
			{
				return;
			}
			try
			{
				DoorUpgrader.TryUpgradeScene(scene);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Handling scene '{((Scene)(ref scene)).name}' threw; the moon keeps its own doors. {arg}");
			}
		}
	}
}