Decompiled source of CircusLabyrinth v0.14.1

BepInEx/plugins/JLeonL-CircusLabyrinth/CircusLabyrinth.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLevelLoader;
using Microsoft.CodeAnalysis;
using Unity.AI.Navigation;
using Unity.Collections;
using Unity.Netcode;
using Unity.Netcode.Components;
using Unity.Netcode.Samples;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CircusLabyrinth")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.14.1.0")]
[assembly: AssemblyInformationalVersion("0.14.1")]
[assembly: AssemblyProduct("CircusLabyrinth")]
[assembly: AssemblyTitle("CircusLabyrinth")]
[assembly: AssemblyVersion("0.14.1.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 CircusLabyrinth
{
	internal static class CircusAmbience
	{
		private static AudioSource source;

		private static readonly AudioClip[] laughs = (AudioClip[])(object)new AudioClip[3];

		private static Random random;

		private static bool wasInside;

		private static float nextLaugh;

		internal static void Initialize(MonoBehaviour runtime, string directory)
		{
			//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)
			GameObject val = new GameObject("CircusLabyrinth_MazeLaughter");
			val.transform.SetParent(((Component)runtime).transform, false);
			source = val.AddComponent<AudioSource>();
			source.playOnAwake = false;
			source.loop = false;
			source.spatialBlend = 1f;
			source.dopplerLevel = 0f;
			source.rolloffMode = (AudioRolloffMode)1;
			source.minDistance = 5f;
			source.maxDistance = 24f;
			source.volume = 0.38f;
			source.priority = 120;
			for (int i = 0; i < laughs.Length; i++)
			{
				runtime.StartCoroutine(Load(Path.Combine(directory, "audio", "effects", $"maze-laugh-{i + 1:00}.wav"), i));
			}
		}

		private static IEnumerator Load(string path, int index)
		{
			if (!File.Exists(path))
			{
				CircusPlugin.Log.LogWarning((object)("Missing maze laughter: " + path));
				yield break;
			}
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, (AudioType)20);
			try
			{
				yield return request.SendWebRequest();
				if ((int)request.result == 1)
				{
					laughs[index] = DownloadHandlerAudioClip.GetContent(request);
				}
				else
				{
					CircusPlugin.Log.LogWarning((object)("Maze laughter: " + request.error));
				}
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}

		internal static void BeginVisit(int seed)
		{
			random = new Random(seed ^ 0x5A1236);
			wasInside = false;
		}

		internal static void EndVisit()
		{
			if ((Object)(object)source != (Object)null)
			{
				source.Stop();
			}
			wasInside = false;
		}

		internal static void Tick()
		{
			//IL_0132: 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)
			if ((Object)(object)source == (Object)null)
			{
				return;
			}
			PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			if (!CircusPlugin.Active || !((Object)(object)CircusPlugin.MazeRoot != (Object)null) || !((Object)(object)val != (Object)null) || !val.isInsideFactory || val.isPlayerDead)
			{
				if (wasInside)
				{
					source.Stop();
				}
				wasInside = false;
				return;
			}
			if (random == null)
			{
				BeginVisit(StartOfRound.Instance.randomMapSeed);
			}
			if (!wasInside)
			{
				wasInside = true;
				nextLaugh = Time.unscaledTime + 20f + (float)random.NextDouble() * 30f;
			}
			if (!(Time.unscaledTime < nextLaugh))
			{
				nextLaugh = Time.unscaledTime + 45f + (float)random.NextDouble() * 50f;
				int num = random.Next(laughs.Length);
				if (!((Object)(object)laughs[num] == (Object)null))
				{
					float num2 = (float)random.NextDouble() * MathF.PI * 2f;
					((Component)source).transform.position = ((Component)val).transform.position + new Vector3(Mathf.Cos(num2) * 7f, 1.3f, Mathf.Sin(num2) * 7f);
					source.pitch = 0.94f + (float)random.NextDouble() * 0.12f;
					source.PlayOneShot(laughs[num]);
					CircusPlugin.Log.LogInfo((object)("CIRCUS_MAZE_LAUGH variant=" + (num + 1)));
				}
			}
		}

		internal static void Dispose()
		{
			EndVisit();
			if ((Object)(object)source != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)source).gameObject);
			}
			AudioClip[] array = laughs;
			foreach (AudioClip val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
			source = null;
		}
	}
	public sealed class CircusAtmosphere : MonoBehaviour
	{
		private CircusGeometry geometry;

		private bool inside;

		private float nextTick;

		private float[] distances;

		private int[] lightOrder;

		private Volume volume;

		private Fog fog;

		public void Initialize(CircusGeometry builder, bool interior)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			geometry = builder;
			inside = interior;
			distances = new float[builder.Lamps.Count];
			lightOrder = new int[builder.Lamps.Count];
			for (int i = 0; i < builder.Lamps.Count; i++)
			{
				((Component)builder.Lamps[i]).gameObject.AddComponent<HDAdditionalLightData>().SetIntensity(builder.LampLumens[i], (LightUnit)0);
			}
			VolumeProfile val = ScriptableObject.CreateInstance<VolumeProfile>();
			Exposure obj = val.Add<Exposure>(true);
			((VolumeParameter<ExposureMode>)(object)obj.mode).Override((ExposureMode)0);
			((VolumeParameter<float>)(object)obj.fixedExposure).Override(inside ? 2f : 2.3f);
			fog = val.Add<Fog>(true);
			((VolumeParameter<bool>)(object)fog.enabled).Override(true);
			((VolumeParameter<bool>)(object)fog.enableVolumetricFog).Override(true);
			((VolumeParameter<float>)(object)fog.meanFreePath).Override((float)(inside ? 38 : 65));
			((VolumeParameter<Color>)(object)fog.albedo).Override(new Color(0.23f, 0.29f, 0.35f));
			((VolumeParameter<float>)(object)fog.baseHeight).Override(((Component)this).transform.position.y - 2f);
			((VolumeParameter<float>)(object)fog.maximumHeight).Override(((Component)this).transform.position.y + 100f);
			VisualEnvironment obj2 = val.Add<VisualEnvironment>(true);
			((VolumeParameter<int>)(object)obj2.skyType).Override(0);
			((VolumeParameter<SkyAmbientMode>)(object)obj2.skyAmbientMode).Override((SkyAmbientMode)0);
			ColorAdjustments obj3 = val.Add<ColorAdjustments>(true);
			((VolumeParameter<float>)(object)obj3.postExposure).Override(0f);
			((VolumeParameter<float>)(object)obj3.saturation).Override(-7f);
			volume = ((Component)this).gameObject.AddComponent<Volume>();
			volume.isGlobal = true;
			volume.priority = 10000f;
			volume.weight = 0f;
			BoxCollider obj4 = ((Component)this).gameObject.AddComponent<BoxCollider>();
			((Collider)obj4).isTrigger = true;
			obj4.center = (inside ? new Vector3(0f, 45f, 0f) : new Vector3(-16f, 45f, -94f));
			obj4.size = (inside ? new Vector3(240f, 150f, 240f) : new Vector3(345f, 150f, 440f));
			volume.sharedProfile = val;
			volume.blendDistance = 0f;
			if (!inside)
			{
				GameObject val2 = new GameObject("CircusMoonlight");
				val2.transform.SetParent(((Component)this).transform, false);
				val2.transform.localRotation = Quaternion.Euler(60f, -35f, 0f);
				Light obj5 = val2.AddComponent<Light>();
				obj5.type = (LightType)1;
				obj5.color = new Color(0.43f, 0.57f, 0.8f);
				obj5.shadows = (LightShadows)0;
				val2.AddComponent<HDAdditionalLightData>().SetIntensity(0.06f, (LightUnit)2);
				GameObject val3 = new GameObject("CircusMoonFill");
				val3.transform.SetParent(((Component)this).transform, false);
				val3.transform.localRotation = Quaternion.Euler(24f, 145f, 0f);
				Light obj6 = val3.AddComponent<Light>();
				obj6.type = (LightType)1;
				obj6.color = new Color(0.3f, 0.47f, 0.53f);
				obj6.shadows = (LightShadows)0;
				val3.AddComponent<HDAdditionalLightData>().SetIntensity(0.015f, (LightUnit)2);
			}
		}

		private void Update()
		{
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: 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_01c2: Unknown result type (might be due to invalid IL or missing references)
			if (geometry == null)
			{
				return;
			}
			PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			volume.weight = (((Object)(object)val != (Object)null && CircusPlugin.Active && val.isInsideFactory == inside) ? 1 : 0);
			if (Time.unscaledTime < nextTick)
			{
				return;
			}
			nextTick = Time.unscaledTime + 0.12f;
			Vector3 val3;
			if (!inside && (Object)(object)val != (Object)null)
			{
				Vector3 val2 = ((Component)this).transform.InverseTransformPoint(((Component)val).transform.position);
				val2.y = 0f;
				val3 = val2 - CircusGeometry.Ship;
				float num = Mathf.Clamp01((((Vector3)(ref val3)).magnitude - 22f) / 40f);
				((VolumeParameter<float>)(object)fog.meanFreePath).value = 230f + -165f * (num * num * (3f - 2f * num));
			}
			double num2;
			if (!((Object)(object)NetworkManager.Singleton != (Object)null))
			{
				num2 = Time.time;
			}
			else
			{
				NetworkTime serverTime = NetworkManager.Singleton.ServerTime;
				num2 = ((NetworkTime)(ref serverTime)).Time;
			}
			double num3 = num2;
			for (int i = 0; i < geometry.Lamps.Count; i++)
			{
				Light val4 = geometry.Lamps[i];
				lightOrder[i] = i;
				float[] array = distances;
				int num4 = i;
				float num5;
				if (!((Object)(object)val4 != (Object)null) || !((Object)(object)val != (Object)null))
				{
					num5 = float.MaxValue;
				}
				else
				{
					val3 = ((Component)val4).transform.position - ((Component)val).transform.position;
					num5 = ((Vector3)(ref val3)).sqrMagnitude;
				}
				array[num4] = num5;
				if (inside && (Object)(object)val != (Object)null && (Object)(object)val4 != (Object)null && Mathf.Abs(((Component)val4).transform.position.y - ((Component)val).transform.position.y - 4.5f) > 8f)
				{
					distances[i] = float.MaxValue;
				}
				if ((Object)(object)val4 != (Object)null)
				{
					((Behaviour)val4).enabled = false;
				}
			}
			Array.Sort(distances, lightOrder);
			for (int j = 0; j < Math.Min(28, lightOrder.Length); j++)
			{
				int num6 = lightOrder[j];
				Light val5 = geometry.Lamps[num6];
				if (!((Object)(object)val5 == (Object)null) && !(distances[j] > 3025f))
				{
					double num7 = (num3 + (double)num6 * 11.731) % 29.0;
					bool flag = CircusPlugin.Flicker.Value && num7 < 0.8 && (int)(num7 * 18.0 + (double)num6) % 3 == 0;
					((Behaviour)val5).enabled = !flag;
				}
			}
		}
	}
	internal static class CircusCaine
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__ReceiveState;

			public static HandleNamedMessageDelegate <1>__ReceiveRequest;
		}

		private const string StateMessage = "JLeonL.Circus.CaineState";

		private const string RequestMessage = "JLeonL.Circus.CaineRequest";

		private static Transform root;

		private static AudioSource source;

		private static AudioClip clip;

		private static CircusCaineRoute route;

		private static NetworkManager registered;

		private static int seed;

		private static float speed;

		private static float nextRequest;

		private static float nextSense;

		private static double epoch;

		private static bool ready;

		private static CircusCaineEncounter encounter = new CircusCaineEncounter();

		internal static void Initialize(MonoBehaviour runtime, string directory)
		{
			string text = Path.Combine(directory, "audio", "caine-encounter.wav");
			runtime.StartCoroutine(Load(File.Exists(text) ? text : Path.Combine(directory, "audio", "effects", "caine-encounter-fallback.wav")));
		}

		private static IEnumerator Load(string file)
		{
			if (!File.Exists(file))
			{
				CircusPlugin.Log.LogWarning((object)("CIRCUS_CAINE_AUDIO_MISSING " + file));
				yield break;
			}
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(file).AbsoluteUri, (AudioType)20);
			try
			{
				yield return request.SendWebRequest();
				if ((int)request.result == 1)
				{
					clip = DownloadHandlerAudioClip.GetContent(request);
				}
				else
				{
					CircusPlugin.Log.LogWarning((object)("CIRCUS_CAINE_AUDIO_FAILED " + request.error));
				}
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}

		internal static void BeginVisit()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			EndVisit();
			if (CircusPlugin.Stack == null || (Object)(object)CircusPlugin.MazeRoot == (Object)null)
			{
				return;
			}
			seed = CircusPlugin.Layout.Seed;
			route = new CircusCaineRoute(CircusPlugin.Stack);
			encounter = new CircusCaineEncounter();
			root = new GameObject("Caine_InteriorRunner").transform;
			root.SetParent(CircusPlugin.MazeRoot.transform, false);
			if (!CircusCharacterAssets.CreateCaine(root, 2.1f))
			{
				Object.Destroy((Object)(object)((Component)root).gameObject);
				root = null;
				CircusPlugin.Log.LogError((object)"CIRCUS_CAINE_MODEL_MISSING");
				return;
			}
			CircusHarmlessMob.Attach(root, inside: true, 2.1f);
			((Component)root.Find("CircusMobScanNode")).GetComponent<ScanNodeProperties>().subText = "Caine";
			source = ((Component)root).gameObject.AddComponent<AudioSource>();
			source.playOnAwake = false;
			source.loop = true;
			source.spatialBlend = 1f;
			source.dopplerLevel = 0f;
			source.rolloffMode = (AudioRolloffMode)1;
			source.minDistance = 3f;
			source.maxDistance = 28f;
			source.volume = 0.5f;
			source.priority = 100;
			((Component)root).gameObject.SetActive(false);
			Register(NetworkManager.Singleton);
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening || singleton.IsServer)
			{
				float movementSpeed = 4.6f;
				if ((Object)(object)StartOfRound.Instance != (Object)null)
				{
					PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
					foreach (PlayerControllerB val in allPlayerScripts)
					{
						if ((Object)(object)val != (Object)null && val.isPlayerControlled && !val.isPlayerDead)
						{
							movementSpeed = val.movementSpeed;
							break;
						}
					}
				}
				speed = CircusCaineRoute.SpeedFromPlayer(movementSpeed);
				double num;
				if (!((Object)(object)singleton != (Object)null) || !singleton.IsListening)
				{
					num = Time.time;
				}
				else
				{
					NetworkTime serverTime = singleton.ServerTime;
					num = ((NetworkTime)(ref serverTime)).Time;
				}
				epoch = num;
				ready = true;
				Send();
			}
			CircusPlugin.Log.LogInfo((object)("CIRCUS_CAINE_READY height=" + 2.1f + " floors=" + CircusPlugin.Stack.Count + " covered=" + string.Join(",", route.CoveredCells) + " points=" + route.Points.Length + " speed=" + (ready ? speed.ToString() : "awaiting host") + " harmless=True chase=False"));
		}

		private static void Register(NetworkManager net)
		{
			//IL_0045: 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_0050: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			if (!((Object)(object)registered == (Object)(object)net) && !((Object)(object)net == (Object)null) && net.CustomMessagingManager != null)
			{
				Unregister();
				registered = net;
				CustomMessagingManager customMessagingManager = net.CustomMessagingManager;
				object obj = <>O.<0>__ReceiveState;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = ReceiveState;
					<>O.<0>__ReceiveState = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("JLeonL.Circus.CaineState", (HandleNamedMessageDelegate)obj);
				CustomMessagingManager customMessagingManager2 = net.CustomMessagingManager;
				object obj2 = <>O.<1>__ReceiveRequest;
				if (obj2 == null)
				{
					HandleNamedMessageDelegate val2 = ReceiveRequest;
					<>O.<1>__ReceiveRequest = val2;
					obj2 = (object)val2;
				}
				customMessagingManager2.RegisterNamedMessageHandler("JLeonL.Circus.CaineRequest", (HandleNamedMessageDelegate)obj2);
			}
		}

		private static void ReceiveState(ulong sender, FastBufferReader reader)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (sender == 0L && CircusPlugin.Active && !((Object)(object)root == (Object)null) && !ready)
			{
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
				float num2 = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num2, default(ForPrimitives));
				double num3 = default(double);
				((FastBufferReader)(ref reader)).ReadValueSafe<double>(ref num3, default(ForPrimitives));
				if (num == seed && !float.IsNaN(num2) && !float.IsInfinity(num2) && !(num2 < 0.9f) && !(num2 > 54f) && !double.IsNaN(num3) && !double.IsInfinity(num3) && !(num3 < 0.0))
				{
					speed = num2;
					epoch = num3;
					ready = true;
				}
			}
		}

		private static void ReceiveRequest(ulong sender, FastBufferReader reader)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)registered == (Object)null) && registered.IsServer && CircusPlugin.Active && ready && !((Object)(object)root == (Object)null))
			{
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
				if (num == seed)
				{
					Send(sender);
				}
			}
		}

		private unsafe static void Send(ulong? recipient = null)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)registered == (Object)null || !registered.IsListening || !registered.IsServer || !ready)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(24, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref seed, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref speed, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref epoch, default(ForPrimitives));
				if (recipient.HasValue)
				{
					registered.CustomMessagingManager.SendNamedMessage("JLeonL.Circus.CaineState", recipient.Value, val, (NetworkDelivery)3);
				}
				else
				{
					registered.CustomMessagingManager.SendNamedMessageToAll("JLeonL.Circus.CaineState", val, (NetworkDelivery)3);
				}
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		internal unsafe static void Tick(double clock)
		{
			//IL_00d7: 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_00f8: 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_0075: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			if (!CircusPlugin.Active || (Object)(object)root == (Object)null || route == null)
			{
				return;
			}
			Register(NetworkManager.Singleton);
			if (!ready)
			{
				if (!((Object)(object)registered != (Object)null) || !registered.IsListening || !(Time.unscaledTime >= nextRequest))
				{
					return;
				}
				nextRequest = Time.unscaledTime + 1f;
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1);
				try
				{
					((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref seed, default(ForPrimitives));
					registered.CustomMessagingManager.SendNamedMessage("JLeonL.Circus.CaineRequest", 0uL, val, (NetworkDelivery)3);
					return;
				}
				finally
				{
					((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
				}
			}
			CaineRoutePose caineRoutePose = route.Sample(Math.Max(0.0, clock - epoch), speed);
			root.localPosition = caineRoutePose.Position;
			root.localRotation = Quaternion.Euler(0f, Mathf.Atan2(0f - caineRoutePose.Direction.x, 0f - caineRoutePose.Direction.z) * 57.29578f, 0f);
			if (!((Component)root).gameObject.activeSelf)
			{
				((Component)root).gameObject.SetActive(true);
			}
			if ((Object)(object)source.clip == (Object)null && (Object)(object)clip != (Object)null)
			{
				source.clip = clip;
			}
			PlayerControllerB val2 = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			bool flag = (Object)(object)val2 != (Object)null && val2.isInsideFactory && !val2.isPlayerDead;
			bool crossing = false;
			if (flag && Time.unscaledTime >= nextSense)
			{
				nextSense = Time.unscaledTime + 0.1f;
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val3 in allPlayerScripts)
				{
					if ((Object)(object)val3 == (Object)null || !val3.isPlayerControlled || val3.isPlayerDead || !val3.isInsideFactory)
					{
						continue;
					}
					Vector3 val4 = ((Component)val3).transform.position - root.position;
					if (!(Mathf.Abs(val4.y) > 2.5f) && !(((Vector3)(ref val4)).sqrMagnitude > 36f))
					{
						Vector3 val5 = (((Object)(object)val3.gameplayCamera != (Object)null) ? ((Component)val3.gameplayCamera).transform.position : (((Component)val3).transform.position + Vector3.up * 1.5f));
						if (!Physics.Linecast(root.position + Vector3.up * 1.5749999f, val5, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
						{
							crossing = true;
							break;
						}
					}
				}
			}
			bool flag2 = encounter.Tick(clock, flag, crossing);
			if (flag2 && (Object)(object)source.clip != (Object)null && !source.isPlaying)
			{
				source.Play();
			}
			else if (!flag2 && source.isPlaying)
			{
				source.Stop();
			}
		}

		internal static void EndVisit()
		{
			if ((Object)(object)source != (Object)null)
			{
				source.Stop();
			}
			if ((Object)(object)root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)root).gameObject);
			}
			root = null;
			source = null;
			route = null;
			ready = false;
			nextRequest = (nextSense = 0f);
			Unregister();
			CircusCharacterAssets.ForgetCaine();
		}

		private static void Unregister()
		{
			if ((Object)(object)registered != (Object)null && registered.CustomMessagingManager != null)
			{
				registered.CustomMessagingManager.UnregisterNamedMessageHandler("JLeonL.Circus.CaineState");
				registered.CustomMessagingManager.UnregisterNamedMessageHandler("JLeonL.Circus.CaineRequest");
			}
			registered = null;
		}

		internal static void Dispose()
		{
			EndVisit();
			if ((Object)(object)clip != (Object)null)
			{
				Object.Destroy((Object)(object)clip);
			}
			clip = null;
		}
	}
	internal static class CircusCharacterAssets
	{
		private sealed class Asset
		{
			public CharacterAssetData Data;

			public Mesh[] Meshes;

			public Material[] Materials;
		}

		private sealed class Actor
		{
			public Transform Root;

			public Transform[] Bones;

			public Asset Asset;

			public CircusPatrol Patrol;

			public int Index;

			public float Blend;

			public float NextTick;

			public float LastTick;

			public bool Inside;

			public CharacterClipData WalkClip;

			public CharacterClipData IdleClip;
		}

		private static readonly Dictionary<string, Asset> assets = new Dictionary<string, Asset>();

		private static readonly List<Actor> actors = new List<Actor>();

		private static readonly List<Texture2D> textures = new List<Texture2D>();

		private static string directory;

		private static bool initialized;

		private static readonly string[] keys = new string[7] { "horror_clown", "killer_clown", "pomni", "mummy", "wraith", "caine", "killer_clown_walker" };

		public static int ActorCount => actors.Count;

		public static void Initialize(string pluginDirectory)
		{
			directory = Path.Combine(pluginDirectory, "characters");
			CircusGeometry.CharacterFactory = Create;
		}

		private static void EnsureReady()
		{
			if (initialized)
			{
				return;
			}
			initialized = true;
			string[] array = keys;
			foreach (string text in array)
			{
				try
				{
					assets.Add(text, Load(text));
				}
				catch (Exception ex)
				{
					CircusPlugin.Log.LogError((object)("CIRCUS_CHARACTER_ASSET_FAILED " + text + ": " + ex));
				}
			}
			CircusPlugin.Log.LogInfo((object)("CIRCUS_CHARACTER_ASSETS loaded=" + assets.Count + "/" + keys.Length + "; weighted rigs and three LODs."));
		}

		private static Vector3 V(float[] a, int offset = 0)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(a[offset], a[offset + 1], a[offset + 2]);
		}

		private static Quaternion Q(float[] a, int offset)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Quaternion(a[offset], a[offset + 1], a[offset + 2], a[offset + 3]);
		}

		private static Texture2D Texture(string name, bool normal)
		{
			//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_0034: 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_0043: Expected O, but got Unknown
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			if (Path.GetFileName(name) != name)
			{
				throw new InvalidDataException("Invalid character texture path");
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, normal)
			{
				name = name,
				filterMode = (FilterMode)2,
				anisoLevel = 2
			};
			if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(directory, name)), false))
			{
				throw new InvalidDataException("Cannot decode " + name);
			}
			if (!normal)
			{
				val.Compress(true);
			}
			val.Apply(true, true);
			textures.Add(val);
			return val;
		}

		private static Asset Load(string key)
		{
			//IL_0098: 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_00bc: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: 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_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Expected O, but got Unknown
			CharacterAssetData characterAssetData = CharacterAssetData.Read(Path.Combine(directory, key + ".cskin"));
			if (characterAssetData.Key != key)
			{
				throw new InvalidDataException("Character key mismatch");
			}
			Asset asset = new Asset
			{
				Data = characterAssetData,
				Materials = (Material[])(object)new Material[characterAssetData.Materials.Length],
				Meshes = (Mesh[])(object)new Mesh[characterAssetData.Lods.Length]
			};
			Shader val = Shader.Find("HDRP/Lit");
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("HDRP/Lit is not loaded");
			}
			for (int i = 0; i < asset.Materials.Length; i++)
			{
				CharacterMaterialData characterMaterialData = characterAssetData.Materials[i];
				Material val2 = new Material(val)
				{
					name = "CircusImported_" + key + "_" + characterMaterialData.Name
				};
				float[] color = characterMaterialData.Color;
				val2.SetColor("_BaseColor", new Color(color[0] * 0.88f, color[1] * 0.88f, color[2] * 0.88f, 1f));
				val2.SetFloat("_Metallic", Mathf.Min(0.15f, characterMaterialData.Surface[0]));
				val2.SetFloat("_Smoothness", Mathf.Clamp01(1f - characterMaterialData.Surface[1]));
				Texture2D val3 = Texture(characterMaterialData.Albedo, normal: false);
				if ((Object)(object)val3 != (Object)null)
				{
					val2.SetTexture("_BaseColorMap", (Texture)(object)val3);
				}
				Texture2D val4 = Texture(characterMaterialData.Normal, normal: true);
				if ((Object)(object)val4 != (Object)null)
				{
					val2.SetTexture("_NormalMap", (Texture)(object)val4);
					val2.SetFloat("_NormalMapSpace", 0f);
					val2.SetFloat("_NormalScale", 0.7f);
					val2.EnableKeyword("_NORMALMAP_TANGENT_SPACE");
				}
				val2.SetFloat("_DoubleSidedEnable", 1f);
				val2.SetFloat("_CullMode", 0f);
				val2.SetFloat("_CullModeForward", 0f);
				val2.SetVector("_DoubleSidedConstants", new Vector4(1f, 1f, -1f, 0f));
				val2.EnableKeyword("_DOUBLESIDED_ON");
				asset.Materials[i] = val2;
			}
			for (int j = 0; j < asset.Meshes.Length; j++)
			{
				CharacterMeshData characterMeshData = characterAssetData.Lods[j];
				int num = characterMeshData.Vertices.Length / 8;
				Vector3[] array = (Vector3[])(object)new Vector3[num];
				Vector3[] array2 = (Vector3[])(object)new Vector3[num];
				Vector2[] array3 = (Vector2[])(object)new Vector2[num];
				BoneWeight[] array4 = (BoneWeight[])(object)new BoneWeight[num];
				for (int k = 0; k < num; k++)
				{
					array[k] = V(characterMeshData.Vertices, k * 8);
					array2[k] = V(characterMeshData.Vertices, k * 8 + 3);
					array3[k] = new Vector2(characterMeshData.Vertices[k * 8 + 6], characterMeshData.Vertices[k * 8 + 7]);
					int num2 = k * 4;
					int num3 = k;
					BoneWeight val5 = default(BoneWeight);
					((BoneWeight)(ref val5)).boneIndex0 = characterMeshData.Bones[num2];
					((BoneWeight)(ref val5)).boneIndex1 = characterMeshData.Bones[num2 + 1];
					((BoneWeight)(ref val5)).boneIndex2 = characterMeshData.Bones[num2 + 2];
					((BoneWeight)(ref val5)).boneIndex3 = characterMeshData.Bones[num2 + 3];
					((BoneWeight)(ref val5)).weight0 = characterMeshData.Weights[num2];
					((BoneWeight)(ref val5)).weight1 = characterMeshData.Weights[num2 + 1];
					((BoneWeight)(ref val5)).weight2 = characterMeshData.Weights[num2 + 2];
					((BoneWeight)(ref val5)).weight3 = characterMeshData.Weights[num2 + 3];
					array4[num3] = val5;
				}
				Mesh val6 = new Mesh
				{
					name = "CircusSkin_" + key + "_LOD" + j,
					indexFormat = (IndexFormat)1
				};
				val6.vertices = array;
				val6.normals = array2;
				val6.uv = array3;
				val6.boneWeights = array4;
				val6.bindposes = characterAssetData.BindPositions.Select((float[] p) => Matrix4x4.Translate(-V(p))).ToArray();
				val6.subMeshCount = characterMeshData.Indices.Length;
				for (int num4 = 0; num4 < characterMeshData.Indices.Length; num4++)
				{
					val6.SetTriangles(characterMeshData.Indices[num4], num4);
				}
				val6.RecalculateTangents();
				val6.RecalculateBounds();
				asset.Meshes[j] = val6;
			}
			CircusPlugin.Log.LogInfo((object)("CIRCUS_CHARACTER_READY " + key + " bones=" + characterAssetData.Parents.Length + " triangles=" + string.Join(",", characterAssetData.Lods.Select((CharacterMeshData l) => l.Indices.Sum((int[] s) => s.Length) / 3))));
			return asset;
		}

		private static bool Create(Transform parent, string kind, int index, CircusPatrol patrol)
		{
			EnsureReady();
			bool inside = kind == "clown_walker_inside";
			string text = keys[(kind == "mummy") ? (3 + index % 2) : (index % 3)];
			if (patrol != null)
			{
				CircusHarmlessMob.Attach(parent, inside, text switch
				{
					"wraith" => 2.6f, 
					"killer_clown" => 2.4f, 
					"horror_clown" => 2.35f, 
					"pomni" => 2.15f, 
					_ => 2.5f, 
				});
			}
			if (patrol != null && text == "killer_clown")
			{
				text = "killer_clown_walker";
			}
			return Spawn(parent, text, index, patrol, inside) != null;
		}

		internal static bool CreateCaine(Transform parent, float height)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			EnsureReady();
			Actor actor = Spawn(parent, "caine", 0, null, inside: true);
			if (actor == null)
			{
				return false;
			}
			actor.Root.localScale = Vector3.one * (height / 2f);
			return true;
		}

		internal static void ForgetCaine()
		{
			actors.RemoveAll((Actor a) => a.Asset.Data.Key == "caine");
		}

		private static Actor Spawn(Transform parent, string key, int index, CircusPatrol patrol, bool inside)
		{
			//IL_0026: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			if (!assets.TryGetValue(key, out var asset))
			{
				return null;
			}
			Transform transform = new GameObject("Imported_" + key).transform;
			transform.SetParent(parent, false);
			CharacterAssetData data = asset.Data;
			Transform[] array = (Transform[])(object)new Transform[data.Parents.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new GameObject(data.BoneNames[i]).transform;
				array[i].SetParent((data.Parents[i] < 0) ? transform : array[data.Parents[i]], false);
				array[i].localPosition = V(data.LocalPositions[i]);
			}
			LOD[] array2 = (LOD[])(object)new LOD[asset.Meshes.Length];
			float[] array3 = new float[3] { 0.15f, 0.055f, 0.008f };
			for (int j = 0; j < array2.Length; j++)
			{
				GameObject val = new GameObject("CharacterLOD" + j);
				val.transform.SetParent(transform, false);
				SkinnedMeshRenderer val2 = val.AddComponent<SkinnedMeshRenderer>();
				val2.sharedMesh = asset.Meshes[j];
				val2.bones = array;
				val2.rootBone = array[0];
				((Renderer)val2).sharedMaterials = data.Lods[j].Materials.Select((int m) => asset.Materials[m]).ToArray();
				val2.quality = (SkinQuality)4;
				((Renderer)val2).localBounds = new Bounds(new Vector3(0f, 1f, 0f), new Vector3(5f, 6f, 5f));
				val2.updateWhenOffscreen = false;
				((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val2).receiveShadows = true;
				array2[j] = new LOD(array3[j], (Renderer[])(object)new Renderer[1] { (Renderer)val2 });
			}
			LODGroup obj = ((Component)transform).gameObject.AddComponent<LODGroup>();
			obj.SetLODs(array2);
			obj.localReferencePoint = Vector3.up;
			obj.size = 3.4f;
			CharacterClipData characterClipData = data.Clips.FirstOrDefault((CharacterClipData c) => c.Name == "wave") ?? data.Clips[0];
			CharacterClipData characterClipData2 = ((patrol == null) ? characterClipData : (data.Clips.FirstOrDefault((CharacterClipData c) => c.Name == "walk") ?? characterClipData));
			CharacterClipData idleClip = ((patrol == null) ? characterClipData : (data.Clips.FirstOrDefault((CharacterClipData c) => c.Name == "idle") ?? characterClipData2));
			Actor actor = new Actor
			{
				Root = transform,
				Bones = array,
				Asset = asset,
				Patrol = patrol,
				Index = index,
				Inside = inside,
				WalkClip = characterClipData2,
				IdleClip = idleClip,
				Blend = ((patrol != null) ? 1 : 0)
			};
			actors.Add(actor);
			Apply(actor, 0.0);
			return actor;
		}

		public static void Tick(double clock)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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)
			PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			foreach (Actor actor in actors)
			{
				if (!((Object)(object)actor.Root == (Object)null) && actor.Inside == val.isInsideFactory && !(unscaledTime < actor.NextTick))
				{
					Vector3 val2 = actor.Root.position - ((Component)val).transform.position;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					actor.NextTick = unscaledTime + ((!(actor.Asset.Data.Key == "caine")) ? ((sqrMagnitude < 1225f) ? (1f / 30f) : (1f / 12f)) : ((sqrMagnitude < 1225f) ? (1f / 60f) : (1f / 24f)));
					if (!(sqrMagnitude > 28900f))
					{
						float num = Mathf.Clamp(unscaledTime - actor.LastTick, 0f, 0.2f);
						actor.LastTick = unscaledTime;
						float num2 = ((actor.Patrol != null && actor.Patrol.Sample(clock + (double)(actor.Index * 17)).Walking) ? 1 : 0);
						actor.Blend = Mathf.MoveTowards(actor.Blend, num2, num * 5f);
						Apply(actor, clock + (double)actor.Index * 0.73);
					}
				}
			}
		}

		private static void Sample(CharacterClipData clip, double time, int stride, out int a, out int b, out float blend)
		{
			double num = (time % (double)clip.Duration + (double)clip.Duration) % (double)clip.Duration / (double)clip.Duration * (double)(clip.Frames - 1);
			int num2 = (int)num;
			a = num2 * stride;
			b = Math.Min(num2 + 1, clip.Frames - 1) * stride;
			blend = (float)(num - (double)num2);
		}

		private static void Apply(Actor actor, double time)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0082: 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_0096: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0118: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			CharacterAssetData data = actor.Asset.Data;
			int stride = 3 + actor.Bones.Length * 4;
			CharacterClipData walkClip = actor.WalkClip;
			CharacterClipData idleClip = actor.IdleClip;
			Sample(walkClip, time, stride, out var a, out var b, out var blend);
			Sample(idleClip, time, stride, out var a2, out var b2, out var blend2);
			actor.Bones[0].localPosition = V(data.LocalPositions[0]) + Vector3.Lerp(Vector3.Lerp(V(idleClip.Samples, a2), V(idleClip.Samples, b2), blend2), Vector3.Lerp(V(walkClip.Samples, a), V(walkClip.Samples, b), blend), actor.Blend);
			for (int i = 0; i < actor.Bones.Length; i++)
			{
				int num = 3 + i * 4;
				Quaternion val = Quaternion.Slerp(Q(walkClip.Samples, a + num), Q(walkClip.Samples, b + num), blend);
				Quaternion val2 = Quaternion.Slerp(Q(idleClip.Samples, a2 + num), Q(idleClip.Samples, b2 + num), blend2);
				actor.Bones[i].localRotation = Quaternion.Slerp(val2, val, actor.Blend);
			}
		}

		public static void EndVisit()
		{
			actors.Clear();
		}

		public static void Dispose()
		{
			actors.Clear();
			CircusGeometry.CharacterFactory = null;
			foreach (Asset value in assets.Values)
			{
				Mesh[] meshes = value.Meshes;
				for (int i = 0; i < meshes.Length; i++)
				{
					Object.Destroy((Object)(object)meshes[i]);
				}
				Material[] materials = value.Materials;
				for (int i = 0; i < materials.Length; i++)
				{
					Object.Destroy((Object)(object)materials[i]);
				}
			}
			foreach (Texture2D texture in textures)
			{
				Object.Destroy((Object)(object)texture);
			}
			textures.Clear();
			assets.Clear();
			initialized = false;
		}
	}
	[HarmonyPatch]
	internal static class CircusClock
	{
		internal static bool Hide
		{
			get
			{
				PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
				if (CircusPlugin.Active && (Object)(object)val != (Object)null)
				{
					return val.isInsideFactory;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(HUDManager), "SetClockVisible")]
		[HarmonyPrefix]
		private static void Visibility(ref bool visible)
		{
			if (Hide)
			{
				visible = false;
			}
		}

		[HarmonyPatch(typeof(HUDManager), "Update")]
		[HarmonyPostfix]
		private static void Enforce(HUDManager __instance)
		{
			if (Hide && __instance.Clock != null)
			{
				__instance.Clock.targetAlpha = 0f;
				if ((Object)(object)__instance.Clock.canvasGroup != (Object)null)
				{
					__instance.Clock.canvasGroup.alpha = 0f;
				}
			}
		}
	}
	internal static class CircusDiagnostics
	{
		private static readonly string Report = Path.Combine(Paths.PluginPath, "CircusLabyrinth-startup.txt");

		internal static void Write(string stage, string body)
		{
			try
			{
				File.AppendAllText(Report, DateTime.UtcNow.ToString("O") + " [" + stage + "] " + body + "\n");
			}
			catch (Exception ex)
			{
				ManualLogSource log = CircusPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Diagnostic write failed: " + ex.Message));
				}
			}
		}

		internal static void StartWatcher(CircusPlugin plugin)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			GameObject val = new GameObject("CircusStartupWatcher")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<CircusStartupWatcher>();
		}

		internal static void Audit(string stage)
		{
			//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)
			CircusPlugin instance = CircusPlugin.Instance;
			PluginInfo value;
			Assembly assembly = ((!Chainloader.PluginInfos.TryGetValue("imabatby.lethallevelloader", out value)) ? null : ((object)value.Instance)?.GetType().Assembly);
			Assembly assembly2 = typeof(Plugin).Assembly;
			string text = string.Join(" | ", from a in AppDomain.CurrentDomain.GetAssemblies()
				where a.GetName().Name == "LethalLevelLoader"
				select a.FullName + " at " + a.Location);
			Patches patchInfo = Harmony.GetPatchInfo((MethodBase)AccessTools.Method(typeof(StartOfRound), "Awake", (Type[])null, (Type[])null));
			string text2 = ((patchInfo == null) ? "none" : string.Join(",", patchInfo.Owners));
			BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.NonPublic;
			Delegate obj = assembly2.GetType("LethalLevelLoader.Plugin").GetField("onBeforeSetup", bindingAttr)?.GetValue(null) as Delegate;
			Delegate obj2 = assembly2.GetType("LethalLevelLoader.Plugin").GetField("onSetupComplete", bindingAttr)?.GetValue(null) as Delegate;
			object[] obj3 = new object[9]
			{
				(Object)(object)instance != (Object)null,
				(Object)(object)CircusPlugin.Runtime != (Object)null,
				(Object)(object)CircusPlugin.Runtime != (Object)null && ((Component)CircusPlugin.Runtime).gameObject.activeInHierarchy,
				assembly == assembly2,
				((object)obj != null) ? obj.GetInvocationList().Length : 0,
				((object)obj2 != null) ? obj2.GetInvocationList().Length : 0,
				text2,
				null,
				null
			};
			Scene activeScene = SceneManager.GetActiveScene();
			obj3[7] = ((Scene)(ref activeScene)).name;
			obj3[8] = text;
			Write(stage, string.Format("bootstrapAlive={0}; runtimeAlive={1}; runtimeActive={2}; sameLoaderAssembly={3}; beforeListeners={4}; completeListeners={5}; awakePatchOwners={6}; scene={7}; loaderAssemblies={8}", obj3));
		}
	}
	public sealed class CircusStartupWatcher : MonoBehaviour
	{
		private float next;

		private string lastScene;

		private void Update()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			if (!(Time.realtimeSinceStartup < next) || !(name == lastScene))
			{
				next = Time.realtimeSinceStartup + 10f;
				lastScene = name;
				CircusDiagnostics.Audit("WATCH");
				if (Plugin.IsLobbyInitialized && (Object)(object)CircusPlugin.Runtime != (Object)null)
				{
					((Behaviour)this).enabled = false;
				}
			}
		}
	}
	[BepInPlugin("JLeonL.CircusLabyrinth", "Circus Labyrinth", "0.14.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class CircusPlugin : BaseUnityPlugin
	{
		private static Transform nativeEmergencyVisual;

		public const string Guid = "JLeonL.CircusLabyrinth";

		internal static CircusPlugin Instance;

		internal static CircusRuntime Runtime;

		internal static ManualLogSource Log;

		internal static SelectableLevel Moon;

		private static ExtendedLevel extendedMoon;

		private static bool moonConfigured;

		internal static GameObject ExteriorRoot;

		internal static GameObject MazeRoot;

		internal static CircusGeometry Exterior;

		internal static CircusGeometry Interior;

		internal static MazeLayout Layout;

		internal static MazeStack Stack;

		internal static ConfigEntry<int> RoutePrice;

		internal static ConfigEntry<float> MusicVolume;

		internal static ConfigEntry<string> MusicFile;

		internal static ConfigEntry<bool> Flicker;

		internal static ConfigEntry<bool> TestMode;

		internal static Vector3 ExteriorOffset;

		internal static readonly Vector3 MazeOffset = CircusGeometry.MazeOrigin;

		internal static readonly Vector3[] DoorPositions = (Vector3[])(object)new Vector3[6];

		internal static readonly Vector3[] Arrivals = (Vector3[])(object)new Vector3[6];

		private static readonly List<EntranceTeleport> templateEntrances = new List<EntranceTeleport>();

		internal static Sprite Hand;

		private static bool hadCulling;

		private static readonly Dictionary<Camera, bool> cameraCulling = new Dictionary<Camera, bool>();

		private static Light[] templateLights = Array.Empty<Light>();

		private static float nextSceneGuard;

		private static int testIndex;

		internal static bool Active
		{
			get
			{
				if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.currentLevel != (Object)null)
				{
					return StartOfRound.Instance.currentLevel.PlanetName == "77 Circus Labyrinth";
				}
				return false;
			}
		}

		private static void CaptureNativeDoorVisuals(GameObject[] roots)
		{
			nativeEmergencyVisual = roots.SelectMany((GameObject r) => r.GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)((Component)t).gameObject).name == "FireExitDoorContainer" && ((Component)t).GetComponentsInChildren<MeshRenderer>(true).Any((MeshRenderer r) => ((Renderer)r).sharedMaterials.Any((Material m) => (Object)(object)m != (Object)null && ((Object)m).name.StartsWith("ClosetRedDoor")))));
			if ((Object)(object)nativeEmergencyVisual != (Object)null)
			{
				Log.LogInfo((object)("CIRCUS_NATIVE_FIRE_EXIT_SOURCE " + ((Object)nativeEmergencyVisual).name));
			}
		}

		private static void InstallDoorVisual(EntranceTeleport portal, bool main)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: 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)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_0171: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: 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_0107: 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_0122: 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_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Component)portal).transform.Find("CircusNativeDoorVisual") != (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)portal).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			GameObject val = new GameObject("CircusNativeDoorVisual");
			val.transform.SetParent(((Component)portal).transform, false);
			EntranceTeleport val2 = ((IEnumerable<EntranceTeleport>)templateEntrances).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport p) => (Object)(object)p != (Object)null && p.entranceId == 0 && p.isEntranceToBuilding && (Object)(object)p.thisEntranceAnimator != (Object)null));
			if (!main && !portal.isEntranceToBuilding && (Object)(object)nativeEmergencyVisual != (Object)null)
			{
				CopyVisualHierarchy(nativeEmergencyVisual, val.transform);
				val.transform.localScale = nativeEmergencyVisual.lossyScale;
				Bounds val3 = VisualBounds(val.transform, ((Component)portal).transform);
				if (((Bounds)(ref val3)).size.z > ((Bounds)(ref val3)).size.x)
				{
					val.transform.localRotation = Quaternion.Euler(0f, -90f, 0f);
					val3 = VisualBounds(val.transform, ((Component)portal).transform);
				}
				float num = Mathf.Min(3.3f / Mathf.Max(0.1f, ((Bounds)(ref val3)).size.y), 2.1f / Mathf.Max(0.1f, ((Bounds)(ref val3)).size.x));
				Transform transform = val.transform;
				transform.localScale *= num;
				val.transform.localPosition = new Vector3((0f - ((Bounds)(ref val3)).center.x) * num, (0f - ((Bounds)(ref val3)).min.y) * num, (0f - ((Bounds)(ref val3)).center.z) * num);
				Log.LogInfo((object)("CIRCUS_NATIVE_FIRE_EXIT_VISUAL " + ((Object)portal).name + " source=" + ((Object)nativeEmergencyVisual).name + " meshes=" + val.GetComponentsInChildren<Renderer>().Length));
			}
			else if (main && (Object)(object)val2 != (Object)null)
			{
				CopyVisualHierarchy(((Component)val2.thisEntranceAnimator).transform, val.transform);
				val.transform.localRotation = Quaternion.identity;
				val.transform.localScale = ((Component)val2.thisEntranceAnimator).transform.lossyScale;
				Renderer[] componentsInChildren2 = val.GetComponentsInChildren<Renderer>();
				if (componentsInChildren2.Length != 0)
				{
					Bounds val4 = default(Bounds);
					bool flag = true;
					componentsInChildren = componentsInChildren2;
					foreach (Renderer val5 in componentsInChildren)
					{
						Bounds bounds = val5.bounds;
						for (int num2 = -1; num2 <= 1; num2 += 2)
						{
							for (int num3 = -1; num3 <= 1; num3 += 2)
							{
								for (int num4 = -1; num4 <= 1; num4 += 2)
								{
									Vector3 val6 = ((Component)portal).transform.InverseTransformPoint(((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)num2, (float)num3, (float)num4)));
									if (flag)
									{
										((Bounds)(ref val4))..ctor(val6, Vector3.zero);
										flag = false;
									}
									else
									{
										((Bounds)(ref val4)).Encapsulate(val6);
									}
								}
							}
						}
						val5.enabled = true;
						val5.allowOcclusionWhenDynamic = false;
					}
					float num5 = Mathf.Min(3.45f / Mathf.Max(0.1f, ((Bounds)(ref val4)).size.y), 4.2f / Mathf.Max(0.1f, ((Bounds)(ref val4)).size.x));
					Transform transform2 = val.transform;
					transform2.localScale *= num5;
					val.transform.localPosition = new Vector3((0f - ((Bounds)(ref val4)).center.x) * num5, (0f - ((Bounds)(ref val4)).min.y) * num5, (0f - ((Bounds)(ref val4)).center.z) * num5);
				}
				portal.thisEntranceAnimator = val.GetComponent<Animator>();
				if ((Object)(object)portal.thisEntranceAnimator != (Object)null)
				{
					portal.thisEntranceAnimator.Rebind();
				}
				Log.LogInfo((object)("CIRCUS_NATIVE_MAIN_VISUAL " + ((Object)portal).name + " source=" + ((Object)val2.thisEntranceAnimator).name + " meshes=" + componentsInChildren2.Length));
			}
			else
			{
				CircusGeometry circusGeometry = new CircusGeometry(val.transform, highDefinition: true);
				circusGeometry.ExitDoor(Vector3.zero, "");
				circusGeometry.Flush();
				if (main)
				{
					Log.LogWarning((object)"Native scene main-door Animator was unavailable; functional native A entrance uses a temporary facade.");
				}
				else if (!portal.isEntranceToBuilding)
				{
					Log.LogWarning((object)"Native scene fire-exit visual unavailable; keeping a functional emergency facade.");
				}
			}
		}

		private static Bounds VisualBounds(Transform root, Transform space)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_0092: 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_00b0: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			bool flag = true;
			MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if ((Object)(object)val.sharedMesh == (Object)null || (Object)(object)((Component)val).GetComponent<MeshRenderer>() == (Object)null)
				{
					continue;
				}
				Bounds bounds = val.sharedMesh.bounds;
				for (int j = -1; j <= 1; j += 2)
				{
					for (int k = -1; k <= 1; k += 2)
					{
						for (int l = -1; l <= 1; l += 2)
						{
							Vector3 val2 = space.InverseTransformPoint(((Component)val).transform.TransformPoint(((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)j, (float)k, (float)l))));
							if (flag)
							{
								((Bounds)(ref result))..ctor(val2, Vector3.zero);
								flag = false;
							}
							else
							{
								((Bounds)(ref result)).Encapsulate(val2);
							}
						}
					}
				}
			}
			return result;
		}

		private static void CopyVisualHierarchy(Transform source, Transform target)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			MeshFilter component = ((Component)source).GetComponent<MeshFilter>();
			MeshRenderer component2 = ((Component)source).GetComponent<MeshRenderer>();
			if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
			{
				((Component)target).gameObject.layer = 8;
				((Component)target).gameObject.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
				MeshRenderer obj = ((Component)target).gameObject.AddComponent<MeshRenderer>();
				((Renderer)obj).sharedMaterials = ((Renderer)component2).sharedMaterials;
				((Renderer)obj).allowOcclusionWhenDynamic = false;
			}
			Animator component3 = ((Component)source).GetComponent<Animator>();
			if ((Object)(object)component3 != (Object)null)
			{
				Animator obj2 = ((Component)target).gameObject.AddComponent<Animator>();
				obj2.runtimeAnimatorController = component3.runtimeAnimatorController;
				obj2.cullingMode = (AnimatorCullingMode)0;
			}
			foreach (Transform item in source)
			{
				Transform val = item;
				Transform transform = new GameObject(((Object)val).name).transform;
				transform.SetParent(target, false);
				transform.localPosition = val.localPosition;
				transform.localRotation = val.localRotation;
				transform.localScale = val.localScale;
				CopyVisualHierarchy(val, transform);
			}
		}

		private void Awake()
		{
			//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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			string name = ((Object)((Component)this).gameObject).name;
			Scene scene = ((Component)this).gameObject.scene;
			CircusDiagnostics.Write("AWAKE", $"pluginObject={name}, scene={((Scene)(ref scene)).name}, active={((Component)this).gameObject.activeInHierarchy}");
			RoutePrice = ((BaseUnityPlugin)this).Config.Bind<int>("Moon", "RoutePrice", 0, "Travel cost. Free while testing the first playable build.");
			MusicVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "MusicVolume", 0.22f, new ConfigDescription("Map soundtrack volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			MusicFile = ((BaseUnityPlugin)this).Config.Bind<string>("Audio", "MusicFile", "audio/night-at-the-carnival.ogg", "Local OGG, WAV or MP3, relative to CircusLabyrinth.dll or an absolute path. Missing or invalid files use the original calliope fallback.");
			Flicker = ((BaseUnityPlugin)this).Config.Bind<bool>("Visuals", "FlickeringLamps", true, "Occasional short streetlamp flickers.");
			TestMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "EnableTestControls", false, "F8: cycle entrance locations for local testing on the host. F9: report navigation and portal health.");
			Plugin.onBeforeSetup += ConfigureMoon;
			Plugin.onSetupComplete += ReportRegistration;
			SceneManager.sceneLoaded += SceneLoaded;
			SceneManager.sceneUnloaded += SceneUnloaded;
			Harmony.CreateAndPatchAll(typeof(CircusPlugin).Assembly, "JLeonL.CircusLabyrinth");
			GameObject val = new GameObject("CircusLabyrinth_Runtime")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val);
			Runtime = val.AddComponent<CircusRuntime>();
			CircusGeometry.TextureDirectory = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "textures");
			CircusCharacterAssets.Initialize(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			CircusScrap.Initialize(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			CircusDiagnostics.StartWatcher(this);
			CircusDiagnostics.Audit("AWAKE_PATCHED");
			RegisterContentEarly();
			CircusSoundtrack.Initialize((MonoBehaviour)(object)Runtime, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			CircusAmbience.Initialize((MonoBehaviour)(object)Runtime, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			CircusHedgeAmbience.Initialize((MonoBehaviour)(object)Runtime, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			CircusCaine.Initialize((MonoBehaviour)(object)Runtime, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			Log.LogInfo((object)"Circus Labyrinth 0.14.1 loaded. Rebuilt standing killer clown with separate preserved riders, private hedge ambience and bundled original audio fallbacks.");
		}

		private void OnDestroy()
		{
			CircusDiagnostics.Write("BOOTSTRAP_DESTROY", "protectedRuntimeAlive=" + ((Object)(object)Runtime != (Object)null));
		}

		internal static void Shutdown()
		{
			Plugin.onBeforeSetup -= ConfigureMoon;
			Plugin.onSetupComplete -= ReportRegistration;
			SceneManager.sceneLoaded -= SceneLoaded;
			SceneManager.sceneUnloaded -= SceneUnloaded;
			Harmony.UnpatchID("JLeonL.CircusLabyrinth");
			CircusLoading.Stop();
			CircusSoundtrack.Dispose();
			CircusAmbience.Dispose();
			CircusHedgeAmbience.Dispose();
			CircusCaine.Dispose();
			CircusHazards.Dispose();
			CircusParkourRewards.EndVisit();
			CircusMobBridge.EndVisit();
			CircusSlides.EndVisit();
			CircusCharacterAssets.Dispose();
			CircusScanNodes.EndVisit();
			CircusScrap.Dispose();
			RestoreCameras();
		}

		private static void RegisterContentEarly()
		{
			PatchedContent.RegisterExtendedMod(ExtendedMod.Create("Circus Labyrinth", "JLeonL"));
			Log.LogInfo((object)"Circus empty content container registered; awaiting the lobby's planet assets.");
		}

		private static void ConfigureMoon()
		{
			ConfigureFrom(null);
		}

		internal static void ConfigureFrom(SelectableLevel[] loadedLevels)
		{
			CircusDiagnostics.Write("CONFIGURE_ENTER", "configured=" + moonConfigured + " levels=" + ((loadedLevels == null) ? (-1) : loadedLevels.Length));
			if (moonConfigured)
			{
				return;
			}
			try
			{
				ConfigureMoonCore(loadedLevels);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("CIRCUS_REGISTRATION_FAILED: " + ex));
			}
		}

		private static void ConfigureMoonCore(SelectableLevel[] loadedLevels)
		{
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Expected O, but got Unknown
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Expected O, but got Unknown
			SelectableLevel val = ((IEnumerable<SelectableLevel>)(loadedLevels ?? Resources.FindObjectsOfTypeAll<SelectableLevel>())).FirstOrDefault((Func<SelectableLevel, bool>)((SelectableLevel l) => l.PlanetName != null && l.PlanetName.Contains("Experimentation")));
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)"Cannot register Circus: Experimentation template missing.");
				return;
			}
			Animator val2 = (((Object)(object)val.planetPrefab != (Object)null) ? val.planetPrefab.GetComponent<Animator>() : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.runtimeAnimatorController == (Object)null)
			{
				throw new InvalidOperationException("The loaded Experimentation planet prefab or its Animator controller is missing.");
			}
			Moon = Object.Instantiate<SelectableLevel>(val);
			((Object)Moon).name = "CircusLabyrinthLevel";
			Moon.PlanetName = "77 Circus Labyrinth";
			Moon.LevelDescription = "CIRCUS LABYRINTH\nAn abandoned island fairground. The clown's mouth leads into a night-time hedge maze.\nEmergency exits: carousel and Ferris wheel. All three entrances are connected.\nThe paths change on every landing.\n";
			Moon.riskLevel = "A";
			Moon.factorySizeMultiplier = val.factorySizeMultiplier;
			Moon.minScrap = 24;
			Moon.maxScrap = 35;
			Moon.minTotalScrapValue = 450;
			Moon.maxTotalScrapValue = 900;
			Moon.spawnableScrap = new List<SpawnableItemWithRarity>(val.spawnableScrap);
			Moon.Enemies = new List<SpawnableEnemyWithRarity>();
			EnemyType val3 = (from e in (loadedLevels ?? Resources.FindObjectsOfTypeAll<SelectableLevel>()).SelectMany((SelectableLevel l) => l.OutsideEnemies)
				select e.enemyType).FirstOrDefault((Func<EnemyType, bool>)((EnemyType e) => (Object)(object)e != (Object)null && (Object)(object)e.enemyPrefab != (Object)null && (Object)(object)e.enemyPrefab.GetComponent<MouthDogAI>() != (Object)null));
			if ((Object)(object)val3 == (Object)null)
			{
				throw new InvalidOperationException("The native Eyeless Dog enemy prefab was not loaded.");
			}
			Moon.OutsideEnemies = new List<SpawnableEnemyWithRarity>
			{
				new SpawnableEnemyWithRarity(val3, 100)
			};
			Moon.DaytimeEnemies = new List<SpawnableEnemyWithRarity>();
			Moon.maxEnemyPowerCount = 0;
			Moon.maxDaytimeEnemyPowerCount = 0;
			Moon.maxOutsideEnemyPowerCount = 6;
			Moon.enemySpawnChanceThroughoutDay = AnimationCurve.Constant(0f, 1f, 0f);
			Moon.daytimeEnemySpawnChanceThroughDay = AnimationCurve.Constant(0f, 1f, 0f);
			Log.LogInfo((object)("CIRCUS_ENEMIES outside=" + val3.enemyName + " only; inside=0 daytime=0."));
			Moon.spawnableOutsideObjects = Array.Empty<SpawnableOutsideObjectWithRarity>();
			Moon.spawnableMapObjects = Array.Empty<SpawnableMapObject>();
			Moon.indoorMapHazards = Array.Empty<IndoorMapHazard>();
			Moon.canSpawnMold = false;
			Moon.moldSpreadIterations = 0;
			Moon.moldStartPosition = -1;
			Moon.randomWeathers = Array.Empty<RandomWeatherWithVariables>();
			Moon.overrideWeather = true;
			Moon.overrideWeatherType = (LevelWeatherType)(-1);
			Moon.currentWeather = (LevelWeatherType)(-1);
			Moon.dungeonFlowTypes = (IntWithRarity[])(object)new IntWithRarity[1]
			{
				new IntWithRarity(0, 100, (LevelAmbienceLibrary)null)
			};
			extendedMoon = ScriptableObject.CreateInstance<ExtendedLevel>();
			((Object)extendedMoon).name = "CircusLabyrinthExtendedLevel";
			extendedMoon.SelectableLevel = Moon;
			extendedMoon.RoutePrice = RoutePrice.Value;
			extendedMoon.OverrideRouteNoun = "circus";
			extendedMoon.OverrideDynamicRiskLevelAssignment = true;
			extendedMoon.IsRouteHidden = false;
			extendedMoon.IsRouteLocked = false;
			extendedMoon.OverrideCameraFarPlaneDistanceOutside = 750f;
			extendedMoon.GenerateAutomaticConfigurationOptions = false;
			PatchedContent.RegisterExtendedMod(ExtendedMod.Create("Circus Labyrinth", "JLeonL", (ExtendedContent[])(object)new ExtendedContent[1] { (ExtendedContent)extendedMoon }));
			moonConfigured = true;
			Log.LogInfo((object)("Registered 77 Circus Labyrinth. Terminal: route circus. Base scene: " + Moon.sceneName));
		}

		private static void ReportRegistration()
		{
			CircusDiagnostics.Audit("SETUP_COMPLETE");
			bool flag = PatchedContent.ExtendedLevels.Any((ExtendedLevel l) => (Object)(object)l == (Object)(object)extendedMoon);
			Log.LogInfo((object)("CIRCUS_CATALOGUE registered=" + flag + " configured=" + moonConfigured + ". Use ROUTE CIRCUS in the terminal."));
		}

		private unsafe static void SceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			CircusDiagnostics.Write("PLUGIN_SCENE", ((Scene)(ref scene)).name + " mode=" + ((object)(*(LoadSceneMode*)(&mode))/*cast due to .constrained prefix*/).ToString());
			if (!Active || (Object)(object)Moon == (Object)null || ((Scene)(ref scene)).name != Moon.sceneName)
			{
				return;
			}
			try
			{
				BuildExterior(scene);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Exterior generation failed: " + ex));
			}
		}

		private static void SceneUnloaded(Scene scene)
		{
			if (!((Object)(object)Moon == (Object)null) && !(((Scene)(ref scene)).name != Moon.sceneName))
			{
				CircusLoading.Stop();
				templateEntrances.Clear();
				nativeEmergencyVisual = null;
				templateLights = Array.Empty<Light>();
				RestoreCameras();
				CircusSoundtrack.EndVisit();
				CircusAmbience.EndVisit();
				CircusHedgeAmbience.EndVisit();
				CircusCaine.EndVisit();
				if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.occlusionCuller != (Object)null)
				{
					((Behaviour)StartOfRound.Instance.occlusionCuller).enabled = hadCulling;
				}
				CircusHazards.EndVisit();
				CircusParkourRewards.EndVisit();
				CircusMobBridge.EndVisit();
				CircusSlides.EndVisit();
				CircusCharacterAssets.EndVisit();
				CircusScanNodes.EndVisit();
				Exterior = null;
				Interior = null;
				Layout = null;
				Stack = null;
				ExteriorRoot = null;
				MazeRoot = null;
			}
		}

		private unsafe static void BuildExterior(Scene scene)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_01cd: 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_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Expected O, but got Unknown
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0549: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Expected O, but got Unknown
			//IL_07a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ExteriorRoot != (Object)null)
			{
				return;
			}
			Vector3 ship = StartOfRound.Instance.shipLandingPosition.position;
			float y = ship.y;
			RaycastHit[] array = (from h in Physics.RaycastAll(ship + Vector3.up * 25f, Vector3.down, 100f, -1, (QueryTriggerInteraction)1)
				where ((Component)((RaycastHit)(ref h)).collider).gameObject.scene == scene && ((RaycastHit)(ref h)).normal.y > 0.7f && ((RaycastHit)(ref h)).point.y <= ship.y + 1f
				orderby ((RaycastHit)(ref h)).point.y descending
				select h).ToArray();
			if (array.Length != 0)
			{
				y = ((RaycastHit)(ref array[0])).point.y;
			}
			ManualLogSource log = Log;
			string[] obj = new string[6] { "Circus scene loaded. Ship landing=", null, null, null, null, null };
			Vector3 val = ship;
			obj[1] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString();
			obj[2] = "; ground=";
			obj[3] = y.ToString();
			obj[4] = "; original scene=";
			obj[5] = ((Scene)(ref scene)).name;
			log.LogInfo((object)string.Concat(obj));
			GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
			CaptureNativeDoorVisuals(rootGameObjects);
			templateLights = rootGameObjects.Where((GameObject r) => (Object)(object)r.GetComponentInChildren<RuntimeDungeon>(true) == (Object)null).SelectMany((GameObject r) => r.GetComponentsInChildren<Light>(true)).ToArray();
			File.WriteAllLines(Path.Combine(Paths.PluginPath, "CircusLabyrinth-scene.txt"), rootGameObjects.Select((GameObject r) => ((Object)r).name + " " + ((object)r.transform.position/*cast due to .constrained prefix*/).ToString()));
			EntranceTeleport[] array2 = Object.FindObjectsOfType<EntranceTeleport>();
			foreach (EntranceTeleport val2 in array2)
			{
				if (!(((Component)val2).gameObject.scene != scene))
				{
					if ((Object)(object)Hand == (Object)null && (Object)(object)((Component)val2).GetComponent<InteractTrigger>() != (Object)null)
					{
						Hand = ((Component)val2).GetComponent<InteractTrigger>().hoverIcon;
					}
					templateEntrances.Add(val2);
				}
			}
			GameObject[] array3 = rootGameObjects;
			foreach (GameObject val3 in array3)
			{
				if ((Object)(object)val3.GetComponentInChildren<RuntimeDungeon>(true) != (Object)null)
				{
					continue;
				}
				Renderer[] componentsInChildren = val3.GetComponentsInChildren<Renderer>(true);
				for (int num2 = 0; num2 < componentsInChildren.Length; num2++)
				{
					componentsInChildren[num2].enabled = false;
				}
				Collider[] componentsInChildren2 = val3.GetComponentsInChildren<Collider>(true);
				for (int num2 = 0; num2 < componentsInChildren2.Length; num2++)
				{
					componentsInChildren2[num2].enabled = false;
				}
				Terrain[] componentsInChildren3 = val3.GetComponentsInChildren<Terrain>(true);
				foreach (Terrain obj2 in componentsInChildren3)
				{
					obj2.drawHeightmap = false;
					obj2.drawTreesAndFoliage = false;
				}
				Light[] componentsInChildren4 = val3.GetComponentsInChildren<Light>(true);
				for (int num2 = 0; num2 < componentsInChildren4.Length; num2++)
				{
					((Behaviour)componentsInChildren4[num2]).enabled = false;
				}
				LocalVolumetricFog[] componentsInChildren5 = val3.GetComponentsInChildren<LocalVolumetricFog>(true);
				for (int num2 = 0; num2 < componentsInChildren5.Length; num2++)
				{
					((Behaviour)componentsInChildren5[num2]).enabled = false;
				}
				AudioSource[] componentsInChildren6 = val3.GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource obj3 in componentsInChildren6)
				{
					obj3.Stop();
					((Behaviour)obj3).enabled = false;
				}
				Transform[] componentsInChildren7 = val3.GetComponentsInChildren<Transform>(true);
				foreach (Transform val4 in componentsInChildren7)
				{
					if (((Component)val4).CompareTag("OutsideAINode"))
					{
						((Component)val4).gameObject.tag = "Untagged";
					}
				}
			}
			NavMesh.RemoveAllNavMeshData();
			ExteriorRoot = new GameObject("CircusLabyrinth_Exterior");
			SceneManager.MoveGameObjectToScene(ExteriorRoot, scene);
			StartOfRound instance = StartOfRound.Instance;
			Vector3 val5 = instance.shipLandingPosition.rotation * Vector3.left;
			val5.y = 0f;
			Quaternion val6 = CircusGeometry.LandingOrientation(instance.shipLandingPosition.rotation);
			ExteriorOffset = new Vector3(ship.x, y, ship.z) - val6 * CircusGeometry.Ship;
			ExteriorRoot.transform.position = ExteriorOffset;
			ExteriorRoot.transform.rotation = val6;
			Log.LogInfo((object)("CIRCUS_SHIP_PATH landingFrame=True doorNormalLocal=-X exitDirection=" + ((object)((Vector3)(ref val5)).normalized/*cast due to .constrained prefix*/).ToString() + " mapYaw=" + ((Quaternion)(ref val6)).eulerAngles.y));
			CircusSoundtrack.BeginVisit(instance.randomMapSeed);
			CircusAmbience.BeginVisit(instance.randomMapSeed);
			CircusHedgeAmbience.BeginVisit(instance.randomMapSeed);
			Exterior = new CircusGeometry(ExteriorRoot.transform, highDefinition: true);
			Exterior.BuildExterior();
			Exterior.Flush();
			for (int num3 = 0; num3 < Exterior.OutsideNodes.Count; num3++)
			{
				MakeNode("OutsideAINode", ExteriorRoot.transform, Exterior.OutsideNodes[num3]);
			}
			GameObject val7 = GameObject.FindGameObjectWithTag("MapPropsContainer");
			if ((Object)(object)val7 != (Object)null)
			{
				val7.tag = "Untagged";
			}
			SceneManager.MoveGameObjectToScene(new GameObject("Circus_MapProps")
			{
				tag = "MapPropsContainer"
			}, scene);
			RoundManager instance2 = RoundManager.Instance;
			instance2.outsideAINodes = null;
			instance2.outsideAIWaterNodes = null;
			instance2.GetOutsideAINodes(true);
			Bake(ExteriorRoot);
			if ((Object)(object)StartOfRound.Instance.occlusionCuller != (Object)null)
			{
				hadCulling = ((Behaviour)StartOfRound.Instance.occlusionCuller).enabled;
				((Behaviour)StartOfRound.Instance.occlusionCuller).enabled = false;
			}
			ExteriorRoot.AddComponent<CircusAtmosphere>().Initialize(Exterior, interior: false);
			Log.LogInfo((object)("Circus exterior built: clown entrance, carousel, Ferris wheel, fence, island and " + Exterior.OutsideNodes.Count + " AI nodes."));
			Log.LogInfo((object)$"CIRCUS_EXTERIOR_DETAIL mountains={Exterior.MountainSegments} horrorScenes={Exterior.HorrorScenes} pines={Exterior.Pines} caravans={Exterior.Caravans} marketStalls={Exterior.MarketStalls} mummies={Exterior.MummyRoutes.Count} wavingClowns={Exterior.ClownRiders} boardPanels={Exterior.PrintedPanels} image=circus-night-overview-v040.png.");
			Log.LogInfo((object)("CIRCUS_CHARACTERS importedActors=" + CircusCharacterAssets.ActorCount + "; riders=14 walkingClowns=" + Exterior.ClownRoutes.Count + " mummies=6; harmless NPC bodies=" + Object.FindObjectsOfType<CircusHarmlessMob>().Length + " with red scan nodes."));
			Log.LogInfo((object)$"CIRCUS_SCENERY booths={Exterior.Booths}; grass={Exterior.GrassClumps}; pumpkins={Exterior.Pumpkins}; bodies={Exterior.Corpses}; wallEyes={Exterior.EyePairs}; lamps={Exterior.Lamps.Count}; shipToGate={Vector3.Distance(CircusGeometry.Ship, new Vector3(0f, 0f, -53f)):F0}m.");
			Log.LogInfo((object)("CIRCUS_SCENE_ENTRANCES active=" + templateEntrances.Count((EntranceTeleport p) => (Object)(object)p != (Object)null && ((Behaviour)p).isActiveAndEnabled) + "; retained until replacement portals are ready."));
		}

		internal static void PrepareScaffold(RuntimeDungeon dungeon)
		{
			dungeon.Generator.RestrictDungeonToBounds = false;
			dungeon.Generator.LengthMultiplier = Mathf.Max(1f, dungeon.Generator.LengthMultiplier);
			CircusLoading.Begin(dungeon.Generator);
		}

		internal static void ReplaceDungeon(RoundManager rm)
		{
			//IL_0025: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: 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_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)MazeRoot != (Object)null)
			{
				return;
			}
			if ((Object)(object)ExteriorRoot == (Object)null)
			{
				BuildExterior(SceneManager.GetSceneByName(Moon.sceneName));
			}
			Dungeon currentDungeon = rm.dungeonGenerator.Generator.CurrentDungeon;
			if ((Object)(object)currentDungeon == (Object)null)
			{
				throw new InvalidOperationException("Missing generation scaffold.");
			}
			ItemGroup[] array = (from s in ((Component)currentDungeon).GetComponentsInChildren<RandomScrapSpawn>(true)
				select s.spawnableItems).Distinct().ToArray();
			foreach (Transform item in ((Component)currentDungeon).transform)
			{
				((Component)item).gameObject.SetActive(false);
			}
			MazeRoot = new GameObject("CircusLabyrinth_Interior");
			SceneManager.MoveGameObjectToScene(MazeRoot, ExteriorRoot.scene);
			MazeRoot.transform.SetPositionAndRotation(MazeOffset, Quaternion.identity);
			MazeRoot.transform.localScale = Vector3.one;
			Stack = new MazeStack(StartOfRound.Instance.randomMapSeed);
			Layout = Stack.Floors[0];
			Interior = new CircusGeometry(MazeRoot.transform, highDefinition: true);
			Interior.BuildStack(Stack);
			Interior.Flush();
			for (int num = 0; num < Stack.Count; num++)
			{
				for (int num2 = 0; num2 < Stack.Floors[num].Openings.Length; num2++)
				{
					Vector3 val = Interior.StackCell(Stack, num, num2);
					if (Stack.ConnectorRoom(num, num2) != 0)
					{
						continue;
					}
					if (num2 % 3 == 0)
					{
						MakeNode("AINode", MazeRoot.transform, val + Vector3.up);
					}
					if (num2 % 5 != 0 || Stack.IsHazardCell(num, num2) || Stack.IsParkourZone(num, num2))
					{
						continue;
					}
					if (array.Length == 0)
					{
						MakeScrapPoint(val, null, num2);
						continue;
					}
					for (int num3 = 0; num3 < array.Length; num3++)
					{
						MakeScrapPoint(val, array[num3], num * 100000 + num2 * 20 + num3);
					}
				}
			}
			foreach (CircusHazardGeometry hazard in Interior.Hazards)
			{
				if (hazard.Plan.Kind == MazeHazardKind.Parkour || Stack.IsParkourZone(hazard.Plan.Floor, hazard.Plan.Cell))
				{
					continue;
				}
				Vector3 p = hazard.Center + hazard.Rotation * new Vector3(0f, 0f, hazard.Plan.Length * 0.5f - 1.8f);
				float range = 0.6f;
				if (array.Length == 0)
				{
					MakeScrapPoint(p, null, 900000 + hazard.Plan.Id, range);
					continue;
				}
				for (int num4 = 0; num4 < array.Length; num4++)
				{
					MakeScrapPoint(p, array[num4], 900000 + hazard.Plan.Id * 100 + num4, range);
				}
			}
			CircusParkourRewards.BeginVisit(Stack, (MazeHazardPlan h) => MazeRoot.transform.TransformPoint(Interior.ParkourRewardPosition(Stack, h)));
			SetDoorLocations();
			rm.insideAINodes = GameObject.FindGameObjectsWithTag("AINode");
			rm.currentDungeonType = 0;
			MazeRoot.AddComponent<CircusAtmosphere>().Initialize(Interior, interior: true);
			CircusHazards.BeginVisit();
			CircusCaine.BeginVisit();
			Log.LogInfo((object)string.Format("CIRCUS_STACK floors={0} portalFloors={1} hazards={2} slides={3} rootScale={4} isolatedRoot=True origin={5}.", Stack.Count, string.Join(",", Stack.DoorFloors.Select((int f) => f + 1)), Interior.Hazards.Count, Interior.Slides.Count, MazeRoot.transform.lossyScale, MazeOffset));
			Log.LogInfo((object)$"CIRCUS_PARKOUR_GATES emergencyId={Stack.ParkourEmergencyDoor} floor={Stack.DoorFloors[Stack.ParkourEmergencyDoor] + 1} bypasses=False rewardChance={33}% rewardWins={Stack.Hazards.Count((MazeHazardPlan h) => h.Reward != null)} rewardValue={70}-{90}.");
			int floor;
			for (floor = 0; floor < Stack.Count; floor++)
			{
				Log.LogInfo((object)$"CIRCUS_FLOOR_CHALLENGES floor={floor + 1} parkour={Stack.Hazards.Count((MazeHazardPlan h) => h.Floor == floor && h.Kind == MazeHazardKind.Parkour)} target={MazeStack.ParkourRoomTarget(floor)} fragile={Stack.Hazards.Count((MazeHazardPlan h) => h.Floor == floor && h.Kind == MazeHazardKind.Fragile)} fragileLength={3f}m.");
			}
			Log.LogInfo((object)$"CIRCUS_MAZE_DETAIL hedges={Interior.HedgeSections}; lamps={Interior.Lamps.Count}; pumpkins={Interior.Pumpkins}; bodies={Interior.Corpses}; wallEyes={Interior.EyePairs}; opaqueCeilings={Interior.OpaqueCeilings}; interiorShafts={((Stack.Count > 1) ? 2 : 0)}.");
			Log.LogInfo((object)$"CIRCUS_CLOWN_PATROLS outside={Exterior.ClownRoutes.Count} inside={Interior.ClownRoutes.Count} importedActors={CircusCharacterAssets.ActorCount} solidBodies={Object.FindObjectsOfType<CircusHarmlessMob>().Length}; neutral=True scan=red.");
			Log.LogInfo((object)$"CONNECTED MAZE seed={Layout.Seed}; {29}x{29}; hash={Layout.Fingerprint()}; reachable={Layout.Openings.Length}; exit distances={Layout.Distances(Layout.MainCell)[Layout.CarouselCell]},{Layout.Distances(Layout.MainCell)[Layout.WheelCell]}.");
		}

		private static void MakeScrapPoint(Vector3 p, ItemGroup group, int index, float range = 1.4f)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("CircusScrap_" + index);
			val.transform.SetParent(MazeRoot.transform, false);
			val.transform.localPosition = p + Vector3.up * 0.25f;
			RandomScrapSpawn obj = val.AddComponent<RandomScrapSpawn>();
			obj.spawnableItems = group;
			obj.itemSpawnRange = range;
		}

		private static void MakeNode(string tag, Transform parent, Vector3 p)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Circus_" + tag)
			{
				tag = tag
			};
			val.transform.SetParent(parent, false);
			val.transform.localPosition = p;
		}

		private static void Bake(GameObject root)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < NavMesh.GetSettingsCount(); i++)
			{
				NavMeshSurface obj = root.AddComponent<NavMeshSurface>();
				NavMeshBuildSettings settingsByIndex = NavMesh.GetSettingsByIndex(i);
				obj.agentTypeID = ((NavMeshBuildSettings)(ref settingsByIndex)).agentTypeID;
				obj.collectObjects = (CollectObjects)2;
				obj.useGeometry = (NavMeshCollectGeometry)1;
				obj.layerMask = LayerMask.op_Implicit(256);
				obj.overrideVoxelSize = true;
				obj.voxelSize = 0.18f;
				obj.BuildNavMesh();
			}
		}

		private static void SetDoorLocations()
		{
			//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_001a: 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_0034: 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_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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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