Decompiled source of ExtraChainedPuzzleCustomization v1.6.7

plugins/ScanPosOverride.dll

Decompiled 5 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using AIGraph;
using Agents;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using GTFO.API;
using GTFO.API.Extensions;
using GTFO.API.Utilities;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Text;
using LevelGeneration;
using Localization;
using MTFO.API;
using Microsoft.CodeAnalysis;
using Player;
using ScanPosOverride.Component;
using ScanPosOverride.JSON;
using ScanPosOverride.Managers;
using ScanPosOverride.PuzzleOverrideData;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ScanPosOverride")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ScanPosOverride")]
[assembly: AssemblyTitle("ScanPosOverride")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ScanPosOverride
{
	internal static class SPOLogger
	{
		private static readonly ManualLogSource logger = Logger.CreateLogSource("ScanPosOverride");

		public static void Log(string format, params object[] args)
		{
			Log(string.Format(format, args));
		}

		public static void Log(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)8, (object)str);
			}
		}

		public static void Warning(string format, params object[] args)
		{
			Warning(string.Format(format, args));
		}

		public static void Warning(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)4, (object)str);
			}
		}

		public static void Error(string format, params object[] args)
		{
			Error(string.Format(format, args));
		}

		public static void Error(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)2, (object)str);
			}
		}

		public static void Debug(string format, params object[] args)
		{
			Debug(string.Format(format, args));
		}

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)32, (object)str);
			}
		}

		public static void Log(BepInExDebugLogInterpolatedStringHandler logHandler)
		{
			logger.LogDebug(logHandler);
		}
	}
	[BepInPlugin("ScanPositionOverride", "ScanPositionOverride", "1.6.7")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class Plugin : BasePlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static LiveEditEventHandler <0>__LiveEdit_FileChanged;
		}

		private static Dictionary<uint, Dictionary<uint, PuzzleOverride>> PuzzleOverrides = new Dictionary<uint, Dictionary<uint, PuzzleOverride>>();

		public static readonly string OVERRIDE_SCAN_POS_PATH = Path.Combine(MTFOPathAPI.CustomPath, "ScanPositionOverrides");

		private static LiveEditListener listener = null;

		private static Harmony m_Harmony = null;

		public override void Load()
		{
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			SPOLogger.Error(OVERRIDE_SCAN_POS_PATH);
			if (!Directory.Exists(OVERRIDE_SCAN_POS_PATH))
			{
				Directory.CreateDirectory(OVERRIDE_SCAN_POS_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(OVERRIDE_SCAN_POS_PATH, "Template.json"));
				streamWriter.WriteLine(Json.Serialize(new PuzzleOverrideJsonFile()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			foreach (string item in Directory.EnumerateFiles(OVERRIDE_SCAN_POS_PATH, "*.json", SearchOption.AllDirectories))
			{
				Json.Load<PuzzleOverrideJsonFile>(item, out var config);
				if (PuzzleOverrides.ContainsKey(config.MainLevelLayout))
				{
					SPOLogger.Warning("Duplicate MainLevelLayout {0}, won't load.", config.MainLevelLayout);
					continue;
				}
				Dictionary<uint, PuzzleOverride> dictionary = new Dictionary<uint, PuzzleOverride>();
				foreach (PuzzleOverride puzzle in config.Puzzles)
				{
					if (dictionary.ContainsKey(puzzle.Index))
					{
						SPOLogger.Error("Duplicate Puzzle Override found. MainLevelLayout {0}, Index {1}.", config.MainLevelLayout, puzzle.Index);
						continue;
					}
					puzzle.EventsOnBioscanProgress.RemoveAll((BioscanProgressEvent e) => e.Progress <= 0f);
					puzzle.EventsOnBioscanProgress.Sort((BioscanProgressEvent e1, BioscanProgressEvent e2) => Mathf.RoundToInt(e1.Progress - e2.Progress));
					dictionary.Add(puzzle.Index, puzzle);
				}
				PuzzleOverrides.Add(config.MainLevelLayout, dictionary);
			}
			listener = LiveEdit.CreateListener(OVERRIDE_SCAN_POS_PATH, "*.json", true);
			LiveEditListener obj = listener;
			object obj2 = <>O.<0>__LiveEdit_FileChanged;
			if (obj2 == null)
			{
				LiveEditEventHandler val = LiveEdit_FileChanged;
				<>O.<0>__LiveEdit_FileChanged = val;
				obj2 = (object)val;
			}
			obj.FileChanged += (LiveEditEventHandler)obj2;
			m_Harmony = new Harmony("ScanPosOverride.Patches");
			m_Harmony.PatchAll();
		}

		private static void LiveEdit_FileChanged(LiveEditEventArgs e)
		{
			SPOLogger.Warning("LiveEdit File Changed: " + e.FullPath + ".");
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				PuzzleOverrideJsonFile puzzleOverrideJsonFile = Json.Deserialize<PuzzleOverrideJsonFile>(content);
				if (!PuzzleOverrides.ContainsKey(puzzleOverrideJsonFile.MainLevelLayout))
				{
					SPOLogger.Warning("MainLevelLayout not found, which is now not supported. Will not replace.");
				}
				else
				{
					Dictionary<uint, PuzzleOverride> dictionary = PuzzleOverrides[puzzleOverrideJsonFile.MainLevelLayout];
					dictionary.Clear();
					foreach (PuzzleOverride puzzle in puzzleOverrideJsonFile.Puzzles)
					{
						if (dictionary.ContainsKey(puzzle.Index))
						{
							SPOLogger.Error("Duplicate Puzzle Override found. MainLevelLayout {0}, Index {1}.", puzzleOverrideJsonFile.MainLevelLayout, puzzle.Index);
						}
						else
						{
							puzzle.EventsOnBioscanProgress.Sort((BioscanProgressEvent e1, BioscanProgressEvent e2) => Mathf.RoundToInt(e1.Progress - e2.Progress));
							dictionary.Add(puzzle.Index, puzzle);
						}
					}
					SPOLogger.Warning("Replaced Override Puzzle with MainLevelLayout {0}", puzzleOverrideJsonFile.MainLevelLayout);
				}
			});
		}

		internal static PuzzleOverride GetOverride(uint mainLevelLayout, uint puzzleIndex)
		{
			if (!PuzzleOverrides.ContainsKey(mainLevelLayout))
			{
				return null;
			}
			Dictionary<uint, PuzzleOverride> dictionary = PuzzleOverrides[mainLevelLayout];
			if (!dictionary.ContainsKey(puzzleIndex))
			{
				return null;
			}
			return dictionary[puzzleIndex];
		}
	}
	public static class Utils
	{
	}
}
namespace ScanPosOverride.PuzzleOverrideData
{
	internal sealed class PuzzleOverrideJsonFile
	{
		public uint MainLevelLayout { get; set; }

		public List<PuzzleOverride> Puzzles { get; set; } = new List<PuzzleOverride>
		{
			new PuzzleOverride()
		};

	}
	public class BioscanProgressEvent
	{
		public float Progress { get; set; } = -1f;


		public List<WardenObjectiveEventData> Events { get; set; } = new List<WardenObjectiveEventData>();

	}
	public class ClusterProgressEvent
	{
		public int Count { get; set; } = -1;


		public List<WardenObjectiveEventData> Events { get; set; } = new List<WardenObjectiveEventData>();

	}
	public class PuzzleOverride
	{
		public uint Index { get; set; }

		public Vec3 Position { get; set; } = new Vec3();


		public Vec3 Rotation { get; set; } = new Vec3();


		public bool HideSpline { get; set; }

		public Vec3 PrevPosOverride { get; set; } = new Vec3();


		public uint PrevPosOverrideIndex { get; set; }

		public bool ConcurrentCluster { get; set; }

		public float TMoveSpeedMulti { get; set; } = -1f;


		public List<BioscanProgressEvent> EventsOnBioscanProgress { get; set; } = new List<BioscanProgressEvent>
		{
			new BioscanProgressEvent()
		};


		public List<ClusterProgressEvent> EventsOnClusterProgress { get; set; } = new List<ClusterProgressEvent>
		{
			new ClusterProgressEvent()
		};


		public List<Vec3> TPositions { get; set; } = new List<Vec3>
		{
			new Vec3()
		};


		public List<int> RequiredItemsIndices { get; set; } = new List<int> { 0 };


		public List<WardenObjectiveEventData> EventsOnPuzzleSolved { get; set; } = new List<WardenObjectiveEventData>();

	}
	public class Vec3
	{
		public float x { get; set; }

		public float y { get; set; }

		public float z { get; set; }

		public Vector3 ToVector3()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(x, y, z);
		}

		public Quaternion ToQuaternion()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.Euler(x, y, z);
		}
	}
}
namespace ScanPosOverride.Patches
{
	[HarmonyPatch]
	internal static class Patch_CP_BasicMovable_TryGetNextIndex
	{
	}
	[HarmonyPatch]
	internal static class Patch_CP_Bioscan_Core_OnSyncStateChange
	{
		private static Dictionary<IntPtr, int> EOPIndex;

		static Patch_CP_Bioscan_Core_OnSyncStateChange()
		{
			EOPIndex = new Dictionary<IntPtr, int>();
			LevelAPI.OnBuildStart += EOPIndex.Clear;
			LevelAPI.OnLevelCleanup += EOPIndex.Clear;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Bioscan_Core), "OnSyncStateChange")]
		private static void Post_OnSyncStateChanged_CheckEOPAndEventsOnPuzzleSolved(CP_Bioscan_Core __instance, float progress, eBioscanStatus status, List<PlayerAgent> playersInScan, bool isDropinState)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Invalid comparison between Unknown and I4
			uint bioscanCoreOverrideIndex = PuzzleOverrideManager.Current.GetBioscanCoreOverrideIndex(__instance);
			PuzzleOverride def = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, bioscanCoreOverrideIndex);
			if (def != null)
			{
				if (def.EventsOnBioscanProgress.Count > 0)
				{
					CheckBioscanEventsOnProgress();
				}
				if ((int)status == 4 && !isDropinState && def.EventsOnPuzzleSolved.Count > 0)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(def.EventsOnPuzzleSolved), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				}
			}
			void CheckBioscanEventsOnProgress()
			{
				if (!EOPIndex.ContainsKey(((Il2CppObjectBase)__instance).Pointer))
				{
					EOPIndex[((Il2CppObjectBase)__instance).Pointer] = 0;
				}
				int i = EOPIndex[((Il2CppObjectBase)__instance).Pointer];
				if (isDropinState)
				{
					for (; i < def.EventsOnBioscanProgress.Count && !(def.EventsOnBioscanProgress[i].Progress > progress); i++)
					{
					}
				}
				else if (i < def.EventsOnBioscanProgress.Count && def.EventsOnBioscanProgress[i].Progress < progress)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(def.EventsOnBioscanProgress[i].Events), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
					EOPIndex[((Il2CppObjectBase)__instance).Pointer] = i + 1;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Bioscan_Core), "OnSyncStateChange")]
		private static void Post_OnSyncStateChanged_CheckReqItemAndConcurrentCluster(CP_Bioscan_Core __instance, float progress, eBioscanStatus status, List<PlayerAgent> playersInScan, bool isDropinState)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_0129: 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_014c: Invalid comparison between Unknown and I4
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Invalid comparison between Unknown and I4
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Invalid comparison between Unknown and I4
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			bool flag = PlayerScannerManager.Current.IsConcurrentCluster(__instance);
			if (flag && __instance.m_reqItemsEnabled)
			{
				SPOLogger.Warning($"OnSyncStateChange: status - {status}, playersInScan - {playersInScan.Count}, progress: {progress}");
			}
			if ((int)status != 3)
			{
				if (flag)
				{
					if ((int)status == 4)
					{
						CP_Cluster_Core val = ((Il2CppObjectBase)__instance.Owner).TryCast<CP_Cluster_Core>();
						if ((Object)(object)val == (Object)null)
						{
							SPOLogger.Error("Cannot find parent cluster core! The concurrent cluster may fail!");
						}
						else
						{
							PlayerScannerManager.Current.CompleteConcurrentCluster(val, __instance);
						}
					}
					else
					{
						PlayerScannerManager.Current.CCShouldProgress(__instance, IsThisScanShouldProgress: false);
					}
				}
				if (__instance.m_reqItemsEnabled)
				{
					__instance.m_graphics.SetColorMode((eChainedPuzzleGraphicsColorMode)((!__instance.m_hasAlarm) ? 1 : 4));
				}
			}
			else
			{
				if (!__instance.IsMovable && !flag && !__instance.m_reqItemsEnabled)
				{
					return;
				}
				CP_PlayerScanner cacheScanner = PlayerScannerManager.Current.GetCacheScanner(__instance);
				if ((Object)(object)cacheScanner == (Object)null)
				{
					return;
				}
				int count = playersInScan.Count;
				List<PlayerAgent> playerAgentsInLevel = PlayerManager.PlayerAgentsInLevel;
				float num = 0f;
				float[] cacheOriginalScanSpeed = PlayerScannerManager.Current.GetCacheOriginalScanSpeed(__instance);
				if ((int)__instance.m_playerScanner.ScanPlayersRequired == 0)
				{
					num = ((count <= 0) ? 0f : cacheOriginalScanSpeed[count - 1]);
				}
				else if (((int)cacheScanner.m_playerRequirement == 1 && count == playerAgentsInLevel.Count) || ((int)cacheScanner.m_playerRequirement == 2 && count == 1))
				{
					num = cacheOriginalScanSpeed[0];
				}
				bool flag2 = num > 0f;
				if (flag2 && cacheScanner.m_reqItemsEnabled)
				{
					for (int i = 0; i < ((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems).Length; i++)
					{
						Vector3 val2 = Vector3.zero;
						if ((int)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickupItemStatus == 0)
						{
							val2 = ((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].transform.position;
						}
						else if ((int)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickupItemStatus == 1)
						{
							if ((Object)(object)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickedUpByPlayer != (Object)null)
							{
								val2 = ((Agent)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickedUpByPlayer).Position;
							}
							else
							{
								Debug.LogError(Object.op_Implicit("Playerscanner is looking for an item that has ePickupItemStatus.PickedUp but null player, how come!?"));
							}
						}
						Vector3 val3 = ((Component)cacheScanner).transform.position - val2;
						if (((Vector3)(ref val3)).sqrMagnitude >= cacheScanner.m_scanRadiusSqr)
						{
							flag2 = false;
							break;
						}
					}
				}
				if (flag)
				{
					if (flag2)
					{
						flag2 = PlayerScannerManager.Current.CCShouldProgress(__instance, IsThisScanShouldProgress: true);
					}
					else
					{
						PlayerScannerManager.Current.CCShouldProgress(__instance, IsThisScanShouldProgress: false);
					}
				}
				if (flag2)
				{
					if (flag)
					{
						CP_Cluster_Core parent = ((Il2CppObjectBase)__instance.Owner).Cast<CP_Cluster_Core>();
						PlayerScannerManager.Current.RestoreCCScanSpeed(parent);
					}
					if (__instance.IsMovable)
					{
						__instance.m_movingComp.ResumeMovement();
					}
					if (cacheScanner.m_reqItemsEnabled)
					{
						if ((int)cacheScanner.m_playerRequirement == 0)
						{
							((Il2CppArrayBase<float>)(object)cacheScanner.m_scanSpeeds)[0] = ((count > 0) ? cacheOriginalScanSpeed[count - 1] : 0f);
						}
						__instance.m_graphics.SetColorMode((eChainedPuzzleGraphicsColorMode)(__instance.m_hasAlarm ? 5 : 2));
					}
					return;
				}
				if (flag)
				{
					CP_Cluster_Core parent2 = ((Il2CppObjectBase)__instance.Owner).Cast<CP_Cluster_Core>();
					PlayerScannerManager.Current.ZeroCCScanSpeed(parent2);
				}
				if (__instance.IsMovable)
				{
					__instance.m_movingComp.PauseMovement();
				}
				if (cacheScanner.m_reqItemsEnabled)
				{
					if ((int)cacheScanner.m_playerRequirement == 0)
					{
						PlayerScannerManager.Current.GetCacheOriginalScanSpeed(__instance);
						((Il2CppArrayBase<float>)(object)cacheScanner.m_scanSpeeds)[0] = 0f;
					}
					__instance.m_graphics.SetColorMode((eChainedPuzzleGraphicsColorMode)((!__instance.m_hasAlarm) ? 1 : 4));
				}
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_CP_Bioscan_Core_Setup
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")]
		private static void Pre_CP_Bioscan_Core_Setup(CP_Bioscan_Core __instance, int puzzleIndex, iChainedPuzzleOwner owner, ref Vector3 prevPuzzlePos, ref bool revealWithHoloPath, ref bool onlyShowHUDWhenPlayerIsClose)
		{
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: 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_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: 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_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: 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_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			ChainedPuzzleInstance val = ((Il2CppObjectBase)owner).TryCast<ChainedPuzzleInstance>();
			uint num = PuzzleOverrideManager.Current.Register(__instance);
			PuzzleOverride @override = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, num);
			if ((Object)(object)val != (Object)null)
			{
				bool flag = false;
				if (@override != null)
				{
					if (@override.PrevPosOverride.ToVector3() != Vector3.zero)
					{
						prevPuzzlePos = @override.PrevPosOverride.ToVector3();
						flag = true;
					}
					else if (@override.PrevPosOverrideIndex != 0)
					{
						CP_Bioscan_Core bioscanCore = PuzzleOverrideManager.Current.GetBioscanCore(@override.PrevPosOverrideIndex);
						? val2;
						if (bioscanCore == null)
						{
							CP_Cluster_Core clusterCore = PuzzleOverrideManager.Current.GetClusterCore(@override.PrevPosOverrideIndex);
							val2 = ((clusterCore != null) ? ((Component)clusterCore).transform.position : Vector3.zero);
						}
						else
						{
							val2 = bioscanCore.m_position;
						}
						Vector3 val3 = (Vector3)val2;
						if (val3 == Vector3.zero)
						{
							SPOLogger.Error($"PuzzleOverrideIndex: {num} - trying to use 'PrevPosOverrideIndex' ({@override.PrevPosOverrideIndex}) but the puzzle is not found.");
							SPOLogger.Error($"The puzzle is probably yet registered. NOTE: 'PrevPosOverrideIndex' could only be a integer that is less than PuzzleOverrideIndex({num})");
							flag = false;
						}
						else
						{
							prevPuzzlePos = val3;
							flag = true;
						}
					}
				}
				if (!flag && puzzleIndex != 0)
				{
					CP_Bioscan_Core val4 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Bioscan_Core>();
					if ((Object)(object)val4 != (Object)null)
					{
						prevPuzzlePos = ((Component)val4).transform.position;
					}
					else
					{
						CP_Cluster_Core val5 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Cluster_Core>();
						if ((Object)(object)val5 == (Object)null)
						{
							SPOLogger.Error($"Cannot cast m_chainedPuzzleCores[{puzzleIndex - 1}] to neither CP_Bioscan_Core or CP_Cluster_Core! WTF???");
						}
						else
						{
							prevPuzzlePos = ((Component)val5).transform.position;
						}
					}
				}
			}
			else
			{
				CP_Cluster_Core val6 = ((Il2CppObjectBase)owner).Cast<CP_Cluster_Core>();
				if (@override != null && @override.PrevPosOverride.ToVector3() != Vector3.zero)
				{
					prevPuzzlePos = @override.PrevPosOverride.ToVector3();
				}
				else if (@override != null && @override.PrevPosOverrideIndex != 0)
				{
					CP_Bioscan_Core bioscanCore2 = PuzzleOverrideManager.Current.GetBioscanCore(@override.PrevPosOverrideIndex);
					? val7;
					if (bioscanCore2 == null)
					{
						CP_Cluster_Core clusterCore2 = PuzzleOverrideManager.Current.GetClusterCore(@override.PrevPosOverrideIndex);
						val7 = ((clusterCore2 != null) ? ((Component)clusterCore2).transform.position : Vector3.zero);
					}
					else
					{
						val7 = bioscanCore2.m_position;
					}
					Vector3 val8 = (Vector3)val7;
					if (val8 == Vector3.zero)
					{
						SPOLogger.Error($"PuzzleOverrideIndex: {num} - trying to use 'PrevPosOverrideIndex' ({@override.PrevPosOverrideIndex}) but the puzzle is not found.");
						SPOLogger.Error($"The puzzle is probably yet registered. NOTE: 'PrevPosOverrideIndex' could only be a integer that is less than PuzzleOverrideIndex({num})");
						prevPuzzlePos = ((Component)val6).transform.position;
					}
					else
					{
						prevPuzzlePos = val8;
					}
				}
				else
				{
					prevPuzzlePos = ((Component)val6).transform.position;
				}
				val = ((Il2CppObjectBase)val6.m_owner).Cast<ChainedPuzzleInstance>();
				if (val.Data.OnlyShowHUDWhenPlayerIsClose)
				{
					onlyShowHUDWhenPlayerIsClose = true;
				}
			}
			if (@override != null)
			{
				if (@override.Position.ToVector3() != Vector3.zero || @override.Rotation.ToVector3() != Vector3.zero)
				{
					((Component)__instance).transform.SetPositionAndRotation(@override.Position.ToVector3(), @override.Rotation.ToQuaternion());
				}
				if (@override.HideSpline || ((Object)(object)__instance.m_movingComp != (Object)null && __instance.m_movingComp.IsMoveConfigured))
				{
					revealWithHoloPath = false;
				}
				if (@override.RequiredItemsIndices != null && @override.RequiredItemsIndices.Count > 0)
				{
					PuzzleReqItemManager.Current.QueueForAddingReqItems(__instance, @override.RequiredItemsIndices);
				}
				SPOLogger.Warning("Overriding CP_Bioscan_Core." + (((Object)(object)val == (Object)null) ? "" : $"Zone {val.m_sourceArea.m_zone.Alias}, Layer {val.m_sourceArea.m_zone.Layer.m_type}, Dim {val.m_sourceArea.m_zone.DimensionIndex}"));
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_ChainedPuzzleInstance_SetupMovement
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ChainedPuzzleInstance), "SetupMovement")]
		private static bool Pre_SetupMovement(ChainedPuzzleInstance __instance, GameObject gameObject)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			iChainedPuzzleMovable movingComp = gameObject.GetComponent<iChainedPuzzleMovable>();
			if (movingComp == null || !movingComp.UsingStaticBioscanPoints)
			{
				return true;
			}
			CP_BasicMovable val = ((Il2CppObjectBase)movingComp).Cast<CP_BasicMovable>();
			CP_Bioscan_Core core = ((Il2CppObjectBase)gameObject.GetComponent<iChainedPuzzleCore>()).Cast<CP_Bioscan_Core>();
			uint bioscanCoreOverrideIndex = PuzzleOverrideManager.Current.GetBioscanCoreOverrideIndex(core);
			if (bioscanCoreOverrideIndex == 0)
			{
				SPOLogger.Error("Did not find registered movable override for this movable scan.");
				return true;
			}
			PuzzleOverride @override = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, bioscanCoreOverrideIndex);
			if (@override == null || @override.TPositions.Count < 1)
			{
				SPOLogger.Error("No Override for this T-Scan, falling back to vanilla impl.");
				return true;
			}
			@override.TPositions.ForEach(delegate(Vec3 pos)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				movingComp.ScanPositions.Add(pos.ToVector3());
			});
			gameObject.transform.position = @override.TPositions[0].ToVector3();
			val.m_amountOfPositions = @override.TPositions.Count;
			if (@override.TMoveSpeedMulti > 0f)
			{
				val.m_movementSpeed *= @override.TMoveSpeedMulti;
			}
			SPOLogger.Warning("Overriding T-Scan pos!");
			return false;
		}
	}
	[HarmonyPatch]
	internal class Patch_CarryItemPickup_Core_Setup
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CarryItemPickup_Core), "Setup")]
		private static void Post_CarryItemPickup_Core_Setup(CarryItemPickup_Core __instance)
		{
			PuzzleReqItemManager.Current.Register(__instance);
		}
	}
	[HarmonyPatch]
	internal static class Patch_CP_Cluster_Core_OnSyncStateChange
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Cluster_Core), "OnSyncStateChange")]
		private static void Post_CheckEventsOnPuzzleSolved(CP_Cluster_Core __instance, eClusterStatus newStatus, bool isDropinState)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)newStatus == 3)
			{
				uint clusterCoreOverrideIndex = PuzzleOverrideManager.Current.GetClusterCoreOverrideIndex(__instance);
				PuzzleOverride @override = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, clusterCoreOverrideIndex);
				if (@override != null && @override.EventsOnPuzzleSolved.Count > 0 && !isDropinState)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(@override.EventsOnPuzzleSolved), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				}
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_CP_Cluster_Core_Setup
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(CP_Cluster_Core), "Setup")]
		private static void Pre_CP_Cluster_Core_Setup(CP_Cluster_Core __instance, int puzzleIndex, iChainedPuzzleOwner owner, ref Vector3 prevPuzzlePos, ref bool revealWithHoloPath)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			uint num = PuzzleOverrideManager.Current.Register(__instance);
			PuzzleOverride @override = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, num);
			ChainedPuzzleInstance val = ((Il2CppObjectBase)owner).Cast<ChainedPuzzleInstance>();
			bool flag = false;
			if (@override != null)
			{
				if (@override.PrevPosOverride.ToVector3() != Vector3.zero)
				{
					prevPuzzlePos = @override.PrevPosOverride.ToVector3();
					flag = true;
				}
				else if (@override.PrevPosOverrideIndex != 0)
				{
					CP_Bioscan_Core bioscanCore = PuzzleOverrideManager.Current.GetBioscanCore(@override.PrevPosOverrideIndex);
					? val2;
					if (bioscanCore == null)
					{
						CP_Cluster_Core clusterCore = PuzzleOverrideManager.Current.GetClusterCore(@override.PrevPosOverrideIndex);
						val2 = ((clusterCore != null) ? ((Component)clusterCore).transform.position : Vector3.zero);
					}
					else
					{
						val2 = bioscanCore.m_position;
					}
					Vector3 val3 = (Vector3)val2;
					if (val3 == Vector3.zero)
					{
						SPOLogger.Error($"PuzzleOverrideIndex: {num} - trying to use 'PrevPosOverrideIndex' ({@override.PrevPosOverrideIndex}) but the puzzle is not found.");
						SPOLogger.Error($"The puzzle is probably yet registered. NOTE: 'PrevPosOverrideIndex' could only be a integer that is less than PuzzleOverrideIndex({num})");
						flag = false;
					}
					else
					{
						prevPuzzlePos = val3;
						flag = true;
					}
				}
			}
			if (!flag && puzzleIndex != 0)
			{
				CP_Bioscan_Core val4 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Bioscan_Core>();
				if ((Object)(object)val4 != (Object)null)
				{
					prevPuzzlePos = ((Component)val4).transform.position;
				}
				else
				{
					CP_Cluster_Core val5 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Cluster_Core>();
					if ((Object)(object)val5 == (Object)null)
					{
						SPOLogger.Error($"Cannot cast m_chainedPuzzleCores[{puzzleIndex - 1}] to neither CP_Bioscan_Core or CP_Cluster_Core! WTF???");
					}
					else
					{
						prevPuzzlePos = ((Component)val5).transform.position;
					}
				}
			}
			if (@override != null)
			{
				if (@override.Position.ToVector3() != Vector3.zero || @override.Rotation.ToVector3() != Vector3.zero)
				{
					((Component)__instance).transform.SetPositionAndRotation(@override.Position.ToVector3(), @override.Rotation.ToQuaternion());
				}
				if (@override.RequiredItemsIndices != null && @override.RequiredItemsIndices.Count > 0)
				{
					PuzzleReqItemManager.Current.QueueForAddingReqItems(__instance, @override.RequiredItemsIndices);
				}
				if (@override.HideSpline)
				{
					revealWithHoloPath = false;
				}
				SPOLogger.Warning("Overriding CP_Cluster_Core!");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Cluster_Core), "Setup")]
		private static void Post_CP_Cluster_Core_Setup(CP_Cluster_Core __instance)
		{
			ChainedPuzzleInstance val = ((Il2CppObjectBase)__instance.m_owner).Cast<ChainedPuzzleInstance>();
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores)
			{
				if (item.IsMovable && PuzzleOverrideManager.Current.GetBioscanCoreOverrideIndex(((Il2CppObjectBase)item).Pointer) != 0)
				{
					val.SetupMovement(((Component)((Il2CppObjectBase)item).Cast<CP_Bioscan_Core>()).gameObject, val.m_sourceArea);
				}
			}
			uint clusterCoreOverrideIndex = PuzzleOverrideManager.Current.GetClusterCoreOverrideIndex(__instance);
			if (clusterCoreOverrideIndex == 0)
			{
				return;
			}
			PuzzleOverride def = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, clusterCoreOverrideIndex);
			if (def == null)
			{
				return;
			}
			if (def.ConcurrentCluster)
			{
				if (2 <= ((Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores).Count && ((Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores).Count <= 4)
				{
					CP_Cluster_Hud val2 = ((Il2CppObjectBase)__instance.m_hud).Cast<CP_Cluster_Hud>();
					ConcurrentClusterHud concurrentClusterHud = ((Component)val2).gameObject.AddComponent<ConcurrentClusterHud>();
					concurrentClusterHud.parent = __instance;
					concurrentClusterHud.parentHud = ((Il2CppObjectBase)val2.m_hud).Cast<CP_Bioscan_Hud>();
					concurrentClusterHud.def = def;
					if (concurrentClusterHud.Setup())
					{
						PlayerScannerManager.Current.RegisterConcurrentCluster(__instance);
						SPOLogger.Warning("Setting up CP_Cluster_Core as Concurrent Cluster!");
					}
					else
					{
						SPOLogger.Warning("Concurrent Cluster: failed to setup");
					}
				}
				else
				{
					SPOLogger.Error("Trying to setup concurrent cluster, " + $"but the cluster scan has {((Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores).Count}, which is senseless or is impossible for 4 players to complete");
				}
			}
			if (def.EventsOnClusterProgress.Count <= 0)
			{
				return;
			}
			foreach (iChainedPuzzleCore item2 in (Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores)
			{
				item2.OnPuzzleDone += Action<int>.op_Implicit((Action<int>)CheckEventsOnClusterProgress);
			}
			void CheckEventsOnClusterProgress(int puzzleIndex)
			{
				int num = 0;
				for (int i = 0; i < ((Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores).Length; i++)
				{
					if (((Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores)[i].IsFinished())
					{
						num++;
					}
				}
				foreach (ClusterProgressEvent item3 in def.EventsOnClusterProgress)
				{
					if (item3.Count == num)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(item3.Events), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
					}
				}
			}
		}
	}
	[HarmonyPatch]
	internal class Patches_CP_Cluster_Hud_ReqItems
	{
		private static Dictionary<IntPtr, List<bool>> childrenReqItemEnabled { get; }

		private static Dictionary<IntPtr, List<string[]>> clustersChildrenReqItemNames { get; }

		private static Dictionary<IntPtr, List<Il2CppStructArray<bool>>> clustersChildrenReqItemsStatus { get; }

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Bioscan_Core), "AddRequiredItems")]
		private static void Post_CP_Bioscan_Core_AddRequiredItems(CP_Bioscan_Core __instance, Il2CppReferenceArray<iWardenObjectiveItem> requiredItems)
		{
			CP_Cluster_Core val = ((Il2CppObjectBase)__instance.Owner).TryCast<CP_Cluster_Core>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (__instance.m_hud == null)
			{
				SPOLogger.Error("CP_Cluster_Hud_ReqItems: replacement Cluster_hud is null.");
				return;
			}
			CP_Cluster_Hud val2 = ((Il2CppObjectBase)__instance.m_hud).Cast<CP_Cluster_Hud>();
			string[] array = new string[((Il2CppArrayBase<iWardenObjectiveItem>)(object)requiredItems).Count];
			for (int i = 0; i < __instance.m_reqItems.Count; i++)
			{
				if (__instance.m_reqItems[i] != null)
				{
					array[i] = __instance.m_reqItems[i].PublicName;
				}
				else
				{
					SPOLogger.Error("Post_CP_Bioscan_Core_AddRequiredItems: CP_Bioscan_Core " + ((Object)__instance).name + " has a missing m_reqItem! " + i);
				}
			}
			List<bool> list;
			List<string[]> list2;
			if (childrenReqItemEnabled.ContainsKey(((Il2CppObjectBase)val2).Pointer))
			{
				list = childrenReqItemEnabled[((Il2CppObjectBase)val2).Pointer];
				list2 = clustersChildrenReqItemNames[((Il2CppObjectBase)val2).Pointer];
			}
			else
			{
				list = Enumerable.Repeat(element: false, val.NRofPuzzles()).ToList();
				list2 = Enumerable.Repeat(new string[0], val.NRofPuzzles()).ToList();
				childrenReqItemEnabled.Add(((Il2CppObjectBase)val2).Pointer, list);
				clustersChildrenReqItemNames.Add(((Il2CppObjectBase)val2).Pointer, list2);
			}
			list[__instance.m_puzzleIndex] = __instance.m_reqItemsEnabled;
			list2[__instance.m_puzzleIndex] = array;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CP_Cluster_Hud), "SetRequiredItemData")]
		private static bool Pre_CP_Cluster_Hud_SetRequiredItemData(CP_Cluster_Hud __instance, int puzzleIndex, Il2CppStructArray<bool> reqItemStatus)
		{
			List<Il2CppStructArray<bool>> list;
			if (!clustersChildrenReqItemsStatus.ContainsKey(((Il2CppObjectBase)__instance).Pointer))
			{
				list = Enumerable.Repeat<Il2CppStructArray<bool>>(null, __instance.m_clusterSize).ToList();
				clustersChildrenReqItemsStatus.Add(((Il2CppObjectBase)__instance).Pointer, list);
			}
			else
			{
				list = clustersChildrenReqItemsStatus[((Il2CppObjectBase)__instance).Pointer];
			}
			list[puzzleIndex] = reqItemStatus;
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Cluster_Hud), "UpdateDataFor")]
		private static void Post_CP_Cluster_Hud_UpdateDataFor(CP_Cluster_Hud __instance, int index)
		{
			if (clustersChildrenReqItemsStatus.ContainsKey(((Il2CppObjectBase)__instance).Pointer))
			{
				if (!childrenReqItemEnabled.ContainsKey(((Il2CppObjectBase)__instance).Pointer) || !clustersChildrenReqItemNames.ContainsKey(((Il2CppObjectBase)__instance).Pointer))
				{
					SPOLogger.Error("CP_Cluster_Hud_UpdateDataFor: Found registered reqItemStatus but ReqItemEnabled or ReqItemNames is missing!");
					return;
				}
				Il2CppStructArray<bool> val = clustersChildrenReqItemsStatus[((Il2CppObjectBase)__instance).Pointer][index];
				__instance.m_hud.SetupRequiredItems(childrenReqItemEnabled[((Il2CppObjectBase)__instance).Pointer][index], Il2CppStringArray.op_Implicit(clustersChildrenReqItemNames[((Il2CppObjectBase)__instance).Pointer][index]));
				__instance.m_hud.SetRequiredItemData(__instance.m_puzzleIndex, val);
			}
		}

		private static void Clear()
		{
			clustersChildrenReqItemsStatus.Clear();
			clustersChildrenReqItemNames.Clear();
			childrenReqItemEnabled.Clear();
		}

		static Patches_CP_Cluster_Hud_ReqItems()
		{
			childrenReqItemEnabled = new Dictionary<IntPtr, List<bool>>();
			clustersChildrenReqItemNames = new Dictionary<IntPtr, List<string[]>>();
			clustersChildrenReqItemsStatus = new Dictionary<IntPtr, List<Il2CppStructArray<bool>>>();
			LevelAPI.OnLevelCleanup += Clear;
		}
	}
}
namespace ScanPosOverride.Managers
{
	public class PlayerScannerManager
	{
		private static readonly float[] ZERO_SCAN_SPEED;

		private Mutex CCStateMutex;

		private Dictionary<IntPtr, CP_PlayerScanner> ChildScanners = new Dictionary<IntPtr, CP_PlayerScanner>();

		public static PlayerScannerManager Current { get; }

		private Dictionary<IntPtr, List<CP_PlayerScanner>> CCCores { get; } = new Dictionary<IntPtr, List<CP_PlayerScanner>>();


		private Dictionary<IntPtr, HashSet<IntPtr>> CCChildren { get; } = new Dictionary<IntPtr, HashSet<IntPtr>>();


		private Dictionary<IntPtr, HashSet<IntPtr>> CCChildrenState { get; } = new Dictionary<IntPtr, HashSet<IntPtr>>();


		private Dictionary<IntPtr, float[]> OriginalClusterScanSpeeds { get; } = new Dictionary<IntPtr, float[]>();


		private Dictionary<IntPtr, float[]> OriginalScanSpeed { get; } = new Dictionary<IntPtr, float[]>();


		internal bool RegisterConcurrentCluster(CP_Cluster_Core core)
		{
			if (CCCores.ContainsKey(((Il2CppObjectBase)core).Pointer))
			{
				return false;
			}
			List<CP_PlayerScanner> list = Enumerable.Repeat<CP_PlayerScanner>(null, core.m_amountOfPuzzles).ToList();
			HashSet<IntPtr> hashSet = new HashSet<IntPtr>();
			for (int i = 0; i < ((Il2CppArrayBase<iChainedPuzzleCore>)(object)core.m_childCores).Count; i++)
			{
				if ((Object)(object)list[i] != (Object)null)
				{
					SPOLogger.Error("SetupConcurrentClusterScanners: Duplicate child scanner for child scan. ??");
					continue;
				}
				iChainedPuzzleCore val = ((Il2CppArrayBase<iChainedPuzzleCore>)(object)core.m_childCores)[i];
				CP_Bioscan_Core val2 = ((Il2CppObjectBase)val).TryCast<CP_Bioscan_Core>();
				if ((Object)(object)val2 == (Object)null)
				{
					SPOLogger.Error("SetupConcurrentClusterScanners: Failed to cast child to CP_Bioscan_Core");
					continue;
				}
				CP_PlayerScanner val3 = ((Il2CppObjectBase)val2.PlayerScanner).TryCast<CP_PlayerScanner>();
				if ((Object)(object)val3 == (Object)null)
				{
					SPOLogger.Error("SetupConcurrentClusterScanners: Failed to cast CP_Bioscan_Core.PlayerScanner to CP_PlayerScanner");
					continue;
				}
				list[i] = val3;
				ChildScanners.Add(((Il2CppObjectBase)val).Pointer, val3);
				hashSet.Add(((Il2CppObjectBase)val2).Pointer);
				if (!OriginalClusterScanSpeeds.ContainsKey(((Il2CppObjectBase)core).Pointer))
				{
					Il2CppStructArray<float> scanSpeeds = val3.m_scanSpeeds;
					float[] array = new float[((Il2CppArrayBase<float>)(object)scanSpeeds).Length];
					Array.Copy(Il2CppArrayBase<float>.op_Implicit((Il2CppArrayBase<float>)(object)scanSpeeds), array, ((Il2CppArrayBase<float>)(object)scanSpeeds).Length);
					OriginalClusterScanSpeeds.Add(((Il2CppObjectBase)core).Pointer, array);
				}
			}
			CCCores.Add(((Il2CppObjectBase)core).Pointer, list);
			CCChildren.Add(((Il2CppObjectBase)core).Pointer, hashSet);
			CCChildrenState.Add(((Il2CppObjectBase)core).Pointer, new HashSet<IntPtr>());
			return true;
		}

		internal bool IsConcurrentCluster(CP_Cluster_Core core)
		{
			return CCCores.ContainsKey(((Il2CppObjectBase)core).Pointer);
		}

		internal bool IsConcurrentCluster(CP_Bioscan_Core core)
		{
			return CCCores.ContainsKey(((Il2CppObjectBase)core.Owner).Pointer);
		}

		internal void ZeroCCScanSpeed(CP_Cluster_Core parent)
		{
			if (!CCCores.ContainsKey(((Il2CppObjectBase)parent).Pointer))
			{
				return;
			}
			foreach (CP_PlayerScanner item in CCCores[((Il2CppObjectBase)parent).Pointer])
			{
				bool flag = true;
				for (int i = 0; i < 4; i++)
				{
					flag = flag && ((Il2CppArrayBase<float>)(object)item.m_scanSpeeds)[i] == 0f;
					((Il2CppArrayBase<float>)(object)item.m_scanSpeeds)[i] = 0f;
				}
				if (flag)
				{
					break;
				}
			}
		}

		internal void RestoreCCScanSpeed(CP_Cluster_Core parent)
		{
			if (!CCCores.ContainsKey(((Il2CppObjectBase)parent).Pointer) || !OriginalClusterScanSpeeds.ContainsKey(((Il2CppObjectBase)parent).Pointer))
			{
				return;
			}
			float[] array = OriginalClusterScanSpeeds[((Il2CppObjectBase)parent).Pointer];
			foreach (CP_PlayerScanner item in CCCores[((Il2CppObjectBase)parent).Pointer])
			{
				bool flag = false;
				for (int i = 0; i < 4; i++)
				{
					flag = flag || ((Il2CppArrayBase<float>)(object)item.m_scanSpeeds)[i] != 0f;
					((Il2CppArrayBase<float>)(object)item.m_scanSpeeds)[i] = array[i];
				}
				if (flag)
				{
					break;
				}
			}
		}

		internal float[] GetCacheOriginalScanSpeed(CP_Bioscan_Core core)
		{
			if (IsConcurrentCluster(core))
			{
				if (!CCCores.ContainsKey(((Il2CppObjectBase)core.Owner).Pointer))
				{
					return ZERO_SCAN_SPEED;
				}
				return OriginalClusterScanSpeeds[((Il2CppObjectBase)core.Owner).Pointer];
			}
			if (OriginalScanSpeed.ContainsKey(((Il2CppObjectBase)core).Pointer))
			{
				return OriginalScanSpeed[((Il2CppObjectBase)core).Pointer];
			}
			CP_PlayerScanner cacheScanner = GetCacheScanner(core);
			if ((Object)(object)cacheScanner == (Object)null)
			{
				SPOLogger.Error("GetCacheOriginalScanSpeed: cannot get scanner for this CP_Bioscan_Core");
				return ZERO_SCAN_SPEED;
			}
			float[] array = new float[4];
			Array.Copy(Il2CppArrayBase<float>.op_Implicit((Il2CppArrayBase<float>)(object)cacheScanner.m_scanSpeeds), array, array.Length);
			OriginalScanSpeed.Add(((Il2CppObjectBase)core).Pointer, array);
			return array;
		}

		public CP_PlayerScanner GetCacheScanner(CP_Bioscan_Core core)
		{
			if (ChildScanners.ContainsKey(((Il2CppObjectBase)core).Pointer))
			{
				return ChildScanners[((Il2CppObjectBase)core).Pointer];
			}
			CP_PlayerScanner val = ((Il2CppObjectBase)core.PlayerScanner).TryCast<CP_PlayerScanner>();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			ChildScanners.Add(((Il2CppObjectBase)core).Pointer, val);
			return val;
		}

		internal bool CCShouldProgress(CP_Bioscan_Core child, bool IsThisScanShouldProgress)
		{
			if (CCStateMutex == null)
			{
				CCStateMutex = new Mutex();
			}
			if (CCStateMutex.WaitOne(2000))
			{
				if (!CCCores.ContainsKey(((Il2CppObjectBase)child.Owner).Pointer))
				{
					SPOLogger.Error("ConcurrentClusterShouldProgress: failed to find cluster parent!");
					CCStateMutex.ReleaseMutex();
					return false;
				}
				CP_Cluster_Core val = ((Il2CppObjectBase)child.Owner).Cast<CP_Cluster_Core>();
				if (!CCChildrenState.ContainsKey(((Il2CppObjectBase)val).Pointer))
				{
					SPOLogger.Error("ConcurrentClusterShouldProgress: ConcurrentClusterChildScanState initialization error!");
					CCStateMutex.ReleaseMutex();
					return false;
				}
				HashSet<IntPtr> hashSet = CCChildrenState[((Il2CppObjectBase)val).Pointer];
				bool result;
				if (IsThisScanShouldProgress)
				{
					hashSet.Add(((Il2CppObjectBase)child).Pointer);
					result = hashSet.Count == val.m_amountOfPuzzles;
				}
				else
				{
					hashSet.Remove(((Il2CppObjectBase)child).Pointer);
					result = false;
				}
				CCStateMutex.ReleaseMutex();
				return result;
			}
			SPOLogger.Debug("ConcurrentCluster: Failed to acquire scan mutex.");
			return false;
		}

		internal void CompleteConcurrentCluster(CP_Cluster_Core parent, CP_Bioscan_Core child)
		{
			if (CCChildren.ContainsKey(((Il2CppObjectBase)parent).Pointer))
			{
				HashSet<IntPtr> hashSet = CCChildren[((Il2CppObjectBase)parent).Pointer];
				hashSet.Remove(((Il2CppObjectBase)child).Pointer);
				if (hashSet.Count < 1)
				{
					CCChildren.Remove(((Il2CppObjectBase)parent).Pointer);
				}
			}
		}

		public List<CP_PlayerScanner> GetCCChildrenScanner(CP_Cluster_Core parent)
		{
			if (!CCCores.ContainsKey(((Il2CppObjectBase)parent).Pointer))
			{
				return null;
			}
			return CCCores[((Il2CppObjectBase)parent).Pointer];
		}

		public void Clear()
		{
			CCCores.Clear();
			CCChildren.Clear();
			CCChildrenState.Clear();
			OriginalClusterScanSpeeds.Clear();
			ChildScanners.Clear();
			OriginalScanSpeed.Clear();
			if (CCStateMutex != null)
			{
				CCStateMutex.Dispose();
			}
			CCStateMutex = null;
		}

		static PlayerScannerManager()
		{
			ZERO_SCAN_SPEED = new float[4];
			Current = new PlayerScannerManager();
			LevelAPI.OnLevelCleanup += Current.Clear;
		}

		private PlayerScannerManager()
		{
		}
	}
	public class PuzzleReqItemManager
	{
		public static readonly PuzzleReqItemManager Current;

		private Dictionary<int, CarryItemPickup_Core> BigPickupItemsInLevel = new Dictionary<int, CarryItemPickup_Core>();

		private int itemIndexCounter = 1;

		private List<(CP_Bioscan_Core, List<int>)> bioscanCoresToAddReqItems = new List<(CP_Bioscan_Core, List<int>)>();

		private List<(CP_Cluster_Core, List<int>)> clusterCoresToAddReqItems = new List<(CP_Cluster_Core, List<int>)>();

		private Dictionary<IntPtr, CP_Bioscan_Core> movableScansWithReqItems = new Dictionary<IntPtr, CP_Bioscan_Core>();

		internal int Register(CarryItemPickup_Core item)
		{
			int num = itemIndexCounter;
			itemIndexCounter++;
			BigPickupItemsInLevel.Add(num, item);
			return num;
		}

		internal void QueueForAddingReqItems(CP_Bioscan_Core core, List<int> itemsIndices)
		{
			bioscanCoresToAddReqItems.Add((core, itemsIndices));
		}

		internal void QueueForAddingReqItems(CP_Cluster_Core core, List<int> itemsIndices)
		{
			clusterCoresToAddReqItems.Add((core, itemsIndices));
		}

		internal CP_Bioscan_Core GetMovableCoreWithReqItem(CP_PlayerScanner scanner)
		{
			if (!movableScansWithReqItems.ContainsKey(((Il2CppObjectBase)scanner).Pointer))
			{
				return null;
			}
			return movableScansWithReqItems[((Il2CppObjectBase)scanner).Pointer];
		}

		public CarryItemPickup_Core GetBigPickupItem(int bigPickupInLevelIndex)
		{
			if (!BigPickupItemsInLevel.ContainsKey(bigPickupInLevelIndex))
			{
				return null;
			}
			return BigPickupItemsInLevel[bigPickupInLevelIndex];
		}

		public bool AddReqItems(CP_Bioscan_Core puzzle, int itemIndex)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			if ((Object)(object)puzzle == (Object)null || itemIndex == 0L)
			{
				return false;
			}
			if (!BigPickupItemsInLevel.ContainsKey(itemIndex))
			{
				SPOLogger.Error($"Unregistered BigPickup Item with index {itemIndex}");
				return false;
			}
			CarryItemPickup_Core val = BigPickupItemsInLevel[itemIndex];
			puzzle.AddRequiredItems(Il2CppReferenceArray<iWardenObjectiveItem>.op_Implicit((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1]
			{
				new iWardenObjectiveItem(((Il2CppObjectBase)val).Pointer)
			}));
			return true;
		}

		public bool AddReqItems(CP_Cluster_Core puzzle, int itemIndex)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			if ((Object)(object)puzzle == (Object)null || itemIndex == 0L)
			{
				return false;
			}
			if (!BigPickupItemsInLevel.ContainsKey(itemIndex))
			{
				SPOLogger.Error($"Unregistered BigPickup Item with index {itemIndex}");
				return false;
			}
			CarryItemPickup_Core val = BigPickupItemsInLevel[itemIndex];
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)puzzle.m_childCores)
			{
				item.AddRequiredItems(Il2CppReferenceArray<iWardenObjectiveItem>.op_Implicit((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1]
				{
					new iWardenObjectiveItem(((Il2CppObjectBase)val).Pointer)
				}));
			}
			return true;
		}

		public bool AddReqItems(CP_Bioscan_Core puzzle, List<int> itemsIndices)
		{
			if ((Object)(object)puzzle == (Object)null || itemsIndices == null || itemsIndices.Count < 1)
			{
				return false;
			}
			bool flag = false;
			foreach (int item in itemsIndices.ToHashSet())
			{
				flag |= AddReqItems(puzzle, item);
			}
			if (puzzle.IsMovable && flag)
			{
				movableScansWithReqItems.Add(((Il2CppObjectBase)puzzle.m_playerScanner).Pointer, puzzle);
			}
			return flag;
		}

		public void RemoveReqItem(CP_Bioscan_Core puzzle, int itemIndex)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			if (!((Object)(object)puzzle == (Object)null))
			{
				if (!BigPickupItemsInLevel.ContainsKey(itemIndex) && itemIndex != 0L)
				{
					SPOLogger.Error($"Unregistered BigPickup Item with index {itemIndex}");
				}
				else
				{
					CarryItemPickup_Core val = BigPickupItemsInLevel[itemIndex];
					puzzle.RemoveRequiredItems((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1]
					{
						new iWardenObjectiveItem(((Il2CppObjectBase)val).Pointer)
					});
				}
			}
		}

		public void RemoveReqItem(CP_Cluster_Core puzzle, int itemIndex)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			if ((Object)(object)puzzle == (Object)null)
			{
				return;
			}
			if (!BigPickupItemsInLevel.ContainsKey(itemIndex) && itemIndex != 0L)
			{
				SPOLogger.Error($"Unregistered BigPickup Item with index {itemIndex}");
				return;
			}
			CarryItemPickup_Core val = BigPickupItemsInLevel[itemIndex];
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)puzzle.m_childCores)
			{
				item.RemoveRequiredItems((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1]
				{
					new iWardenObjectiveItem(((Il2CppObjectBase)val).Pointer)
				});
			}
		}

		private void AddQueuedReqItems()
		{
			foreach (var (puzzle, itemsIndices) in bioscanCoresToAddReqItems)
			{
				AddReqItems(puzzle, itemsIndices);
			}
			foreach (var (val, itemsIndices2) in clusterCoresToAddReqItems)
			{
				foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_childCores)
				{
					CP_Bioscan_Core val2 = ((Il2CppObjectBase)item).TryCast<CP_Bioscan_Core>();
					if ((Object)(object)val2 == (Object)null)
					{
						SPOLogger.Error("Failed to cast child core to CP_Bioscan_Core");
					}
					else
					{
						AddReqItems(val2, itemsIndices2);
					}
				}
			}
		}

		public void OutputLevelBigPickupInfo()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_010a: 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)
			StringBuilder val = new StringBuilder();
			val.AppendLine();
			List<CarryItemPickup_Core> list = new List<CarryItemPickup_Core>(BigPickupItemsInLevel.Values);
			list.Sort(delegate(CarryItemPickup_Core b1, CarryItemPickup_Core b2)
			{
				//IL_0014: 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_0043: 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_002c: 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_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: 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)
				AIG_CourseNode spawnNode = b1.SpawnNode;
				AIG_CourseNode spawnNode2 = b2.SpawnNode;
				if (spawnNode.m_dimension.DimensionIndex != spawnNode2.m_dimension.DimensionIndex)
				{
					if (spawnNode.m_dimension.DimensionIndex > spawnNode2.m_dimension.DimensionIndex)
					{
						return 1;
					}
					return -1;
				}
				if (spawnNode.LayerType != spawnNode2.LayerType)
				{
					if (spawnNode.LayerType >= spawnNode2.LayerType)
					{
						return 1;
					}
					return -1;
				}
				return (spawnNode.m_zone.LocalIndex != spawnNode2.m_zone.LocalIndex) ? ((spawnNode.m_zone.LocalIndex >= spawnNode2.m_zone.LocalIndex) ? 1 : (-1)) : 0;
			});
			Dictionary<CarryItemPickup_Core, int> dictionary = new Dictionary<CarryItemPickup_Core, int>();
			foreach (int key in BigPickupItemsInLevel.Keys)
			{
				dictionary.Add(BigPickupItemsInLevel[key], key);
			}
			foreach (CarryItemPickup_Core item in list)
			{
				val.AppendLine("Item Name: " + ((Item)item).ItemDataBlock.publicName);
				val.AppendLine($"Zone {item.SpawnNode.m_zone.Alias}, {item.SpawnNode.LayerType}, Dim {item.SpawnNode.m_dimension.DimensionIndex}");
				val.AppendLine($"Item Index: {dictionary[item]}");
				val.AppendLine();
			}
			SPOLogger.Debug(((Object)val).ToString());
		}

		internal void OnEnterLevel()
		{
			AddQueuedReqItems();
			OutputLevelBigPickupInfo();
		}

		public void Clear()
		{
			BigPickupItemsInLevel.Clear();
			itemIndexCounter = 1;
			bioscanCoresToAddReqItems.Clear();
			clusterCoresToAddReqItems.Clear();
			movableScansWithReqItems.Clear();
		}

		static PuzzleReqItemManager()
		{
			Current = new PuzzleReqItemManager();
			LevelAPI.OnLevelCleanup += Current.Clear;
			LevelAPI.OnEnterLevel += Current.OnEnterLevel;
		}

		private PuzzleReqItemManager()
		{
		}
	}
	public class PuzzleOverrideManager
	{
		public static readonly PuzzleOverrideManager Current;

		private uint puzzleOverrideIndex = 1u;

		public static uint MainLevelLayout => RundownManager.ActiveExpedition.LevelLayoutData;

		private Dictionary<IntPtr, uint> bioscanIndex { get; } = new Dictionary<IntPtr, uint>();


		private Dictionary<IntPtr, uint> clusterIndex { get; } = new Dictionary<IntPtr, uint>();


		private Dictionary<uint, CP_Bioscan_Core> index2Bioscan { get; } = new Dictionary<uint, CP_Bioscan_Core>();


		private Dictionary<uint, CP_Cluster_Core> index2Cluster { get; } = new Dictionary<uint, CP_Cluster_Core>();


		public uint Register(CP_Bioscan_Core __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return 0u;
			}
			uint num = puzzleOverrideIndex;
			puzzleOverrideIndex++;
			if (!bioscanIndex.ContainsKey(((Il2CppObjectBase)__instance).Pointer))
			{
				bioscanIndex.Add(((Il2CppObjectBase)__instance).Pointer, num);
				index2Bioscan.Add(num, __instance);
				return num;
			}
			return GetBioscanCoreOverrideIndex(__instance);
		}

		public uint Register(CP_Cluster_Core __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return 0u;
			}
			uint num = puzzleOverrideIndex;
			puzzleOverrideIndex++;
			if (!clusterIndex.ContainsKey(((Il2CppObjectBase)__instance).Pointer))
			{
				clusterIndex.Add(((Il2CppObjectBase)__instance).Pointer, num);
				index2Cluster.Add(num, __instance);
				return num;
			}
			return GetClusterCoreOverrideIndex(__instance);
		}

		public void OutputLevelPuzzleInfo()
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			List<ChainedPuzzleInstance> list = new List<ChainedPuzzleInstance>();
			Enumerator<ChainedPuzzleInstance> enumerator = ChainedPuzzleManager.Current.m_instances.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ChainedPuzzleInstance current = enumerator.Current;
				list.Add(current);
			}
			list.Sort(delegate(ChainedPuzzleInstance c1, ChainedPuzzleInstance c2)
			{
				//IL_0019: 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_003e: 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_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				LG_Zone zone2 = c1.m_sourceArea.m_zone;
				LG_Zone zone3 = c2.m_sourceArea.m_zone;
				if (zone2.DimensionIndex != zone3.DimensionIndex)
				{
					if (zone2.DimensionIndex >= zone3.DimensionIndex)
					{
						return 1;
					}
					return -1;
				}
				if (zone2.Layer.m_type != zone3.Layer.m_type)
				{
					if (zone2.Layer.m_type >= zone3.Layer.m_type)
					{
						return 1;
					}
					return -1;
				}
				return (zone2.LocalIndex >= zone3.LocalIndex) ? 1 : (-1);
			});
			StringBuilder stringBuilder = new StringBuilder();
			foreach (ChainedPuzzleInstance item in list)
			{
				LG_Zone zone = item.m_sourceArea.m_zone;
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder3 = stringBuilder2;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(15, 3, stringBuilder2);
				handler.AppendLiteral("\nZone ");
				handler.AppendFormatted(zone.Alias);
				handler.AppendLiteral(", ");
				handler.AppendFormatted<LG_LayerType>(zone.m_layer.m_type);
				handler.AppendLiteral(", Dim ");
				handler.AppendFormatted<eDimensionIndex>(zone.DimensionIndex);
				handler.AppendLiteral("\n");
				stringBuilder3.Append(ref handler);
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder4 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(14, 1, stringBuilder2);
				handler.AppendLiteral("Alarm name: ");
				handler.AppendFormatted(item.Data.PublicAlarmName);
				handler.AppendLiteral(":\n");
				stringBuilder4.Append(ref handler);
				for (int i = 0; i < ((Il2CppArrayBase<iChainedPuzzleCore>)(object)item.m_chainedPuzzleCores).Count; i++)
				{
					iChainedPuzzleCore val = ((Il2CppArrayBase<iChainedPuzzleCore>)(object)item.m_chainedPuzzleCores)[i];
					if (bioscanIndex.ContainsKey(((Il2CppObjectBase)val).Pointer))
					{
						uint value = bioscanIndex[((Il2CppObjectBase)val).Pointer];
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder5 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(15, 1, stringBuilder2);
						handler.AppendLiteral("puzzle index: ");
						handler.AppendFormatted(i);
						handler.AppendLiteral("\n");
						stringBuilder5.Append(ref handler);
						stringBuilder.Append("type: CP_Bioscan_Core\n");
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder6 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(22, 1, stringBuilder2);
						handler.AppendLiteral("PuzzleOverrideIndex: ");
						handler.AppendFormatted(value);
						handler.AppendLiteral("\n");
						stringBuilder6.Append(ref handler);
						CP_Bioscan_Core val2 = ((Il2CppObjectBase)val).Cast<CP_Bioscan_Core>();
						CP_PlayerScanner val3 = ((Il2CppObjectBase)val2.PlayerScanner).Cast<CP_PlayerScanner>();
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder7 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder2);
						handler.AppendLiteral("Position: ");
						handler.AppendFormatted<Vector3>(val2.m_position);
						handler.AppendLiteral("\n");
						stringBuilder7.Append(ref handler);
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder8 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(9, 1, stringBuilder2);
						handler.AppendLiteral("Radius: ");
						handler.AppendFormatted(val3.Radius);
						handler.AppendLiteral("\n");
						stringBuilder8.Append(ref handler);
					}
					else if (clusterIndex.ContainsKey(((Il2CppObjectBase)val).Pointer))
					{
						uint value2 = clusterIndex[((Il2CppObjectBase)val).Pointer];
						CP_Cluster_Core val4 = ((Il2CppObjectBase)val).Cast<CP_Cluster_Core>();
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder9 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(15, 1, stringBuilder2);
						handler.AppendLiteral("puzzle index: ");
						handler.AppendFormatted(i);
						handler.AppendLiteral("\n");
						stringBuilder9.Append(ref handler);
						stringBuilder.Append("type: CP_Cluster_Core\n");
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder10 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(22, 1, stringBuilder2);
						handler.AppendLiteral("PuzzleOverrideIndex: ");
						handler.AppendFormatted(value2);
						handler.AppendLiteral("\n");
						stringBuilder10.Append(ref handler);
						stringBuilder.Append("=== Clustered puzzles info: ===\n");
						for (int j = 0; j < val4.m_amountOfPuzzles; j++)
						{
							iChainedPuzzleCore val5 = ((Il2CppArrayBase<iChainedPuzzleCore>)(object)val4.m_childCores)[j];
							if (!bioscanIndex.ContainsKey(((Il2CppObjectBase)val5).Pointer))
							{
								SPOLogger.Error("Unregistered clustered iChainedPuzzleCore found...");
								continue;
							}
							uint value3 = bioscanIndex[((Il2CppObjectBase)val5).Pointer];
							stringBuilder2 = stringBuilder;
							StringBuilder stringBuilder11 = stringBuilder2;
							handler = new StringBuilder.AppendInterpolatedStringHandler(15, 1, stringBuilder2);
							handler.AppendLiteral("puzzle index: ");
							handler.AppendFormatted(j);
							handler.AppendLiteral("\n");
							stringBuilder11.Append(ref handler);
							stringBuilder.Append("type: CP_Bioscan_Core\n");
							stringBuilder2 = stringBuilder;
							StringBuilder stringBuilder12 = stringBuilder2;
							handler = new StringBuilder.AppendInterpolatedStringHandler(22, 1, stringBuilder2);
							handler.AppendLiteral("PuzzleOverrideIndex: ");
							handler.AppendFormatted(value3);
							handler.AppendLiteral("\n");
							stringBuilder12.Append(ref handler);
							CP_Bioscan_Core val6 = ((Il2CppObjectBase)val5).Cast<CP_Bioscan_Core>();
							CP_PlayerScanner val7 = ((Il2CppObjectBase)val6.PlayerScanner).Cast<CP_PlayerScanner>();
							stringBuilder2 = stringBuilder;
							StringBuilder stringBuilder13 = stringBuilder2;
							handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder2);
							handler.AppendLiteral("Position: ");
							handler.AppendFormatted<Vector3>(val6.m_position);
							handler.AppendLiteral("\n");
							stringBuilder13.Append(ref handler);
							stringBuilder2 = stringBuilder;
							StringBuilder stringBuilder14 = stringBuilder2;
							handler = new StringBuilder.AppendInterpolatedStringHandler(9, 1, stringBuilder2);
							handler.AppendLiteral("Radius: ");
							handler.AppendFormatted(val7.Radius);
							handler.AppendLiteral("\n");
							stringBuilder14.Append(ref handler);
						}
						stringBuilder.Append("=== Clustered puzzles END ===\n");
					}
					else
					{
						SPOLogger.Error("Unregistered iChainedPuzzleCore found...");
					}
				}
				stringBuilder.Append('\n');
			}
			SPOLogger.Debug(stringBuilder.ToString());
		}

		public uint GetBioscanCoreOverrideIndex(CP_Bioscan_Core core)
		{
			if (bioscanIndex.ContainsKey(((Il2CppObjectBase)core).Pointer))
			{
				return bioscanIndex[((Il2CppObjectBase)core).Pointer];
			}
			return 0u;
		}

		public uint GetClusterCoreOverrideIndex(CP_Cluster_Core core)
		{
			if (clusterIndex.ContainsKey(((Il2CppObjectBase)core).Pointer))
			{
				return clusterIndex[((Il2CppObjectBase)core).Pointer];
			}
			return 0u;
		}

		public uint GetBioscanCoreOverrideIndex(IntPtr pointer)
		{
			if (bioscanIndex.ContainsKey(pointer))
			{
				return bioscanIndex[pointer];
			}
			return 0u;
		}

		public uint GetClusterCoreOverrideIndex(IntPtr pointer)
		{
			if (clusterIndex.ContainsKey(pointer))
			{
				return clusterIndex[pointer];
			}
			return 0u;
		}

		public CP_Bioscan_Core GetBioscanCore(uint puzzleOverrideIndex)
		{
			if (!index2Bioscan.ContainsKey(puzzleOverrideIndex))
			{
				return null;
			}
			return index2Bioscan[puzzleOverrideIndex];
		}

		public CP_Cluster_Core GetClusterCore(uint puzzleOverrideIndex)
		{
			if (!index2Cluster.ContainsKey(puzzleOverrideIndex))
			{
				return null;
			}
			return index2Cluster[puzzleOverrideIndex];
		}

		public void Clear()
		{
			puzzleOverrideIndex = 1u;
			bioscanIndex.Clear();
			clusterIndex.Clear();
			index2Bioscan.Clear();
			index2Cluster.Clear();
		}

		private PuzzleOverrideManager()
		{
		}

		static PuzzleOverrideManager()
		{
			Current = new PuzzleOverrideManager();
			LevelAPI.OnEnterLevel += Current.OutputLevelPuzzleInfo;
			LevelAPI.OnBuildStart += Current.Clear;
			LevelAPI.OnLevelCleanup += Current.Clear;
		}

		public iChainedPuzzleOwner ChainedPuzzleInstanceOwner(CP_Bioscan_Core bioscanCore)
		{
			if ((Object)(object)bioscanCore == (Object)null)
			{
				return null;
			}
			iChainedPuzzleOwner owner = bioscanCore.Owner;
			if ((Object)(object)((Il2CppObjectBase)owner).TryCast<ChainedPuzzleInstance>() != (Object)null)
			{
				return owner;
			}
			CP_Cluster_Core val = ((Il2CppObjectBase)owner).TryCast<CP_Cluster_Core>();
			if ((Object)(object)val != (Object)null)
			{
				return val.m_owner;
			}
			SPOLogger.Error("Failed to find CP_BioScan_Core owner (instance of ChainedPuzzleInstance).");
			return null;
		}
	}
}
namespace ScanPosOverride.JSON
{
	public static class InjectLibUtil
	{
		public const string PLUGIN_GUID = "GTFO.InjectLib";

		public static JsonConverter InjectLibConnector { get; private set; }

		public static bool IsLoaded { get; private set; }

		static InjectLibUtil()
		{
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("GTFO.InjectLib", out var value))
			{
				return;
			}
			try
			{
				Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				InjectLibConnector = (JsonConverter)Activator.CreateInstance(obj.GetTypes().First((Type t) => t.Name == "InjectLibConnector") ?? throw new Exception("Unable to Find InjectLibConnector Class"));
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				SPOLogger.Error($"Exception thrown while reading data from GTFO.AWO: {value2}");
			}
		}
	}
	internal class LocalizedTextConverter : JsonConverter<LocalizedText>
	{
		public override bool HandleNull => false;

		public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string @string = reader.GetString();
				return new LocalizedText
				{
					Id = 0u,
					UntranslatedText = @string
				};
			}
			case JsonTokenType.Number:
				return new LocalizedText
				{
					Id = reader.GetUInt32(),
					UntranslatedText = null
				};
			default:
				throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
		{
			JsonSerializer.Serialize<LocalizedText>(writer, value, options);
		}
	}
	public sealed class MyVector3Converter : JsonConverter<Vector3>
	{
		public override bool HandleNull => false;

		public override Vector3 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//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_0114: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			Vector3 vector = Vector3.zero;
			switch (reader.TokenType)
			{
			case JsonTokenType.StartObject:
			{
				int currentDepth = reader.CurrentDepth;
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject && reader.CurrentDepth == currentDepth)
					{
						SPOLogger.Warning($"Parsed Vector3 : {vector}");
						return vector;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string? @string = reader.GetString();
					reader.Read();
					switch (@string.ToLowerInvariant())
					{
					case "x":
						vector.x = reader.GetSingle();
						break;
					case "y":
						vector.y = reader.GetSingle();
						break;
					case "z":
						vector.z = reader.GetSingle();
						break;
					}
				}
				throw new JsonException("Expected EndObject token");
			}
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				if (TryParseVector3(text, out vector))
				{
					return vector;
				}
				throw new JsonException("Vector3 format is not right: " + text);
			}
			default:
				throw new JsonException($"Vector3Json type: {reader.TokenType} is not implemented!");
			}
		}

		private static bool TryParseVector3(string input, out Vector3 vector)
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			float[] array = default(float[]);
			if (!RegexUtils.TryParseVectorString(input, ref array))
			{
				vector = Vector3.zero;
				return false;
			}
			if (array.Length < 3)
			{
				vector = Vector3.zero;
				return false;
			}
			vector = new Vector3(array[0], array[1], array[2]);
			return true;
		}

		public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			writer.WriteStringValue($"({value.x} {value.y} {value.z})");
		}
	}
	internal static class Json
	{
		private static readonly JsonSerializerOptions _setting;

		static Json()
		{
			_setting = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = false,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				IgnoreReadOnlyProperties = true
			};
			_setting.Converters.Add(new JsonStringEnumConverter());
			_setting.Converters.Add(new MyVector3Converter());
			if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
			{
				_setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
				_setting.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter);
				SPOLogger.Log("PartialData Support Found!");
			}
			else
			{
				_setting.Converters.Add(new LocalizedTextConverter());
			}
			if (InjectLibUtil.IsLoaded)
			{
				_setting.Converters.Add(InjectLibUtil.InjectLibConnector);
				SPOLogger.Log("InjectLib (AWO) support found!");
			}
		}

		public static T Deserialize<T>(string json)
		{
			return JsonSerializer.Deserialize<T>(json, _setting);
		}

		public static object Deserialize(Type type, string json)
		{
			return JsonSerializer.Deserialize(json, type, _setting);
		}

		public static string Serialize<T>(T value)
		{
			return JsonSerializer.Serialize(value, _setting);
		}

		public static void Load<T>(string file, out T config) where T : new()
		{
			if (file.Length < ".json".Length)
			{
				config = default(T);
				return;
			}
			if (file.Substring(file.Length - ".json".Length) != ".json")
			{
				file += ".json";
			}
			file = File.ReadAllText(Path.Combine(Plugin.OVERRIDE_SCAN_POS_PATH, file));
			config = Deserialize<T>(file);
		}
	}
	public static class MTFOPartialDataUtil
	{
		public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";

		public static JsonConverter PersistentIDConverter { get; private set; }

		public static JsonConverter LocalizedTextConverter { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool Initialized { get; private set; }

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

		static MTFOPartialDataUtil()
		{
			PersistentIDConverter = null;
			LocalizedTextConverter = null;
			IsLoaded = false;
			Initialized = false;
			PartialDataPath = string.Empty;
			ConfigPath = string.Empty;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value))
			{
				return;
			}
			try
			{
				Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type[] types = obj.GetTypes();
				Type type = types.First((Type t) => t.Name == "PersistentIDConverter");
				if ((object)type == null)
				{
					throw new Exception("Unable to Find PersistentIDConverter Class");
				}
				Type type2 = types.First((Type t) => t.Name == "PartialDataManager");
				if ((object)type2 == null)
				{
					throw new Exception("Unable to Find PartialDataManager Class");
				}
				Type type3 = types.First((Type t) => t.Name == "LocalizedTextConverter") ?? throw new Exception("Unable to Find LocalizedTextConverter Class");
				PropertyInfo property = type2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo property2 = type2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo? property3 = type2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public);
				if ((object)property == null)
				{
					throw new Exception("Unable to Find Property: Initialized");
				}
				if ((object)property2 == null)
				{
					throw new Exception("Unable to Find Property: PartialDataPath");
				}
				if ((object)property3 == null)
				{
					throw new Exception("Unable to Find Field: ConfigPath");
				}
				Initialized = (bool)property.GetValue(null);
				PartialDataPath = (string)property2.GetValue(null);
				ConfigPath = (string)property3.GetValue(null);
				PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type);
				LocalizedTextConverter = (JsonConverter)Activator.CreateInstance(type3);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				SPOLogger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}");
			}
		}
	}
	public static class MTFOUtil
	{
		public const string PLUGIN_GUID = "com.dak.MTFO";

		public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public;

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

		static MTFOUtil()
		{
			GameDataPath = string.Empty;
			CustomPath = string.Empty;
			HasCustomContent = false;
			IsLoaded = false;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
			{
				return;
			}
			try
			{
				Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
				FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				SPOLogger.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}");
			}
		}
	}
}
namespace ScanPosOverride.Component
{
	internal class ConcurrentClusterHud : MonoBehaviour
	{
		public enum PlayerCountRequirement
		{
			INVALID,
			ANY,
			SOLO,
			DUO
		}

		private StringBuilder displayText = new StringBuilder();

		private bool m_isValid;

		private List<CP_Bioscan_Core> children;

		private float childRadius = -1f;

		private int[] playerInScanCount;

		private readonly string[] ROMAN = new string[4] { "I", "II", "III", "IV" };

		internal CP_Cluster_Core parent { get; set; }

		internal CP_Bioscan_Hud parentHud { get; set; }

		internal PuzzleOverride def { get; set; }

		public PlayerCountRequirement playerCountReq { get; private set; }

		private PlayerCountRequirement ReqPlayerCount(iChainedPuzzleCore child)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			CP_PlayerScanner obj = ((Il2CppObjectBase)((Il2CppObjectBase)child).Cast<CP_Bioscan_Core>().m_playerScanner).Cast<CP_PlayerScanner>();
			PlayerRequirement playerRequirement = obj.m_playerRequirement;
			Il2CppStructArray<float> scanSpeeds = obj.m_scanSpeeds;
			switch ((int)playerRequirement)
			{
			case 2:
				if (!(((Il2CppArrayBase<float>)(object)scanSpeeds)[0] > 0f))
				{
					return PlayerCountRequirement.INVALID;
				}
				return PlayerCountRequirement.SOLO;
			case 0:
			{
				int i;
				for (i = 0; i < ((Il2CppArrayBase<float>)(object)scanSpeeds).Count && ((Il2CppArrayBase<float>)(object)scanSpeeds)[i] == 0f; i++)
				{
				}
				if (i >= 2)
				{
					return PlayerCountRequirement.INVALID;
				}
				if (i == 1)
				{
					return PlayerCountRequirement.DUO;
				}
				if (!(((Il2CppArrayBase<float>)(object)scanSpeeds)[i + 1] > 0f))
				{
					return PlayerCountRequirement.SOLO;
				}
				return PlayerCountRequirement.ANY;
			}
			default:
				return PlayerCountRequirement.INVALID;
			}
		}

		internal bool Setup()
		{
			if (((Il2CppArrayBase<iChainedPuzzleCore>)(object)parent.m_childCores).Count < 2 || ((Il2CppArrayBase<iChainedPuzzleCore>)(object)parent.m_childCores).Count > 4)
			{
				SPOLogger.Error($"ConcurrentClusterHud: got cluster scan with {((Il2CppArrayBase<iChainedPuzzleCore>)(object)parent.m_childCores).Count} children, which is invalid for concurrent cluster");
				return false;
			}
			playerCountReq = ReqPlayerCount(((Il2CppArrayBase<iChainedPuzzleCore>)(object)parent.m_childCores)[0]);
			if (playerCountReq == PlayerCountRequirement.INVALID)
			{
				SPOLogger.Error($"ConcurrentCluster setup: playerRequirement is {1}, which is invalid for concurrent cluster");
				return false;
			}
			switch (((Il2CppArrayBase<iChainedPuzzleCore>)(object)parent.m_childCores).Count)
			{
			case 2:
				switch (playerCountReq)
				{
				case PlayerCountRequirement.ANY:
				case PlayerCountRequirement.SOLO:
					m_isValid = true;
					break;
				case PlayerCountRequirement.DUO:
					m_isValid = true;
					break;
				}
				break;
			case 4:
			{
				PlayerCountRequirement playerCountRequirement = playerCountReq;
				if ((uint)(playerCountRequirement - 1) <= 1u)
				{
					m_isValid = true;
				}
				break;
			}
			case 3:
			{
				PlayerCountRequirement playerCountRequirement = playerCountReq;
				if ((uint)(playerCountRequirement - 1) <= 1u)
				{
					m_isValid = true;
				}
				break;
			}
			}
			if (!m_isValid)
			{
				SPOLogger.Error($"ConcurrentCluster setup: Something went wrong! PlayerCountRequirement: {playerCountReq}, children num: {((Il2CppArrayBase<iChainedPuzzleCore>)(object)parent.m_childCores).Count}");
				return false;
			}
			playerInScanCount = new int[((Il2CppArrayBase<iChainedPuzzleCore>)(object)parent.m_childCores).Count];
			Array.Fill(playerInScanCount, 0);
			children = ((IEnumerable<iChainedPuzzleCore>)parent.m_childCores).ToList().ConvertAll((iChainedPuzzleCore c) => ((Il2CppObjectBase)c).Cast<CP_Bioscan_Core>());
			childRadius = ((Il2CppObjectBase)((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)parent.m_childCores)[0]).Cast<CP_Bioscan_Core>().m_playerScanner).Cast<CP_PlayerScanner>().Radius;
			return true;
		}

		private void LateUpdate()
		{
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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)
			if (!m_isValid || !parentHud.m_visible || !parentHud.m_isClosestToPlayer)
			{
				return;
			}
			displayText.Clear();
			displayText.AppendLine().Append("<color=white>");
			for (int i = 0; i < children.Count; i++)
			{
				int num = 0;
				CP_Bioscan_Core val = children[i];
				Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Vector3 val2 = ((Agent)enumerator.Current).Position - ((Component)val).transform.position;
					if (((Vector3)(ref val2)).magnitude < childRadius)
					{
						num++;
					}
				}
				playerInScanCount[i] = num;
				string value = string.Empty;
				string value2 = string.Empty;
				switch (playerCountReq)
				{
				case PlayerCountRequirement.ANY:
					switch (num)
					{
					case 0:
						value = " ";
						break;
					case 1:
						value = "A";
						break;
					case 2:
						value = "A,B";
						break;
					case 3:
						value = "A,B,C";
						break;
					case 4:
						value = "A,B,C,D";
						break;
					}
					value2 = ((num > 0) ? "white" : "orange");
					break;
				case PlayerCountRequirement.SOLO:
					switch (num)
					{
					case 0:
						value = " ";
						value2 = "orange";
						break;
					case 1:
						value = "A";
						value2 = "white";
						break;
					case 2:
						value = "A,<color=red>B</color>";
						value2 = "orange";
						break;
					case 3:
						value = "A,<color=red>B</color>,<color=red>C</color>";
						value2 = "orange";
						break;
					case 4:
						value = "A,<color=red>B</color>,<color=red>C</color>,<color=red>D</color>";
						value2 = "orange";
						break;
					}
					break;
				case PlayerCountRequirement.DUO:
					switch (num)
					{
					case 0:
						value = " , ";
						value2 = "orange";
						break;
					case 1:
						value = "A, ";
						value2 = "orange";
						break;
					case 2:
						value = "A,B";
						value2 = "white";
						break;
					case 3:
						value = "A,B,<color=red>C</color>";
						value2 = "orange";
						break;
					case 4:
						value = "A,B,<color=red>C</color>,<color=red>D</color>";
						value2 = "orange";
						break;
					}
					break;
				}
				StringBuilder stringBuilder = displayText;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(8, 1, stringBuilder);
				handler.AppendLiteral("<color=");
				handler.AppendFormatted(value2);
				handler.AppendLiteral(">");
				StringBuilder stringBuilder2 = stringBuilder.Append(ref handler).Append(ROMAN[i]).Append(": ")
					.Append("[")
					.Append(value)
					.Append("]");
				StringBuilder.AppendInterpolatedStringHandler handler2 = new StringBuilder.AppendInterpolatedStringHandler(9, 1, stringBuilder2);
				handler2.AppendLiteral("</color=");
				handler2.AppendFormatted(value2);
				handler2.AppendLiteral(">");
				stringBuilder2.Append(ref handler2);
				if (i != children.Count - 1)
				{
					displayText.Append(" | ");
				}
			}
			displayText.Append("</color=white>");
			parentHud.m_msgCharBuffer.Add(displayText.ToString());
			GuiManager.InteractionLayer.SetMessage(parentHud.m_msgCharBuffer, parentHud.m_msgStyle, 0);
		}

		private void OnDestroy()
		{
			parent = null;
			parentHud = null;
			def = null;
			children.Clear();
			children = null;
			m_isValid = false;
			playerInScanCount = null;
			displayText = null;
		}

		static ConcurrentClusterHud()
		{
			ClassInjector.RegisterTypeInIl2Cpp<ConcurrentClusterHud>();
		}
	}
}