Decompiled source of BeyondTheWall v0.6.1

BeyondTheWall.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Mirror;
using Steamworks;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace BeyondTheWall;

[BepInPlugin("purp.bigwalk.beyondthewall", "Beyond The Wall", "0.6.1")]
public class Plugin : BasePlugin
{
	internal static ManualLogSource LogSource;

	public override void Load()
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		LogSource = ((BasePlugin)this).Log;
		try
		{
			ClassInjector.RegisterTypeInIl2Cpp<ArgController>();
		}
		catch (Exception ex)
		{
			((BasePlugin)this).Log.LogError((object)("Could not register ArgController with IL2CPP: " + ex.Message));
			return;
		}
		try
		{
			GameObject val = new GameObject("BeyondTheWall_ARG");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<ArgController>();
			((BasePlugin)this).Log.LogInfo((object)"Beyond The Wall is listening.");
		}
		catch (Exception ex2)
		{
			((BasePlugin)this).Log.LogError((object)("Could not create ARG controller: " + ex2));
		}
	}
}
public class ArgController : MonoBehaviour
{
	private sealed class Peer
	{
		public ulong Nonce;

		public float Seen;

		public float RequestAt;

		public uint Actor;
	}

	private readonly EncounterProgress progress = new EncounterProgress();

	private GameObject noticedFigure;

	private GameObject thirdBell;

	private GameObject beyond;

	private readonly List<Renderer> beyondRenderers = new List<Renderer>();

	private float noticedTime;

	private float bellLookTime;

	private float nextLateAttempt;

	private float lastNoticeTick;

	private bool sightingCounted;

	private bool lateFailed;

	private string progressPath;

	private float nextEventAt;

	private float nextScanAt;

	private float eventEndAt;

	private float blackSpawnAt = -1f;

	private int blackConstructionRetries;

	private const int MaxBlackConstructionRetries = 3;

	private GameObject activeFigure;

	private Camera cam;

	private Random rng = new Random();

	private bool debugMenuOpen;

	private Material whiteMaterial;

	private Material blackMaterial;

	private bool gameplayArmed;

	private float nextGameplayProbeAt;

	private HashSet<string> alreadyLoggedObjectNames = new HashSet<string>();

	private int lastMainCameraId;

	private bool activeFigureIsDebug;

	private bool activeFigureIsNaturalWhite;

	private bool activeFigureIsNaturalBlack;

	private bool key6WasDown;

	private bool key1WasDown;

	private bool key2WasDown;

	private bool dreamSuspended;

	private const int VK_1 = 49;

	private const int VK_2 = 50;

	private const int VK_6 = 54;

	private const int VK_NUMPAD1 = 97;

	private const int VK_NUMPAD2 = 98;

	private const int VK_NUMPAD6 = 102;

	private AudioSource chaseAudio;

	private AudioClip chaseClip;

	private bool chaseStarted;

	private bool debugSpawningPaused;

	private bool debugLateHidden;

	private bool debugCursorOwned;

	private bool debugPreviousCursorVisible;

	private CursorLockMode debugPreviousCursorLock;

	private Texture2D debugRounded;

	private Texture2D debugEye;

	private GUIStyle debugButton;

	private GUIStyle debugLabel;

	private GUIStyle debugSmall;

	private Light fallbackSun;

	private Vector3 bellBearing;

	private Material finderMaterial;

	private bool lastFinderReveal;

	private float nextSunSearch;

	private PlayerCharacter capturedHost;

	private Corpse capturedCorpse;

	private HostPhysicsSnapshot capturedPhysics;

	private bool savedUpdate;

	private bool savedLate;

	private bool savedFixed;

	private bool savedKinematic;

	private bool savedGhost;

	private bool savedAudioGhost;

	private bool savedCursorVisible;

	private CursorLockMode savedCursorLock;

	private float capturedAt;

	private bool captureActive;

	private bool captureWasHost;

	private string returnNotice = "";

	private float nextReturnAttempt;

	private GameObject huntedFigure;

	private HuntState hunt;

	private bool wallReady;

	private float nextWallSearch;

	private Vector3 wallOrigin;

	private Vector3 wallOutward;

	private readonly List<Material> landmarkMaterials = new List<Material>();

	private readonly List<Mesh> landmarkMeshes = new List<Mesh>();

	private readonly List<Mesh> figureMeshes = new List<Mesh>();

	private readonly List<Material> figureMaterials = new List<Material>();

	private int renderAuditId;

	private float renderAuditAt;

	private bool renderAudited;

	private const int SharedChannel = 14731;

	private readonly Dictionary<ulong, Peer> sharedPeers = new Dictionary<ulong, Peer>();

	private readonly Dictionary<ulong, PlayerCharacter> sharedRoster = new Dictionary<ulong, PlayerCharacter>();

	private ulong sharedLocal;

	private ulong sharedHost;

	private ulong sharedAuthority;

	private ulong sharedNonce;

	private ulong sharedAuthorityNonce;

	private ulong sharedTarget;

	private uint sharedActor;

	private uint sharedSequence;

	private uint sharedEvent;

	private uint sharedLastSequence;

	private uint sharedCapturedEvent;

	private int sharedFigureInstance;

	private float sharedHelloAt;

	private float sharedSnapshotAt;

	private float sharedRosterAt;

	private float sharedReplicaExpires;

	private float sharedErrorAt;

	private SharedFrame replica;

	private bool SpawningPaused
	{
		get
		{
			if (!SharedFollower)
			{
				return debugSpawningPaused;
			}
			if (replica != null)
			{
				return (replica.Request & 1) != 0;
			}
			return false;
		}
	}

	private bool LateEntitiesHidden
	{
		get
		{
			if (!SpawningPaused)
			{
				if (!SharedFollower)
				{
					return debugLateHidden;
				}
				if (replica != null)
				{
					return (replica.Request & 2) != 0;
				}
				return false;
			}
			return true;
		}
	}

	private bool SharedFollower
	{
		get
		{
			if (sharedAuthority != 0L)
			{
				return sharedAuthority != sharedLocal;
			}
			return false;
		}
	}

	private bool SharedDriver => !SharedFollower;

	[DllImport("user32.dll")]
	private static extern short GetAsyncKeyState(int vKey);

	public ArgController(IntPtr ptr)
		: base(ptr)
	{
	}

	public void Start()
	{
		LoadChaseMusic();
		progressPath = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "BeyondTheWall.progress.txt");
		try
		{
			if (File.Exists(progressPath))
			{
				progress.Load(File.ReadAllText(progressPath));
			}
		}
		catch (Exception ex)
		{
			Plugin.LogSource.LogWarning((object)("Progress load: " + ex.Message));
		}
		lastNoticeTick = Time.time;
		nextEventAt = float.PositiveInfinity;
		nextScanAt = float.PositiveInfinity;
		nextGameplayProbeAt = Time.time + 2f;
		try
		{
			Camera main = Camera.main;
			lastMainCameraId = (((Object)(object)main != (Object)null) ? ((Object)main).GetInstanceID() : 0);
		}
		catch
		{
			lastMainCameraId = 0;
		}
	}

	public void Update()
	{
		TickShared();
		if (UpdateHostCapture())
		{
			SetDebugMenu(open: false);
			return;
		}
		bool flag = false;
		List<PlayerCharacter> allPlayerCharacters = PlayerCharacter.allPlayerCharacters;
		if (allPlayerCharacters != null)
		{
			for (int i = 0; i < allPlayerCharacters.Count; i++)
			{
				if ((Object)(object)allPlayerCharacters[i] != (Object)null && ((NetworkBehaviour)allPlayerCharacters[i]).isLocalPlayer)
				{
					flag = allPlayerCharacters[i].dreamer != null && allPlayerCharacters[i].dreamer.isDreaming;
					break;
				}
			}
		}
		if (flag)
		{
			if (!dreamSuspended)
			{
				ClearActiveFigure();
				ClearLateEntities();
				dreamSuspended = true;
			}
			lastNoticeTick = Time.time;
			return;
		}
		if (dreamSuspended)
		{
			dreamSuspended = false;
			ScheduleNextEvent(75f, 210f);
		}
		PollDebugKeysFallback();
		if (SpawningPaused)
		{
			lastNoticeTick = Time.time;
			return;
		}
		try
		{
			Camera main = Camera.main;
			int num = (((Object)(object)main != (Object)null) ? ((Object)main).GetInstanceID() : 0);
			if (num != lastMainCameraId)
			{
				lastMainCameraId = num;
				gameplayArmed = false;
				ClearActiveFigure();
				ClearLateEntities();
				nextEventAt = float.PositiveInfinity;
				nextScanAt = float.PositiveInfinity;
				nextGameplayProbeAt = Time.time + 1f;
				alreadyLoggedObjectNames.Clear();
				cam = main;
				if (Plugin.LogSource != null)
				{
					Plugin.LogSource.LogInfo((object)"ARG camera/scene transition detected; disarmed until gameplay is verified.");
				}
			}
		}
		catch
		{
		}
		if ((Object)(object)cam == (Object)null)
		{
			cam = Camera.main;
		}
		if (Time.time >= nextGameplayProbeAt)
		{
			nextGameplayProbeAt = Time.time + 15f;
			bool flag2 = LooksLikeGameplayScene();
			if (!gameplayArmed && flag2)
			{
				gameplayArmed = true;
				ScheduleNextEvent(45f, 100f);
				nextScanAt = Time.time + 10f;
				if (Plugin.LogSource != null)
				{
					Plugin.LogSource.LogInfo((object)"ARG gameplay scene armed.");
				}
			}
			else if (gameplayArmed && !flag2)
			{
				gameplayArmed = false;
				ClearActiveFigure();
				ClearLateEntities();
				nextEventAt = float.PositiveInfinity;
				nextScanAt = float.PositiveInfinity;
				if (Plugin.LogSource != null)
				{
					Plugin.LogSource.LogInfo((object)"ARG gameplay scene disarmed.");
				}
			}
		}
		float delta = Math.Max(0f, Math.Min(0.1f, Time.time - lastNoticeTick));
		lastNoticeTick = Time.time;
		if (gameplayArmed)
		{
			try
			{
				if (SharedDriver)
				{
					ObserveEncounter(delta);
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("Sighting check skipped: " + ex.Message));
				nextGameplayProbeAt = Time.time;
			}
			if (!lateFailed)
			{
				try
				{
					UpdateLateEntities(delta);
				}
				catch (Exception ex2)
				{
					lateFailed = true;
					ClearLateEntities();
					Plugin.LogSource.LogError((object)("Late entities disabled: " + ex2));
				}
			}
		}
		if ((Object)(object)activeFigure == (Object)null && (activeFigureIsDebug || activeFigureIsNaturalWhite || activeFigureIsNaturalBlack))
		{
			RecoverMissingFigure();
		}
		if ((Object)(object)activeFigure != (Object)null && Time.time >= eventEndAt)
		{
			EndActiveFigure();
		}
		AuditFigureRendering();
		if (SharedDriver)
		{
			UpdateHunt();
		}
		else
		{
			UpdateSharedReplica();
		}
		if (!gameplayArmed || SharedFollower)
		{
			return;
		}
		if (Time.time >= nextScanAt)
		{
			nextScanAt = Time.time + 120f;
			ScanIsland();
		}
		if (blackSpawnAt > 0f && Time.time >= blackSpawnAt)
		{
			if ((Object)(object)cam == (Object)null)
			{
				cam = Camera.main;
			}
			if ((Object)(object)cam == (Object)null || (Object)(object)activeFigure != (Object)null)
			{
				blackSpawnAt = Time.time + 0.5f;
			}
			else
			{
				blackSpawnAt = -1f;
				SpawnBlackOne();
			}
		}
		if ((Object)(object)activeFigure == (Object)null && blackSpawnAt <= 0f && Time.time >= nextEventAt)
		{
			BeginWhiteOneEvent();
		}
	}

	private bool PhysicalKeyDown(int mainKey, int numpadKey)
	{
		try
		{
			return (GetAsyncKeyState(mainKey) & 0x8000) != 0 || (GetAsyncKeyState(numpadKey) & 0x8000) != 0;
		}
		catch
		{
			return false;
		}
	}

	private void PollDebugKeysFallback()
	{
		if (!Application.isFocused)
		{
			return;
		}
		bool flag = PhysicalKeyDown(54, 102);
		bool flag2 = PhysicalKeyDown(49, 97);
		bool flag3 = PhysicalKeyDown(50, 98);
		if (flag && !key6WasDown)
		{
			SetDebugMenu(!debugMenuOpen);
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogInfo((object)(debugMenuOpen ? "DEBUG MENU OPEN" : "DEBUG MENU CLOSED"));
			}
		}
		if (debugMenuOpen)
		{
			if (flag2 && !key1WasDown)
			{
				DebugSpawnWhiteOne();
			}
			if (flag3 && !key2WasDown)
			{
				DebugSpawnBlackOne();
			}
		}
		key6WasDown = flag;
		key1WasDown = flag2;
		key2WasDown = flag3;
	}

	public void OnGUI()
	{
		if (!DrawHostCapture() && debugMenuOpen)
		{
			DrawBentleyMenu();
		}
	}

	private void PrepareForDebugSpawn()
	{
		if ((Object)(object)activeFigure != (Object)null && activeFigureIsNaturalWhite)
		{
			if (gameplayArmed)
			{
				ScheduleNextEvent(75f, 210f);
			}
			else
			{
				nextEventAt = float.PositiveInfinity;
			}
		}
		if ((Object)(object)activeFigure != (Object)null && activeFigureIsNaturalBlack)
		{
			blackConstructionRetries = 0;
			blackSpawnAt = (gameplayArmed ? (Time.time + 0.5f) : (-1f));
		}
		ClearFigureOnly();
	}

	private bool TryFindNearbyDebugSpawn(float groundOffset, out Vector3 position, bool white = false)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: 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_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		if ((Object)(object)cam == (Object)null)
		{
			cam = Camera.main;
		}
		if ((Object)(object)cam == (Object)null)
		{
			return false;
		}
		Vector3 position2 = ((Component)cam).transform.position;
		Vector3 val = default(Vector3);
		RaycastHit val2 = default(RaycastHit);
		Vector3 val4 = default(Vector3);
		RaycastHit val5 = default(RaycastHit);
		for (int i = 0; i < 18; i++)
		{
			float num = (float)(rng.NextDouble() * Math.PI * 2.0);
			float num2 = 3f + (float)rng.NextDouble() * 7f;
			((Vector3)(ref val))..ctor(position2.x + (float)Math.Cos(num) * num2, position2.y + 2f, position2.z + (float)Math.Sin(num) * num2);
			if (!Physics.Raycast(val + Vector3.up * 4f, Vector3.down, ref val2, 12f, -1, (QueryTriggerInteraction)1))
			{
				continue;
			}
			val = ((RaycastHit)(ref val2)).point + Vector3.up * groundOffset;
			if (white && !WhiteSideOfWall(val))
			{
				continue;
			}
			Vector3 val3 = val + Vector3.up * 1.25f - position2;
			float num3 = (float)Math.Sqrt(val3.x * val3.x + val3.y * val3.y + val3.z * val3.z);
			if (!(num3 < 0.01f))
			{
				((Vector3)(ref val4))..ctor(val3.x / num3, val3.y / num3, val3.z / num3);
				if (!Physics.Raycast(position2, val4, ref val5, Math.Max(0.1f, num3 - 0.35f), -1, (QueryTriggerInteraction)1))
				{
					position = val;
					return true;
				}
			}
		}
		return false;
	}

	private void DebugSpawnWhiteOne()
	{
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		if (SpawningPaused)
		{
			return;
		}
		debugLateHidden = false;
		if (RequestSharedSpawn(1))
		{
			return;
		}
		if ((Object)(object)cam == (Object)null)
		{
			cam = Camera.main;
		}
		if ((Object)(object)cam == (Object)null)
		{
			return;
		}
		PrepareForDebugSpawn();
		try
		{
			activeFigure = BuildFigure("The White One", white: true);
			activeFigureIsDebug = true;
			activeFigureIsNaturalWhite = false;
			activeFigureIsNaturalBlack = false;
		}
		catch (Exception ex)
		{
			activeFigure = null;
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("White One debug spawn skipped: " + ex.Message));
			}
			return;
		}
		if ((Object)(object)activeFigure == (Object)null)
		{
			activeFigureIsDebug = false;
			return;
		}
		try
		{
			if (!TryFindNearbyDebugSpawn(0.6f, out var position, white: true))
			{
				AbortSpawnedFigure();
				if (Plugin.LogSource != null)
				{
					Plugin.LogSource.LogWarning((object)"DEBUG: could not find a clear nearby spawn point for The White One.");
				}
				return;
			}
			activeFigure.transform.position = position;
			FaceCamera(activeFigure);
			eventEndAt = Time.time + 12f;
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogInfo((object)"DEBUG: spawned The White One within 10m.");
			}
		}
		catch (Exception ex2)
		{
			AbortSpawnedFigure();
			cam = null;
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("White One debug placement aborted: " + ex2.Message));
			}
		}
	}

	private void DebugSpawnBlackOne()
	{
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		if (SpawningPaused)
		{
			return;
		}
		debugLateHidden = false;
		if (RequestSharedSpawn(2))
		{
			return;
		}
		if ((Object)(object)cam == (Object)null)
		{
			cam = Camera.main;
		}
		if ((Object)(object)cam == (Object)null)
		{
			return;
		}
		PrepareForDebugSpawn();
		try
		{
			activeFigure = BuildFigure("The Black One", white: false);
			activeFigureIsDebug = true;
			activeFigureIsNaturalWhite = false;
			activeFigureIsNaturalBlack = false;
		}
		catch (Exception ex)
		{
			activeFigure = null;
			activeFigureIsDebug = false;
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("Black One spawn skipped: " + ex.Message));
			}
			return;
		}
		if ((Object)(object)activeFigure == (Object)null)
		{
			activeFigureIsDebug = false;
			return;
		}
		try
		{
			if (!TryFindNearbyDebugSpawn(0.03f, out var position))
			{
				AbortSpawnedFigure();
				if (Plugin.LogSource != null)
				{
					Plugin.LogSource.LogWarning((object)"DEBUG: could not find a clear nearby spawn point for The Black One.");
				}
				return;
			}
			activeFigure.transform.position = position;
			activeFigure.transform.localScale = new Vector3(0.68f, 1.85f, 0.68f);
			FaceCamera(activeFigure);
			BeginHunt();
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogInfo((object)"DEBUG: spawned The Black One within 10m.");
			}
		}
		catch (Exception ex2)
		{
			AbortSpawnedFigure();
			cam = null;
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("Black One debug placement aborted: " + ex2.Message));
			}
		}
	}

	private void AbortSpawnedFigure()
	{
		StopChaseMusic();
		noticedFigure = null;
		noticedTime = 0f;
		sightingCounted = false;
		eventEndAt = 0f;
		if ((Object)(object)activeFigure != (Object)null)
		{
			DestroyFigure(activeFigure);
		}
		activeFigure = null;
		activeFigureIsDebug = false;
		activeFigureIsNaturalWhite = false;
		activeFigureIsNaturalBlack = false;
	}

	private void ClearFigureOnly()
	{
		StopChaseMusic();
		noticedFigure = null;
		noticedTime = 0f;
		sightingCounted = false;
		eventEndAt = 0f;
		if ((Object)(object)activeFigure != (Object)null)
		{
			DestroyFigure(activeFigure);
		}
		activeFigure = null;
		activeFigureIsDebug = false;
		activeFigureIsNaturalWhite = false;
		activeFigureIsNaturalBlack = false;
	}

	private void ClearActiveFigure()
	{
		blackSpawnAt = -1f;
		blackConstructionRetries = 0;
		ClearFigureOnly();
	}

	private List<GameObject> FindAllGameObjectsSafe()
	{
		List<GameObject> list = new List<GameObject>();
		try
		{
			MethodInfo[] methods = typeof(Resources).GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo == null || methodInfo.Name != "FindObjectsOfTypeAll" || !methodInfo.IsGenericMethodDefinition || methodInfo.GetGenericArguments().Length != 1 || methodInfo.GetParameters().Length != 0)
				{
					continue;
				}
				try
				{
					if (!(methodInfo.MakeGenericMethod(typeof(GameObject)).Invoke(null, null) is IEnumerable enumerable))
					{
						continue;
					}
					foreach (object item in enumerable)
					{
						GameObject val = (GameObject)((item is GameObject) ? item : null);
						if ((Object)(object)val != (Object)null)
						{
							list.Add(val);
						}
					}
					if (list.Count <= 0)
					{
						continue;
					}
					return list;
				}
				catch
				{
				}
			}
		}
		catch
		{
		}
		return list;
	}

	private bool LooksLikeGameplayScene()
	{
		try
		{
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return false;
			}
			List<GameObject> list = FindAllGameObjectsSafe();
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				GameObject val = list[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				bool activeInHierarchy;
				string name;
				try
				{
					activeInHierarchy = val.activeInHierarchy;
					name = ((Object)val).name;
				}
				catch
				{
					continue;
				}
				if (!activeInHierarchy)
				{
					continue;
				}
				num++;
				if (!string.IsNullOrEmpty(name))
				{
					string text = name.ToLowerInvariant();
					if (text.Contains("gourd") || text.Contains("puzzle") || text.Contains("bell") || text.Contains("train") || text.Contains("tram") || text.Contains("bird") || text.Contains("player"))
					{
						return true;
					}
					if ((text.Contains("mainmenu") || text.Contains("titlemenu") || text.Contains("loading") || text.Contains("boot")) && num < 40)
					{
						return false;
					}
				}
			}
			if (list.Count == 0)
			{
				string text2 = "";
				try
				{
					text2 = (((Object)(object)((Component)main).gameObject != (Object)null) ? ((Object)((Component)main).gameObject).name.ToLowerInvariant() : "");
				}
				catch
				{
				}
				if (text2.Contains("menu") || text2.Contains("title") || text2.Contains("loading") || text2.Contains("boot"))
				{
					return false;
				}
				return true;
			}
			return num >= 40;
		}
		catch (Exception ex)
		{
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("Gameplay probe skipped: " + ex.Message));
			}
			return gameplayArmed;
		}
	}

	private Vector3 PutOnGround(Vector3 position, float fallbackYOffset, float footClearance)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: 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_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = position + Vector3.up * 20f;
		try
		{
			int num = -5;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, Vector3.down, ref val2, 80f, num, (QueryTriggerInteraction)1))
			{
				position.y = ((RaycastHit)(ref val2)).point.y + footClearance;
				return position;
			}
		}
		catch
		{
		}
		position.y = (((Object)(object)cam != (Object)null) ? (((Component)cam).transform.position.y + fallbackYOffset + footClearance) : (position.y + footClearance));
		return position;
	}

	public void OnDestroy()
	{
		DisposeDebugMenu();
		DisposeChaseMusic();
		ReleaseHost(force: true);
		ClearActiveFigure();
		ClearLateEntities();
		if ((Object)(object)whiteMaterial != (Object)null)
		{
			Object.Destroy((Object)(object)whiteMaterial);
		}
		if ((Object)(object)blackMaterial != (Object)null)
		{
			Object.Destroy((Object)(object)blackMaterial);
		}
		whiteMaterial = null;
		blackMaterial = null;
	}

	private void ScheduleNextEvent(float minSeconds, float maxSeconds)
	{
		float num = (float)rng.NextDouble();
		nextEventAt = Time.time + minSeconds + (maxSeconds - minSeconds) * num;
	}

	private void BeginWhiteOneEvent()
	{
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		debugLateHidden = false;
		if (blackSpawnAt > 0f)
		{
			return;
		}
		if ((Object)(object)cam == (Object)null)
		{
			ScheduleNextEvent(20f, 40f);
			return;
		}
		try
		{
			activeFigure = BuildFigure("The White One", white: true);
			activeFigureIsDebug = false;
			activeFigureIsNaturalWhite = true;
			activeFigureIsNaturalBlack = false;
		}
		catch (Exception ex)
		{
			activeFigure = null;
			activeFigureIsDebug = false;
			activeFigureIsNaturalWhite = false;
			ScheduleNextEvent(20f, 40f);
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("White One spawn skipped: " + ex.Message));
			}
			return;
		}
		if ((Object)(object)activeFigure == (Object)null)
		{
			activeFigureIsDebug = false;
			activeFigureIsNaturalWhite = false;
			ScheduleNextEvent(20f, 40f);
			return;
		}
		try
		{
			if (!TryNaturalPosition(28f, 52f, 0.6f, out var point, white: true))
			{
				AbortSpawnedFigure();
				ScheduleNextEvent(25f, 45f);
				return;
			}
			if (rng.Next(0, 100) < 2)
			{
				point.y += 6.5f;
			}
			activeFigure.transform.position = point;
			FaceCamera(activeFigure);
			eventEndAt = Time.time + 12f;
			if (progress.White >= 2 && rng.Next(0, 100) < 30)
			{
				blackConstructionRetries = 0;
				blackSpawnAt = eventEndAt + 0.25f + (float)rng.NextDouble() * 1.5f;
			}
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogInfo((object)"???");
			}
		}
		catch (Exception ex2)
		{
			AbortSpawnedFigure();
			cam = null;
			ScheduleNextEvent(20f, 40f);
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("White One placement aborted: " + ex2.Message));
			}
		}
	}

	private void RetryOrAbandonBlackOne(string reason)
	{
		blackConstructionRetries++;
		if (gameplayArmed && blackConstructionRetries <= 3)
		{
			blackSpawnAt = Time.time + 1f;
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("Black One spawn retry " + blackConstructionRetries + "/" + 3 + ": " + reason));
			}
		}
		else
		{
			blackSpawnAt = -1f;
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("Black One spawn abandoned after " + blackConstructionRetries + " construction failures: " + reason));
			}
			blackConstructionRetries = 0;
		}
	}

	private void SpawnBlackOne()
	{
		//IL_00d4: 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)
		if ((Object)(object)cam == (Object)null || (Object)(object)activeFigure != (Object)null)
		{
			return;
		}
		try
		{
			activeFigure = BuildFigure("The Black One", white: false);
			activeFigureIsDebug = false;
			activeFigureIsNaturalWhite = false;
			activeFigureIsNaturalBlack = true;
		}
		catch (Exception ex)
		{
			activeFigure = null;
			activeFigureIsNaturalBlack = false;
			RetryOrAbandonBlackOne("construction exception: " + ex.Message);
			return;
		}
		if ((Object)(object)activeFigure == (Object)null)
		{
			activeFigureIsNaturalBlack = false;
			RetryOrAbandonBlackOne("figure construction returned null");
			return;
		}
		blackConstructionRetries = 0;
		try
		{
			if (!TryNaturalPosition(34f, 56f, 0.03f, out var point))
			{
				AbortSpawnedFigure();
				RetryOrAbandonBlackOne("no clear grounded position");
				return;
			}
			activeFigure.transform.position = point;
			activeFigure.transform.localScale = new Vector3(0.68f, 1.85f, 0.68f);
			FaceCamera(activeFigure);
			BeginHunt();
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogInfo((object)"???");
			}
		}
		catch (Exception ex2)
		{
			AbortSpawnedFigure();
			cam = null;
			RetryOrAbandonBlackOne("placement exception: " + ex2.Message);
		}
	}

	private GameObject BuildFigure(string name, bool white)
	{
		return BuildPlayerFigure(name, white);
	}

	private Material MakeMaterial(Color color)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Expected O, but got Unknown
		Shader val = Shader.Find("Unlit/Color");
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Sprites/Default");
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("UI/Default");
		}
		if ((Object)(object)val == (Object)null)
		{
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)"No usable shader found for ARG figure.");
			}
			return null;
		}
		return new Material(val)
		{
			color = color
		};
	}

	private void ApplyMaterial(GameObject go, Material mat)
	{
		Renderer component = go.GetComponent<Renderer>();
		if ((Object)(object)component != (Object)null && (Object)(object)mat != (Object)null)
		{
			component.sharedMaterial = mat;
		}
	}

	private void RemoveCollider(GameObject go)
	{
		Collider component = go.GetComponent<Collider>();
		if ((Object)(object)component != (Object)null)
		{
			component.enabled = false;
			Object.Destroy((Object)(object)component);
		}
	}

	private void FaceCamera(GameObject go)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)cam == (Object)null))
		{
			Vector3 position = ((Component)cam).transform.position;
			position.y = go.transform.position.y + 1.5f;
			go.transform.LookAt(position);
		}
	}

	private void RecoverMissingFigure()
	{
		ClearFigureMeshes();
		bool num = activeFigureIsDebug;
		bool flag = activeFigureIsNaturalWhite;
		bool flag2 = activeFigureIsNaturalBlack;
		activeFigure = null;
		activeFigureIsDebug = false;
		activeFigureIsNaturalWhite = false;
		activeFigureIsNaturalBlack = false;
		noticedFigure = null;
		noticedTime = 0f;
		sightingCounted = false;
		eventEndAt = 0f;
		if (num)
		{
			return;
		}
		if (flag)
		{
			if (gameplayArmed)
			{
				ScheduleNextEvent(75f, 210f);
			}
			else
			{
				nextEventAt = float.PositiveInfinity;
			}
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)"Natural White figure vanished externally; ARG state recovered.");
			}
		}
		else if (flag2 && Plugin.LogSource != null)
		{
			Plugin.LogSource.LogWarning((object)"Natural Black figure vanished externally; ARG state recovered.");
		}
	}

	private void EndActiveFigure()
	{
		StopChaseMusic();
		ClearFigureMeshes();
		bool num = activeFigureIsDebug;
		bool flag = activeFigureIsNaturalWhite;
		if ((Object)(object)activeFigure != (Object)null)
		{
			DestroyFigure(activeFigure);
		}
		activeFigure = null;
		activeFigureIsDebug = false;
		activeFigureIsNaturalWhite = false;
		activeFigureIsNaturalBlack = false;
		noticedFigure = null;
		noticedTime = 0f;
		sightingCounted = false;
		eventEndAt = 0f;
		if (!num && flag)
		{
			if (gameplayArmed)
			{
				ScheduleNextEvent(75f, 210f);
			}
			else
			{
				nextEventAt = float.PositiveInfinity;
			}
		}
	}

	private void ScanIsland()
	{
		try
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			HashSet<string> hashSet = new HashSet<string>();
			List<GameObject> list = FindAllGameObjectsSafe();
			for (int i = 0; i < list.Count; i++)
			{
				GameObject val = list[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				bool activeInHierarchy;
				string name;
				try
				{
					activeInHierarchy = val.activeInHierarchy;
					name = ((Object)val).name;
				}
				catch
				{
					continue;
				}
				if (activeInHierarchy && !string.IsNullOrEmpty(name))
				{
					string text = name.ToLowerInvariant();
					bool flag = false;
					if (text.Contains("ball"))
					{
						num++;
						flag = true;
					}
					if (text.Contains("bell"))
					{
						num2++;
						flag = true;
					}
					if (text.Contains("lantern") || text.Contains("lamp"))
					{
						num3++;
						flag = true;
					}
					if (text.Contains("puzzle"))
					{
						num4++;
						flag = true;
					}
					if (text.Contains("gourd"))
					{
						num5++;
						flag = true;
					}
					if (flag && hashSet.Count < 80 && !alreadyLoggedObjectNames.Contains(name))
					{
						hashSet.Add(name);
					}
				}
			}
			if (Plugin.LogSource == null)
			{
				return;
			}
			Plugin.LogSource.LogInfo((object)("??? ball=" + num + " bell=" + num2 + " lantern=" + num3 + " puzzle=" + num4 + " gourd=" + num5));
			foreach (string item in hashSet)
			{
				alreadyLoggedObjectNames.Add(item);
				Plugin.LogSource.LogInfo((object)("??? object=" + item));
			}
		}
		catch (Exception ex)
		{
			if (Plugin.LogSource != null)
			{
				Plugin.LogSource.LogWarning((object)("ARG scene scan skipped: " + ex.Message));
			}
		}
	}

	private void LoadChaseMusic()
	{
		try
		{
			using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "BlackOneChase.wav")))))
			{
				if (new string(binaryReader.ReadChars(4)) != "RIFF")
				{
					throw new InvalidDataException("Expected RIFF WAV");
				}
				binaryReader.ReadUInt32();
				if (new string(binaryReader.ReadChars(4)) != "WAVE")
				{
					throw new InvalidDataException("Expected WAVE");
				}
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				int num4 = 0;
				byte[] array = null;
				while (binaryReader.BaseStream.Position + 8 <= binaryReader.BaseStream.Length)
				{
					string text = new string(binaryReader.ReadChars(4));
					int num5 = checked((int)binaryReader.ReadUInt32());
					long num6 = binaryReader.BaseStream.Position + num5;
					if (num6 > binaryReader.BaseStream.Length)
					{
						throw new InvalidDataException("Truncated WAV chunk");
					}
					if (text == "fmt ")
					{
						if (num5 < 16)
						{
							throw new InvalidDataException("Invalid format chunk");
						}
						num4 = binaryReader.ReadUInt16();
						num = binaryReader.ReadUInt16();
						num2 = binaryReader.ReadInt32();
						binaryReader.ReadUInt32();
						binaryReader.ReadUInt16();
						num3 = binaryReader.ReadUInt16();
					}
					else if (text == "data")
					{
						array = binaryReader.ReadBytes(num5);
					}
					binaryReader.BaseStream.Position = num6 + (num5 & 1);
				}
				if (num4 != 1 || num3 != 16 || num < 1 || num > 2 || num2 < 8000 || array == null || array.Length % (num * 2) != 0)
				{
					throw new InvalidDataException("Expected 16-bit PCM mono/stereo WAV");
				}
				Il2CppStructArray<float> val = new Il2CppStructArray<float>((long)(array.Length / 2));
				for (int i = 0; i < ((Il2CppArrayBase<float>)(object)val).Length; i++)
				{
					((Il2CppArrayBase<float>)(object)val)[i] = (float)(short)(array[i * 2] | (array[i * 2 + 1] << 8)) / 32768f;
				}
				chaseClip = AudioClip.Create("Black One - Run!", ((Il2CppArrayBase<float>)(object)val).Length / num, num, num2, false);
				if (!chaseClip.SetData(val, 0))
				{
					throw new InvalidDataException("Audio sample upload failed");
				}
			}
			chaseAudio = ((Component)this).gameObject.AddComponent<AudioSource>();
			chaseAudio.playOnAwake = false;
			chaseAudio.clip = chaseClip;
			chaseAudio.loop = true;
			chaseAudio.spatialBlend = 0f;
			chaseAudio.volume = 0.65f;
			Plugin.LogSource.LogInfo((object)("Black One chase music loaded: " + chaseClip.length.ToString("F1") + " seconds."));
		}
		catch (Exception ex)
		{
			Plugin.LogSource.LogWarning((object)("Chase music unavailable; encounters remain active: " + ex.Message));
		}
	}

	private void SetChaseMusic(bool playing)
	{
		if ((Object)(object)chaseAudio == (Object)null)
		{
			return;
		}
		if (!playing)
		{
			if (chaseStarted)
			{
				chaseAudio.Pause();
			}
		}
		else if (!chaseStarted)
		{
			chaseAudio.Play();
			chaseStarted = true;
		}
		else if (!chaseAudio.isPlaying)
		{
			chaseAudio.UnPause();
		}
	}

	private void StopChaseMusic()
	{
		if ((Object)(object)chaseAudio != (Object)null)
		{
			chaseAudio.Stop();
		}
		chaseStarted = false;
	}

	private void DisposeChaseMusic()
	{
		StopChaseMusic();
		if ((Object)(object)chaseAudio != (Object)null)
		{
			Object.Destroy((Object)(object)chaseAudio);
		}
		if ((Object)(object)chaseClip != (Object)null)
		{
			Object.Destroy((Object)(object)chaseClip);
		}
		chaseAudio = null;
		chaseClip = null;
	}

	public void OnDisable()
	{
		SetDebugMenu(open: false);
		StopChaseMusic();
	}

	private void SetDebugMenu(bool open)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		debugMenuOpen = open;
		if (open && !debugCursorOwned)
		{
			debugPreviousCursorLock = Cursor.lockState;
			debugPreviousCursorVisible = Cursor.visible;
			debugCursorOwned = true;
		}
		if (!open && debugCursorOwned)
		{
			Cursor.lockState = debugPreviousCursorLock;
			Cursor.visible = debugPreviousCursorVisible;
			debugCursorOwned = false;
		}
	}

	public void LateUpdate()
	{
		if (debugMenuOpen && Application.isFocused)
		{
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}
	}

	private void DisposeDebugMenu()
	{
		SetDebugMenu(open: false);
		if ((Object)(object)debugRounded != (Object)null)
		{
			Object.Destroy((Object)(object)debugRounded);
		}
		if ((Object)(object)debugEye != (Object)null)
		{
			Object.Destroy((Object)(object)debugEye);
		}
	}

	private void DeleteDebugEntities()
	{
		if (!SharedFollower)
		{
			ClearActiveFigure();
			ClearLateEntities();
			debugLateHidden = true;
			ScheduleNextEvent(75f, 210f);
			sharedSnapshotAt = 0f;
		}
	}

	private void ToggleDebugSpawning()
	{
		if (!SharedFollower)
		{
			debugSpawningPaused = !debugSpawningPaused;
			if (debugSpawningPaused)
			{
				ClearActiveFigure();
				ClearLateEntities();
			}
			else
			{
				debugLateHidden = false;
				lateFailed = false;
				nextGameplayProbeAt = 0f;
				ScheduleNextEvent(45f, 100f);
			}
			sharedSnapshotAt = 0f;
		}
	}

	private void RefreshDebugEntities()
	{
		ClearActiveFigure();
		ClearLateEntities();
		lateFailed = false;
		debugLateHidden = false;
		sharedFigureInstance = 0;
		sharedHelloAt = 0f;
		sharedSnapshotAt = 0f;
		nextGameplayProbeAt = 0f;
		nextLateAttempt = 0f;
		if (SharedDriver)
		{
			ScheduleNextEvent(45f, 100f);
		}
		Plugin.LogSource.LogInfo((object)"Debug reset: rebuilt encounter presentation and refreshed sync; saved progress preserved.");
	}

	private Texture2D MakeMenuTexture(int width, int height, bool eye)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Expected O, but got Unknown
		//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_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(width, height, (TextureFormat)4, false);
		((Object)val).hideFlags = (HideFlags)61;
		((Texture)val).filterMode = (FilterMode)1;
		((Texture)val).wrapMode = (TextureWrapMode)1;
		Color[] array = (Color[])(object)new Color[width * height];
		for (int i = 0; i < height; i++)
		{
			for (int j = 0; j < width; j++)
			{
				float num = ((float)j + 0.5f) / (float)width;
				float num2 = ((float)i + 0.5f) / (float)height;
				Color val2 = Color.clear;
				if (eye)
				{
					float num3 = 0.1f + 0.47f * (float)Math.Exp(0.0 - Math.Pow((num - 0.52f) / 0.235f, 2.0));
					if (num2 > num3)
					{
						((Color)(ref val2))..ctor(0.39f, 0f, 0.09f, 1f);
					}
					float num4 = (num - 0.52f) / 0.27f;
					float num5 = (num2 - 0.56f) / 0.095f;
					if (num4 * num4 + num5 * num5 < 1f)
					{
						val2 = Color.white;
					}
					float num6 = (num - 0.53f) / 0.207f;
					float num7 = (num2 - 0.48f) / 0.31f;
					if (num6 * num6 + num7 * num7 < 1f)
					{
						((Color)(ref val2))..ctor(1f, 0.945f, 0.8f, 1f);
					}
					float num8 = (num - 0.54f) / 0.087f;
					float num9 = (num2 - 0.48f) / 0.185f;
					if (num8 * num8 + num9 * num9 < 1f)
					{
						((Color)(ref val2))..ctor(0.115f, 0f, 0f, 1f);
					}
				}
				else
				{
					float num10 = Math.Max(0f, Math.Abs(num - 0.5f) - 0.32f);
					float num11 = Math.Max(0f, Math.Abs(num2 - 0.5f) - 0.32f);
					float num12 = Math.Max(0f, Math.Min(1f, (0.18f - (float)Math.Sqrt(num10 * num10 + num11 * num11)) * (float)width));
					((Color)(ref val2))..ctor(1f, 1f, 1f, num12);
				}
				array[i * width + j] = val2;
			}
		}
		val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
		val.Apply();
		return val;
	}

	private void PrepareMenuStyles()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Expected O, but got Unknown
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Expected O, but got Unknown
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Expected O, but got Unknown
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Expected O, but got Unknown
		if ((Object)(object)debugRounded == (Object)null)
		{
			debugRounded = MakeMenuTexture(128, 128, eye: false);
		}
		if ((Object)(object)debugEye == (Object)null)
		{
			debugEye = MakeMenuTexture(1024, 340, eye: true);
		}
		if (debugButton == null)
		{
			debugButton = new GUIStyle(GUI.skin.button);
			debugButton.fontSize = 31;
			debugButton.fontStyle = (FontStyle)1;
			debugButton.alignment = (TextAnchor)4;
			debugButton.wordWrap = true;
			debugButton.normal.background = debugRounded;
			debugButton.hover.background = debugRounded;
			debugButton.active.background = debugRounded;
			debugButton.focused.background = debugRounded;
			debugButton.normal.textColor = Color.white;
			debugButton.hover.textColor = new Color(1f, 0.945f, 0.8f);
			debugButton.active.textColor = Color.white;
			debugButton.focused.textColor = Color.white;
			debugButton.border = new RectOffset(24, 24, 24, 24);
			debugButton.padding = new RectOffset(14, 14, 8, 8);
			debugLabel = new GUIStyle(GUI.skin.label);
			debugLabel.fontSize = 28;
			debugLabel.fontStyle = (FontStyle)1;
			debugLabel.normal.textColor = new Color(1f, 0.945f, 0.8f);
			debugSmall = new GUIStyle(debugLabel);
			debugSmall.fontSize = 17;
			debugSmall.wordWrap = true;
		}
	}

	private void MenuPanel(Rect rect, Color color)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		Color color2 = GUI.color;
		GUI.color = color;
		GUI.DrawTexture(rect, (Texture)(object)debugRounded);
		GUI.color = color2;
	}

	private bool MenuButton(Rect rect, string text, Color color)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		Color backgroundColor = GUI.backgroundColor;
		GUI.backgroundColor = color;
		bool result = GUI.Button(rect, text, debugButton);
		GUI.backgroundColor = backgroundColor;
		return result;
	}

	private void DrawBentleyMenu()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: 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_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: 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_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: 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_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0380: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Unknown result type (might be due to invalid IL or missing references)
		//IL_0455: Unknown result type (might be due to invalid IL or missing references)
		//IL_0473: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
		PrepareMenuStyles();
		Matrix4x4 matrix = GUI.matrix;
		Color color = GUI.color;
		Color backgroundColor = GUI.backgroundColor;
		bool enabled = GUI.enabled;
		try
		{
			float num = Math.Min((float)Screen.width / 1100f, (float)Screen.height / 820f) * 0.94f;
			float num2 = ((float)Screen.width - 1100f * num) * 0.5f;
			float num3 = ((float)Screen.height - 820f * num) * 0.5f;
			GUI.matrix = Matrix4x4.TRS(new Vector3(num2, num3, 0f), Quaternion.identity, new Vector3(num, num, 1f));
			GUI.color = Color.white;
			GUI.DrawTexture(new Rect(0f, 0f, 1100f, 820f), (Texture)(object)Texture2D.whiteTexture);
			GUI.DrawTexture(new Rect(0f, 0f, 1100f, 340f), (Texture)(object)debugEye);
			if (MenuButton(new Rect(986f, 16f, 94f, 48f), "6 / X", new Color(0.24f, 0f, 0.055f)))
			{
				SetDebugMenu(open: false);
			}
			GUI.enabled = enabled && !SpawningPaused;
			if (MenuButton(new Rect(48f, 350f, 456f, 148f), "Spawn the\nblack one  [2]", new Color(0.115f, 0.115f, 0.115f)))
			{
				DebugSpawnBlackOne();
			}
			debugButton.normal.textColor = new Color(0.39f, 0f, 0.09f);
			debugButton.hover.textColor = new Color(0.55f, 0f, 0.12f);
			if (MenuButton(new Rect(596f, 350f, 456f, 148f), "Spawn the\nwhite one  [1]", new Color(0.86f, 0.86f, 0.86f)))
			{
				DebugSpawnWhiteOne();
			}
			debugButton.normal.textColor = Color.white;
			debugButton.hover.textColor = new Color(1f, 0.945f, 0.8f);
			GUI.enabled = enabled;
			MenuPanel(new Rect(32f, 530f, 646f, 256f), new Color(0.2f, 0.23f, 0.28f));
			string text = (LateEntitiesHidden ? "paused" : (progress.BeyondUnlocked ? "enabled" : "locked"));
			string text2 = (LateEntitiesHidden ? "paused" : (progress.BellUnlocked ? "enabled" : "locked"));
			GUI.Label(new Rect(56f, 548f, 610f, 42f), "The one beyond: " + text, debugLabel);
			GUI.Label(new Rect(56f, 592f, 610f, 42f), "Third bell: " + text2, debugLabel);
			if (MenuButton(new Rect(52f, 645f, 605f, 78f), "Reset all", new Color(0.39f, 0f, 0.09f)))
			{
				RefreshDebugEntities();
			}
			GUI.Label(new Rect(57f, 732f, 600f, 46f), "Use if others can't see them. Refreshes entities; keeps progress.", debugSmall);
			GUI.enabled = enabled && SharedDriver;
			if (MenuButton(new Rect(726f, 520f, 326f, 118f), "Delete current\nentities", new Color(0.88f, 0.06f, 0.24f)))
			{
				DeleteDebugEntities();
			}
			if (MenuButton(new Rect(726f, 653f, 326f, 133f), SpawningPaused ? "Enable entity\nspawning" : "Disable entity\nspawning", new Color(0.39f, 0f, 0.09f)))
			{
				ToggleDebugSpawning();
			}
			GUI.enabled = enabled;
			debugSmall.normal.textColor = new Color(0.39f, 0f, 0.09f);
			GUI.Label(new Rect(35f, 790f, 1040f, 28f), (SharedFollower ? "Following leader (delete / disable: leader only)" : "Encounter leader") + "  |  Peers: " + sharedPeers.Count + "  |  6 to close", debugSmall);
			debugSmall.normal.textColor = new Color(1f, 0.945f, 0.8f);
		}
		finally
		{
			GUI.matrix = matrix;
			GUI.color = color;
			GUI.backgroundColor = backgroundColor;
			GUI.enabled = enabled;
		}
	}

	private bool FinderActive()
	{
		PeckEffectPropXRay activeEffect = PeckEffectPropXRay.activeEffect;
		return PresentationRules.FinderReveal(progress.BeyondUnlocked, (Object)(object)activeEffect != (Object)null && ((Behaviour)activeEffect).isActiveAndEnabled, (Object)(object)activeEffect != (Object)null && activeEffect.isInDeadZone);
	}

	private void PositionHorizonBell()
	{
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: 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_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_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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_008b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)thirdBell == (Object)null || (Object)(object)cam == (Object)null)
		{
			return;
		}
		if (SharedFollower)
		{
			if (replica != null && replica.BellPresent)
			{
				thirdBell.transform.position = new Vector3(replica.BellX, replica.BellY, replica.BellZ);
				thirdBell.transform.localScale = Vector3.one * replica.BellScale;
			}
		}
		else
		{
			float num = PresentationRules.HorizonDistance(cam.farClipPlane);
			thirdBell.transform.position = ((Component)cam).transform.position + bellBearing * num - Vector3.up * (num * 0.08f);
			thirdBell.transform.localScale = Vector3.one * (num / 240f);
		}
	}

	private Light FindSun()
	{
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Invalid comparison between Unknown and I4
		Light sun = RenderSettings.sun;
		if ((Object)(object)sun != (Object)null && ((Behaviour)sun).enabled)
		{
			return sun;
		}
		if (Time.time >= nextSunSearch)
		{
			nextSunSearch = Time.time + 15f;
			fallbackSun = null;
			foreach (GameObject item in FindAllGameObjectsSafe())
			{
				if (!((Object)(object)item == (Object)null) && item.activeInHierarchy)
				{
					Light component = item.GetComponent<Light>();
					if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled && (int)component.type == 1 && component.intensity > 0f && ((Object)(object)fallbackSun == (Object)null || component.intensity > fallbackSun.intensity))
					{
						fallbackSun = component;
					}
				}
			}
		}
		return fallbackSun;
	}

	private void SaveProgress()
	{
		try
		{
			string text = progressPath + ".tmp";
			File.WriteAllText(text, progress.Save());
			if (File.Exists(progressPath))
			{
				File.Replace(text, progressPath, null);
			}
			else
			{
				File.Move(text, progressPath);
			}
		}
		catch (Exception ex)
		{
			Plugin.LogSource.LogWarning((object)("Progress save failed: " + ex.Message));
		}
	}

	private bool VisiblePoint(Vector3 point)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: 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_0044: 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_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)cam == (Object)null)
		{
			return false;
		}
		Vector3 val = cam.WorldToViewportPoint(point);
		if (val.z <= 0f || val.x < 0.12f || val.x > 0.88f || val.y < 0.12f || val.y > 0.88f)
		{
			return false;
		}
		Vector3 val2 = point - ((Component)cam).transform.position;
		float num = (float)Math.Sqrt(((Vector3)(ref val2)).sqrMagnitude);
		if (num < 0.1f)
		{
			return false;
		}
		((Vector3)(ref val2)).Normalize();
		RaycastHit val3 = default(RaycastHit);
		return !Physics.Raycast(((Component)cam).transform.position, val2, ref val3, Math.Max(0.1f, num - 0.4f), -5, (QueryTriggerInteraction)1);
	}

	private void ObserveEncounter(float delta)
	{
		//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_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)activeFigure == (Object)null || Time.time >= eventEndAt || activeFigureIsDebug || (!activeFigureIsNaturalWhite && !activeFigureIsNaturalBlack))
		{
			noticedFigure = null;
			noticedTime = 0f;
			sightingCounted = false;
			return;
		}
		if ((Object)(object)noticedFigure != (Object)(object)activeFigure)
		{
			noticedFigure = activeFigure;
			noticedTime = 0f;
			sightingCounted = false;
		}
		if (!sightingCounted)
		{
			if (VisiblePoint(activeFigure.transform.position + Vector3.up * 2.5f))
			{
				noticedTime += delta;
			}
			else
			{
				noticedTime = 0f;
			}
			if (!(noticedTime < 0.75f))
			{
				sightingCounted = true;
				progress.Notice(activeFigureIsNaturalWhite);
				SaveProgress();
				Plugin.LogSource.LogInfo((object)("Noticed encounter: white=" + progress.White + ", black=" + progress.Black));
			}
		}
	}

	private bool TryNaturalPosition(float min, float max, float clearance, out Vector3 point, bool white = false)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: 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_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: 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)
		point = Vector3.zero;
		if ((Object)(object)cam == (Object)null)
		{
			return false;
		}
		Vector3 forward = ((Component)cam).transform.forward;
		forward.y = 0f;
		if (((Vector3)(ref forward)).sqrMagnitude < 0.1f)
		{
			forward = Vector3.forward;
		}
		((Vector3)(ref forward)).Normalize();
		Vector3 right = ((Component)cam).transform.right;
		right.y = 0f;
		((Vector3)(ref right)).Normalize();
		RaycastHit val2 = default(RaycastHit);
		for (int i = 0; i < 16; i++)
		{
			Vector3 val = ((Component)cam).transform.position + forward * (min + (float)rng.NextDouble() * (max - min)) + right * ((float)rng.NextDouble() * 2f - 1f) * (max * 0.5f);
			if (Physics.Raycast(val + Vector3.up * 60f, Vector3.down, ref val2, 180f, -5, (QueryTriggerInteraction)1))
			{
				val = ((RaycastHit)(ref val2)).point + Vector3.up * clearance;
				if ((!white || WhiteSideOfWall(val)) && VisiblePoint(val + Vector3.up * 2.5f))
				{
					point = val;
					return true;
				}
			}
		}
		return false;
	}

	private GameObject Part(GameObject root, string name, PrimitiveType type, Vector3 position, Vector3 scale, Material material)
	{
		//IL_0000: 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_0033: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.CreatePrimitive(type);
		((Object)val).name = name;
		val.transform.SetParent(root.transform, false);
		val.transform.localPosition = position;
		val.transform.localScale = scale;
		ApplyMaterial(val, material);
		RemoveCollider(val);
		if ((Object)(object)root == (Object)(object)beyond)
		{
			Renderer component = val.GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null)
			{
				component.enabled = false;
				beyondRenderers.Add(component);
			}
		}
		return val;
	}

	private void UpdateLateEntities(float delta)
	{
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a5: 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_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_0333: Unknown result type (might be due to invalid IL or missing references)
		//IL_0338: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Unknown result type (might be due to invalid IL or missing references)
		//IL_034b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0355: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: Unknown result type (might be due to invalid IL or missing references)
		//IL_035c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0362: Unknown result type (might be due to invalid IL or missing references)
		//IL_036a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0370: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_037f: Unknown result type (might be due to invalid IL or missing references)
		//IL_038a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Expected O, but got Unknown
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		if (LateEntitiesHidden)
		{
			if ((Object)(object)thirdBell != (Object)null || (Object)(object)beyond != (Object)null)
			{
				ClearLateEntities();
			}
			return;
		}
		if ((Object)(object)cam == (Object)null)
		{
			return;
		}
		if (SharedFollower)
		{
			if (replica == null)
			{
				return;
			}
			progress.Load(replica.White + "," + replica.Black + "," + (replica.BellSeen ? "1" : "0"));
			if (!replica.BellPresent && (Object)(object)thirdBell != (Object)null)
			{
				Object.Destroy((Object)(object)thirdBell);
				thirdBell = null;
			}
		}
		if ((Object)(object)blackMaterial == (Object)null)
		{
			blackMaterial = MakeMaterial(Color.black);
		}
		if ((Object)(object)blackMaterial == (Object)null || !ResolveWall())
		{
			return;
		}
		if ((Object)(object)beyond == (Object)null)
		{
			BuildBeyondModel();
		}
		bool num;
		if ((Object)(object)thirdBell == (Object)null)
		{
			if (!SharedFollower)
			{
				if (progress.BellUnlocked && (Object)(object)activeFigure == (Object)null)
				{
					num = Time.time >= nextLateAttempt;
					goto IL_018d;
				}
			}
			else if (replica != null)
			{
				num = replica.BellPresent;
				goto IL_018d;
			}
		}
		goto IL_0244;
		IL_0244:
		PositionHorizonBell();
		if (SharedDriver && (Object)(object)thirdBell != (Object)null && !progress.BellSeen)
		{
			bellLookTime = (VisiblePoint(thirdBell.transform.position + Vector3.up * (40f * thirdBell.transform.localScale.y)) ? (bellLookTime + delta) : 0f);
			if (bellLookTime >= 1f)
			{
				progress.NoticeBell();
				SaveProgress();
			}
		}
		Light val = FindSun();
		bool flag = false;
		if (progress.BeyondUnlocked && (Object)(object)val != (Object)null && ((Behaviour)val).enabled)
		{
			Vector3 val2 = beyond.transform.position - ((Component)cam).transform.position;
			((Vector3)(ref val2)).Normalize();
			Vector3 val3 = ((Component)val).transform.forward * -1f;
			float num2 = val2.x * val3.x + val2.y * val3.y + val2.z * val3.z;
			flag = val3.y > 0f && num2 > 0.985f;
		}
		bool flag2 = progress.BeyondUnlocked && FinderActive();
		foreach (Renderer beyondRenderer in beyondRenderers)
		{
			if ((Object)(object)beyondRenderer != (Object)null)
			{
				beyondRenderer.enabled = flag || flag2;
			}
		}
		if (flag2 != lastFinderReveal)
		{
			lastFinderReveal = flag2;
			Plugin.LogSource.LogInfo((object)(flag2 ? "Item finder reveals The One Beyond The Wall." : "Item finder reveal ended; normal cloak restored."));
		}
		return;
		IL_018d:
		if (num)
		{
			nextLateAttempt = Time.time + 30f;
			bellBearing = ((Component)cam).transform.forward;
			bellBearing.y = 0f;
			if (((Vector3)(ref bellBearing)).sqrMagnitude < 0.1f)
			{
				bellBearing = Vector3.forward;
			}
			((Vector3)(ref bellBearing)).Normalize();
			thirdBell = new GameObject("The Third Bell");
			thirdBell.SetActive(false);
			PositionHorizonBell();
			BuildChristmasBell(thirdBell, Vector3.zero, 70f);
			thirdBell.SetActive(true);
			Plugin.LogSource.LogInfo((object)"The Third Bell is present.");
		}
		goto IL_0244;
	}

	private void ClearLateEntities()
	{
		if ((Object)(object)thirdBell != (Object)null)
		{
			Object.Destroy((Object)(object)thirdBell);
		}
		if ((Object)(object)beyond != (Object)null)
		{
			Object.Destroy((Object)(object)beyond);
		}
		if ((Object)(object)finderMaterial != (Object)null)
		{
			Object.Destroy((Object)(object)finderMaterial);
		}
		finderMaterial = null;
		lastFinderReveal = false;
		ClearLandmarkAssets();
		wallReady = false;
		nextWallSearch = 0f;
		thirdBell = null;
		beyond = null;
		fallbackSun = null;
		nextSunSearch = 0f;
		beyondRenderers.Clear();
		bellLookTime = 0f;
		nextLateAttempt = Time.time + 15f;
	}

	private void CapturePlayer(PlayerCharacter player)
	{
		//IL_01ea: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null || !((NetworkBehaviour)player).isLocalPlayer)
		{
			return;
		}
		if (NetworkServer.active)
		{
			if ((Object)(object)capturedHost != (Object)null || (Object)(object)player.rb == (Object)null || player.registry == null || (Object)(object)player.registry.corpsePrefab == (Object)null || (Object)(object)player.playerNetworking == (Object)null)
			{
				return;
			}
			savedUpdate = player.bypassUpdate;
			savedLate = player.bypassLateUpdate;
			savedFixed = player.bypassFixedUpdate;
			savedKinematic = player.rb.isKinematic;
			savedGhost = player.playerNetworking.isGhost;
			savedAudioGhost = player.playerNetworking.isAudioGhost;
			savedCursorVisible = Cursor.visible;
			savedCursorLock = Cursor.lockState;
			capturedPhysics = new HostPhysicsSnapshot(player);
			capturedHost = player;
			captureWasHost = true;
			captureActive = true;
			returnNotice = "";
			capturedAt = Time.unscaledTime;
			try
			{
				capturedCorpse = Corpse.CreateAndSpawn(player, player.registry.corpsePrefab);
				if ((Object)(object)capturedCorpse == (Object)null)
				{
					throw new InvalidOperationException("Vanilla corpse creation failed");
				}
				player.playerNetworking.NetworkisGhost = true;
				player.playerNetworking.NetworkisAudioGhost = true;
				player.bypassUpdate = true;
				player.bypassLateUpdate = true;
				player.bypassFixedUpdate = true;
				player.rb.isKinematic = true;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				Plugin.LogSource.LogInfo((object)"Black One caught the host: avatar suspended, native corpse spawned, server kept running.");
				return;
			}
			catch
			{
				ReleaseHost(force: true);
				throw;
			}
		}
		if (!NetworkClient.isConnected || captureActive || (Object)(object)player.rb == (Object)null)
		{
			return;
		}
		savedUpdate = player.bypassUpdate;
		savedLate = player.bypassLateUpdate;
		savedFixed = player.bypassFixedUpdate;
		savedCursorVisible = Cursor.visible;
		savedCursorLock = Cursor.lockState;
		capturedPhysics = new HostPhysicsSnapshot(player);
		capturedHost = player;
		captureWasHost = false;
		capturedCorpse = null;
		captureActive = true;
		returnNotice = "";
		capturedAt = Time.unscaledTime;
		nextReturnAttempt = 0f;
		try
		{
			player.bypassUpdate = true;
			player.bypassLateUpdate = true;
			player.bypassFixedUpdate = true;
			player.rb.isKinematic = true;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			Plugin.LogSource.LogInfo((object)"Black One caught the local guest: controls suspended; lobby, avatar and voice retained.");
		}
		catch
		{
			ReleaseHost(force: true);
			throw;
		}
	}

	private bool UpdateHostCapture()
	{
		if (!captureActive)
		{
			return false;
		}
		if ((Object)(object)capturedHost == (Object)null || (captureWasHost ? (!NetworkServer.active) : (!NetworkClient.isConnected)) || !((Component)capturedHost).gameObject.activeInHierarchy)
		{
			ReleaseHost(force: true);
			return false;
		}
		Cursor.lockState = (CursorLockMode)0;
		Cursor.visible = true;
		if (Application.isFocused && Time.unscaledTime - capturedAt > 1f && Time.unscaledTime >= nextReturnAttempt && (GetAsyncKeyState(13) & 0x8000) != 0)
		{
			nextReturnAttempt = Time.unscaledTime + 1f;
			ReleaseHost();
			return captureActive;
		}
		return true;
	}

	private void RestorePart(Action action, string name)
	{
		try
		{
			action();
		}
		catch (Exception ex)
		{
			Plugin.LogSource.LogWarning((object)("Host return " + name + ": " + ex.Message));
		}
	}

	private void ReleaseHost(bool force = false)
	{
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		if (!captureActive)
		{
			return;
		}
		PlayerCharacter player = capturedHost;
		if (!force && (Object)(object)player != (Object)null && (Object)(object)capturedCorpse != (Object)null && capturedPhysics != null && NetworkServer.active)
		{
			try
			{
				if (!capturedPhysics.TryUseCorpsePosition(capturedCorpse))
				{
					returnNotice = "No safe standing space near your body. Move it to open ground and retry.";
					Plugin.LogSource.LogWarning((object)returnNotice);
					return;
				}
			}
			catch (Exception ex)
			{
				returnNotice = "Could not check a safe return spot. Please retry.";
				Plugin.LogSource.LogWarning((object)(returnNotice + " " + ex.Message));
				return;
			}
		}
		if ((Object)(object)player != (Object)null)
		{
			if ((Object)(object)capturedCorpse != (Object)null && NetworkServer.active)
			{
				RestorePart(delegate
				{
					capturedCorpse.ExpireDueToRevival(player);
				}, "corpse/item return");
			}
			if (captureWasHost && NetworkServer.active && (Object)(object)player.playerNetworking != (Object)null)
			{
				RestorePart(delegate
				{
					player.playerNetworking.NetworkisGhost = savedGhost;
				}, "visibility");
				RestorePart(delegate
				{
					player.playerNetworking.NetworkisAudioGhost = savedAudioGhost;
				}, "voice");
			}
			RestorePart(delegate
			{
				if (capturedPhysics != null)
				{
					capturedPhysics.Restore();
				}
			}, "collision and safe return");
			RestorePart(delegate
			{
				player.bypassUpdate = savedUpdate;
			}, "Update");
			RestorePart(delegate
			{
				player.bypassLateUpdate = savedLate;
			}, "LateUpdate");
			RestorePart(delegate
			{
				player.bypassFixedUpdate = savedFixed;
			}, "FixedUpdate");
			Plugin.LogSource.LogInfo((object)"Capture return: restored avatar physics and controls; connection preserved.");
		}
		capturedPhysics = null;
		capturedHost = null;
		captureActive = false;
		capturedCorpse = null;
		Cursor.lockState = savedCursorLock;
		Cursor.visible = savedCursorVisible;
		ClearActiveFigure();
		ScheduleNextEvent(75f, 210f);
	}

	private bool DrawHostCapture()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: 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_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: 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)
		if ((Object)(object)capturedHost == (Object)null)
		{
			return false;
		}
		int depth = GUI.depth;
		Color color = GUI.color;
		GUI.depth = -10000;
		GUI.color = Color.black;
		GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = Color.white;
		float num = Math.Min(560f, (float)Screen.width - 32f);
		float num2 = ((float)Screen.width - num) / 2f;
		float num3 = (float)Screen.height / 2f - 90f;
		GUI.Box(new Rect(num2, num3, num, 240f), "THE BLACK ONE FOUND YOU");
		GUI.Label(new Rect(num2 + 20f, num3 + 40f, num - 40f, 60f), captureWasHost ? "You are out of play. Your body remains with your friends.\nYour PC is still hosting the lobby so they can keep playing." : "You were caught, but you are still connected.\nYour avatar and voice remain in the lobby. Return when ready.");
		if (returnNotice.Length > 0)
		{
			GUI.Label(new Rect(num2 + 20f, num3 + 170f, num - 40f, 60f), returnNotice);
		}
		bool enabled = GUI.enabled;
		GUI.enabled = Time.unscaledTime - capturedAt > 1f;
		if (GUI.Button(new Rect(num2 + 40f, num3 + 115f, num - 80f, 44f), "Return to play  [Enter]"))
		{
			ReleaseHost();
		}
		GUI.enabled = enabled;
		GUI.color = color;
		GUI.depth = depth;
		return true;
	}

	private void BeginHunt()
	{
		StopChaseMusic();
		huntedFigure = activeFigure;
		hunt = new HuntState();
		sharedTarget = 0uL;
		eventEndAt = Time.time + 30f;
	}

	private void UpdateHunt()
	{
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: 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_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: 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_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		if (hunt == null)
		{
			StopChaseMusic();
			return;
		}
		if ((Object)(object)activeFigure == (Object)null || (Object)(object)huntedFigure != (Object)(object)activeFigure)
		{
			StopChaseMusic();
			hunt = null;
			huntedFigure = null;
			return;
		}
		try
		{
			PlayerCharacter val = SharedHuntPlayer();
			List<PlayerCharacter> allPlayerCharacters = PlayerCharacter.allPlayerCharacters;
			if ((Object)(object)val == (Object)null && sharedLocal == 0L && allPlayerCharacters != null)
			{
				for (int i = 0; i < allPlayerCharacters.Count; i++)
				{
					if ((Object)(object)allPlayerCharacters[i] != (Object)null && ((NetworkBehaviour)allPlayerCharacters[i]).isLocalPlayer)
					{
						val = allPlayerCharacters[i];
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy || (Object)(object)val.rb == (Object)null || (((NetworkBehaviour)val).isLocalPlayer && val.rb.isKinematic))
			{
				SetChaseMusic(playing: false);
				return;
			}
			if (((NetworkBehaviour)val).isLocalPlayer && (!Application.isFocused || (val.menu != null && (val.menu.localHasMenuOpen || val.menu.localHasSteamOverlay))))
			{
				SetChaseMusic(playing: false);
				hunt.Tick(0f, canAttack: false);
				return;
			}
			Vector3 position = activeFigure.transform.position;
			Vector3 worldCenterOfMass = val.rb.worldCenterOfMass;
			Vector3 val2 = worldCenterOfMass - Vector3.up * 1.1f;
			Vector3 val3 = val2 - position;
			float magnitude = ((Vector3)(ref val3)).magnitude;
			Vector3 val4 = val3;
			val4.y = 0f;
			if (((Vector3)(ref val4)).sqrMagnitude > 0.0001f)
			{
				activeFigure.transform.rotation = Quaternion.LookRotation(((Vector3)(ref val4)).normalized, Vector3.up);
			}
			Vector3 val5 = worldCenterOfMass - (position + Vector3.up * 1.1f);
			bool flag = HuntRules.InAttackRange(((Vector3)(ref val5)).sqrMagnitude);
			if (hunt.Tick(Time.deltaTime, flag))
			{
				SharedCatch(val);
				return;
			}
			SetChaseMusic(hunt.Ready);
			if (!(!hunt.Ready || flag) && !(magnitude < 0.01f))
			{
				float num = 3f * Math.Min(Time.deltaTime, 0.05f);
				activeFigure.transform.position = Vector3.MoveTowards(position, val2, num);
			}
		}
		catch (Exception ex)
		{
			hunt = null;
			huntedFigure = null;
			EndActiveFigure();
			Plugin.LogSource.LogWarning((object)("Black One encounter safely ended: " + ex.Message));
		}
	}

	private unsafe bool ResolveWall()
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: 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)
		if (wallReady)
		{
			return true;
		}
		if (Time.time < nextWallSearch)
		{
			return false;
		}
		nextWallSearch = Time.time + 10f;
		foreach (GameObject item in FindAllGameObjectsSafe())
		{
			if ((Object)(object)item == (Object)null)
			{
				continue;
			}
			Scene scene = item.scene;
			if (!((Scene)(ref scene)).IsValid())
			{
				continue;
			}
			scene = item.scene;
			if (!((Scene)(ref scene)).isLoaded || ((Object)item).name != "EndingWall_Components")
			{
				continue;
			}
			Transform parent = item.transform.parent;
			if (!((Object)(object)parent == (Object)null) && !(((Object)parent).name != "GatePositioner"))
			{
				wallOrigin = parent.position;
				wallOutward = parent.forward;
				wallOutward.y = 0f;
				((Vector3)(ref wallOutward)).Normalize();
				if (Vector3.Dot(wallOutward, Vector3.forward) < 0f)
				{
					wallOutward = -wallOutward;
				}
				wallReady = true;
				ManualLogSource logSource = Plugin.LogSource;
				Vector3 val = wallOrigin;
				string? text = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString();
				val = wallOutward;
				logSource.LogInfo((object)("Ending wall anchor resolved at " + text + "; far-side normal " + ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString()));
				return true;
			}
		}
		return false;
	}

	private bool WhiteSideOfWall(Vector3 point)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		if (ResolveWall())
		{
			return Vector3.Dot(point - wallOrigin, wallOutward) < -8f;
		}
		return false;
	}

	private Material LandmarkMaterial(Color color)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Expected O, but got Unknown
		Shader val = Shader.Find("Universal Render Pipeline/Lit");
		Material val2 = null;
		if ((Object)(object)val != (Object)null && val.isSupported)
		{
			val2 = new Material(val);
		}
		if ((Object)(object)val2 == (Object)null)
		{
			List<PlayerCharacter> allPlayerCharacters = PlayerCharacter.allPlayerCharacters;
			if (allPlayerCharacters != null)
			{
				for (int i = 0; i < allPlayerCharacters.Count; i++)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						break;
					}
					PlayerCharacter val3 = allPlayerCharacters[i];
					if ((Object)(object)val3 == (Object)null || val3.registry == null || (Object)(object)val3.registry.corpsePrefab == (Object)null)
					{
						continue;
					}
					foreach (MeshRenderer componentsInChild in val3.registry.corpsePrefab.GetComponentsInChildren<MeshRenderer>(true))
					{
						foreach (Material item in (Il2CppArrayBase<Material>)(object)((Renderer)componentsInChild).sharedMaterials)
						{
							if ((Object)(object)item != (Object)null && (Object)(object)item.shader != (Object)null && ((Object)item.shader).name == "househouse/PlayerCharacter" && item.shader.isSupported)
							{
								val2 = new Material(item);
								break;
							}
						}
						if ((Object)(object)val2 != (Object)null)
						{
							break;
						}
					}
				}
			}
		}
		if ((Object)(object)val2 == (Object)null)
		{
			throw new InvalidOperationException("No supported landmark shader");
		}
		string[] array = new string[5]
		{
			"_Color",
			"_BaseColor",
			"_BaseColour",
			"_Color0",
			PlayerLooks.lookColorPropertyName
		};
		foreach (string text in array)
		{
			if (!string.IsNullOrEmpty(text) && val2.HasProperty(text))
			{
				val2.SetColor(text, color);
			}
		}
		if (val2.HasProperty("_Metallic"))
		{
			val2.SetFloat("_Metallic", 0.35f);
		}
		if (val2.HasProperty("_Smoothness"))
		{
			val2.SetFloat("_Smoothness", 0.38f);
		}
		if (val2.HasProperty("_Glossiness"))
		{
			val2.SetFloat("_Glossiness", 0.38f);
		}
		if (val2.HasProperty("_EmissionColor"))
		{
			val2.SetColor("_EmissionColor", Color.black);
		}
		val2.DisableKeyword("_EMISSION");
		array = new string[6] { "_Surface", "_Blend", "_AlphaClip", "_DstBlend", "_Rewardness", "_Speechlessness" };
		foreach (string text2 in array)
		{
			if (val2.HasProperty(text2))
			{
				val2.SetFloat(text2, 0f);
			}
		}
		array = new string[2] { "_ZWrite", "_SrcBlend" };
		foreach (string text3 in array)
		{
			if (val2.HasProperty(text3))
			{
				val2.SetFloat(text3, 1f);
			}
		}
		if (val2.HasProperty("_ZTest"))
		{
			val2.SetInt("_ZTest", 4);
		}
		if (val2.HasProperty("_BaseMap"))
		{
			val2.SetTexture("_BaseMap", (Texture)(object)Texture2D.whiteTexture);
		}
		val2.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
		val2.DisableKeyword("_ALPHATEST_ON");
		val2.DisableKeyword("_ALPHAPREMULTIPLY_ON");
		val2.renderQueue = 2000;
		val2.SetOverrideTag("RenderType", "Opaque");
		landmarkMaterials.Add(val2);
		return val2;
	}

	private void RegisterBeyond(GameObject part, Color color)
	{
		Renderer component = part.GetComponent<Renderer>();
		if (!((Object)(object)component == (Object)null))
		{
			component.enabled = false;
		}
	}

	private GameObject Shape(GameObject root, string name, Vector3 pos, Vector3 scale, Color color)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Part(root, name, (PrimitiveType)0, pos, scale, LandmarkMaterial(color));
		if ((Object)(object)root == (Object)(object)beyond)
		{
			RegisterBeyond(val, color);
		}
		return val;
	}

	private void Limb(GameObject root, string name, Vector3 a, Vector3 b, float width, Color color)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: 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_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_0070: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Part(root, name, (PrimitiveType)1, (a + b) * 0.5f, new Vector3(width, Vector3.Distance(a, b) * 0.5f, width), LandmarkMaterial(color));
		Transform transform = val.transform;
		Vector3 up = Vector3.up;
		Vector3 val2 = b - a;
		transform.localRotation = Quaternion.FromToRotation(up, ((Vector3)(ref val2)).normalized);
		if ((Object)(object)root == (Object)(object)beyond)
		{
			RegisterBeyond(val, color);
		}
	}

	private GameObject MeshPart(GameObject root, string name, Vector3 position, float scale, List<Vector3> verts, List<int> triangles, Color color)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Expected O, but got Unknown
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: 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)
		Mesh val = new Mesh();
		((Object)val).name = name;
		val.vertices = new Il2CppStructArray<Vector3>(verts.ToArray());
		val.triangles = new Il2CppStructArray<int>(triangles.ToArray());
		val.RecalculateNormals();
		val.RecalculateBounds();
		landmarkMeshes.Add(val);
		GameObject val2 = new GameObject(name);
		val2.transform.SetParent(root.transform, false);
		val2.transform.localPosition = position;
		val2.transform.localScale = Vector3.one * scale;
		val2.AddComponent<MeshFilter>().sharedMesh = val;
		MeshRenderer val3 = val2.AddComponent<MeshRenderer>();
		((Renderer)val3).sharedMaterial = LandmarkMaterial(color);
		((Renderer)val3).shadowCastingMode = (ShadowCastingMode)1;
		((Renderer)val3).receiveShadows = true;
		if ((Object)(object)root == (Object)(object)beyond)
		{
			beyondRenderers.Add((Renderer)(object)val3);
			RegisterBeyond(val2, color);
		}
		return val2;
	}

	private void BuildChristmasBell(GameObject root, Vector3 center, float size)
	{
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: 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_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: 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_02f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0304: 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_0313: Unknown result type (might be due to invalid IL or missing references)
		Color color = default(Color);
		((Color)(ref color))..ctor(0.58f, 0.012f, 0.018f, 1f);
		Color color2 = default(Color);
		((Color)(ref color2))..ctor(0.045f, 0.009f, 0.008f, 1f);
		Color color3 = default(Color);
		((Color)(ref color3))..ctor(0.48f, 0.25f, 0.06f, 1f);
		List<Vector3> list = new List<Vector3>();
		List<int> list2 = new List<int>();
		for (int i = 0; i <= 32; i++)
		{
			float num = (float)Math.PI * (float)i / 32f;
			for (int j = 0; j <= 64; j++)
			{
				float num2 = (float)Math.PI * 2f * (float)j / 64f;
				list.Add(new Vector3((float)Math.Sin(num) * (float)Math.Cos(num2), (float)Math.Cos(num), (float)Math.Sin(num) * (float)Math.Sin(num2)) * 0.5f);
			}
		}
		for (int k = 0; k < 32; k++)
		{
			for (int l = 0; l < 64; l++)
			{
				if (k < 17 || (l % 16 != 0 && l % 16 != 15))
				{
					int num3 = k * 65 + l;
					int num4 = num3 + 64 + 1;
					list2.Add(num3);
					list2.Add(num3 + 1);
					list2.Add(num4);
					list2.Add(num3 + 1);
					list2.Add(num4 + 1);
					list2.Add(num4);
				}
			}
		}
		MeshPart(root, "Red jingle bell shell", center + Vector3.up * (size * 0.52f), size, list, list2, color);
		Shape(root, "Dark hollow behind sound slots", center + Vector3.up * (size * 0.52f), Vector3.one * (size * 0.88f), color2);
		List<Vector3> list3 = new List<Vector3>();
		List<int> list4 = new List<int>();
		for (int m = 0; m <= 40; m++)
		{
			for (int n = 0; n <= 10; n++)
			{
				float num5 = (float)Math.PI * 2f * (float)m / 40f;
				float num6 = (float)Math.PI * 2f * (float)n / 10f;
				float num7 = 0.13f + 0.027f * (float)Math.Cos(num6);
				list3.Add(new Vector3(num7 * (float)Math.Cos(num5), num7 * (float)Math.Sin(num5), 0.027f * (float)Math.Sin(num6)));
			}
		}
		for (int num8 = 0; num8 < 40; num8++)
		{
			for (int num9 = 0; num9 < 10; num9++)
			{
				int num10 = num8 * 11 + num9;
				int num11 = num10 + 10 + 1;
				list4.Add(num10);
				list4.Add(num11);
				list4.Add(num10 + 1);
				list4.Add(num10 + 1);
				list4.Add(num11);
				list4.Add(num11 + 1);
			}
		}
		MeshPart(root, "Bell hanging loop", center + Vector3.up * (size * 1.1f), size, list3, list4, color3);
	}

	private void BuildBeyondModel()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: 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_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		//IL_028c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: 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_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0302: Unknown result type (might be due to invalid IL or missing references)
		//IL_0330: 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_0349: Unknown result type (might be due to invalid IL or missing references)
		//IL_036f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0387: Unknown result type (might be due to invalid IL or missing references)
		//IL_0391: Unknown result type (might be d