Decompiled source of Anomalies v0.1.0

Anomalies.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("AnomaliesTest")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Anomalies")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+a08a5c55af92db409c2f3fa50a5f84874e31f555")]
[assembly: AssemblyProduct("Anomalies")]
[assembly: AssemblyTitle("Anomalies")]
[assembly: AssemblyVersion("0.1.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 Anomalies
{
	internal class Blink : MonoBehaviour
	{
		private static float until;

		private static float length;

		private static Texture2D black;

		internal static void Run(float seconds)
		{
			length = seconds;
			until = Time.unscaledTime + seconds;
		}

		private void OnGUI()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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)
			float num = until - Time.unscaledTime;
			if (!(num <= 0f))
			{
				if ((Object)(object)black == (Object)null)
				{
					black = new Texture2D(1, 1);
					black.SetPixel(0, 0, Color.black);
					black.Apply();
				}
				float num2 = 1f - num / Mathf.Max(0.01f, length);
				float num3 = ((num2 < 0.25f) ? 1f : (1f - (num2 - 0.25f) / 0.75f));
				GUI.color = new Color(1f, 1f, 1f, num3);
				GUI.depth = -1000;
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)black);
				GUI.color = Color.white;
			}
		}
	}
	internal static class Cloner
	{
		internal sealed class Copy
		{
			public GameObject Root;

			public Transform[] RealT;

			public Transform[] CopyT;

			public readonly List<(Animator real, Animator copy)> Animators = new List<(Animator, Animator)>();

			public Renderer[] RealR;

			public Renderer[] CopyR;

			public Light[] RealL;

			public Light[] CopyL;

			public ReflectionProbe[] RealP;

			public ReflectionProbe[] CopyP;

			public Transform Find(Transform real)
			{
				for (int i = 0; i < RealT.Length; i++)
				{
					if ((Object)(object)RealT[i] == (Object)(object)real)
					{
						return CopyT[i];
					}
				}
				return null;
			}
		}

		private static readonly HashSet<string> KeepScripts = new HashSet<string>
		{
			typeof(HDAdditionalLightData).FullName,
			typeof(HDAdditionalReflectionData).FullName,
			typeof(DecalProjector).FullName,
			typeof(Volume).FullName,
			typeof(LensFlareComponentSRP).FullName,
			typeof(LocalVolumetricFog).FullName,
			typeof(AudioReverbTrigger).FullName
		};

		private static readonly HashSet<string> UntagThese = new HashSet<string> { "AINode", "CaveNode", "OutsideAINode", "PoweredLight", "EnemySpawn", "MapPropsContainer" };

		internal static Copy Make(GameObject src, Transform parent, Vector3 pos, Quaternion rot, HashSet<Animator> keepAnimators)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0020: 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)
			GameObject val = new GameObject("Anomalies.CloneHolder");
			val.SetActive(false);
			val.transform.SetParent(parent, false);
			GameObject val2 = Object.Instantiate<GameObject>(src, pos, rot, val.transform);
			((Object)val2).name = ((Object)src).name + " (anomaly)";
			Copy copy = new Copy
			{
				Root = val2
			};
			copy.RealT = src.GetComponentsInChildren<Transform>(true);
			copy.CopyT = val2.GetComponentsInChildren<Transform>(true);
			copy.RealR = src.GetComponentsInChildren<Renderer>(true);
			copy.CopyR = val2.GetComponentsInChildren<Renderer>(true);
			copy.RealL = src.GetComponentsInChildren<Light>(true);
			copy.CopyL = val2.GetComponentsInChildren<Light>(true);
			copy.RealP = src.GetComponentsInChildren<ReflectionProbe>(true);
			copy.CopyP = val2.GetComponentsInChildren<ReflectionProbe>(true);
			Animator[] componentsInChildren = src.GetComponentsInChildren<Animator>(true);
			Animator[] componentsInChildren2 = val2.GetComponentsInChildren<Animator>(true);
			HashSet<Animator> hashSet = new HashSet<Animator>();
			if (componentsInChildren.Length == componentsInChildren2.Length)
			{
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if (keepAnimators != null && keepAnimators.Contains(componentsInChildren[i]))
					{
						copy.Animators.Add((componentsInChildren[i], componentsInChildren2[i]));
						hashSet.Add(componentsInChildren2[i]);
					}
				}
			}
			Strip(val2, hashSet);
			Transform[] copyT = copy.CopyT;
			foreach (Transform val3 in copyT)
			{
				if ((Object)(object)val3 != (Object)null && UntagThese.Contains(((Component)val3).tag))
				{
					((Component)val3).gameObject.tag = "Untagged";
				}
			}
			val2.transform.SetParent(parent, true);
			Object.Destroy((Object)(object)val);
			return copy;
		}

		private static void Strip(GameObject go, HashSet<Animator> keptAnim)
		{
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			AudioReverbTrigger[] componentsInChildren = go.GetComponentsInChildren<AudioReverbTrigger>(true);
			foreach (AudioReverbTrigger val in componentsInChildren)
			{
				hashSet.Add(((Component)val).gameObject);
			}
			for (int j = 0; j < 4; j++)
			{
				bool flag = false;
				Component[] componentsInChildren2 = go.GetComponentsInChildren<Component>(true);
				foreach (Component val2 in componentsInChildren2)
				{
					if (!((Object)(object)val2 == (Object)null) && ShouldRemove(val2, j, hashSet, keptAnim))
					{
						try
						{
							Object.DestroyImmediate((Object)(object)val2);
							flag = true;
						}
						catch (Exception)
						{
						}
					}
				}
				if (!flag && j > 0)
				{
					break;
				}
			}
		}

		private static bool ShouldRemove(Component comp, int pass, HashSet<GameObject> reverbObjects, HashSet<Animator> keptAnim)
		{
			if (!(comp is Transform))
			{
				MonoBehaviour val = (MonoBehaviour)(object)((comp is MonoBehaviour) ? comp : null);
				if (val != null)
				{
					return !KeepScripts.Contains(((object)val).GetType().FullName);
				}
				if (pass == 0)
				{
					return false;
				}
				if (!(comp is MeshFilter) && !(comp is Renderer) && !(comp is LODGroup) && !(comp is Light) && !(comp is ReflectionProbe) && !(comp is ParticleSystem) && !(comp is AudioSource) && !(comp is AudioLowPassFilter) && !(comp is AudioHighPassFilter) && !(comp is AudioReverbFilter) && !(comp is AudioEchoFilter) && !(comp is AudioDistortionFilter) && !(comp is AudioChorusFilter) && !(comp is LensFlare))
				{
					Collider val2 = (Collider)(object)((comp is Collider) ? comp : null);
					if (val2 == null)
					{
						Animator val3 = (Animator)(object)((comp is Animator) ? comp : null);
						if (val3 != null)
						{
							return !keptAnim.Contains(val3);
						}
						return true;
					}
					if (val2.isTrigger)
					{
						return !reverbObjects.Contains(((Component)val2).gameObject);
					}
					return false;
				}
				return false;
			}
			return false;
		}

		internal static void CopyPose(Transform[] real, Transform[] copy)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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)
			if (real == null || copy == null || real.Length != copy.Length)
			{
				return;
			}
			for (int i = 1; i < real.Length; i++)
			{
				if (!((Object)(object)real[i] == (Object)null) && !((Object)(object)copy[i] == (Object)null))
				{
					copy[i].localPosition = real[i].localPosition;
					copy[i].localRotation = real[i].localRotation;
					copy[i].localScale = real[i].localScale;
				}
			}
		}
	}
	internal enum Kind
	{
		LoopRoom,
		LongWayBack,
		DriftRoom,
		ShyLights
	}
	internal static class Day
	{
		internal static readonly List<Kind> Today = new List<Kind>();

		internal static bool PreferDoorForTest;

		private static readonly (Kind kind, int weight)[] Weights = new(Kind, int)[2]
		{
			(Kind.LoopRoom, 35),
			(Kind.LongWayBack, 25)
		};

		internal static string TestShape;

		internal static List<Kind> Draw(int seed, float dayChance)
		{
			Random rng;
			return Draw(seed, dayChance, out rng);
		}

		internal static List<Kind> Draw(int seed, float dayChance, out Random rng)
		{
			List<Kind> list = new List<Kind>();
			rng = new Random(seed ^ 0xA11);
			bool flag = rng.NextDouble() < (double)dayChance;
			int num = rng.Next(1, 3);
			List<(Kind, int)> list2 = Weights.ToList();
			for (int i = 0; i < num; i++)
			{
				if (list2.Count <= 0)
				{
					break;
				}
				int maxValue = list2.Sum<(Kind, int)>(((Kind kind, int weight) w) => w.weight);
				int num2 = rng.Next(maxValue);
				int num3;
				for (num3 = 0; num2 >= list2[num3].Item2; num3++)
				{
					num2 -= list2[num3].Item2;
				}
				list.Add(list2[num3].Item1);
				list2.RemoveAt(num3);
			}
			if (!flag)
			{
				list.Clear();
			}
			return list;
		}

		internal static void OnLevelReady()
		{
			Today.Clear();
			RoundManager instance = RoundManager.Instance;
			StartOfRound instance2 = StartOfRound.Instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				RuntimeDungeon dungeonGenerator = instance.dungeonGenerator;
				if (dungeonGenerator == null)
				{
					obj = null;
				}
				else
				{
					DungeonGenerator generator = dungeonGenerator.Generator;
					obj = ((generator != null) ? generator.CurrentDungeon : null);
				}
			}
			Dungeon val = (Dungeon)obj;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null || (Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"no dungeon: no anomalies today");
				return;
			}
			int randomMapSeed = instance2.randomMapSeed;
			Today.AddRange(Draw(randomMapSeed, Plugin.DayChance.Value, out var rng));
			if (Plugin.ForceLoopRoom.Value && !Today.Contains(Kind.LoopRoom))
			{
				Today.Insert(0, Kind.LoopRoom);
			}
			if (Plugin.ForceLongWayBack.Value && !Today.Contains(Kind.LongWayBack))
			{
				Today.Add(Kind.LongWayBack);
			}
			Plugin.Log.LogInfo((object)string.Format("seed {0}: anomalies today: {1}", randomMapSeed, (Today.Count == 0) ? "none" : string.Join(", ", Today)));
			if (Today.Contains(Kind.LoopRoom))
			{
				List<(Tile, Doorway)> list = LoopCandidates(val);
				if (PreferDoorForTest)
				{
					List<(Tile, Doorway)> list2 = list.Where(((Tile, Doorway) td) => (Object)(object)td.Item2.UsedDoorPrefabInstance != (Object)null && td.Item2.UsedDoorPrefabInstance.GetComponentsInChildren<SpawnSyncedObject>(true).Any((SpawnSyncedObject o) => (Object)(object)o.spawnPrefab != (Object)null && (Object)(object)o.spawnPrefab.GetComponentInChildren<DoorLock>(true) != (Object)null)).ToList();
					Plugin.Log.LogInfo((object)$"test: {list2.Count} of {list.Count} Loop Room candidates have a spawned door");
					if (list2.Count > 0)
					{
						list = list2;
					}
				}
				if (list.Count == 0)
				{
					Plugin.Log.LogInfo((object)"no room fits a Loop Room today");
				}
				else
				{
					var (tile, door) = list[rng.Next(list.Count)];
					LoopRoom.Build(tile, door, val, randomMapSeed);
				}
			}
			if (!Today.Contains(Kind.LongWayBack))
			{
				return;
			}
			Tile loop = (((Object)(object)LoopRoom.Instance != (Object)null) ? LoopRoom.Instance.Real : null);
			List<(Tile, Doorway, Doorway)> list3 = (from h in HallCandidates(val)
				where (Object)(object)loop == (Object)null || ((Object)(object)h.Item2.ConnectedDoorway.Tile != (Object)(object)loop && (Object)(object)h.Item3.ConnectedDoorway.Tile != (Object)(object)loop)
				select h).ToList();
			if (list3.Count == 0)
			{
				Plugin.Log.LogInfo((object)"no hallway fits a Long Way Back today");
				return;
			}
			bool straight;
			List<(Tile, Doorway, Doorway)> list4 = list3.Where(((Tile, Doorway, Doorway) h) => LongWayBack.PairShape(h.Item1, h.Item2, h.Item3, out straight) == null && straight).ToList();
			if (list4.Count > 0)
			{
				list3 = list4;
			}
			var (hall, e, x) = list3[rng.Next(list3.Count)];
			LongWayBack.Build(hall, e, x, val, randomMapSeed);
		}

		internal static List<(Tile, Doorway)> LoopCandidates(Dungeon dungeon)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			List<(Tile, Doorway)> list = new List<(Tile, Doorway)>();
			Tile val = ((dungeon.MainPathTiles.Count > 0) ? dungeon.MainPathTiles[0] : null);
			foreach (Tile allTile in dungeon.AllTiles)
			{
				if ((Object)(object)allTile == (Object)null || (Object)(object)allTile == (Object)(object)val || allTile.UsedDoorways.Count != 1)
				{
					continue;
				}
				Bounds bounds = allTile.Bounds;
				float num = Mathf.Min(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z);
				float num2 = Mathf.Max(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z);
				if (!(num < 5f) && !(num2 > 40f) && !(((Bounds)(ref bounds)).size.y > 20f) && !Special(allTile) && ((Component)allTile).GetComponentsInChildren<Light>(true).Length != 0)
				{
					Doorway val2 = allTile.UsedDoorways[0];
					if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.ConnectedDoorway == (Object)null) && !HasSecureDoor(val2) && !HasSecureDoor(val2.ConnectedDoorway))
					{
						list.Add((allTile, val2));
					}
				}
			}
			return list;
		}

		internal static List<(Tile, Doorway, Doorway)> HallCandidates(Dungeon dungeon)
		{
			//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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			List<(Tile, Doorway, Doorway)> list = new List<(Tile, Doorway, Doorway)>();
			Dictionary<string, int> why = new Dictionary<string, int>();
			List<string> detail = new List<string>();
			Tile cur = null;
			Tile val = ((dungeon.MainPathTiles.Count > 0) ? dungeon.MainPathTiles[0] : null);
			int num = 0;
			int num2 = 0;
			foreach (Tile allTile in dungeon.AllTiles)
			{
				if ((Object)(object)allTile == (Object)null || (Object)(object)allTile == (Object)(object)val)
				{
					continue;
				}
				cur = allTile;
				List<Doorway> list2 = allTile.UsedDoorways.Where((Doorway d) => (Object)(object)d != (Object)null && (Object)(object)d.ConnectedDoorway != (Object)null).ToList();
				if (list2.Count < 2)
				{
					No("dead end");
					continue;
				}
				Bounds bounds = allTile.Bounds;
				if (((Bounds)(ref bounds)).size.y > 12f)
				{
					No("taller than 12 m", $"h {((Bounds)(ref bounds)).size.y:F1}");
					continue;
				}
				Doorway e = null;
				Doorway x = null;
				bool flag = false;
				string text = null;
				for (int num3 = 0; num3 < list2.Count; num3++)
				{
					if (flag)
					{
						break;
					}
					for (int num4 = num3 + 1; num4 < list2.Count; num4++)
					{
						if (flag)
						{
							break;
						}
						Doorway val2 = list2[num3];
						Doorway val3 = list2[num4];
						bool straight;
						string text2 = LongWayBack.PairShape(allTile, val2, val3, out straight);
						if (text2 != null)
						{
							text = text ?? text2;
						}
						else if (straight)
						{
							e = val2;
							x = val3;
							flag = true;
						}
						else if ((Object)(object)e == (Object)null)
						{
							e = val2;
							x = val3;
						}
					}
				}
				if ((Object)(object)e == (Object)null)
				{
					No("no straight or corner pair", text);
					continue;
				}
				if (TestShape == "straight" && !flag)
				{
					No("test: not straight");
					continue;
				}
				if (TestShape == "corner" && flag)
				{
					No("test: not a corner");
					continue;
				}
				if (list2.Where((Doorway d) => (Object)(object)d != (Object)(object)e && (Object)(object)d != (Object)(object)x).ToList().Any((Doorway d) => !d.BlockerPrefabWeights.Any((GameObjectWeight w) => w != null && (Object)(object)w.GameObject != (Object)null)))
				{
					No("side opening has no blocker");
					continue;
				}
				if (((Component)allTile).GetComponentsInChildren<Light>(true).Length == 0)
				{
					No("no light");
					continue;
				}
				if (Special(allTile) || Special(e.ConnectedDoorway.Tile) || Special(x.ConnectedDoorway.Tile))
				{
					No("entrance/apparatus/breaker");
					continue;
				}
				if ((Object)(object)e.ConnectedDoorway.Tile == (Object)(object)x.ConnectedDoorway.Tile)
				{
					No("both ends one room");
					continue;
				}
				if (FrameDoor(e) || FrameDoor(e.ConnectedDoorway) || FrameDoor(x) || FrameDoor(x.ConnectedDoorway))
				{
					No("door built into a frame");
					continue;
				}
				if (flag)
				{
					num++;
				}
				else
				{
					num2++;
				}
				list.Add((allTile, e, x));
			}
			if (Plugin.VerboseLog.Value)
			{
				Plugin.Log.LogInfo((object)(string.Format("[Long] flow {0}: {1} tiles, {2} fit ({3} straight, {4} corner); rejected: ", ((Object)(object)dungeon.DungeonFlow != (Object)null) ? ((Object)dungeon.DungeonFlow).name : "?", dungeon.AllTiles.Count, list.Count, num, num2) + ((why.Count == 0) ? "none" : string.Join(", ", from k in why
					orderby k.Value descending
					select $"{k.Key} {k.Value}"))));
				if (detail.Count > 0)
				{
					Plugin.Log.LogInfo((object)("[Long] rejects: " + string.Join("; ", detail)));
				}
			}
			return list;
			void No(string r, string m = null)
			{
				why.TryGetValue(r, out var value);
				why[r] = value + 1;
				if ((Object)(object)cur != (Object)null && cur.UsedDoorways.Count >= 2)
				{
					detail.Add(((Object)cur).name.Replace("(Clone)", "") + " " + r + ((m != null) ? (" (" + m + ")") : ""));
				}
			}
		}

		private static bool Special(Tile t)
		{
			if ((Object)(object)((Component)t).GetComponentInChildren<EntranceTeleport>(false) != (Object)null || (Object)(object)((Component)t).GetComponentInChildren<LungProp>(false) != (Object)null || (Object)(object)((Component)t).GetComponentInChildren<BreakerBox>(false) != (Object)null)
			{
				return true;
			}
			return ((Component)t).GetComponentsInChildren<SpawnSyncedObject>(false).Any((SpawnSyncedObject s) => (Object)(object)s.spawnPrefab != (Object)null && ((Object)(object)s.spawnPrefab.GetComponentInChildren<BreakerBox>(true) != (Object)null || (Object)(object)s.spawnPrefab.GetComponentInChildren<EntranceTeleport>(true) != (Object)null || (Object)(object)s.spawnPrefab.GetComponentInChildren<LungProp>(true) != (Object)null));
		}

		private static bool FrameDoor(Doorway d)
		{
			GameObject usedDoorPrefabInstance = d.UsedDoorPrefabInstance;
			if ((Object)(object)usedDoorPrefabInstance != (Object)null)
			{
				if (!((Object)(object)usedDoorPrefabInstance.GetComponentInChildren<DoorLock>(false) != (Object)null))
				{
					return usedDoorPrefabInstance.GetComponentsInChildren<TerminalAccessibleObject>(false).Any((TerminalAccessibleObject t) => t.isBigDoor);
				}
				return true;
			}
			return false;
		}

		private static bool HasSecureDoor(Doorway d)
		{
			GameObject usedDoorPrefabInstance = d.UsedDoorPrefabInstance;
			if ((Object)(object)usedDoorPrefabInstance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)usedDoorPrefabInstance.GetComponentInChildren<TerminalAccessibleObject>(true) != (Object)null)
			{
				return true;
			}
			return usedDoorPrefabInstance.GetComponentsInChildren<SpawnSyncedObject>(true).Any((SpawnSyncedObject s) => (Object)(object)s.spawnPrefab != (Object)null && (Object)(object)s.spawnPrefab.GetComponentInChildren<TerminalAccessibleObject>(true) != (Object)null);
		}
	}
	[HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")]
	internal static class FinishGeneratingLevelPatch
	{
		private static void Postfix(RoundManager __instance)
		{
			((MonoBehaviour)__instance).StartCoroutine(Later());
		}

		private static IEnumerator Later()
		{
			yield return null;
			try
			{
				Day.OnLevelReady();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("setting up today's anomalies failed: " + ex));
			}
		}
	}
	internal class LongWayBack : MonoBehaviour
	{
		internal sealed class EndDoor
		{
			internal bool AtX;

			internal Transform Spawner;

			internal Transform Root;

			internal AnimatedObjectTrigger Anim;

			internal readonly List<Cloner.Copy> Copies = new List<Cloner.Copy>();

			internal bool Open
			{
				get
				{
					if ((Object)(object)Anim != (Object)null)
					{
						return Anim.boolValue;
					}
					return false;
				}
			}
		}

		internal enum Phase
		{
			Idle,
			InPocket,
			Cooldown
		}

		internal static LongWayBack Instance;

		internal static bool Hold;

		internal Tile Real;

		internal Bounds RealBounds;

		internal Doorway DoorE;

		internal Doorway DoorX;

		internal Vector3 PE;

		internal Vector3 PX;

		internal Vector3 Axis;

		internal Vector3 Right;

		internal Vector3 Step;

		internal Vector3 Offset;

		internal Vector3 OutE;

		internal Vector3 OutX;

		internal float Length;

		internal int Copies;

		internal bool Ring;

		internal float Turn;

		internal Vector3 Pivot;

		internal Vector3 Bend;

		internal readonly List<Doorway> Sides = new List<Doorway>();

		internal const int RingCopies = 4;

		private Bounds pocketBounds;

		internal bool BlinkOutE;

		internal bool BlinkOutX;

		internal readonly List<EndDoor> EndDoors = new List<EndDoor>();

		private float nextDoorBind;

		private bool shutLogged;

		private GameObject pocket;

		private readonly List<(Animator real, Animator copy)> lights = new List<(Animator, Animator)>();

		private readonly List<GameObject> standIns = new List<GameObject>();

		private readonly List<Cloner.Copy> hallCopies = new List<Cloner.Copy>();

		private Transform cullProxy;

		internal Phase State;

		internal int Swaps;

		internal int LastSwapFrame;

		internal int Trips;

		internal string LastSwap = "";

		internal int Dir;

		internal int WayInSide = -1;

		internal int EntrySide = -1;

		internal int RingCur;

		internal int RingProgress;

		private bool ringCameOn;

		private float enteredAt;

		private float cooldownUntil;

		private float activeSince = -1f;

		private float lastNear = -100f;

		private bool wasIn;

		private static void V(string s)
		{
			if (Plugin.VerboseLog.Value)
			{
				Plugin.Log.LogInfo((object)("[Long] " + s));
			}
		}

		private static Vector3 Flat(Vector3 v)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			v.y = 0f;
			return v;
		}

		internal static string PairShape(Tile t, Doorway a, Doorway c, out bool straight)
		{
			//IL_0009: 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)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0094: 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_009c: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			straight = false;
			Vector3 val = ((Component)c).transform.position - ((Component)a).transform.position;
			if (Mathf.Abs(val.y) > 0.3f)
			{
				return "not level";
			}
			val.y = 0f;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 1f)
			{
				return "doorways together";
			}
			Vector3 val2 = val / magnitude;
			Vector3 val3 = Flat(((Component)a).transform.forward);
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			val3 = Flat(((Component)c).transform.forward);
			Vector3 normalized2 = ((Vector3)(ref val3)).normalized;
			Bounds bounds = t.Bounds;
			if (Vector3.Dot(normalized, -val2) >= 0.95f && Vector3.Dot(normalized2, val2) >= 0.95f)
			{
				if (magnitude < 6f || magnitude > 40f)
				{
					return $"straight {magnitude:F1} m";
				}
				Vector3 val4 = Vector3.Cross(Vector3.up, val2);
				float num = Mathf.Abs(val4.x) * ((Bounds)(ref bounds)).size.x + Mathf.Abs(val4.z) * ((Bounds)(ref bounds)).size.z;
				if (num > 10f)
				{
					return $"straight {num:F1} m wide";
				}
				straight = true;
				return null;
			}
			if (Mathf.Abs(Vector3.Dot(normalized, normalized2)) < 0.1f)
			{
				if (Mathf.Max(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z) > 20f)
				{
					return $"corner {((Bounds)(ref bounds)).size.x:F0}x{((Bounds)(ref bounds)).size.z:F0} m";
				}
				float num2 = RingTurn(normalized, normalized2);
				Vector3 pivot = RingPivot(((Component)a).transform.position, ((Component)c).transform.position, num2);
				Bounds[] array = (Bounds[])(object)new Bounds[4];
				for (int i = 0; i < 4; i++)
				{
					array[i] = Turned(bounds, pivot, num2 * (float)i);
					((Bounds)(ref array[i])).Expand(-1f);
				}
				for (int j = 0; j < 4; j++)
				{
					for (int k = j + 1; k < 4; k++)
					{
						if (((Bounds)(ref array[j])).Intersects(array[k]))
						{
							return "corner ring overlaps";
						}
					}
				}
				return null;
			}
			if (Vector3.Dot(normalized, normalized2) > 0.9f)
			{
				return "U-turn (both doorways face one way)";
			}
			if (Vector3.Dot(normalized, normalized2) < -0.9f)
			{
				return "offset straight (doorways not in line)";
			}
			return $"angled doorways (dots {Vector3.Dot(normalized, -val2):F2}/{Vector3.Dot(normalized2, val2):F2})";
		}

		private static float RingTurn(Vector3 outE, Vector3 outX)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Round(Vector3.SignedAngle(outE, -outX, Vector3.up) / 90f) * 90f;
		}

		private static Vector3 RingPivot(Vector3 pe, Vector3 px, float turn)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0031: 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_0040: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0093: 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)
			Quaternion val = Quaternion.AngleAxis(turn, Vector3.up);
			Vector3 val2 = val * Vector3.right;
			Vector3 val3 = val * Vector3.forward;
			Vector3 val4 = px - val * pe;
			float num = 1f - val2.x;
			float num2 = 0f - val3.x;
			float num3 = 0f - val2.z;
			float num4 = 1f - val3.z;
			float num5 = num * num4 - num2 * num3;
			return new Vector3((val4.x * num4 - num2 * val4.z) / num5, 0f, (num * val4.z - num3 * val4.x) / num5);
		}

		private static Bounds Turned(Bounds b, Vector3 pivot, float angle)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_004f: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = Quaternion.AngleAxis(angle, Vector3.up);
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(pivot + val * (((Bounds)(ref b)).min - pivot), Vector3.zero);
			Vector3 val2 = default(Vector3);
			for (int i = 0; i < 8; i++)
			{
				((Vector3)(ref val2))..ctor(((i & 1) == 0) ? ((Bounds)(ref b)).min.x : ((Bounds)(ref b)).max.x, ((i & 2) == 0) ? ((Bounds)(ref b)).min.y : ((Bounds)(ref b)).max.y, ((i & 4) == 0) ? ((Bounds)(ref b)).min.z : ((Bounds)(ref b)).max.z);
				((Bounds)(ref result)).Encapsulate(pivot + val * (val2 - pivot));
			}
			return result;
		}

		internal static LongWayBack Build(Tile hall, Doorway e, Doorway x, Dungeon dungeon, int seed)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_001b: Expected O, but got Unknown
			GameObject val = new GameObject("Anomalies.LongWayBack");
			SceneManager.MoveGameObjectToScene(val, ((Component)dungeon).gameObject.scene);
			LongWayBack longWayBack = val.AddComponent<LongWayBack>();
			longWayBack.Init(hall, e, x, dungeon, seed);
			Instance = longWayBack;
			return longWayBack;
		}

		private void Init(Tile hall, Doorway e, Doorway x, Dungeon dungeon, int seed)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00c7: 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_00d2: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Expected O, but got Unknown
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0532: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_070d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_079e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0587: Unknown result type (might be due to invalid IL or missing references)
			//IL_0612: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			Real = hall;
			DoorE = e;
			DoorX = x;
			RealBounds = hall.Bounds;
			PE = ((Component)e).transform.position;
			PX = ((Component)x).transform.position;
			Vector3 val = Flat(((Component)e).transform.forward);
			OutE = ((Vector3)(ref val)).normalized;
			val = Flat(((Component)x).transform.forward);
			OutX = ((Vector3)(ref val)).normalized;
			PairShape(hall, e, x, out var straight);
			Ring = !straight;
			Step = PX - PE;
			Vector3 val2 = Flat(Step);
			Axis = ((Vector3)(ref val2)).normalized;
			Right = Vector3.Cross(Vector3.up, Axis);
			if (Ring)
			{
				Turn = RingTurn(OutE, OutX);
				Pivot = RingPivot(PE, PX, Turn);
				Bend = PE - OutE * Vector3.Dot(PE - PX, OutE);
				Bend.y = PE.y;
				val = Flat(Bend - PE);
				float magnitude = ((Vector3)(ref val)).magnitude;
				val = Flat(PX - Bend);
				Length = magnitude + ((Vector3)(ref val)).magnitude;
			}
			else
			{
				Length = ((Vector3)(ref val2)).magnitude;
			}
			foreach (Doorway usedDoorway in hall.UsedDoorways)
			{
				if ((Object)(object)usedDoorway != (Object)null && (Object)(object)usedDoorway != (Object)(object)e && (Object)(object)usedDoorway != (Object)(object)x && (Object)(object)usedDoorway.ConnectedDoorway != (Object)null)
				{
					Sides.Add(usedDoorway);
				}
			}
			Random random = new Random(seed ^ 0x10B6);
			Copies = random.Next(3, 6);
			Tile tile = e.ConnectedDoorway.Tile;
			Tile tile2 = x.ConnectedDoorway.Tile;
			int num = (Ring ? 4 : Copies);
			Bounds realBounds = RealBounds;
			for (int i = 1; i < num; i++)
			{
				((Bounds)(ref realBounds)).Encapsulate(MoveBounds(RealBounds, i, Vector3.zero));
			}
			if (!Ring)
			{
				((Bounds)(ref realBounds)).Encapsulate(tile.Bounds);
				((Bounds)(ref realBounds)).Encapsulate(MoveBounds(tile2.Bounds, Copies - 1, Vector3.zero));
			}
			Offset = PickOffset(dungeon, realBounds);
			pocketBounds = realBounds;
			ref Bounds reference = ref pocketBounds;
			((Bounds)(ref reference)).center = ((Bounds)(ref reference)).center + Offset;
			((Bounds)(ref pocketBounds)).Expand(2f);
			pocket = new GameObject("Pocket");
			pocket.SetActive(false);
			pocket.transform.SetParent(((Component)this).transform, false);
			HashSet<Animator> keepAnimators = PocketKit.PoweredLightAnimators(hall);
			for (int j = 0; j < num; j++)
			{
				Cloner.Copy copy = Cloner.Make(((Component)hall).gameObject, pocket.transform, ToCopy(((Component)hall).transform.position, j), Rot(j) * ((Component)hall).transform.rotation, keepAnimators);
				((Object)copy.Root).name = $"H{j} {((Object)hall).name}";
				PocketKit.CollectLights(copy, lights);
				PocketKit.FixCulledState(copy, hall);
				hallCopies.Add(copy);
				int k = j;
				foreach (Doorway side in Sides)
				{
					PocketKit.SealDoorway(side, copy.Root.transform, (Vector3 p) => ToCopy(p, k), Rot(k));
				}
			}
			FitFrames();
			FindEndDoors();
			if (!Ring)
			{
				Room(tile, e.ConnectedDoorway, Offset, "E");
				Room(tile2, x.ConnectedDoorway, Offset + Step * (float)(Copies - 1), "X");
				BlinkOutE = Sides.Count > 0 || OtherDoorwaySeen(tile, e.ConnectedDoorway);
				BlinkOutX = Sides.Count > 0 || OtherDoorwaySeen(tile2, x.ConnectedDoorway);
			}
			cullProxy = new GameObject("CullProxy").transform;
			cullProxy.SetParent(((Component)this).transform, false);
			Plugin.Log.LogInfo((object)(Ring ? ($"Long Way Back (corner ring): {((Object)hall).name} at {((Bounds)(ref RealBounds)).center}, {Length:F1} m from {((Object)e).name} round the bend to {((Object)x).name}, turn {Turn:F0} about {Pivot}, " + $"{Copies} corners ({Length * (float)Copies:F0} m), {Sides.Count} side openings walled, pocket offset {Offset}, {lights.Count} powered lights copied, " + $"doors due at E {EndDoors.Count((EndDoor d) => !d.AtX)}, X {EndDoors.Count((EndDoor d) => d.AtX)}") : ($"Long Way Back (straight): {((Object)hall).name} at {((Bounds)(ref RealBounds)).center}, {Length:F1} m from {((Object)e).name} to {((Object)x).name}, x{Copies} " + $"({Length * (float)Copies:F0} m), rooms {((Object)tile).name} / {((Object)tile2).name}, {Sides.Count} side openings walled, pocket offset {Offset}, {lights.Count} powered lights copied, " + "exit at E " + (BlinkOutE ? "blinks" : "unseen") + ", at X " + (BlinkOutX ? "blinks" : "unseen") + ", " + $"doors due at E {EndDoors.Count((EndDoor d) => !d.AtX)}, X {EndDoors.Count((EndDoor d) => d.AtX)}")));
		}

		internal static bool IsDoorPrefab(GameObject prefab)
		{
			if (!((Object)(object)prefab.GetComponentInChildren<DoorLock>(true) != (Object)null))
			{
				return prefab.GetComponentsInChildren<TerminalAccessibleObject>(true).Any((TerminalAccessibleObject t) => t.isBigDoor);
			}
			return true;
		}

		private void FindEndDoors()
		{
			(Doorway, bool)[] array = new(Doorway, bool)[2]
			{
				(DoorE, false),
				(DoorX, true)
			};
			for (int i = 0; i < array.Length; i++)
			{
				(Doorway, bool) tuple = array[i];
				Doorway item = tuple.Item1;
				bool item2 = tuple.Item2;
				HashSet<Transform> hashSet = new HashSet<Transform>();
				GameObject[] array2 = (GameObject[])(object)new GameObject[2]
				{
					item.UsedDoorPrefabInstance,
					item.ConnectedDoorway.UsedDoorPrefabInstance
				};
				foreach (GameObject val in array2)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					SpawnSyncedObject[] componentsInChildren = val.GetComponentsInChildren<SpawnSyncedObject>(false);
					foreach (SpawnSyncedObject val2 in componentsInChildren)
					{
						if ((Object)(object)val2.spawnPrefab != (Object)null && IsDoorPrefab(val2.spawnPrefab) && hashSet.Add(((Component)val2).transform))
						{
							EndDoors.Add(new EndDoor
							{
								AtX = item2,
								Spawner = ((Component)val2).transform
							});
						}
					}
				}
			}
		}

		private IEnumerable<int> DoorCopyIndices(bool atX)
		{
			int count = hallCopies.Count;
			bool flag = EndDoors.Any((EndDoor d) => d.AtX);
			if (atX || !flag)
			{
				return Enumerable.Range(0, count);
			}
			if (!Ring)
			{
				return new int[1];
			}
			return Enumerable.Empty<int>();
		}

		private void BindEndDoors()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			nextDoorBind = Time.time + 2f;
			AnimatedObjectTrigger[] array = null;
			foreach (EndDoor endDoor in EndDoors)
			{
				if ((Object)(object)endDoor.Anim != (Object)null)
				{
					continue;
				}
				array = array ?? Object.FindObjectsOfType<AnimatedObjectTrigger>();
				AnimatedObjectTrigger[] array2 = array;
				foreach (AnimatedObjectTrigger val in array2)
				{
					if ((Object)(object)((Component)val).GetComponent<DoorLock>() == (Object)null)
					{
						TerminalAccessibleObject component = ((Component)val).GetComponent<TerminalAccessibleObject>();
						if (component == null || !component.isBigDoor)
						{
							continue;
						}
					}
					NetworkObject componentInParent = ((Component)val).GetComponentInParent<NetworkObject>();
					Transform val2 = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).transform : ((Component)val).transform);
					Vector3 val3 = val2.position - endDoor.Spawner.position;
					if (((Vector3)(ref val3)).sqrMagnitude > 0.25f)
					{
						continue;
					}
					endDoor.Anim = val;
					endDoor.Root = val2;
					foreach (int item in DoorCopyIndices(endDoor.AtX))
					{
						Cloner.Copy copy = Cloner.Make(((Component)val2).gameObject, pocket.transform, ToCopy(val2.position, item), Rot(item) * val2.rotation, null);
						((Object)copy.Root).name = string.Format("Door{0} {1} {2}", endDoor.AtX ? "X" : "E", item, ((Object)val2).name);
						if (copy.RealT.Length == copy.CopyT.Length)
						{
							endDoor.Copies.Add(copy);
							continue;
						}
						Object.Destroy((Object)(object)copy.Root);
						Plugin.Log.LogWarning((object)("Long Way Back: door copy mismatch at " + (endDoor.AtX ? "X" : "E")));
					}
					Plugin.Log.LogInfo((object)string.Format("Long Way Back: bound the door at {0} ({1}, {2}), shown in {3} copies", endDoor.AtX ? "X" : "E", ((Object)val2).name, endDoor.Open ? "open" : "shut", endDoor.Copies.Count));
					break;
				}
			}
		}

		internal bool EndDoorsOpen()
		{
			return EndDoors.All((EndDoor d) => d.Open);
		}

		private void MirrorDoors()
		{
			foreach (EndDoor endDoor in EndDoors)
			{
				if (!((Object)(object)endDoor.Root != (Object)null))
				{
					continue;
				}
				foreach (Cloner.Copy copy in endDoor.Copies)
				{
					Cloner.CopyPose(copy.RealT, copy.CopyT);
				}
			}
		}

		private bool OtherDoorwaySeen(Tile room, Doorway toHall)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_007b: 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_008a: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			int collidersAndRoomMaskAndDefault = StartOfRound.Instance.collidersAndRoomMaskAndDefault;
			List<Vector3> list = new List<Vector3>();
			float[] array = new float[3] { 0.15f, 0.5f, 0.85f };
			foreach (float num in array)
			{
				float[] array2 = new float[3] { -0.6f, 0f, 0.6f };
				foreach (float num2 in array2)
				{
					list.Add(PE + Step * num + Right * num2 + Vector3.up * 1.6f);
				}
			}
			foreach (Doorway usedDoorway in room.UsedDoorways)
			{
				if ((Object)(object)usedDoorway == (Object)null || (Object)(object)usedDoorway == (Object)(object)toHall)
				{
					continue;
				}
				array = new float[3] { 0.4f, 1.2f, 2f };
				foreach (float num3 in array)
				{
					float[] array2 = new float[3] { -0.6f, 0f, 0.6f };
					foreach (float num4 in array2)
					{
						Vector3 to = ((Component)usedDoorway).transform.position + Vector3.up * num3 + ((Component)usedDoorway).transform.right * num4;
						foreach (Vector3 item in list)
						{
							if (Clear(item, to, collidersAndRoomMaskAndDefault))
							{
								V("room " + ((Object)room).name + ": doorway " + ((Object)usedDoorway).name + " is in view from the hallway");
								return true;
							}
						}
					}
				}
			}
			return false;
		}

		private static bool Clear(Vector3 from, Vector3 to, int mask)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = to - from;
			float num = ((Vector3)(ref val)).magnitude - 0.3f;
			if (num <= 0f)
			{
				return true;
			}
			RaycastHit[] array = Physics.RaycastAll(from, ((Vector3)(ref val)).normalized, num, mask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val2 = array[i];
				if ((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<NetworkObject>() == (Object)null)
				{
					return false;
				}
			}
			return true;
		}

		private static bool Seen(Vector3 eye, Vector3 door, Vector3 right)
		{
			//IL_0049: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			int collidersAndRoomMaskAndDefault = StartOfRound.Instance.collidersAndRoomMaskAndDefault;
			float[] array = new float[3] { 0.4f, 1.2f, 2f };
			foreach (float num in array)
			{
				float[] array2 = new float[3] { -0.6f, 0f, 0.6f };
				foreach (float num2 in array2)
				{
					if (Clear(eye, door + Vector3.up * num + right * num2, collidersAndRoomMaskAndDefault))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static Vector3 PickOffset(Dungeon dungeon, Bounds chain)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			Bounds val = chain;
			foreach (Tile allTile in dungeon.AllTiles)
			{
				if ((Object)(object)allTile != (Object)null)
				{
					((Bounds)(ref val)).Encapsulate(allTile.Bounds);
				}
			}
			float num = ((Bounds)(ref val)).min.y - 40f - ((Bounds)(ref chain)).max.y;
			if (((Bounds)(ref chain)).min.y + num < -560f)
			{
				num = -560f - ((Bounds)(ref chain)).min.y;
			}
			return new Vector3(((Bounds)(ref val)).min.x - 80f - ((Bounds)(ref chain)).max.x, num, 0f);
		}

		private void FitFrames()
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			GameObject usedDoorPrefabInstance = DoorE.UsedDoorPrefabInstance;
			GameObject usedDoorPrefabInstance2 = DoorX.UsedDoorPrefabInstance;
			bool flag = (Object)(object)usedDoorPrefabInstance != (Object)null && usedDoorPrefabInstance.transform.IsChildOf(((Component)Real).transform);
			bool flag2 = (Object)(object)usedDoorPrefabInstance2 != (Object)null && usedDoorPrefabInstance2.transform.IsChildOf(((Component)Real).transform);
			int num = (Ring ? 4 : (Copies - 1));
			for (int i = 0; i < num; i++)
			{
				int num2 = (i + 1) % hallCopies.Count;
				if (flag && flag2)
				{
					Transform val = hallCopies[num2].Find(usedDoorPrefabInstance.transform);
					if ((Object)(object)val != (Object)null)
					{
						Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
					}
				}
				else if (!flag && !flag2 && (Object)(object)usedDoorPrefabInstance2 != (Object)null)
				{
					((Object)Cloner.Make(usedDoorPrefabInstance2, pocket.transform, ToCopy(usedDoorPrefabInstance2.transform.position, i), Rot(i) * usedDoorPrefabInstance2.transform.rotation, null).Root).name = $"Frame {i}/{num2}";
				}
			}
		}

		private void Room(Tile room, Doorway toHall, Vector3 shift, string tag)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00de: Unknown result type (might be due to invalid IL or missing references)
			Cloner.Copy copy = Cloner.Make(((Component)room).gameObject, pocket.transform, ((Component)room).transform.position + shift, ((Component)room).transform.rotation, PocketKit.PoweredLightAnimators(room));
			((Object)copy.Root).name = "Room" + tag + " " + ((Object)room).name;
			PocketKit.CollectLights(copy, lights);
			PocketKit.FixCulledState(copy, room);
			int num = 0;
			int num2 = 0;
			foreach (Doorway usedDoorway in room.UsedDoorways)
			{
				if (!((Object)(object)usedDoorway == (Object)null) && !((Object)(object)usedDoorway == (Object)(object)toHall))
				{
					if ((Object)(object)PocketKit.SealDoorway(usedDoorway, copy.Root.transform, (Vector3 p) => p + shift, Quaternion.identity) != (Object)null)
					{
						num++;
					}
					else
					{
						num2++;
					}
				}
			}
			V($"room {tag}: {((Object)room).name}, {num} doorways walled, {num2} left open (no blocker)");
		}

		internal Quaternion Rot(int i)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (!Ring)
			{
				return Quaternion.identity;
			}
			return Quaternion.AngleAxis(Turn * (float)i, Vector3.up);
		}

		private Bounds MoveBounds(Bounds b, int i, Vector3 offset)
		{
			//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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (Ring)
			{
				Bounds result = Turned(b, Pivot, Turn * (float)i);
				((Bounds)(ref result)).center = ((Bounds)(ref result)).center + offset;
				return result;
			}
			((Bounds)(ref b)).center = ((Bounds)(ref b)).center + (offset + Step * (float)i);
			return b;
		}

		internal Vector3 ToCopy(Vector3 realPos, int i)
		{
			//IL_0028: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!Ring)
			{
				return realPos + Offset + Step * (float)i;
			}
			return Offset + Pivot + Rot(i) * (realPos - Pivot);
		}

		private Vector3 FromCopy(Vector3 pocketPos, int i)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!Ring)
			{
				return pocketPos - Offset - Step * (float)i;
			}
			return Pivot + Quaternion.AngleAxis((0f - Turn) * (float)i, Vector3.up) * (pocketPos - Offset - Pivot);
		}

		private float U(Vector3 pocketPos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Dot(pocketPos - Offset - PE, Axis);
		}

		internal int CopyIndex(Vector3 pocketPos)
		{
			//IL_0009: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (!Ring)
			{
				return Mathf.Clamp(Mathf.FloorToInt(U(pocketPos) / Length), 0, Copies - 1);
			}
			int result = 0;
			float num = float.MaxValue;
			for (int i = 0; i < 4; i++)
			{
				Vector3 val = FromCopy(pocketPos, i) + Vector3.up * 0.5f;
				float num2;
				if (!((Bounds)(ref RealBounds)).Contains(val))
				{
					Vector3 val2 = ((Bounds)(ref RealBounds)).ClosestPoint(val) - val;
					num2 = ((Vector3)(ref val2)).sqrMagnitude;
				}
				else
				{
					num2 = 0f;
				}
				float num3 = num2;
				if (num3 < num)
				{
					num = num3;
					result = i;
				}
			}
			return result;
		}

		internal Vector3 ToReal(Vector3 pocketPos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return FromCopy(pocketPos, CopyIndex(pocketPos));
		}

		internal float YawToReal(float yaw, Vector3 pocketPos)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!Ring)
			{
				return yaw;
			}
			return yaw - Turn * (float)CopyIndex(pocketPos);
		}

		internal bool InReal(Vector3 feet)
		{
			//IL_0006: 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)
			return ((Bounds)(ref RealBounds)).Contains(feet + Vector3.up * 0.5f);
		}

		internal bool InPocket(Vector3 feet)
		{
			//IL_0006: 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)
			return ((Bounds)(ref pocketBounds)).Contains(feet + Vector3.up * 0.5f);
		}

		internal Vector3 Joint(int i)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (!Ring)
			{
				return PE + Offset + Step * (float)i;
			}
			return ToCopy(PE, i);
		}

		private static float Clock()
		{
			TimeOfDay instance = TimeOfDay.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				return 6f + instance.normalizedTimeOfDay * (float)instance.numberOfHours;
			}
			return 0f;
		}

		private void Update()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)val == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)Real == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)val).transform.position;
			bool flag = val.isPlayerControlled && !val.isPlayerDead;
			bool flag2 = flag && InReal(position);
			TrackSides(position, flag2);
			if (flag && WayInSide >= 0 && State == Phase.Idle && Near(position))
			{
				lastNear = Time.time;
			}
			bool flag3 = State == Phase.InPocket || Time.time - lastNear < 3f;
			if (Time.time >= nextDoorBind && EndDoors.Any((EndDoor d) => (Object)(object)d.Anim == (Object)null))
			{
				BindEndDoors();
			}
			if (flag3 != pocket.activeSelf)
			{
				SetPocket(flag3);
			}
			if (pocket.activeSelf)
			{
				PocketKit.MirrorLights(lights);
				MirrorDoors();
			}
			switch (State)
			{
			case Phase.Idle:
				if (flag2 && CanEnter(val, position))
				{
					Enter(val, position);
				}
				break;
			case Phase.InPocket:
				InPocketUpdate(val, position, flag, instance);
				break;
			case Phase.Cooldown:
				if (!flag2 && Time.time > cooldownUntil)
				{
					State = Phase.Idle;
					V("armed again");
				}
				break;
			}
		}

		private bool Near(Vector3 feet)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = feet - PE;
			Vector3 val2 = feet - PX;
			val.y = 0f;
			val2.y = 0f;
			if (Mathf.Abs(feet.y - PE.y) < 6f)
			{
				if (!(((Vector3)(ref val)).magnitude < 14f) && !(((Vector3)(ref val2)).magnitude < 14f))
				{
					return InReal(feet);
				}
				return true;
			}
			return false;
		}

		private void TrackSides(Vector3 feet, bool inReal)
		{
			//IL_0012: 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)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (inReal && !wasIn)
			{
				Vector3 val = feet - PE;
				float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
				val = feet - PX;
				EntrySide = ((!(sqrMagnitude <= ((Vector3)(ref val)).sqrMagnitude)) ? 1 : 0);
				if (WayInSide < 0)
				{
					WayInSide = EntrySide;
					V("way in is through " + ((EntrySide == 0) ? ((Object)DoorE).name : ((Object)DoorX).name));
				}
				V("in the hallway through " + ((EntrySide == 0) ? "E" : "X") + ((EntrySide != WayInSide) ? " (the way back)" : ""));
			}
			if (!inReal && wasIn)
			{
				EntrySide = -1;
			}
			wasIn = inReal;
		}

		private bool CanEnter(PlayerControllerB p, Vector3 feet)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			if (Hold || EntrySide < 0 || WayInSide < 0 || EntrySide == WayInSide)
			{
				return false;
			}
			if (!Plugin.ForceLongWayBack.Value && Clock() < Plugin.NotBeforeHour.Value)
			{
				return false;
			}
			if (activeSince < 0f || Time.time - activeSince < 0.5f)
			{
				return false;
			}
			if (p.inSpecialInteractAnimation || p.isClimbingLadder || (Object)(object)p.inAnimationWithEnemy != (Object)null || !p.isInsideFactory)
			{
				return false;
			}
			if (StartOfRound.Instance.shipIsLeaving)
			{
				return false;
			}
			if (!EndDoorsOpen())
			{
				if (!shutLogged)
				{
					V("an end door is shut: not taking the long way");
				}
				shutLogged = true;
				return false;
			}
			shutLogged = false;
			Vector3 val = ((EntrySide == 0) ? PE : PX);
			Vector3 val2 = -((EntrySide == 0) ? OutE : OutX);
			float num;
			Vector3 val3;
			if (!Ring)
			{
				num = ((EntrySide == 0) ? Vector3.Dot(feet - PE, Axis) : (Length - Vector3.Dot(feet - PE, Axis)));
			}
			else
			{
				val3 = Flat(feet - val);
				num = ((Vector3)(ref val3)).magnitude;
			}
			float num2 = num;
			float num3;
			if (!Ring)
			{
				num3 = Length * 0.5f;
			}
			else
			{
				val3 = Flat(Bend - val);
				num3 = Mathf.Max(2.5f, ((Vector3)(ref val3)).magnitude);
			}
			float num4 = num3;
			if (num2 < 1.5f || num2 > num4)
			{
				return false;
			}
			Vector3 forward = ((Component)p.gameplayCamera).transform.forward;
			forward.y = 0f;
			if (Vector3.Dot(((Vector3)(ref forward)).normalized, val2) < 0.5f)
			{
				return false;
			}
			return !OtherPlayerIn(p, InReal);
		}

		private static bool OtherPlayerIn(PlayerControllerB me, Func<Vector3, bool> where)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)me && val.isPlayerControlled && !val.isPlayerDead && where(((Component)val).transform.position))
				{
					return true;
				}
			}
			return false;
		}

		internal int StartCopy(int dir)
		{
			if (!Ring)
			{
				if (dir <= 0)
				{
					return Copies - 1;
				}
				return 0;
			}
			return 0;
		}

		private void Enter(PlayerControllerB p, Vector3 feet)
		{
			//IL_0067: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			Trips++;
			Dir = ((EntrySide == 0) ? 1 : (-1));
			int num = (RingCur = StartCopy(Dir));
			RingProgress = 0;
			ringCameOn = true;
			MakeStandIns();
			State = Phase.InPocket;
			enteredAt = Time.time;
			Blink.Run(0.45f);
			Swap(p, ToCopy(feet, num), ((Component)p).transform.eulerAngles.y + (Ring ? (Turn * (float)num) : 0f), "enter (blink)");
			PocketKit.SetCuller(cullProxy, on: true);
		}

		private void InPocketUpdate(PlayerControllerB p, Vector3 feet, bool alive, StartOfRound sor)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00a8: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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_01ac: 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)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			if (!alive)
			{
				Leave(p, null, "died");
				return;
			}
			cullProxy.position = ToReal(((Component)p.gameplayCamera).transform.position);
			bool flag = !InPocket(feet);
			bool flag2 = !EndDoorsOpen();
			if (flag || flag2 || sor.shipIsLeaving || sor.inShipPhase || Time.time - enteredAt > Plugin.MaxLongSeconds.Value)
			{
				Blink.Run(0.35f);
				Leave(p, (ToReal(feet), YawToReal(((Component)p).transform.eulerAngles.y, feet)), flag ? "lost the pocket" : (flag2 ? "a door shut" : (sor.shipIsLeaving ? "ship leaving" : "time")));
			}
			else if (Ring)
			{
				RingUpdate(p, feet);
			}
			else if (!Hold && !(Time.time - enteredAt < 1f))
			{
				float num = U(feet);
				int num2 = CopyIndex(feet);
				if (num2 == Copies - 1 && num - Length * (float)(Copies - 1) >= 1.2f && PocketKit.OutOfView(p.gameplayCamera, Joint(Copies - 1), Right))
				{
					Out(p, feet, BlinkOutX, (Dir > 0) ? "far end" : "turned back");
				}
				else if (num2 == 0 && Length - num >= 1.2f && PocketKit.OutOfView(p.gameplayCamera, Joint(1), Right))
				{
					Out(p, feet, BlinkOutE, (Dir < 0) ? "far end" : "turned back");
				}
			}
		}

		private void RingUpdate(PlayerControllerB p, Vector3 feet)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			int num = CopyIndex(feet);
			if (num != RingCur)
			{
				ringCameOn = num == (RingCur + Dir + 4) % 4;
				RingProgress += (ringCameOn ? 1 : (-1));
				RingCur = num;
				V($"ring copy {num}, {RingProgress} corners on");
			}
			if (!Hold && !(Time.time - enteredAt < 1f) && (RingProgress >= Copies || RingProgress < 0))
			{
				bool num2 = Dir > 0 == ringCameOn;
				Doorway val = (num2 ? DoorE : DoorX);
				Doorway val2 = (num2 ? DoorX : DoorE);
				Vector3 val3 = ToCopy(((Component)val).transform.position, num);
				Vector3 door = ToCopy(((Component)val2).transform.position, num);
				Vector3 val4 = Flat(feet - val3);
				if (!(((Vector3)(ref val4)).magnitude < 1.2f) && PocketKit.OutOfView(p.gameplayCamera, val3, Rot(num) * ((Component)val).transform.right))
				{
					bool blink = Sides.Count > 0 || Seen(((Component)p.gameplayCamera).transform.position, door, Rot(num) * ((Component)val2).transform.right);
					Out(p, feet, blink, (RingProgress >= Copies) ? "far end" : "turned back");
				}
			}
		}

		private void Out(PlayerControllerB p, Vector3 feet, bool blink, string why)
		{
			//IL_0010: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (blink)
			{
				Blink.Run(0.35f);
			}
			Leave(p, (ToReal(feet), YawToReal(((Component)p).transform.eulerAngles.y, feet)), (blink ? "blink, " : "unseen, ") + why);
		}

		private void Leave(PlayerControllerB p, (Vector3 pos, float yaw)? to, string why)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			ReturnItems();
			ClearStandIns();
			if (to.HasValue)
			{
				Swap(p, to.Value.pos, to.Value.yaw, "exit (" + why + ")");
			}
			PocketKit.SetCuller(cullProxy, on: false);
			State = Phase.Cooldown;
			cooldownUntil = Time.time + 120f;
			WayInSide = ((Dir <= 0) ? 1 : 0);
			V($"left the long way: {why}, {Time.time - enteredAt:F1} s");
		}

		private void Swap(PlayerControllerB p, Vector3 pos, float yaw, string kind)
		{
			//IL_0001: 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)
			PocketKit.Teleport(p, pos, yaw);
			Swaps++;
			LastSwapFrame = Time.frameCount;
			LastSwap = kind;
			V($"swap {kind} -> {pos} yaw {yaw:F0} (frame {Time.frameCount})");
		}

		private void SetPocket(bool on)
		{
			pocket.SetActive(on);
			activeSince = (on ? Time.time : (-1f));
			if (on)
			{
				PocketKit.SnapLights(lights);
			}
			if (!on)
			{
				ClearStandIns();
			}
			V("pocket " + (on ? "shown" : "hidden"));
		}

		private void MakeStandIns()
		{
			//IL_004c: 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_0082: 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_0095: 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)
			ClearStandIns();
			int count = hallCopies.Count;
			GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
			foreach (GrabbableObject val in array)
			{
				if ((Object)(object)val == (Object)null || val.isHeld || val.isPocketed || !InReal(((Component)val).transform.position))
				{
					continue;
				}
				for (int j = 0; j < count; j++)
				{
					Cloner.Copy copy = Cloner.Make(((Component)val).gameObject, pocket.transform, ToCopy(((Component)val).transform.position, j), Rot(j) * ((Component)val).transform.rotation, null);
					((Object)copy.Root).name = "StandIn " + val.itemProperties?.itemName;
					Collider[] componentsInChildren = copy.Root.GetComponentsInChildren<Collider>(true);
					for (int k = 0; k < componentsInChildren.Length; k++)
					{
						Object.Destroy((Object)(object)componentsInChildren[k]);
					}
					standIns.Add(copy.Root);
				}
			}
			if (standIns.Count > 0)
			{
				V($"{standIns.Count / count} scrap stand-ins");
			}
		}

		private void ClearStandIns()
		{
			foreach (GameObject standIn in standIns)
			{
				if ((Object)(object)standIn != (Object)null)
				{
					Object.Destroy((Object)(object)standIn);
				}
			}
			standIns.Clear();
		}

		private void ReturnItems()
		{
			//IL_002e: 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)
			GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
			foreach (GrabbableObject val in array)
			{
				if (!((Object)(object)val == (Object)null) && !val.isHeld && !val.isPocketed && InPocket(((Component)val).transform.position))
				{
					Net.SendReturn(val, ToReal(((Component)val).transform.position));
				}
			}
		}

		private void OnDestroy()
		{
			PocketKit.SetCuller(cullProxy, on: false);
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	internal class LoopRoom : MonoBehaviour
	{
		internal enum Phase
		{
			Idle,
			InPocket,
			Cooldown
		}

		internal static LoopRoom Instance;

		internal static bool Hold;

		internal Tile Real;

		internal Doorway Door;

		internal Bounds RealBounds;

		internal Vector3 DoorPos;

		internal Vector3 DoorFwd;

		internal Vector3 DoorRight;

		internal Vector3 Offset;

		private static readonly Quaternion Flip = Quaternion.Euler(0f, 180f, 0f);

		private GameObject pocket;

		private Cloner.Copy a1;

		private Cloner.Copy a2;

		private Transform[] doorReal;

		private Transform[] doorCopy;

		private DoorLock doorLock;

		private Transform doorSpawner;

		private float nextDoorBind;

		private readonly List<(Animator real, Animator copy)> lights = new List<(Animator, Animator)>();

		private readonly List<GameObject> standIns = new List<GameObject>();

		private Transform cullProxy;

		internal Phase State;

		internal int Laps;

		internal int LapTarget;

		internal int Swaps;

		internal int LastSwapFrame;

		internal string LastSwap = "";

		internal bool Released;

		internal string ReleaseReason = "";

		internal readonly List<float> LapStarts = new List<float>();

		private float enteredAt;

		private float releasedAt;

		private float cooldownUntil;

		private float activeSince = -1f;

		private float lastInReal = -100f;

		private int side;

		private int entries;

		internal Vector3 Junction => DoorPos + Offset;

		internal DoorLock RealDoor => doorLock;

		private static void V(string s)
		{
			if (Plugin.VerboseLog.Value)
			{
				Plugin.Log.LogInfo((object)("[Loop] " + s));
			}
		}

		internal static LoopRoom Build(Tile tile, Doorway door, Dungeon dungeon, int seed)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_001b: Expected O, but got Unknown
			GameObject val = new GameObject("Anomalies.LoopRoom");
			SceneManager.MoveGameObjectToScene(val, ((Component)dungeon).gameObject.scene);
			LoopRoom loopRoom = val.AddComponent<LoopRoom>();
			loopRoom.Init(tile, door, dungeon, seed);
			Instance = loopRoom;
			return loopRoom;
		}

		private void Init(Tile tile, Doorway door, Dungeon dungeon, int seed)
		{
			//IL_0010: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00f9: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			Real = tile;
			Door = door;
			RealBounds = tile.Bounds;
			DoorPos = ((Component)door).transform.position;
			Vector3 val = ((Component)door).transform.forward;
			val.y = 0f;
			((Vector3)(ref val)).Normalize();
			Vector3 val2 = DoorPos - ((Bounds)(ref RealBounds)).center;
			val2.y = 0f;
			if (Vector3.Dot(val, val2) < 0f)
			{
				val = -val;
			}
			DoorFwd = val;
			DoorRight = Vector3.Cross(Vector3.up, val);
			Offset = PickOffset(dungeon);
			pocket = new GameObject("Pocket");
			pocket.SetActive(false);
			pocket.transform.SetParent(((Component)this).transform, false);
			HashSet<Animator> keepAnimators = PocketKit.PoweredLightAnimators(tile);
			a1 = Cloner.Make(((Component)tile).gameObject, pocket.transform, ((Component)tile).transform.positi