Decompiled source of TOA Heavy Industries v1.1.74

BeplnEx/plugins/TOA Heavy Industries/Custom/Net.6/TOA_Heavy_Industries_2.2.0.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
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 BepInEx.Unity.IL2CPP.Utils.Collections;
using CellMenu;
using ChainedPuzzles;
using EOSExt.TacticalBigPickup.Definitions.Generic.BigPickup.Definition;
using EOSExt.TacticalBigPickup.FogBeacon.Generic;
using EOSExt.TacticalBigPickup.Functions.FogBeacon.BigPickup;
using EOSExt.TacticalBigPickup.Functions.FogBeacon.LevelSpawned;
using EOSExt.TacticalBigPickup.Functions.Generic.BigPickup;
using EOSExt.TacticalBigPickup.Functions.Generic.BigPickup.Definition;
using EOSExt.TacticalBigPickup.Impl;
using EOSExt.TacticalBigPickup.Impl.FogBeacon.LeveSpawned;
using EOSExt.TacticalBigPickup.Managers;
using Enemies;
using ExtraObjectiveSetup;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.JSON;
using ExtraObjectiveSetup.Utils;
using FloLib.Networks.Replications;
using GTFO.API;
using GTFO.API.Extensions;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using ScanPosOverride.Managers;
using StateMachines;
using TMPro;
using TOA_Heavy_Industries;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("TOA_Heavy_Industries")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.2.0.0")]
[assembly: AssemblyInformationalVersion("2.2.0")]
[assembly: AssemblyProduct("TOA_Heavy_Industries")]
[assembly: AssemblyTitle("TOA_Heavy_Industries")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace EOSExt.TacticalBigPickup.Patches
{
	[HarmonyPatch]
	internal static class FixLevelSpawnedFogBeaconRange
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(HeavyFogRepellerGlobalState), "AttemptInteract")]
		private static void Post_HeavyFogRepellerGlobalState_AttemptInteract(HeavyFogRepellerGlobalState __instance)
		{
			LevelSpawnedFogBeaconSettings lSFBDef = LevelSpawnedFogBeaconSettingManager.Current.GetLSFBDef(__instance);
			if (lSFBDef != null)
			{
				__instance.m_repellerSphere.Range = lSFBDef.Range;
			}
		}
	}
	[HarmonyPatch]
	public static class SetupBigPickupItemWithItemId
	{
		public const string BIG_PICKUP_FOG_BEACON_NAME = "Carry_FogBeacon - ConstantFog";

		public const string BIG_PICKUP_OBSERVER_NAME = "Carry_Observer";

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_PickupItem), "SetupBigPickupItemWithItemId")]
		private static void Post_Setup(LG_PickupItem __instance, uint itemId)
		{
			BigPickupItemManager.Current.Register(__instance);
		}
	}
}
namespace EOSExt.TacticalBigPickup.FogBeacon.Generic
{
	public abstract class TOAGenericDefinitionManager<T> where T : new()
	{
		protected readonly Dictionary<uint, GenericDefinition<T>> definitions = new Dictionary<uint, GenericDefinition<T>>();

		protected abstract string DEFINITION_NAME { get; }

		protected string DEFINITION_PATH { get; }

		protected TOAGenericDefinitionManager()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			DEFINITION_PATH = Path.Combine(TOAConfigPaths.GetCustomPath(), "TOA_Heavy_Industries", "FogBeacon", DEFINITION_NAME);
			Directory.CreateDirectory(DEFINITION_PATH);
			EnsureTemplate();
			LoadDefinitions();
			LiveEdit.CreateListener(DEFINITION_PATH, "*.json", true).FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void EnsureTemplate()
		{
			string path = Path.Combine(DEFINITION_PATH, "Template.json");
			if (!File.Exists(path))
			{
				File.WriteAllText(path, EOSJson.Serialize<GenericDefinition<T>>(new GenericDefinition<T>()));
			}
		}

		private void LoadDefinitions()
		{
			foreach (string item in Directory.EnumerateFiles(DEFINITION_PATH, "*.json", SearchOption.AllDirectories))
			{
				try
				{
					AddDefinitions(EOSJson.Deserialize<GenericDefinition<T>>(File.ReadAllText(item)));
				}
				catch (Exception value)
				{
					EOSLogger.Error($"TOA Fog Beacon definition load failed for '{item}': {value}");
				}
			}
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				AddDefinitions(EOSJson.Deserialize<GenericDefinition<T>>(content));
			});
		}

		private void AddDefinitions(GenericDefinition<T> definition)
		{
			if (definition != null)
			{
				definitions[definition.ID] = definition;
			}
		}

		public GenericDefinition<T> GetDefinition(uint id)
		{
			if (!definitions.TryGetValue(id, out GenericDefinition<T> value))
			{
				return null;
			}
			return value;
		}

		public virtual void Init()
		{
		}
	}
	public abstract class TOAExpeditionDefinitionManager<T> where T : new()
	{
		protected readonly Dictionary<uint, GenericExpeditionDefinition<T>> definitions = new Dictionary<uint, GenericExpeditionDefinition<T>>();

		protected abstract string DEFINITION_NAME { get; }

		protected string DEFINITION_PATH { get; }

		protected TOAExpeditionDefinitionManager()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			DEFINITION_PATH = Path.Combine(TOAConfigPaths.GetCustomPath(), "TOA_Heavy_Industries", "FogBeacon", DEFINITION_NAME);
			Directory.CreateDirectory(DEFINITION_PATH);
			EnsureTemplate();
			LoadDefinitions();
			LiveEdit.CreateListener(DEFINITION_PATH, "*.json", true).FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void EnsureTemplate()
		{
			string path = Path.Combine(DEFINITION_PATH, "Template.json");
			if (!File.Exists(path))
			{
				File.WriteAllText(path, EOSJson.Serialize<GenericExpeditionDefinition<T>>(new GenericExpeditionDefinition<T>()));
			}
		}

		private void LoadDefinitions()
		{
			foreach (string item in Directory.EnumerateFiles(DEFINITION_PATH, "*.json", SearchOption.AllDirectories))
			{
				try
				{
					AddDefinitions(EOSJson.Deserialize<GenericExpeditionDefinition<T>>(File.ReadAllText(item)));
				}
				catch (Exception value)
				{
					EOSLogger.Error($"TOA Fog Beacon definition load failed for '{item}': {value}");
				}
			}
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				AddDefinitions(EOSJson.Deserialize<GenericExpeditionDefinition<T>>(content));
			});
		}

		private void AddDefinitions(GenericExpeditionDefinition<T> definition)
		{
			if (definition != null)
			{
				definitions[definition.MainLevelLayout] = definition;
			}
		}

		public GenericExpeditionDefinition<T> GetDefinition(uint levelLayout)
		{
			if (!definitions.TryGetValue(levelLayout, out GenericExpeditionDefinition<T> value))
			{
				return null;
			}
			return value;
		}

		public virtual void Init()
		{
		}
	}
}
namespace EOSExt.TacticalBigPickup.Definitions.Generic.BigPickup.Definition
{
	public class BigPickupFunction
	{
		public string Type { get; set; } = string.Empty;

		public uint SettingID { get; set; }
	}
}
namespace EOSExt.TacticalBigPickup.Managers
{
	public class BigPickupItemManager : PickupItemManager<CarryItemPickup_Core>
	{
		public static BigPickupItemManager Current { get; }

		private BigPickupItemManager()
		{
		}

		static BigPickupItemManager()
		{
			Current = new BigPickupItemManager();
		}
	}
	internal static class ItemInLevelUtils
	{
		internal static (eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex) GetGlobalZoneIndex(this ItemInLevel item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			pItemData pItemData = ((Item)item).pItemData;
			AIG_CourseNode val = default(AIG_CourseNode);
			if (((pCourseNode)(ref pItemData.originCourseNode)).TryGet(ref val))
			{
				return (dim: val.m_dimension.DimensionIndex, layer: val.LayerType, localIndex: val.m_zone.LocalIndex);
			}
			throw new NullReferenceException("originCourseNode is null");
		}

		internal static LG_PickupItem GetLGPickupItem(this ItemInLevel item)
		{
			return ((Component)item).GetComponentInParent<LG_PickupItem>();
		}
	}
	public abstract class PickupItemManager<T> where T : ItemInLevel
	{
		protected Dictionary<uint, List<T>> RegisteredItems { get; private set; } = new Dictionary<uint, List<T>>();

		public virtual void Register(LG_PickupItem item)
		{
			T componentInChildren = ((Component)item.m_root).GetComponentInChildren<T>();
			Register(componentInChildren);
		}

		public virtual void Register(T item)
		{
			ItemDataBlock itemDataBlock = ((Item)(object)item).ItemDataBlock;
			if (!RegisteredItems.TryGetValue(((GameDataBlockBase<ItemDataBlock>)(object)itemDataBlock).persistentID, out List<T> value))
			{
				value = new List<T>();
				RegisteredItems[((GameDataBlockBase<ItemDataBlock>)(object)itemDataBlock).persistentID] = value;
			}
			value.Add(item);
		}

		public virtual Dictionary<(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex), List<T>> GetItemsOf(uint itemId)
		{
			if (!RegisteredItems.TryGetValue(itemId, out List<T> value))
			{
				return null;
			}
			return (from item in value
				group item by ((ItemInLevel)(object)item).GetGlobalZoneIndex()).ToDictionary((IGrouping<(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex), T> g) => g.Key, (IGrouping<(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex), T> g) => g.ToList());
		}

		protected virtual void OnBuildDone()
		{
		}

		protected virtual void Clear()
		{
			RegisteredItems.Clear();
		}

		protected PickupItemManager()
		{
			LevelAPI.OnBuildDone += OnBuildDone;
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}

		static PickupItemManager()
		{
		}
	}
}
namespace EOSExt.TacticalBigPickup.Functions.Generic.BigPickup
{
	public class BigPickupCustomHelper : MonoBehaviour
	{
		private Dictionary<ePickupItemStatus, List<WardenObjectiveEventData>> eventsOnState = new Dictionary<ePickupItemStatus, List<WardenObjectiveEventData>>();

		public ItemInLevel Item { get; private set; }

		private void Setup(ItemInLevel item)
		{
			Item = item;
			item.GetSyncComponent().OnSyncStateChange += Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>.op_Implicit((Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>)OnSyncStateChange);
		}

		public bool TryGetEvents(ePickupItemStatus state, out List<WardenObjectiveEventData> events)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return eventsOnState.TryGetValue(state, out events);
		}

		private void OnSyncStateChange(ePickupItemStatus state, pPickupPlacement placement, PlayerAgent player, bool isRecall)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (!isRecall && SNet.IsMaster && TryGetEvents(state, out List<WardenObjectiveEventData> events))
			{
				EOSLogger.Log($"item {((Item)Item).PublicName} on state {state}, executing {events.Count} events");
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(events), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
			}
		}

		private void OnDestroy()
		{
			eventsOnState.Clear();
			eventsOnState = null;
		}

		private BigPickupCustomHelper()
		{
		}

		public static void Setup(ItemInLevel item, BigPickupCustomization states)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			BigPickupCustomHelper bigPickupCustomHelper = ((Component)item).gameObject.GetComponent<BigPickupCustomHelper>();
			if ((Object)(object)bigPickupCustomHelper == (Object)null)
			{
				bigPickupCustomHelper = ((Component)item).gameObject.AddComponent<BigPickupCustomHelper>();
				bigPickupCustomHelper.Setup(item);
			}
			foreach (BigPickupStateEvent item2 in states.OnState)
			{
				if (!bigPickupCustomHelper.eventsOnState.TryGetValue(item2.State, out List<WardenObjectiveEventData> value))
				{
					value = new List<WardenObjectiveEventData>();
					bigPickupCustomHelper.eventsOnState[item2.State] = value;
				}
				value.AddRange(item2.EventsOnState);
			}
		}

		static BigPickupCustomHelper()
		{
			ClassInjector.RegisterTypeInIl2Cpp<BigPickupCustomHelper>();
		}
	}
	public class BigPickupCustomizationManager : TOAExpeditionDefinitionManager<BigPickups>
	{
		public static BigPickupCustomizationManager Current { get; } = new BigPickupCustomizationManager();

		protected override string DEFINITION_NAME => "BigPickupCustomization";

		private void Build(BigPickups def)
		{
			Dictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex), List<CarryItemPickup_Core>> itemsOf = BigPickupItemManager.Current.GetItemsOf(def.ItemId);
			foreach (BigPickupCustomization bigPickupItem in def.BigPickupItems)
			{
				if (!itemsOf.TryGetValue(((GlobalZoneIndex)bigPickupItem).GlobalZoneIndexTuple(), out var value))
				{
					EOSLogger.Error($"EventsOnBigPickup: zone not found {((GlobalZoneIndex)bigPickupItem).GlobalZoneIndexTuple()}");
				}
				else if (bigPickupItem.Index < 0 || bigPickupItem.Index >= value.Count)
				{
					EOSLogger.Error($"EventsOnBigPickup: itemID {def.ItemId}, index {bigPickupItem.Index} is invalid - there're {value.Count} items in {((GlobalZoneIndex)bigPickupItem).GlobalZoneIndexTuple()} - valid value falls in range [0, {value.Count - 1})");
				}
				else
				{
					CarryItemPickup_Core item = value[bigPickupItem.Index];
					BigPickupCustomHelper.Setup((ItemInLevel)(object)item, bigPickupItem);
					CustomBigPickupFunctionImplementor.SetupCustomBigPickupFunctions(((ItemInLevel)(object)item).GetLGPickupItem(), bigPickupItem.Functions);
				}
			}
		}

		private void Build()
		{
			if (definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out GenericExpeditionDefinition<BigPickups> value))
			{
				value.Definitions.ForEach(Build);
			}
		}

		public BigPickupCustomizationManager()
		{
			LevelAPI.OnBuildDone += Build;
		}
	}
}
namespace EOSExt.TacticalBigPickup.Functions.Generic.BigPickup.Definition
{
	public class BigPickupCustomization : GlobalZoneIndex
	{
		public int Index { get; set; }

		public List<BigPickupFunction> Functions { get; set; } = new List<BigPickupFunction>
		{
			new BigPickupFunction()
		};

		public List<BigPickupStateEvent> OnState { get; set; } = new List<BigPickupStateEvent>
		{
			new BigPickupStateEvent()
		};
	}
	public class BigPickups
	{
		public uint ItemId { get; set; }

		public List<BigPickupCustomization> BigPickupItems { get; set; } = new List<BigPickupCustomization>
		{
			new BigPickupCustomization()
		};
	}
	public class BigPickupStateEvent
	{
		public ePickupItemStatus State { get; set; }

		public List<WardenObjectiveEventData> EventsOnState { get; set; } = new List<WardenObjectiveEventData>();
	}
}
namespace EOSExt.TacticalBigPickup.Functions.FogBeacon.LevelSpawned
{
	public class LevelSpawnedFogBeaconSettings
	{
		public int AreaIndex { get; set; }

		public float GrowDuration { get; set; } = 10f;

		public float ShrinkDuration { get; set; } = 10f;

		public float Range { get; set; } = 11f;

		public string WorldEventObjectFilter { get; set; } = string.Empty;

		public Vec3 Position { get; set; } = new Vec3();
	}
	public class LevelSpawnedFogBeaconDefinition : GlobalZoneIndex
	{
		public List<LevelSpawnedFogBeaconSettings> SpawnedBeaconsInZone { get; set; } = new List<LevelSpawnedFogBeaconSettings>
		{
			new LevelSpawnedFogBeaconSettings()
		};
	}
	public class LevelSpawnedFogBeaconSettingManager : TOAExpeditionDefinitionManager<LevelSpawnedFogBeaconDefinition>
	{
		public enum LSFBEvent
		{
			ToggleLevelSpawnedFogBeaconState = 922
		}

		private Dictionary<IntPtr, LevelSpawnedFogBeaconSettings> LSFBGlobalStatesSet = new Dictionary<IntPtr, LevelSpawnedFogBeaconSettings>();

		public static LevelSpawnedFogBeaconSettingManager Current { get; }

		protected override string DEFINITION_NAME => "LevelSpawnedFogBeacon_EOS";

		private Dictionary<string, LevelSpawnedFogBeacon> LevelSpawnedFogBeacons { get; } = new Dictionary<string, LevelSpawnedFogBeacon>();

		private void Build(LevelSpawnedFogBeaconDefinition def)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			foreach (LevelSpawnedFogBeaconSettings item in def.SpawnedBeaconsInZone)
			{
				if (item.WorldEventObjectFilter == null || item.WorldEventObjectFilter == string.Empty || LevelSpawnedFogBeacons.ContainsKey(item.WorldEventObjectFilter))
				{
					EOSLogger.Error("LevelSpawnedFogBeaconManager: WorldEventObjectFilter '" + item.WorldEventObjectFilter + "' is either unassigned or has already been assigned.");
					continue;
				}
				LevelSpawnedFogBeacon levelSpawnedFogBeacon = LevelSpawnedFogBeacon.Instantiate(((GlobalZoneIndex)def).DimensionIndex, ((GlobalZoneIndex)def).LayerType, ((GlobalZoneIndex)def).LocalIndex, item);
				if (levelSpawnedFogBeacon != null)
				{
					LevelSpawnedFogBeacons[item.WorldEventObjectFilter] = levelSpawnedFogBeacon;
					LSFBGlobalStatesSet[((Il2CppObjectBase)levelSpawnedFogBeacon.GlobalState).Pointer] = item;
					EOSLogger.Debug($"LevelSpawnedFogBeaconManager: spawned '{item.WorldEventObjectFilter}' in {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Area_{(ushort)(65 + item.AreaIndex)}");
				}
			}
		}

		public LevelSpawnedFogBeaconSettings GetLSFBDef(HeavyFogRepellerGlobalState h)
		{
			if (!LSFBGlobalStatesSet.TryGetValue(((Il2CppObjectBase)h).Pointer, out LevelSpawnedFogBeaconSettings value))
			{
				return null;
			}
			return value;
		}

		public void ToggleLSFBState(string worldEventgObjectFilter, bool enable)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (!LevelSpawnedFogBeacons.TryGetValue(worldEventgObjectFilter, out LevelSpawnedFogBeacon value))
			{
				EOSLogger.Error("ToggleLSFBState: '" + worldEventgObjectFilter + "' is not defined");
			}
			else if (SNet.IsMaster)
			{
				value.GlobalState.AttemptInteract(new pCarryItemWithGlobalState_Interaction
				{
					type = ((!enable) ? ((byte)1) : ((byte)0)),
					owner = (eCarryItemWithGlobalStateOwner)2,
					staticPosition = value.Position
				});
			}
		}

		private void Clear()
		{
			foreach (LevelSpawnedFogBeacon value in LevelSpawnedFogBeacons.Values)
			{
				value.Destroy();
			}
			LSFBGlobalStatesSet.Clear();
			LevelSpawnedFogBeacons.Clear();
		}

		private void BuildLevelSpawnedFogBeacons()
		{
			if (definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData))
			{
				definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.ForEach(Build);
			}
		}

		private LevelSpawnedFogBeaconSettingManager()
		{
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
			LevelAPI.OnBuildDone += BuildLevelSpawnedFogBeacons;
			EOSWardenEventManager.Current.AddEventDefinition(LSFBEvent.ToggleLevelSpawnedFogBeaconState.ToString(), 922u, (Action<WardenObjectiveEventData>)ToggleLevelSpawnedFogBeaconState);
		}

		static LevelSpawnedFogBeaconSettingManager()
		{
			Current = new LevelSpawnedFogBeaconSettingManager();
		}

		private static void ToggleLevelSpawnedFogBeaconState(WardenObjectiveEventData e)
		{
			Current.ToggleLSFBState(e.WorldEventObjectFilter, e.Enabled);
		}
	}
}
namespace EOSExt.TacticalBigPickup.Functions.FogBeacon.BigPickup
{
	public class RepellerSphereSetting
	{
		public bool InfiniteDuration { get; set; }

		public float GrowDuration { get; set; } = 10f;

		public float ShrinkDuration { get; set; } = 10f;

		public float Range { get; set; } = 11f;
	}
	public class BigPickupFogBeaconSetting
	{
		public float TimeToPickup { get; set; } = 1f;

		public float TimeToPlace { get; set; } = 1f;

		public RepellerSphereSetting RSHold { get; set; } = new RepellerSphereSetting();

		public RepellerSphereSetting RSPlaced { get; set; } = new RepellerSphereSetting();
	}
	internal class BigPickupFogBeaconSettingManager : TOAGenericDefinitionManager<BigPickupFogBeaconSetting>
	{
		public static BigPickupFogBeaconSettingManager Current { get; private set; }

		protected override string DEFINITION_NAME => "BigPickupFogBeacon_EOS";

		public override void Init()
		{
		}

		private BigPickupFogBeaconSettingManager()
		{
		}

		static BigPickupFogBeaconSettingManager()
		{
			Current = new BigPickupFogBeaconSettingManager();
		}
	}
}
namespace EOSExt.TacticalBigPickup.Impl
{
	public abstract class CustomBigPickupFunctionImplementor
	{
		private static Dictionary<string, CustomBigPickupFunctionImplementor> s_implementors;

		protected abstract string FunctionName { get; }

		public static void SetupCustomBigPickupFunctions(LG_PickupItem item, List<BigPickupFunction> functions)
		{
			foreach (BigPickupFunction function in functions)
			{
				if (s_implementors.TryGetValue(function.Type, out CustomBigPickupFunctionImplementor value))
				{
					value.SetupCustomBigPickupFunction(item, function.SettingID);
					EOSLogger.Log("ICustomBigPickupFunctionImplementor: function '" + function.Type + "' applied to " + ((Object)item).name);
				}
				else
				{
					EOSLogger.Error("ICustomBigPickupFunctionImplementor: function '" + function.Type + "' not found");
				}
			}
		}

		static CustomBigPickupFunctionImplementor()
		{
			s_implementors = new Dictionary<string, CustomBigPickupFunctionImplementor>();
			foreach (Type item in from x in typeof(CustomBigPickupFunctionImplementor).Assembly.GetTypes()
				where !x.IsAbstract
				where x.IsAssignableTo(typeof(CustomBigPickupFunctionImplementor))
				select x)
			{
				CustomBigPickupFunctionImplementor customBigPickupFunctionImplementor = (CustomBigPickupFunctionImplementor)Activator.CreateInstance(item, nonPublic: true);
				if (s_implementors.TryGetValue(customBigPickupFunctionImplementor.FunctionName, out CustomBigPickupFunctionImplementor _))
				{
					EOSLogger.Error("CustomBigPickupFunctionImplementor: Duplicate " + customBigPickupFunctionImplementor.FunctionName + "!");
					continue;
				}
				EOSLogger.Log("CustomBigPickupFunctionImplementor: registered " + customBigPickupFunctionImplementor.FunctionName + "!");
				s_implementors[customBigPickupFunctionImplementor.FunctionName] = customBigPickupFunctionImplementor;
			}
		}

		public abstract void SetupCustomBigPickupFunction(LG_PickupItem item, uint settingID);
	}
}
namespace EOSExt.TacticalBigPickup.Impl.FogBeacon.LeveSpawned
{
	public class LevelSpawnedFogBeacon
	{
		public static uint LSFB_ITEM_DB_ID { get; private set; }

		public static bool HasFogBeaconItemDBDefinition => LSFB_ITEM_DB_ID != 0;

		public string WorldEventObjectFilter => def?.WorldEventObjectFilter ?? string.Empty;

		public LevelSpawnedFogBeaconSettings def { get; private set; }

		public HeavyFogRepellerGlobalState GlobalState { get; private set; }

		public LG_PickupItem LG_PickupItem { get; private set; }

		public NavMarker NavMarker { get; private set; }

		public Vector3 Position
		{
			get
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				LG_PickupItem lG_PickupItem = LG_PickupItem;
				if (lG_PickupItem == null)
				{
					return Vector3.zero;
				}
				return ((Component)lG_PickupItem).transform.position;
			}
		}

		public Color NAV_MARKER_COLOR { get; } = new Color(1f, 0.75686276f, 0.14509805f);

		public static LevelSpawnedFogBeacon Instantiate(eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex, LevelSpawnedFogBeaconSettings def)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if (!HasFogBeaconItemDBDefinition)
			{
				EOSLogger.Error("LevelSpawnedFogBeaconManager: ItemDatablock Definition of vanilla Fog Repeller Turbine is not found...");
				return null;
			}
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layer, localIndex, ref val) || (Object)(object)val == (Object)null || def.AreaIndex < 0 || def.AreaIndex >= val.m_areas.Count)
			{
				EOSLogger.Error($"LevelSpawnedFogBeacon: cannot find {(dimensionIndex, layer, localIndex)}, Area_{(ushort)(65 + def.AreaIndex)}");
				return null;
			}
			AIG_CourseNode courseNode = val.m_areas[def.AreaIndex].m_courseNode;
			return new LevelSpawnedFogBeacon(def, courseNode)
			{
				def = def
			};
		}

		internal void Destroy()
		{
			Object.Destroy((Object)(object)((Component)LG_PickupItem.m_root).gameObject);
			GlobalState = null;
			LG_PickupItem = null;
			def = null;
		}

		private LevelSpawnedFogBeacon(LevelSpawnedFogBeaconSettings def, AIG_CourseNode node)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//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)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			this.def = def;
			GameObject val = new GameObject($"LSBF_{def.WorldEventObjectFilter}-Area_{(ushort)(65 + def.AreaIndex)}");
			val.transform.SetPositionAndRotation(def.Position.ToVector3(), Quaternion.identity);
			LG_PickupItem = LG_PickupItem.SpawnGenericPickupItem(val.transform);
			LG_PickupItem.SpawnNode = node;
			int count = ((Il2CppArrayBase<Dictionary<byte, iCarryItemWithGlobalState>>)(object)CarryItemWithGlobalStateManager.Current.m_carryItemGlobalStatesInstancesPerType)[0].Count;
			LG_PickupItem.SetupAsBigPickupItem(1, LSFB_ITEM_DB_ID, false, -1);
			CarryItemPickup_Core componentInChildren = ((Component)LG_PickupItem.m_root).GetComponentInChildren<CarryItemPickup_Core>();
			LG_PickupItem_Sync val2 = ((Il2CppObjectBase)componentInChildren.m_sync).Cast<LG_PickupItem_Sync>();
			if ((Object)(object)val2 != (Object)null)
			{
				pPickupItemState state = val2.m_stateReplicator.State;
				((pCourseNode)(ref state.placement.node)).Set(LG_PickupItem.SpawnNode);
			}
			((Component)((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>()).gameObject.SetActive(false);
			iTerminalItem componentInChildren2 = ((Component)LG_PickupItem).GetComponentInChildren<iTerminalItem>();
			if (componentInChildren2 != null)
			{
				LG_LevelInteractionManager.DeregisterTerminalItem(componentInChildren2);
			}
			NavMarker = GuiManager.NavMarkerLayer.PrepareGenericMarker(((Component)LG_PickupItem).gameObject);
			if ((Object)(object)NavMarker != (Object)null)
			{
				NavMarker.SetColor(NAV_MARKER_COLOR);
				NavMarker.SetStyle((eNavMarkerStyle)14);
				NavMarker.SetVisible(false);
			}
			iCarryItemWithGlobalState val3 = default(iCarryItemWithGlobalState);
			if (!CarryItemWithGlobalStateManager.TryGetItemInstance((eCarryItemWithGlobalStateType)0, (byte)count, ref val3))
			{
				EOSLogger.Error("LevelSpawnedFogBeaconManager: Didn't find GlobalState of '" + def.WorldEventObjectFilter + "'");
				return;
			}
			GlobalState = ((Il2CppObjectBase)val3).Cast<HeavyFogRepellerGlobalState>();
			FogRepeller_Sphere repellerSphere = GlobalState.m_repellerSphere;
			repellerSphere.GrowDuration = def.GrowDuration;
			repellerSphere.ShrinkDuration = def.ShrinkDuration;
			repellerSphere.Range = def.Range;
			HeavyFogRepellerGlobalState globalState = GlobalState;
			globalState.CallbackOnStateChange += Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>.op_Implicit((Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>)delegate(pCarryItemWithGlobalState_State oldState, pCarryItemWithGlobalState_State newState, bool isRecall)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected I4, but got Unknown
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Expected O, but got Unknown
				eHeavyFogRepellerStatus val4 = (eHeavyFogRepellerStatus)newState.status;
				switch ((int)val4)
				{
				case 0:
				case 2:
					NavMarker.SetVisible(false);
					break;
				case 1:
					NavMarker.SetVisible(true);
					if (isRecall)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(new WardenObjectiveEventData
						{
							Type = (eWardenObjectiveEventType)922,
							WorldEventObjectFilter = WorldEventObjectFilter,
							Enabled = true,
							Delay = 1.1f
						}, (eWardenObjectiveEventTrigger)0, true, 0f);
					}
					break;
				}
			});
		}

		private static void FindFogTurbineItemDBID()
		{
			if (!HasFogBeaconItemDBDefinition)
			{
				LSFB_ITEM_DB_ID = ((GameDataBlockBase<ItemDataBlock>)(object)GameDataBlockBase<ItemDataBlock>.GetBlock("Carry_HeavyFogRepeller"))?.persistentID ?? 0;
				if (LSFB_ITEM_DB_ID == 0)
				{
					EOSLogger.Error("LevelSpawnedFogBeaconManager: ItemDatablock Definition of vanilla Fog Repeller Turbine is not found...");
				}
			}
		}

		static LevelSpawnedFogBeacon()
		{
			FindFogTurbineItemDBID();
			LevelAPI.OnBuildStart += FindFogTurbineItemDBID;
		}
	}
}
namespace EOSExt.TacticalBigPickup.Impl.FogBeacon.BigPickup
{
	internal class BigPickupFogBeaconImplementor : CustomBigPickupFunctionImplementor
	{
		protected override string FunctionName => "FogBeacon";

		public override void SetupCustomBigPickupFunction(LG_PickupItem item, uint settingID)
		{
			//IL_0065: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Expected O, but got Unknown
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Expected O, but got Unknown
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: 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_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			GenericDefinition<BigPickupFogBeaconSetting> definition = BigPickupFogBeaconSettingManager.Current.GetDefinition(settingID);
			if (definition == null || definition.Definition == null)
			{
				EOSLogger.Error($"BigPickupFogBeacon: setting ID {settingID} not found");
				return;
			}
			BigPickupFogBeaconSetting setting = definition.Definition;
			FogRepeller_Sphere val = new GameObject("FogInstance_Beacon_Fake").AddComponent<FogRepeller_Sphere>();
			val.InfiniteDuration = false;
			val.LifeDuration = 99999f;
			val.GrowDuration = 99999f;
			val.ShrinkDuration = 99999f;
			val.Range = 1f;
			FogRepeller_Sphere fogRepHold = new GameObject("FogInstance_Beacon_SmallLayer").AddComponent<FogRepeller_Sphere>();
			fogRepHold.InfiniteDuration = setting.RSHold.InfiniteDuration;
			fogRepHold.GrowDuration = setting.RSHold.GrowDuration;
			fogRepHold.ShrinkDuration = setting.RSHold.ShrinkDuration;
			fogRepHold.Range = setting.RSHold.Range;
			fogRepHold.Offset = Vector3.zero;
			FogRepeller_Sphere fogRepPlaced = new GameObject("FogInstance_Beacon_BigLayer").AddComponent<FogRepeller_Sphere>();
			fogRepPlaced.InfiniteDuration = setting.RSPlaced.InfiniteDuration;
			fogRepPlaced.GrowDuration = setting.RSPlaced.GrowDuration;
			fogRepPlaced.ShrinkDuration = setting.RSPlaced.ShrinkDuration;
			fogRepPlaced.Range = setting.RSPlaced.Range;
			fogRepPlaced.Offset = Vector3.zero;
			CarryItemPickup_Core componentInChildren = ((Component)item.m_root).GetComponentInChildren<CarryItemPickup_Core>();
			HeavyFogRepellerPickup val2 = ((Il2CppObjectBase)componentInChildren).Cast<HeavyFogRepellerPickup>();
			iCarryItemWithGlobalState val3 = default(iCarryItemWithGlobalState);
			byte byteId = default(byte);
			if (CarryItemWithGlobalStateManager.TryCreateItemInstance((eCarryItemWithGlobalStateType)0, item.m_root, ref val3, ref byteId))
			{
				pItemData_Custom customData = ((Item)val2).GetCustomData();
				customData.byteId = byteId;
				pItemData_Custom val4 = customData;
				((Item)val2).SetCustomData(val4, true);
			}
			HeavyFogRepellerGlobalState val5 = ((Il2CppObjectBase)val3).Cast<HeavyFogRepellerGlobalState>();
			((Component)fogRepHold).transform.SetParent(((Component)val5).transform, false);
			((Component)fogRepPlaced).transform.SetParent(((Component)val5).transform, false);
			val5.m_repellerSphere = val;
			fogRepHold.m_sphereAllocator = new FogSphereAllocator();
			fogRepPlaced.m_sphereAllocator = new FogSphereAllocator();
			Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>();
			((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
			val5.CallbackOnStateChange += Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>.op_Implicit((Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>)delegate(pCarryItemWithGlobalState_State oldState, pCarryItemWithGlobalState_State newState, bool isRecall)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Invalid comparison between Unknown and I4
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				if (isRecall)
				{
					FogRepeller_Sphere obj = fogRepHold;
					if (obj != null)
					{
						obj.KillRepellerInstantly();
					}
					FogRepeller_Sphere obj2 = fogRepPlaced;
					if (obj2 != null)
					{
						obj2.KillRepellerInstantly();
					}
				}
				else
				{
					eHeavyFogRepellerStatus val6 = (eHeavyFogRepellerStatus)newState.status;
					if ((int)val6 != 1)
					{
						if ((int)val6 == 2)
						{
							FogRepeller_Sphere obj3 = fogRepHold;
							if (obj3 != null)
							{
								obj3.StopRepelling();
							}
							FogRepeller_Sphere obj4 = fogRepPlaced;
							if (obj4 != null)
							{
								obj4.StartRepelling();
							}
							((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
						}
					}
					else
					{
						FogRepeller_Sphere obj5 = fogRepHold;
						if (obj5 != null)
						{
							obj5.StartRepelling();
						}
						if (oldState.status != 0)
						{
							FogRepeller_Sphere obj6 = fogRepPlaced;
							if (obj6 != null)
							{
								obj6.StopRepelling();
							}
						}
						((Interact_Timed)interact).InteractDuration = setting.TimeToPlace;
					}
				}
			});
		}

		internal BigPickupFogBeaconImplementor()
		{
		}
	}
}
namespace TOA_Heavy_Industries
{
	internal static class MTFOPartialDataIdResolver
	{
		private const string PartialDataPluginGuid = "MTFO.Extension.PartialBlocks";

		private const string IdFileName = "_persistentID.json";

		private static readonly object Sync = new object();

		private static Dictionary<string, uint>? _guidToId;

		private static bool _loadAttempted;

		internal static bool TryResolve(string guid, out uint id)
		{
			id = 0u;
			if (string.IsNullOrWhiteSpace(guid))
			{
				return false;
			}
			EnsureLoaded();
			lock (Sync)
			{
				return _guidToId != null && _guidToId.TryGetValue(guid.Trim(), out id);
			}
		}

		private static void EnsureLoaded()
		{
			lock (Sync)
			{
				if (_loadAttempted)
				{
					return;
				}
				_loadAttempted = true;
				try
				{
					string text = TryGetPartialDataPathFromPlugin();
					if (string.IsNullOrWhiteSpace(text))
					{
						return;
					}
					string text2 = Path.Combine(text, "_persistentID.json");
					if (File.Exists(text2))
					{
						Dictionary<string, uint> dictionary = ReadPersistentIdFile(text2);
						if (dictionary.Count > 0)
						{
							_guidToId = dictionary;
						}
					}
				}
				catch (Exception ex)
				{
					TOARuntime.LogThrottled("MTFO PartialData persistentID resolver failed: " + ex.Message);
				}
			}
		}

		private static string TryGetPartialDataPathFromPlugin()
		{
			try
			{
				if (((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value))
				{
					Assembly assembly = ((value == null) ? null : value.Instance?.GetType()?.Assembly);
					if (assembly != null && (assembly.GetTypes().FirstOrDefault((Type t) => string.Equals(t.Name, "PartialDataManager", StringComparison.Ordinal))?.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public))?.GetValue(null) is string text && !string.IsNullOrWhiteSpace(text))
					{
						return text;
					}
				}
			}
			catch
			{
			}
			return DiscoverPartialDataPathFromFileSystem();
		}

		private static string DiscoverPartialDataPathFromFileSystem()
		{
			try
			{
				foreach (string item in Directory.EnumerateFiles(Paths.PluginPath, "_persistentID.json", SearchOption.AllDirectories))
				{
					string directoryName = Path.GetDirectoryName(item);
					if (!string.IsNullOrWhiteSpace(directoryName))
					{
						return directoryName;
					}
				}
			}
			catch
			{
			}
			return string.Empty;
		}

		private static Dictionary<string, uint> ReadPersistentIdFile(string idFilePath)
		{
			Dictionary<string, uint> dictionary = new Dictionary<string, uint>(StringComparer.OrdinalIgnoreCase);
			string text = File.ReadAllText(idFilePath);
			try
			{
				using JsonDocument jsonDocument = JsonDocument.Parse(text, new JsonDocumentOptions
				{
					CommentHandling = JsonCommentHandling.Skip,
					AllowTrailingCommas = true
				});
				if (jsonDocument.RootElement.ValueKind == JsonValueKind.Array)
				{
					foreach (JsonElement item in jsonDocument.RootElement.EnumerateArray())
					{
						if (TryReadGuidEntry(item, out string guid, out uint id))
						{
							dictionary[guid] = id;
						}
					}
				}
				else if (jsonDocument.RootElement.ValueKind == JsonValueKind.Object)
				{
					foreach (JsonProperty item2 in jsonDocument.RootElement.EnumerateObject())
					{
						if (TryReadUIntElement(item2.Value, out var id2) && !string.IsNullOrWhiteSpace(item2.Name))
						{
							dictionary[item2.Name.Trim()] = id2;
						}
					}
				}
			}
			catch
			{
				foreach (Match item3 in Regex.Matches(text, "\\{[^{}]*\\\"GUID\\\"\\s*:\\s*\\\"(?<guid>(?:\\\\.|[^\\\"])*)\\\"[^{}]*\\\"ID\\\"\\s*:\\s*(?<id>\\d+)[^{}]*\\}", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant))
				{
					string text2 = TOAJsonConfig.UnescapeJsonStringForRuntime(item3.Groups["guid"].Value).Trim();
					if (!string.IsNullOrWhiteSpace(text2) && uint.TryParse(item3.Groups["id"].Value, out var result))
					{
						dictionary[text2] = result;
					}
				}
			}
			return dictionary;
		}

		private static bool TryReadGuidEntry(JsonElement entry, out string guid, out uint id)
		{
			guid = string.Empty;
			id = 0u;
			if (entry.ValueKind != JsonValueKind.Object)
			{
				return false;
			}
			foreach (JsonProperty item in entry.EnumerateObject())
			{
				if (string.Equals(item.Name, "GUID", StringComparison.OrdinalIgnoreCase) || string.Equals(item.Name, "Guid", StringComparison.OrdinalIgnoreCase) || string.Equals(item.Name, "persistentID", StringComparison.OrdinalIgnoreCase))
				{
					guid = ((item.Value.ValueKind == JsonValueKind.String) ? (item.Value.GetString() ?? string.Empty).Trim() : item.Value.ToString().Trim());
				}
				else if (string.Equals(item.Name, "ID", StringComparison.OrdinalIgnoreCase) || string.Equals(item.Name, "Id", StringComparison.OrdinalIgnoreCase))
				{
					TryReadUIntElement(item.Value, out id);
				}
			}
			if (!string.IsNullOrWhiteSpace(guid))
			{
				return id != 0;
			}
			return false;
		}

		private static bool TryReadUIntElement(JsonElement element, out uint id)
		{
			id = 0u;
			if (element.ValueKind == JsonValueKind.Number && element.TryGetUInt32(out var value))
			{
				id = value;
				return true;
			}
			if (element.ValueKind == JsonValueKind.String && uint.TryParse(element.GetString(), out var result))
			{
				id = result;
				return true;
			}
			return false;
		}
	}
	internal static class TOAConfigPaths
	{
		internal const string CustomRootFolderName = "TOA_Heavy_Industries";

		internal static string GetFeaturePath(string featureName)
		{
			return Path.Combine(GetCustomPath(), "TOA_Heavy_Industries", featureName);
		}

		internal static string GetCustomPath()
		{
			if (TryGetMTFOCustomPath(out string customPath))
			{
				return customPath;
			}
			return Path.Combine(Paths.BepInExRootPath, "Custom");
		}

		private static bool TryGetMTFOCustomPath(out string customPath)
		{
			customPath = string.Empty;
			try
			{
				Type type = FindLoadedType("MTFO.API.MTFOPathAPI");
				if (type == null)
				{
					return false;
				}
				if (type.GetProperty("CustomPath", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) is string text && !string.IsNullOrWhiteSpace(text))
				{
					customPath = Path.GetFullPath(text);
					return true;
				}
			}
			catch (Exception ex)
			{
				TOARuntime.LogThrottled("Could not read MTFOPathAPI.CustomPath, falling back to BepInEx/Custom: " + ex.Message);
			}
			return false;
		}

		private static Type? FindLoadedType(string fullName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				Type type = assemblies[i].GetType(fullName, throwOnError: false, ignoreCase: false);
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}
	}
	internal sealed class TOALevelRule
	{
		internal string Name = string.Empty;

		internal string ButtonText = string.Empty;

		internal readonly HashSet<uint> OfflineIDs = new HashSet<uint>();

		internal readonly HashSet<string> LevelLayoutIDStrings = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		internal bool HasAnySelector
		{
			get
			{
				if (OfflineIDs.Count <= 0)
				{
					return LevelLayoutIDStrings.Count > 0;
				}
				return true;
			}
		}
	}
	internal sealed class TOAConfigDocument
	{
		internal string FilePath = string.Empty;

		internal bool Enabled = true;

		internal bool EnableInstantReload;

		internal readonly List<TOALevelRule> Levels = new List<TOALevelRule>();
	}
	internal static class TOAJsonConfig
	{
		internal const string ConfigFolderName = "TOA_Heavy_Industries";

		internal const string GearSwapFeatureFolderName = "GearSwap";

		internal const string ConfigFileName = "GearSwap.json";

		internal const string ConfigSearchPattern = "*.json";

		private static readonly object _sync = new object();

		private static readonly List<TOAConfigDocument> _configs = new List<TOAConfigDocument>();

		private static readonly List<string> _configPaths = new List<string>();

		private static readonly List<FileSystemWatcher> _watchers = new List<FileSystemWatcher>();

		private static string _lastConfigStamp = string.Empty;

		private static long _reloadPending;

		private static float _nextFallbackFileCheckTime;

		internal static string ConfigPathSummary
		{
			get
			{
				lock (_sync)
				{
					return (_configPaths.Count == 0) ? "<none>" : string.Join(" | ", _configPaths);
				}
			}
		}

		internal static IReadOnlyList<TOAConfigDocument> Configs
		{
			get
			{
				lock (_sync)
				{
					return _configs.ToArray();
				}
			}
		}

		internal static bool IsInstantReloadEnabled
		{
			get
			{
				lock (_sync)
				{
					return _configs.Any((TOAConfigDocument c) => c.Enabled && c.EnableInstantReload);
				}
			}
		}

		internal static void LoadOrCreate(ManualLogSource? log, bool force = false)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				List<string> list = DiscoverExistingConfigPaths().ToList();
				if (list.Count == 0)
				{
					list = CreateDefaultConfigsInCandidateRundownFolders(log).ToList();
				}
				string text = BuildConfigStamp(list);
				if (!force && text == _lastConfigStamp)
				{
					return;
				}
				List<TOAConfigDocument> list2 = new List<TOAConfigDocument>();
				foreach (string item in list)
				{
					try
					{
						list2.Add(LoadConfigFile(item));
					}
					catch (Exception ex)
					{
						ManualLogSource val = log;
						if (val != null)
						{
							BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(46, 2, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to read TOA_Heavy_Industries JSON at ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(item);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
							}
							val.LogError(val2);
						}
					}
				}
				lock (_sync)
				{
					_configs.Clear();
					_configs.AddRange(list2);
					_configPaths.Clear();
					_configPaths.AddRange(list);
					_lastConfigStamp = text;
				}
				Interlocked.Exchange(ref _reloadPending, 0L);
				ApplyInstantReloadMode(log);
			}
			catch (Exception ex2)
			{
				ManualLogSource val = log;
				if (val != null)
				{
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(52, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load TOA_Heavy_Industries JSON config(s): ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex2);
					}
					val.LogError(val2);
				}
			}
		}

		internal static void ApplyInstantReloadMode(ManualLogSource? log)
		{
			if (IsInstantReloadEnabled)
			{
				RestartWatchers(log);
			}
			else
			{
				StopWatchers();
			}
		}

		internal static void ReloadIfChanged(ManualLogSource? log)
		{
			if (IsInstantReloadEnabled)
			{
				bool flag = Interlocked.Read(in _reloadPending) != 0;
				bool flag2 = Time.realtimeSinceStartup >= _nextFallbackFileCheckTime;
				if (flag || flag2)
				{
					_nextFallbackFileCheckTime = Time.realtimeSinceStartup + 5f;
					LoadOrCreate(log, flag);
				}
			}
		}

		private static TOAConfigDocument LoadConfigFile(string configPath)
		{
			string json = StripJsonLineComments(File.ReadAllText(configPath));
			TOAConfigDocument tOAConfigDocument = new TOAConfigDocument
			{
				FilePath = configPath,
				Enabled = ReadBool(json, "Enabled", defaultValue: true),
				EnableInstantReload = ReadBool(json, "EnableInstantReload", defaultValue: false)
			};
			TOALevelRule tOALevelRule = new TOALevelRule
			{
				Name = "MainLevelLayoutIDs",
				ButtonText = "Switch Gear"
			};
			AddUIntOrStringValue(json, "MainLevelLayoutIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings);
			if (tOALevelRule.HasAnySelector)
			{
				tOAConfigDocument.Levels.Add(tOALevelRule);
			}
			return tOAConfigDocument;
		}

		private static IEnumerable<TOALevelRule> ReadLevelRules(string json)
		{
			List<string> list = new List<string>();
			string[] array = new string[6] { "Levels", "LevelLayouts", "Rundowns", "Entries", "Groups", "AllowedLevels" };
			foreach (string propertyName in array)
			{
				string text = ExtractNamedArrayContent(json, propertyName);
				if (!string.IsNullOrWhiteSpace(text))
				{
					list.AddRange(ExtractTopLevelObjectBlocksFromArray(text));
				}
			}
			if (list.Count == 0 && json.TrimStart().StartsWith("[", StringComparison.Ordinal))
			{
				list.AddRange(ExtractTopLevelObjectBlocksFromArray(json));
			}
			foreach (string item in list)
			{
				TOALevelRule tOALevelRule = new TOALevelRule
				{
					Name = ReadString(item, "Name", string.Empty),
					ButtonText = ReadString(item, "ButtonText", "Switch Gear")
				};
				AddUIntArray(item, "OfflineIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings);
				AddUIntArray(item, "LevelLayoutIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings);
				AddUIntArray(item, "AllowedLevelLayoutIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings);
				AddUIntOrStringValue(item, "MainLevelLayoutIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings);
				AddStringArray(item, "PartialDataIDs", tOALevelRule.LevelLayoutIDStrings);
				AddStringArray(item, "PartialDataLevelLayoutIDs", tOALevelRule.LevelLayoutIDStrings);
				AddStringArray(item, "LevelLayoutIDStrings", tOALevelRule.LevelLayoutIDStrings);
				AddStringArray(item, "AllowedLevelLayoutIDStrings", tOALevelRule.LevelLayoutIDStrings);
				AddStringArray(item, "AllowedPartialDataLevelLayoutIDs", tOALevelRule.LevelLayoutIDStrings);
				AddStringArray(item, "BlockNames", tOALevelRule.LevelLayoutIDStrings);
				AddStringArray(item, "LevelLayoutNames", tOALevelRule.LevelLayoutIDStrings);
				if (tOALevelRule.HasAnySelector)
				{
					yield return tOALevelRule;
				}
			}
		}

		private static void RestartWatchers(ManualLogSource? log)
		{
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Expected O, but got Unknown
			try
			{
				StopWatchers();
				lock (_sync)
				{
					HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
					foreach (string configPath in _configPaths)
					{
						string directoryName = Path.GetDirectoryName(configPath);
						if (!string.IsNullOrWhiteSpace(directoryName) && Directory.Exists(directoryName))
						{
							hashSet.Add(directoryName);
						}
					}
					using HashSet<string>.Enumerator enumerator2 = hashSet.GetEnumerator();
					while (enumerator2.MoveNext())
					{
						FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(enumerator2.Current, "*.json")
						{
							NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime),
							IncludeSubdirectories = false,
							EnableRaisingEvents = true
						};
						fileSystemWatcher.Changed += delegate
						{
							MarkReloadPending();
						};
						fileSystemWatcher.Created += delegate
						{
							MarkReloadPending();
						};
						fileSystemWatcher.Renamed += delegate
						{
							MarkReloadPending();
						};
						fileSystemWatcher.Deleted += delegate
						{
							MarkReloadPending();
						};
						_watchers.Add(fileSystemWatcher);
					}
				}
			}
			catch (Exception ex)
			{
				if (log != null)
				{
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(84, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not start instant JSON reload watcher. Falling back to passive file checks. ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.GetType().Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val);
				}
			}
		}

		private static void StopWatchers()
		{
			lock (_sync)
			{
				foreach (FileSystemWatcher watcher in _watchers)
				{
					try
					{
						watcher.Dispose();
					}
					catch
					{
					}
				}
				_watchers.Clear();
			}
		}

		private static void MarkReloadPending()
		{
			Interlocked.Exchange(ref _reloadPending, 1L);
		}

		private static IEnumerable<string> DiscoverExistingConfigPaths()
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (string item in EnumerateFilesSafe(TOAConfigPaths.GetFeaturePath("GearSwap"), "*.json", SearchOption.TopDirectoryOnly))
			{
				hashSet.Add(Path.GetFullPath(item));
			}
			return hashSet.OrderBy<string, string>((string p) => p, StringComparer.OrdinalIgnoreCase);
		}

		private static IEnumerable<string> CreateDefaultConfigsInCandidateRundownFolders(ManualLogSource? log)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			hashSet.Add(TOAConfigPaths.GetFeaturePath("GearSwap"));
			foreach (string item in hashSet.OrderBy<string, string>((string p) => p, StringComparer.OrdinalIgnoreCase))
			{
				Directory.CreateDirectory(item);
				string path = Path.Combine(item, "GearSwap.json");
				if (!File.Exists(path))
				{
					File.WriteAllText(path, CreateDefaultJson());
				}
				yield return Path.GetFullPath(path);
			}
		}

		private static IEnumerable<string> DiscoverRundownCustomRoots()
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (string item in EnumerateDirectoriesSafe(Paths.PluginPath, "Custom", SearchOption.AllDirectories))
			{
				string fullPath = Path.GetFullPath(item);
				if (fullPath.IndexOf(Path.DirectorySeparatorChar + "TOA_Heavy_Industries" + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) < 0)
				{
					hashSet.Add(fullPath);
				}
			}
			return hashSet.OrderBy<string, string>((string p) => p, StringComparer.OrdinalIgnoreCase);
		}

		private static IEnumerable<string> EnumerateDirectoriesSafe(string root, string searchPattern, SearchOption option)
		{
			if (!Directory.Exists(root))
			{
				return Array.Empty<string>();
			}
			try
			{
				return Directory.EnumerateDirectories(root, searchPattern, option).ToArray();
			}
			catch
			{
				return Array.Empty<string>();
			}
		}

		private static IEnumerable<string> EnumerateFilesSafe(string root, string searchPattern, SearchOption option)
		{
			if (!Directory.Exists(root))
			{
				return Array.Empty<string>();
			}
			try
			{
				return (from path in Directory.EnumerateFiles(root, searchPattern, option)
					where !ShouldIgnoreConfigFile(path)
					select path).ToArray();
			}
			catch
			{
				return Array.Empty<string>();
			}
		}

		private static bool ShouldIgnoreConfigFile(string path)
		{
			string fileName = Path.GetFileName(path);
			if (!fileName.StartsWith("Template", StringComparison.OrdinalIgnoreCase) && !fileName.StartsWith("README", StringComparison.OrdinalIgnoreCase))
			{
				return fileName.StartsWith("Example", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static string GetPluginAssemblyDirectory()
		{
			try
			{
				string location = Assembly.GetExecutingAssembly().Location;
				string text = (string.IsNullOrWhiteSpace(location) ? null : Path.GetDirectoryName(location));
				if (!string.IsNullOrWhiteSpace(text))
				{
					return text;
				}
			}
			catch
			{
			}
			return Paths.PluginPath;
		}

		private static string BuildConfigStamp(IEnumerable<string> configPaths)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (string item in configPaths.OrderBy<string, string>((string p) => p, StringComparer.OrdinalIgnoreCase))
			{
				DateTime dateTime = (File.Exists(item) ? File.GetLastWriteTimeUtc(item) : DateTime.MinValue);
				long value = (File.Exists(item) ? new FileInfo(item).Length : (-1));
				stringBuilder.Append(item).Append('|').Append(dateTime.Ticks)
					.Append('|')
					.Append(value)
					.Append('\n');
			}
			return stringBuilder.ToString();
		}

		private static bool ReadBool(string json, string propertyName, bool defaultValue)
		{
			Match match = Regex.Match(json, "\\\"" + Regex.Escape(propertyName) + "\\\"\\s*:\\s*(true|false)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
			if (!match.Success)
			{
				return defaultValue;
			}
			return string.Equals(match.Groups[1].Value, "true", StringComparison.OrdinalIgnoreCase);
		}

		private static string ReadString(string json, string propertyName, string defaultValue)
		{
			Match match = Regex.Match(json, "\\\"" + Regex.Escape(propertyName) + "\\\"\\s*:\\s*\\\"(?<value>(?:\\\\.|[^\\\"])*)\\\"", RegexOptions.Singleline | RegexOptions.CultureInvariant);
			if (!match.Success)
			{
				return defaultValue;
			}
			string text = UnescapeJsonString(match.Groups["value"].Value).Trim();
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return defaultValue;
		}

		private static void AddUIntOrStringValue(string json, string propertyName, HashSet<uint> numericTarget, HashSet<string> stringTarget)
		{
			if (!TryReadScalarValue(json, propertyName, out string value))
			{
				return;
			}
			string text = value.Trim();
			if (!string.IsNullOrWhiteSpace(text))
			{
				if (uint.TryParse(text, out var result))
				{
					numericTarget.Add(result);
				}
				else
				{
					stringTarget.Add(text);
				}
			}
		}

		private static bool TryReadScalarValue(string json, string propertyName, out string value)
		{
			value = string.Empty;
			Match match = Regex.Match(json, "\\\"" + Regex.Escape(propertyName) + "\\\"\\s*:", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
			if (!match.Success)
			{
				return false;
			}
			int i;
			for (i = match.Index + match.Length; i < json.Length && char.IsWhiteSpace(json[i]); i++)
			{
			}
			if (i >= json.Length)
			{
				return false;
			}
			if (json[i] == '[' || json[i] == '{')
			{
				return false;
			}
			if (json[i] == '"')
			{
				StringBuilder stringBuilder = new StringBuilder();
				bool flag = false;
				for (i++; i < json.Length; i++)
				{
					char c = json[i];
					if (flag)
					{
						stringBuilder.Append('\\').Append(c);
						flag = false;
						continue;
					}
					switch (c)
					{
					case '\\':
						flag = true;
						break;
					case '"':
						value = UnescapeJsonString(stringBuilder.ToString());
						return true;
					default:
						stringBuilder.Append(c);
						break;
					}
				}
				return false;
			}
			int num = i;
			for (; i < json.Length && !char.IsWhiteSpace(json[i]) && json[i] != ',' && json[i] != '}' && json[i] != ']'; i++)
			{
			}
			value = json.Substring(num, i - num).Trim();
			return !string.IsNullOrWhiteSpace(value);
		}

		private static void AddUIntArray(string json, string propertyName, HashSet<uint> numericTarget, HashSet<string> stringTarget)
		{
			string text = ExtractNamedArrayContent(json, propertyName);
			if (string.IsNullOrWhiteSpace(text))
			{
				return;
			}
			foreach (string item in ReadTopLevelArrayScalarItems(text))
			{
				string text2 = item.Trim();
				if (uint.TryParse(text2, out var result))
				{
					numericTarget.Add(result);
				}
				else if (!string.IsNullOrWhiteSpace(text2))
				{
					stringTarget.Add(text2);
				}
			}
		}

		private static void AddStringArray(string json, string propertyName, HashSet<string> target)
		{
			string text = ExtractNamedArrayContent(json, propertyName);
			if (string.IsNullOrWhiteSpace(text))
			{
				return;
			}
			foreach (string item in ReadArrayStringItems(text))
			{
				string text2 = item.Trim();
				if (!string.IsNullOrWhiteSpace(text2))
				{
					target.Add(text2);
				}
			}
		}

		private static IEnumerable<string> ReadArrayStringItems(string arrayContent)
		{
			foreach (string item in ReadTopLevelArrayScalarItems(arrayContent))
			{
				if (!uint.TryParse(item.Trim(), out var _))
				{
					yield return item;
				}
			}
		}

		private static IEnumerable<string> ReadTopLevelArrayScalarItems(string arrayContent)
		{
			string text = arrayContent.Trim();
			if (text.StartsWith("[", StringComparison.Ordinal))
			{
				int num = FindMatchingBracket(text, 0, '[', ']');
				if (num > 0)
				{
					text = text.Substring(1, num - 1);
				}
			}
			bool inString = false;
			bool escaped = false;
			int objectDepth = 0;
			int arrayDepth = 0;
			int tokenStart = -1;
			StringBuilder stringBuilder = null;
			for (int i = 0; i <= text.Length; i++)
			{
				char c = ((i < text.Length) ? text[i] : ',');
				if (inString)
				{
					if (escaped)
					{
						stringBuilder?.Append('\\').Append(c);
						escaped = false;
						continue;
					}
					switch (c)
					{
					case '\\':
						escaped = true;
						break;
					case '"':
						inString = false;
						if (objectDepth == 0 && arrayDepth == 0 && stringBuilder != null)
						{
							yield return UnescapeJsonString(stringBuilder.ToString());
						}
						stringBuilder = null;
						break;
					default:
						stringBuilder?.Append(c);
						break;
					}
					continue;
				}
				switch (c)
				{
				case '"':
					inString = true;
					escaped = false;
					stringBuilder = ((objectDepth == 0 && arrayDepth == 0) ? new StringBuilder() : null);
					tokenStart = -1;
					continue;
				case '{':
					objectDepth++;
					tokenStart = -1;
					continue;
				case '}':
					if (objectDepth > 0)
					{
						objectDepth--;
					}
					tokenStart = -1;
					continue;
				case '[':
					arrayDepth++;
					tokenStart = -1;
					continue;
				case ']':
					if (arrayDepth > 0)
					{
						arrayDepth--;
					}
					tokenStart = -1;
					continue;
				}
				if (objectDepth != 0 || arrayDepth != 0)
				{
					tokenStart = -1;
				}
				else if (char.IsWhiteSpace(c) || c == ',')
				{
					if (tokenStart >= 0)
					{
						string text2 = text.Substring(tokenStart, i - tokenStart).Trim();
						if (!string.IsNullOrWhiteSpace(text2))
						{
							yield return text2;
						}
						tokenStart = -1;
					}
				}
				else if (tokenStart < 0)
				{
					tokenStart = i;
				}
			}
		}

		private static string? ExtractNamedArrayContent(string json, string propertyName)
		{
			Match match = Regex.Match(json, "\\\"" + Regex.Escape(propertyName) + "\\\"\\s*:", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
			if (!match.Success)
			{
				return null;
			}
			int num = json.IndexOf('[', match.Index + match.Length);
			if (num < 0)
			{
				return null;
			}
			int num2 = FindMatchingBracket(json, num, '[', ']');
			if (num2 <= num)
			{
				return null;
			}
			return json.Substring(num + 1, num2 - num - 1);
		}

		private static IEnumerable<string> ExtractTopLevelObjectBlocksFromArray(string arrayOrArrayContent)
		{
			string text = arrayOrArrayContent.Trim();
			if (text.StartsWith("[", StringComparison.Ordinal))
			{
				int num = FindMatchingBracket(text, 0, '[', ']');
				if (num > 0)
				{
					text = text.Substring(1, num - 1);
				}
			}
			bool inString = false;
			bool escaped = false;
			int depth = 0;
			int num2 = -1;
			for (int i = 0; i < text.Length; i++)
			{
				char c = text[i];
				if (inString)
				{
					if (escaped)
					{
						escaped = false;
						continue;
					}
					switch (c)
					{
					case '\\':
						escaped = true;
						break;
					case '"':
						inString = false;
						break;
					}
					continue;
				}
				switch (c)
				{
				case '"':
					inString = true;
					break;
				case '{':
					if (depth == 0)
					{
						num2 = i;
					}
					depth++;
					break;
				case '}':
					depth--;
					if (depth == 0 && num2 >= 0)
					{
						yield return text.Substring(num2, i - num2 + 1);
						num2 = -1;
					}
					break;
				}
			}
		}

		private static int FindMatchingBracket(string text, int openIndex, char openChar, char closeChar)
		{
			bool flag = false;
			bool flag2 = false;
			int num = 0;
			for (int i = openIndex; i < text.Length; i++)
			{
				char c = text[i];
				if (flag)
				{
					if (flag2)
					{
						flag2 = false;
						continue;
					}
					switch (c)
					{
					case '\\':
						flag2 = true;
						break;
					case '"':
						flag = false;
						break;
					}
				}
				else if (c == '"')
				{
					flag = true;
				}
				else if (c == openChar)
				{
					num++;
				}
				else if (c == closeChar)
				{
					num--;
					if (num == 0)
					{
						return i;
					}
				}
			}
			return -1;
		}

		private static string StripJsonLineComments(string json)
		{
			StringBuilder stringBuilder = new StringBuilder(json.Length);
			bool flag = false;
			bool flag2 = false;
			for (int i = 0; i < json.Length; i++)
			{
				char c = json[i];
				if (flag)
				{
					stringBuilder.Append(c);
					if (flag2)
					{
						flag2 = false;
						continue;
					}
					switch (c)
					{
					case '\\':
						flag2 = true;
						break;
					case '"':
						flag = false;
						break;
					}
					continue;
				}
				switch (c)
				{
				case '"':
					flag = true;
					stringBuilder.Append(c);
					continue;
				case '/':
					if (i + 1 < json.Length && json[i + 1] == '/')
					{
						for (; i < json.Length && json[i] != '\n'; i++)
						{
						}
						if (i < json.Length)
						{
							stringBuilder.Append(json[i]);
						}
						continue;
					}
					break;
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString();
		}

		internal static string UnescapeJsonStringForRuntime(string value)
		{
			return UnescapeJsonString(value);
		}

		private static string UnescapeJsonString(string value)
		{
			return value.Replace("\\\"", "\"").Replace("\\\\", "\\").Replace("\\/", "/")
				.Replace("\\n", "\n")
				.Replace("\\r", "\r")
				.Replace("\\t", "\t");
		}

		private static string CreateDefaultJson()
		{
			return "{\n  \"Enabled\": true,\n  \"EnableInstantReload\": false,\n  \"MainLevelLayoutIDs\": \"Level_10_L1\"\n}\n";
		}
	}
	internal static class TOATextResolver
	{
		internal static string Resolve(string text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return string.Empty;
			}
			string text2 = text.Trim();
			try
			{
				if (uint.TryParse(text2, out var result) && result != 0)
				{
					return Text.Get(result);
				}
				if (MTFOPartialDataIdResolver.TryResolve(text2, out var id) && id != 0)
				{
					return Text.Get(id);
				}
			}
			catch (Exception ex)
			{
				TOARuntime.LogThrottled("TOA text resolver failed for '" + text2 + "': " + ex.Message);
			}
			return text;
		}

		internal static string ResolveObject(object? value)
		{
			if (value == null)
			{
				return string.Empty;
			}
			try
			{
				uint num = ReadUInt(value, "Id");
				if (num != 0)
				{
					string text = Text.Get(num);
					if (!string.IsNullOrWhiteSpace(text) && !text.Equals("Localization.LocalizedText", StringComparison.Ordinal))
					{
						return text;
					}
				}
				string text2 = ReadMember(value, "UntranslatedText")?.ToString() ?? string.Empty;
				if (!string.IsNullOrWhiteSpace(text2))
				{
					return text2;
				}
				string text3 = value.ToString() ?? string.Empty;
				return text3.Equals("Localization.LocalizedText", StringComparison.Ordinal) ? string.Empty : text3;
			}
			catch (Exception ex)
			{
				TOARuntime.LogThrottled("TOA localized object resolver failed: " + ex.Message);
				return string.Empty;
			}
		}

		private static uint ReadUInt(object value, string name)
		{
			object obj = ReadMember(value, name);
			if (obj != null)
			{
				return Convert.ToUInt32(obj);
			}
			return 0u;
		}

		private static object? ReadMember(object value, string name)
		{
			Type type = value.GetType();
			object obj = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value);
			if (obj != null)
			{
				return obj;
			}
			return type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value);
		}
	}
	internal sealed class TOAEventScanComponent : MonoBehaviour
	{
		public const float UPDATE_INTERVAL = 0.3f;

		public const string VANILLA_CP_PREFAB_PATH = "Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab";

		private GameObject _root;

		private GameObject _cylinder;

		private GameObject _visual;

		private GameObject _information;

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

		private float time = float.NaN;

		private float m_colorLerpDelta;

		private const float LERP_DURATION = 0.5f;

		public GameObject Cylinder => _cylinder;

		public GameObject Visual => _visual;

		public GameObject Information => _information;

		public GameObject TextMeshProGO
		{
			get
			{
				if (Information.transform.childCount <= 0)
				{
					return Information;
				}
				return ((Component)Information.transform.GetChild(0)).gameObject;
			}
		}

		public Renderer VisualRenderer { get; private set; }

		public TextMeshPro DisplayText { get; private set; }

		private Vector3 Position => ((Component)this).gameObject.transform.position;

		public StateReplicator<TOAEventScanStatus> StateReplicator { get; private set; }

		public TOAEventScanDefinition def { get; internal set; }

		internal bool ExecuteEventsLocally { get; set; } = true;

		internal bool IsActive
		{
			get
			{
				if (StateReplicator != null)
				{
					return StateReplicator.State.Status == TOAEventScanState.Active;
				}
				return false;
			}
		}

		internal bool IsInactive
		{
			get
			{
				if (StateReplicator != null)
				{
					return StateReplicator.State.Status != TOAEventScanState.Active;
				}
				return false;
			}
		}

		public Color Color_Waiting { get; private set; }

		public Color Color_Active { get; private set; }

		private bool TryBindAssetHierarchy()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if (!TryBindLegacyHierarchy())
			{
				ManualLogSource log = TOARuntime.Log;
				if (log != null)
				{
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(108, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' asset hierarchy mismatch. Expected TOA/Legacy shape root/Cylinder+Visual(+Information). Actual=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(DescribeHierarchy(((Component)this).gameObject.transform, 4));
					}
					log.LogError(val);
				}
				return false;
			}
			DisplayText = _information.GetComponentInChildren<TextMeshPro>(true) ?? _root.GetComponentInChildren<TextMeshPro>(true);
			_visualRenderers.Clear();
			foreach (Renderer componentsInChild in _visual.GetComponentsInChildren<Renderer>(true))
			{
				if ((Object)(object)componentsInChild != (Object)null)
				{
					_visualRenderers.Add(componentsInChild);
				}
			}
			if (_visualRenderers.Count == 0)
			{
				foreach (Renderer componentsInChild2 in _root.GetComponentsInChildren<Renderer>(true))
				{
					if ((Object)(object)componentsInChild2 != (Object)null)
					{
						_visualRenderers.Add(componentsInChild2);
					}
				}
			}
			VisualRenderer = _visual.GetComponentInChildren<Renderer>(true);
			return _visualRenderers.Count > 0;
		}

		private bool TryBindLegacyHierarchy()
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			if (((Component)this).gameObject.transform.childCount == 0)
			{
				return false;
			}
			_root = ((Component)((Component)this).gameObject.transform.GetChild(0)).gameObject;
			if (_root.transform.childCount >= 3)
			{
				_cylinder = ((Component)_root.transform.GetChild(0)).gameObject;
				_visual = ((Component)_root.transform.GetChild(1)).gameObject;
				_information = ((Component)_root.transform.GetChild(2)).gameObject;
				return true;
			}
			if (_root.transform.childCount >= 2)
			{
				_cylinder = ((Component)_root.transform.GetChild(0)).gameObject;
				_visual = ((Component)_root.transform.GetChild(1)).gameObject;
				_information = EnsureInformationObject(_root.transform);
				ManualLogSource log = TOARuntime.Log;
				if (log != null)
				{
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(123, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' asset has no Information child. A TOA Information container was created so the Legacy EventScan logic can run.");
					}
					log.LogWarning(val);
				}
				return true;
			}
			return false;
		}

		private static GameObject EnsureInformationObject(Transform root)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			for (int i = 0; i < root.childCount; i++)
			{
				Transform child = root.GetChild(i);
				if ((Object)(object)child != (Object)null && ((Object)child).name.IndexOf("Information", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return ((Component)child).gameObject;
				}
			}
			GameObject val = new GameObject("Information");
			val.transform.SetParent(root, false);
			return val;
		}

		private static string DescribeHierarchy(Transform transform, int depth)
		{
			if (depth <= 0 || (Object)(object)transform == (Object)null)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(((Object)transform).name);
			stringBuilder.Append('(');
			stringBuilder.Append(transform.childCount);
			stringBuilder.Append(')');
			if (transform.childCount > 0)
			{
				stringBuilder.Append(": ");
				for (int i = 0; i < transform.childCount; i++)
				{
					if (i > 0)
					{
						stringBuilder.Append(", ");
					}
					stringBuilder.Append(DescribeHierarchy(transform.GetChild(i), depth - 1));
				}
			}
			return stringBuilder.ToString();
		}

		public void Setup()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Expected O, but got Unknown
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ee: Expected O, but got Unknown
			if (def == null)
			{
				ManualLogSource? log = TOARuntime.Log;
				if (log != null)
				{
					log.LogError((object)"EventScan Setup: assign a EventScanDefinition before calling Setup()!");
				}
				return;
			}
			((Component)this).gameObject.transform.SetPositionAndRotation(def.Position.ToVector3(), Quaternion.identity);
			bool flag = default(bool);
			ManualLogSource log2;
			if (!TryBindAssetHierarchy())
			{
				log2 = TOARuntime.Log;
				if (log2 != null)
				{
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(137, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' setup failed because the TOA EventScan AssetBundle prefab does not expose the required TOA/Legacy EventScan visual children.");
					}
					log2.LogError(val);
				}
				return;
			}
			((Component)this).gameObject.SetActiveRecursively(true);
			if ((Object)(object)DisplayText == (Object)null && def.ShowDisplayText)
			{
				TryCreateDisplayTextFromVanillaCP();
			}
			if ((Object)(object)DisplayText != (Object)null)
			{
				if (def.ShowDisplayText)
				{
					((TMP_Text)DisplayText).SetText(LocalizedText.op_Implicit(def.DisplayText), true);
					((TMP_Text)DisplayText).ForceMeshUpdate(false, false);
					Information.SetActive(true);
					((Component)DisplayText).gameObject.SetActive(true);
				}
				else
				{
					foreach (TMP_Text componentsInChild in _root.GetComponentsInChildren<TMP_Text>(true))
					{
						if ((Object)(object)componentsInChild != (Object)null)
						{
							componentsInChild.SetText(string.Empty, true);
							((Component)componentsInChild).gameObject.SetActive(false);
						}
					}
					Information.SetActive(false);
				}
			}
			else if (def.ShowDisplayText)
			{
				log2 = TOARuntime.Log;
				if (log2 != null)
				{
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(122, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(def.WorldEventObjectFilter);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' has ShowDisplayText=true but neither TOA EventScan nor vanilla CP text could provide a TextMeshPro component.");
					}
					log2.LogWarning(val2);
				}
			}
			log2 = TOARuntime.Log;
			if (log2 != null)
			{
				BepInExMessageLogInterpolatedStringHandler val3 = new BepInExMessageLogInterpolatedStringHandler(65, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("EventScan '");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(def.WorldEventObjectFilter);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': using TOA EventScan AssetBundle prefab at ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Vector3>(((Component)this).gameObject.transform.position);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" radius=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(def.Radius);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(".");
				}
				log2.LogMessage(val3);
			}
			log2 = TOARuntime.Log;
			if (log2 != null)
			{
				BepInExMessageLogInterpolatedStringHandler val3 = new BepInExMessageLogInterpolatedStringHandler(80, 6, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("EventScan '");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(def.WorldEventObjectFilter);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': bound Root='");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(((Object)_root).name);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', Visual='");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(((Object)_visual).name);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', Cylinder='");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(((Object)_cylinder).name);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', Information='");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(((Object)_information).name);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', Renderers=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(_visualRenderers.Count);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(".");
				}
				log2.LogMessage(val3);
			}
			TOAVec3 waiting = def.ColorSetting.Waiting;
			TOAVec3 active = def.ColorSetting.Active;
			Color_Waiting = new Color(waiting.x, waiting.y, waiting.z);
			Color_Active = new Color(active.x, active.y, active.z);
			float num = 0.16216217f;
			float num2 = Mathf.Max(0.01f, def.Radius);
			((Component)this).gameObject.transform.localScale = new Vector3(num2, num2, num2);
			Transform transform = ((Component)this).gameObject.transform;
			transform.localPosition += Vector3.up * num;
			SetVisualColor(Color_Waiting);
			uint num3 = EOSNetworking.AllotReplicatorID();
			if (num3 == 0)
			{
				TOANetworkStateAudit.Current.ReplicatorFailed("EventScan:" + def.WorldEventObjectFilter, "Replicator ID depleted");
				ManualLogSource? log3 = TOARuntime.Log;
				if (log3 != null)
				{
					log3.LogError((object)"EventScan: Replicator ID depleted, cannot setup");
				}
				return;
			}
			StateReplicator = TOAStateReplicatorCompat.Create(num3, new TOAEventScanStatus
			{
				Status = TOAEventScanState.Waiting
			}, (LifeTimeType)1, "EventScan:" + def.WorldEventObjectFilter);
			if (StateReplicator == null)
			{
				TOANetworkStateAudit.Current.ReplicatorFailed("EventScan:" + def.WorldEventObjectFilter, "StateReplicator creation failed");
				log2 = TOARuntime.Log;
				if (log2 != null)
				{
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(57, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan:");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": StateReplicator creation failed, cannot setup");
					}
					log2.LogError(val);
				}
			}
			else
			{
				StateReplicator.OnStateChanged += OnStateChange;
				TOANetworkStateAudit.Current.ReplicatorCreated("EventScan:" + def.WorldEventObjectFilter, num3, "Level");
			}
		}

		private void TryCreateDisplayTextFromVanillaCP()
		{
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				GameObject loadedAsset = AssetAPI.GetLoadedAsset<GameObject>("Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab");
				if ((Object)(object)loadedAsset == (Object)null || loadedAsset.transform.childCount == 0)
				{
					ManualLogSource log = TOARuntime.Log;
					if (log != null)
					{
						BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(83, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' could not clone display text because vanilla CP prefab was not loaded.");
						}
						log.LogWarning(val);
					}
					return;
				}
				Transform child = loadedAsset.transform.GetChild(0);
				if (child.childCount <= 1)
				{
					ManualLogSource log = TOARuntime.Log;
					if (log != null)
					{
						BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(92, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' could not clone display text because vanilla CP prefab hierarchy is unexpected.");
						}
						log.LogWarning(val);
					}
				}
				else
				{
					GameObject val2 = Object.Instantiate<GameObject>(((Component)child.GetChild(1)).gameObject);
					((Object)val2).name = "TOA_EventScan_DisplayText";
					val2.transform.SetParent(_information.transform, false);
					float num = Mathf.Max(0.01f, def.Radius);
					val2.transform.localScale = new Vector3(1f / num, 1f / num, 1f / num);
					DisplayText = val2.GetComponentInChildren<TextMeshPro>(true);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = TOARuntime.Log;
				if (log != null)
				{
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(61, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' failed to clone display text from vanilla CP: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.GetType().Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val);
				}
			}
		}

		private void SetVisualColor(Color color)
		{
			//IL_0050: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			if (_visualRenderers.Count == 0)
			{
				return;
			}
			foreach (Renderer visualRenderer in _visualRenderers)
			{
				if ((Object)(object)visualRenderer == (Object)null)
				{
					continue;
				}
				Material material = visualRenderer.material;
				if (!((Object)(object)material == (Object)null))
				{
					if (material.HasProperty("_ColorA"))
					{
						material.SetColor("_ColorA", color);
					}
					if (material.HasProperty("_Color"))
					{
						material.SetColor("_Color", color);
					}
					material.color = color;
				}
			}
		}

		private void OnStateChange(TOAEventScanStatus oldState, TOAEventScanStatus newState, bool isRecall)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = TOARuntime.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(15, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<TOAEventScanState>(oldState.Status);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" => ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<TOAEventScanState>(newState.Status);
				}
				log.LogWarning(val);
			}
			if (isRecall)
			{
				TOANetworkStateAudit.Current.StateRecall("EventScan:" + def.WorldEventObjectFilter, oldState.Status.ToString(), newState.Status.ToString());
			}
			switch (newState.Status)
			{
			case TOAEventScanState.Disabled:
			{
				m_colorLerpDelta = 0f;
				TextMeshPro displayText3 = DisplayText;
				if (displayText3 != null)
				{
					((Component)displayText3).gameObject.SetActive(false);
				}
				Information.SetActive(false);
				Cylinder.SetActive(false);
				CoroutineManager.BlinkOut(Visual, 0f);
				break;
			}
			case TOAEventScanState.Waiting:
				if (!Visual.active)
				{
					CoroutineManager.BlinkIn(Visual, 0f);
					Cylinder.SetActive(true);
					if (def.ShowDisplayText)
					{
						Information.SetActive(true);
						TextMeshPro displayText2 = DisplayText;
						if (displayText2 != null)
						{
							((Component)displayText2).gameObject.SetActive(true);
						}
					}
				}
				if (!isRecall && ExecuteEventsLocally && oldState.Status == TOAEventScanState.Active)
				{
					using (TOAType2003TriggerScope.PushRadius("TOA_EventScan_Deactivate", Position, def.Radius))
					{
						ExecuteConfiguredEvents(def.EventsOnDeactivate, "Deactivate");
					}
				}
				break;
			case TOAEventScanState.Active:
				if (!Visual.active)
				{
					CoroutineManager.BlinkIn(Visual, 0f);
					Cylinder.SetActive(true);
					if (def.ShowDisplayText)
					{
						Information.SetActive(true);
						TextMeshPro displayText = DisplayText;
						if (displayText != null)
						{
							((Component)displayText).gameObject.SetActive(true);
						}
					}
				}
				if (!isRecall && ExecuteEventsLocally && oldState.Status == TOAEventScanState.Waiting)
				{
					using (TOAType2003TriggerScope.PushRadius("TOA_EventScan_Activate", Position, def.Radius))
					{
						ExecuteConfiguredEvents(def.EventsOnActivate, "Activate");
					}
				}
				break;
			}
			TOAEventScanManager.Current.EvaluateIndexGroups(!isRecall);
		}

		private void ExecuteConfiguredEvents(List<WardenObjectiveEventData> events, string transition)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			bool flag = default(bool);
			foreach (WardenObjectiveEventData @event in events)
			{
				ManualLogSource log = TOARuntime.Log;
				if (log != null)
				{
					BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(86, 4, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(transition);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": dispatching configured vanilla/custom event. Filter='");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(@event.WorldEventObjectFilter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', Count=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(@event.Count);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Duration=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(@event.Duration, "0.###");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
					}
					log.LogMessage(val);
				}
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(@event, (eWardenObjectiveEventTrigger)0, true, 0f);
			}
		}

		public void ChangeToState(TOAEventScanState newState)
		{
			ChangedToStateUnsynced(newState);
			if (StateReplicator != null && TOANetworkStateAudit.Current.CanMasterWrite("EventScan:" + def.WorldEventObjectFilter, $"SetState:{newState}"))
			{
				StateReplicator.SetState(new TOAEventScanStatus
				{
					Status = newState
				});
			}
		}

		private void ChangedToStateUnsynced(TOAEventScanState newState)
		{
		}

		private void Update()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: 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_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Invalid comparison between Unknown and I4
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: 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_023c: Expected O, but got Unknown
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			if (StateReplicator == null)
			{
				return;
			}
			TOAEventScanState status = StateReplicator.State.Status;
			if (status == TOAEventScanState.Disabled)
			{
				return;
			}
			float num = Clock.Delta / 0.5f;
			if (status == TOAEventScanState.Waiting)
			{
				num = 0f - num;
			}
			float colorLerpDelta = m_colorLerpDelta;
			m_colorLerpDelta = Mathf.Clamp01(m_colorLerpDelta + num);
			if (!Mathf.Approximately(colorLerpDelta, m_colorLerpDelta))
			{
				Color visualColor = Color.Lerp(Color_Waiting, Color_Active, Mathf.Pow(m_colorLerpDelta, 5f));
				SetVisualColor(visualColor);
			}
			if (!float.IsNaN(time) && Clock.Time < time + 0.3f)
			{
				return;
			}
			time = Clock.Time + 0.3f;
			if (def.ActiveCondition.RequiredPlayerCount == 0 && def.ActiveCondition.RequiredBigPickupIndices.Count == 0)
			{
				return;
			}
			bool flag = false;
			bool flag2 = false;
			Vector3 val;
			if (def.ActiveCondition.RequiredPlayerCount > 0)
			{
				int num2 = 0;
				Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
				while (enumerator.MoveNext())
				{
					PlayerAgent current = enumerator.Current;
					if (!((Object)(object)current != (Object)null) || !((Agent)current).Alive)
					{
						continue;
					}
					val = Position - ((Agent)current).Position;
					if (((Vector3)(ref val)).magnitude < def.Radius)
					{
						num2++;
						if (num2 >= def.ActiveCondition.RequiredPlayerCount)
						{
							flag = true;
							break;
						}
					}
				}
			}
			else
			{
				flag = true;
			}
			if (flag)
			{
				List<int> requiredBigPickupIndices = def.ActiveCondition.RequiredBigPickupIndices;
				if (requiredBigPickupIndices.Count > 0)
				{
					int num3 = 0;
					bool flag3 = default(bool);
					foreach (int item in requiredBigPickupIndices)
					{
						CarryItemPickup_Core bigPickupItem = PuzzleReqItemManager.Current.GetBigPickupItem(item);
						if ((Object)(object)bigPickupItem == (Object)null)
						{
							num3++;
							continue;
						}
						pPickupItemState currentState = bigPickupItem.m_sync.GetCurrentState();
						Vector3 zero = Vector3.zero;
						ePickupItemStatus status2 = currentState.status;
						if ((int)status2 != 0)
						{
							if ((int)status2 != 1)
							{
								ManualLogSource log = TOARuntime.Log;
								if (log != null)
								{
									BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag3);
									if (flag3)
									{
										((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Item has invalid state: ");
										((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<ePickupItemStatus>(currentState.status);
									}
									log.LogError(val2);
								}
								continue;
							}
							zero = ((Component)bigPickupItem.PickedUpByPlayer).transform.position;
						}
						else
						{
							zero = ((Component)bigPickupItem).transform.position;
						}
						val = Position - zero;
						if (((Vector3)(ref val)).magnitude < def.Radius)
						{
							num3++;
						}
					}
					flag2 = num3 >= requiredBigPickupIndices.Count;
				}
				else
				{
					flag2 = true;
				}
			}
			switch (status)
			{
			case TOAEventScanState.Waiting:
				if (flag && flag2)
				{
					ChangeToState(TOAEventScanState.Active);
				}
				break;
			case TOAEventScanState.Active:
				if (!flag || !flag2)
				{
					ChangeToState(TOAEventScanState.Waiting);
				}
				break;
			}
		}

		private void OnDestroy()
		{
			def = null;
			VisualRenderer = null;