Decompiled source of ExtraObjectiveSetup M v0.1.1

plugins/Inas07.ExtraObjectiveSetup.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using AIGraph;
using AK;
using Agents;
using AmorLib.Dependencies;
using AmorLib.Networking.StateReplicators;
using AmorLib.Utils;
using AmorLib.Utils.JsonElementConverters;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using ChainedPuzzles;
using Enemies;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.BaseClasses.CustomTerminalDefinition;
using ExtraObjectiveSetup.Expedition;
using ExtraObjectiveSetup.Expedition.Gears;
using ExtraObjectiveSetup.Expedition.IndividualGeneratorGroup;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Instances;
using ExtraObjectiveSetup.Instances.ChainedPuzzle;
using ExtraObjectiveSetup.JSON;
using ExtraObjectiveSetup.Objectives.ActivateSmallHSU;
using ExtraObjectiveSetup.Objectives.GeneratorCluster;
using ExtraObjectiveSetup.Objectives.IndividualGenerator;
using ExtraObjectiveSetup.Objectives.ObjectiveCounter;
using ExtraObjectiveSetup.Objectives.TerminalUplink;
using ExtraObjectiveSetup.Tweaks.BossEvents;
using ExtraObjectiveSetup.Tweaks.Scout;
using ExtraObjectiveSetup.Tweaks.TerminalPosition;
using ExtraObjectiveSetup.Tweaks.TerminalTweak;
using ExtraObjectiveSetup.Utils;
using GTFO.API;
using GTFO.API.Extensions;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using MTFO.API;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using StateMachines;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Inas07.ExtraObjectiveSetup")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4c41a207dfaa6ad7f7c49b30d46675feaa6c9188")]
[assembly: AssemblyProduct("Inas07.ExtraObjectiveSetup")]
[assembly: AssemblyTitle("Inas07.ExtraObjectiveSetup")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ExtraObjectiveSetup
{
	public static class EOSNetworking
	{
		public const uint INVALID_ID = 0u;

		public const uint FOREVER_REPLICATOR_ID_START = 1000u;

		public const uint REPLICATOR_ID_START = 10000u;

		private static uint currentForeverID;

		private static uint currentID;

		private static HashSet<uint> foreverUsedIDs;

		private static HashSet<uint> usedIDs;

		public static uint AllotReplicatorID()
		{
			while (currentID >= 10000 && usedIDs.Contains(currentID))
			{
				currentID++;
			}
			if (currentID < 10000)
			{
				EOSLogger.Error("Replicator ID depleted. How?");
				return 0u;
			}
			uint num = currentID;
			usedIDs.Add(num);
			currentID++;
			return num;
		}

		public static bool TryAllotID(uint id)
		{
			return usedIDs.Add(id);
		}

		public static uint AllotForeverReplicatorID()
		{
			while (currentForeverID < 10000 && foreverUsedIDs.Contains(currentForeverID))
			{
				currentForeverID++;
			}
			if (currentForeverID >= 10000)
			{
				EOSLogger.Error("Forever Replicator ID depleted.");
				return 0u;
			}
			uint num = currentForeverID;
			foreverUsedIDs.Add(num);
			currentForeverID++;
			return num;
		}

		private static void Clear()
		{
			usedIDs.Clear();
			currentID = 10000u;
		}

		public static void ClearForever()
		{
			foreverUsedIDs.Clear();
			currentForeverID = 1000u;
		}

		static EOSNetworking()
		{
			currentForeverID = 1000u;
			currentID = 10000u;
			foreverUsedIDs = new HashSet<uint>();
			usedIDs = new HashSet<uint>();
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}
	}
	public sealed class BatchBuildManager
	{
		private Dictionary<BatchName, Action> OnBatchStart = new Dictionary<BatchName, Action>();

		private Dictionary<BatchName, Action> OnBatchDone = new Dictionary<BatchName, Action>();

		public static BatchBuildManager Current { get; private set; }

		public void Init()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (OnBatchStart.Count < 1)
			{
				foreach (object value in Enum.GetValues(typeof(BatchName)))
				{
					OnBatchStart[(BatchName)value] = null;
				}
			}
			if (OnBatchDone.Count >= 1)
			{
				return;
			}
			foreach (object value2 in Enum.GetValues(typeof(BatchName)))
			{
				OnBatchDone[(BatchName)value2] = null;
			}
		}

		public void Add_OnBatchDone(BatchName batchName, Action action)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<BatchName, Action> onBatchDone = OnBatchDone;
			onBatchDone[batchName] = (Action)Delegate.Combine(onBatchDone[batchName], action);
		}

		public void Remove_OnBatchDone(BatchName batchName, Action action)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<BatchName, Action> onBatchDone = OnBatchDone;
			onBatchDone[batchName] = (Action)Delegate.Remove(onBatchDone[batchName], action);
		}

		public Action Get_OnBatchDone(BatchName batchName)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return OnBatchDone[batchName];
		}

		public void Add_OnBatchStart(BatchName batchName, Action action)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<BatchName, Action> onBatchStart = OnBatchStart;
			onBatchStart[batchName] = (Action)Delegate.Combine(onBatchStart[batchName], action);
		}

		public void Remove_OnBatchStart(BatchName batchName, Action action)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<BatchName, Action> onBatchStart = OnBatchStart;
			onBatchStart[batchName] = (Action)Delegate.Remove(onBatchStart[batchName], action);
		}

		public Action Get_OnBatchStart(BatchName batchName)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return OnBatchStart[batchName];
		}

		private BatchBuildManager()
		{
		}

		static BatchBuildManager()
		{
			Current = new BatchBuildManager();
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.ExtraObjectiveSetup", "ExtraObjectiveSetup", "1.8.0")]
	[BepInIncompatibility("Amor.ExcellentObjectiveSetup")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "ExtraObjectiveSetup";

		public const string VERSION = "1.8.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			m_Harmony = new Harmony("ExtraObjectiveSetup");
			m_Harmony.PatchAll();
			SetupManagers();
		}

		private void SetupManagers()
		{
			LocalPlayer.Init();
			BatchBuildManager.Current.Init();
			SerialGeneratorManager.Init();
			IndividualGeneratorObjectiveManager.Current.Init();
			GeneratorClusterObjectiveManager.Current.Init();
			HSUActivatorObjectiveManager.Current.Init();
			UplinkObjectiveManager.Current.Init();
			TerminalPositionOverrideManager.Current.Init();
			ScoutScreamEventManager.Current.Init();
			BossDeathEventManager.Current.Init();
			ExpeditionDefinitionManager.Current.Init();
			ExpeditionGearManager.Current.Init();
			ExpeditionIGGroupManager.Current.Init();
			GeneratorClusterInstanceManager.Current.Init();
			HSUActivatorInstanceManager.Current.Init();
			PowerGeneratorInstanceManager.Current.Init();
			TerminalInstanceManager.Current.Init();
			ObjectiveCounterManager.Current.Init();
		}
	}
}
namespace ExtraObjectiveSetup.Utils
{
	public static class EOSTerminalUtils
	{
		public static List<LG_ComputerTerminal> FindTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, Predicate<LG_ComputerTerminal> predicate)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val) || (Object)(object)val == (Object)null)
			{
				EOSLogger.Error($"SelectTerminal: Could NOT find zone {(dimensionIndex, layerType, localIndex)}");
				return null;
			}
			if (val.TerminalsSpawnedInZone.Count <= 0)
			{
				EOSLogger.Error($"SelectTerminal: Could not find any terminals in zone {(dimensionIndex, layerType, localIndex)}");
				return null;
			}
			List<LG_ComputerTerminal> list = new List<LG_ComputerTerminal>();
			Enumerator<LG_ComputerTerminal> enumerator = val.TerminalsSpawnedInZone.GetEnumerator();
			while (enumerator.MoveNext())
			{
				LG_ComputerTerminal current = enumerator.Current;
				if (predicate != null)
				{
					if (predicate(current))
					{
						list.Add(current);
					}
				}
				else
				{
					list.Add(current);
				}
			}
			return list;
		}

		public static TerminalLogFileData GetLocalLog(this LG_ComputerTerminal terminal, string logName)
		{
			Dictionary<string, TerminalLogFileData> localLogs = terminal.GetLocalLogs();
			logName = logName.ToUpperInvariant();
			return localLogs.ContainsKey(logName) ? localLogs[logName] : null;
		}

		public static void ResetInitialOutput(this LG_ComputerTerminal terminal)
		{
			terminal.m_command.ClearOutputQueueAndScreenBuffer();
			terminal.m_command.AddInitialTerminalOutput();
			if (terminal.IsPasswordProtected)
			{
				terminal.m_command.AddPasswordProtectedOutput((Il2CppStringArray)null);
			}
		}

		public static List<WardenObjectiveEventData> GetUniqueCommandEvents(this LG_ComputerTerminal terminal, string command)
		{
			List<WardenObjectiveEventData> result = new List<WardenObjectiveEventData>();
			if ((Object)(object)terminal.ConnectedReactor != (Object)null)
			{
				return result;
			}
			List<LG_ComputerTerminal> terminalsSpawnedInZone = terminal.SpawnNode.m_zone.TerminalsSpawnedInZone;
			int num = terminalsSpawnedInZone.IndexOf(terminal);
			AIG_CourseNode spawnNode = terminal.SpawnNode;
			ExpeditionZoneData val = ((spawnNode != null) ? spawnNode.m_zone.m_settings.m_zoneData : null) ?? null;
			if (val == null)
			{
				EOSLogger.Error("GetCommandEvents: Cannot find target zone data.");
				return result;
			}
			if (num < 0 || num >= val.TerminalPlacements.Count)
			{
				EOSLogger.Debug($"GetCommandEvents: TerminalDataIndex({num}), TargetZoneData.TerminalPlacements.Count == ({val.TerminalPlacements.Count}) - maybe a custom terminal, skipped");
				return result;
			}
			List<CustomTerminalCommand> uniqueCommands = val.TerminalPlacements[num].UniqueCommands;
			Enumerator<CustomTerminalCommand> enumerator = uniqueCommands.GetEnumerator();
			while (enumerator.MoveNext())
			{
				CustomTerminalCommand current = enumerator.Current;
				if (current.Command.ToLower().Equals(command.ToLower()))
				{
					return current.CommandEvents.ToManaged<WardenObjectiveEventData>();
				}
			}
			EOSLogger.Error("GetCommandEvents: command '" + command + "' not found on " + terminal.ItemKey);
			return result;
		}

		public static LG_ComputerTerminal SelectPasswordTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, eSeedType seedType, int staticSeed = 1)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected I4, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)seedType == 0)
			{
				EOSLogger.Error($"SelectTerminal: unsupported seed type {seedType}");
				return null;
			}
			List<LG_ComputerTerminal> list = FindTerminal(dimensionIndex, layerType, localIndex, (LG_ComputerTerminal x) => !x.HasPasswordPart);
			if (list == null)
			{
				EOSLogger.Error($"SelectTerminal: Could not find zone {(dimensionIndex, layerType, localIndex)}!");
				return null;
			}
			if (list.Count <= 0)
			{
				EOSLogger.Error($"SelectTerminal: Could not find any terminals without a password part in zone {(dimensionIndex, layerType, localIndex)}, putting the password on random (session) already used terminal.");
				LG_Zone val = default(LG_Zone);
				Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val);
				return val.TerminalsSpawnedInZone[Builder.SessionSeedRandom.Range(0, val.TerminalsSpawnedInZone.Count, "NO_TAG")];
			}
			switch (seedType - 1)
			{
			case 0:
				return list[Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG")];
			case 1:
				return list[Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG")];
			case 2:
				Random.InitState(staticSeed);
				return list[Random.Range(0, list.Count)];
			default:
				EOSLogger.Error("SelectTerminal: did not have a valid SeedType!!");
				return null;
			}
		}

		public static void BuildPassword(LG_ComputerTerminal terminal, TerminalPasswordData data)
		{
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Invalid comparison between Unknown and I4
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0589: Expected O, but got Unknown
			//IL_058c: Expected O, but got Unknown
			if (!data.PasswordProtected)
			{
				return;
			}
			if (terminal.IsPasswordProtected)
			{
				EOSLogger.Error("EOSTerminalUtils.BuildPassword: " + terminal.PublicName + " is already password-protected!");
				return;
			}
			if (!data.GeneratePassword)
			{
				terminal.LockWithPassword(data.Password, new string[1] { data.PasswordHintText });
				return;
			}
			if (data.TerminalZoneSelectionDatas.Count <= 0)
			{
				EOSLogger.Error($"Tried to generate a password for terminal {terminal.PublicName} with no {typeof(TerminalZoneSelectionData).Name}!! This is not allowed.");
				return;
			}
			string codeWord = SerialGeneratorManager.GetCodeWord(data.PasswordWordLength);
			string passwordHintText = data.PasswordHintText;
			string text = "<b>[Forgot your password?]</b> Backup security key(s) located in logs on ";
			int num = data.PasswordPartCount;
			if (codeWord.Length % num != 0)
			{
				EOSLogger.Error($"Build() password.Length ({codeWord.Length}) not divisible by passwordParts ({num}). Defaulting to 1.");
				num = 1;
			}
			string[] array = ((num > 1) ? Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)StringUtils.SplitIntoChunksArray(codeWord, codeWord.Length / num)) : new string[1] { codeWord });
			string text2 = "";
			if (data.ShowPasswordPartPositions)
			{
				for (int i = 0; i < array[0].Length; i++)
				{
					text2 += "-";
				}
			}
			HashSet<LG_ComputerTerminal> hashSet = new HashSet<LG_ComputerTerminal>();
			LG_Zone val = default(LG_Zone);
			for (int j = 0; j < num; j++)
			{
				int index = j % data.TerminalZoneSelectionDatas.Count;
				List<CustomTerminalZoneSelectionData> list = data.TerminalZoneSelectionDatas[index];
				int index2 = Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG");
				CustomTerminalZoneSelectionData customTerminalZoneSelectionData = list[index2];
				LG_ComputerTerminal val2;
				if ((int)customTerminalZoneSelectionData.SeedType == 0)
				{
					if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(customTerminalZoneSelectionData.DimensionIndex, customTerminalZoneSelectionData.LayerType, customTerminalZoneSelectionData.LocalIndex, ref val) || (Object)(object)val == (Object)null)
					{
						EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find zone {customTerminalZoneSelectionData.GlobalZoneIndexTuple()}");
					}
					if (val.TerminalsSpawnedInZone.Count <= 0)
					{
						EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find terminal zone {customTerminalZoneSelectionData.GlobalZoneIndexTuple()}");
					}
					val2 = val.TerminalsSpawnedInZone[customTerminalZoneSelectionData.TerminalIndex];
				}
				else
				{
					val2 = SelectPasswordTerminal(customTerminalZoneSelectionData.DimensionIndex, customTerminalZoneSelectionData.LayerType, customTerminalZoneSelectionData.LocalIndex, customTerminalZoneSelectionData.SeedType);
				}
				if ((Object)(object)val2 == (Object)null)
				{
					EOSLogger.Error($"BuildPassword: CRITICAL ERROR, could not get a LG_ComputerTerminal for password part ({j + 1}/{num}) for {terminal.PublicName} backup log.");
					continue;
				}
				string text3 = "";
				string text4;
				if (data.ShowPasswordPartPositions)
				{
					for (int k = 0; k < j; k++)
					{
						text3 += text2;
					}
					text4 = text3 + array[j];
					for (int l = j; l < num - 1; l++)
					{
						text4 += text2;
					}
				}
				else
				{
					text4 = array[j];
				}
				string value = (data.ShowPasswordPartPositions ? $"0{j + 1}" : $"0{Builder.SessionSeedRandom.Range(0, 9, "NO_TAG")}");
				TerminalLogFileData val3 = new TerminalLogFileData
				{
					FileName = $"key{value}_{LG_TerminalPasswordLinkerJob.GetTerminalNumber(terminal)}{(val2.HasPasswordPart ? "_1" : "")}.LOG",
					FileContent = new LocalizedText
					{
						UntranslatedText = string.Format(Text.Get((num > 1) ? 1431221909u : 2260297836u), text4),
						Id = 0u
					}
				};
				val2.AddLocalLog(val3, true);
				if (!hashSet.Contains(val2))
				{
					if (j > 0)
					{
						text += ", ";
					}
					text = text + val2.PublicName + " in " + val2.SpawnNode.m_zone.AliasName;
				}
				hashSet.Add(val2);
				val2.HasPasswordPart = true;
			}
			string text5 = text + ".";
			if (data.ShowPasswordLength)
			{
				terminal.LockWithPassword(codeWord, new string[3]
				{
					passwordHintText,
					text5,
					"Char[" + codeWord.Length + "]"
				});
			}
			else
			{
				terminal.LockWithPassword(codeWord, new string[2] { passwordHintText, text5 });
			}
		}

		public static void AddUniqueCommand(LG_ComputerTerminal terminal, CustomCommand cmd)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: 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)
			if (terminal.m_command.m_commandsPerString.ContainsKey(cmd.Command))
			{
				EOSLogger.Error("Duplicate command name: '" + cmd.Command + "', cannot add command");
				return;
			}
			TERM_Command val = default(TERM_Command);
			if (!terminal.m_command.TryGetUniqueCommandSlot(ref val))
			{
				EOSLogger.Error("Cannot get more unique command slot, max: 5");
				return;
			}
			terminal.m_command.AddCommand(val, cmd.Command, cmd.CommandDesc.ParseToLocalizedText(), cmd.SpecialCommandRule, ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents), ListExtensions.ToIl2Cpp<TerminalOutput>(cmd.PostCommandOutputs.ConvertAll((CustomCommand.LocaleTerminalOutput x) => x.ToTerminalOutput())));
			for (int num = 0; num < cmd.CommandEvents.Count; num++)
			{
				WardenObjectiveEventData val2 = cmd.CommandEvents[num];
				if (val2.ChainPuzzle == 0)
				{
					continue;
				}
				ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(val2.ChainPuzzle);
				if (block == null)
				{
					continue;
				}
				LG_Area val3;
				Transform val4;
				if (terminal.SpawnNode != null)
				{
					val3 = terminal.SpawnNode.m_area;
					val4 = terminal.m_wardenObjectiveSecurityScanAlign;
				}
				else
				{
					LG_WardenObjective_Reactor connectedReactor = terminal.ConnectedReactor;
					object obj;
					if (connectedReactor == null)
					{
						obj = null;
					}
					else
					{
						AIG_CourseNode spawnNode = connectedReactor.SpawnNode;
						obj = ((spawnNode != null) ? spawnNode.m_area : null);
					}
					if (obj == null)
					{
						obj = null;
					}
					val3 = (LG_Area)obj;
					LG_WardenObjective_Reactor connectedReactor2 = terminal.ConnectedReactor;
					val4 = ((connectedReactor2 != null) ? connectedReactor2.m_chainedPuzzleAlign : null) ?? null;
				}
				if ((Object)(object)val3 == (Object)null)
				{
					EOSLogger.Error("Terminal Source Area is not found! Cannot create chained puzzle for command " + cmd.Command + "!");
					continue;
				}
				ChainedPuzzleInstance val5 = ChainedPuzzleManager.CreatePuzzleInstance(block, val3, val4.position, val4, val2.UseStaticBioscanPoints);
				List<WardenObjectiveEventData> events = ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents.GetRange(num, cmd.CommandEvents.Count - num));
				val5.OnPuzzleSolved += Action.op_Implicit((Action)delegate
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(events, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				});
				terminal.SetChainPuzzleForCommand(val, num, val5);
			}
		}
	}
	public static class EOSUtils
	{
		public static List<T> ToManaged<T>(this List<T> il2cppList)
		{
			List<T> list = new List<T>();
			Enumerator<T> enumerator = il2cppList.GetEnumerator();
			while (enumerator.MoveNext())
			{
				T current = enumerator.Current;
				list.Add(current);
			}
			return list;
		}

		public static void ResetProgress(this ChainedPuzzleInstance chainedPuzzle)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (chainedPuzzle.Data.DisableSurvivalWaveOnComplete)
			{
				chainedPuzzle.m_sound = new CellSoundPlayer(chainedPuzzle.m_parent.position);
			}
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)chainedPuzzle.m_chainedPuzzleCores)
			{
				ResetChild(item);
			}
			if (SNet.IsMaster)
			{
				pChainedPuzzleState state = chainedPuzzle.m_stateReplicator.State;
				pChainedPuzzleState val = new pChainedPuzzleState
				{
					status = (eChainedPuzzleStatus)0,
					currentSurvivalWave_EventID = state.currentSurvivalWave_EventID,
					isSolved = false,
					isActive = false
				};
				chainedPuzzle.m_stateReplicator.InteractWithState(val, new pChainedPuzzleInteraction
				{
					type = (eChainedPuzzleInteraction)2
				});
			}
			static void ResetChild(iChainedPuzzleCore ICore)
			{
				CP_Bioscan_Core val2 = ((Il2CppObjectBase)ICore).TryCast<CP_Bioscan_Core>();
				if ((Object)(object)val2 != (Object)null)
				{
					CP_Holopath_Spline val3 = ((Il2CppObjectBase)val2.m_spline).Cast<CP_Holopath_Spline>();
					CP_PlayerScanner val4 = ((Il2CppObjectBase)val2.PlayerScanner).Cast<CP_PlayerScanner>();
					val4.ResetScanProgression(0f);
					val2.Deactivate();
				}
				else
				{
					CP_Cluster_Core val5 = ((Il2CppObjectBase)ICore).TryCast<CP_Cluster_Core>();
					if ((Object)(object)val5 == (Object)null)
					{
						EOSLogger.Error("ResetChild: found iChainedPuzzleCore that is neither CP_Bioscan_Core nor CP_Cluster_Core...");
					}
					else
					{
						CP_Holopath_Spline val6 = ((Il2CppObjectBase)val5.m_spline).Cast<CP_Holopath_Spline>();
						foreach (iChainedPuzzleCore item2 in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val5.m_childCores)
						{
							ResetChild(item2);
						}
						val5.Deactivate();
					}
				}
			}
		}
	}
	public static class TSL_Wrapper
	{
		public static LocalizedText ParseToLocalizedText(this LocaleText text)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			return new LocalizedText
			{
				UntranslatedText = text.ParseTextFragments(),
				Id = 0u
			};
		}

		public unsafe static string ParseTextFragments(this LocaleText input)
		{
			return ((object)(*(LocaleText*)(&input))/*cast due to .constrained prefix*/).ToString().ParseTextFragments();
		}

		public static string ParseTextFragments(this string input)
		{
			return (InteropAPI.Call("TSL.ParseTextFragments", new object[1] { input }) as string) ?? input;
		}
	}
	public class EOSColor
	{
		public float r { get; set; }

		public float g { get; set; }

		public float b { get; set; }

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

		public Color ToUnityColor()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Color(r, g, b, a);
		}
	}
	public static class VanillaTMPPros
	{
		public const string VANILLA_CP_PREFAB_PATH = "Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab";

		public static GameObject Instantiate(GameObject parent = null)
		{
			GameObject loadedAsset = AssetAPI.GetLoadedAsset<GameObject>("Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab");
			if ((Object)(object)loadedAsset == (Object)null)
			{
				EOSLogger.Error("VanillaTMPPros.Instantiate: Cannot find TMPPro from vanilla CP!");
				return null;
			}
			GameObject gameObject = ((Component)loadedAsset.transform.GetChild(0).GetChild(1).GetChild(0)).gameObject;
			return ((Object)(object)parent != (Object)null) ? Object.Instantiate<GameObject>(gameObject.gameObject, parent.transform) : Object.Instantiate<GameObject>(gameObject.gameObject);
		}
	}
	public class Vec4 : Vec3
	{
		[JsonPropertyOrder(-9)]
		public float w { get; set; } = 0f;

		public Vector4 ToVector4()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Vector4(base.x, base.y, base.z, w);
		}
	}
	public class Vec3
	{
		[JsonPropertyOrder(-10)]
		public float x { get; set; }

		[JsonPropertyOrder(-10)]
		public float y { get; set; }

		[JsonPropertyOrder(-10)]
		public float z { get; set; }

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

		public Quaternion ToQuaternion()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.Euler(x, y, z);
		}
	}
	public static class EOSLogger
	{
		private static ManualLogSource logger = Logger.CreateLogSource("ExtraObjectiveSetup");

		private static string Timestamped(string str)
		{
			return "[" + DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture) + "] " + str;
		}

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

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

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

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

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

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

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

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)8, (object)Timestamped(str));
			}
		}
	}
	public static class LocalPlayer
	{
		private static int? _InstanceID;

		private static bool _started;

		public static bool HasAgent { get; private set; }

		public static PlayerAgent Agent { get; private set; }

		public static LocalPlayerAgent LocalAgent { get; private set; }

		public static bool TryGetAgent(out PlayerAgent agent)
		{
			agent = Agent;
			return HasAgent;
		}

		public static bool TryGetLocalAgent(out LocalPlayerAgent agent)
		{
			agent = LocalAgent;
			return HasAgent;
		}

		public static Vector3 GetPosition()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return HasAgent ? ((Agent)Agent).Position : Vector3.zero;
		}

		public static Vector3 GetPosition(Vector3 fallback)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return HasAgent ? ((Agent)Agent).Position : fallback;
		}

		public static Vector3 GetEyePosition()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return HasAgent ? ((Agent)Agent).EyePosition : Vector3.zero;
		}

		public static Vector3 GetEyePosition(Vector3 fallback)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return HasAgent ? ((Agent)Agent).EyePosition : fallback;
		}

		internal static void Init()
		{
			AssetAPI.OnStartupAssetsLoaded += StartPolling;
			if (AssetAPI.Status != null && AssetAPI.Status.Ready)
			{
				StartPolling();
			}
		}

		private static void StartPolling()
		{
			if (!_started)
			{
				_started = true;
				CoroutineDispatcher.StartCoroutine(UpdatePlayerInfo());
			}
		}

		private static IEnumerator UpdatePlayerInfo()
		{
			while (true)
			{
				if (PlayerManager.HasLocalPlayerAgent())
				{
					PlayerAgent agent = PlayerManager.GetLocalPlayerAgent();
					int instanceID = ((Object)agent).GetInstanceID();
					if (!_InstanceID.HasValue || _InstanceID.Value != instanceID)
					{
						Agent = agent;
						LocalAgent = ((Il2CppObjectBase)agent).Cast<LocalPlayerAgent>();
						_InstanceID = instanceID;
						HasAgent = true;
					}
				}
				else
				{
					Agent = null;
					LocalAgent = null;
					_InstanceID = null;
					HasAgent = false;
				}
				yield return null;
			}
		}
	}
}
namespace ExtraObjectiveSetup.Tweaks.TerminalTweak
{
	public struct TerminalState
	{
		public bool Enabled;

		public bool Approached;

		private int _data;

		private byte _length;

		public bool[] Value
		{
			readonly get
			{
				bool[] array = new bool[_length];
				for (int i = 0; i < _length; i++)
				{
					array[i] = (_data & (1 << i)) != 0;
				}
				return array;
			}
			set
			{
				if (value.Length > 32)
				{
					return;
				}
				_data = 0;
				_length = (byte)value.Length;
				for (int i = 0; i < value.Length; i++)
				{
					if (value[i])
					{
						_data |= 1 << i;
					}
				}
			}
		}

		public TerminalState()
		{
			Enabled = true;
			Approached = false;
			_data = 0;
			_length = 0;
		}

		public TerminalState(bool Enabled)
		{
			_data = 0;
			_length = 0;
			this.Enabled = true;
			Approached = false;
			this.Enabled = Enabled;
		}

		public TerminalState(bool[] logFileRead)
		{
			_data = 0;
			_length = 0;
			Enabled = true;
			Approached = false;
			Value = logFileRead;
		}

		public TerminalState(TerminalState o)
		{
			Enabled = true;
			Approached = false;
			Enabled = o.Enabled;
			Approached = o.Approached;
			_data = o._data;
			_length = o._length;
		}
	}
	public class TerminalWrapper
	{
		private readonly Dictionary<string, List<WardenObjectiveEventData>> logFileEvents = new Dictionary<string, List<WardenObjectiveEventData>>();

		private readonly List<string> logFileNames = new List<string>();

		public LG_ComputerTerminal lgTerminal { get; private set; }

		public StateReplicator<TerminalState> stateReplicator { get; private set; }

		private ExpeditionTerminalsDefinition expeditionTerminalDefinition { get; set; } = null;

		private void ChangeStateUnsynced(bool enabled)
		{
			EOSLogger.Debug($"{lgTerminal.ItemKey} state, enabled: {enabled}");
			lgTerminal.OnProximityExit();
			Interact_ComputerTerminal componentInChildren = ((Component)lgTerminal).GetComponentInChildren<Interact_ComputerTerminal>(true);
			bool flag = enabled;
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Behaviour)componentInChildren).enabled = flag;
				((Interact_Base)componentInChildren).SetActive(flag);
			}
			lgTerminal.m_interfaceScreen.SetActive(flag);
			lgTerminal.m_loginScreen.SetActive(flag);
			if ((Object)(object)lgTerminal.m_text != (Object)null)
			{
				((Behaviour)lgTerminal.m_text).enabled = flag;
			}
			if (!flag)
			{
				PlayerAgent localInteractionSource = lgTerminal.m_localInteractionSource;
				if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger)
				{
					lgTerminal.ExitFPSView();
				}
			}
		}

		public void ChangeState(bool enabled)
		{
			ChangeStateUnsynced(enabled);
			if (SNet.IsMaster)
			{
				StateReplicator<TerminalState> obj = stateReplicator;
				TerminalState state = stateReplicator.State;
				state.Enabled = enabled;
				obj.SetState(state);
			}
		}

		public void ChangeState()
		{
			if (SNet.IsMaster && !stateReplicator.State.Approached)
			{
				StateReplicator<TerminalState> obj = stateReplicator;
				TerminalState state = stateReplicator.State;
				state.Approached = true;
				obj.SetState(state);
			}
		}

		public void ReceiveCommand(TERM_Command cmd, string param)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			if (expeditionTerminalDefinition == null)
			{
				return;
			}
			if (SNet.IsMaster && (int)cmd == 29)
			{
				ChangeState(param);
			}
			if ((int)cmd == 31)
			{
				float delay;
				List<WardenObjectiveEventData> events;
				if (!lgTerminal.EvaluatePassword(param))
				{
					List<WardenObjectiveEventData> eventsOnPasswordInputFailure = expeditionTerminalDefinition.EventsOnPasswordInputFailure;
					float num = 2.6f;
					delay = num;
					events = eventsOnPasswordInputFailure;
				}
				else
				{
					List<WardenObjectiveEventData> eventsOnPasswordInputSuccess = expeditionTerminalDefinition.EventsOnPasswordInputSuccess;
					float num = 2.8f;
					delay = num;
					events = eventsOnPasswordInputSuccess;
				}
				ExecuteEvents(events, delay);
			}
		}

		public void ChangeState(string fileName)
		{
			int num = logFileNames.IndexOf(fileName);
			if (expeditionTerminalDefinition != null && stateReplicator != null && num != -1)
			{
				bool[] value = stateReplicator.State.Value;
				bool[] array = new bool[logFileNames.Count];
				for (int i = 0; i < value.Length && i < array.Length; i++)
				{
					array[i] = value[i];
				}
				if (!array[num])
				{
					array[num] = true;
					StateReplicator<TerminalState> obj = stateReplicator;
					TerminalState state = stateReplicator.State;
					state.Value = array;
					obj.SetState(state);
				}
			}
		}

		private void OnStateChanged(TerminalState oldState, TerminalState newState, bool isRecall)
		{
			if (oldState.Enabled != newState.Enabled)
			{
				ChangeStateUnsynced(newState.Enabled);
			}
			if (expeditionTerminalDefinition == null || isRecall)
			{
				return;
			}
			if (!oldState.Approached && newState.Approached)
			{
				ExecuteEvents(expeditionTerminalDefinition.EventsOnApproach, 0f);
			}
			bool[] value = oldState.Value;
			bool[] value2 = newState.Value;
			for (int i = 0; i < logFileNames.Count; i++)
			{
				bool flag = i < value.Length && value[i];
				bool flag2 = i < value2.Length && value2[i];
				if (!flag && flag2 && logFileEvents.TryGetValue(logFileNames[i], out var value3))
				{
					ExecuteEvents(value3, 3f);
				}
			}
		}

		private void ExecuteEvents(List<WardenObjectiveEventData> events, float delay)
		{
			if (events != null && events.Count != 0)
			{
				if (delay <= 0f)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(events), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				}
				else
				{
					CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DelayedEvents(events, delay)), (Action)null);
				}
			}
		}

		private static IEnumerator DelayedEvents(List<WardenObjectiveEventData> events, float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(events), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
		}

		private void SetupExpeditionDefinition()
		{
			if (!ExpeditionDefinitionManager.Current.TryGetTerminalDefinitionFromInstance(lgTerminal, out var termDef))
			{
				return;
			}
			expeditionTerminalDefinition = termDef;
			foreach (TerminalLogFileEvents logFile in termDef.LogFiles)
			{
				if (!string.IsNullOrWhiteSpace(logFile.FileName))
				{
					string text = logFile.FileName.ToUpperInvariant();
					logFileEvents[text] = logFile.EventsOnFileRead;
					logFileNames.Add(text);
				}
			}
		}

		public static TerminalWrapper Instantiate(LG_ComputerTerminal lgTerminal, uint replicatorID)
		{
			if ((Object)(object)lgTerminal == (Object)null || replicatorID == 0)
			{
				return null;
			}
			TerminalWrapper terminalWrapper = new TerminalWrapper();
			terminalWrapper.lgTerminal = lgTerminal;
			terminalWrapper.stateReplicator = StateReplicator<TerminalState>.Create(replicatorID, new TerminalState
			{
				Enabled = true
			}, (LifeTimeType)1, (IStateReplicatorHolder<TerminalState>)null);
			terminalWrapper.stateReplicator.OnStateChanged += terminalWrapper.OnStateChanged;
			terminalWrapper.SetupExpeditionDefinition();
			return terminalWrapper;
		}

		private TerminalWrapper()
		{
		}
	}
	public static class SerialGeneratorManager
	{
		private class ShuffledStepArray
		{
			private readonly string[] _values;

			private readonly int[] _order;

			private int _step = -1;

			public ShuffledStepArray(IEnumerable<string> values)
			{
				_values = values.Distinct().ToArray();
				_order = Enumerable.Range(0, _values.Length).ToArray();
				for (int num = _order.Length - 1; num > 0; num--)
				{
					int num2 = _random.Next(0, num + 1);
					ref int reference = ref _order[num];
					ref int reference2 = ref _order[num2];
					int num3 = _order[num2];
					int num4 = _order[num];
					reference = num3;
					reference2 = num4;
				}
			}

			public string Next()
			{
				_step++;
				if (_step >= _order.Length)
				{
					_step = 0;
				}
				return _values[_order[_step]];
			}
		}

		public enum CodeWordLength
		{
			Three = 3,
			Four,
			Five,
			Six,
			Seven
		}

		public const string AUTOGEN_GUID = "000-the_tavern-AutogenRundown";

		public const string LONGERCODES_GUID = "com.Brandont.LongerCodes";

		private static Random _random;

		private static readonly bool _hasPluginConflict;

		private static readonly Dictionary<CodeWordLength, ShuffledStepArray> _codeWords;

		private static ShuffledStepArray _hardPrefixes;

		public static readonly string[] CodeWordPrefixes;

		public static readonly string[] HardCodeWordPrefixes;

		public static readonly string[] ThreeLetterWords;

		public static readonly string[] FourLetterWords;

		public static readonly string[] FiveLetterWords;

		public static readonly string[] SixLetterWords;

		public static readonly string[] SevenLetterWords;

		static SerialGeneratorManager()
		{
			_random = null;
			_codeWords = new Dictionary<CodeWordLength, ShuffledStepArray>();
			_hardPrefixes = null;
			CodeWordPrefixes = new string[27]
			{
				"X01", "X02", "X03", "X04", "X05", "X06", "X07", "X08", "X09", "Y01",
				"Y02", "Y03", "Y04", "Y05", "Y06", "Y07", "Y08", "Y09", "Z01", "Z02",
				"Z03", "Z04", "Z05", "Z06", "Z07", "Z08", "Z09"
			};
			HardCodeWordPrefixes = new string[84]
			{
				"A01", "A02", "A03", "A04", "A05", "A06", "A07", "A08", "A09", "A10",
				"A11", "A12", "B01", "B02", "B03", "B04", "B05", "B06", "B07", "B08",
				"B09", "B10", "B11", "B12", "C01", "C02", "C03", "C04", "C05", "C06",
				"C07", "C08", "C09", "C10", "C11", "C12", "W01", "W02", "W03", "W04",
				"W05", "W06", "W07", "W08", "W09", "W10", "W11", "W12", "X01", "X02",
				"X03", "X04", "X05", "X06", "X07", "X08", "X09", "X10", "X11", "X12",
				"Y01", "Y02", "Y03", "Y04", "Y05", "Y06", "Y07", "Y08", "Y09", "Y10",
				"Y11", "Y12", "Z01", "Z02", "Z03", "Z04", "Z05", "Z06", "Z07", "Z08",
				"Z09", "Z10", "Z11", "Z12"
			};
			ThreeLetterWords = new string[300]
			{
				"ace", "act", "add", "age", "ago", "aid", "aim", "air", "ale", "all",
				"and", "ant", "any", "ape", "apt", "arc", "are", "arm", "art", "ash",
				"ask", "ate", "bad", "bag", "ban", "bar", "bat", "bay", "bed", "bee",
				"beg", "bet", "bid", "big", "bin", "bit", "bob", "bog", "boo", "bow",
				"box", "boy", "bud", "bug", "bun", "bus", "but", "buy", "cab", "can",
				"cap", "car", "cat", "cob", "cod", "cog", "cop", "cow", "cry", "cub",
				"cup", "cut", "dad", "dap", "day", "den", "dew", "did", "die", "dig",
				"dim", "dip", "dog", "dot", "dry", "due", "duo", "ear", "eat", "egg",
				"ego", "end", "era", "eve", "eye", "fan", "far", "fat", "fed", "fee",
				"few", "fig", "fin", "fir", "fit", "fix", "fly", "fog", "for", "fox",
				"fry", "fun", "fur", "gap", "gas", "get", "gig", "god", "got", "gum",
				"gun", "guy", "gym", "had", "ham", "has", "hat", "hay", "hem", "hen",
				"her", "hey", "hid", "him", "hip", "his", "hit", "hot", "how", "hub",
				"hue", "hug", "hum", "hut", "ice", "ill", "ink", "inn", "ion", "its",
				"jam", "jar", "jaw", "jet", "job", "jog", "joy", "jug", "key", "kid",
				"kin", "kit", "lab", "lad", "lag", "lap", "law", "lay", "led", "leg",
				"let", "lid", "lie", "lip", "lit", "log", "lot", "low", "mad", "man",
				"map", "mat", "may", "men", "met", "mix", "mob", "mom", "mop", "mud",
				"mug", "nap", "net", "new", "nod", "not", "now", "nut", "oak", "oar",
				"odd", "off", "oil", "old", "one", "ore", "our", "out", "owe", "owl",
				"own", "pad", "pal", "pan", "par", "pat", "pay", "pea", "pen", "per",
				"pet", "pie", "pig", "pin", "pit", "pop", "pot", "pub", "put", "rag",
				"ram", "ran", "rap", "rat", "raw", "ray", "red", "rib", "rid", "rig",
				"rim", "rip", "rob", "rod", "rot", "row", "run", "sad", "sag", "sap",
				"sat", "saw", "say", "sea", "see", "set", "sew", "she", "shy", "sin",
				"sip", "sir", "sit", "six", "ski", "sky", "son", "spy", "sue", "sun",
				"tab", "tag", "tan", "tap", "tar", "tax", "tea", "ten", "the", "tie",
				"tin", "tip", "toe", "ton", "too", "top", "toy", "try", "two", "use",
				"van", "vet", "via", "war", "was", "way", "web", "wed", "wet", "who",
				"why", "win", "wit", "won", "wow", "yes", "yet", "you", "zip", "zoo"
			};
			FourLetterWords = new string[733]
			{
				"jazz", "fuzz", "quiz", "jack", "jump", "junk", "cozy", "joke", "jive", "jeep",
				"lazy", "flux", "maze", "jury", "jobs", "mojo", "foxy", "jaws", "zoom", "kick",
				"gaze", "buck", "lynx", "puck", "flex", "pump", "back", "exam", "bump", "zone",
				"pack", "quit", "expo", "cuff", "jolt", "jail", "join", "just", "pick", "comb",
				"size", "biff", "much", "bomb", "hoax", "luck", "camp", "hack", "tzar", "duck",
				"hawk", "funk", "punk", "chip", "chew", "chef", "next", "club", "neck", "iffy",
				"knob", "hymn", "know", "folk", "flak", "dump", "deck", "whip", "milk", "hulk",
				"lack", "walk", "lump", "lock", "monk", "copy", "baby", "pulp", "numb", "hemp",
				"bank", "plum", "pawn", "hype", "beak", "sock", "gulf", "view", "kiwi", "verb",
				"dunk", "husk", "lamb", "bark", "peak", "vice", "vibe", "lamp", "mark", "mask",
				"week", "make", "damp", "weak", "wake", "work", "park", "levy", "skip", "bike",
				"wave", "sick", "envy", "flew", "flaw", "flip", "flop", "flow", "taxi", "flap",
				"film", "five", "plug", "pork", "poke", "fork", "perk", "keep", "king", "bake",
				"tick", "puma", "yank", "exit", "axis", "fake", "limb", "text", "cube", "move",
				"bowl", "book", "wolf", "blow", "navy", "cook", "cake", "clip", "rock", "cave",
				"claw", "clap", "wing", "wife", "brow", "fang", "farm", "riff", "pull", "ugly",
				"epic", "clay", "kind", "kill", "ramp", "face", "fact", "help", "fame", "pope",
				"form", "pony", "busy", "prop", "spam", "half", "busy", "fund", "full", "fury",
				"poem", "swim", "firm", "flag", "pipe", "yawn", "foam", "bull", "play", "nuke",
				"wasp", "warm", "such", "warp", "crab", "give", "hook", "link", "worm", "glow",
				"crop", "crow", "crew", "when", "hive", "push", "golf", "coma", "very", "beam",
				"beef", "inch", "body", "talk", "huge", "holy", "home", "hope", "tank", "rank",
				"rich", "mild", "menu", "mesh", "moth", "mule", "plan", "page", "oval", "oven",
				"path", "knee", "lawn", "lake", "itch", "kilo", "math", "like", "skin", "live",
				"sink", "love", "shop", "show", "silk", "look", "drum", "down", "volt", "void",
				"vine", "wage", "dawn", "dark", "dive", "diva", "wall", "wash", "echo", "type",
				"fill", "fall", "find", "fish", "turk", "foul", "twig", "evil", "etch", "bell",
				"bend", "bath", "bald", "ball", "band", "blur", "bold", "blue", "bill", "army",
				"clan", "clue", "city", "cold", "both", "brag", "burn", "wild", "cash", "cell",
				"will", "wind", "cage", "call", "desk", "grow", "game", "germ", "gasp", "grip",
				"fuel", "them", "frog", "gang", "grab", "must", "hill", "name", "gold", "mute",
				"card", "risk", "wine", "nice", "swan", "they", "news", "mint", "mile", "cone",
				"corn", "scan", "cool", "cure", "cute", "muse", "coin", "hold", "save", "coal",
				"moon", "mono", "code", "mood", "yell", "guru", "take", "task", "able", "acid",
				"pool", "pole", "plot", "yoga", "ally", "hall", "over", "hell", "wool", "wood",
				"bird", "once", "only", "omen", "bolt", "bone", "open", "born", "bead", "pelt",
				"peel", "barn", "pure", "word", "paid", "bent", "belt", "mini", "town", "duty",
				"dull", "lama", "lame", "visa", "lady", "vest", "idly", "spur", "slip", "slim",
				"slow", "slug", "took", "slam", "skit", "slap", "left", "snow", "hunt", "drop",
				"drip", "drug", "snug", "hurl", "soak", "leap", "draw", "vote", "leaf", "snip",
				"kite", "tuba", "fine", "soup", "span", "feed", "feel", "twin", "food", "foil",
				"fool", "flat", "tube", "vase", "kiss", "vast", "fade", "fail", "ever", "spin",
				"life", "snap", "made", "loaf", "deep", "long", "main", "weed", "mail", "want",
				"loop", "lush", "mean", "meal", "doom", "lift", "lily", "lime", "deny", "dime",
				"lips", "taco", "yard", "urge", "trip", "stew", "undo", "spit", "trim", "semi",
				"were", "west", "scar", "tame", "time", "your", "yarn", "wire", "snag", "wise",
				"raft", "rush", "step", "rely", "slay", "ring", "ripe", "roof", "rope", "robe",
				"rift", "rice", "thin", "then", "wait", "trap", "room", "sift", "tidy", "wart",
				"spot", "same", "stab", "soft", "stem", "term", "sing", "sofa", "soap", "race",
				"sign", "song", "safe", "some", "cost", "core", "lend", "coat", "cast", "case",
				"logo", "horn", "hood", "hour", "hurt", "hint", "hole", "dish", "land", "dash",
				"lash", "item", "mate", "boat", "boot", "mass", "miss", "mist", "bite", "mess",
				"boss", "care", "gain", "free", "frat", "fear", "fate", "feet", "fast", "foot",
				"fort", "fits", "fist", "fire", "halo", "hard", "drag", "doll", "hide", "herd",
				"head", "goal", "edge", "girl", "gone", "dual", "grin", "duel", "good", "grid",
				"dune", "oboe", "aged", "omit", "oily", "atom", "noun", "nosy", "pest", "post",
				"pose", "port", "past", "pass", "beer", "most", "beta", "best", "bait", "bias",
				"more", "unit", "goat", "runt", "this", "easy", "dust", "odds", "shoe", "rash",
				"duet", "airy", "that", "tell", "tend", "told", "used", "send", "nail", "tuna",
				"sand", "tune", "sell", "turn", "tall", "rage", "eery", "toll", "gear", "gate",
				"noon", "yeti", "deed", "lane", "lard", "none", "deal", "dead", "sold", "dine",
				"idol", "idle", "shot", "dent", "soul", "dial", "nine", "loan", "load", "rosy",
				"lint", "line", "lean", "lead", "lens", "year", "slur", "hero", "hire", "hiss",
				"here", "neon", "done", "ruin", "rule", "need", "hear", "heat", "lord", "host",
				"rude", "stun", "stay", "auto", "dirt", "diet", "door", "dose", "anti", "dire",
				"earn", "else", "does", "edit", "dare", "dart", "user", "data", "date", "tale",
				"lose", "lore", "loss", "lost", "side", "loot", "salt", "sane", "seen", "seed",
				"seal", "list", "last", "soda", "liar", "slot", "less", "rant", "rent", "redo",
				"raid", "rail", "rain", "ride", "nest", "ruse", "rust", "near", "neat", "nose",
				"note", "road", "tent", "tide", "lair", "tile", "teen", "torn", "true", "tool",
				"toad", "tone", "tilt", "soon", "idea", "sure", "sour", "iron", "suit", "rear",
				"iris", "rest", "tsar", "trio", "sort", "rate", "rare", "tree", "site", "tear",
				"stir", "east", "ease", "area", "rise", "roar", "tier", "ties", "test", "star",
				"tire", "rose", "riot"
			};
			FiveLetterWords = new string[1064]
			{
				"about", "actor", "adapt", "adieu", "adobe", "aeons", "after", "again", "agape", "agate",
				"aging", "aglow", "agree", "ahead", "aimed", "aired", "alarm", "alive", "alley", "allow",
				"aloft", "along", "aloud", "alpha", "altar", "alter", "altos", "amiss", "amity", "among",
				"amour", "ample", "amply", "angle", "angry", "aping", "appal", "apply", "aptly", "arena",
				"array", "arson", "ashen", "aside", "asked", "asset", "atlas", "atone", "attic", "audio",
				"audit", "augur", "avail", "awake", "award", "awoke", "axles", "babel", "baits", "baize",
				"baker", "balmy", "banjo", "basal", "based", "baste", "batch", "bathe", "baths", "beads",
				"beams", "bears", "beast", "beaux", "begun", "being", "belie", "bench", "berry", "bible",
				"bides", "bight", "biped", "birch", "black", "blade", "blast", "blend", "bless", "blink",
				"bliss", "blots", "blown", "blues", "blush", "board", "boars", "boast", "bodes", "boggy",
				"boils", "boles", "books", "boons", "boots", "booze", "borne", "bough", "braid", "brake",
				"brats", "bread", "break", "brief", "brier", "brine", "bring", "brink", "briny", "brood",
				"brown", "budge", "bugle", "build", "built", "bulks", "bulls", "bunks", "burnt", "burrs",
				"burst", "buyer", "cabin", "cable", "caked", "cakes", "calms", "camps", "caper", "casks",
				"casts", "cater", "cause", "cedar", "chafe", "chaff", "chain", "chaos", "charm", "chart",
				"chary", "chasm", "chats", "cheat", "check", "cheek", "cheer", "chess", "chide", "child",
				"chill", "choir", "chops", "chord", "chump", "chums", "chunk", "churl", "chute", "cinch",
				"cites", "clash", "clasp", "class", "claws", "clear", "climb", "clips", "clods", "clogs",
				"close", "clout", "clown", "coast", "cobra", "comes", "comic", "cooed", "cools", "cores",
				"corns", "could", "count", "court", "cover", "covey", "crabs", "craft", "crash", "crass",
				"crate", "craze", "creak", "creek", "creep", "crews", "cribs", "crick", "cries", "crime",
				"croak", "croup", "crows", "crude", "cruel", "crumb", "cubes", "curls", "curly", "curve",
				"cycle", "cynic", "dairy", "dames", "damps", "dance", "dared", "dares", "dates", "daubs",
				"dears", "death", "debit", "debts", "decoy", "decry", "deeds", "deeps", "delay", "dells",
				"delta", "demon", "depot", "deuce", "dimes", "dimly", "diner", "ditch", "ditto", "ditty",
				"dizzy", "docks", "dogma", "doing", "doled", "dolls", "dosed", "doses", "doves", "downs",
				"drink", "drone", "ducks", "dukes", "dummy", "dumps", "dunce", "dupes", "dusty", "dwell",
				"dwelt", "eager", "earls", "early", "earth", "eaten", "eater", "edged", "egged", "eight",
				"elate", "elder", "elude", "email", "empty", "ended", "enemy", "ennui", "epics", "equal",
				"equip", "error", "every", "evils", "evoke", "exalt", "excel", "expel", "extra", "faces",
				"false", "fares", "farms", "fasts", "fault", "fears", "feign", "fells", "ferry", "feted",
				"fever", "fiche", "fiefs", "field", "fifth", "fifty", "fight", "files", "filet", "final",
				"fines", "fires", "first", "fishy", "fives", "fjord", "flaky", "flame", "flank", "flaps",
				"flats", "flaws", "fleck", "flees", "flesh", "flier", "fling", "flirt", "float", "flood",
				"floor", "floss", "flows", "flues", "fluke", "flume", "folio", "folks", "foods", "foray",
				"force", "fords", "forks", "forte", "forts", "forum", "found", "fours", "foxes", "frame",
				"fraud", "freer", "frees", "front", "fruit", "fugue", "fully", "fumed", "fumes", "furze",
				"fuses", "gains", "games", "gangs", "gapes", "gases", "gazes", "geese", "gents", "germs",
				"ghost", "giant", "gilds", "gills", "girth", "given", "gives", "glade", "glass", "glean",
				"glint", "glove", "glows", "gnaws", "goads", "godly", "going", "golly", "gongs", "goody",
				"gored", "gourd", "gowns", "grain", "grant", "graph", "grate", "grave", "graze", "great",
				"greed", "greys", "grime", "gross", "group", "grown", "grows", "guard", "guild", "guile",
				"guilt", "gully", "hails", "hairs", "hands", "hangs", "happy", "harms", "harsh", "haste",
				"haven", "heady", "heard", "heart", "hedge", "heirs", "helix", "helps", "hence", "hides",
				"hills", "hilts", "hinds", "hinge", "hives", "hoist", "holds", "holly", "homes", "horde",
				"hours", "house", "howls", "hulks", "human", "hunch", "hunts", "hurts", "icily", "ideas",
				"idiom", "idled", "idler", "idols", "image", "impel", "imply", "incur", "inept", "infer",
				"inter", "irony", "issue", "jacks", "jaunt", "jeans", "jeers", "jelly", "jests", "jetty",
				"jiffy", "jokes", "junks", "karma", "khaki", "kicks", "knack", "knelt", "knits", "knobs",
				"knots", "known", "label", "ladle", "lager", "lambs", "lamed", "lance", "lanes", "lapel",
				"larch", "large", "largo", "larva", "latch", "later", "lawns", "leafy", "leaky", "leans",
				"leapt", "lease", "least", "leave", "ledge", "level", "liege", "liens", "light", "liked",
				"liken", "limbo", "limbs", "limit", "lines", "lions", "lithe", "lived", "livid", "llama",
				"loads", "loans", "loath", "lobby", "lobes", "local", "looks", "looms", "loops", "loser",
				"lousy", "loved", "lower", "lowly", "lucid", "lucky", "lulls", "lunar", "lurid", "lusty",
				"lymph", "lyric", "mains", "maize", "major", "maker", "makes", "males", "mamma", "mange",
				"mango", "mania", "manor", "manse", "march", "mated", "mates", "maybe", "mayor", "mazes",
				"means", "meats", "medal", "media", "meets", "melon", "memes", "merit", "metal", "might",
				"milch", "miles", "milky", "mimes", "mince", "mined", "mines", "mints", "minus", "mirth",
				"mites", "mixed", "moats", "modem", "modes", "moles", "money", "month", "moody", "moral",
				"mores", "mouse", "mover", "mowed", "mower", "munch", "music", "musky", "musty", "myths",
				"naked", "names", "nasal", "nasty", "natty", "naval", "needs", "nerve", "nests", "never",
				"niche", "night", "nooks", "north", "nosed", "oases", "oaten", "odium", "offer", "often",
				"oiled", "olden", "older", "omits", "onion", "opals", "opens", "opera", "order", "other",
				"ounce", "ovals", "owner", "oxide", "paddy", "paler", "pales", "palsy", "panel", "panic",
				"pansy", "pared", "party", "paste", "patio", "paved", "payed", "payer", "peach", "peaks",
				"pears", "pecks", "pelts", "pence", "penne", "peril", "pesky", "pesos", "pests", "petal",
				"phase", "phone", "piled", "pinch", "pines", "pinto", "pints", "pitch", "pivot", "place",
				"plaid", "plant", "plaza", "plush", "poems", "poets", "point", "pokes", "pools", "popes",
				"poppy", "ports", "pound", "pours", "power", "press", "price", "prick", "pries", "prime",
				"privy", "prize", "props", "prosy", "prove", "prows", "proxy", "psalm", "pudgy", "puffy",
				"pumps", "puree", "purge", "putty", "quart", "quays", "queen", "queue", "quips", "quite",
				"raged", "raise", "rated", "raven", "react", "ready", "reaps", "rebus", "reeds", "reeve",
				"refer", "relic", "remit", "renew", "reply", "rests", "rhyme", "rides", "right", "riled",
				"rills", "rimes", "rinse", "ripen", "risen", "risks", "risky", "roads", "roams", "roast",
				"roles", "rolls", "roomy", "roost", "roots", "rosin", "rouge", "rough", "rouse", "rover",
				"rowdy", "rowed", "ruder", "ruins", "ruler", "runes", "ruses", "sagas", "sails", "salsa",
				"salvo", "scalp", "scarf", "scent", "scion", "scold", "scoop", "scope", "scour", "scowl",
				"seals", "sects", "seeds", "seems", "seers", "seize", "sense", "serfs", "serum", "sever",
				"sewed", "shack", "shaft", "shaky", "shale", "shall", "shams", "shape", "share", "shawl",
				"shear", "sheds", "shift", "ships", "shirk", "shoal", "shone", "short", "shout", "showy",
				"shred", "shrub", "siege", "sieve", "signs", "silky", "silly", "since", "siren", "sites",
				"skate", "skies", "skiff", "skips", "skirt", "skull", "slack", "slang", "slave", "sleds",
				"sleek", "sleet", "slept", "slime", "slink", "slips", "sloop", "slope", "slunk", "slush",
				"small", "smash", "smelt", "smite", "smoke", "snags", "snake", "snaky", "snaps", "snarl",
				"snipe", "snuff", "soars", "sober", "socks", "soggy", "songs", "sonny", "sores", "sough",
				"souls", "south", "sowed", "space", "spans", "spark", "spelt", "spicy", "spike", "spins",
				"spire", "split", "spoor", "sprig", "spurn", "squad", "stage", "stags", "stale", "stamp",
				"stank", "stare", "start", "state", "steal", "steep", "stews", "stiff", "still", "stoic",
				"store", "storm", "story", "stove", "strew", "study", "stump", "sucks", "suite", "suits",
				"sully", "surer", "surly", "sweat", "swell", "swept", "swims", "swing", "sworn", "synod",
				"taboo", "tacks", "taint", "taken", "tamed", "tapes", "tardy", "tarry", "tarts", "tasks",
				"taunt", "taxed", "teems", "teeth", "tempo", "temps", "tenet", "tents", "tepid", "texts",
				"thank", "their", "these", "thick", "thing", "think", "third", "those", "three", "thumb",
				"tibia", "tiers", "tight", "tiles", "times", "tires", "toads", "today", "toils", "tolls",
				"tonic", "tooth", "topaz", "topic", "torso", "torts", "tough", "tours", "towed", "toxic",
				"toyed", "trade", "trail", "trash", "treed", "trice", "trick", "tries", "trill", "tripe",
				"trite", "truly", "trump", "trunk", "trust", "tubes", "tunes", "tunic", "tusks", "tweed",
				"twice", "types", "udder", "uncle", "uncut", "under", "unfit", "unsay", "until", "urban",
				"users", "using", "utter", "vales", "vases", "venom", "verbs", "vials", "video", "views",
				"villa", "viola", "visit", "vista", "vogue", "voice", "volts", "voter", "vouch", "vowel",
				"vying", "wakes", "walks", "wants", "warns", "watch", "water", "waxed", "wears", "weave",
				"weeks", "weigh", "whale", "wheel", "whelp", "where", "which", "while", "whine", "whirl",
				"whist", "white", "whole", "whoop", "whose", "wield", "wilds", "wiles", "wills", "winds",
				"wines", "winks", "wiped", "wipes", "wired", "wires", "woman", "women", "words", "works",
				"world", "worst", "worth", "would", "wound", "wrath", "wreak", "wrong", "years", "yield",
				"yoked", "yolks", "young", "yours"
			};
			SixLetterWords = new string[1394]
			{
				"abated", "abbess", "abbots", "abided", "aboard", "abroad", "abrupt", "abused", "abuser", "acacia",
				"accede", "acidic", "acorns", "across", "action", "addict", "adding", "adduce", "adduct", "adjoin",
				"admire", "admits", "adored", "adorns", "adroit", "adults", "agates", "agency", "agenda", "aghast",
				"agrees", "aisles", "albeit", "albums", "alcove", "allium", "allows", "allure", "almost", "alpaca",
				"alpine", "alumna", "always", "ambers", "amidst", "amoeba", "ampere", "amused", "anemia", "anemic",
				"angles", "animas", "anneal", "anodes", "anomie", "answer", "anthem", "anyone", "apices", "apiece",
				"append", "arcana", "arcane", "ardent", "around", "artful", "aspect", "aspire", "assort", "assure",
				"asylum", "atrial", "attack", "attend", "audits", "avatar", "avenge", "avocet", "avowed", "awakes",
				"axioms", "babies", "backer", "backup", "badges", "bagger", "bailer", "baited", "baking", "bamboo",
				"banged", "banger", "banned", "banyan", "baobab", "barbed", "baring", "barked", "barman", "barrel",
				"basket", "basque", "basses", "basted", "batted", "batten", "battle", "baying", "bayous", "beamer",
				"beaver", "become", "bedlam", "befall", "before", "begone", "behind", "behold", "beings", "belted",
				"belter", "bended", "better", "bevels", "biased", "biceps", "bidden", "bidder", "biller", "binder",
				"biomes", "bionic", "birder", "bisect", "blades", "blamed", "blames", "blasts", "blazer", "blazon",
				"blenny", "blight", "blocky", "blonde", "blooms", "bluest", "boasts", "boater", "bobbed", "bobcat",
				"bogeys", "bolded", "bombed", "boosts", "bosons", "botany", "bougie", "bouton", "bovine", "bowled",
				"bowman", "boxers", "bracer", "breeze", "bright", "brinks", "broads", "broker", "broods", "broths",
				"bruise", "brushy", "bryony", "bucked", "budget", "buffed", "buffer", "buffet", "bugged", "burden",
				"burley", "busker", "busses", "butter", "buyout", "bypass", "cabins", "cached", "called", "caller",
				"calmer", "cancan", "candor", "caning", "canner", "canons", "capita", "carafe", "career", "carman",
				"carols", "cartel", "caucus", "causer", "causes", "caveat", "celebs", "cental", "center", "chaise",
				"chance", "change", "charms", "chased", "chasms", "cheats", "chided", "chiles", "chintz", "chisel",
				"chocks", "choirs", "choker", "chokes", "cholla", "choose", "chords", "chucks", "clefts", "clerks",
				"climes", "cloned", "closed", "cloths", "cloudy", "clowns", "coddle", "coffee", "coffer", "cohort",
				"coined", "coking", "coldly", "comber", "coming", "common", "confit", "conics", "coning", "conned",
				"cookie", "cooper", "coping", "copped", "copter", "corals", "corded", "corked", "corker", "corner",
				"corral", "corset", "cortex", "cougar", "county", "couple", "coupon", "course", "covert", "cozens",
				"cramps", "crated", "craves", "crayon", "creaky", "critic", "crowns", "cruise", "crusts", "crypto",
				"cuboid", "cuddly", "cupids", "curing", "curlew", "curved", "custom", "cutest", "cyclic", "cypher",
				"dabble", "daemon", "daikon", "dampen", "danced", "dances", "danger", "darker", "darned", "darted",
				"dearer", "debate", "debits", "debugs", "decoys", "decree", "deepen", "defeat", "deists", "deltas",
				"dement", "demons", "demote", "demure", "depict", "depose", "depths", "derive", "desire", "detach",
				"detail", "detect", "detest", "devise", "devoid", "diadem", "dialup", "dictum", "digest", "dilate",
				"dimers", "dimmed", "dimmer", "dimple", "dinner", "discos", "discus", "dodges", "dogmas", "dollar",
				"donate", "donkey", "donned", "dosage", "dosing", "doting", "double", "dozers", "draper", "drapes",
				"dreamy", "dredge", "driers", "driver", "dually", "ducats", "duffel", "dumber", "dumped", "dunked",
				"dunker", "during", "duster", "dyadic", "earing", "earths", "earwax", "earwig", "easter", "echoes",
				"eddies", "editor", "eerily", "effete", "effort", "eights", "eighty", "either", "elects", "elicit",
				"eluted", "embark", "embeds", "emcees", "empire", "encore", "energy", "engulf", "enjoys", "enlace",
				"enough", "enrage", "entail", "enters", "entree", "envoys", "equine", "errata", "erupts", "eschew",
				"escrow", "esprit", "essays", "esteem", "esters", "evades", "evenly", "excels", "exhale", "exiles",
				"exodus", "exotic", "expire", "expiry", "extant", "extend", "eyelid", "family", "faster", "father",
				"fathom", "faults", "faulty", "favors", "feeble", "feeler", "feline", "felted", "femmes", "fenced",
				"fences", "fender", "fescue", "fiddle", "fiends", "filing", "filmed", "firmer", "fixate", "fixing",
				"fixity", "fizzle", "flaked", "flamed", "flaxen", "flayed", "fleece", "fleets", "flexor", "flicks",
				"flight", "flimsy", "flinch", "flings", "flocks", "floret", "fluffy", "fogged", "foiled", "fondly",
				"fondue", "forced", "forego", "formal", "format", "former", "francs", "freely", "freeze", "friend",
				"fronts", "frosts", "frosty", "frowns", "fruits", "funder", "fungal", "furrow", "futile", "future",
				"gables", "gadfly", "gagged", "gaging", "galore", "gambol", "gamete", "gaming", "gammon", "gander",
				"garage", "garden", "garnet", "gassed", "gather", "gauges", "ghetto", "gibbet", "ginkgo", "givers",
				"giving", "glared", "global", "globes", "gnomes", "goaded", "gobble", "gobies", "goober", "gouges",
				"gourds", "grainy", "grants", "graphs", "grates", "graven", "grebes", "greets", "greyed", "grieve",
				"groats", "groovy", "grovel", "groves", "guilds", "gummed", "gunman", "gunmen", "haggis", "halite",
				"halted", "hamper", "hanger", "hangup", "happen", "harass", "harbor", "having", "headed", "health",
				"hearts", "heated", "heaves", "heddle", "heeded", "height", "helped", "herder", "hereof", "heresy",
				"hermit", "herons", "hiatus", "highly", "hinted", "hipped", "hippie", "hitter", "holler", "hombre",
				"homers", "hominy", "honest", "honeys", "hoodie", "hoopoe", "hooves", "hopper", "horned", "horror",
				"hosing", "hotels", "howled", "hubbub", "hubris", "huddle", "humbly", "humbug", "hummus", "hunker",
				"hurdle", "hushed", "husker", "hymnal", "hyphen", "iceman", "imager", "imbued", "impair", "impugn",
				"inched", "indigo", "indole", "induct", "infant", "infest", "inform", "inking", "inning", "inputs",
				"insane", "inside", "insole", "invite", "inward", "islets", "isobar", "issues", "italic", "jabbed",
				"jacked", "jaunts", "jaunty", "jigger", "jigsaw", "jingle", "jokers", "jovian", "juggle", "juntas",
				"jurors", "kaftan", "karats", "keeper", "ketone", "kicked", "killed", "kimchi", "kindle", "kindly",
				"kiosks", "kismet", "kitbag", "kitted", "kitten", "kittle", "knifed", "knocks", "knowns", "koalas",
				"kvetch", "labile", "lackey", "ladder", "lament", "landau", "landed", "lapdog", "lapels", "laptop",
				"lasing", "lasses", "lasted", "lawyer", "layman", "laymen", "lazily", "league", "leaner", "leaves",
				"legume", "lender", "lesion", "lessee", "liable", "licked", "lifter", "likely", "liming", "limped",
				"limpid", "linage", "linens", "liners", "lingua", "linker", "little", "livery", "living", "loaded",
				"loader", "loaned", "loathe", "locate", "lodges", "looney", "looped", "looser", "looses", "louver",
				"loving", "lowest", "lowing", "lulled", "lumped", "luring", "lurked", "lusted", "luxury", "lyceum",
				"machos", "macros", "maimed", "making", "mallee", "mallow", "malted", "mangle", "maniac", "mantel",
				"manure", "mapper", "marked", "market", "maroon", "masons", "massif", "matter", "maxims", "mayors",
				"medals", "medley", "meeker", "melody", "member", "memory", "menace", "mended", "merely", "merest",
				"merino", "metals", "method", "methyl", "micron", "midair", "midden", "midrib", "mimics", "minced",
				"minors", "minted", "mirage", "misery", "mishap", "missal", "moaned", "mobbed", "mocked", "modern",
				"modest", "modulo", "moiety", "moment", "moneys", "months", "morrow", "mortar", "motels", "mother",
				"mounds", "mounts", "mouthy", "mouton", "museum", "musher", "mussel", "mutant", "mutton", "myopic",
				"myself", "mystic", "mythos", "nagged", "nailed", "nannie", "napped", "napper", "native", "navels",
				"nearby", "neared", "netted", "niacin", "nickel", "nipper", "nipple", "nobler", "noises", "nomads",
				"norths", "notify", "novena", "nudges", "number", "nutmeg", "nutria", "oblate", "obsess", "obtain",
				"obtuse", "occult", "oddest", "oddity", "odious", "offend", "office", "oldest", "online", "opened",
				"openly", "optics", "orbits", "ordain", "orders", "orgies", "origin", "ornate", "osprey", "others",
				"otters", "outdid", "outers", "output", "outrun", "owners", "oxides", "oxygen", "pagans", "paging",
				"pained", "paints", "palate", "paltry", "pandan", "pander", "parens", "parent", "parish", "parkas",
				"parlay", "parley", "parlor", "parody", "parole", "parrot", "parsed", "parses", "partly", "pastas",
				"pastel", "pastor", "payees", "payors", "peaker", "peapod", "pearly", "pecked", "peeler", "peeves",
				"pelvis", "people", "period", "person", "petals", "petite", "petrel", "petted", "phased", "phones",
				"phonic", "photos", "picker", "piddle", "pillar", "pillow", "pinger", "pipped", "pistil", "pistol",
				"plague", "plaids", "plaint", "plated", "plates", "playas", "played", "player", "pleads", "please",
				"plexus", "plural", "points", "police", "policy", "polkas", "polled", "poplar", "poppet", "portal",
				"posses", "possum", "postal", "poured", "precis", "prefer", "preset", "pretty", "preyed", "prised",
				"prissy", "proofs", "propel", "propyl", "proven", "prover", "pseudo", "public", "puffin", "pulley",
				"pulser", "pumper", "pundit", "pupils", "puppet", "purged", "purple", "puzzle", "pylons", "quarry",
				"queues", "quiver", "rabbit", "rabble", "rabies", "racing", "racked", "racoon", "radian", "radios",
				"raffia", "raffle", "raider", "rained", "ramjet", "rammed", "ranged", "ranked", "ranker", "rapper",
				"rashly", "rather", "ravers", "ravine", "really", "reaper", "reason", "rebels", "rebind", "recast",
				"recede", "reckon", "record", "recoup", "rectal", "rector", "redden", "redial", "redraw", "reefer",
				"refers", "refuel", "refute", "regime", "region", "reheat", "reined", "relate", "relent", "relied",
				"remain", "remand", "remits", "remove", "renege", "renown", "rented", "repeat", "report", "rescan",
				"reseal", "resent", "resign", "result", "retake", "retest", "return", "reverb", "revere", "review",
				"revise", "revive", "revolt", "revues", "revved", "rewire", "rhesus", "rhumba", "rhymer", "rhymes",
				"ribbon", "riches", "riding", "riffle", "rigged", "rigger", "righty", "rioted", "ripper", "riprap",
				"rising", "roader", "roared", "robbed", "rookie", "rooter", "rosary", "rotors", "rotten", "roughs",
				"roused", "rouser", "routes", "royals", "rubber", "rudder", "rueful", "rufous", "ruling", "rushed",
				"sachem", "saddle", "safari", "sagged", "sailer", "sanely", "sanity", "sarong", "satiny", "satyrs",
				"savant", "saying", "scalps", "scarfs", "schist", "school", "scopes", "scorch", "scored", "scorer",
				"scores", "scorns", "scours", "scouse", "scouts", "scrape", "scraps", "scrawl", "scrips", "scroll",
				"scrubs", "sculls", "season", "seaway", "secede", "second", "secret", "sector", "sedges", "seeker",
				"sender", "septic", "series", "setups", "sevens", "sewage", "shader", "shades", "shafts", "shaggy",
				"shales", "shamed", "shanty", "shaper", "shapes", "sharps", "sherry", "shiner", "shines", "shoppe",
				"shorty", "should", "shrews", "shrink", "shroud", "shrubs", "shunts", "sicker", "sidled", "sieves",
				"silage", "simmer", "simply", "sinewy", "single", "singly", "siphon", "sipper", "sitcom", "sitter",
				"skater", "sketch", "skills", "skyway", "slalom", "slings", "sloppy", "slough", "smacks", "smarmy",
				"smidge", "smiley", "smocks", "smudge", "smugly", "snacks", "snippy", "snuffy", "soaked", "social",
				"socked", "soiled", "soothe", "sorrow", "sought", "souped", "sowing", "spaced", "sparse", "specie",
				"specks", "speeds", "spells", "spices", "spiffy", "spinal", "spined", "spoons", "spores", "sprang",
				"sprays", "spring", "sprite", "sprung", "spurns", "spying", "square", "squawk", "staple", "stared",
				"stares", "starts", "stater", "states", "statue", "steamy", "steels", "steers", "stifle", "stinky",
				"stints", "stitch", "stoked", "stomps", "stools", "storks", "stowed", "straws", "street", "strewn",
				"strode", "strong", "strove", "struck", "stunts", "stupid", "subpar", "subsea", "subset", "subtly",
				"sucker", "suckle", "sudden", "sugars", "suited", "sunder", "sundew", "sundog", "sundry", "suplex",
				"surety", "surfer", "surged", "swales", "swamps", "swathe", "swears", "sweaty", "swifty", "swirls",
				"swivel", "swords", "syndic", "syrupy", "system", "tablet", "tacker", "taking", "talked", "tamper",
				"tangle", "tanked", "tanner", "tapped", "tapper", "target", "tattle", "tawdry", "teases", "teensy",
				"temper", "tempts", "tended", "tenner", "tennis", "tented", "termed", "thanks", "things", "though",
				"throat", "throbs", "throne", "thrush", "tickle", "tildes", "tilted", "tilter", "timers", "tiptoe",
				"tiptop", "tissue", "titers", "toasty", "toffee", "toiled", "tokens", "tomato", "tomcat", "toners",
				"tonics", "towels", "tracks", "trader", "trains", "treads", "trials", "tricks", "tricky", "troupe",
				"trying", "tsetse", "tufted", "tumult", "tundra", "turbid", "turbos", "turnip", "tuxedo", "twelve",
				"twined", "typify", "ulcers", "umlaut", "uncool", "undone", "undyed", "unhook", "united", "unites",
				"unless", "unlink", "unlock", "unread", "unroll", "unseat", "unspun", "unsung", "untrue", "unused",
				"unveil", "update", "upkeep", "urbane", "urgent", "urging", "ursine", "usable", "utopia", "valets",
				"valued", "valves", "vandal", "varies", "veered", "veiled", "venial", "verily", "vernal", "versed",
				"versus", "vertex", "vestry", "villas", "vining", "violet", "violin", "vireos", "virile", "vistas",
				"vizier", "voodoo", "vortex", "voters", "vowing", "wading", "wagers", "waited", "wanted", "warder",
				"warmly", "weapon", "wetted", "whaler", "whammy", "whence", "whinge", "whiten", "whoops", "wicked",
				"wiener", "wigeon", "wiggle", "wiggly", "wigwam", "window", "winnow", "wintry", "wipers", "within",
				"wolves", "wombat", "woolen", "woolly", "worded", "wormed", "wretch", "wrongs", "yahoos", "yawned",
				"yeoman", "yippee", "yogurt", "zealot", "zenith", "zephyr", "zeroes", "zigzag", "zinger", "zinnia",
				"zodiac", "zombie", "zoomed", "zygote"
			};
			SevenLetterWords = new string[1601]
			{
				"abating", "abiding", "ability", "abolish", "abyssal", "acacias", "academy", "accents", "account", "acquire",
				"acreage", "actions", "acutely", "address", "adjunct", "adjusts", "adviser", "affixed", "affront", "against",
				"aground", "aircrew", "airflow", "airmail", "allelic", "allowed", "allured", "almanac", "almonds", "alpacas",
				"already", "amateur", "amazing", "ambling", "amended", "ammonia", "amorous", "amyloid", "anarchy", "anguish",
				"annexes", "annulus", "another", "answers", "antacid", "antenna", "anthems", "antonym", "anymore", "apostle",
				"apparel", "applies", "aqueous", "archery", "archive", "armband", "armorer", "arouses", "arrival", "arsenic",
				"article", "artless", "arugula", "asylums", "attract", "aunties", "auroras", "austere", "authors", "avenger",
				"avenues", "average", "awakens", "awaking", "awesome", "babbled", "babysit", "backing", "backlog", "badgers",
				"baggage", "ballads", "ballots", "baneful", "banging", "bangles", "banking", "banquet", "baptize", "barking",
				"baronet", "baroque", "barring", "bashful", "basques", "bathtub", "battles", "baubles", "beading", "bearish",
				"beavers", "because", "bedrock", "beepers", "beeping", "befalls", "belcher", "beliefs", "believe", "belongs",
				"belting", "bending", "benefit", "berated", "betrays", "betting", "bettors", "between", "bicycle", "bifocal",
				"biggest", "biology", "biotics", "birding", "bishops", "bitumen", "blacked", "blacken", "blaming", "blankly",
				"bleeder", "blessed", "blinded", "blister", "blitzed", "blocker", "bloomed", "blooper", "blouses", "blowers",
				"blunted", "blurred", "blurted", "blusher", "boarded", "boatmen", "boffins", "boggles", "bolding", "bollard",
				"bombard", "bonuses", "bookend", "bookies", "booklet", "boolean", "boomers", "booster", "boredom", "borings",
				"borough", "bossier", "bothers", "bottles", "bouncer", "bounces", "bowhead", "boycott", "bracing", "brasher",
				"braving", "breaded", "breathy", "breezes", "bribery", "bridals", "briefed", "brights", "brining", "briskly",
				"bristle", "bristly", "broadly", "bromide", "bronzes", "brother", "brought", "brownie", "browsed", "bruises",
				"brutish", "buddies", "budgets", "buffers", "buffets", "bugbear", "bulbous", "bulging", "bulking", "bulldog",
				"bullies", "bullish", "bullpen", "bumpers", "bunched", "bungled", "bunting", "buoyant", "bureaus", "burgers",
				"burrito", "butters", "buttery", "buyouts", "cabanas", "cabinet", "caching", "cadmium", "calcium", "calling",
				"cantons", "capping", "caprice", "captain", "captors", "carafes", "caramel", "caravan", "carcass", "cargoes",
				"carpets", "carrion", "carrots", "cartoon", "castors", "catarrh", "catcher", "catches", "catered", "causing",
				"caveman", "ceasing", "cements", "censors", "censure", "centers", "central", "century", "certain", "ceviche",
				"chafing", "chalice", "challah", "changed", "changes", "channel", "chanted", "chaotic", "chapped", "charger",
				"charted", "chasers", "chasing", "checker", "cherubs", "chevron", "chicory", "chiming", "choline", "chopped",
				"chorale", "chorizo", "chucked", "clapped", "clashed", "classic", "cleanse", "clearly", "clicked", "climbed",
				"clinger", "clipped", "clipper", "clogged", "closely", "closeup", "clotted", "clovers", "clubbed", "coaches",
				"coasted", "coerced", "cognate", "collars", "college", "combust", "comedic", "comment", "commies", "commune",
				"company", "compare", "compels", "compere", "comport", "compose", "conceal", "concert", "concise", "condemn",
				"condors", "conjure", "console", "consume", "contact", "contend", "content", "contest", "control", "convert",
				"cookout", "coolest", "coopers", "cooties", "coppers", "copycat", "cornets", "coronet", "corsage", "cougars",
				"coulomb", "council", "country", "courage", "courant", "coursed", "courses", "covered", "cowbird", "coyotes",
				"cracked", "crackle", "crashed", "creaked", "created", "credits", "crimper", "crimson", "cronies", "cropper",
				"crowing", "crucify", "crudely", "cruelly", "crusher", "crushes", "cubbies", "cubicle", "culture", "culvert",
				"cumulus", "cunning", "currant", "current", "curried", "cushion", "cuticle", "cutlery", "cyclops", "cypress",
				"dabbled", "damping", "damsels", "dancing", "dawning", "daytime", "debater", "debtors", "decease", "decided",
				"decimal", "deckers", "decoder", "decodes", "decreed", "deduced", "deeming", "defiant", "defraud", "defunct",
				"defused", "deicing", "deliver", "deltoid", "demands", "demonic", "demoted", "deniers", "densest", "depicts",
				"deposed", "depress", "dequeue", "derails", "derived", "derives", "designs", "desired", "desktop", "despite",
				"details", "detects", "detente", "devises", "devours", "diabolo", "dialing", "dictate", "diesels", "digests",
				"diggers", "digging", "digital", "dilated", "dilator", "dinette", "diorama", "dirtier", "disable", "disease",
				"dislike", "display", "dispute", "diurnal", "divider", "divides", "divisor", "doctors", "dollars", "dominos",
				"donning", "dossier", "drafted", "dragoon", "dreaded", "drifter", "drinker", "drizzly", "droning", "dubious",
				"durable", "dusting", "dyeable", "eagerly", "earlier", "earlobe", "earners", "earshot", "echelon", "echoing",
				"edibles", "edifice", "edition", "ejected", "elected", "elector", "elution", "embassy", "embolic", "eminent",
				"emirate", "empower", "emptied", "emulate", "encased", "encores", "endgame", "endings", "endowed", "endures",
				"enjoins", "enjoyed", "enlaces", "enraged", "enteric", "envious", "enzymes", "episode", "erosive", "erratum",
				"estates", "evacuee", "evaders", "evasion", "evoking", "evolved", "exactly", "examine", "example", "excises",
				"exciter", "excites", "exempts", "existed", "explain", "exploit", "exports", "expunge", "faculty", "faintly",
				"fairies", "falcons", "fangled", "farmers", "farming", "farther", "fascias", "fastest", "fatally", "fateful",
				"fathers", "favored", "fawning", "federal", "feeders", "feelers", "feeling", "females", "fetched", "fielder",
				"fifteen", "figures", "filling", "finally", "finance", "fishery", "fission", "flaming", "flatbed", "flecked",
				"flicked", "floated", "floored", "flopped", "flowery", "fluidic", "flutter", "foaming", "folders", "fondled",
				"fooling", "footway", "forages", "forceps", "foresaw", "forests", "forgave", "forging", "forgive", "forsake",
				"forward", "framers", "fraying", "freeing", "freezer", "frescos", "freshly", "friends", "frigate", "fringes",
				"fuchsia", "fuelled", "fulcrum", "fumbles", "funnies", "further", "futures", "gallery", "galling", "gallops",
				"gambler", "gangway", "gapping", "garners", "garters", "gasping", "gazelle", "gazette", "gelatin", "general",
				"genetic", "genital", "gestalt", "getting", "gigabit", "giraffe", "glacial", "glamour", "glanced", "glassed",
				"glazing", "gleeful", "glimmer", "glossed", "glutton", "goalies", "gobbler", "godhead", "goofing", "goulash",
				"gracing", "grained", "granary", "grander", "granola", "granted", "grantee", "granule", "grassed", "gravest",
				"graying", "greases", "greater", "greener", "gremlin", "grenade", "griddle", "gripper", "grizzle", "grooved",
				"grosses", "grouchy", "grouped", "growing", "growths", "grudges", "grumble", "guessed", "gumtree", "gymnast",
				"habitat", "hacksaw", "halcyon", "hallows", "hallway", "halting", "hammers", "hamster", "handing", "handoff",
				"hapless", "haploid", "happens", "harmony", "harping", "harpoon", "hastens", "hatches", "haulage", "hawkish",
				"hayseed", "hazards", "healers", "heaping", "heaters", "heavier", "heights", "helmets", "hickory", "himself",
				"hipster", "history", "hitched", "hobnail", "hoedown", "hoisted", "hollers", "hollows", "hooting", "hopeful",
				"hoppers", "hopping", "hormone", "horrors", "hospice", "hostels", "hostile", "hosting", "hotdogs", "hotline",
				"however", "hulking", "humanly", "humbled", "humerus", "humidor", "humming", "hunters", "husband", "huskers",
				"huskies", "idyllic", "ignited", "imagine", "impaler", "imperil", "impiety", "impious", "implies", "imposed",
				"impound", "imprint", "improve", "imputed", "include", "indents", "indexed", "indexer", "indexes", "indicts",
				"indulge", "infects", "inflict", "infuser", "ingress", "injects", "injured", "innings", "inquest", "inroads",
				"insider", "insides", "insight", "insists", "inspect", "instate", "instead", "insured", "insures", "invents",
				"inverse", "ionized", "ionizer", "islands", "isomers", "isotope", "issuers", "jackals", "janitor", "january",
				"jarring", "jazzman", "jeepers", "jellies", "jerking", "jigsaws", "jobbers", "jobsite", "joiners", "joining",
				"jolting", "journal", "judging", "jungles", "justice", "karaoke", "kernels", "ketchup", "ketones", "ketosis",
				"keylock", "keypads", "kicking", "kimonos", "kindred", "kinetic", "kissing", "kitting", "kneeled", "knowhow",
				"labored", "lacking", "lagging", "lagoons", "lancets", "largely", "latches", "lateral", "launder", "lawless",
				"layaway", "leaders", "leading", "leaflet", "leaking", "leaving", "lecture", "leeward", "legumes", "leisure",
				"lemming", "leopard", "lessees", "liberty", "library", "licking", "lifting", "likable", "lilting", "limited",
				"limiter", "lintels", "listens", "listing", "lithium", "liturgy", "livable", "lobbies", "located", "locater",
				"locates", "lockets", "locknut", "lodging", "logbook", "looking", "lookout", "lookups", "looming", "lotions",
				"louvers", "loyalty", "lurkers", "machine", "magical", "magnify", "mahjong", "mailbox", "maiming", "majored",
				"malting", "manager", "manatee", "mangers", "mangoes", "mankind", "mansion", "mariner", "markets", "married",
				"marries", "marshal", "martial", "martyrs", "massing", "mastiff", "mastoid", "matinee", "maudlin", "mauling",
				"maxilla", "meaning", "medical", "mediums", "meeting", "melanin", "members", "mermaid", "message", "meteors",
				"microbe", "middles", "midline", "midterm", "million", "mimosas", "mincing", "minding", "mingled", "mingles",
				"minimum", "minnows", "minuses", "minutes", "miserly", "mislead", "missile", "missing", "mistake", "modeled",
				"modular", "moments", "monarch", "montage", "monthly", "moorhen", "moorish", "morning", "mosaics", "mothers",
				"mountie", "mulling", "mullion", "mumbles", "mummies", "musings", "muskets", "muskrat", "mutable", "mutants",
				"mutates", "mutters", "mystics", "nagging", "napkins", "natural", "nebulae", "nesting", "netball", "netting",
				"network", "nibbles", "nightly", "nipping", "noisily", "noncash", "nonstop", "notable", "notably", "notched",
				"notches", "nothing", "noticed", "novelty", "nozzles", "numbers", "numeric", "nurture", "nutcase", "oakmoss",
				"obviate", "ocarina", "octaves", "october", "offends", "offeror", "officer", "offside", "ominous", "omnibus",
				"onboard", "oneself", "onshore", "openers", "opening", "opinion", "opossum", "optical", "options", "oracles",
				"oranges", "orbital", "ordeals", "outcome", "outfits", "outlets", "outlier", "outrage", "outside", "overdue",
				"overrun", "oversaw", "oxfords", "oysters", "pageant", "paisley", "pampers", "panacea", "pancake", "paneled",
				"panning", "pansies", "papayas", "parable", "paraded", "parapet", "parents", "parfait", "parlors", "paroled",
				"parsley", "parsons", "parties", "passage", "passing", "passive", "pastors", "patella", "patrons", "pattern",
				"pausing", "payable", "payment", "payroll", "pecking", "penalty", "pending", "peonies", "percent", "percept",
				"perches", "perfect", "perfume", "perhaps", "pickets", "picture", "piercer", "pigtail", "pincher", "pinkish",
				"pinless", "pirated", "pitched", "pitfall", "pivoted", "plainer", "plainly", "planets", "planted", "planter",
				"plateau", "platoon", "players", "playing", "pleases", "pliable", "plotter", "plunges", "plywood", "poetess",
				"pointed", "pointer", "pontiff", "pontoon", "pooling", "poppies", "popular", "porcine", "possums", "postbag",
				"postfix", "posting", "postman", "postwar", "potions", "powdery", "powered", "preachy", "preamps", "precise",
				"pregame", "preheat", "premise", "prepare", "present", "preteen", "preying", "primacy", "priming", "prisons",
				"privacy", "private", "problem", "process", "proctor", "prodded", "produce", "product", "profess", "profile",
				"profits", "program", "project", "prolong", "protect", "provide", "proving", "proxied", "proxies", "prudent",
				"psyched", "publish", "puffing", "pulsars", "punched", "punches", "pungent", "puritan", "pursuer", "pushing",
				"pushrod", "putters", "puzzled", "pygmies", "pyramid", "quality", "quantal", "quarrel", "quickly", "quintet",
				"quizzes", "radiate", "raiders", "raiding", "railway", "raining", "rallied", "rambled", "rancher", "ranchos",
				"rangers", "rapidly", "rappers", "rascals", "rattled", "ravioli", "rawhide", "reached", "reacher", "reading",
				"readout", "reasons", "rebuked", "recalls", "recipes", "reckons", "recline", "records", "rectors", "rectory",
				"recurse", "recusal", "recused", "redbird", "reddish", "redfish", "reeling", "reentry", "referee", "reflect",
				"refocus", "reforms", "refuted", "regaled", "regency", "regimen", "regress", "regrets", "regroup", "regular",
				"reissue", "rejoice", "relapse", "related", "relaxed", "release", "reliant", "remakes", "remarks", "remarry",
				"remixed", "remnant", "remodel", "removes", "renames", "rentals", "renters", "reorder", "repeals", "repents",
				"replays", "replete", "reports", "reproof", "repulse", "request", "rescale", "resists", "resound", "respect",
				"restate", "results", "retails", "reticle", "retract", "retread", "returns", "reunion", "reveals", "reveled",
				"revered", "reverse", "reviews", "reviser", "revisor", "revived", "rewinds", "rewrote", "ribbons", "ricotta",
				"ridding", "riddled", "rioting", "ripcord", "ripoffs", "riposte", "rippers", "riveted", "riveter", "roaring",
				"roasted", "roebuck", "rollout", "romaine", "rompers", "roofing", "rooster", "rotator", "rounded", "rounder",
				"rousing", "royalty", "ruffles", "rumbled", "rumored", "rundown", "running", "runtime", "rustled", "saguaro",
				"saintly", "salmons", "salting", "salvage", "sampled", "sandman", "saucers", "savages", "savings", "savored",
				"sayings", "scalper", "scamper", "scanner", "scarcer", "scarier", "scarred", "scatter", "schools", "science",
				"scissor", "scooped", "scooter", "scourge", "scouted", "scraped", "scrapes", "scratch", "scribes", "scrubby",
				"seasons", "seaters", "seconds", "secrete", "section", "seeders", "seethed", "seismic", "selfish", "sellout",
				"serious", "servant", "service", "settles", "several", "shadowy", "shakeup", "shapely", "sharing", "sheared",
				"sheaths", "sheeted", "shellac", "shifted", "shifter", "shingle", "shipper", "shocker", "shoeing", "shovels",
				"showers", "shrieks", "shrinks", "shudder", "shuffle", "sickens", "sidecar", "sigmoid", "signers", "silents",
				"similar", "similes", "sirloin", "sizzler", "skewing", "skidded", "skillet", "skimmed", "skipper", "skylark",
				"slander", "slapped", "sleeper", "slicker", "slivers", "sloping", "smacked", "smarter", "smiling", "smitten",
				"smudges", "smuggle", "sneaked", "sneezed", "snicker", "snorkel", "snuffed", "soaking", "soberly", "society",
				"softest", "softies", "someone", "sonnets", "soothed", "sorcery", "sorrows", "sorters", "sorting", "sources",
				"spatial", "spawner", "spaying", "special", "species", "specify", "specter", "spiders", "spiller", "spindle",
				"spinner", "splints", "spotter", "squalls", "squeals", "squishy", "stabler", "stainer", "stamped", "stapled",
				"starker", "started", "station", "statute", "stereos", "sterner", "stipend", "stopgap", "stopped", "stopper",
				"stories", "storing", "streets", "strolls", "stubble", "student", "studies", "stuffed", "stunned", "subdued",
				"subject", "sublime", "subsume", "subtype", "success", "suggest", "summery", "summons", "sunrise", "sunsets",
				"sunspot", "suppers", "support", "surface", "surfers", "surgeon", "surgery", "surreal", "swapper", "swarmed",
				"swarthy", "sweeper", "swifter", "swisher", "systems", "tablets", "tacitly", "tacking", "tactics", "tailors",
				"talking", "tamping", "tangent", "tangles", "tanners", "tannery", "tannins", "tantrum", "tapioca", "tassels",
				"tatting", "tattoos", "teaches", "teacups", "teasers", "tedious", "tempted", "tempter", "tenable", "tenders",
				"tending", "tenures", "termini", "testbed", "testers", "tetanus", "textual", "theater", "thereon", "thicken",
				"thimble", "thirdly", "thirsty", "thither", "thought", "threads", "through", "thumbed", "thumper", "tickets",
				"tickled", "tidings", "tidying", "tilings", "tinting", "tippers", "tissues", "tithing", "toaster", "toggled",
				"toggles", "toiling", "tonight", "tooting", "topiary", "topside", "torrent", "tossing", "touched", "touches",
				"touting", "towards", "toyland", "traffic", "tragedy", "trapped", "treason", "treated", "trefoil", "tresses",
				"tricked", "trigram", "trimmed", "triplet", "tripods", "tritone", "trolled", "troller", "trotted", "trustee",
				"tubular", "tumbles", "tutored", "twaddle", "tweedle", "tweeter", "twiddle", "twining", "twinkle", "twisted",
				"ugliest", "unarmed", "unasked", "unblock", "uncivil", "unfired", "unicorn", "unifies", "unknown", "unlearn",
				"unspent", "untruth", "untying", "untyped", "unwired", "updated", "upholds", "uploads", "upwards", "usually",
				"utilize", "utopian", "vacancy", "vaccine", "vagrant", "valiant", "various", "vassals", "vectors", "velvety",
				"vendors", "verbose", "verdant", "version", "vertigo", "vestige", "vetting", "vibrant", "violent", "virtues",
				"viruses", "viscous", "visions", "visuals", "voicing", "wafting", "waiting", "wallaby", "walling", "wardens",
				"warming", "warning", "warring", "warrior", "warthog", "website", "weekend", "welcome", "wettest", "whaling",
				"wheelie", "whereby", "wherein", "whether", "whitish", "whizzes", "widower", "winches", "windows", "windrow",
				"winging", "winking", "winless", "winning", "winsome", "wiretap", "wisdoms", "wishful", "wishing", "without",
				"wizards", "wobbler", "workers", "working", "workmen", "wrapper", "wreaths", "wriggle", "writing", "written",
				"xylitol"
			};
			_hasPluginConflict = ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("000-the_tavern-AutogenRundown") || ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("com.Brandont.LongerCodes");
			if (_hasPluginConflict)
			{
				EOSLogger.Warning("Conflicting plugin: \"000-the_tavern-AutogenRundown\" and/or \"com.Brandont.LongerCodes\". Using default SerialGenerator settings");
			}
		}

		private static void OnBuildStart()
		{
			_random = RandomUtil.CreateSessionRandom("EOS_SerialGenerator");
			_codeWords.Clear();
			_codeWords[CodeWordLength.Three] = new ShuffledStepArray(ThreeLetterWords);
			_codeWords[CodeWordLength.Five] = new ShuffledStepArray(FiveLetterWords);
			_codeWords[CodeWordLength.Six] = new ShuffledStepArray(SixLetterWords);
			_codeWords[CodeWordLength.Seven] = new ShuffledStepArray(SevenLetterWords);
			_hardPrefixes = new ShuffledStepArray(HardCodeWordPrefixes);
		}

		public static void Init()
		{
			LevelAPI.OnBuildStart += OnBuildStart;
		}

		public static int GetUniqueSerialNo()
		{
			return SerialGenerator.GetUniqueSerialNo();
		}

		public static string GetIPAddress(bool useIPv6)
		{
			if (_hasPluginConflict || !useIPv6)
			{
				return SerialGenerator.GetIpAddress();
			}
			string[] array = new string[4]
			{
				RandomHex(256, 4608),
				RandomHex(4096, 65535),
				RandomHex(0, 511),
				RandomHex(0, 16383)
			};
			int num = array.Length;
			while (num > 1)
			{
				int num2 = _random.Next(0, num--);
				ref string reference = ref array[num2];
				ref string reference2 = ref array[num];
				string text = array[num];
				string text2 = array[num2];
				reference = text;
				reference2 = text2;
			}
			return RandomHex(8192, 16383) + "::" + string.Join(':', array);
		}

		private static string RandomHex(int min, int max)
		{
			return _random.Next(min, max).ToString("x");
		}

		public static string GetCodeWord(CodeWordLength wordLength)
		{
			if (_hasPluginConflict || !_codeWords.TryGetValue(wordLength, out var value))
			{
				return SerialGenerator.GetCodeWord();
			}
			return value.Next();
		}

		public static string GetCodeWordPrefix(bool useHardPrefixes, bool hyphenate = false)
		{
			string text = ((!_hasPluginConflict && useHardPrefixes) ? _hardPrefixes.Next() : SerialGenerator.

plugins/AmorLib.dll

Decompiled 2 days ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using AIGraph;
using Agents;
using AmorLib.API;
using AmorLib.Dependencies;
using AmorLib.Events;
using AmorLib.Utils;
using AmorLib.Utils.Extensions;
using AmorLib.Utils.JsonElementConverters;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CullingSystem;
using GTFO.API;
using GTFO.API.Extensions;
using GTFO.API.JSON;
using GTFO.API.JSON.Converters;
using GTFO.API.Utilities;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using InjectLib.JsonNETInjection.Supports;
using LevelGeneration;
using Localization;
using MTFO.Ext.PartialData;
using MTFO.Managers;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using SemanticVersioning;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("AmorLib")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ca3f17a6fa8ba94a25bbaf8db1f8b73b29636030")]
[assembly: AssemblyProduct("AmorLib")]
[assembly: AssemblyTitle("AmorLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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 AmorLib
{
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
	internal sealed class CallConstructorOnLoadAttribute : Attribute
	{
	}
	[BepInPlugin("Amor.AmorLib", "AmorLib", "1.3.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class EntryPoint : BasePlugin
	{
		public override void Load()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Logger.MLS = ((BasePlugin)this).Log;
			new Harmony("Amor.AmorLib").PatchAll();
			CallAllAutoConstructors();
			Logger.Message("AmorLib is done loading!");
		}

		private void CallAllAutoConstructors()
		{
			IEnumerable<Type> enumerable = from t in AccessTools.GetTypesFromAssembly(((object)this).GetType().Assembly)
				where t.IsDefined(typeof(CallConstructorOnLoadAttribute), inherit: false)
				select t;
			foreach (Type item in enumerable)
			{
				RuntimeHelpers.RunClassConstructor(item.TypeHandle);
			}
		}
	}
	internal static class Logger
	{
		public static ManualLogSource MLS { get; internal set; }

		public static void Error(BepInExErrorLogInterpolatedStringHandler handler)
		{
			MLS.LogError(handler);
		}

		public static void Error(string str)
		{
			MLS.LogError((object)str);
		}

		public static void Warn(BepInExWarningLogInterpolatedStringHandler handler)
		{
			MLS.LogWarning(handler);
		}

		public static void Warn(string str)
		{
			MLS.LogWarning((object)str);
		}

		public static void Message(BepInExMessageLogInterpolatedStringHandler handler)
		{
			MLS.LogMessage(handler);
		}

		public static void Message(string str)
		{
			MLS.LogMessage((object)str);
		}

		public static void Info(BepInExInfoLogInterpolatedStringHandler handler)
		{
			MLS.LogInfo(handler);
		}

		public static void Info(string str)
		{
			MLS.LogInfo((object)str);
		}

		public static void Debug(BepInExDebugLogInterpolatedStringHandler handler)
		{
			MLS.LogDebug(handler);
		}

		public static void Debug(string str)
		{
			MLS.LogDebug((object)str);
		}
	}
}
namespace AmorLib.Utils
{
	[CallConstructorOnLoad]
	public static class CourseNodeUtil
	{
		private class DimensionMap
		{
			private const float IndexSize = 4f;

			public List<AIG_CourseNode>?[,] BuildNodeMap;

			public AIG_CourseNode[,][] NodeMap;

			public (int x, int z) MinCellBound;

			public (int x, int z) MaxCellBound;

			public (int x, int z) MapSize;

			internal DimensionMap()
			{
				BuildNodeMap = null;
				NodeMap = null;
				MapSize = (x: 0, z: 0);
				MinCellBound = (x: int.MaxValue, z: int.MaxValue);
				MaxCellBound = (x: int.MinValue, z: int.MinValue);
			}

			internal void UpdateBounds(Vector3 position)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				int val = (int)(position.x / 4f);
				int val2 = (int)(position.z / 4f);
				MinCellBound = (x: Math.Min(val, MinCellBound.x), z: Math.Min(val2, MinCellBound.z));
				MaxCellBound = (x: Math.Max(val, MaxCellBound.x), z: Math.Max(val2, MaxCellBound.z));
			}

			internal void CreateNodeMap()
			{
				MapSize = (x: MaxCellBound.x - MinCellBound.x + 1, z: MaxCellBound.z - MinCellBound.z + 1);
				BuildNodeMap = new List<AIG_CourseNode>[MapSize.x, MapSize.z];
				NodeMap = new AIG_CourseNode[MapSize.x, MapSize.z][];
			}

			internal (int x, int z) GetMapPos(Vector3 position)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				return (x: Math.Clamp((int)(position.x / 4f) - MinCellBound.x, 0, MapSize.x - 1), z: Math.Clamp((int)(position.z / 4f) - MinCellBound.z, 0, MapSize.z - 1));
			}

			internal List<AIG_CourseNode> GetBuildNodeList(Vector3 position)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				(int x, int z) mapPos = GetMapPos(position);
				int item = mapPos.x;
				int item2 = mapPos.z;
				List<AIG_CourseNode> list = BuildNodeMap[item, item2];
				if (list == null)
				{
					list = (BuildNodeMap[item, item2] = new List<AIG_CourseNode>());
				}
				return list;
			}

			internal void FinishBuild()
			{
				for (int i = 0; i < MapSize.x; i++)
				{
					for (int j = 0; j < MapSize.z; j++)
					{
						NodeMap[i, j] = BuildNodeMap[i, j]?.ToArray();
					}
				}
				BuildNodeMap = null;
			}

			public AIG_CourseNode[] GetNodes(Vector3 position)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c0: Expected O, but got Unknown
				//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
				var (num, num2) = GetMapPos(position);
				if (NodeMap[num, num2] != null)
				{
					return NodeMap[num, num2];
				}
				float num3 = Math.Max(MapSize.x, MapSize.z);
				for (int i = 1; (float)i < num3; i++)
				{
					int num4 = Math.Max(num - i, 0);
					int num5 = Math.Min(num + i, MapSize.x - 1);
					int num6 = Math.Max(num2 - i, 0);
					int num7 = Math.Min(num2 + i, MapSize.z - 1);
					for (int j = num4; j <= num5; j++)
					{
						if (NodeMap[j, num6] != null)
						{
							return NodeMap[j, num6];
						}
						if (NodeMap[j, num7] != null)
						{
							return NodeMap[j, num7];
						}
					}
					for (int k = num6 + 1; k <= num7 - 1; k++)
					{
						if (NodeMap[num4, k] != null)
						{
							return NodeMap[num4, k];
						}
						if (NodeMap[num5, k] != null)
						{
							return NodeMap[num5, k];
						}
					}
				}
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(66, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Unable to get any node for (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(position);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")! How are you even playing the game?!");
				}
				Logger.Error(val);
				return null;
			}
		}

		private static readonly Dictionary<eDimensionIndex, DimensionMap> _maps;

		static CourseNodeUtil()
		{
			_maps = new Dictionary<eDimensionIndex, DimensionMap>();
			LevelAPI.OnAfterBuildBatch += OnAfterBuildBatch;
		}

		private static void OnAfterBuildBatch(BatchName batch)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			if ((int)batch != 38)
			{
				return;
			}
			_maps.Clear();
			Enumerator<AIG_NodeCluster> enumerator = AIG_NodeCluster.AllNodeClusters.GetEnumerator();
			while (enumerator.MoveNext())
			{
				AIG_NodeCluster current = enumerator.Current;
				object obj;
				if (current == null)
				{
					obj = null;
				}
				else
				{
					AIG_CourseNode courseNode = current.m_courseNode;
					obj = ((courseNode != null) ? courseNode.m_dimension : null);
				}
				if (obj != null)
				{
					if (!_maps.TryGetValue(current.m_courseNode.m_dimension.DimensionIndex, out DimensionMap value))
					{
						_maps.Add(current.m_courseNode.m_dimension.DimensionIndex, value = new DimensionMap());
					}
					Enumerator<AIG_INode> enumerator2 = current.m_nodes.GetEnumerator();
					while (enumerator2.MoveNext())
					{
						AIG_INode current2 = enumerator2.Current;
						value.UpdateBounds(current2.Position);
					}
				}
			}
			foreach (DimensionMap value2 in _maps.Values)
			{
				value2.CreateNodeMap();
			}
			Enumerator<AIG_NodeCluster> enumerator4 = AIG_NodeCluster.AllNodeClusters.GetEnumerator();
			while (enumerator4.MoveNext())
			{
				AIG_NodeCluster current4 = enumerator4.Current;
				object obj2;
				if (current4 == null)
				{
					obj2 = null;
				}
				else
				{
					AIG_CourseNode courseNode2 = current4.m_courseNode;
					obj2 = ((courseNode2 != null) ? courseNode2.m_dimension : null);
				}
				if (obj2 == null)
				{
					continue;
				}
				DimensionMap dimensionMap = _maps[current4.m_courseNode.m_dimension.DimensionIndex];
				int id = current4.CourseNode.NodeID;
				Enumerator<AIG_INode> enumerator5 = current4.m_nodes.GetEnumerator();
				while (enumerator5.MoveNext())
				{
					AIG_INode current5 = enumerator5.Current;
					List<AIG_CourseNode> buildNodeList = dimensionMap.GetBuildNodeList(current5.Position);
					if (!buildNodeList.Any((AIG_CourseNode node) => id == node.NodeID))
					{
						buildNodeList.Add(current4.CourseNode);
					}
				}
			}
			foreach (DimensionMap value3 in _maps.Values)
			{
				value3.FinishBuild();
			}
		}

		private static bool TryGetClosestNodeInCluster(AIG_NodeCluster cluster, Vector3 position, out AIG_INode node)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			AIG_VoxelNodeVolume voxelNodeVolume = cluster.m_nodeVolume.m_voxelNodeVolume;
			if (voxelNodeVolume.TryGetCloseVoxelNode_Safe(position, position.y - 0.5f, position.y + 0.5f, ref node, false))
			{
				return true;
			}
			int num = default(int);
			int num2 = default(int);
			voxelNodeVolume.GetGridPosition(position, ref num, ref num2);
			num = Mathf.Clamp(num, 0, voxelNodeVolume.m_countX - 1);
			num2 = Mathf.Clamp(num2, 0, voxelNodeVolume.m_countZ - 1);
			float num3 = float.MaxValue;
			AIG_VoxelNode val = null;
			AIG_VoxelNodePillar val2 = default(AIG_VoxelNodePillar);
			for (int i = -1; i < 2; i++)
			{
				for (int j = -1; j < 2; j++)
				{
					if (!voxelNodeVolume.TryGetPillar(num + i, num2 + j, ref val2))
					{
						continue;
					}
					Enumerator<AIG_VoxelNode> enumerator = val2.m_nodes.GetEnumerator();
					while (enumerator.MoveNext())
					{
						AIG_VoxelNode current = enumerator.Current;
						if (current.ClusterID != cluster.ID)
						{
							continue;
						}
						Vector3 val3 = current.Position - position;
						float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
						if (sqrMagnitude < num3)
						{
							val = current;
							num3 = sqrMagnitude;
							if (num3 < 0.55f)
							{
								node = ((Il2CppObjectBase)val).Cast<AIG_INode>();
								return true;
							}
						}
					}
				}
			}
			if (val != null)
			{
				node = ((Il2CppObjectBase)val).Cast<AIG_INode>();
				return true;
			}
			return false;
		}

		public static AIG_CourseNode ResolveCourseNode(AIG_CourseNode[] list, Vector3 position)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			if (list == null)
			{
				return null;
			}
			if (list.Length == 1)
			{
				return list[0];
			}
			(AIG_CourseNode, AIG_INode)[] array = new(AIG_CourseNode, AIG_INode)[list.Length];
			int num = 0;
			foreach (AIG_CourseNode val in list)
			{
				if (!TryGetClosestNodeInCluster(val.m_nodeCluster, position, out AIG_INode node))
				{
					node = val.m_nodeCluster.m_nodes[0];
				}
				array[num++] = (val, node);
			}
			bool flag = false;
			float num2 = float.MaxValue;
			AIG_CourseNode result = null;
			(AIG_CourseNode, AIG_INode)[] array2 = array;
			for (int j = 0; j < array2.Length; j++)
			{
				var (val2, val3) = array2[j];
				if (val3 != null)
				{
					bool flag2 = val3.Position.y - 0.25f <= position.y;
					Vector3 val4 = position - val3.Position;
					float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
					if ((!flag && flag2) || (flag == flag2 && sqrMagnitude < num2))
					{
						flag = flag2;
						num2 = sqrMagnitude;
						result = val2;
					}
				}
			}
			return result;
		}

		public static AIG_CourseNode GetCourseNode(Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Dimension dimensionFromPos = Dimension.GetDimensionFromPos(position);
			return GetCourseNode(position, (eDimensionIndex)((dimensionFromPos != null) ? ((int)dimensionFromPos.DimensionIndex) : 0));
		}

		public static AIG_CourseNode GetCourseNode(Vector3 position, eDimensionIndex dimensionIndex)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!_maps.TryGetValue(dimensionIndex, out DimensionMap value))
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No Position-To-Node map for dimension ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eDimensionIndex>(dimensionIndex);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("!");
				}
				Logger.Error(val);
				return null;
			}
			return ResolveCourseNode(value.GetNodes(position), position);
		}

		public static AIG_CourseNode[] GetCourseNodes(Vector3 position, eDimensionIndex dimensionIndex)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!_maps.TryGetValue(dimensionIndex, out DimensionMap value))
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No Position-To-Node map for dimension ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eDimensionIndex>(dimensionIndex);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("!");
				}
				Logger.Error(val);
				return null;
			}
			return value.GetNodes(position);
		}
	}
	public static class DataBlockUtil
	{
		public static bool TryGetBlock<T>(string name, [MaybeNullWhen(false)] out T block) where T : GameDataBlockBase<T>
		{
			if (PartialData_Wrapper.TryGetGUID(name, out var guid))
			{
				return DataBlockUtil.TryGetBlock<T>(guid, out block);
			}
			block = GameDataBlockBase<T>.GetBlock(name);
			return block != null && ((GameDataBlockBase<T>)block).internalEnabled;
		}

		public static bool TryGetBlock<T>(uint id, [MaybeNullWhen(false)] out T block) where T : GameDataBlockBase<T>
		{
			block = GameDataBlockBase<T>.GetBlock(id);
			return block != null && ((GameDataBlockBase<T>)block).internalEnabled;
		}
	}
	public abstract class GlobalBase
	{
		private eDimensionIndex _dimIndex = (eDimensionIndex)0;

		private LG_LayerType _layerType = (LG_LayerType)0;

		private eLocalZoneIndex _localIndex = (eLocalZoneIndex)0;

		private GlobalZoneIndex _struct;

		private (int dim, int layer, int zone) _tuple;

		public Dimension? Dimension;

		public LG_Zone? Zone;

		private bool _isDirty = true;

		[JsonPropertyOrder(-10)]
		public eDimensionIndex DimensionIndex
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _dimIndex;
			}
			set
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				_dimIndex = value;
				MarkDirty();
			}
		}

		[JsonPropertyOrder(-10)]
		public LG_LayerType Layer
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _layerType;
			}
			set
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				_layerType = value;
				MarkDirty();
			}
		}

		[JsonPropertyOrder(-10)]
		public eLocalZoneIndex LocalIndex
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _localIndex;
			}
			set
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				_localIndex = value;
				MarkDirty();
			}
		}

		[JsonIgnore]
		public GlobalZoneIndex GlobalZoneIndex
		{
			get
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				Refresh();
				return _struct;
			}
		}

		[JsonIgnore]
		public (int dimension, int layer, int zone) IntTuple
		{
			get
			{
				Refresh();
				return _tuple;
			}
		}

		protected GlobalBase()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Refresh();
			GlobalIndexUtil.BaseInstances.Add(new WeakReference<GlobalBase>(this));
		}

		private void MarkDirty()
		{
			_isDirty = true;
		}

		private void Refresh()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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)
			if (_isDirty)
			{
				_struct = GlobalIndexUtil.ToStruct(DimensionIndex, Layer, LocalIndex);
				_tuple = GlobalIndexUtil.ToIntTuple(DimensionIndex, Layer, LocalIndex);
				_isDirty = false;
			}
		}

		public override string ToString()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			return $"({DimensionIndex}, {Layer}, {LocalIndex})";
		}
	}
	public static class GlobalIndexUtil
	{
		internal static readonly List<WeakReference<GlobalBase>> BaseInstances;

		static GlobalIndexUtil()
		{
			BaseInstances = new List<WeakReference<GlobalBase>>();
			LevelAPI.OnAfterBuildBatch += OnAfterBuildBatch;
			LevelAPI.OnLevelCleanup += OnLevelCleanup;
		}

		private static void OnAfterBuildBatch(BatchName batch)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)batch != 8)
			{
				return;
			}
			foreach (WeakReference<GlobalBase> baseInstance in BaseInstances)
			{
				if (baseInstance.TryGetTarget(out var target))
				{
					target.Dimension = (TryGetDimension(target.DimensionIndex, out Dimension dim) ? dim : null);
					target.Zone = (TryGetZone(target.DimensionIndex, target.Layer, target.LocalIndex, out LG_Zone zone) ? zone : null);
				}
			}
		}

		private static void OnLevelCleanup()
		{
			BaseInstances.RemoveAll(delegate(WeakReference<GlobalBase> weakRef)
			{
				if (weakRef.TryGetTarget(out GlobalBase target))
				{
					target.Dimension = null;
					target.Zone = null;
					return false;
				}
				return true;
			});
		}

		public static (int dimension, int layer, int zone) ToIntTuple(this LG_Zone zone)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return ToIntTuple(zone.DimensionIndex, zone.Layer.m_type, zone.LocalIndex);
		}

		public static (int dimension, int layer, int zone) ToIntTuple(this GlobalZoneIndex globalIndex)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return ToIntTuple(globalIndex.Dimension, globalIndex.Layer, globalIndex.Zone);
		}

		public static (int dimension, int layer, int zone) ToIntTuple(eDimensionIndex dimension, LG_LayerType layer, eLocalZoneIndex zone)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected I4, but got Unknown
			//IL_0009: Expected I4, but got Unknown
			//IL_0009: Expected I4, but got Unknown
			return (dimension: (int)dimension, layer: (int)layer, zone: (int)zone);
		}

		public static GlobalZoneIndex ToStruct(this LG_Zone zone)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return ToStruct(zone.DimensionIndex, zone.Layer.m_type, zone.LocalIndex);
		}

		public static GlobalZoneIndex ToStruct(eDimensionIndex dimension, LG_LayerType layer, eLocalZoneIndex zone)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new GlobalZoneIndex(dimension, layer, zone);
		}

		public static bool TryGetZone(this (int, int, int) index, [MaybeNullWhen(false)] out LG_Zone zone)
		{
			return TryGetZone((eDimensionIndex)index.Item1, (LG_LayerType)(byte)index.Item2, (eLocalZoneIndex)index.Item3, out zone);
		}

		public static bool TryGetZone(this GlobalZoneIndex index, [MaybeNullWhen(false)] out LG_Zone zone)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return TryGetZone(index.Dimension, index.Layer, index.Zone, out zone);
		}

		public static bool TryGetZone(eDimensionIndex dimension, LG_LayerType layer, eLocalZoneIndex localIndex, [MaybeNullWhen(false)] out LG_Zone zone)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0045: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			zone = null;
			if ((Object)(object)Builder.CurrentFloor == (Object)null || (int)GameStateManager.CurrentStateName < 6 || (int)GameStateManager.CurrentStateName > 10)
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TryGetZone(");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eDimensionIndex>(dimension);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LG_LayerType>(layer);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eLocalZoneIndex>(localIndex);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): Not in level!");
				}
				Logger.Error(val);
				return false;
			}
			if (TryGetDimension(dimension, out Dimension dim))
			{
				Enumerator<LG_Layer> enumerator = dim.Layers.GetEnumerator();
				while (enumerator.MoveNext())
				{
					LG_Layer current = enumerator.Current;
					if (current.m_type == layer && current.m_zonesByLocalIndex.ContainsKey(localIndex))
					{
						zone = current.m_zonesByLocalIndex[localIndex];
						return (Object)(object)zone != (Object)null;
					}
				}
			}
			return false;
		}

		public static bool TryGetDimension(eDimensionIndex dimension, [MaybeNullWhen(false)] out Dimension dim)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			dim = null;
			if ((Object)(object)Builder.CurrentFloor == (Object)null || (int)GameStateManager.CurrentStateName < 6 || (int)GameStateManager.CurrentStateName > 10)
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TryGetDimension(");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eDimensionIndex>(dimension);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): Not in level!");
				}
				Logger.Error(val);
				return false;
			}
			Dictionary<eDimensionIndex, Dimension> indexToDimensionMap = Builder.CurrentFloor.m_indexToDimensionMap;
			if (indexToDimensionMap.ContainsKey(dimension))
			{
				dim = indexToDimensionMap[dimension];
				return dim != null;
			}
			return false;
		}
	}
	public static class JsonSerializerUtil
	{
		public static JsonSerializerOptions CreateDefaultSettings(bool useLocalizedText = true, bool usePartialData = false, bool useInjectLib = false)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions(JsonSerializer.DefaultSerializerSettings);
			if (useLocalizedText)
			{
				if (usePartialData && PartialData_Wrapper.IsLoaded)
				{
					jsonSerializerOptions.Converters.Add(new LocalizedTextPDataConverter());
				}
				else
				{
					jsonSerializerOptions.Converters.Add((JsonConverter)new LocalizedTextConverter());
				}
			}
			if (usePartialData && PartialData_Wrapper.IsLoaded)
			{
				jsonSerializerOptions.Converters.Add(PartialData_Wrapper.PersistentIDConverter);
			}
			if (useInjectLib && InjectLib_Wrapper.IsLoaded)
			{
				jsonSerializerOptions.Converters.Add(InjectLib_Wrapper.InjectLibConverter);
			}
			return jsonSerializerOptions;
		}
	}
	public static class RandomUtil
	{
		public static Random CreateSessionRandom(string offsetKey)
		{
			int seed = RundownManager.ActiveExpedition.SessionSeed ^ HashOffsetKey(offsetKey);
			return new Random(seed);
		}

		private static int HashOffsetKey(string offsetKey)
		{
			uint num = 2166136261u;
			foreach (char c in offsetKey)
			{
				num ^= c;
				num *= 16777619;
			}
			return (int)num;
		}
	}
	public sealed class ZoneNode
	{
		public class ZoneEdge
		{
			public readonly LG_Gate Gate;

			public readonly ZoneNode Neighbor;

			public bool IsOpen { get; private set; }

			public ZoneEdge(LG_Gate gate, ZoneNode zone)
			{
				Gate = gate;
				Neighbor = zone;
				UpdateOpen();
			}

			internal void UpdateOpen()
			{
				IsOpen = Gate.IsTraversable;
			}
		}

		public readonly LG_Zone Zone;

		private List<(LG_Gate gate, ZoneNode zone)> _neighborsToAdd = new List<(LG_Gate, ZoneNode)>();

		private readonly Dictionary<ushort, int> _areaGroups = new Dictionary<ushort, int>();

		public AreaNode[] Areas { get; private set; } = null;

		public ZoneEdge[] Edges { get; private set; } = null;

		public IReadOnlyCollection<ushort> AreaGroups => _areaGroups.Keys;

		public ushort Group { get; private set; } = 0;

		public ZoneNode(LG_Zone zone)
		{
			Zone = zone;
			LG_Gate sourceGate = zone.m_sourceGate;
			object obj;
			if (sourceGate == null)
			{
				obj = null;
			}
			else
			{
				LG_Area linksFrom = ((LG_ZoneExpander)sourceGate).m_linksFrom;
				obj = ((linksFrom != null) ? linksFrom.m_zone : null);
			}
			LG_Zone val = (LG_Zone)obj;
			if ((Object)(object)val != (Object)null)
			{
				ZoneNode zoneNode = ZoneGraphUtil.GetZoneNode(val);
				zoneNode._neighborsToAdd.Add((sourceGate, this));
				_neighborsToAdd.Add((sourceGate, zoneNode));
			}
		}

		internal void OnNodesCreated()
		{
			Edges = _neighborsToAdd.ConvertAll(((LG_Gate gate, ZoneNode zone) pair) => new ZoneEdge(pair.gate, pair.zone)).ToArray();
			_neighborsToAdd = null;
			List<AreaNode> list = new List<AreaNode>(Zone.m_areas.Count);
			Enumerator<LG_Area> enumerator = Zone.m_areas.GetEnumerator();
			while (enumerator.MoveNext())
			{
				LG_Area current = enumerator.Current;
				list.Add(ZoneGraphUtil.GetAreaNode(current));
			}
			Areas = list.ToArray();
		}

		public bool IsZoneReachable(ZoneGraphGroup group)
		{
			return Group == group.Zone && group.Zone != 0;
		}

		public bool IsZoneReachable(ushort group)
		{
			return Group == group && group != 0;
		}

		public bool IsZoneReachable()
		{
			return Group != 0;
		}

		public bool IsReachable(ZoneGraphGroup group)
		{
			return _areaGroups.ContainsKey(group.Area);
		}

		public bool IsReachable(ushort group)
		{
			return _areaGroups.ContainsKey(group);
		}

		public bool IsReachable()
		{
			return _areaGroups.Count > 0;
		}

		internal void Reset()
		{
			_areaGroups.Clear();
			Group = 0;
		}

		internal void SetGroup(ushort group)
		{
			Group = group;
		}

		internal void UpdateEdges()
		{
			ZoneEdge[] edges = Edges;
			foreach (ZoneEdge zoneEdge in edges)
			{
				zoneEdge.UpdateOpen();
			}
		}

		internal void OnAreaReachable(ushort newGroup, ushort oldGroup)
		{
			if (_areaGroups.TryGetValue(oldGroup, out var value) && --value == 0)
			{
				_areaGroups.Remove(oldGroup);
			}
			if (newGroup != 0)
			{
				value = _areaGroups.GetValueOrDefault(newGroup);
				_areaGroups[newGroup] = value + 1;
			}
		}
	}
	public sealed class AreaNode
	{
		public class AreaEdge
		{
			public readonly LG_Gate Gate;

			public readonly AreaNode Neighbor;

			public bool IsOpen { get; private set; }

			public AreaEdge(LG_Gate gate, AreaNode area)
			{
				Gate = gate;
				Neighbor = area;
				UpdateOpen();
			}

			internal void UpdateOpen()
			{
				IsOpen = Gate.IsTraversable;
			}
		}

		public readonly LG_Area Area;

		public ushort Group { get; private set; } = 0;

		public ZoneNode Zone { get; private set; } = null;

		public AreaEdge[] Edges { get; private set; } = null;

		public AreaNode(LG_Area area)
		{
			Area = area;
		}

		public bool IsReachable(ZoneGraphGroup group)
		{
			return Group == group.Area && group.Area != 0;
		}

		public bool IsReachable(ushort group)
		{
			return Group == group && group != 0;
		}

		public bool IsReachable()
		{
			return Group != 0;
		}

		internal void OnNodesCreated()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Invalid comparison between Unknown and I4
			Zone = ZoneGraphUtil.GetZoneNode(Area.m_zone);
			List<AreaEdge> list = new List<AreaEdge>();
			Enumerator<LG_Gate> enumerator = Area.m_gates.GetEnumerator();
			while (enumerator.MoveNext())
			{
				LG_Gate current = enumerator.Current;
				LG_Area val = ((LG_ZoneExpander)current).m_linksFrom;
				if (!((Object)(object)val == (Object)null))
				{
					if (val.UID == Area.UID)
					{
						val = ((LG_ZoneExpander)current).m_linksTo;
					}
					if (!((Object)(object)val == (Object)null) && (int)((LG_ZoneExpander)current).ExpanderStatus != 2)
					{
						list.Add(new AreaEdge(current, ZoneGraphUtil.GetAreaNode(val)));
					}
				}
			}
			Edges = list.ToArray();
		}

		internal void Reset()
		{
			Group = 0;
		}

		internal void SetGroup(ushort group)
		{
			Zone.OnAreaReachable(group, Group);
			Group = group;
		}

		internal void UpdateEdges()
		{
			AreaEdge[] edges = Edges;
			foreach (AreaEdge areaEdge in edges)
			{
				areaEdge.UpdateOpen();
			}
		}
	}
	public record struct ZoneGraphGroup
	{
		public ushort Zone;

		public ushort Area;

		public ZoneGraphGroup()
		{
			Zone = 0;
			Area = 0;
			Zone = 0;
			Area = 0;
		}

		public void Reset()
		{
			Zone = 0;
			Area = 0;
		}
	}
	[CallConstructorOnLoad]
	public sealed class ZoneGraphUtil
	{
		public const ushort NoGroup = 0;

		internal static readonly ZoneGraphUtil Current;

		private readonly Dictionary<int, ZoneNode> _zoneToNode = new Dictionary<int, ZoneNode>();

		private readonly Dictionary<int, AreaNode> _areaToNode = new Dictionary<int, AreaNode>();

		private readonly Dictionary<int, ZoneGraphGroup> _playerToGroup = new Dictionary<int, ZoneGraphGroup>();

		private ZoneGraphGroup _lastGroup = new ZoneGraphGroup();

		public static bool IsReady { get; private set; }

		public static event Action? OnReachableUpdate;

		public static ZoneNode GetZoneNode(Agent agent)
		{
			return GetZoneNode(agent.CourseNode.m_zone);
		}

		public static ZoneNode GetZoneNode(AIG_CourseNode courseNode)
		{
			return GetZoneNode(courseNode.m_zone);
		}

		public static ZoneNode GetZoneNode(LG_Zone zone)
		{
			return Current._zoneToNode[zone.ID];
		}

		public static AreaNode GetAreaNode(Agent agent)
		{
			return GetAreaNode(agent.CourseNode.m_area);
		}

		public static AreaNode GetAreaNode(AIG_CourseNode courseNode)
		{
			return GetAreaNode(courseNode.m_area);
		}

		public static AreaNode GetAreaNode(LG_Area area)
		{
			return Current._areaToNode[area.UID];
		}

		public static ZoneGraphGroup GetPlayerGroup(PlayerAgent player)
		{
			return Current._playerToGroup.GetValueOrDefault(player.PlayerSlotIndex);
		}

		public static bool IsReachable(PlayerAgent player, AIG_CourseNode courseNode)
		{
			return GetAreaNode(courseNode).IsReachable(GetPlayerGroup(player));
		}

		public static bool IsReachable(PlayerAgent player, LG_Area area)
		{
			return GetAreaNode(area).IsReachable(GetPlayerGroup(player));
		}

		public static bool IsReachable(PlayerAgent player, LG_Zone zone)
		{
			return GetZoneNode(zone).IsReachable(GetPlayerGroup(player));
		}

		public static bool IsReachable(AIG_CourseNode courseNode)
		{
			return GetAreaNode(courseNode).IsReachable();
		}

		public static bool IsReachable(LG_Area area)
		{
			return GetAreaNode(area).IsReachable();
		}

		public static bool IsReachable(LG_Zone zone)
		{
			return GetZoneNode(zone).IsReachable();
		}

		public static bool IsZoneReachable(PlayerAgent player, AIG_CourseNode courseNode)
		{
			return GetZoneNode(courseNode.m_zone).IsZoneReachable(GetPlayerGroup(player));
		}

		public static bool IsZoneReachable(PlayerAgent player, LG_Area area)
		{
			return GetZoneNode(area.m_zone).IsZoneReachable(GetPlayerGroup(player));
		}

		public static bool IsZoneReachable(PlayerAgent player, LG_Zone zone)
		{
			return GetZoneNode(zone).IsZoneReachable(GetPlayerGroup(player));
		}

		public static bool IsZoneReachable(AIG_CourseNode courseNode)
		{
			return GetZoneNode(courseNode.m_zone).IsZoneReachable();
		}

		public static bool IsZoneReachable(LG_Area area)
		{
			return GetZoneNode(area.m_zone).IsZoneReachable();
		}

		public static bool IsZoneReachable(LG_Zone zone)
		{
			return GetZoneNode(zone).IsZoneReachable();
		}

		static ZoneGraphUtil()
		{
			IsReady = false;
			Current = new ZoneGraphUtil();
			LevelAPI.OnBuildStart += delegate
			{
				LG_Area.s_areaUIDCounter = 0;
			};
			LevelAPI.OnBuildDone += Current.BuildZoneGraph;
			LevelAPI.OnLevelCleanup += Current.Cleanup;
			EventAPI.OnCheckpointReloaded += Current.RefreshOnCheckpoint;
		}

		private static void DebugLogging()
		{
			OnReachableUpdate += delegate
			{
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0171: Expected O, but got Unknown
				string text = string.Join(", ", Current._playerToGroup.ToList().ConvertAll((KeyValuePair<int, ZoneGraphGroup> kv) => $"(Slot: {kv.Key}, Zone: {kv.Value.Zone}, Area: {kv.Value.Area})"));
				string text2 = string.Join(", ", from a in Current._areaToNode.Values
					where a.IsReachable()
					select $"({((Object)a.Zone.Zone.NavInfo).ToString()}{((Object)a.Area.m_navInfo).ToString()}:{a.Group})");
				string text3 = string.Join(", ", from z in Current._zoneToNode.Values
					where z.IsReachable()
					select $"({((Object)z.Zone.NavInfo).ToString()}:[{string.Join(", ", z.AreaGroups)}])");
				string text4 = string.Join(", ", from z in Current._zoneToNode.Values
					where z.IsZoneReachable()
					select $"({((Object)z.Zone.NavInfo).ToString()}:{z.Group})");
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(101, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Graph update | Player groups: [");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] | Reachable nodes: [");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] | Reachable zones: [");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("], ZoneReachable zones: [");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("]");
				}
				Logger.Info(val);
			};
		}

		private void BuildZoneGraph()
		{
			Enumerator<LG_Zone> enumerator = Builder.CurrentFloor.allZones.GetEnumerator();
			while (enumerator.MoveNext())
			{
				LG_Zone current = enumerator.Current;
				_zoneToNode.TryAdd(current.ID, new ZoneNode(current));
				Enumerator<LG_Area> enumerator2 = current.m_areas.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					LG_Area current2 = enumerator2.Current;
					_areaToNode.TryAdd(current2.UID, new AreaNode(current2));
				}
			}
			foreach (ZoneNode value in _zoneToNode.Values)
			{
				value.OnNodesCreated();
			}
			foreach (AreaNode value2 in _areaToNode.Values)
			{
				value2.OnNodesCreated();
			}
			IsReady = true;
		}

		private void Cleanup()
		{
			_zoneToNode.Clear();
			_areaToNode.Clear();
			_playerToGroup.Clear();
			_lastGroup.Reset();
			IsReady = false;
		}

		private void RefreshOnCheckpoint()
		{
			foreach (ZoneNode value in _zoneToNode.Values)
			{
				value.UpdateEdges();
			}
			foreach (AreaNode value2 in _areaToNode.Values)
			{
				value2.UpdateEdges();
			}
			RefreshGraph();
		}

		private void RefreshGraph()
		{
			foreach (ZoneNode value in _zoneToNode.Values)
			{
				value.Reset();
			}
			foreach (AreaNode value2 in _areaToNode.Values)
			{
				value2.Reset();
			}
			_playerToGroup.Clear();
			_lastGroup.Reset();
			Enumerator<PlayerAgent> enumerator3 = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator3.MoveNext())
			{
				PlayerAgent current3 = enumerator3.Current;
				if (((Agent)current3).CourseNode != null)
				{
					UpdateOrCreateGroup(current3, out var _);
				}
			}
			ZoneGraphUtil.OnReachableUpdate?.Invoke();
		}

		private bool UpdateOrCreateGroup(PlayerAgent player, out ZoneGraphGroup group)
		{
			group = new ZoneGraphGroup();
			AreaNode areaNode = GetAreaNode((Agent)(object)player);
			ZoneNode zone = areaNode.Zone;
			if (areaNode.IsReachable())
			{
				group.Area = areaNode.Group;
			}
			else
			{
				group.Area = ++_lastGroup.Area;
				PropagateGroup(areaNode, group.Area);
			}
			if (zone.IsZoneReachable())
			{
				group.Zone = zone.Group;
			}
			else
			{
				group.Zone = ++_lastGroup.Zone;
				PropagateGroup(zone, group.Zone);
			}
			if (!_playerToGroup.TryGetValue(player.PlayerSlotIndex, out var value) || value != group)
			{
				_playerToGroup[player.PlayerSlotIndex] = group;
				return true;
			}
			return false;
		}

		private static void PropagateGroup(AreaNode areaNode, ushort group)
		{
			areaNode.SetGroup(group);
			AreaNode.AreaEdge[] edges = areaNode.Edges;
			foreach (AreaNode.AreaEdge areaEdge in edges)
			{
				if (areaEdge.IsOpen && areaEdge.Neighbor.Group != group)
				{
					PropagateGroup(areaEdge.Neighbor, group);
				}
			}
		}

		private static void PropagateGroup(ZoneNode zoneNode, ushort group)
		{
			zoneNode.SetGroup(group);
			ZoneNode.ZoneEdge[] edges = zoneNode.Edges;
			foreach (ZoneNode.ZoneEdge zoneEdge in edges)
			{
				if (zoneEdge.IsOpen && zoneEdge.Neighbor.Group != group)
				{
					PropagateGroup(zoneEdge.Neighbor, group);
				}
			}
		}

		internal void Internal_OnPlayerNodeChanged(PlayerAgent player, AIG_CourseNode oldNode)
		{
			if (!IsReady)
			{
				return;
			}
			ZoneGraphGroup group;
			bool flag = UpdateOrCreateGroup(player, out group);
			if (oldNode != null)
			{
				AreaNode oldAreaNode = GetAreaNode(oldNode.m_area);
				if (!oldAreaNode.IsReachable(group.Area) && _playerToGroup.Values.All((ZoneGraphGroup zoneGraphGroup) => !oldAreaNode.IsReachable(zoneGraphGroup.Area)))
				{
					PropagateGroup(oldAreaNode, 0);
					flag = true;
				}
				ZoneNode oldZoneNode = oldAreaNode.Zone;
				if (!oldZoneNode.IsZoneReachable(group.Zone) && _playerToGroup.Values.All((ZoneGraphGroup zoneGraphGroup) => !oldZoneNode.IsZoneReachable(zoneGraphGroup.Zone)))
				{
					PropagateGroup(oldZoneNode, 0);
					flag = true;
				}
			}
			if (flag)
			{
				ZoneGraphUtil.OnReachableUpdate?.Invoke();
			}
		}

		internal void Internal_OnDoorStateChanged(LG_Gate gate, bool isOpen)
		{
			if (!IsReady)
			{
				return;
			}
			AreaNode areaNode = GetAreaNode(((LG_ZoneExpander)gate).m_linksFrom);
			AreaNode areaNode2 = GetAreaNode(((LG_ZoneExpander)gate).m_linksTo);
			bool flag = areaNode.Zone != areaNode2.Zone;
			areaNode.UpdateEdges();
			areaNode2.UpdateEdges();
			if (flag)
			{
				areaNode.Zone.UpdateEdges();
				areaNode2.Zone.UpdateEdges();
			}
			if (!isOpen)
			{
				if (areaNode.IsReachable() || (flag && areaNode.Zone.IsZoneReachable()))
				{
					RefreshGraph();
				}
				return;
			}
			bool flag2 = TryPropagate(areaNode2, areaNode) || TryPropagate(areaNode, areaNode2);
			bool flag3 = flag && (TryPropagateZone(areaNode2.Zone, areaNode.Zone) || TryPropagateZone(areaNode.Zone, areaNode2.Zone));
			if (flag2 || flag3)
			{
				ZoneGraphUtil.OnReachableUpdate?.Invoke();
			}
			bool TryPropagate(AreaNode oldArea, AreaNode newArea)
			{
				if (!newArea.IsReachable())
				{
					return false;
				}
				KeyValuePair<int, ZoneGraphGroup>[] array = _playerToGroup.ToArray();
				foreach (KeyValuePair<int, ZoneGraphGroup> keyValuePair in array)
				{
					keyValuePair.Deconstruct(out var key, out var value);
					int key2 = key;
					ZoneGraphGroup zoneGraphGroup = value;
					if (zoneGraphGroup.Area == oldArea.Group)
					{
						Dictionary<int, ZoneGraphGroup> playerToGroup = _playerToGroup;
						value = zoneGraphGroup with
						{
							Area = newArea.Group
						};
						playerToGroup[key2] = value;
					}
				}
				PropagateGroup(oldArea, newArea.Group);
				return true;
			}
			bool TryPropagateZone(ZoneNode oldZone, ZoneNode newZone)
			{
				if (!newZone.IsZoneReachable())
				{
					return false;
				}
				KeyValuePair<int, ZoneGraphGroup>[] array = _playerToGroup.ToArray();
				foreach (KeyValuePair<int, ZoneGraphGroup> keyValuePair in array)
				{
					keyValuePair.Deconstruct(out var key, out var value);
					int key2 = key;
					ZoneGraphGroup zoneGraphGroup = value;
					if (zoneGraphGroup.Zone == oldZone.Group)
					{
						Dictionary<int, ZoneGraphGroup> playerToGroup = _playerToGroup;
						value = zoneGraphGroup with
						{
							Zone = newZone.Group
						};
						playerToGroup[key2] = value;
					}
				}
				PropagateGroup(oldZone, newZone.Group);
				return true;
			}
		}
	}
}
namespace AmorLib.Utils.JsonElementConverters
{
	[JsonConverter(typeof(BoolBaseConverter))]
	public struct BoolBase
	{
		public BoolMode Mode;

		public static readonly BoolBase False = new BoolBase(BoolMode.False);

		public static readonly BoolBase True = new BoolBase(BoolMode.True);

		public static readonly BoolBase Unchanged = new BoolBase(BoolMode.Unchanged);

		public BoolBase(bool mode)
		{
			Mode = (mode ? BoolMode.True : BoolMode.False);
		}

		public BoolBase(BoolMode mode)
		{
			Mode = mode;
		}

		public readonly bool GetValue(bool originalValue)
		{
			return Mode switch
			{
				BoolMode.True => true, 
				BoolMode.False => false, 
				_ => originalValue, 
			};
		}
	}
	public enum BoolMode
	{
		False,
		True,
		Unchanged
	}
	public sealed class BoolBaseConverter : JsonConverter<BoolBase>
	{
		public override bool HandleNull => false;

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(BoolBase);
		}

		public override BoolBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string text = reader.GetString()?.Trim();
				if (string.IsNullOrEmpty(text))
				{
					throw new JsonException("BoolBase string value is null or empty!");
				}
				if (text.EqualsAny(true, "Unchanged", "Ignore", "Keep", "Original", "KeepOriginal"))
				{
					return BoolBase.Unchanged;
				}
				if (bool.TryParse(text, out var result))
				{
					return new BoolBase(result);
				}
				throw new JsonException("Cannot parse BoolBase string: " + text + "! Are you sure it's in right format?");
			}
			case JsonTokenType.True:
				return BoolBase.True;
			case JsonTokenType.False:
				return BoolBase.False;
			default:
				throw new JsonException($"BoolBaseJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, BoolBase value, JsonSerializerOptions options)
		{
			switch (value.Mode)
			{
			case BoolMode.True:
				writer.WriteBooleanValue(value: true);
				break;
			case BoolMode.False:
				writer.WriteBooleanValue(value: false);
				break;
			case BoolMode.Unchanged:
				writer.WriteStringValue("Unchanged");
				break;
			}
			writer.WriteCommentValue("BoolBase");
		}
	}
	[JsonConverter(typeof(LocaleTextConverter))]
	public struct LocaleText : IEquatable<LocaleText>
	{
		public uint ID;

		public string RawText;

		public static readonly LocaleText Empty = new LocaleText(string.Empty);

		private readonly string TextFallback => (ID == 0) ? RawText : Text.Get(ID);

		public LocaleText(LocalizedText baseText)
		{
			RawText = ((Object)baseText).ToString();
			ID = baseText.Id;
		}

		public LocaleText(string text)
		{
			if (PartialData_Wrapper.TryGetGUID(text, out var guid))
			{
				RawText = string.Empty;
				ID = guid;
			}
			else
			{
				RawText = text;
				ID = 0u;
			}
		}

		public LocaleText(uint id)
		{
			RawText = string.Empty;
			ID = id;
		}

		public readonly LocalizedText ToLocalizedText()
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			return new LocalizedText
			{
				Id = ID,
				UntranslatedText = TextFallback
			};
		}

		public static explicit operator LocaleText(LocalizedText localizedText)
		{
			return new LocaleText(localizedText);
		}

		public static explicit operator LocaleText(string text)
		{
			return new LocaleText(text);
		}

		public static implicit operator LocalizedText(LocaleText localeText)
		{
			return localeText.ToLocalizedText();
		}

		public static implicit operator string(LocaleText localeText)
		{
			return localeText.ToString();
		}

		public override readonly string ToString()
		{
			return TextFallback;
		}

		public readonly bool Equals(LocaleText other)
		{
			return ID == other.ID && string.Equals(RawText, other.RawText, StringComparison.Ordinal);
		}

		public override readonly bool Equals(object? obj)
		{
			return obj is LocaleText other && Equals(other);
		}

		public override readonly int GetHashCode()
		{
			return HashCode.Combine(ID, RawText);
		}

		public static bool operator ==(LocaleText left, LocaleText right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(LocaleText left, LocaleText right)
		{
			return !(left == right);
		}
	}
	public class LocaleTextConverter : JsonConverter<LocaleText>
	{
		public override bool HandleNull => true;

		public override LocaleText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			return reader.TokenType switch
			{
				JsonTokenType.String => new LocaleText(reader.GetString()), 
				JsonTokenType.Number => new LocaleText(reader.GetUInt32()), 
				JsonTokenType.Null => LocaleText.Empty, 
				_ => throw new JsonException($"LocaleTextJson type: {reader.TokenType} is not implemented!"), 
			};
		}

		public override void Write(Utf8JsonWriter writer, LocaleText value, JsonSerializerOptions options)
		{
			if (value.ID != 0)
			{
				writer.WriteNumberValue(value.ID);
			}
			else
			{
				writer.WriteStringValue(value.RawText);
			}
		}
	}
	public sealed class LocalizedTextPDataConverter : JsonConverter<LocalizedText>
	{
		public override bool HandleNull => false;

		public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			if (reader.TokenType == JsonTokenType.String)
			{
				string text = reader.GetString();
				LocalizedText val = new LocalizedText();
				if (PartialData_Wrapper.TryGetGUID(text, out var guid))
				{
					val.Id = guid;
					val.UntranslatedText = null;
				}
				else
				{
					val.Id = 0u;
					val.UntranslatedText = text;
				}
				return val;
			}
			if (reader.TokenType == JsonTokenType.Number)
			{
				return new LocalizedText
				{
					Id = reader.GetUInt32(),
					UntranslatedText = null
				};
			}
			throw new JsonException($"LocalizedTextJson type: {reader.TokenType} not implemented");
		}

		public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
		{
			if (value.Id != 0)
			{
				JsonSerializer.Serialize(writer, value.Id, options);
			}
			else
			{
				JsonSerializer.Serialize(writer, value.UntranslatedText, options);
			}
		}
	}
	[JsonConverter(typeof(ValueBaseConverter))]
	public struct ValueBase
	{
		public float Value;

		public ValueMode Mode;

		public bool FromDefault;

		public static readonly ValueBase Unchanged = new ValueBase(1f, ValueMode.Rel, fromDefault: true);

		public static readonly ValueBase Zero = new ValueBase(0f, ValueMode.Abs, fromDefault: false);

		public ValueBase(float value = 1f, ValueMode mode = ValueMode.Rel, bool fromDefault = true)
		{
			Value = value;
			Mode = mode;
			FromDefault = fromDefault;
		}

		public readonly float GetAbsValue(float maxValue, float currentValue)
		{
			if (Mode == ValueMode.Rel)
			{
				return FromDefault ? (currentValue * Value) : (maxValue * Value);
			}
			return Value;
		}

		public readonly float GetAbsValue(float baseValue)
		{
			return (Mode == ValueMode.Abs) ? Value : (baseValue * Value);
		}

		public readonly int GetAbsValue(int maxValue, int currentValue)
		{
			return (int)Math.Round(GetAbsValue((float)maxValue, (float)currentValue));
		}

		public readonly int GetAbsValue(int baseValue)
		{
			return (int)Math.Round(GetAbsValue((float)baseValue));
		}

		public override readonly string ToString()
		{
			return $"[Mode: {Mode}, Value: {Value}]";
		}
	}
	public enum ValueMode
	{
		Rel,
		Abs
	}
	public sealed class ValueBaseConverter : JsonConverter<ValueBase>
	{
		public override bool HandleNull => false;

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(ValueBase);
		}

		public override ValueBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			switch (reader.TokenType)
			{
			case JsonTokenType.Number:
				return new ValueBase(reader.GetSingle(), ValueMode.Abs);
			case JsonTokenType.StartObject:
			{
				ValueBase result3 = default(ValueBase);
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return result3;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string text3 = reader.GetString();
					reader.Read();
					switch (text3.ToLowerInvariant())
					{
					case "value":
						result3.Value = reader.GetSingle();
						break;
					case "mode":
					{
						if (Enum.TryParse<ValueMode>(reader.GetString(), out var result4))
						{
							result3.Mode = result4;
						}
						break;
					}
					case "fromdefault":
						result3.FromDefault = reader.GetBoolean();
						break;
					}
				}
				throw new JsonException("Expected EndObject token");
			}
			case JsonTokenType.String:
			{
				string text = reader.GetString()?.Trim();
				if (string.IsNullOrEmpty(text))
				{
					throw new JsonException("ValueBase string value is null or empty!");
				}
				bool fromDefault = false;
				if (text.EndsWith("of default", StringComparison.OrdinalIgnoreCase))
				{
					fromDefault = true;
					string text2 = text;
					text = text2.Substring(0, text2.Length - 10).TrimEnd();
				}
				if (text.EndsWith("%", StringComparison.InvariantCulture))
				{
					string text2 = text;
					if (float.TryParse(text2.Substring(0, text2.Length - 1).TrimEnd(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result))
					{
						return new ValueBase(result / 100f, ValueMode.Rel, fromDefault);
					}
				}
				if (text.EqualsAny(true, "Unchanged", "Ignore", "Keep", "Original", "KeepOriginal"))
				{
					return new ValueBase(1f, ValueMode.Rel, fromDefault: false);
				}
				if (float.TryParse(text, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result2))
				{
					return new ValueBase(result2, ValueMode.Abs);
				}
				throw new JsonException("Cannot parse ValueBase string: " + text + "! Are you sure it's in right format?");
			}
			default:
				throw new JsonException($"ValueBaseJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, ValueBase value, JsonSerializerOptions options)
		{
			switch (value.Mode)
			{
			case ValueMode.Rel:
			{
				if (Mathf.Approximately(value.Value, 1f))
				{
					writer.WriteStringValue("Unchanged");
					break;
				}
				string format = (value.FromDefault ? "{0}% of default" : "{0}%");
				writer.WriteStringValue(string.Format(format, value.Value * 100f));
				break;
			}
			case ValueMode.Abs:
				writer.WriteStringValue(value.Value.ToString());
				break;
			}
			writer.WriteCommentValue("ValueBase");
		}
	}
}
namespace AmorLib.Utils.Extensions
{
	public static class CollectionExtensions
	{
		public static TValue GetOrAddNew<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key) where TValue : new()
		{
			if (!dict.TryGetValue(key, out TValue value))
			{
				value = (dict[key] = new TValue());
			}
			return value;
		}

		public static void ForEachValue<TKey, TValue>(this IDictionary<TKey, TValue> dict, Action<TValue> action) where TKey : notnull
		{
			foreach (TValue value in dict.Values)
			{
				action(value);
			}
		}

		public static bool AnyAllValues<TKey, TCollection, TValue>(this IDictionary<TKey, TCollection> dict, Func<TValue, bool> predicate) where TCollection : IEnumerable<TValue>
		{
			foreach (TCollection value in dict.Values)
			{
				if (value.Any(predicate))
				{
					return true;
				}
			}
			return false;
		}

		public static TValue? FirstOrDefaultAllValues<TKey, TCollection, TValue>(this IDictionary<TKey, TCollection> dict, Func<TValue, bool> predicate) where TCollection : IEnumerable<TValue>
		{
			foreach (TCollection value in dict.Values)
			{
				foreach (TValue item in value)
				{
					if (predicate(item))
					{
						return item;
					}
				}
			}
			return default(TValue);
		}
	}
	public static class GameObjectPlusExtensions
	{
		public static bool TryAndGetComponent<T>(this GameObject go, out T component)
		{
			component = go.GetComponent<T>();
			return component != null;
		}

		public static T AddOrGetComponent<T>(this GameObject go) where T : Component
		{
			if (!go.TryAndGetComponent<T>(out var component))
			{
				return go.AddComponent<T>();
			}
			return component;
		}

		public static bool HasComponent<T>(this GameObject go) where T : Component
		{
			return (Object)(object)go.GetComponent<T>() != (Object)null;
		}

		public static string GetFullPath(this GameObject go)
		{
			StringBuilder stringBuilder = new StringBuilder(((Object)go).name);
			Transform parent = go.transform.parent;
			while ((Object)(object)parent != (Object)null)
			{
				stringBuilder.Insert(0, ((Object)parent).name + "/");
				parent = parent.parent;
			}
			return stringBuilder.ToString();
		}

		public static GameObject ClonePrefabSpawners(this GameObject original, Vector3 position, Quaternion rotation, Transform parent)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(original, position, rotation, parent);
			foreach (LG_PrefabSpawner componentsInChild in val.GetComponentsInChildren<LG_PrefabSpawner>())
			{
				try
				{
					GameObject val2 = Object.Instantiate<GameObject>(componentsInChild.m_prefab, ((Component)componentsInChild).transform.position, ((Component)componentsInChild).transform.rotation, ((Component)componentsInChild).transform.parent);
					if (componentsInChild.m_disableCollision)
					{
						foreach (Collider componentsInChild2 in val2.GetComponentsInChildren<Collider>())
						{
							componentsInChild2.enabled = false;
						}
					}
					if (componentsInChild.m_applyScale)
					{
						val2.transform.localScale = ((Component)componentsInChild).transform.localScale;
					}
					val2.transform.SetParent(((Component)componentsInChild).transform);
				}
				catch
				{
				}
			}
			return val;
		}

		public static uint PostWithCleanup(this CellSoundPlayer soundPlayer, uint eventID, Vector3 pos, uint in_uFlags = 1u)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return soundPlayer.Post(eventID, pos, in_uFlags, EventCallback.op_Implicit((Action<Object, AkCallbackType, AkCallbackInfo>)SoundDoneCallback), (Object)(object)soundPlayer);
		}

		private static void SoundDoneCallback(Object in_pCookie, AkCallbackType in_type, AkCallbackInfo callbackInfo)
		{
			CellSoundPlayer val = ((Il2CppObjectBase)in_pCookie).Cast<CellSoundPlayer>();
			if (val != null)
			{
				val.Recycle();
			}
		}

		public static bool IsWithinSqrDistance(this Vector3 a, Vector3 b, float sqrThreshold, out float sqrDistance)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = a - b;
			sqrDistance = ((Vector3)(ref val)).sqrMagnitude;
			return sqrDistance <= sqrThreshold;
		}

		public static bool IsWithinSqrDistance(this Vector3 a, Vector3 b, float sqrThreshold)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = a - b;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			return sqrMagnitude <= sqrThreshold;
		}

		public static Quaternion ToQuaternion(this Vector3 rotation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.Euler(rotation);
		}

		public static void SetPositionRotationScale(this Transform transform, Vector3 position, Vector3 rotation, Vector3 scale)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			transform.SetPositionAndRotation(position, rotation.ToQuaternion());
			transform.localScale = scale;
		}
	}
	public static class PluginInfoExtensions
	{
		public static bool VersionEquals(this PluginInfo pluginInfo, string verison)
		{
			int? num = CompareVersion(pluginInfo, verison);
			return num.HasValue && num.GetValueOrDefault() == 0;
		}

		public static bool VersionExceeds(this PluginInfo pluginInfo, string version)
		{
			int? num = CompareVersion(pluginInfo, version);
			return num.HasValue && num.GetValueOrDefault() > 0;
		}

		public static bool VersionAtLeast(this PluginInfo pluginInfo, string version)
		{
			int? num = CompareVersion(pluginInfo, version);
			return num.HasValue && num.GetValueOrDefault() >= 0;
		}

		private static int? CompareVersion(PluginInfo pluginInfo, string verison)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			object obj;
			if (pluginInfo == null)
			{
				obj = null;
			}
			else
			{
				BepInPlugin metadata = pluginInfo.Metadata;
				obj = ((metadata != null) ? metadata.Version : null);
			}
			if ((Version)obj == (Version)null)
			{
				Logger.Error("PluginInfo or Version.Metadata is null");
				return null;
			}
			Match match = Regex.Match(verison, "^(\\d+)\\.(\\d+)\\.(\\d+)$");
			if (!match.Success)
			{
				Logger.Error("Version string format is incorrect");
				return null;
			}
			int num = int.Parse(match.Groups[1].Value);
			int num2 = int.Parse(match.Groups[2].Value);
			int num3 = int.Parse(match.Groups[3].Value);
			return pluginInfo.Metadata.Version.CompareTo(new Version(num, num2, num3, (string)null, (string)null));
		}
	}
	public static class StringExtensions
	{
		public static bool EqualsAny(this string input, bool ignoreCase = false, params string[] args)
		{
			StringComparison comparisonType = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
			foreach (string value in args)
			{
				if (input.Equals(value, comparisonType))
				{
					return true;
				}
			}
			return false;
		}

		public static LocaleText ToLocaleText(this string input)
		{
			return new LocaleText(input);
		}
	}
}
namespace AmorLib.Patches.SNet
{
	[HarmonyPatch(typeof(SNet_SyncManager), "OnRecallDone")]
	internal static class Patch_OnRecallDone
	{
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void Post_RecallDone()
		{
			SNetEvents.RecallDone();
		}
	}
	[HarmonyPatch(typeof(SNet_Capture))]
	internal static class Patch_SNet_Capture
	{
		[HarmonyPatch("TriggerCapture")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		private static void Pre_TriggerCapture(SNet_Capture __instance)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			SNetEvents.BufferCaptured(__instance.PrimedBufferType);
		}

		[HarmonyPatch("RecallBuffer")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void Post_RecallBuffer(SNet_Capture __instance, eBufferType bufferType)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.IsRecalling)
			{
				SNetEvents.BufferRecalled(bufferType);
			}
		}
	}
}
namespace AmorLib.Patches.LevelGen
{
	[HarmonyPatch]
	internal static class BuilderPatches
	{
		[HarmonyPatch(typeof(Builder), "BuildDone")]
		[HarmonyPostfix]
		[HarmonyBefore(new string[] { "dev.gtfomodding.gtfo-api" })]
		[HarmonyWrapSafe]
		private static void BuildDone_Early()
		{
			LevelEvents.BuildDoneEarly();
		}

		[HarmonyPatch(typeof(Builder), "BuildDone")]
		[HarmonyPostfix]
		[HarmonyAfter(new string[] { "dev.gtfomodding.gtfo-api" })]
		[HarmonyWrapSafe]
		private static void BuildDone_Late()
		{
			LevelEvents.BuildDoneLate();
		}
	}
	[HarmonyPatch(typeof(LG_BuildZoneLightsJob), "Build")]
	internal static class LightsPatches
	{
		[HarmonyPrefix]
		[HarmonyPriority(600)]
		[HarmonyWrapSafe]
		private static void Pre_ZoneBuild(LG_BuildZoneLightsJob __instance, out List<LightWorker>? __state)
		{
			LG_Zone zone = __instance.m_zone;
			if ((Object)(object)zone == (Object)null)
			{
				__state = null;
				return;
			}
			__state = new List<LightWorker>();
			Enumerator<AIG_CourseNode> enumerator = zone.m_courseNodes.GetEnumerator();
			while (enumerator.MoveNext())
			{
				AIG_CourseNode current = enumerator.Current;
				foreach (LG_Light componentsInChild in ((Component)current.m_area).GetComponentsInChildren<LG_Light>(false))
				{
					__state.Add(new LightWorker(zone, current, componentsInChild, ((Object)componentsInChild).GetInstanceID(), componentsInChild.m_intensity));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(600)]
		[HarmonyWrapSafe]
		private static void Post_ZoneBuild(LG_BuildZoneLightsJob __instance, bool __result, List<LightWorker>? __state)
		{
			if ((Object)(object)__instance.m_zone == (Object)null || !__result || __state == null)
			{
				return;
			}
			foreach (LightWorker item in __state)
			{
				item.Setup();
				LightAPI.AllLightsMap.TryAdd(item.InstanceID, item);
			}
		}
	}
	[HarmonyPatch]
	internal static class TerminalPatches
	{
		private static readonly Dictionary<(int, int, int), LG_ComputerTerminal> ReactorTerminals;

		static TerminalPatches()
		{
			ReactorTerminals = new Dictionary<(int, int, int), LG_ComputerTerminal>();
			LevelAPI.OnAfterBuildBatch += OnAfterBatchBuild;
			LevelAPI.OnLevelCleanup += OnLevelCleanup;
		}

		private static void OnAfterBatchBuild(BatchName batch)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			if ((int)batch != 47)
			{
				return;
			}
			foreach (KeyValuePair<(int, int, int), LG_ComputerTerminal> kvp in ReactorTerminals)
			{
				if (kvp.Key.TryGetZone(out LG_Zone zone) && !ListExtensions.ToManaged<LG_ComputerTerminal>(zone.TerminalsSpawnedInZone).Any((LG_ComputerTerminal term) => term.SyncID == kvp.Value.SyncID))
				{
					zone.TerminalsSpawnedInZone.Add(kvp.Value);
					Logger.Debug("Appended reactor terminal to its TerminalsSpawnedInZone");
				}
			}
		}

		private static void OnLevelCleanup()
		{
			ReactorTerminals.Clear();
		}

		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")]
		[HarmonyPrefix]
		[HarmonyPriority(700)]
		[HarmonyWrapSafe]
		private static void HiddenCommandExecutionFix(LG_ComputerTerminalCommandInterpreter __instance, ref TERM_Command cmd)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			if (((Il2CppArrayBase<TERM_Command>)(object)LG_ComputerTerminalCommandInterpreter.m_alwaysHiddenCommands).Contains(cmd))
			{
				return;
			}
			TERM_Command val = cmd;
			TERM_Command val2 = val;
			if ((int)val2 <= 6)
			{
				if ((int)val2 == 0 || val2 - 5 <= 1)
				{
					return;
				}
			}
			else if (val2 - 10 <= 1 || (int)val2 == 16 || (int)val2 == 31)
			{
				return;
			}
			if (__instance.m_terminal.CommandIsHidden(cmd))
			{
				cmd = (TERM_Command)10;
			}
		}

		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Start")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void CustomReactorTerminalFix(LG_WardenObjective_Reactor __instance)
		{
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("FlowGeos") && !((Object)(object)__instance.m_terminalPrefab != (Object)null))
			{
				Logger.Info("Resolving terminal prefab for reactor");
				GameObject loadedAsset = AssetAPI.GetLoadedAsset<GameObject>("Assets/AssetPrefabs/Complex/Generic/FunctionMarkers/Terminal_Floor.prefab");
				if ((Object)(object)loadedAsset == (Object)null)
				{
					Logger.Error("Failed to find terminal prefab loaded asset?");
				}
				else
				{
					__instance.m_terminalPrefab = loadedAsset;
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static bool ReactorTerminalSpawnNodeFix(LG_ComputerTerminal __instance, ref AIG_CourseNode __result)
		{
			if ((Object)(object)__instance.ConnectedReactor != (Object)null && __instance.m_terminalItem.SpawnNode == null)
			{
				__result = __instance.ConnectedReactor.SpawnNode;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "GenericObjectiveSetup")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void ReactorTerminalInZoneFix(LG_WardenObjective_Reactor __instance)
		{
			if (__instance.SpawnNode.m_zone.TerminalsSpawnedInZone != null && (Object)(object)__instance.m_terminal != (Object)null)
			{
				ReactorTerminals.Add(__instance.SpawnNode.m_zone.ToIntTuple(), __instance.m_terminal);
			}
		}
	}
	[HarmonyPatch]
	internal static class ZoneGraphPatches
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static void Pre_PlayerNodeSet(PlayerAgent __instance, ref AIG_CourseNode __state)
		{
			__state = ((Agent)__instance).CourseNode;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		private static void Post_PlayerNodeSet(PlayerAgent __instance, AIG_CourseNode __state)
		{
			AIG_CourseNode courseNode = ((Agent)__instance).CourseNode;
			if (courseNode != null && __state != courseNode)
			{
				ZoneGraphUtil.Current.Internal_OnPlayerNodeChanged(__instance, __state);
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static void Pre_GateIsTraversable(LG_Gate __instance, ref bool __state)
		{
			__state = __instance.IsTraversable;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		private static void Post_GateIsTraversable(LG_Gate __instance, bool __state)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			if (__state != __instance.IsTraversable && (int)((LG_ZoneExpander)__instance).ExpanderStatus == 1)
			{
				ZoneGraphUtil.Current.Internal_OnDoorStateChanged(__instance, !__state);
			}
		}
	}
}
namespace AmorLib.Networking
{
	public struct LowResColor
	{
		public byte r;

		public byte g;

		public byte b;

		public byte a;

		private static Color _color = Color.black;

		public static implicit operator Color(LowResColor lowResColor)
		{
			//IL_005d: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			_color.r = (float)(int)lowResColor.r / 255f;
			_color.g = (float)(int)lowResColor.g / 255f;
			_color.b = (float)(int)lowResColor.b / 255f;
			_color.a = (float)(int)lowResColor.a / 255f;
			return _color;
		}

		public static implicit operator LowResColor(Color color)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			return new LowResColor
			{
				r = (byte)(color.r * 255f),
				g = (byte)(color.g * 255f),
				b = (byte)(color.b * 255f),
				a = (byte)(color.a * 255f)
			};
		}
	}
	public abstract class SyncedEvent<S> where S : struct
	{
		public delegate void ReceiveHandler(S packet);

		public virtual string Prefix => string.Empty;

		public abstract string GUID { get; }

		public bool IsSetup { get; private set; } = false;

		public string EventName { get; private set; } = string.Empty;

		public event ReceiveHandler? OnReceive;

		public event ReceiveHandler? OnReceiveLocal;

		public void Setup()
		{
			if (!IsSetup)
			{
				EventName = (Utility.IsNullOrWhiteSpace(Prefix) ? ("SE-" + GUID) : ("SE-" + Prefix + "-" + GUID));
				NetworkAPI.RegisterEvent<S>(EventName, (Action<ulong, S>)ReceiveClient_Callback);
				IsSetup = true;
			}
		}

		public void Send(S packetData, SNet_Player? target = null, SNet_ChannelType priority = (SNet_ChannelType)4)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target != (Object)null)
			{
				NetworkAPI.InvokeEvent<S>(EventName, packetData, target, priority);
			}
			else
			{
				NetworkAPI.InvokeEvent<S>(EventName, packetData, priority);
			}
			ReceiveLocal_Callback(packetData);
		}

		private void ReceiveLocal_Callback(S packet)
		{
			ReceiveLocal(packet);
			this.OnReceiveLocal?.Invoke(packet);
		}

		private void ReceiveClient_Callback(ulong sender, S packet)
		{
			Receive(packet);
			this.OnReceive?.Invoke(packet);
		}

		protected virtual void ReceiveLocal(S packet)
		{
		}

		protected virtual void Receive(S packet)
		{
		}
	}
	public abstract class SyncedEventMasterOnly<S> : SyncedEvent<S> where S : struct
	{
		public void Send(S packet, SNet_ChannelType priority = (SNet_ChannelType)4)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster)
			{
				Send(packet, SNet.Master, priority);
			}
			else
			{
				Receive(packet);
			}
		}
	}
}
namespace AmorLib.Networking.StateReplicators
{
	public interface IStateReplicatorHolder<S> where S : struct
	{
		StateReplicator<S>? Replicator { get; }

		void OnStateChange(S oldState, S state, bool isRecall);
	}
	public struct Packet
	{
		public uint replicatorID;

		public PacketAction action;
	}
	public enum PacketAction : byte
	{
		Created,
		Destroyed,
		SyncRequest
	}
	internal sealed class ReplicatorHandshake
	{
		public delegate void ClientRequestedSyncDel(SNet_Player requestedPlayer);

		private readonly Dictionary<uint, (bool SetupOnHost, bool SetupOnClient)> _lookup = new Dictionary<uint, (bool, bool)>();

		public string EventName { get; private set; }

		public bool IsReadyToSync { get; private set; }

		public event ClientRequestedSyncDel? OnClientSyncRequested;

		public ReplicatorHandshake(string eventName)
		{
			EventName = eventName;
			NetworkAPI.RegisterEvent<Packet>(EventName, (Action<ulong, Packet>)OnSyncAction);
			SNetEvents.OnRecallDone += OnRecallDone;
		}

		private void OnRecallDone()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Handshake :: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(EventName);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Client sending sync request");
			}
			Logger.Warn(val);
			ClientSyncRequest();
		}

		private void ClientSyncRequest()
		{
			if (SNet.IsMaster)
			{
				return;
			}
			foreach (uint key in _lookup.Keys)
			{
				NetworkAPI.InvokeEvent<Packet>(EventName, new Packet
				{
					replicatorID = key,
					action = PacketAction.SyncRequest
				}, SNet.Master, (SNet_ChannelType)2);
			}
		}

		public void Reset()
		{
			_lookup.Clear();
		}

		private void OnSyncAction(ulong sender, Packet packet)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			if (!SNet.IsMaster && sender == SNet.Master.Lookup)
			{
				if (packet.action != PacketAction.SyncRequest)
				{
					SetHostState(packet.replicatorID, packet.action == PacketAction.Created);
				}
				else
				{
					Logger.Warn("Handshake :: OnSyncAction host sync request has no implementation");
				}
			}
			else
			{
				if (!SNet.IsMaster)
				{
					return;
				}
				bool flag = default(bool);
				switch (packet.action)
				{
				case PacketAction.Created:
					SetClientState(packet.replicatorID, isSetup: true);
					break;
				case PacketAction.Destroyed:
					SetClientState(packet.replicatorID, isSetup: false);
					break;
				case PacketAction.SyncRequest:
				{
					SNet_Player requestedPlayer = default(SNet_Player);
					if (!SNet.TryGetPlayer(sender, ref requestedPlayer))
					{
						BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(45, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Handshake :: Cannot find player from sender: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(sender);
						}
						Logger.Error(val);
					}
					else
					{
						this.OnClientSyncRequested?.Invoke(requestedPlayer);
					}
					break;
				}
				default:
				{
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(35, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Handshake :: Unknown packet action ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<PacketAction>(packet.action);
					}
					Logger.Error(val);
					break;
				}
				}
			}
		}

		public void UpdateCreated(uint id)
		{
			if (SNet.IsInLobby)
			{
				if (SNet.IsMaster)
				{
					SetHostState(id, isSetup: true);
					NetworkAPI.InvokeEvent<Packet>(EventName, new Packet
					{
						replicatorID = id,
						action = PacketAction.Created
					}, (SNet_ChannelType)2);
				}
				else if (SNet.HasMaster)
				{
					SetClientState(id, isSetup: true);
					NetworkAPI.InvokeEvent<Packet>(EventName, new Packet
					{
						replicatorID = id,
						action = PacketAction.Created
					}, SNet.Master, (SNet_ChannelType)2);
				}
				else
				{
					Logger.Error("Handshake :: MASTER is NULL in lobby; this should NOT happen!!");
				}
			}
			else
			{
				Logger.Error("Handshake :: Session LifeTimeType StateReplicator cannot be created without lobby!");
			}
		}

		public void UpdateDestroyed(uint id)
		{
			if (SNet.IsInLobby)
			{
				if (SNet.IsMaster)
				{
					SetHostState(id, isSetup: true);
					NetworkAPI.InvokeEvent<Packet>(EventName, new Packet
					{
						replicatorID = id,
						action = PacketAction.Destroyed
					}, (SNet_ChannelType)2);
				}
				else if (SNet.HasMaster)
				{
					SetClientState(id, isSetup: true);
					NetworkAPI.InvokeEvent<Packet>(EventName, new Packet
					{
						replicatorID = id,
						action = PacketAction.Destroyed
					}, SNet.Master, (SNet_ChannelType)2);
				}
				else
				{
					Logger.Error("Handshake :: MASTER is NULL in lobby; this should NOT happen!!");
				}
			}
			else
			{
				Logger.Error("Handshake :: Session LifeTimeType StateReplicator cannot be created without lobby!");
			}
		}

		private void SetHostState(uint id, bool isSetup)
		{
			if (_lookup.TryGetValue(id, out (bool, bool) value))
			{
				value.Item1 = isSetup;
			}
			else
			{
				_lookup[id] = new(bool, bool)
				{
					Item1 = isSetup
				};
			}
			UpdateSyncState(id);
		}

		private void SetClientState(uint id, bool isSetup)
		{
			if (_lookup.TryGetValue(id, out (bool, bool) value))
			{
				value.Item2 = isSetup;
			}
			else
			{
				_lookup[id] = new(bool, bool)
				{
					Item2 = isSetup
				};
			}
			UpdateSyncState(id);
		}

		private void UpdateSyncState(uint id)
		{
			bool isReadyToSync = IsReadyToSync;
			IsReadyToSync = _lookup.TryGetValue(id, out (bool, bool) value) && value.Item1 && value.Item2;
			if (IsReadyToSync && IsReadyToSync != isReadyToSync && SNet.HasMaster && !SNet.IsMaster)
			{
				NetworkAPI.InvokeEvent<Packet>(EventName, new Packet
				{
					replicatorID = id,
					action = PacketAction.SyncRequest
				}, SNet.Master, (SNet_ChannelType)2);
			}
		}
	}
	public enum Size
	{
		State4Byte = 4,
		State8Byte = 8,
		State16Byte = 16,
		State32Byte = 32,
		State48Byte = 48,
		State64Byte = 64,
		State80Byte = 80,
		State96Byte = 96,
		State128Byte = 128,
		State196Byte = 196,
		State256Byte = 256
	}
	internal delegate void OnReceiveDel<S>(ulong sender, uint replicatorID, S newState) where S : struct;
	internal interface IReplicatorEvent<S>
	{
		string EventName { get; }

		bool IsRegistered { get; }

		void Invoke(uint replicatorID, S data, SNet_Player? target = null, SNet_ChannelType priority = (SNet_ChannelType)2);
	}
	internal interface IStatePayload
	{
		uint ID { get; set; }

		S Get<S>(Size size) where S : struct;

		void Set<S>(S stateData, Size size) where S : struct;
	}
	internal class ReplicatorPayload<S, P> : IReplicatorEvent<S> where S : struct where P : struct, IStatePayload
	{
		private readonly Size _payloadSize;

		public string EventName { get; private set; } = string.Empty;

		public bool IsRegistered => NetworkAPI.IsEventRegistered(EventName);

		public ReplicatorPayload(Size size, string eventName, OnReceiveDel<S> onReceiveCallback)
		{
			ReplicatorPayload<S, P> replicatorPayload = this;
			NetworkAPI.RegisterEvent<P>(eventName, (Action<ulong, P>)delegate(ulong sender, P payload)
			{
				onReceiveCallback?.Invoke(sender, payload.ID, payload.Get<S>(replicatorPayload._payloadSize));
			});
			EventName = eventName;
			_payloadSize = size;
		}

		public void Invoke(uint replicatorID, S data, SNet_Player? target, SNet_ChannelType priority)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			P val = new P
			{
				ID = replicatorID
			};
			val.Set(data, _payloadSize);
			if ((Object)(object)target != (Object)null)
			{
				NetworkAPI.InvokeEvent<P>(EventName, val, target, priority);
			}
			else
			{
				NetworkAPI.InvokeEvent<P>(EventName, val, priority);
			}
		}
	}
	internal struct StatePayloadBytes : IStatePayload
	{
		public unsafe fixed byte PayloadBytes[256];

		public uint ID { get; set; }

		public unsafe S Get<S>(Size size) where S : struct
		{
			byte[] array = new byte[(int)size];
			fixed (byte* payloadBytes = PayloadBytes)
			{
				Marshal.Copy((IntPtr)payloadBytes, array, 0, (int)size);
			}
			return FromBytes<S>(array);
		}

		public unsafe void Set<S>(S stateData, Size size) where S : struct
		{
			byte[] array = ToBytes(stateData);
			if (array.Length > (int)size)
			{
				throw new ArgumentException($"Data size {array.Length} exceeds payload size {size}, unable to serialize {"S"}!");
			}
			fixed (byte* payloadBytes = PayloadBytes)
			{
				Marshal.Copy(array, 0, (IntPtr)payloadBytes, array.Length);
				for (int i = array.Length; i < (int)size; i++)
				{
					payloadBytes[i] = 0;
				}
			}
		}

		private static byte[] ToBytes<S>(S data) where S : struct
		{
			int num = Marshal.SizeOf<S>();
			byte[] array = new byte[num];
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			try
			{
				Marshal.StructureToPtr(data, intPtr, fDeleteOld: false);
				Marshal.Copy(intPtr, array, 0, num);
				return array;
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
			}
		}

		private static S FromBytes<S>(byte[] arr) where S : struct
		{
			IntPtr intPtr = Marshal.AllocHGlobal(arr.Length);
			try
			{
				Marshal.Copy(arr, 0, intPtr, arr.Length);
				return Marshal.PtrToStructure<S>(intPtr);
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
			}
		}
	}
	public enum LifeTimeType
	{
		Permanent,
		Session
	}
	public sealed class StateReplicator<S> where S : struct
	{
		internal readonly Dictionary<eBufferType, S> _recallStateSnapshots = new Dictionary<eBufferType, S>();

		public static readonly string Name;

		public static readonly string HashName;

		public static readonly string ClientRequestEventName;

		public static readonly string HostSetStateEventName;

		public static readonly string HostSetRecallStateEventName;

		public static readonly string HandshakeEventName;

		public static readonly int StateSize;

		public static readonly Size StateSizeType;

		private static readonly IReplicatorEvent<S>? _clientRequestEvent;

		private static readonly IReplicatorEvent<S>? _hostSetStateEvent;

		private static readonly IReplicatorEvent<S>? _hostSetRecallStateEvent;

		private static readonly ReplicatorHandshake? _handshake;

		internal static readonly Dictionary<uint, StateReplicator<S>> _replicators;

		public bool IsValid => ID != 0;

		public bool IsInvalid => ID == 0;

		public uint ID { get; private set; }

		public LifeTimeType LifeTime { get; private set; }

		public IStateReplicatorHolder<S>? Holder { get; private set; }

		public S State { get; private set; }

		public S LastState { get; private set; }

		public bool ClientSendStateAllowed { get; set; } = true;

		public bool CanSendToClient => SNet.IsInLobby && SNet.IsMaster;

		public bool CanSendToHost => SNet.IsInLobby && !SNet.IsMaster && SNet.HasMaster && ClientSendStateAllowed;

		public event Action<S, S, bool>? OnStateChanged;

		public void SetState(S state)
		{
			if (!IsInvalid)
			{
				DoSync(state);
			}
		}

		public void SetStateUnsynced(S state)
		{
			if (!IsInvalid)
			{
				LastState = state;
				State = state;
			}
		}

		public void Unload()
		{
			if (IsValid)
			{
				_replicators.Remove(ID);
				_recallStateSnapshots.Clear();
				_handshake?.UpdateDestroyed(ID);
				ID = 0u;
			}
		}

		private void DoSync(S newState)
		{
			if (IsValid)
			{
				if (CanSendToClient)
				{
					_hostSetStateEvent?.Invoke(ID, newState, null, (SNet_ChannelType)2);
					Internal_ChangeState(newState, isRecall: false);
				}
				else if (CanSendToHost)
				{
					_clientRequestEvent?.Invoke(ID, newState, SNet.Master, (SNet_ChannelType)2);
				}
			}
		}

		private void Internal_ChangeState(S state, bool isRecall)
		{
			if (!IsInvalid)
			{
				S state2 = State;
				State = state;
				LastState = state2;
				this.OnStateChanged?.Invoke(state2, state, isRecall);
				Holder?.OnStateChange(state2, state, isRecall);
			}
		}

		private void SendDropInState(SNet_Player target)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if (IsInvalid || (Object)(object)target == (Object)null)
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(35, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("IsInvalid: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(IsInvalid);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("SendDropInState");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" :: Target was null? ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)target == (Object)null);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("?");
				}
				Logger.Error(val);
			}
			else
			{
				_hostSetRecallStateEvent?.Invoke(ID, State, target, (SNet_ChannelType)2);
			}
		}

		public void ClearAllRecallSnapshot()
		{
			if (!IsInvalid)
			{
				_recallStateSnapshots.Clear();
			}
		}

		private void SaveSnapshot(eBufferType type)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!IsInvalid)
			{
				_recallStateSnapshots[type] = State;
			}
		}

		private void RestoreSnapshot(eBufferType type)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (!IsValid || !CanSendToClient)
			{
				return;
			}
			if (_recallStateSnapshots.TryGetValue(type, out var value))
			{
				_hostSetRecallStateEvent?.Invoke(ID, value, null, (SNet_ChannelType)2);
				Internal_ChangeState(value, isRecall: true);
				return;
			}
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("RestoreSnapshot");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" :: There was no snapshot for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eBufferType>(type);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("?");
			}
			Logger.Error(val);
		}

		static StateReplicator()
		{
			_replicators = new Dictionary<uint, StateReplicator<S>>();
			Name = typeof(S).Name;
			StateSize = Marshal.SizeOf(typeof(S));
			StateSizeType = GetSizeType(StateSize);
			using MD5 mD = MD5.Create();
			byte[] inArray = mD.ComputeHash(Encoding.UTF8.GetBytes(typeof(S).FullName));
			HashName = Convert.ToBase64String(inArray);
			ClientRequestEventName = "SRcr-" + Name + "-" + HashName;
			HostSetStateEventName = "SRhs-" + Name + "-" + HashName;
			HostSetRecallStateEventName = "SRre-" + Name + "-" + HashName;
			HandshakeEventName = "RH-" + Name + "-" + HashName;
			_clientRequestEvent = CreatePayloadEvent(ClientRequestEventName, ClientRequestEventCallback);
			_hostSetStateEvent = CreatePayloadEvent(HostSetStateEventName, HostSetStateEventCallback);
			_hostSetRecallStateEvent = CreatePayloadEvent(HostSetRecallStateEventName, HostSetRecallStateEventCallback);
			_handshake = CreateHandshakeEvent();
			SNetEvents.OnBufferCapture += BufferStored;
			SNetEvents.OnBufferRecall += BufferRecalled;
			LevelAPI.OnLevelCleanup += OnLevelCleanup;
		}

		public static StateReplicator<S>? Create(uint replicatorID, S startState, LifeTimeType lifeTime, IStateReplicatorHolder<S>? holder = null)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			if (replicatorID == 0)
			{
				Logger.Error("Replicator ID 0 is reserved for empty!");
				return null;
			}
			if (_replicators.ContainsKey(replicatorID))
			{
				Logger.Error("Replicator ID has already assigned!");
				return null;
			}
			StateReplicator<S> stateReplicator = new StateReplicator<S>
			{
				ID = replicatorID,
				LifeTime = lifeTime,
				Holder = holder,
				State = startState
			};
			switch (lifeTime)
			{
			case LifeTimeType.Permanent:
				Logger.Debug("LifeTime is Permanent :: Handshaking is disabled");
				break;
			case LifeTimeType.Session:
				_handshake?.UpdateCreated(replicatorID);
				break;
			default:
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LifeTime ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LifeTimeType>(lifeTime);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is invalid!");
				}
				Logger.Error(val);
				return null;
			}
			}
			_replicators[replicatorID] = stateReplicator;
			return stateReplicator;
		}

		public static Size GetSizeType(int stateSize)
		{
			Size size = Size.State8Byte;
			foreach (Size value in Enum.GetValues(typeof(Size)))
			{
				if (stateSize <= (int)value && size < value)
				{
					size = valu

plugins/Inas07.EOSExt.DimensionWarp.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AIGraph;
using Agents;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using EOSExt.DimensionWarp.Definition;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Utils;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.DimensionWarp
{
	public class DimensionWarpManager : GenericExpeditionDefinitionManager<DimensionWarpDefinition>
	{
		public enum WardenEvents_Warp
		{
			WarpTeam = 160,
			WarpRange,
			WarpItemsInZone
		}

		private readonly ImmutableList<Vector3> lookDirs = new List<Vector3>
		{
			Vector3.forward,
			Vector3.back,
			Vector3.left,
			Vector3.right
		}.ToImmutableList();

		public static DimensionWarpManager Current { get; private set; }

		protected override string DEFINITION_NAME => "DimensionWarp";

		public AIG_NodeCluster GetNodeFromDimensionPosition(eDimensionIndex dimensionIndex, Vector3 position)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			AIG_GeomorphNodeVolume val = default(AIG_GeomorphNodeVolume);
			AIG_VoxelNodePillar val2 = default(AIG_VoxelNodePillar);
			AIG_INode val3 = default(AIG_INode);
			AIG_NodeCluster result = default(AIG_NodeCluster);
			if (!AIG_GeomorphNodeVolume.TryGetGeomorphVolume(0, dimensionIndex, position, ref val) || !((AIG_NodeVolume)val).m_voxelNodeVolume.TryGetPillar(position, ref val2) || !val2.TryGetVoxelNode(position.y, ref val3) || !AIG_NodeCluster.TryGetNodeCluster(val3.ClusterID, ref result))
			{
				EOSLogger.Error("GetNodeFromDimensionPosition: Position is not valid, try again inside an area.");
				return null;
			}
			return result;
		}

		public DimensionWarpDefinition GetWarpDefinition(string worldEventObjectFilter)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if ((int)GameStateManager.CurrentStateName != 10 || !base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData))
			{
				EOSLogger.Error($"GetWarpPositions: Didn't find config with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}");
				return null;
			}
			DimensionWarpDefinition dimensionWarpDefinition = base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.Find((DimensionWarpDefinition def) => def.WorldEventObjectFilter == worldEventObjectFilter);
			if (dimensionWarpDefinition == null)
			{
				EOSLogger.Error($"GetWarpPositions: Didn't find config for {worldEventObjectFilter} with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}");
				return new DimensionWarpDefinition();
			}
			return dimensionWarpDefinition;
		}

		public void WarpItem(ItemInLevel item, eDimensionIndex warpToDim, Vector3 warpToPosition)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_002a: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (SNet.IsMaster && (int)GameStateManager.CurrentStateName == 10 && (Object)(object)item != (Object)null)
			{
				AIG_NodeCluster nodeFromDimensionPosition = GetNodeFromDimensionPosition(warpToDim, warpToPosition);
				if (nodeFromDimensionPosition != null)
				{
					item.GetSyncComponent().AttemptPickupInteraction((ePickupItemInteractionType)1, (SNet_Player)null, ((Item)item).pItemData.custom, warpToPosition, Quaternion.identity, nodeFromDimensionPosition.CourseNode, true, true);
				}
				else
				{
					EOSLogger.Error("WarpTeam: cannot find course node for item to warp");
				}
			}
		}

		public void WarpItemsInZone(eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex, string worldEventObjectFilter)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster || (int)GameStateManager.CurrentStateName != 10)
			{
				return;
			}
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			if ((Object)(object)localPlayerAgent == (Object)null)
			{
				EOSLogger.Error("WarpItemsInZone: master - LocalPlayerAgent is null???");
				return;
			}
			DimensionWarpDefinition warpDefinition = GetWarpDefinition(worldEventObjectFilter);
			if (warpDefinition == null)
			{
				EOSLogger.Error("WarpItemsInZone: worldEventObjectFilter '" + worldEventObjectFilter + "' is not defined");
				return;
			}
			List<PositionAndLookDir> locations = warpDefinition.Locations;
			if (locations.Count < 1)
			{
				EOSLogger.Error("WarpItemsInZone: no warp position found");
				return;
			}
			int num = 0;
			Enumerator<IWarpableObject> enumerator = Dimension.WarpableObjects.GetEnumerator();
			while (enumerator.MoveNext())
			{
				IWarpableObject current = enumerator.Current;
				ItemInLevel val = ((Il2CppObjectBase)current).TryCast<ItemInLevel>();
				if ((Object)(object)val != (Object)null)
				{
					AIG_CourseNode courseNode = val.CourseNode;
					if (val.internalSync.GetCurrentState().placement.droppedOnFloor && courseNode.m_dimension.DimensionIndex == dimensionIndex && courseNode.LayerType == layer && courseNode.m_zone.LocalIndex == localIndex && (!warpDefinition.OnWarp.WarpItemsInZone_OnlyWarpWarpable || val.CanWarp))
					{
						Vector3 warpToPosition = locations[num].Position.ToVector3();
						WarpItem(val, dimensionIndex, warpToPosition);
					}
					num = (num + 1) % locations.Count;
				}
			}
		}

		internal void WarpItemsInZone(WardenObjectiveEventData e)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			eDimensionIndex dimensionIndex = e.DimensionIndex;
			LG_LayerType layer = e.Layer;
			eLocalZoneIndex localIndex = e.LocalIndex;
			string worldEventObjectFilter = e.WorldEventObjectFilter;
			WarpItemsInZone(dimensionIndex, layer, localIndex, worldEventObjectFilter);
		}

		public void WarpRange(Vector3 rangeOrigin, float range, string worldEventObjectFilter)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: 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)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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_0274: 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_01f0: 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_029f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)GameStateManager.CurrentStateName != 10)
			{
				return;
			}
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			if ((Object)(object)localPlayerAgent == (Object)null)
			{
				EOSLogger.Error("WarpTeam: LocalPlayerAgent is null");
				return;
			}
			DimensionWarpDefinition warpDefinition = GetWarpDefinition(worldEventObjectFilter);
			if (warpDefinition == null)
			{
				EOSLogger.Error("WarpItemsInZone: worldEventObjectFilter '" + worldEventObjectFilter + "' is not defined");
				return;
			}
			List<PositionAndLookDir> locations = warpDefinition.Locations;
			if (locations.Count < 1)
			{
				EOSLogger.Error("WarpAlivePlayersInRange: no warp locations found");
				return;
			}
			int index = localPlayerAgent.PlayerSlotIndex % locations.Count;
			Vector3 val = locations[index].Position.ToVector3();
			int index2 = locations[index].LookDir % lookDirs.Count;
			Vector3 val2 = lookDirs[index2];
			int num = 0;
			List<SentryGunInstance> list = new List<SentryGunInstance>();
			Enumerator<IWarpableObject> enumerator = Dimension.WarpableObjects.GetEnumerator();
			Vector3 val4;
			while (enumerator.MoveNext())
			{
				IWarpableObject current = enumerator.Current;
				SentryGunInstance val3 = ((Il2CppObjectBase)current).TryCast<SentryGunInstance>();
				if ((Object)(object)val3 != (Object)null)
				{
					if (!((ItemEquippable)val3).LocallyPlaced || !((Agent)((Item)val3).Owner).Alive)
					{
						continue;
					}
					val4 = rangeOrigin - ((Agent)((Item)val3).Owner).Position;
					if (((Vector3)(ref val4)).magnitude < range)
					{
						val4 = rangeOrigin - ((Component)val3).transform.position;
						if (((Vector3)(ref val4)).magnitude < range || warpDefinition.OnWarp.WarpRange_WarpDeployedSentryOutsideRange)
						{
							list.Add(val3);
						}
					}
				}
				else
				{
					if (!SNet.IsMaster)
					{
						continue;
					}
					ItemInLevel val5 = ((Il2CppObjectBase)current).TryCast<ItemInLevel>();
					if ((Object)(object)val5 != (Object)null)
					{
						val4 = ((Component)val5).transform.position - rangeOrigin;
						if (((Vector3)(ref val4)).magnitude < range)
						{
							Vector3 warpToPosition = locations[num].Position.ToVector3();
							WarpItem(val5, warpDefinition.DimensionIndex, warpToPosition);
							num = (num + 1) % locations.Count;
						}
					}
				}
			}
			list.ForEach(delegate(SentryGunInstance sentryGun)
			{
				sentryGun.m_sync.WantItemAction(((Item)sentryGun).Owner, (SyncedItemAction_New)0);
			});
			if (((Agent)localPlayerAgent).Alive)
			{
				val4 = rangeOrigin - ((Agent)localPlayerAgent).Position;
				if (((Vector3)(ref val4)).magnitude < range && !localPlayerAgent.TryWarpTo(warpDefinition.DimensionIndex, val, val2, true))
				{
					EOSLogger.Error($"WarpAlivePlayersInRange: TryWarpTo failed, Position: {val}");
				}
			}
		}

		internal void WarpRange(WardenObjectiveEventData e)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = e.Position;
			float fogTransitionDuration = e.FogTransitionDuration;
			string worldEventObjectFilter = e.WorldEventObjectFilter;
			WarpRange(position, fogTransitionDuration, worldEventObjectFilter);
		}

		public void WarpTeam(string worldEventObjectFilter)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			if ((int)GameStateManager.CurrentStateName != 10)
			{
				return;
			}
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			if ((Object)(object)localPlayerAgent == (Object)null)
			{
				EOSLogger.Error("WarpTeam: LocalPlayerAgent is null");
				return;
			}
			DimensionWarpDefinition warpDefinition = GetWarpDefinition(worldEventObjectFilter);
			if (warpDefinition == null)
			{
				EOSLogger.Error("WarpTeam: worldEventObjectFilter '" + worldEventObjectFilter + "' is not defined");
				return;
			}
			List<PositionAndLookDir> locations = warpDefinition.Locations;
			if (locations.Count < 1)
			{
				EOSLogger.Error("WarpTeam: no warp locations found");
				return;
			}
			int num = localPlayerAgent.PlayerSlotIndex % locations.Count;
			Vector3 val = locations[num].Position.ToVector3();
			int index = locations[num].LookDir % lookDirs.Count;
			Vector3 val2 = lookDirs[index];
			int num2 = 0;
			List<SentryGunInstance> list = new List<SentryGunInstance>();
			Enumerator<IWarpableObject> enumerator = Dimension.WarpableObjects.GetEnumerator();
			while (enumerator.MoveNext())
			{
				IWarpableObject current = enumerator.Current;
				SentryGunInstance val3 = ((Il2CppObjectBase)current).TryCast<SentryGunInstance>();
				if ((Object)(object)val3 != (Object)null)
				{
					if (((ItemEquippable)val3).LocallyPlaced)
					{
						list.Add(val3);
					}
				}
				else if (SNet.IsMaster && warpDefinition.OnWarp.WarpTeam_WarpAllWarpableBigPickupItems)
				{
					ItemInLevel val4 = ((Il2CppObjectBase)current).TryCast<ItemInLevel>();
					if ((Object)(object)val4 != (Object)null && val4.CanWarp && val4.internalSync.GetCurrentState().placement.droppedOnFloor)
					{
						Vector3 warpToPosition = locations[num2].Position.ToVector3();
						WarpItem(val4, warpDefinition.DimensionIndex, warpToPosition);
						EOSLogger.Warning(((Item)val4).PublicName ?? "");
						num2 = (num2 + 1) % locations.Count;
					}
				}
			}
			list.ForEach(delegate(SentryGunInstance sentryGun)
			{
				sentryGun.m_sync.WantItemAction(((Item)sentryGun).Owner, (SyncedItemAction_New)0);
			});
			if (!localPlayerAgent.TryWarpTo(warpDefinition.DimensionIndex, val, val2, true))
			{
				EOSLogger.Error($"WarpTeam: TryWarpTo failed. Position: {val}, playerSlotIndex: {localPlayerAgent.PlayerSlotIndex}, warpLocationIndex: {num}");
			}
		}

		internal void WarpTeam(WardenObjectiveEventData e)
		{
			WarpTeam(e.WorldEventObjectFilter);
		}

		private DimensionWarpManager()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			EOSWardenEventManager.Current.AddEventDefinition(WardenEvents_Warp.WarpTeam.ToString(), 160u, (Action<WardenObjectiveEventData>)WarpTeam);
			EOSWardenEventManager.Current.AddEventDefinition(WardenEvents_Warp.WarpRange.ToString(), 161u, (Action<WardenObjectiveEventData>)WarpRange);
			EOSWardenEventManager.Current.AddEventDefinition(WardenEvents_Warp.WarpItemsInZone.ToString(), 162u, (Action<WardenObjectiveEventData>)WarpItemsInZone);
		}

		static DimensionWarpManager()
		{
			Current = new DimensionWarpManager();
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.EOSExt.DimensionWarp", "EOSExt.DimensionWarp", "1.1.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.DimensionWarp";

		public const string VERSION = "1.1.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			SetupManagers();
			m_Harmony = new Harmony("EOSExt.DimensionWarp");
			m_Harmony.PatchAll();
			EOSLogger.Log("ExtraObjectiveSetup.DimensionWarp loaded.");
		}

		private void SetupManagers()
		{
			((GenericExpeditionDefinitionManager<DimensionWarpDefinition>)DimensionWarpManager.Current).Init();
		}
	}
}
namespace EOSExt.DimensionWarp.Definition
{
	public class PositionAndLookDir
	{
		public Vec3 Position { get; set; } = new Vec3();

		public int LookDir { get; set; } = 0;
	}
	public class OnWarp
	{
		public bool WarpTeam_WarpAllWarpableBigPickupItems { get; set; } = true;

		public bool WarpRange_WarpDeployedSentryOutsideRange { get; set; } = true;

		public bool WarpItemsInZone_OnlyWarpWarpable { get; set; } = true;
	}
	public class DimensionWarpDefinition
	{
		public string WorldEventObjectFilter { get; set; } = string.Empty;

		public eDimensionIndex DimensionIndex { get; set; } = (eDimensionIndex)0;

		public OnWarp OnWarp { get; set; } = new OnWarp();

		public List<PositionAndLookDir> Locations { get; set; } = new List<PositionAndLookDir>();
	}
}

plugins/Inas07.EOSExt.EMP.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AK;
using Agents;
using AmorLib.API;
using AmorLib.Networking.StateReplicators;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using EOSExt.EMP.Definition;
using EOSExt.EMP.EMPComponent;
using EOSExt.EMP.Impl;
using EOSExt.EMP.Impl.Handlers;
using EOSExt.EMP.Impl.PersistentEMP;
using ExtraObjectiveSetup;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Utils;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.EMP
{
	internal static class AWOUtil
	{
		public const string PLUGIN_GUID = "GTFO.AWO";

		public static bool IsLoaded { get; private set; }

		static AWOUtil()
		{
			IsLoaded = false;
			IsLoaded = ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("GTFO.AWO", out var _);
			EOSLogger.Debug($"EOSExt.EMP: AWO Loaded? {IsLoaded}");
		}
	}
	public class EMPManager : GenericExpeditionDefinitionManager<pEMPDefinition>
	{
		private bool _lightHandlersHooked;

		public static EMPManager Current { get; }

		public PlayerAgent Player => (SNet.HasLocalPlayer && SNet.LocalPlayer.HasPlayerAgent) ? ((Il2CppObjectBase)SNet.LocalPlayer.PlayerAgent).Cast<PlayerAgent>() : null;

		internal List<EMPShock> ActiveEMPs { get; } = new List<EMPShock>();

		private Dictionary<uint, pEMP> _pEMPs { get; } = new Dictionary<uint, pEMP>();

		public IEnumerable<pEMP> pEMPs => _pEMPs.Values;

		protected override string DEFINITION_NAME => "PersistentEMP";

		internal void SetLocalPlayerAgent(PlayerAgent localPlayerAgent)
		{
			if ((Object)(object)PlayerpEMPComponent.Current == (Object)null)
			{
				((Component)localPlayerAgent).gameObject.AddComponent<PlayerpEMPComponent>();
			}
		}

		public void ActivateEMPShock(Vector3 position, float range, float duration)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!GameStateManager.IsInExpedition)
			{
				EOSLogger.Error("Tried to activate an EMP when not in level, this shouldn't happen!");
				return;
			}
			float endTime = Clock.Time + duration;
			EMPShock eMPShock = new EMPShock(position, range, endTime);
			foreach (EMPHandler allHandler in EMPHandler.AllHandlers)
			{
				if (Vector3.Distance(position, allHandler.position) < range)
				{
					allHandler.AddAffectedBy(eMPShock);
				}
			}
			ActiveEMPs.Add(eMPShock);
		}

		internal void RemoveInactiveEMPs()
		{
			float time = Clock.Time;
			ActiveEMPs.RemoveAll((EMPShock emp) => emp.endTime < time);
		}

		public bool IsPlayerMapEMPD()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player == (Object)null || !GameStateManager.IsInExpedition)
			{
				return false;
			}
			Vector3 position = ((Agent)Player).Position;
			foreach (EMPShock activeEMP in ActiveEMPs)
			{
				if (Vector3.Distance(position, activeEMP.position) < activeEMP.range)
				{
					return true;
				}
			}
			foreach (pEMP pEMP in pEMPs)
			{
				if (pEMP.State != ActiveState.ENABLED || !pEMP.ItemToDisable.Map || !(Vector3.Distance(position, pEMP.position) < pEMP.range))
				{
					continue;
				}
				EOSLogger.Warning("MapEMPD: by pEMP");
				return true;
			}
			return false;
		}

		protected override void FileChanged(LiveEditEventArgs e)
		{
			base.FileChanged(e);
			if (!base.definitions.TryGetValue(base.CurrentMainLevelLayout, out var value))
			{
				return;
			}
			foreach (pEMPDefinition definition in value.Definitions)
			{
				EOSLogger.Warning(definition.ItemToDisable.ToString());
			}
		}

		private void HookLightHandlers()
		{
			if (_lightHandlersHooked)
			{
				return;
			}
			_lightHandlersHooked = true;
			LevelAPI.OnBuildDone += delegate
			{
				foreach (LightWorker item in LightAPI.GetLightWorkersInDimension(Enum.GetValues<eDimensionIndex>()))
				{
					if (!((Object)(object)item?.Light == (Object)null))
					{
						GameObject gameObject = ((Component)item.Light).gameObject;
						if (!((Object)(object)gameObject.GetComponent<EMPController>() != (Object)null))
						{
							gameObject.AddComponent<EMPController>().AssignHandler(new EMPLightHandler(item));
						}
					}
				}
			};
		}

		public override void Init()
		{
			EMPWardenEvents.Init();
			Events.InventoryWielded = (Action<InventorySlot>)Delegate.Combine(Events.InventoryWielded, new Action<InventorySlot>(SetupAmmoWeaponHandlers));
			pEMPInit();
			HookLightHandlers();
		}

		private EMPManager()
		{
		}

		static EMPManager()
		{
			Current = new EMPManager();
			ClassInjector.RegisterTypeInIl2Cpp<EMPController>();
			ClassInjector.RegisterTypeInIl2Cpp<PlayerpEMPComponent>();
		}

		internal void SetupHUDAndFlashlight()
		{
			if ((Object)(object)Player == (Object)null)
			{
				EOSLogger.Error($"{"SetupHUDAndFlashlight": LocalPlayerAgent is not set!}");
				return;
			}
			if (EMPPlayerHudHandler.Instance == null)
			{
				((Component)Player).gameObject.AddComponent<EMPController>().AssignHandler(new EMPPlayerHudHandler());
				EOSLogger.Log("pEMP: PlayerHud setup completed");
			}
			if (EMPPlayerFlashLightHandler.Instance == null)
			{
				((Component)Player).gameObject.AddComponent<EMPController>().AssignHandler(new EMPPlayerFlashLightHandler());
				EOSLogger.Log("pEMP: PlayerFlashlight setup completed");
			}
		}

		internal void SetupAmmoWeaponHandlers(InventorySlot slot)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (slot - 1 <= 1)
			{
				SetupAmmoWeaponHandlerForSlot(slot);
			}
			static void SetupAmmoWeaponHandlerForSlot(InventorySlot val)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack;
				BackpackItem val2 = default(BackpackItem);
				if (localBackpack.TryGetBackpackItem(val, ref val2))
				{
					if (!((Object)(object)((Component)val2.Instance).gameObject.GetComponent<EMPController>() != (Object)null))
					{
						((Component)val2.Instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPGunSightHandler());
						EOSLogger.Log($"pEMP: Backpack {val} setup completed");
					}
				}
				else
				{
					EOSLogger.Warning($"Couldn't get item for slot {val}!");
				}
			}
		}

		internal void SetupToolHandler()
		{
			PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack;
			BackpackItem val = default(BackpackItem);
			if (localBackpack.TryGetBackpackItem((InventorySlot)3, ref val))
			{
				if (!((Object)(object)((Component)val.Instance).gameObject.GetComponent<EMPController>() != (Object)null) && (Object)(object)((Component)val.Instance).GetComponent<EnemyScanner>() != (Object)null)
				{
					((Component)val.Instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPBioTrackerHandler());
					EOSLogger.Log($"pEMP: Backpack {3} setup completed");
				}
			}
			else
			{
				EOSLogger.Warning($"Couldn't get item for slot {3}!");
			}
		}

		public void TogglepEMPState(uint pEMPIndex, bool enabled)
		{
			if (!_pEMPs.ContainsKey(pEMPIndex))
			{
				EOSLogger.Error($"TogglepEMPState: pEMPIndex {pEMPIndex} not defined");
			}
			else
			{
				ActiveState newState = (enabled ? ActiveState.ENABLED : ActiveState.DISABLED);
				pEMP pEMP = _pEMPs[pEMPIndex];
				pEMP.ChangeToState(newState);
			}
		}

		public void TogglepEMPState(WardenObjectiveEventData e)
		{
			uint count = (uint)e.Count;
			bool enabled = e.Enabled;
			TogglepEMPState(count, enabled);
		}

		private void pEMPInit()
		{
			LevelAPI.OnBuildStart += delegate
			{
				pEMPClear();
				InitializepEMPs();
			};
			LevelAPI.OnLevelCleanup += pEMPClear;
		}

		private void pEMPClear()
		{
			foreach (pEMP value in _pEMPs.Values)
			{
				value.Destroy();
			}
			_pEMPs.Clear();
		}

		private void InitializepEMPs()
		{
			if (!base.definitions.ContainsKey(base.CurrentMainLevelLayout))
			{
				return;
			}
			GenericExpeditionDefinition<pEMPDefinition> val = base.definitions[base.CurrentMainLevelLayout];
			if (val == null || val.Definitions.Count < 1)
			{
				return;
			}
			foreach (pEMPDefinition definition in val.Definitions)
			{
				pEMP pEMP = new pEMP(definition);
				_pEMPs[definition.pEMPIndex] = pEMP;
				uint num = EOSNetworking.AllotReplicatorID();
				if (num == 0)
				{
					EOSLogger.Error("SetuppEMPReplicators: replicator ID depleted, cannot set up!");
					continue;
				}
				pEMP.SetupReplicator(num);
				EOSLogger.Debug($"pEMP_{definition.pEMPIndex} initialized");
			}
		}
	}
	internal static class EMPWardenEvents
	{
		public enum EMPEvents
		{
			Instant_Shock = 300,
			Toggle_PEMP_State
		}

		internal static void InstantShock(WardenObjectiveEventData e)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = e.Position;
			float fogTransitionDuration = e.FogTransitionDuration;
			float duration = e.Duration;
			EMPManager.Current.ActivateEMPShock(position, fogTransitionDuration, duration);
		}

		internal static void TogglepEMPState(WardenObjectiveEventData e)
		{
			EMPManager.Current.TogglepEMPState(e);
		}

		internal static void Init()
		{
			EOSWardenEventManager.Current.AddEventDefinition(EMPEvents.Instant_Shock.ToString(), 300u, (Action<WardenObjectiveEventData>)InstantShock);
			EOSWardenEventManager.Current.AddEventDefinition(EMPEvents.Toggle_PEMP_State.ToString(), 301u, (Action<WardenObjectiveEventData>)TogglepEMPState);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.EOSExt.EMP", "EOSExt.EMP", "1.2.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.EMP";

		public const string VERSION = "1.2.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			m_Harmony = new Harmony("EOSExt.EMP");
			m_Harmony.PatchAll();
			SetupManagers();
		}

		private void SetupManagers()
		{
			((GenericExpeditionDefinitionManager<pEMPDefinition>)EMPManager.Current).Init();
		}
	}
	public static class Events
	{
		public static Action<GearPartFlashlight> FlashLightWielded;

		public static Action<InventorySlot> InventoryWielded;

		public static Action EnterGSInLevel;
	}
}
namespace EOSExt.EMP.Patches
{
	[HarmonyPatch]
	[HarmonyWrapSafe]
	internal class Inject_CM_PageMap
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageMap), "UpdatePlayerData")]
		private static void Post_CM_PageMap_OnEnable()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			CM_PageMap pageMap = MainMenuGuiLayer.Current.PageMap;
			if (!((Object)(object)pageMap == (Object)null) && RundownManager.ActiveExpedition != null && (int)GameStateManager.CurrentStateName == 10 && !pageMap.m_mapDisconnected.activeSelf && EMPManager.Current.IsPlayerMapEMPD())
			{
				pageMap.SetMapVisualsIsActive(false);
				pageMap.SetMapDisconnetedTextIsActive(true);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyScanner))]
	internal static class Inject_EnemyScanner
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("UpdateDetectedEnemies")]
		internal static bool Pre_UpdateDetectedEnemies()
		{
			EMPBioTrackerHandler instance = EMPBioTrackerHandler.Instance;
			return instance == null || !instance.IsEMPed();
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("UpdateTagProgress")]
		internal static bool Pre_UpdateTagProgress(EnemyScanner __instance)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (EMPBioTrackerHandler.Instance == null)
			{
				return true;
			}
			if (EMPBioTrackerHandler.Instance.IsEMPed())
			{
				((ItemEquippable)__instance).Sound.Post(EVENTS.BIOTRACKER_TOOL_LOOP_STOP, true);
				__instance.m_screen.SetStatusText("ERROR");
				((ProgressBarBase)__instance.m_progressBar).SetProgress(1f);
				__instance.m_screen.SetGuixColor(Color.yellow);
				return false;
			}
			__instance.m_screen.SetStatusText("Ready to tag");
			__instance.m_screen.SetGuixColor(Color.red);
			return true;
		}
	}
	[HarmonyPatch]
	internal static class Inject_Events
	{
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(PlayerInventoryBase), "OnItemEquippableFlashlightWielded")]
		internal static void Post_OnItemEquippableFlashlightWielded(GearPartFlashlight flashlight)
		{
			Events.FlashLightWielded?.Invoke(flashlight);
		}

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(PlayerInventoryLocal), "DoWieldItem")]
		internal static void Post_DoWieldItem(PlayerInventoryLocal __instance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Events.InventoryWielded?.Invoke(((PlayerInventoryBase)__instance).WieldedSlot);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GS_InLevel), "Enter")]
		private static void Post_SetupGear(GS_InLevel __instance)
		{
			Events.EnterGSInLevel?.Invoke();
		}
	}
	[HarmonyPatch]
	internal static class Inject_PlayerAgent
	{
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(PlayerAgent), "Setup")]
		internal static void Post_Setup(PlayerAgent __instance)
		{
			if (((Agent)__instance).IsLocallyOwned)
			{
				EMPManager.Current.SetLocalPlayerAgent(__instance);
			}
		}
	}
	[HarmonyPatch]
	internal static class Inject_PlayerHUD
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(PlayerGuiLayer), "UpdateGUIElementsVisibility")]
		private static bool Pre_UpdateGUIElementsVisibility()
		{
			if (EMPPlayerHudHandler.Instance != null && EMPPlayerHudHandler.Instance.IsEMPed())
			{
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(CellSettingsApply), "ApplyPlayerGhostOpacity")]
		private static void Pre_ApplyPlayerGhostOpacity(ref float value)
		{
			if (EMPPlayerHudHandler.Instance != null && EMPPlayerHudHandler.Instance.IsEMPed())
			{
				value = 0f;
			}
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(CellSettingsApply), "ApplyHUDAlwaysShowTeammateInfo")]
		private static void Pre_ApplyHUDAlwaysShowTeammateInfo(ref bool value)
		{
			if (EMPPlayerHudHandler.Instance != null && EMPPlayerHudHandler.Instance.IsEMPed())
			{
				value = false;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerSync))]
	internal static class Inject_PlayerSync
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("WantsToSetFlashlightEnabled")]
		internal static void Pre_WantsToSetFlashlightEnabled(PlayerSync __instance, ref bool enable)
		{
			if (EMPPlayerFlashLightHandler.Instance != null && EMPPlayerFlashLightHandler.Instance.IsEMPed())
			{
				enable = false;
			}
		}
	}
	[HarmonyPatch(typeof(SentryGunInstance))]
	internal static class Inject_SentryGunInstance
	{
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch("Setup")]
		internal static void Post_Setup(SentryGunInstance __instance)
		{
			((Component)__instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPSentryHandler());
		}
	}
}
namespace EOSExt.EMP.Impl
{
	public sealed class EMPController : MonoBehaviour
	{
		private bool _hasHandler;

		private bool _setup;

		private float next_remove_time = float.NaN;

		private const float UPDATE_INTERVAL = 1f;

		public EMPHandler Handler { get; private set; }

		public float endTime { get; private set; }

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

		private void Update()
		{
			if (_hasHandler)
			{
				float time = Clock.Time;
				Handler.Tick();
				if (float.IsNaN(next_remove_time) || next_remove_time < time)
				{
					Handler.RemoveEndedEMPs();
					next_remove_time = time + 1f;
				}
			}
		}

		[HideFromIl2Cpp]
		public void AssignHandler(EMPHandler handler)
		{
			if (Handler != null)
			{
				EOSLogger.Warning("Tried to assign a handler to a controller that already had one!");
				return;
			}
			Handler = handler;
			Handler.Setup(((Component)this).gameObject, this);
			_hasHandler = true;
			_setup = true;
		}

		[HideFromIl2Cpp]
		public void ForceState(EMPState state)
		{
			if (Handler != null)
			{
				Handler.ForceState(state);
			}
		}

		private void OnDestroy()
		{
			Handler.OnDespawn();
			Handler = null;
		}
	}
	public abstract class EMPHandler
	{
		protected enum DeviceState
		{
			On,
			Off,
			Unknown
		}

		private static long next_handler_id = 0L;

		protected DeviceState _deviceState;

		protected float _stateTimer;

		private float _delayTimer;

		private bool _destroyed;

		protected static Dictionary<long, EMPHandler> Handlers { get; } = new Dictionary<long, EMPHandler>();

		public static IEnumerable<EMPHandler> AllHandlers => Handlers.Values;

		protected long HandlerId { get; private set; }

		public EMPState State { get; protected set; }

		protected HashSet<EMPShock> AffectedBy { get; } = new HashSet<EMPShock>();

		public GameObject go { get; protected set; }

		public Vector3 position
		{
			get
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				GameObject obj = go;
				return (obj != null) ? obj.transform.position : Vector3.zero;
			}
		}

		protected virtual float FlickerDuration => 0.2f;

		protected virtual float OnToOffMinDelay => 0f;

		protected virtual float OnToOffMaxDelay => 0.75f;

		protected virtual float OffToOnMinDelay => 0.85f;

		protected virtual float OffToOnMaxDelay => 1.5f;

		protected virtual bool IsDeviceOnPlayer => false;

		public virtual bool IsEMPed()
		{
			foreach (EMPShock item in AffectedBy)
			{
				if (Clock.Time < item.endTime)
				{
					return true;
				}
			}
			return false;
		}

		public virtual void Setup(GameObject gameObject, EMPController controller)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			go = gameObject;
			foreach (EMPShock activeEMP in EMPManager.Current.ActiveEMPs)
			{
				if (Vector3.Distance(go.transform.position, activeEMP.position) < activeEMP.range)
				{
					AddAffectedBy(activeEMP);
				}
			}
			HandlerId = next_handler_id++;
			if (Handlers.ContainsKey(HandlerId))
			{
				EOSLogger.Warning("What the hell we got a duplicate EMPHandler ID!?");
			}
			Handlers[HandlerId] = this;
		}

		public virtual void OnDespawn()
		{
			_destroyed = true;
			AffectedBy.Clear();
			Handlers.Remove(HandlerId);
			go = null;
		}

		public void AddAffectedBy(EMPShock empShock)
		{
			AffectedBy.Add(empShock);
		}

		public void RemoveAffectedBy(EMPShock empShock)
		{
			AffectedBy.Remove(empShock);
		}

		internal void RemoveEndedEMPs()
		{
			float time = Clock.Time;
			AffectedBy.RemoveWhere((EMPShock emp) => emp.endTime < time);
		}

		public void ForceState(EMPState state)
		{
			if (State != state)
			{
				State = state;
				_delayTimer = Clock.Time - 1f;
				_stateTimer = Clock.Time - 1f;
				switch (state)
				{
				case EMPState.Off:
					_deviceState = DeviceState.Off;
					DeviceOff();
					break;
				default:
					_deviceState = DeviceState.Unknown;
					break;
				case EMPState.On:
					_deviceState = DeviceState.On;
					DeviceOn();
					break;
				}
			}
		}

		public void Tick()
		{
			if (_destroyed)
			{
				return;
			}
			bool flag = IsEMPed();
			if (flag && State == EMPState.On)
			{
				float randomDelay = Random.GetRandomDelay(OnToOffMinDelay, OnToOffMaxDelay);
				State = EMPState.FlickerOff;
				_delayTimer = Clock.Time + randomDelay;
				_stateTimer = Clock.Time + randomDelay + FlickerDuration;
			}
			if (!flag && State == EMPState.Off)
			{
				float randomDelay2 = Random.GetRandomDelay(OffToOnMinDelay, OffToOnMaxDelay);
				State = EMPState.FlickerOn;
				_delayTimer = Clock.Time + randomDelay2;
				_stateTimer = Clock.Time + randomDelay2 + FlickerDuration;
			}
			switch (State)
			{
			case EMPState.On:
				if (_deviceState != DeviceState.On)
				{
					DeviceOn();
					_deviceState = DeviceState.On;
				}
				break;
			case EMPState.FlickerOff:
				if (!(_delayTimer > Clock.Time))
				{
					if (Clock.Time < _stateTimer)
					{
						FlickerDevice();
					}
					else
					{
						State = EMPState.Off;
					}
				}
				break;
			case EMPState.Off:
				if (_deviceState != DeviceState.Off)
				{
					DeviceOff();
					_deviceState = DeviceState.Off;
				}
				break;
			case EMPState.FlickerOn:
				if (!(_delayTimer > Clock.Time))
				{
					if (Clock.Time < _stateTimer)
					{
						FlickerDevice();
					}
					else
					{
						State = EMPState.On;
					}
				}
				break;
			}
			OnTick(flag);
		}

		protected virtual void OnTick(bool isEMPD)
		{
		}

		protected abstract void FlickerDevice();

		protected abstract void DeviceOn();

		protected abstract void DeviceOff();
	}
	public class EMPShock
	{
		public static readonly ItemToDisable DISABLE_NOTHING = new ItemToDisable
		{
			BioTracker = false,
			PlayerFlashLight = false,
			PlayerHUD = false,
			Sentry = false,
			EnvLight = false,
			GunSight = false,
			Map = false
		};

		public virtual ActiveState State => (RemainingTime > 0f) ? ActiveState.ENABLED : ActiveState.DISABLED;

		public Vector3 position { get; protected set; }

		public float range { get; protected set; }

		public float endTime { get; protected set; }

		public virtual float RemainingTime => endTime - Clock.Time;

		public virtual ItemToDisable ItemToDisable => new ItemToDisable();

		public EMPShock(Vector3 position, float range, float endTime)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			this.position = position;
			this.range = range;
			this.endTime = endTime;
		}

		public bool InRange(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Distance(position, this.position) < range;
		}

		public override bool Equals(object obj)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return obj is EMPShock eMPShock && position == eMPShock.position && range == eMPShock.range;
		}

		public override int GetHashCode()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return HashCode.Combine<ActiveState, Vector3, float, float, float, ItemToDisable>(State, position, range, endTime, RemainingTime, ItemToDisable);
		}
	}
	public enum EMPState
	{
		On,
		FlickerOff,
		Off,
		FlickerOn
	}
	internal static class Random
	{
		internal static System.Random _rand { get; private set; } = new System.Random();

		internal static float GetRandomDelay(float min, float max)
		{
			return min + GetRandom01() * (max - min);
		}

		internal static float GetRandom01()
		{
			return (float)_rand.NextDouble();
		}

		internal static int GetRandomRange(int min, int maxPlusOne)
		{
			return _rand.Next(min, maxPlusOne);
		}

		internal static int Index(int length)
		{
			return _rand.Next(0, length);
		}

		internal static bool FlickerUtil(int oneInX = 2)
		{
			return Index(oneInX) == 0;
		}
	}
}
namespace EOSExt.EMP.Impl.PersistentEMP
{
	public enum ActiveState
	{
		DISABLED,
		ENABLED
	}
	public class pEMP : EMPShock
	{
		private uint replicatorID;

		public pEMPDefinition def { get; private set; }

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

		public override ActiveState State => (StateReplicator != null) ? StateReplicator.State.status : ActiveState.DISABLED;

		public override float RemainingTime => base.endTime;

		public override ItemToDisable ItemToDisable => def?.ItemToDisable ?? EMPShock.DISABLE_NOTHING;

		private void OnStateChanged(pEMPState oldState, pEMPState newState, bool isRecall)
		{
			if (isRecall)
			{
				ChangeToStateUnsynced(newState.status);
			}
		}

		private void ChangeToStateUnsynced(ActiveState newState)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			EOSLogger.Debug($"pEMP_{def.pEMPIndex} Change state: {State} -> {newState}");
			switch (newState)
			{
			case ActiveState.DISABLED:
				base.endTime = float.NegativeInfinity;
				break;
			case ActiveState.ENABLED:
				base.endTime = float.PositiveInfinity;
				break;
			default:
				throw new NotImplementedException();
			}
			if (!ItemToDisable.EnvLight)
			{
				return;
			}
			foreach (EMPLightHandler instance in EMPLightHandler.Instances)
			{
				switch (newState)
				{
				case ActiveState.DISABLED:
					instance.RemoveAffectedBy(this);
					break;
				case ActiveState.ENABLED:
					if (InRange(instance.position))
					{
						instance.AddAffectedBy(this);
					}
					else
					{
						instance.RemoveAffectedBy(this);
					}
					break;
				default:
					throw new NotImplementedException();
				}
			}
		}

		public void ChangeToState(ActiveState newState)
		{
			ChangeToStateUnsynced(newState);
			if (SNet.IsMaster)
			{
				StateReplicator?.SetState(new pEMPState
				{
					status = newState
				});
			}
		}

		internal void SetupReplicator(uint replicatorID)
		{
			this.replicatorID = replicatorID;
			StateReplicator = StateReplicator<pEMPState>.Create(replicatorID, new pEMPState
			{
				status = ActiveState.DISABLED
			}, (LifeTimeType)1, (IStateReplicatorHolder<pEMPState>)null);
			StateReplicator.OnStateChanged += OnStateChanged;
		}

		public pEMP(pEMPDefinition def)
			: base(def.Position.ToVector3(), def.Range, float.NegativeInfinity)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			this.def = new pEMPDefinition(def);
		}

		internal void Destroy()
		{
			base.endTime = float.NegativeInfinity;
			StateReplicator = null;
			def = null;
		}

		public override bool Equals(object obj)
		{
			return obj is pEMP pEMP2 && def.Equals(pEMP2.def) && replicatorID == pEMP2.replicatorID;
		}

		public override int GetHashCode()
		{
			return HashCode.Combine(def, replicatorID);
		}
	}
	public struct pEMPState
	{
		public ActiveState status;

		public pEMPState()
		{
			status = ActiveState.DISABLED;
		}

		public pEMPState(ActiveState status)
		{
			this.status = status;
		}

		public pEMPState(pEMPState o)
		{
			status = o.status;
		}
	}
}
namespace EOSExt.EMP.Impl.Handlers
{
	public class EMPBioTrackerHandler : EMPHandler
	{
		private EnemyScanner _scanner;

		public static EMPBioTrackerHandler Instance { get; private set; }

		static EMPBioTrackerHandler()
		{
		}

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			if (Instance != null)
			{
				EOSLogger.Warning("EMP: re-setup EMPBioTrackerHandler");
				Instance.OnDespawn();
			}
			base.Setup(gameObject, controller);
			_scanner = gameObject.GetComponent<EnemyScanner>();
			if ((Object)(object)_scanner == (Object)null)
			{
				EOSLogger.Error("Couldn't get bio-tracker component!");
			}
			Instance = this;
		}

		public override void OnDespawn()
		{
			base.OnDespawn();
			Instance = null;
		}

		protected override void DeviceOff()
		{
			((ItemEquippable)_scanner).Sound.Post(EVENTS.BIOTRACKER_TOOL_LOOP_STOP, true);
			_scanner.m_graphics.m_display.enabled = false;
		}

		protected override void DeviceOn()
		{
			_scanner.m_graphics.m_display.enabled = true;
		}

		protected override void FlickerDevice()
		{
			((Behaviour)_scanner).enabled = Random.FlickerUtil();
		}
	}
	public class EMPGunSightHandler : EMPHandler
	{
		private static List<EMPGunSightHandler> handlers;

		public GameObject[] _sightPictures;

		public static IEnumerable<EMPGunSightHandler> Instances => handlers;

		static EMPGunSightHandler()
		{
			handlers = new List<EMPGunSightHandler>();
			LevelAPI.OnLevelCleanup += Clear;
			LevelAPI.OnBuildStart += Clear;
		}

		private void SetupGunSights()
		{
			Il2CppArrayBase<Renderer> componentsInChildren = base.go.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren != null)
			{
				_sightPictures = (from x in (IEnumerable<Renderer>)componentsInChildren
					where (Object)(object)x.sharedMaterial != (Object)null && (Object)(object)x.sharedMaterial.shader != (Object)null
					where ((Object)x.sharedMaterial.shader).name.Contains("HolographicSight")
					select ((Component)x).gameObject).ToArray();
			}
			if (_sightPictures == null || _sightPictures.Length < 1)
			{
				EOSLogger.Error("Unable to find sight on " + ((Object)base.go).name + "!");
			}
		}

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			base.Setup(gameObject, controller);
			SetupGunSights();
			handlers.Add(this);
		}

		protected override void DeviceOff()
		{
			ForEachSights(delegate(GameObject x)
			{
				x.SetActive(false);
			});
		}

		protected override void DeviceOn()
		{
			ForEachSights(delegate(GameObject x)
			{
				x.SetActive(true);
			});
		}

		protected override void FlickerDevice()
		{
			ForEachSights(delegate(GameObject x)
			{
				x.SetActive(Random.FlickerUtil());
			});
		}

		private void ForEachSights(Action<GameObject> action)
		{
			GameObject[] sightPictures = _sightPictures;
			foreach (GameObject val in sightPictures)
			{
				if ((Object)(object)val != (Object)null)
				{
					action?.Invoke(val);
				}
			}
		}

		private static void Clear()
		{
			handlers.Clear();
		}
	}
	public class EMPLightHandler : EMPHandler
	{
		private static Dictionary<IntPtr, EMPLightHandler> handlers;

		private readonly LightWorker _worker;

		private ILightModifier _mod;

		public static IEnumerable<EMPLightHandler> Instances => handlers.Values;

		static EMPLightHandler()
		{
			handlers = new Dictionary<IntPtr, EMPLightHandler>();
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}

		private static void Clear()
		{
			foreach (EMPLightHandler value in handlers.Values)
			{
				ILightModifier mod = value._mod;
				if (mod != null)
				{
					mod.Remove();
				}
				value._mod = null;
			}
			handlers.Clear();
		}

		public EMPLightHandler(LightWorker worker)
		{
			_worker = worker;
		}

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			base.Setup(gameObject, controller);
			if ((Object)(object)_worker?.Light == (Object)null)
			{
				EOSLogger.Warning("EMPLightHandler: no light worker");
				return;
			}
			base.State = EMPState.On;
			handlers[((Il2CppObjectBase)_worker.Light).Pointer] = this;
		}

		protected override void OnTick(bool isEMPD)
		{
			base.OnTick(isEMPD);
			if (base.State == EMPState.Off)
			{
				DeviceOff();
			}
			else if (base.State == EMPState.On)
			{
				DeviceOn();
			}
		}

		protected override void FlickerDevice()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_worker?.Light == (Object)null))
			{
				if (_mod == null)
				{
					_mod = _worker.AddModifier(_worker.CurrentColor, _worker.CurrentIntensity, _worker.CurrentEnabled, 2000);
				}
				_mod.Intensity = Random.GetRandom01() * _worker.OrigIntensity;
			}
		}

		protected override void DeviceOn()
		{
			if (_mod != null)
			{
				_mod.Remove();
				_mod = null;
			}
		}

		protected override void DeviceOff()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_worker?.Light == (Object)null))
			{
				if (_mod == null)
				{
					_mod = _worker.AddModifier(_worker.CurrentColor, _worker.CurrentIntensity, _worker.CurrentEnabled, 2000);
				}
				_mod.Color = Color.black;
				_mod.Intensity = 0f;
			}
		}
	}
	public class EMPPlayerFlashLightHandler : EMPHandler
	{
		private PlayerInventoryBase _inventory;

		private float _originalIntensity;

		private bool _originalFlashlightState;

		public static EMPPlayerFlashLightHandler Instance { get; private set; }

		protected override bool IsDeviceOnPlayer => true;

		private bool FlashlightEnabled => _inventory.FlashlightEnabled;

		static EMPPlayerFlashLightHandler()
		{
		}

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			if (Instance != null)
			{
				EOSLogger.Warning("EMP: re-setup EMPPlayerFlashLightHandler");
				Instance.OnDespawn();
			}
			base.Setup(gameObject, controller);
			_inventory = gameObject.GetComponent<PlayerAgent>().Inventory;
			if ((Object)(object)_inventory == (Object)null)
			{
				EOSLogger.Warning("Player inventory was null!");
			}
			else
			{
				base.State = EMPState.On;
				Events.FlashLightWielded = (Action<GearPartFlashlight>)Delegate.Combine(Events.FlashLightWielded, new Action<GearPartFlashlight>(InventoryEvents_ItemWielded));
			}
			Instance = this;
		}

		public override void OnDespawn()
		{
			base.OnDespawn();
			Events.FlashLightWielded = (Action<GearPartFlashlight>)Delegate.Remove(Events.FlashLightWielded, new Action<GearPartFlashlight>(Instance.InventoryEvents_ItemWielded));
			Instance = null;
		}

		private void InventoryEvents_ItemWielded(GearPartFlashlight flashlight)
		{
			_originalIntensity = GameDataBlockBase<FlashlightSettingsDataBlock>.GetBlock(flashlight.m_settingsID).intensity;
		}

		protected override void DeviceOff()
		{
			_originalFlashlightState = FlashlightEnabled;
			if (_originalFlashlightState)
			{
				_inventory.Owner.Sync.WantsToSetFlashlightEnabled(false, false);
			}
		}

		protected override void DeviceOn()
		{
			if (_originalFlashlightState != FlashlightEnabled)
			{
				_inventory.Owner.Sync.WantsToSetFlashlightEnabled(_originalFlashlightState, false);
			}
			_inventory.m_flashlight.intensity = _originalIntensity;
		}

		protected override void FlickerDevice()
		{
			if (FlashlightEnabled)
			{
				_inventory.m_flashlight.intensity = Random.GetRandom01() * _originalIntensity;
			}
		}
	}
	public class EMPPlayerHudHandler : EMPHandler
	{
		private readonly List<RectTransformComp> _targets = new List<RectTransformComp>();

		public static EMPPlayerHudHandler Instance { get; private set; }

		static EMPPlayerHudHandler()
		{
		}

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			if (Instance != null)
			{
				EOSLogger.Warning("EMP: re-setup EMPPlayerHudHandler");
				Instance.OnDespawn();
			}
			_targets.Clear();
			base.Setup(gameObject, controller);
			_targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_compass);
			_targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_wardenObjective);
			_targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.Inventory);
			_targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_playerStatus);
			Instance = this;
		}

		public override void OnDespawn()
		{
			base.OnDespawn();
			_targets.Clear();
			Instance = null;
		}

		private void ForAllComponents(bool enabled)
		{
			foreach (RectTransformComp target in _targets)
			{
				((Component)target).gameObject.SetActive(enabled);
			}
		}

		private void ForPlayerNavMarker(bool enabled)
		{
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (!((Agent)current).IsLocallyOwned)
				{
					current.NavMarker.SetMarkerVisible(enabled);
				}
			}
		}

		private void ForPlayerGhostOpacity(bool enabled)
		{
			CellSettingsApply.ApplyPlayerGhostOpacity(enabled ? CellSettingsManager.SettingsData.HUD.Player_GhostOpacity.Value : 0f);
		}

		protected override void OnTick(bool isEMPD)
		{
			base.OnTick(isEMPD);
			bool flag = !isEMPD;
			if (base.State == EMPState.Off)
			{
				DeviceOff();
			}
			else if (base.State == EMPState.On)
			{
				DeviceOn();
			}
		}

		protected override void DeviceOff()
		{
			ForAllComponents(enabled: false);
			ForPlayerNavMarker(enabled: false);
			ForPlayerGhostOpacity(enabled: false);
		}

		protected override void DeviceOn()
		{
			ForAllComponents(enabled: true);
			ForPlayerNavMarker(enabled: true);
			ForPlayerGhostOpacity(enabled: true);
		}

		protected override void FlickerDevice()
		{
			bool enabled = Random.FlickerUtil();
			ForAllComponents(enabled);
			ForPlayerNavMarker(enabled);
			ForPlayerGhostOpacity(enabled);
		}
	}
	public class EMPSentryHandler : EMPHandler
	{
		private static Color _offColor;

		private SentryGunInstance _sentry;

		private SentryGunInstance_ScannerVisuals_Plane _visuals;

		public static EMPSentryHandler Instance { get; private set; }

		static EMPSentryHandler()
		{
			//IL_0002: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			_offColor = new Color
			{
				r = 0f,
				g = 0f,
				b = 0f,
				a = 0f
			};
		}

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			if (Instance != null)
			{
				EOSLogger.Warning("EMP: re-setup EMPSentryHandler");
				Instance.OnDespawn();
			}
			base.Setup(gameObject, controller);
			_sentry = gameObject.GetComponent<SentryGunInstance>();
			_visuals = gameObject.GetComponent<SentryGunInstance_ScannerVisuals_Plane>();
			if ((Object)(object)_sentry == (Object)null || (Object)(object)_visuals == (Object)null)
			{
				EOSLogger.Error($"Missing components on Sentry! Has Sentry?: {(Object)(object)_sentry == (Object)null}, Has Visuals?: {(Object)(object)_visuals == (Object)null}");
			}
			Instance = this;
		}

		public override void OnDespawn()
		{
			base.OnDespawn();
			Instance = null;
		}

		protected override void DeviceOff()
		{
			//IL_000c: 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)
			_visuals.m_scannerPlane.SetColor(_offColor);
			_visuals.UpdateLightProps(_offColor, false);
			_sentry.m_isSetup = false;
			_sentry.m_isScanning = false;
			_sentry.m_isFiring = false;
			((ItemEquippable)_sentry).Sound.Post(EVENTS.SENTRYGUN_STOP_ALL_LOOPS, true);
		}

		protected override void DeviceOn()
		{
			_sentry.m_isSetup = true;
			_sentry.m_visuals.SetVisualStatus((eSentryGunStatus)0, true);
			_sentry.m_isScanning = false;
			_sentry.m_startScanTimer = Clock.Time + _sentry.m_initialScanDelay;
			((ItemEquippable)_sentry).Sound.Post(EVENTS.SENTRYGUN_LOW_AMMO_WARNING, true);
		}

		protected override void FlickerDevice()
		{
			int randomRange = Random.GetRandomRange(0, 3);
			_sentry.StopFiring();
			switch (randomRange)
			{
			case 0:
				_visuals.SetVisualStatus((eSentryGunStatus)4, true);
				break;
			case 1:
				_visuals.SetVisualStatus((eSentryGunStatus)1, true);
				break;
			case 2:
				_visuals.SetVisualStatus((eSentryGunStatus)2, true);
				break;
			}
		}
	}
}
namespace EOSExt.EMP.Definition
{
	public class ItemToDisable
	{
		public bool BioTracker { get; set; } = true;

		public bool PlayerHUD { get; set; } = true;

		public bool PlayerFlashLight { get; set; } = true;

		public bool EnvLight { get; set; } = true;

		public bool GunSight { get; set; } = true;

		public bool Sentry { get; set; } = true;

		public bool Map { get; set; } = true;

		public override bool Equals(object obj)
		{
			return obj is ItemToDisable itemToDisable && BioTracker == itemToDisable.BioTracker && PlayerHUD == itemToDisable.PlayerHUD && PlayerFlashLight == itemToDisable.PlayerFlashLight && EnvLight == itemToDisable.EnvLight && GunSight == itemToDisable.GunSight && Sentry == itemToDisable.Sentry && Map == itemToDisable.Map;
		}

		public override int GetHashCode()
		{
			return HashCode.Combine(BioTracker, PlayerHUD, PlayerFlashLight, EnvLight, GunSight, Sentry, Map);
		}

		public override string ToString()
		{
			return $"ItemToDisable:\nBioTracker: {BioTracker}, PlayerHUD: {PlayerHUD}, PlayerFlashLight: {PlayerFlashLight},\nEnvLight: {EnvLight}, GunSight: {GunSight}, Sentry: {Sentry}, Map: {Map}";
		}
	}
	public class pEMPDefinition
	{
		public uint pEMPIndex { get; set; } = 0u;

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

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

		public ItemToDisable ItemToDisable { get; set; } = new ItemToDisable();

		public pEMPDefinition()
		{
		}//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown


		public pEMPDefinition(pEMPDefinition other)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			pEMPIndex = other.pEMPIndex;
			Position = new Vec3
			{
				x = other.Position.x,
				y = other.Position.y,
				z = other.Position.z
			};
			Range = other.Range;
			ItemToDisable = new ItemToDisable
			{
				BioTracker = other.ItemToDisable.BioTracker,
				PlayerHUD = other.ItemToDisable.PlayerHUD,
				PlayerFlashLight = other.ItemToDisable.PlayerFlashLight,
				EnvLight = other.ItemToDisable.EnvLight,
				GunSight = other.ItemToDisable.GunSight,
				Sentry = other.ItemToDisable.Sentry,
				Map = other.ItemToDisable.Map
			};
		}

		public override bool Equals(object obj)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			return obj is pEMPDefinition pEMPDefinition2 && pEMPIndex == pEMPDefinition2.pEMPIndex && Position.ToVector3() == pEMPDefinition2.Position.ToVector3() && Range == pEMPDefinition2.Range && ItemToDisable.Equals(pEMPDefinition2.ItemToDisable);
		}

		public override int GetHashCode()
		{
			return HashCode.Combine<uint, Vec3, float, ItemToDisable>(pEMPIndex, Position, Range, ItemToDisable);
		}
	}
}
namespace EOSExt.EMP.EMPComponent
{
	public class PlayerpEMPComponent : MonoBehaviour
	{
		private float nextUpdateTime = float.NaN;

		public const float UPDATE_INTERVAL = 0.2f;

		public static PlayerpEMPComponent Current => (SNet.HasLocalPlayer && SNet.LocalPlayer.HasPlayerAgent) ? ((Component)((Il2CppObjectBase)SNet.LocalPlayer.PlayerAgent).Cast<PlayerAgent>()).GetComponent<PlayerpEMPComponent>() : null;

		public PlayerAgent player => ((Component)this).gameObject.GetComponent<PlayerAgent>();

		private void CheckSetup()
		{
			if (!((Object)(object)EMPManager.Current.Player == (Object)null))
			{
				EMPManager.Current.SetupHUDAndFlashlight();
				EMPManager.Current.SetupToolHandler();
			}
		}

		private void Update()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if ((int)GameStateManager.CurrentStateName != 10 || (!float.IsNaN(nextUpdateTime) && Clock.Time < nextUpdateTime))
			{
				return;
			}
			nextUpdateTime = Clock.Time + 0.2f;
			CheckSetup();
			EMPManager.Current.RemoveInactiveEMPs();
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			foreach (pEMP pEMP in EMPManager.Current.pEMPs)
			{
				ItemToDisable itemToDisable = pEMP.ItemToDisable;
				if (pEMP.State == ActiveState.ENABLED && pEMP.InRange(((Agent)player).Position))
				{
					if (itemToDisable.BioTracker)
					{
						EMPBioTrackerHandler.Instance?.AddAffectedBy(pEMP);
					}
					if (itemToDisable.PlayerFlashLight)
					{
						EMPPlayerFlashLightHandler.Instance?.AddAffectedBy(pEMP);
					}
					if (itemToDisable.PlayerHUD)
					{
						EMPPlayerHudHandler.Instance?.AddAffectedBy(pEMP);
					}
					if (itemToDisable.Sentry)
					{
						EMPSentryHandler.Instance?.AddAffectedBy(pEMP);
					}
					if (!itemToDisable.GunSight)
					{
						continue;
					}
					foreach (EMPGunSightHandler instance in EMPGunSightHandler.Instances)
					{
						instance.AddAffectedBy(pEMP);
					}
					continue;
				}
				EMPBioTrackerHandler.Instance?.RemoveAffectedBy(pEMP);
				EMPPlayerFlashLightHandler.Instance?.RemoveAffectedBy(pEMP);
				EMPPlayerHudHandler.Instance?.RemoveAffectedBy(pEMP);
				EMPSentryHandler.Instance?.RemoveAffectedBy(pEMP);
				foreach (EMPGunSightHandler instance2 in EMPGunSightHandler.Instances)
				{
					instance2.RemoveAffectedBy(pEMP);
				}
			}
		}

		private void OnDestroy()
		{
		}

		static PlayerpEMPComponent()
		{
		}
	}
}

plugins/Inas07.EOSExt.EnvTemperature.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Agents;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using EOSExt.EnvTemperature.Components;
using EOSExt.EnvTemperature.Definitions;
using EOSExt.EnvTemperature.Patches;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.Utils;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using GameEvent;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Inas07.EOSExt.EnvTemperature")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+00ee728818558b44f88b01d48543284e03868873")]
[assembly: AssemblyProduct("Inas07.EOSExt.EnvTemperature")]
[assembly: AssemblyTitle("Inas07.EOSExt.EnvTemperature")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.EnvTemperature
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.EOSExt.EnvTemperature", "EOSExt.EnvTemperature", "1.1.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.EnvTemperature";

		public const string VERSION = "1.1.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			SetupManagers();
			m_Harmony = new Harmony("EOSExt.EnvTemperature");
			m_Harmony.PatchAll();
			EOSLogger.Log("ExtraObjectiveSetup.EnvTemperature loaded.");
		}

		private void SetupManagers()
		{
			((GenericDefinitionManager<TemperatureDefinition>)TemperatureDefinitionManager.Current).Init();
		}
	}
	public class TemperatureDefinitionManager : GenericDefinitionManager<TemperatureDefinition>
	{
		public static readonly TemperatureZoneDefinition DEFAULT_ZONE_DEF;

		public const float MIN_TEMP = 0.005f;

		public const float MAX_TEMP = 1f;

		public static TemperatureDefinitionManager Current { get; }

		protected override string DEFINITION_NAME => "EnvTemperature";

		private Dictionary<(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex), TemperatureZoneDefinition> zoneDefs { get; } = new Dictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex), TemperatureZoneDefinition>();

		protected override void AddDefinitions(GenericDefinition<TemperatureDefinition> definition)
		{
			List<TemperatureSetting> settings = definition.Definition.Settings;
			if (settings.Count > 0)
			{
				settings.Sort((TemperatureSetting t1, TemperatureSetting t2) => t1.Temperature.CompareTo(t2.Temperature));
				bool flag = true;
				if (settings[0].Temperature < 0f)
				{
					EOSLogger.Error($"Found negative temperature: '{settings[0].Temperature}'");
					flag = false;
				}
				if (settings[settings.Count - 1].Temperature > 1f)
				{
					EOSLogger.Error($"Found temperature greater than 1: '{settings[settings.Count - 1].Temperature}'");
					flag = false;
				}
				if (!flag)
				{
					EOSLogger.Error($"Found invalid temperature for MainLevelLayout '{definition.ID}'. Correct it first to make it effective");
					return;
				}
				if (settings[0].Temperature != 0f)
				{
					List<TemperatureSetting> list = new List<TemperatureSetting>();
					TemperatureSetting item = new TemperatureSetting(settings[0])
					{
						Temperature = 0f
					};
					list.Add(item);
					list.AddRange(settings);
					definition.Definition.Settings = list;
					settings.Clear();
					settings = list;
				}
			}
			foreach (TemperatureZoneDefinition zone in definition.Definition.Zones)
			{
				zone.Temperature_Downlimit = Math.Clamp(zone.Temperature_Downlimit, 0.005f, 1f);
				zone.Temperature_Uplimit = Math.Clamp(zone.Temperature_Uplimit, 0.005f, 1f);
				if (zone.Temperature_Downlimit > zone.Temperature_Uplimit)
				{
					EOSLogger.Error($"Invalid Temperature_Down/Up-limit setting! Downlimit == {zone.Temperature_Downlimit}, Uplimit == {zone.Temperature_Uplimit}");
					float temperature_Downlimit = zone.Temperature_Downlimit;
					zone.Temperature_Downlimit = zone.Temperature_Uplimit;
					zone.Temperature_Uplimit = temperature_Downlimit;
				}
				if (!(zone.Temperature_Downlimit <= zone.Temperature_Normal) || !(zone.Temperature_Normal <= zone.Temperature_Uplimit))
				{
					EOSLogger.Error($"Invalid Temperature_Normal setting! Temperature_Normal == {zone.Temperature_Normal} not in limit range [{zone.Temperature_Downlimit}, {zone.Temperature_Uplimit}] !");
					zone.Temperature_Normal = Math.Clamp(zone.Temperature_Normal, zone.Temperature_Downlimit, zone.Temperature_Uplimit);
				}
				zone.FluctuationIntensity = Math.Abs(zone.FluctuationIntensity);
			}
			base.AddDefinitions(definition);
		}

		protected override void FileChanged(LiveEditEventArgs e)
		{
			base.FileChanged(e);
			Clear();
			OnBuildDone();
			if (PlayerTemperatureManager.TryGetCurrentManager(out var mgr) && base.definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out var value))
			{
				mgr.UpdateTemperatureDefinition(value.Definition);
				mgr.UpdateGUIText();
			}
		}

		private void OnBuildDone()
		{
			if (!base.definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out var value))
			{
				return;
			}
			value.Definition.Zones.ForEach(delegate(TemperatureZoneDefinition def)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: 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_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				if (zoneDefs.ContainsKey((((GlobalZoneIndex)def).DimensionIndex, ((GlobalZoneIndex)def).LayerType, ((GlobalZoneIndex)def).LocalIndex)))
				{
					EOSLogger.Warning($"TemperatureDefinitionManager: duplicate definition found: {(((GlobalZoneIndex)def).DimensionIndex, ((GlobalZoneIndex)def).LayerType, ((GlobalZoneIndex)def).LocalIndex)}");
				}
				zoneDefs[(((GlobalZoneIndex)def).DimensionIndex, ((GlobalZoneIndex)def).LayerType, ((GlobalZoneIndex)def).LocalIndex)] = def;
			});
		}

		private void Clear()
		{
			zoneDefs.Clear();
		}

		public bool TryGetZoneDefinition(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, out TemperatureZoneDefinition def)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			return zoneDefs.TryGetValue((dimensionIndex, layerType, localIndex), out def);
		}

		public bool TryGetLevelTemperatureSettings(out List<TemperatureSetting> settings)
		{
			if (base.definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out var value))
			{
				settings = value.Definition.Settings;
				return settings != null && settings.Count > 0;
			}
			settings = null;
			return false;
		}

		private TemperatureDefinitionManager()
		{
			LevelAPI.OnBuildDone += OnBuildDone;
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}

		static TemperatureDefinitionManager()
		{
			Current = new TemperatureDefinitionManager();
			DEFAULT_ZONE_DEF = new TemperatureZoneDefinition
			{
				FluctuationIntensity = 0.0025f
			};
		}
	}
}
namespace EOSExt.EnvTemperature.Patches
{
	[HarmonyPatch]
	internal static class Patch_BulletWeapon
	{
		private static TemperatureSetting? m_curSetting;

		private static Dictionary<uint, float> DefaultReloadTimes;

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(BulletWeaponArchetype), "OnWield")]
		public static void Post_OnWield(BulletWeaponArchetype __instance)
		{
			uint persistentID = ((GameDataBlockBase<ArchetypeDataBlock>)(object)__instance.m_archetypeData).persistentID;
			if (!DefaultReloadTimes.ContainsKey(persistentID))
			{
				DefaultReloadTimes[persistentID] = __instance.m_archetypeData.DefaultReloadTime;
			}
			TemperatureSetting curSetting = m_curSetting;
			if (curSetting != null && curSetting.SlowDownMultiplier_Reload > 0f)
			{
				__instance.m_archetypeData.DefaultReloadTime = DefaultReloadTimes[persistentID] * curSetting.SlowDownMultiplier_Reload;
				EOSLogger.Debug("Temperature: Slowing down reload!");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(BulletWeaponArchetype), "Update")]
		private static void Post_Update(BulletWeaponArchetype __instance)
		{
			TemperatureSetting currentTemperatureSetting = PlayerTemperatureManager.GetCurrentTemperatureSetting();
			if (m_curSetting == currentTemperatureSetting)
			{
				return;
			}
			uint persistentID = ((GameDataBlockBase<ArchetypeDataBlock>)(object)__instance.m_archetypeData).persistentID;
			if (DefaultReloadTimes.ContainsKey(persistentID))
			{
				float num = DefaultReloadTimes[persistentID];
				if (currentTemperatureSetting == null || currentTemperatureSetting.SlowDownMultiplier_Reload <= 0f)
				{
					__instance.m_archetypeData.DefaultReloadTime = num;
				}
				else
				{
					__instance.m_archetypeData.DefaultReloadTime = num * currentTemperatureSetting.SlowDownMultiplier_Reload;
				}
			}
			m_curSetting = currentTemperatureSetting;
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(BulletWeaponArchetype), "OnUnWield")]
		private static void Pre_OnUnWield(BulletWeaponArchetype __instance)
		{
			uint persistentID = ((GameDataBlockBase<ArchetypeDataBlock>)(object)__instance.m_archetypeData).persistentID;
			if (DefaultReloadTimes.ContainsKey(persistentID))
			{
				float defaultReloadTime = DefaultReloadTimes[persistentID];
				__instance.m_archetypeData.DefaultReloadTime = defaultReloadTime;
			}
		}

		private static void Clear()
		{
			DefaultReloadTimes.Clear();
		}

		static Patch_BulletWeapon()
		{
			m_curSetting = null;
			DefaultReloadTimes = new Dictionary<uint, float>();
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}
	}
	[HarmonyPatch]
	internal static class Patch_MWS_ChargeUp_Enter
	{
		private static float DefaultChargeTime = 1f;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MWS_ChargeUp), "Enter")]
		private static void Postfix_Enter(MWS_ChargeUp __instance)
		{
			DefaultChargeTime = __instance.m_maxDamageTime;
			TemperatureSetting currentTemperatureSetting = PlayerTemperatureManager.GetCurrentTemperatureSetting();
			if (currentTemperatureSetting != null && currentTemperatureSetting.SlowDownMultiplier_Melee > 0f)
			{
				__instance.m_maxDamageTime *= currentTemperatureSetting.SlowDownMultiplier_Melee;
			}
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(MWS_ChargeUp), "Exit")]
		private static void Pre_Exit(MWS_ChargeUp __instance)
		{
			__instance.m_maxDamageTime = DefaultChargeTime;
		}
	}
	[HarmonyPatch]
	internal static class Patch_Dam_PlayerDamageBase
	{
		internal static bool s_disableDialog;

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveFallDamage")]
		private static bool Pre_ReceiveFallDamage(Dam_PlayerDamageLocal __instance, pMiniDamageData data)
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax);
			((Dam_PlayerDamageBase)__instance).m_nextRegen = Clock.Time + ((Dam_PlayerDamageBase)__instance).Owner.PlayerData.healthRegenStartDelayAfterDamage;
			if (((Agent)((Dam_PlayerDamageBase)__instance).Owner).IsLocallyOwned)
			{
				DramaManager.CurrentState.OnLocalDamage(num);
				GameEventManager.PostEvent((eGameEvent)13, ((Dam_PlayerDamageBase)__instance).Owner, num, "", (Dictionary<string, string>)null);
			}
			else
			{
				DramaManager.CurrentState.OnTeammatesDamage(num);
			}
			if (((Dam_PlayerDamageBase)__instance).IgnoreAllDamage)
			{
				return false;
			}
			if (SNet.IsMaster)
			{
				if (((Dam_SyncedDamageBase)__instance).RegisterDamage(num))
				{
					((Dam_SyncedDamageBase)__instance).SendSetDead(true);
				}
				else
				{
					((Dam_SyncedDamageBase)__instance).SendSetHealth(((Dam_SyncedDamageBase)__instance).Health);
				}
			}
			__instance.Hitreact(((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax), Vector3.zero, true, !s_disableDialog, false);
			return false;
		}
	}
	[HarmonyPatch]
	internal static class Patch_PlayerAgent
	{
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(PlayerAgent), "Setup")]
		private static void Post_Setup(PlayerAgent __instance)
		{
			if (((Agent)__instance).IsLocallyOwned && !((Object)(object)((Component)__instance).gameObject.GetComponent<PlayerTemperatureManager>() != (Object)null))
			{
				PlayerTemperatureManager playerTemperatureManager = ((Component)__instance).gameObject.AddComponent<PlayerTemperatureManager>();
				playerTemperatureManager.Setup();
			}
		}
	}
	[HarmonyPatch]
	internal static class Patches_PLOC
	{
		private const float MIN_MOD = 0.1f;

		private static float s_moveSpeedMult = 1f;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PLOC_Base), "GetHorizontalVelocityFromInput")]
		private static void Pre_GetHorizontalVelocityFromInput(ref float moveSpeed)
		{
			moveSpeed *= s_moveSpeedMult;
		}

		internal static void SetMoveSpeedModifier(float m)
		{
			s_moveSpeedMult = Math.Max(0.1f, m);
		}

		internal static void ResetMoveSpeedModifier()
		{
			s_moveSpeedMult = 1f;
		}
	}
}
namespace EOSExt.EnvTemperature.Definitions
{
	public class TemperatureSetting
	{
		public float Temperature { get; set; } = 1f;

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

		public float DamageTick { get; set; }

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

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

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

		public TemperatureSetting()
		{
		}

		public TemperatureSetting(TemperatureSetting o)
		{
			Temperature = o.Temperature;
			Damage = o.Damage;
			DamageTick = o.DamageTick;
			SlowDownMultiplier_Reload = o.SlowDownMultiplier_Reload;
			SlowDownMultiplier_Melee = o.SlowDownMultiplier_Melee;
			SlowDownMultiplier_Move = o.SlowDownMultiplier_Move;
		}
	}
	public class TemperatureZoneDefinition : GlobalZoneIndex
	{
		public float Temperature_Downlimit { get; set; } = 0.005f;

		public float Temperature_Normal { get; set; } = 0.5f;

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

		public float FluctuationIntensity { get; set; } = 0f;
	}
	public class TemperatureDefinition
	{
		public float StartTemperature { get; set; } = 0.5f;

		public float JumpActionHeatGained { get; set; }

		public float SprintActionHeatGained { get; set; }

		public float CrouchActionHeatGained { get; set; }

		public float StandingActionHeatGained { get; set; }

		public float LadderClimbingActionHeatGained { get; set; }

		public List<TemperatureZoneDefinition> Zones { get; set; } = new List<TemperatureZoneDefinition>
		{
			new TemperatureZoneDefinition()
		};

		public List<TemperatureSetting> Settings { get; set; } = new List<TemperatureSetting>
		{
			new TemperatureSetting()
		};
	}
}
namespace EOSExt.EnvTemperature.Components
{
	public class PlayerTemperatureManager : MonoBehaviour
	{
		public const float DEFAULT_PLAYER_TEMPERATURE = 0.5f;

		public const float TEMPERATURE_SETTING_UPDATE_TIME = 1f;

		public const float TEMPERATURE_FLUCTUATE_TIME = 1f;

		private float m_tempSettingLastUpdateTime = 0f;

		private float m_lastDamageTime = 0f;

		private float m_tempFluctuateTime = 0f;

		private bool m_ShowDamageWarning = true;

		private TextMeshPro m_TemperatureText;

		private const string DEFAULT_GUI_TEXT = "SUIT TEMP: <color=orange>{0}</color>";

		private string m_GUIText = "SUIT TEMP: <color=orange>{0}</color>";

		private readonly Color m_lowTempColor = new Color(0f, 0.5f, 0.5f);

		private readonly Color m_midTempColor = new Color(1f, 0.64f, 0f);

		private readonly Color m_highTempColor = new Color(1f, 0.07f, 0.576f);

		public PlayerAgent PlayerAgent { get; private set; }

		public TemperatureDefinition? TemperatureDef { get; private set; }

		public TemperatureSetting? TemperatureSetting { get; private set; }

		public float PlayerTemperature { get; private set; } = 0.5f;

		internal void Setup()
		{
			//IL_0058: 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_0077: Invalid comparison between Unknown and I4
			TemperatureDef = null;
			PlayerAgent = ((Component)this).gameObject.GetComponent<PlayerAgent>();
			LevelAPI.OnBuildDone += OnBuildDone;
			LevelAPI.OnEnterLevel += OnEnterLevel;
			EOSLogger.Warning($"GameState: {GameStateManager.CurrentStateName}");
			if ((int)GameStateManager.CurrentStateName == 15)
			{
				OnBuildDone();
				OnEnterLevel();
			}
		}

		private void OnDestroy()
		{
			Object.Destroy((Object)(object)m_TemperatureText);
			LevelAPI.OnBuildDone -= OnBuildDone;
			LevelAPI.OnEnterLevel -= OnEnterLevel;
		}

		private void SetupGUI()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_TemperatureText == (Object)null)
			{
				m_TemperatureText = Object.Instantiate<TextMeshPro>(GuiManager.PlayerLayer.m_objectiveTimer.m_titleText);
				m_TemperatureText.transform.SetParent(((Component)GuiManager.PlayerLayer.m_playerStatus).gameObject.transform, false);
				((Component)m_TemperatureText).GetComponent<RectTransform>().anchoredPosition = new Vector2(-5f, 8f);
				((Component)m_TemperatureText).gameObject.transform.localPosition = new Vector3(268.2203f, 25.3799f, 0f);
				((Component)m_TemperatureText).gameObject.transform.localScale = new Vector3(0.75f, 0.75f, 0.75f);
			}
			((Component)m_TemperatureText).gameObject.SetActive(TemperatureDef != null);
		}

		internal void UpdateGUIText()
		{
			TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("EnvTemperature.Text");
			m_GUIText = ((block != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID) : "SUIT TEMP: <color=orange>{0}</color>");
		}

		private void UpdateGui()
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (TemperatureDef != null)
			{
				((Component)m_TemperatureText).gameObject.SetActive(true);
				((TMP_Text)m_TemperatureText).SetText(string.Format(m_GUIText, (PlayerTemperature * 100f).ToString("N0")), true);
				if (PlayerTemperature > 0.5f)
				{
					((Graphic)m_TemperatureText).color = Color.Lerp(m_midTempColor, m_highTempColor, (PlayerTemperature - 0.5f) * 2f);
				}
				else
				{
					((Graphic)m_TemperatureText).color = Color.Lerp(m_lowTempColor, m_midTempColor, PlayerTemperature * 2f);
				}
				((TMP_Text)m_TemperatureText).ForceMeshUpdate(false, false);
			}
			else
			{
				((Component)m_TemperatureText).gameObject.SetActive(false);
			}
		}

		private void UpdateMoveSpeed()
		{
			if (TemperatureSetting == null || TemperatureSetting.SlowDownMultiplier_Move <= 0f)
			{
				Patches_PLOC.ResetMoveSpeedModifier();
			}
			else
			{
				Patches_PLOC.SetMoveSpeedModifier(TemperatureSetting.SlowDownMultiplier_Move);
			}
		}

		private void ResetMoveSpeed()
		{
			Patches_PLOC.ResetMoveSpeedModifier();
		}

		public void UpdateTemperatureDefinition(TemperatureDefinition def)
		{
			TemperatureDef = def;
			TemperatureSetting = null;
			PlayerTemperature = def?.StartTemperature ?? 0.5f;
		}

		private void OnBuildDone()
		{
			UpdateTemperatureDefinition(((GenericDefinitionManager<TemperatureDefinition>)TemperatureDefinitionManager.Current).GetDefinition(RundownManager.ActiveExpedition.LevelLayoutData)?.Definition ?? null);
		}

		private void OnEnterLevel()
		{
			PlayerTemperature = ((TemperatureDef != null) ? TemperatureDef.StartTemperature : 0.5f);
			UpdateGUIText();
			SetupGUI();
			ResetMoveSpeed();
		}

		private void DealDamage()
		{
			if (TemperatureSetting != null && !(TemperatureSetting.Damage < 0f) && !(Time.time - m_lastDamageTime < TemperatureSetting.DamageTick))
			{
				Patch_Dam_PlayerDamageBase.s_disableDialog = true;
				((Dam_SyncedDamageBase)PlayerAgent.Damage).FallDamage(TemperatureSetting.Damage);
				Patch_Dam_PlayerDamageBase.s_disableDialog = false;
				m_lastDamageTime = Time.time;
			}
		}

		private void UpdateTemperatureSettings()
		{
			if (Time.time - m_tempSettingLastUpdateTime < 1f)
			{
				return;
			}
			if (!TemperatureDefinitionManager.Current.TryGetLevelTemperatureSettings(out var settings))
			{
				TemperatureSetting = null;
				return;
			}
			int num = 0;
			int num2 = settings.Count - 1;
			float playerTemperature = PlayerTemperature;
			while (num < num2)
			{
				int num3 = (num + num2) / 2;
				float temperature = settings[num3].Temperature;
				float num4 = ((num3 + 1 < settings.Count) ? settings[num3 + 1].Temperature : 1f);
				if (temperature <= playerTemperature && playerTemperature < num4)
				{
					break;
				}
				if (playerTemperature < temperature)
				{
					num2 = num3 - 1;
				}
				else
				{
					num = num3 + 1;
				}
			}
			TemperatureSetting = settings[Math.Clamp((num + num2) / 2, 0, settings.Count - 1)];
			m_tempSettingLastUpdateTime = Time.time;
		}

		private void Update()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected I4, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			if ((int)GameStateManager.CurrentStateName != 10 || TemperatureDef == null || (Object)(object)PlayerAgent == (Object)null)
			{
				return;
			}
			Vector3 lastMoveDelta = PlayerAgent.Locomotion.LastMoveDelta;
			float num = ((Vector3)(ref lastMoveDelta)).magnitude / Clock.FixedDelta;
			float num2 = (PlayerAgent.PlayerData.walkMoveSpeed + PlayerAgent.PlayerData.runMoveSpeed) * 0.5f;
			float num3 = 0f;
			PLOC_State currentStateEnum = PlayerAgent.Locomotion.m_currentStateEnum;
			PLOC_State val = currentStateEnum;
			switch ((int)val)
			{
			case 0:
				num3 = TemperatureDef.StandingActionHeatGained * Time.deltaTime;
				break;
			case 1:
				num3 = ((!(num <= num2)) ? ((TemperatureDef.CrouchActionHeatGained + TemperatureDef.SprintActionHeatGained) * Time.deltaTime) : (TemperatureDef.CrouchActionHeatGained * Time.deltaTime));
				break;
			case 2:
				num3 = TemperatureDef.SprintActionHeatGained * Time.deltaTime;
				break;
			case 3:
				num3 = ((!(num <= num2)) ? ((TemperatureDef.JumpActionHeatGained + TemperatureDef.SprintActionHeatGained) * Time.deltaTime) : (TemperatureDef.JumpActionHeatGained * Time.deltaTime));
				break;
			case 7:
				num3 = 0f;
				break;
			case 8:
				num3 = TemperatureDef.LadderClimbingActionHeatGained * Time.deltaTime;
				break;
			}
			float num4 = TemperatureDef.StartTemperature;
			LG_Zone zone = ((Agent)PlayerAgent).CourseNode.m_zone;
			float min = 0.005f;
			float max = 1f;
			if (TemperatureDefinitionManager.Current.TryGetZoneDefinition(zone.DimensionIndex, zone.Layer.m_type, zone.LocalIndex, out var def))
			{
				num4 = def.Temperature_Normal;
				min = def.Temperature_Downlimit;
				max = def.Temperature_Uplimit;
			}
			else
			{
				def = TemperatureDefinitionManager.DEFAULT_ZONE_DEF;
			}
			if ((double)Math.Abs(num3) < 1E-05)
			{
				if (Time.time - m_tempFluctuateTime > 1f)
				{
					float num5 = def.FluctuationIntensity * Random.RandomRange(0f, 1f);
					if (PlayerTemperature > num4)
					{
						PlayerTemperature -= num5;
					}
					else
					{
						PlayerTemperature += num5;
					}
					m_tempFluctuateTime = Time.time;
				}
			}
			else
			{
				m_tempFluctuateTime = Time.time;
			}
			PlayerTemperature += num3;
			PlayerTemperature = Math.Clamp(PlayerTemperature, min, max);
			UpdateTemperatureSettings();
			TemperatureSetting? temperatureSetting = TemperatureSetting;
			if (temperatureSetting != null && temperatureSetting.Damage > 0f)
			{
				DealDamage();
			}
			UpdateGui();
			UpdateMoveSpeed();
		}

		public static bool TryGetCurrentManager(out PlayerTemperatureManager mgr)
		{
			mgr = null;
			LocalPlayerAgent val = default(LocalPlayerAgent);
			if (!LocalPlayer.TryGetLocalAgent(ref val))
			{
				EOSLogger.Debug("Temperature: cannot get localplayeragent");
				return false;
			}
			mgr = ((Component)val).gameObject.GetComponent<PlayerTemperatureManager>();
			if ((Object)(object)mgr == (Object)null)
			{
				EOSLogger.Error("LocalPlayerAgent does not have `PlayerTemperatureManager`!");
				return false;
			}
			return true;
		}

		public static TemperatureSetting? GetCurrentTemperatureSetting()
		{
			if (!TryGetCurrentManager(out var mgr))
			{
				return null;
			}
			return mgr.TemperatureSetting;
		}

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

plugins/Inas07.EOSExt.ExtraDoor.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AIGraph;
using AK;
using Agents;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using EOSExt.ExtraDoor.Config;
using Enemies;
using Expedition;
using ExtraObjectiveSetup;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Utils;
using GTFO.API;
using GTFO.API.Extensions;
using GameData;
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 SNetwork;
using UnityEngine;
using XXHashing;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Inas07.EOSExt.ExtraDoor")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a5104ed29beb6c0446fce0b70afe78132232a184")]
[assembly: AssemblyProduct("Inas07.EOSExt.ExtraDoor")]
[assembly: AssemblyTitle("Inas07.EOSExt.ExtraDoor")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.ExtraDoor
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.EOSExt.ExtraDoor", "EOSExt.ExtraDoor", "1.1.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.ExtraDoor";

		public const string VERSION = "1.1.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			SetupManagers();
			m_Harmony = new Harmony("EOSExt.ExtraDoor");
			m_Harmony.PatchAll();
			EOSLogger.Log("ExtraObjectiveSetup.ExtraDoor loaded.");
		}

		private void SetupManagers()
		{
			((GenericExpeditionDefinitionManager<ForceConnectCfg>)ForceConnectManager.Current).Init();
		}
	}
	internal static class ForceConnectDoorUtils
	{
		public static ForceConnect? GetFC(this LG_SecurityDoor fcdoor)
		{
			return ((Component)fcdoor).gameObject.GetComponentInParent<ForceConnect>();
		}

		public static List<(LG_ZoneExpander fromExp, LG_ZoneExpander toExp)> GetExpandersBetween(LG_Area fromArea, LG_Area toAreaB)
		{
			//IL_0044: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			List<(LG_ZoneExpander, LG_ZoneExpander)> list = new List<(LG_ZoneExpander, LG_ZoneExpander)>();
			Enumerator<LG_ZoneExpander> enumerator = fromArea.m_zoneExpanders.GetEnumerator();
			Vector2 val = default(Vector2);
			Vector2 val2 = default(Vector2);
			while (enumerator.MoveNext())
			{
				LG_ZoneExpander current = enumerator.Current;
				Enumerator<LG_ZoneExpander> enumerator2 = toAreaB.m_zoneExpanders.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					LG_ZoneExpander current2 = enumerator2.Current;
					((Vector2)(ref val))..ctor(((Component)current).transform.position.x, ((Component)current).transform.position.z);
					((Vector2)(ref val2))..ctor(((Component)current2).transform.position.x, ((Component)current2).transform.position.z);
					if (Vector2.Distance(val, val2) <= 0.1f)
					{
						list.Add((current, current2));
					}
				}
			}
			return list;
		}

		public static void FCOnDoorOpenStarted(this LG_SecurityDoor fcdoor)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected I4, but got Unknown
			if ((int)fcdoor.m_securityDoorType == 2)
			{
				LG_LayerType linksToLayerType = fcdoor.LinksToLayerType;
				LG_LayerType val = linksToLayerType;
				switch ((int)val)
				{
				case 0:
					fcdoor.m_sound.Post(EVENTS.BULKHEAD_ENTRANCE_THREAT_HIGH_LOOP, true);
					break;
				case 1:
					fcdoor.m_sound.Post(EVENTS.BULKHEAD_ENTRANCE_THREAT_EXTREME_LOOP, true);
					break;
				case 2:
					fcdoor.m_sound.Post(EVENTS.BULKHEAD_ENTRANCE_THREAT_OVERLOAD_LOOP, true);
					break;
				}
			}
		}

		public static void FCOnDoorIsOpen(this LG_SecurityDoor fcdoor)
		{
			ForceConnect fC = fcdoor.GetFC();
			EOSLogger.Log($"OnDoorIsOpened: ForceConnect: {fcdoor.LinkedToZoneData}");
			if (!((Object)(object)fC != (Object)null))
			{
				return;
			}
			List<LevelEventData> eventsOnEnter = fC.Cfg.Setting.EventsOnEnter;
			EOSLogger.Log("OnDoorIsOpened, FC.EventsOnEnter");
			if (eventsOnEnter != null && eventsOnEnter.Count > 0)
			{
				eventsOnEnter.ForEach(delegate(LevelEventData e)
				{
					((MonoBehaviour)fcdoor).StartCoroutine(fcdoor.TriggerLevelEventWithDelay(e));
				});
			}
			WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnOpenDoor), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
		}

		public static void FCOnSyncDoorStatusChange(this LG_SecurityDoor fcdoor, pDoorState state, bool isRecall)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Invalid comparison between Unknown and I4
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected I4, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Invalid comparison between Unknown and I4
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Invalid comparison between Unknown and I4
			//IL_0653: Unknown result type (might be due to invalid IL or missing references)
			//IL_0654: Unknown result type (might be due to invalid IL or missing references)
			//IL_0660: 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_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Invalid comparison between Unknown and I4
			//IL_0624: Unknown result type (might be due to invalid IL or missing references)
			//IL_062a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Invalid comparison between Unknown and I4
			//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_0278: Invalid comparison between Unknown and I4
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Invalid comparison between Unknown and I4
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_0588: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			ForceConnect fC = fcdoor.GetFC();
			EOSLogger.Log($"OnSyncDoorStatusChange: m_lastState.hasBeenApproached: {fcdoor.m_lastState.hasBeenApproached}, state.hasBeenApproached: {state.hasBeenApproached}, ForceConnect: {fC}");
			if (fcdoor.m_lastState.hasBeenApproached != state.hasBeenApproached && state.hasBeenApproached && (Object)(object)fC != (Object)null && !isRecall)
			{
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnApproachDoor), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				fcdoor.LastStatus = state.status;
				fcdoor.m_lastState = state;
				return;
			}
			fcdoor.Gate.HasBeenOpenedDuringPlay = state.hasBeenOpenedDuringGame;
			fcdoor.m_graphics.OnDoorState(state, isRecall);
			fcdoor.m_anim.OnDoorState(state, isRecall);
			fcdoor.m_locks.OnDoorState(state, isRecall);
			bool flag = (int)fcdoor.m_securityDoorType == 2;
			eDoorStatus status = state.status;
			eDoorStatus val = status;
			switch (val - 1)
			{
			case 0:
			case 1:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
				if ((int)state.status == 8 && fcdoor.OnChainPuzzleActivate != null)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnDoorScanStart), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
					if (fcdoor.LinkedToZoneData.PlayScannerVoiceAudio)
					{
						fcdoor.m_sound.Post(EVENTS.TTS_PLEASE_STEP_INTO_THE_BIOSCAN, true);
					}
					fcdoor.OnChainPuzzleActivate.Invoke();
				}
				if ((int)state.status == 9 && fcdoor.OnChainPuzzleActivate != null)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnDoorScanDone), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
					if (fC.Cfg.Setting.PlayScannerVoiceAudio)
					{
						fcdoor.m_sound.Post(EVENTS.TTS_BIOSCAN_SEQUENCE_COMPLETED, true);
					}
				}
				if (((int)state.status == 9 || (int)state.status == 5) && (int)fcdoor.m_lastState.status == 3)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnUnlockDoor), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				}
				fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 11 : 7));
				fcdoor.CheckSetNavmarkerForBulkheadDoors();
				break;
			case 2:
			{
				fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 11 : 8));
				PlaceNavMarkerOnGO navMarkerPlacer2 = fcdoor.m_navMarkerPlacer;
				if ((Object)(object)navMarkerPlacer2 != (Object)null)
				{
					navMarkerPlacer2.SetMarkerVisible(false);
				}
				break;
			}
			case 3:
				if ((int)fcdoor.m_lastState.status == 3)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnUnlockDoor), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				}
				fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 11 : 9));
				fcdoor.CheckSetNavmarkerForBulkheadDoors();
				break;
			case 9:
			{
				PlaceNavMarkerOnGO navMarkerPlacer = fcdoor.m_navMarkerPlacer;
				if ((Object)(object)navMarkerPlacer != (Object)null)
				{
					navMarkerPlacer.SetMarkerVisible(false);
				}
				fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 12 : 6));
				ActiveEnemyWaveData activeEnemyWave = fC.Cfg.Setting.ActiveEnemyWave;
				if (activeEnemyWave == null || !activeEnemyWave.HasActiveEnemyWave)
				{
					break;
				}
				fcdoor.m_sound.Post(EVENTS.MONSTER_RUCKUS_FROM_BEHIND_SECURITY_DOOR_LOOP_STOP, true);
				if (isRecall || !SNet.IsMaster)
				{
					break;
				}
				ForceConnectCfg cfg = fC.Cfg;
				LG_Zone val2 = default(LG_Zone);
				Builder.CurrentFloor.TryGetZoneByLocalIndex(cfg.DimensionIndex, cfg.To.Layer, cfg.To.LocalIndex, ref val2);
				AIG_CourseNode courseNode = val2.m_areas[cfg.To.AreaIndex].m_courseNode;
				Vector3 val3 = ((Component)fcdoor).transform.position + ((Component)fcdoor).transform.forward * -1.5f + Vector3.up * 0.3f;
				Vector3 gateCrossingVec = fcdoor.Gate.GetGateCrossingVec();
				if (activeEnemyWave.EnemyGroupInfrontOfDoor != 0)
				{
					EnemyGroupDataBlock block = GameDataBlockBase<EnemyGroupDataBlock>.GetBlock(activeEnemyWave.EnemyGroupInfrontOfDoor);
					if (block == null)
					{
						EOSLogger.Error($"Can not spawn group. EnemyGroupDataBlock.GetBlock(ActiveEnemyWaveData.EnemyGroupInfrontOfDoor = {activeEnemyWave.EnemyGroupInfrontOfDoor}) returned null.");
					}
					else
					{
						Mastermind.Current.SpawnGroup(val3, courseNode, (EnemyGroupType)2, (eEnemyGroupSpawnType)3, block, -1f, gateCrossingVec, (IReplicator)null);
					}
				}
				if (activeEnemyWave.EnemyGroupInArea == 0)
				{
					break;
				}
				EnemyGroupDataBlock block2 = GameDataBlockBase<EnemyGroupDataBlock>.GetBlock(activeEnemyWave.EnemyGroupInArea);
				if (block2 == null)
				{
					EOSLogger.Error($"Can not spawn groups.EnemyGroupDataBlock.GetBlock(ActiveEnemyWaveData.EnemyGroupInArea = {activeEnemyWave.EnemyGroupInArea} ) returned null.");
				}
				else
				{
					for (int i = 0; i < activeEnemyWave.EnemyGroupsInArea; i++)
					{
						Mastermind.Current.SpawnGroup(val3, courseNode, (EnemyGroupType)2, (eEnemyGroupSpawnType)0, block2, -1f, default(Vector3), (IReplicator)null);
					}
				}
				break;
			}
			case 14:
			{
				fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 11 : 7));
				PlaceNavMarkerOnGO navMarkerPlacer3 = fcdoor.m_navMarkerPlacer;
				if ((Object)(object)navMarkerPlacer3 != (Object)null)
				{
					navMarkerPlacer3.SetMarkerVisible(false);
				}
				break;
			}
			case 15:
				if (isRecall && SNet.IsMaster)
				{
					fcdoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)0, 0f, 0f, default(Vector3), (Agent)null);
				}
				else if (SNet.IsMaster)
				{
					fcdoor.m_checkpointPuzzle.AttemptInteract((eChainedPuzzleInteraction)0);
				}
				break;
			}
			fcdoor.LastStatus = state.status;
			fcdoor.m_lastState = state;
		}
	}
	public class ForceConnect : MonoBehaviour
	{
		internal bool ShouldFlipDoor;

		private bool _IsDynamicPortalSetup;

		private AIG_CourseNode _FromNode;

		private AIG_CourseNode _ToNode;

		private AIG_CoursePortal _Portal;

		private bool _PortalEnabled = true;

		public LG_SecurityDoor LinkedSecDoor { get; internal set; }

		public ForceConnectCfg Cfg { get; internal set; }

		private void Update()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Invalid comparison between Unknown and I4
			if (!_IsDynamicPortalSetup && (Object)(object)LinkedSecDoor != (Object)null && (int)GameStateManager.CurrentStateName == 10)
			{
				LG_Gate gate = LinkedSecDoor.Gate;
				_Portal = ((LG_ZoneExpander)gate).CoursePortal;
				_FromNode = ((LG_ZoneExpander)gate).m_linksFrom.m_courseNode;
				_ToNode = ((LG_ZoneExpander)gate).m_linksTo.m_courseNode;
				_IsDynamicPortalSetup = true;
			}
			else if (_IsDynamicPortalSetup)
			{
				eDoorStatus status = LinkedSecDoor.m_sync.GetCurrentSyncState().status;
				eDoorStatus val = status;
				if ((int)val != 10)
				{
					SetPortalEnabled(enabled: false);
				}
				else
				{
					SetPortalEnabled(enabled: true);
				}
			}
		}

		private void SetPortalEnabled(bool enabled)
		{
			if (enabled && !_PortalEnabled)
			{
				_FromNode.m_portals.Add(_Portal);
				_ToNode.m_portals.Add(_Portal);
				_PortalEnabled = true;
			}
			else if (!enabled && _PortalEnabled)
			{
				RemoveItem(_FromNode.m_portals, _Portal);
				RemoveItem(_ToNode.m_portals, _Portal);
				_PortalEnabled = false;
			}
		}

		private void RemoveItem(List<AIG_CoursePortal> portals, AIG_CoursePortal portal)
		{
			for (int i = 0; i < portals.Count; i++)
			{
				if (((Il2CppObjectBase)portals[i]).Pointer == ((Il2CppObjectBase)portal).Pointer)
				{
					portals.RemoveAt(i);
					break;
				}
			}
		}

		static ForceConnect()
		{
			ClassInjector.RegisterTypeInIl2Cpp<ForceConnect>();
		}
	}
	public class ForceConnectManager : GenericExpeditionDefinitionManager<ForceConnectCfg>
	{
		public enum FCDoorEventType
		{
			OpenFCDoor = 900,
			UnlockFCDoor,
			CloseFCDoor,
			LockFCDoor
		}

		private Dictionary<string, LG_SecurityDoor> m_doorLookup = new Dictionary<string, LG_SecurityDoor>();

		public static ForceConnectManager Current { get; } = new ForceConnectManager();

		protected override string DEFINITION_NAME => "ExtraDoor";

		public void BuildCfg(ForceConnectCfg cfg)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			eDimensionIndex dimensionIndex = cfg.DimensionIndex;
			Door door = cfg.From;
			Door to = cfg.To;
			LG_Zone val = default(LG_Zone);
			LG_Zone val2 = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, door.Layer, door.LocalIndex, ref val) || 0 > door.AreaIndex || door.AreaIndex >= val.m_areas.Count || !Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, to.Layer, to.LocalIndex, ref val2) || 0 > to.AreaIndex || to.AreaIndex >= val2.m_areas.Count)
			{
				EOSLogger.Error($"CircularZones Build: Cannot find Zone 'From' or 'To'!\nFrom:({(cfg.DimensionIndex, door.Layer, door.LocalIndex, (char)(65 + door.AreaIndex))})To:({(cfg.DimensionIndex, to.Layer, to.LocalIndex, (char)(65 + to.AreaIndex))})");
				return;
			}
			LG_Area fromArea = val.m_areas[door.AreaIndex];
			LG_Area toArea = val2.m_areas[to.AreaIndex];
			List<(LG_ZoneExpander, LG_ZoneExpander)> expandersBetween = ForceConnectDoorUtils.GetExpandersBetween(fromArea, toArea);
			if (expandersBetween.Count < 1)
			{
				EOSLogger.Error($"ExtraDoor: cannot find gate / plug! From:({(cfg.DimensionIndex, door.Layer, door.LocalIndex, (char)(65 + door.AreaIndex))})To:({(cfg.DimensionIndex, to.Layer, to.LocalIndex, (char)(65 + to.AreaIndex))})");
			}
			else if (cfg.FromDoorIndex < 0 || cfg.FromDoorIndex >= expandersBetween.Count)
			{
				EOSLogger.Error($"ExtraDoor: FromDoorIndex ({cfg.FromDoorIndex}) is out of range [0, {expandersBetween.Count})From:({(cfg.DimensionIndex, door.Layer, door.LocalIndex, (char)(65 + door.AreaIndex))})To:({(cfg.DimensionIndex, to.Layer, to.LocalIndex, (char)(65 + to.AreaIndex))})");
			}
			else
			{
				Setup(expandersBetween[cfg.FromDoorIndex].Item1, expandersBetween[cfg.FromDoorIndex].Item2);
			}
			void Setup(LG_ZoneExpander expandFrom, LG_ZoneExpander expandTo)
			{
				LG_Plug val3 = ((Il2CppObjectBase)expandFrom).TryCast<LG_Plug>();
				LG_Plug val4 = ((Il2CppObjectBase)expandTo).TryCast<LG_Plug>();
				if ((Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null)
				{
					val3.m_pariedWith = val4;
					val4.m_pariedWith = val3;
					((LG_ZoneExpander)val3).m_isZoneSource = true;
					expandFrom.ExpanderStatus = (LG_ZoneExpanderStatus)1;
					expandTo.ExpanderStatus = (LG_ZoneExpanderStatus)1;
					expandFrom.m_linksTo = expandTo.m_linksFrom;
					expandTo.m_linksTo = expandFrom.m_linksFrom;
					GameObject gameObject = ((Component)val3).gameObject;
					((Object)gameObject).name = ((Object)gameObject).name + "FORCE PAIR";
					((Component)val3).gameObject.AddComponent<ForceConnect>().Cfg = cfg;
				}
				else
				{
					LG_Gate gate = expandFrom.GetGate();
					switch (cfg.Setting.SecurityGateToEnter)
					{
					case GateType.Security:
						gate.ForceSecurityGate = true;
						break;
					case GateType.Apex:
						gate.ForceApexGate = true;
						break;
					case GateType.Bulkhead:
					case GateType.Bulkhead_Main:
						gate.ForceSecurityGate = true;
						gate.ForceBulkheadGate = true;
						break;
					}
					if (((Il2CppObjectBase)fromArea.m_zone).Pointer != ((Il2CppObjectBase)toArea.m_zone).Pointer)
					{
						expandFrom.m_isZoneSource = true;
						expandFrom.ExpanderStatus = (LG_ZoneExpanderStatus)1;
						expandTo.ExpanderStatus = (LG_ZoneExpanderStatus)1;
					}
					GameObject gameObject2 = ((Component)gate).gameObject;
					((Object)gameObject2).name = ((Object)gameObject2).name + "FORCE PAIR";
					((Component)gate).gameObject.AddComponent<ForceConnect>().Cfg = cfg;
				}
			}
		}

		private void Build()
		{
			if (base.definitions.TryGetValue(base.CurrentMainLevelLayout, out var value))
			{
				value.Definitions.ForEach(BuildCfg);
			}
		}

		private void BuildProgressionPuzzle()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected I4, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Expected O, but got Unknown
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val = default(LG_Zone);
			LG_Zone val2 = default(LG_Zone);
			foreach (KeyValuePair<string, LG_SecurityDoor> item in m_doorLookup)
			{
				LG_SecurityDoor value = item.Value;
				ForceConnect fC = value.GetFC();
				Door door = fC.Cfg.From;
				Door to = fC.Cfg.To;
				if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(fC.Cfg.DimensionIndex, door.Layer, door.LocalIndex, ref val) || 0 > door.AreaIndex || door.AreaIndex >= val.m_areas.Count || !Builder.CurrentFloor.TryGetZoneByLocalIndex(fC.Cfg.DimensionIndex, to.Layer, to.LocalIndex, ref val2) || 0 > to.AreaIndex || to.AreaIndex >= val2.m_areas.Count || val2.ID <= 0)
				{
					continue;
				}
				if ((Object)(object)val2.m_sourceExpander == (Object)null)
				{
					EOSLogger.Error("Found zone without sourceGate AND ID over 0, id: " + val.ID);
					continue;
				}
				FCProgressionPuzzleToEnter progressionPuzzleToEnter = fC.Cfg.Setting.ProgressionPuzzleToEnter;
				LG_Layer layer = val2.Layer;
				eProgressionPuzzleType puzzleType = progressionPuzzleToEnter.PuzzleType;
				eProgressionPuzzleType val3 = puzzleType;
				switch (val3 - 1)
				{
				case 0:
				{
					GateKeyItem randomKey = Builder.CurrentFloor.GetRandomKey(Builder.SessionSeedRandom);
					LG_Factory.InjectJob((LG_FactoryJob)new LG_BuildKeyItemLockJob(value, randomKey), (BatchName)43);
					if (progressionPuzzleToEnter.ZonePlacementData.Count > 0)
					{
						LG_Zone val8 = CreateKeyItemDistribution(randomKey, progressionPuzzleToEnter.ZonePlacementData[Builder.SessionSeedRandom.Range(0, progressionPuzzleToEnter.ZonePlacementData.Count, "NO_TAG")], layer);
						ProgressionObjectivesManager.RegisterProgressionObjective(val2.DimensionIndex, val2.Layer.m_type, val2.LocalIndex, ((Il2CppObjectBase)new ProgressionObjective_KeyCard(randomKey, val2, val8)).Cast<IProgressionObjective>());
					}
					break;
				}
				case 1:
				{
					AIG_CourseNode courseNode = val.m_areas[door.AreaIndex].m_courseNode;
					LG_DistributeItem val4 = new LG_DistributeItem((ExpeditionFunction)6, 1f, courseNode, (LG_Gate)null)
					{
						m_assignedGate = value.Gate
					};
					courseNode.m_zone.DistributionData.GenericFunctionItems.Enqueue(val4);
					LG_Zone val5 = null;
					for (int i = 0; i < progressionPuzzleToEnter.PlacementCount; i++)
					{
						LG_Zone val6 = layer.m_zones[0];
						ZonePlacementWeights val7 = new ZonePlacementWeights();
						if (progressionPuzzleToEnter.ZonePlacementData.Count > 0)
						{
							FCZonePlacementData fCZonePlacementData = progressionPuzzleToEnter.ZonePlacementData[Builder.SessionSeedRandom.Range(0, progressionPuzzleToEnter.ZonePlacementData.Count, "NO_TAG")];
							if (layer.m_zonesByLocalIndex.ContainsKey(((GlobalZoneIndex)fCZonePlacementData).LocalIndex))
							{
								val6 = layer.m_zonesByLocalIndex[((GlobalZoneIndex)fCZonePlacementData).LocalIndex];
								val5 = layer.m_zonesByLocalIndex[((GlobalZoneIndex)fCZonePlacementData).LocalIndex];
								val7 = fCZonePlacementData.Weights;
							}
							else
							{
								EOSLogger.Error($"ProgressionPuzzleToEnter, Could NOT find zone with LocalIndex {((GlobalZoneIndex)fCZonePlacementData).LocalIndex} to place powerCell in to enter Zone {val2.LocalIndex}. Faulty zone specified!? DEFAULTING TO THE FIRST ZONE");
							}
						}
						else
						{
							EOSLogger.Error($"ProgressionPuzzleToEnter has NO placement data for power cell going into {layer.m_type} lg_Zone.LocalIndex");
						}
						((LG_FactoryJob)new LG_Distribute_PickupItemsPerZone(val6, 1f, (ePickupItemType)3, 131u, val7)).Build();
					}
					if ((Object)(object)val5 != (Object)null)
					{
						ProgressionObjectivesManager.RegisterProgressionObjective(val2.DimensionIndex, val2.Layer.m_type, val2.LocalIndex, ((Il2CppObjectBase)new ProgressionObjective_GeneratorCell(val2, val5, courseNode.m_zone)).Cast<IProgressionObjective>());
					}
					break;
				}
				case 2:
					value.SetupAsLockedNoKey(progressionPuzzleToEnter.CustomText);
					break;
				}
			}
		}

		private LG_Zone CreateKeyItemDistribution(GateKeyItem keyItem, FCZonePlacementData placementData, LG_Layer doorLayer)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Expected O, but got Unknown
			EOSLogger.Log($"CreateKeyItemDistribution, keyItem: {keyItem}, placementData: {placementData}");
			LG_Zone val = doorLayer.m_zones[0];
			if (doorLayer.m_zonesByLocalIndex.ContainsKey(((GlobalZoneIndex)placementData).LocalIndex))
			{
				val = doorLayer.m_zonesByLocalIndex[((GlobalZoneIndex)placementData).LocalIndex];
			}
			else
			{
				EOSLogger.Error($"LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution, Could NOT find zone with LocalIndex {((GlobalZoneIndex)placementData).LocalIndex} to place keycard in to enter Zone {val.LocalIndex} Faulty zone specified!? Dim: {doorLayer.m_dimension.DimensionIndex} | DEFAULTING TO THE FIRST ZONE");
			}
			ResourceContainerSpawnData val2 = new ResourceContainerSpawnData
			{
				m_type = (eResourceContainerSpawnType)7,
				m_keyItem = keyItem
			};
			float num = Builder.BuildSeedRandom.Value("LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution_" + keyItem.PublicName);
			AIG_CourseNode val3 = null;
			LG_DistributeItem val4 = default(LG_DistributeItem);
			if (LG_DistributionJobUtils.TryGetExistingZoneFunctionDistribution(val, (ExpeditionFunction)10, Builder.SessionSeedRandom.Value("LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution_TryGetZoneFunctionDistribution"), placementData.Weights, ref val4, ref val3, true, "FindContainerFor " + (object)keyItem))
			{
				LG_DistributeResourceContainer val5 = ((Il2CppObjectBase)val4).Cast<LG_DistributeResourceContainer>();
				if (val5 != null)
				{
					val5.m_packs.Add(val2);
					val5.m_locked = true;
				}
				else
				{
					EOSLogger.Error("LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution could not cast distItem as LG_DistributeResourceContainer!!");
				}
			}
			else
			{
				val3 = LG_DistributionJobUtils.GetRandomNodeFromZoneForFunction(val, (ExpeditionFunction)10, num, 1f);
				LG_DistributeResourceContainer val6 = new LG_DistributeResourceContainer((ExpeditionFunction)10, val2, false, val3, Builder.BuildSeedRandom.Range(0, int.MaxValue, "LG_Distribute_ProgressionPuzzles_New_LG_DistributeResourceContainer"), Builder.BuildSeedRandom.Value("LG_Distribute_ProgressionPuzzles_New_LG_DistributeResourceContainer_Lock"), Builder.BuildSeedRandom.Range(2, 4, "LG_Distribute_ProgressionPuzzles_New_LG_DistributeResourceContainer_StoragePotential"));
				val3.m_zone.DistributionData.ResourceContainerItems.Enqueue(val6);
				EOSLogger.Error("LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution Had to create a new resourceContainer!!");
			}
			iLG_SpawnedInNodeHandler component = ((Component)keyItem.SpawnedItem).GetComponent<iLG_SpawnedInNodeHandler>();
			if (component != null)
			{
				component.SpawnNode = val3;
			}
			return val;
		}

		public void RegisterFCDoor(LG_SecurityDoor fcdoor)
		{
			ForceConnect fC = fcdoor.GetFC();
			if ((Object)(object)fC == (Object)null)
			{
				EOSLogger.Error("ExtraDoor: Registering non-forceconnect door");
				return;
			}
			if (m_doorLookup.ContainsKey(fC.Cfg.WorldEventObjectFilter))
			{
				EOSLogger.Error("ExtraDoor: Duplicate ExtraDoor '" + fC.Cfg.WorldEventObjectFilter + "'");
			}
			m_doorLookup[fC.Cfg.WorldEventObjectFilter] = fcdoor;
		}

		public LG_SecurityDoor GetFCDoor(string worldEventObjectFilter)
		{
			LG_SecurityDoor value;
			return m_doorLookup.TryGetValue(worldEventObjectFilter, out value) ? value : null;
		}

		private void Cleanup()
		{
			m_doorLookup.Clear();
		}

		private void OnEnterLevel()
		{
		}

		private ForceConnectManager()
		{
			BatchBuildManager.Current.Add_OnBatchDone((BatchName)5, (Action)Build);
			BatchBuildManager.Current.Add_OnBatchDone((BatchName)16, (Action)BuildProgressionPuzzle);
			EOSWardenEventManager.Current.AddEventDefinition(FCDoorEventType.OpenFCDoor.ToString(), 900u, (Action<WardenObjectiveEventData>)OpenFCDoor);
			EOSWardenEventManager.Current.AddEventDefinition(FCDoorEventType.UnlockFCDoor.ToString(), 901u, (Action<WardenObjectiveEventData>)UnlockFCDoor);
			EOSWardenEventManager.Current.AddEventDefinition(FCDoorEventType.CloseFCDoor.ToString(), 902u, (Action<WardenObjectiveEventData>)CloseFCDoor);
			EOSWardenEventManager.Current.AddEventDefinition(FCDoorEventType.LockFCDoor.ToString(), 903u, (Action<WardenObjectiveEventData>)LockFCDoor);
			LevelAPI.OnEnterLevel += OnEnterLevel;
			LevelAPI.OnLevelCleanup += Cleanup;
		}

		private static void OpenFCDoor(WardenObjectiveEventData e)
		{
			if (SNet.IsMaster)
			{
				LG_SecurityDoor fCDoor = Current.GetFCDoor(e.WorldEventObjectFilter);
				if ((Object)(object)fCDoor == (Object)null)
				{
					EOSLogger.Error("OpenFCDoor: Cannot find FC door with '" + e.WorldEventObjectFilter + "'");
				}
				else
				{
					fCDoor.ForceOpenSecurityDoor();
				}
			}
		}

		private static void UnlockFCDoor(WardenObjectiveEventData e)
		{
			if (SNet.IsMaster)
			{
				LG_SecurityDoor fCDoor = Current.GetFCDoor(e.WorldEventObjectFilter);
				if ((Object)(object)fCDoor == (Object)null)
				{
					EOSLogger.Error("UnlockFCDoor: Cannot find FC door with '" + e.WorldEventObjectFilter + "'");
				}
				else
				{
					fCDoor.UseChainedPuzzleOrUnlock(SNet.Master);
				}
			}
		}

		private static void CloseFCDoor(WardenObjectiveEventData e)
		{
			//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)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Invalid comparison between Unknown and I4
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Invalid comparison between Unknown and I4
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster)
			{
				return;
			}
			LG_SecurityDoor fCDoor = Current.GetFCDoor(e.WorldEventObjectFilter);
			if ((Object)(object)fCDoor == (Object)null)
			{
				EOSLogger.Error("UnlockFCDoor: Cannot find FC door with '" + e.WorldEventObjectFilter + "'");
				return;
			}
			pDoorState currentSyncState = fCDoor.m_sync.GetCurrentSyncState();
			if ((int)currentSyncState.status != 10 && (int)currentSyncState.status != 16)
			{
				return;
			}
			LG_Door_Sync val = ((Il2CppObjectBase)fCDoor.m_sync).TryCast<LG_Door_Sync>();
			if (!((Object)(object)val == (Object)null))
			{
				pDoorState currentSyncState2 = val.GetCurrentSyncState();
				currentSyncState2.status = (eDoorStatus)1;
				currentSyncState2.hasBeenOpenedDuringGame = false;
				pDoorState state = currentSyncState2;
				val.m_stateReplicator.State = state;
				LG_Gate gate = fCDoor.Gate;
				gate.HasBeenOpenedDuringPlay = false;
				gate.IsTraversable = false;
				ForceConnect fC = fCDoor.GetFC();
				DoorSetting setting = fC.Cfg.Setting;
				if (setting.ActiveEnemyWave != null && setting.ActiveEnemyWave.HasActiveEnemyWave)
				{
					fCDoor.m_sound.Post(EVENTS.MONSTER_RUCKUS_FROM_BEHIND_SECURITY_DOOR_LOOP_START, true);
				}
				EOSLogger.Debug("Door Closed!");
			}
		}

		private static void LockFCDoor(WardenObjectiveEventData e)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster)
			{
				return;
			}
			LG_SecurityDoor fCDoor = Current.GetFCDoor(e.WorldEventObjectFilter);
			if ((Object)(object)fCDoor == (Object)null)
			{
				EOSLogger.Error("UnlockFCDoor: Cannot find FC door with '" + e.WorldEventObjectFilter + "'");
				return;
			}
			LG_Door_Sync val = ((Il2CppObjectBase)fCDoor.m_sync).TryCast<LG_Door_Sync>();
			if (!((Object)(object)val == (Object)null))
			{
				pDoorState currentSyncState = val.GetCurrentSyncState();
				currentSyncState.status = (eDoorStatus)7;
				pDoorState state = currentSyncState;
				val.m_stateReplicator.State = state;
				EOSLogger.Debug("Door Locked!");
			}
		}
	}
}
namespace EOSExt.ExtraDoor.Patches
{
	[HarmonyPatch]
	internal static class CheckDoorFlip
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(LG_BuildSecurityDoorLockJob), "CheckFlip")]
		private static bool Pre_(LG_BuildSecurityDoorLockJob __instance)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			ForceConnect fC = __instance.m_door.GetFC();
			if ((Object)(object)fC == (Object)null)
			{
				return true;
			}
			LG_SecurityDoor door = __instance.m_door;
			Vector3 forward = ((Component)door).transform.forward;
			ForceConnectCfg cfg = fC.Cfg;
			Door door2 = cfg.From;
			LG_Zone val = default(LG_Zone);
			Builder.CurrentFloor.TryGetZoneByLocalIndex(cfg.DimensionIndex, door2.Layer, door2.LocalIndex, ref val);
			LG_Area val2 = val.m_areas[door2.AreaIndex];
			LG_Area linksFrom = ((LG_ZoneExpander)door.Gate).m_linksFrom;
			Door to = cfg.To;
			EOSLogger.Warning($"CheckFilp!\nOri: {((Object)linksFrom).name} -> {((Object)((LG_ZoneExpander)door.Gate).m_linksTo).name}\nShould be: {(cfg.DimensionIndex, door2.Layer, door2.LocalIndex, (char)(65 + door2.AreaIndex))} -> {(cfg.DimensionIndex, to.Layer, to.LocalIndex, (char)(65 + to.AreaIndex))}");
			if (door.FlippedForProgresion)
			{
				EOSLogger.Error("Door already flipped, skipped ....");
				return false;
			}
			if (((Il2CppObjectBase)val2).Pointer == ((Il2CppObjectBase)linksFrom).Pointer)
			{
				EOSLogger.Error("Flipped!");
				door.FlippedForProgresion = true;
				((Component)door).transform.rotation = Quaternion.LookRotation(((Component)door).transform.forward * -1f, ((Component)door).transform.up);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class OnSecurityDoorSetup
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_SecurityDoor), "Setup")]
		private static void Postfix(LG_SecurityDoor __instance)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			ForceConnect fC = __instance.GetFC();
			if (!((Object)(object)fC != (Object)null))
			{
				return;
			}
			ForceConnectCfg cfg = fC.Cfg;
			Door door = cfg.From;
			Door to = cfg.To;
			EOSLogger.Debug($"ForceConnect: {cfg.DimensionIndex}, ({door.Layer}, {door.LocalIndex}, {(ushort)(65 + door.AreaIndex)}) <-> ({to.Layer}, {to.LocalIndex}, {(ushort)(65 + to.AreaIndex)})\nWorldEventObjectFilter: '{cfg.WorldEventObjectFilter}', FromDoorIndex: {cfg.FromDoorIndex}");
			ForceConnectManager.Current.RegisterFCDoor(__instance);
			fC.LinkedSecDoor = __instance;
			__instance.LinksToLayerType = to.Layer;
			LG_Door_Sync val = ((Il2CppObjectBase)__instance.m_sync).Cast<LG_Door_Sync>();
			val.OnDoorStateChange = Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)__instance.FCOnSyncDoorStatusChange);
			LG_SecurityDoor_Anim val2 = ((Il2CppObjectBase)__instance.m_anim).TryCast<LG_SecurityDoor_Anim>();
			if ((Object)(object)val2 != (Object)null)
			{
				val2.OnDoorOpenStarted = Action.op_Implicit((Action)__instance.FCOnDoorOpenStarted);
				val2.OnDoorIsOpen = Action.op_Implicit((Action)__instance.FCOnDoorIsOpen);
				return;
			}
			LG_ApexDoor_Anim val3 = ((Il2CppObjectBase)__instance.m_anim).TryCast<LG_ApexDoor_Anim>();
			if ((Object)(object)val3 != (Object)null)
			{
				val3.OnDoorOpenStarted = Action.op_Implicit((Action)__instance.FCOnDoorOpenStarted);
				val3.OnDoorIsOpen = Action.op_Implicit((Action)__instance.FCOnDoorIsOpen);
			}
			else
			{
				EOSLogger.Error("LG_SecurityDoor: Cannot cast iLG_Door_Anim");
			}
		}
	}
}
namespace EOSExt.ExtraDoor.Patches.SetupFCDoor
{
	[HarmonyPatch]
	internal static class BuildGate
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(LG_BuildGateJob), "Build")]
		private static bool Pre_(LG_BuildGateJob __instance, ref bool __result)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Invalid comparison between Unknown and I4
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected I4, but got Unknown
			//IL_0818: Unknown result type (might be due to invalid IL or missing references)
			//IL_081e: Invalid comparison between Unknown and I4
			//IL_07a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b5: Expected O, but got Unknown
			//IL_084f: Unknown result type (might be due to invalid IL or missing references)
			//IL_085b: Expected O, but got Unknown
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0609: Unknown result type (might be due to invalid IL or missing references)
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_061e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0624: Invalid comparison between Unknown and I4
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_063b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0645: Unknown result type (might be due to invalid IL or missing references)
			//IL_064a: Unknown result type (might be due to invalid IL or missing references)
			//IL_064f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0654: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0689: Unknown result type (might be due to invalid IL or missing references)
			//IL_068b: Unknown result type (might be due to invalid IL or missing references)
			//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0705: Unknown result type (might be due to invalid IL or missing references)
			//IL_0721: Unknown result type (might be due to invalid IL or missing references)
			//IL_0731: Unknown result type (might be due to invalid IL or missing references)
			//IL_074a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0762: Unknown result type (might be due to invalid IL or missing references)
			//IL_076e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0778: Unknown result type (might be due to invalid IL or missing references)
			//IL_0791: Unknown result type (might be due to invalid IL or missing references)
			//IL_0589: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_0599: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			ForceConnect forceConnect = null;
			forceConnect = ((!((Object)(object)__instance.m_plug != (Object)null)) ? ((Component)__instance.m_gate).gameObject.GetComponent<ForceConnect>() : ((Component)__instance.m_plug).gameObject.GetComponent<ForceConnect>());
			if ((Object)(object)forceConnect == (Object)null)
			{
				return true;
			}
			try
			{
				if (((LG_ZoneExpander)__instance.m_gate).m_wasProcessed)
				{
					__result = true;
					return false;
				}
				((LG_ZoneExpander)__instance.m_gate).m_wasProcessed = true;
				if ((Object)(object)__instance.m_plug != (Object)null)
				{
					((LG_ZoneExpander)__instance.m_gate).m_linksFrom = ((LG_ZoneExpander)__instance.m_plug).m_linksFrom;
					((LG_ZoneExpander)__instance.m_gate).ExpanderStatus = ((LG_ZoneExpander)__instance.m_plug).ExpanderStatus;
					if (((LG_ZoneExpander)__instance.m_plug).CoursePortal != null)
					{
						((LG_ZoneExpander)__instance.m_gate).CoursePortal = ((LG_ZoneExpander)__instance.m_plug).CoursePortal;
						((LG_ZoneExpander)__instance.m_gate).CoursePortal.Gate = __instance.m_gate;
						__instance.m_gate.m_needsBorderLinks = true;
						((LG_ZoneExpander)__instance.m_gate).m_linksTo = ((LG_ZoneExpander)__instance.m_plug).m_linksTo;
					}
				}
				else if (((LG_ZoneExpander)__instance.m_gate).CoursePortal != null)
				{
					((LG_ZoneExpander)__instance.m_gate).CoursePortal.Gate = __instance.m_gate;
				}
				if ((int)((LG_ZoneExpander)__instance.m_gate).ExpanderStatus == 2)
				{
					__instance.SetupCappedGate();
				}
				else
				{
					__instance.CalcOpenAtStart();
					LG_GateType type = __instance.m_gate.Type;
					LG_GateType val = type;
					switch ((int)val)
					{
					case 0:
					case 1:
					case 2:
						__instance.CalcOpenAtStart();
						if (__instance.m_gate.m_isTraversableFromStart && __instance.m_gate.HasGateWallRemover && Builder.BuildSeedRandom.Value("LG_BuildGateJob") < RundownManager.ActiveExpeditionBalanceData.WeakDoorOpenChanceForWallRemoverUsed)
						{
							__instance.m_gate.EnableGateWallRemover(RandomExtensions.NextSubSeed(__instance.m_rnd.Random));
						}
						else
						{
							GameObject val2 = null;
							XXHashSeed seed;
							if (__instance.m_gate.ForceBulkheadGate)
							{
								if (forceConnect.Cfg.Setting.SecurityGateToEnter == GateType.Bulkhead_Main)
								{
									seed = __instance.m_rnd.Seed;
									uint num = ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random));
									val2 = Builder.ComplexResourceSetBlock.GetMainPathBulkheadGate(__instance.m_gate.Type, num, (SubComplex)5);
									if ((Object)(object)val2 == (Object)null)
									{
										EOSLogger.Error("Could not get main path bulkhead door prefab: defaulting back to a normal bulkhead door! (You're Complex Resource Set probably don't have the main path bulkhead door references set).");
										val2 = Builder.ComplexResourceSetBlock.GetBulkheadGate(__instance.m_gate.Type, num, (SubComplex)5);
									}
								}
								else
								{
									ComplexResourceSetDataBlock complexResourceSetBlock = Builder.ComplexResourceSetBlock;
									LG_GateType type2 = __instance.m_gate.Type;
									seed = __instance.m_rnd.Seed;
									val2 = complexResourceSetBlock.GetBulkheadGate(type2, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5);
								}
							}
							else if (__instance.m_gate.ForceApexGate)
							{
								ComplexResourceSetDataBlock complexResourceSetBlock2 = Builder.ComplexResourceSetBlock;
								LG_GateType type3 = __instance.m_gate.Type;
								seed = __instance.m_rnd.Seed;
								val2 = complexResourceSetBlock2.GetApexGate(type3, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5);
							}
							else if (__instance.m_gate.ForceSecurityGate)
							{
								ComplexResourceSetDataBlock complexResourceSetBlock3 = Builder.ComplexResourceSetBlock;
								LG_GateType type4 = __instance.m_gate.Type;
								seed = __instance.m_rnd.Seed;
								val2 = complexResourceSetBlock3.GetSecurityGate(type4, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5);
							}
							else if (((LG_ZoneExpander)__instance.m_gate).m_isZoneSource)
							{
								__instance.m_gate.IsCheckpointDoor = forceConnect.Cfg.Setting.IsCheckpointDoor;
								LG_Layer val3 = default(LG_Layer);
								LG_Layer val4 = default(LG_Layer);
								if (((LG_ZoneExpander)__instance.m_gate).IsLayerSource(ref val3, ref val4))
								{
									ComplexResourceSetDataBlock complexResourceSetBlock4 = Builder.ComplexResourceSetBlock;
									LG_GateType type5 = __instance.m_gate.Type;
									seed = __instance.m_rnd.Seed;
									val2 = complexResourceSetBlock4.GetBulkheadGate(type5, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5);
								}
								else
								{
									switch (forceConnect.Cfg.Setting.SecurityGateToEnter)
									{
									case GateType.Apex:
									{
										ComplexResourceSetDataBlock complexResourceSetBlock7 = Builder.ComplexResourceSetBlock;
										LG_GateType type8 = __instance.m_gate.Type;
										seed = __instance.m_rnd.Seed;
										val2 = complexResourceSetBlock7.GetApexGate(type8, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5);
										break;
									}
									case GateType.Security:
									{
										ComplexResourceSetDataBlock complexResourceSetBlock6 = Builder.ComplexResourceSetBlock;
										LG_GateType type7 = __instance.m_gate.Type;
										seed = __instance.m_rnd.Seed;
										val2 = complexResourceSetBlock6.GetSecurityGate(type7, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5);
										break;
									}
									default:
										if (forceConnect.Cfg.Setting.SecurityGateToEnter == GateType.Bulkhead_Main)
										{
											seed = __instance.m_rnd.Seed;
											uint num2 = ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random));
											val2 = Builder.ComplexResourceSetBlock.GetMainPathBulkheadGate(__instance.m_gate.Type, num2, (SubComplex)5);
											if ((Object)(object)val2 == (Object)null)
											{
												EOSLogger.Error("Could not get main path bulkhead door prefab: defaulting back to a normal bulkhead door! (You're Complex Resource Set probably don't have the main path bulkhead door references set).");
												val2 = Builder.ComplexResourceSetBlock.GetBulkheadGate(__instance.m_gate.Type, num2, (SubComplex)5);
											}
										}
										else
										{
											ComplexResourceSetDataBlock complexResourceSetBlock5 = Builder.ComplexResourceSetBlock;
											LG_GateType type6 = __instance.m_gate.Type;
											seed = __instance.m_rnd.Seed;
											val2 = complexResourceSetBlock5.GetBulkheadGate(type6, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5);
										}
										break;
									}
								}
							}
							else
							{
								ComplexResourceSetDataBlock complexResourceSetBlock8 = Builder.ComplexResourceSetBlock;
								LG_GateType type9 = __instance.m_gate.Type;
								seed = __instance.m_rnd.Seed;
								val2 = complexResourceSetBlock8.GetWeakGate(type9, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5);
							}
							Vector3 position = ((Component)__instance.m_gate).transform.position;
							Quaternion val5;
							if (__instance.m_plugWasFlipped || (int)((LG_ZoneExpander)__instance.m_gate).ExpanderRotation == 3)
							{
								val5 = Quaternion.LookRotation(((Component)__instance.m_gate).transform.forward * -1f, Vector3.up);
								__instance.m_gate.m_hasBeenFlipped = true;
							}
							else
							{
								val5 = ((Component)__instance.m_gate).transform.rotation;
								__instance.m_gate.m_hasBeenFlipped = false;
							}
							GameObject val6 = Object.Instantiate<GameObject>(val2, position, val5, ((Component)__instance.m_gate).transform);
							__instance.m_gate.SpawnedDoor = SetupDoor(__instance, val6, forceConnect);
							__instance.SetupSpawners(val6);
							__instance.ProcessDivider(val6, __instance.m_gate.m_hasBeenFlipped);
							Debug.DrawLine(((Component)__instance.m_gate).transform.position, ((LG_ZoneExpander)__instance.m_gate).m_linksFrom.Position, new Color(0f, 0.5f, 1f, 1f), 10000f, false);
							Debug.DrawLine(((Component)__instance.m_gate).transform.position, ((LG_ZoneExpander)__instance.m_gate).m_linksTo.Position, new Color(0f, 1f, 0.5f, 0.25f), 10000f, false);
							Debug.DrawRay(val6.transform.position, val6.transform.forward * 10f, new Color(0f, 1f, 0f, 1f), 10000f, false);
						}
						LG_Factory.InjectJob((LG_FactoryJob)new LG_LinkAIGateJob(__instance.m_gate), (BatchName)29);
						break;
					case 3:
						Debug.LogError(Object.op_Implicit("ERROR : Do we need to use this anymore?"));
						break;
					case 5:
					{
						__instance.m_gate.m_isTraversableFromStart = true;
						((LG_ZoneExpander)__instance.m_gate).m_wasProcessed = true;
						LG_Gate gate = __instance.m_gate;
						((Object)gate).name = ((Object)gate).name + " freePassage!";
						if (__instance.m_plugWasFlipped || (int)((LG_ZoneExpander)__instance.m_gate).ExpanderRotation == 3)
						{
							__instance.m_gate.m_hasBeenFlipped = true;
						}
						else
						{
							__instance.m_gate.m_hasBeenFlipped = false;
						}
						LG_Factory.InjectJob((LG_FactoryJob)new LG_LinkAIGateJob(__instance.m_gate), (BatchName)29);
						break;
					}
					}
				}
				__result = true;
				return false;
			}
			catch (Exception value)
			{
				EOSLogger.Error($"Exception occurred when building Gate: {value}");
				EOSLogger.Error("Falling back to vanilla");
				((LG_ZoneExpander)__instance.m_gate).m_wasProcessed = false;
				return true;
			}
		}

		private static iLG_Door_Core SetupDoor(LG_BuildGateJob __instance, GameObject doorGO, ForceConnect fc)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			iLG_Door_Core val = __instance.SetupDoor(doorGO);
			if (__instance.m_gate.ForceSecurityGate || __instance.m_gate.ForceApexGate || ((LG_ZoneExpander)__instance.m_gate).m_isZoneSource)
			{
				LG_SecurityDoor val2 = ((Il2CppObjectBase)val).Cast<LG_SecurityDoor>();
				if (((LG_ZoneExpander)__instance.m_gate).m_linksTo.m_zone.m_settings.m_zoneData.ChainedPuzzleToEnter == 0)
				{
					uint chainedPuzzleToEnter = fc.Cfg.Setting.ChainedPuzzleToEnter;
					if (chainedPuzzleToEnter != 0)
					{
						LG_Factory.InjectJob((LG_FactoryJob)new LG_BuildChainedPuzzleDoorLockJob(val2, chainedPuzzleToEnter), (BatchName)43);
					}
					else
					{
						LG_Factory.InjectJob((LG_FactoryJob)new LG_SimpleDoorLockJob(val2), (BatchName)43);
					}
				}
				if (fc.Cfg.Setting.IsCheckpointDoor)
				{
					LG_Factory.InjectJob((LG_FactoryJob)new LG_CheckpointScannerJob(val2), (BatchName)43);
				}
				if (fc.Cfg.Setting.ActiveEnemyWave.HasActiveEnemyWave)
				{
					val2.SetupActiveEnemyWaveData(fc.Cfg.Setting.ActiveEnemyWave);
				}
			}
			return val;
		}
	}
}
namespace EOSExt.ExtraDoor.Patches.SetupDoor
{
	[HarmonyPatch]
	internal static class ChainedPuzzles
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(LG_BuildChainedPuzzleDoorLockJob), "Build")]
		private static bool Pre_(LG_BuildChainedPuzzleDoorLockJob __instance, ref bool __result)
		{
			try
			{
				LG_SecurityDoor door = ((LG_BuildSecurityDoorLockJob)__instance).m_door;
				ForceConnect fC = ((LG_BuildSecurityDoorLockJob)__instance).m_door.GetFC();
				if ((Object)(object)fC == (Object)null)
				{
					return true;
				}
				((LG_BuildSecurityDoorLockJob)__instance).CheckFlip();
				((Object)door).name = ((Object)door).name + "_ChainedPuzzleLock";
				uint chainedPuzzleToEnter = fC.Cfg.Setting.ChainedPuzzleToEnter;
				if (chainedPuzzleToEnter != 0)
				{
					door.SetupChainedPuzzleLock(chainedPuzzleToEnter);
				}
				__result = true;
				return false;
			}
			catch (Exception value)
			{
				EOSLogger.Error($"Exception occurred when building ChainedPuzzleDoorLock: {value}");
				EOSLogger.Error("Falling back to vanilla");
				return true;
			}
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(LG_SecurityDoor), "SetupChainedPuzzleLock")]
		private static bool Pre_SetupCPLock(LG_SecurityDoor __instance, uint puzzleDataId)
		{
			//IL_004b: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			ForceConnect fC = __instance.GetFC();
			if ((Object)(object)fC == (Object)null)
			{
				return true;
			}
			ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(puzzleDataId);
			Vector3 val = default(Vector3);
			if (__instance.GetChainedPuzzleStartPosition(ref val))
			{
				ChainedPuzzleInstance val2 = ChainedPuzzleManager.CreatePuzzleInstance(block, ((LG_ZoneExpander)__instance.Gate).m_linksFrom, ((LG_ZoneExpander)__instance.Gate).m_linksTo, val, ((Component)__instance).transform, false);
				eDoorStatus status = __instance.m_locks.SetupForChainedPuzzle(val2);
				__instance.m_sync.SetStateUnsynced(new pDoorState
				{
					status = status,
					damageTaken = 0f
				});
				if (block.ChainedPuzzle.Count == 0)
				{
					__instance.SetupInstantOpeningDoor();
				}
				if (block.TriggerAlarmOnActivate)
				{
					__instance.m_graphics.OnDoorState(new pDoorState
					{
						status = (eDoorStatus)4
					}, false);
					__instance.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)9);
					return false;
				}
				__instance.m_graphics.OnDoorState(new pDoorState
				{
					status = (eDoorStatus)5
				}, false);
			}
			return false;
		}
	}
}
namespace EOSExt.ExtraDoor.Patches.DisableAlarmShutdownOnTerminal
{
	[HarmonyPatch]
	internal static class BuildJob_AlarmShutdownOnTerminalJob
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_AlarmShutdownOnTerminalJob), "Build")]
		private static bool Pre_(LG_AlarmShutdownOnTerminalJob __instance)
		{
			return (Object)(object)__instance.m_securityDoor.GetFC() == (Object)null;
		}
	}
	[HarmonyPatch]
	internal static class DoorLock_OnDoorState
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(LG_SecurityDoor_Locks), "OnDoorState")]
		private static bool Pre_(LG_SecurityDoor_Locks __instance, pDoorState state)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.m_door == (Object)null || (int)state.status != 4)
			{
				return true;
			}
			ForceConnect fC = __instance.m_door.GetFC();
			if ((Object)(object)fC == (Object)null)
			{
				return true;
			}
			((Interact_Base)__instance.m_intUseKeyItem).SetActive(false);
			((Interact_Base)__instance.m_intHack).SetActive(false);
			((Interact_Base)__instance.m_intOpenDoor).SetActive(true);
			__instance.m_intOpenDoor.InteractionMessage = Text.Format(840u, (Object[])(object)new Object[1] { Object.op_Implicit(__instance.ChainedPuzzleToSolve.Data.PublicAlarmName) });
			((Interact_Base)__instance.m_intCustomMessage).SetActive(false);
			__instance.m_lastStatus = state.status;
			return false;
		}
	}
}
namespace EOSExt.ExtraDoor.Config
{
	public class Door
	{
		public LG_LayerType Layer { get; set; }

		public eLocalZoneIndex LocalIndex { get; set; }

		public int AreaIndex { get; set; } = 0;
	}
	public class DoorSetting
	{
		public GateType SecurityGateToEnter { get; set; }

		public List<LevelEventData> EventsOnEnter { get; set; } = new List<LevelEventData>();

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

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

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

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

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

		public FCProgressionPuzzleToEnter ProgressionPuzzleToEnter { get; set; } = new FCProgressionPuzzleToEnter();

		public uint ChainedPuzzleToEnter { get; set; }

		public bool IsCheckpointDoor { get; set; } = false;

		public bool PlayScannerVoiceAudio { get; set; } = true;

		public ActiveEnemyWaveData ActiveEnemyWave { get; set; } = new ActiveEnemyWaveData();
	}
	public class FCZonePlacementData : GlobalZoneIndex
	{
		public ZonePlacementWeights Weights { get; set; } = new ZonePlacementWeights();
	}
	public class FCProgressionPuzzleToEnter
	{
		public eProgressionPuzzleType PuzzleType { get; set; }

		public LocalizedText CustomText { get; set; } = null;

		public int PlacementCount { get; set; } = 1;

		public List<FCZonePlacementData> ZonePlacementData { get; set; } = new List<FCZonePlacementData>
		{
			new FCZonePlacementData()
		};
	}
	public enum GateType
	{
		Security,
		Apex,
		Bulkhead,
		Bulkhead_Main
	}
	public class ForceConnectCfg
	{
		public string WorldEventObjectFilter { get; set; } = string.Empty;

		public eDimensionIndex DimensionIndex { get; set; }

		public Door From { get; set; } = new Door();

		public int FromDoorIndex { get; set; } = 0;

		public Door To { get; set; } = new Door();

		public DoorSetting Setting { get; set; } = new DoorSetting();
	}
}

plugins/Inas07.EOSExt.LevelSpawnedSentry.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AIGraph;
using AK;
using Agents;
using AmorLib.Networking.StateReplicators;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using EOSExt.LevelSpawnedSentry.Definition;
using EOSExt.LevelSpawnedSentry.Impl;
using EOSExt.LevelSpawnedSentry.PlayerGUIMessage;
using ExtraObjectiveSetup;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Utils;
using FX_EffectSystem;
using GTFO.API;
using GameData;
using GameEvent;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using TenChambers.EventHandlers;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.LevelSpawnedSentry
{
	public class LevelSpawnedSentryManager : GenericExpeditionDefinitionManager<LevelSpawnedSentryDefinition>
	{
		public enum LSS_WardenEvents
		{
			ChangeLSSState = 910
		}

		public static LevelSpawnedSentryManager Current { get; private set; }

		protected override string DEFINITION_NAME => "LevelSpawnedSentry";

		private Dictionary<string, LSS> LSSDict { get; } = new Dictionary<string, LSS>();

		internal List<LSS> LSSInstances { get; } = new List<LSS>();

		private void PrepareForBuild()
		{
			Clear();
			if (!base.definitions.TryGetValue(base.CurrentMainLevelLayout, out var value))
			{
				return;
			}
			for (int i = 0; i < value.Definitions.Count; i++)
			{
				LevelSpawnedSentryDefinition levelSpawnedSentryDefinition = value.Definitions[i];
				LSS lSS = LSS.Instantiate(levelSpawnedSentryDefinition, i);
				LSSInstances.Add(lSS);
				if (LSSDict.ContainsKey(levelSpawnedSentryDefinition.WorldEventObjectFilter))
				{
					EOSLogger.Warning("LevelSpawnSentry: found duplicate WorldEventObjectFilter '" + levelSpawnedSentryDefinition.WorldEventObjectFilter + "'");
				}
				LSSDict[levelSpawnedSentryDefinition.WorldEventObjectFilter] = lSS;
			}
		}

		private void Clear()
		{
			LSSInstances.ForEach(delegate(LSS i)
			{
				i.Destroy();
			});
			LSSInstances.Clear();
			LSSDict.Clear();
		}

		private LevelSpawnedSentryManager()
		{
			LevelAPI.OnBuildStart += PrepareForBuild;
			LevelAPI.OnLevelCleanup += Clear;
		}

		static LevelSpawnedSentryManager()
		{
			Current = new LevelSpawnedSentryManager();
			EOSWardenEventManager.Current.AddEventDefinition(LSS_WardenEvents.ChangeLSSState.ToString(), 910u, (Action<WardenObjectiveEventData>)ChangeLSSState);
		}

		private static void ChangeLSSState(WardenObjectiveEventData e)
		{
			if (!Current.LSSDict.TryGetValue(e.WorldEventObjectFilter, out var value))
			{
				EOSLogger.Error("ChangeLSSState: Cannot find LSS with name '" + e.WorldEventObjectFilter + "'");
			}
			else if (SNet.IsMaster)
			{
				bool targetEnemy = e.EnemyID == 0;
				bool targetPlayer = e.SustainedEventSlotIndex > 0;
				bool markerVisible = e.Count == 0;
				bool canRefill = e.FogSetting == 0;
				LSSSyncState lSSSyncState = new LSSSyncState(value.State);
				lSSSyncState.Enabled = e.Enabled;
				lSSSyncState.TargetEnemy = targetEnemy;
				lSSSyncState.TargetPlayer = targetPlayer;
				lSSSyncState.MarkerVisible = markerVisible;
				lSSSyncState.CanRefill = canRefill;
				lSSSyncState.Ammo = value.LSSComp.Sentry.Ammo;
				LSSSyncState state = lSSSyncState;
				value.StateReplicator.SetState(state);
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.EOSExt.LevelSpawnedSentry", "EOSExt.LevelSpawnedSentry", "1.2.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.LevelSpawnedSentry";

		public const string VERSION = "1.2.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			SetupManagers();
			m_Harmony = new Harmony("EOSExt.LevelSpawnedSentry");
			m_Harmony.PatchAll();
			EOSLogger.Log("ExtraObjectiveSetup.LevelSpawnedSentry loaded.");
		}

		private void SetupManagers()
		{
			((GenericExpeditionDefinitionManager<LevelSpawnedSentryDefinition>)LevelSpawnedSentryManager.Current).Init();
		}
	}
	public class LSS
	{
		public static readonly Color OffColor;

		public static readonly Color TargetBothColor;

		public static readonly Color TargetPlayerOnlyColor;

		public static readonly Color TargetEnemyOnlyColor;

		public static readonly Color DoesNotTargetColor;

		public const string PUBLIC_NAME_PREFIX = "E0$L$$";

		private const float SYNC_ALL_IN = 15f;

		private static Coroutine s_syncLSSAmmoCoroutine;

		private LSSTargeted m_LSSTargeted = new LSSTargeted();

		public const string LSS_SYNC_EVT = "LSS_SYNC_EVT";

		public LevelSpawnedSentryDefinition Def { get; }

		public int InstanceIndex { get; }

		public LSSSyncState State => StateReplicator?.State ?? default(LSSSyncState);

		internal StateReplicator<LSSSyncState> StateReplicator { get; private set; }

		public LSSComp LSSComp { get; private set; }

		public int LastSyncedTargetedPlayer => m_LSSTargeted.PlayerSlotIndex;

		public static Color GetScanningColor(bool targetEnemy, bool targetPlayer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Color val = Color.grey * 0.5f;
			if (targetEnemy && targetPlayer)
			{
				return TargetBothColor;
			}
			if (targetEnemy && !targetPlayer)
			{
				return TargetEnemyOnlyColor;
			}
			if (!targetEnemy && targetPlayer)
			{
				return TargetPlayerOnlyColor;
			}
			return DoesNotTargetColor;
		}

		public static string GetMarkerText(bool targetEnemy, bool targetPlayer)
		{
			string empty = string.Empty;
			string empty2 = string.Empty;
			if (targetEnemy && targetPlayer)
			{
				empty = "LSS.State.Both";
				empty2 = "HAVOC";
			}
			else if (targetEnemy && !targetPlayer)
			{
				empty = "LSS.State.Normal";
				empty2 = "NORMAL";
			}
			else if (!targetEnemy && targetPlayer)
			{
				empty = "LSS.State.Player";
				empty2 = "HOSTILE";
			}
			else
			{
				empty = "LSS.State.Idle";
				empty2 = "IDLE";
			}
			TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock(empty);
			return (block != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID) : empty2;
		}

		internal void AssignInstance(LSSComp comp)
		{
			if (!comp.IsSetup)
			{
				EOSLogger.Error("LSS: Assigning to LSS '" + comp.Def.WorldEventObjectFilter + "' an un-setup LSSComp!");
				return;
			}
			bool flag = (Object)(object)LSSComp != (Object)null;
			if (flag)
			{
				EOSLogger.Warning("LSS: re-assigning LSSComp to '" + comp.Def.WorldEventObjectFilter + "'!");
			}
			LSSComp = comp;
			if (flag)
			{
				OnStateChanged(State, State, isRecall: false);
			}
		}

		internal void SetupReplicator()
		{
			if (StateReplicator != null)
			{
				return;
			}
			LevelSpawnedSentryDefinition def = Def;
			uint num = EOSNetworking.AllotReplicatorID();
			if (num != 0)
			{
				LSSSyncState lSSSyncState = new LSSSyncState(def.InitialState);
				lSSSyncState.Ammo = def.InitialAmmo;
				LSSSyncState lSSSyncState2 = lSSSyncState;
				StateReplicator = StateReplicator<LSSSyncState>.Create(num, lSSSyncState2, (LifeTimeType)1, (IStateReplicatorHolder<LSSSyncState>)null);
				StateReplicator.OnStateChanged += OnStateChanged;
				if (SNet.IsMaster)
				{
					StateReplicator.SetState(lSSSyncState2);
				}
			}
		}

		private void OnStateChanged(LSSSyncState oldState, LSSSyncState newState, bool isRecall)
		{
			if (isRecall)
			{
				EOSLogger.Warning("LSS.OnStateChanged recall! Gonna re-assign LSSComp!");
				SpawnLSS_OnRecall();
			}
			else if ((Object)(object)LSSComp == (Object)null)
			{
				EOSLogger.Error("LSS.OnStateChanged: LSSComp is null!");
			}
			else
			{
				LSSComp.OnStateChanged(oldState, newState, isRecall);
			}
		}

		internal void Destroy()
		{
			EOSLogger.Error("LSS Destroyed: " + Def.WorldEventObjectFilter);
			LevelAPI.OnBuildDone -= SetupReplicator;
			LevelAPI.OnEnterLevel -= SpawnLSS_OnEnterLevel;
			StateReplicator?.Unload();
			StateReplicator = null;
		}

		private void SpawnLSS_OnEnterLevel()
		{
			SpawnLSS(Def.InitialAmmo);
		}

		private void SpawnLSS_OnRecall()
		{
			SpawnLSS(State.Ammo);
		}

		private void SpawnLSS(float ammo)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster)
			{
				return;
			}
			LevelSpawnedSentryDefinition def = Def;
			Vector3 val = def.Position.ToVector3();
			AIG_GeomorphNodeVolume val2 = default(AIG_GeomorphNodeVolume);
			AIG_VoxelNodePillar val3 = default(AIG_VoxelNodePillar);
			AIG_INode val4 = default(AIG_INode);
			AIG_NodeCluster val5 = default(AIG_NodeCluster);
			if (!AIG_GeomorphNodeVolume.TryGetGeomorphVolume(0, def.DimensionIndex, val, ref val2) || !((AIG_NodeVolume)val2).m_voxelNodeVolume.TryGetPillar(val, ref val3) || !val3.TryGetVoxelNode(val.y, ref val4) || !AIG_NodeCluster.TryGetNodeCluster(val4.ClusterID, ref val5))
			{
				EOSLogger.Error("SpawnLSS: Position is not valid, try again inside an area.");
				return;
			}
			AIG_CourseNode courseNode = val5.CourseNode;
			PlayerOfflineGearDataBlock block = GameDataBlockBase<PlayerOfflineGearDataBlock>.GetBlock(def.PlayerOfflineGearDBId);
			if (block == null)
			{
				EOSLogger.Error($"SpawnLSS: missing PlayerOfflineGearDataBlock with Id {def.PlayerOfflineGearDBId}");
				return;
			}
			GearIDRange val6 = new GearIDRange(block.GearJSON);
			val6.PublicGearName = $"{"E0$L$$"}_{InstanceIndex}";
			val6.PlayfabItemId = ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).name;
			val6.PlayfabItemInstanceId = $"OfflineGear_LSS_ID_{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}";
			val6.OfflineGearType = (eOfflineGearType)3;
			ItemDataBlock val7 = ((val6.GetCompID((eGearComponent)3) != 0) ? GameDataBlockBase<ItemDataBlock>.GetBlock(val6.GetCompID((eGearComponent)3)) : null);
			ItemReplicationManager.SpawnGear(val6, (delItemCallback)null, (ItemMode)3, val, def.Rotation.ToQuaternion(), courseNode, (PlayerAgent)null, ammo, Def.AmmoCap);
		}

		private LSS(LevelSpawnedSentryDefinition def, int instanceIndex)
		{
			Def = def;
			InstanceIndex = instanceIndex;
		}

		internal static LSS Instantiate(LevelSpawnedSentryDefinition def, int instanceIndex)
		{
			LSS lSS = new LSS(def, instanceIndex);
			LevelAPI.OnBuildDone += lSS.SetupReplicator;
			LevelAPI.OnEnterLevel += lSS.SpawnLSS_OnEnterLevel;
			return lSS;
		}

		private static IEnumerator s_sync()
		{
			int i = 0;
			WaitForSeconds waitOutOfLevel = new WaitForSeconds(15f);
			WaitForSeconds waitInLevel = null;
			while (true)
			{
				if ((int)GameStateManager.CurrentStateName == 10)
				{
					if (SNet.IsMaster && LevelSpawnedSentryManager.Current.LSSInstances.Count > 0)
					{
						if (0 <= i && i < LevelSpawnedSentryManager.Current.LSSInstances.Count)
						{
							LSS instance = LevelSpawnedSentryManager.Current.LSSInstances[i];
							if ((Object)(object)instance.LSSComp == (Object)null)
							{
								EOSLogger.Error("LSSSync: found LSS without LSSComp: " + instance.Def.WorldEventObjectFilter);
							}
							else
							{
								SentryGunInstance sentry = instance.LSSComp.Sentry;
								if ((Object)(object)sentry != (Object)null)
								{
									LSSSyncState state = instance.StateReplicator.State;
									if ((double)Math.Abs(sentry.Ammo - state.Ammo) > 0.0001)
									{
										LSSSyncState syncState = new LSSSyncState(state)
										{
											Ammo = sentry.Ammo
										};
										instance.StateReplicator.SetState(syncState);
									}
								}
							}
						}
						if (i == LevelSpawnedSentryManager.Current.LSSInstances.Count - 1)
						{
							EOSLogger.Debug($"LSS: master synced {LevelSpawnedSentryManager.Current.LSSInstances.Count} in {15f} seconds");
						}
						i = (i + 1) % LevelSpawnedSentryManager.Current.LSSInstances.Count;
					}
					if (waitInLevel == null)
					{
						waitInLevel = new WaitForSeconds(15f / (float)Math.Max(1, LevelSpawnedSentryManager.Current.LSSInstances.Count));
					}
					yield return waitInLevel;
				}
				else
				{
					waitInLevel = null;
					yield return waitOutOfLevel;
				}
			}
		}

		static LSS()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			OffColor = ColorExt.Hex("#00000000");
			TargetBothColor = ColorExt.Hex("FFFA00");
			TargetPlayerOnlyColor = ColorExt.Hex("#F0192EFF");
			TargetEnemyOnlyColor = ColorExt.Hex("#00895CFF");
			DoesNotTargetColor = ColorExt.Hex("#198AF0FF") * 0.5f;
			s_syncLSSAmmoCoroutine = null;
			SetupSync();
			s_syncLSSAmmoCoroutine = CoroutineManager.StartPersistantCoroutine(CollectionExtensions.WrapToIl2Cpp(s_sync()));
			EOSLogger.Debug("===========================");
			EOSLogger.Debug("LSS Sync coroutine started");
			EOSLogger.Debug("===========================");
		}

		internal void OnTargetedPlayer(PlayerAgent player)
		{
			m_LSSTargeted.PlayerSlotIndex = ((player != null) ? player.Owner.PlayerSlotIndex() : (-1));
		}

		internal void OnUpdateMaster()
		{
			m_LSSTargeted.LSSInstanceIndex = InstanceIndex;
			NetworkAPI.InvokeEvent<LSSTargeted>("LSS_SYNC_EVT", m_LSSTargeted, (SNet_ChannelType)2);
		}

		private static void OnReceive(ulong sender, LSSTargeted data)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			int lSSInstanceIndex = data.LSSInstanceIndex;
			if (lSSInstanceIndex < 0 || lSSInstanceIndex >= LevelSpawnedSentryManager.Current.LSSInstances.Count)
			{
				EOSLogger.Error($"LSS_OnReceive: got packet with invalid instance index {lSSInstanceIndex}, LSSCount: {LevelSpawnedSentryManager.Current.LSSInstances.Count}, CurrentGameState: {GameStateManager.CurrentStateName}");
			}
			else
			{
				LSS lSS = LevelSpawnedSentryManager.Current.LSSInstances[lSSInstanceIndex];
				lSS.m_LSSTargeted.PlayerSlotIndex = data.PlayerSlotIndex;
				EOSLogger.Warning($"LSSSync.OnReceive: LSS_{lSSInstanceIndex}, Player_{data.PlayerSlotIndex}");
			}
		}

		private static void SetupSync()
		{
			NetworkAPI.RegisterEvent<LSSTargeted>("LSS_SYNC_EVT", (Action<ulong, LSSTargeted>)OnReceive);
			EOSLogger.Debug("===========================");
			EOSLogger.Debug("LSSTargeted Sync EVT Registered");
			EOSLogger.Debug("===========================");
		}
	}
	[HarmonyPatch]
	public static class LSSDebug
	{
	}
}
namespace EOSExt.LevelSpawnedSentry.PlayerGUIMessage
{
	public class PlayerGUIMessageManager
	{
		private PUI_ObjectiveTimer m_timerLayer;

		private ISet<int> m_targetedByLSS = new HashSet<int>();

		public static PlayerGUIMessageManager Current { get; }

		public static PlayerGuiLayer PlayerGUILayer => GuiManager.PlayerLayer;

		internal void Setup(Transform root)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			m_timerLayer = ((Il2CppObjectBase)((GuiLayer)PlayerGUILayer).AddComp("Gui/Player/PUI_ObjectiveTimer", (GuiAnchor)0, new Vector2(0f, -200f), (Transform)null)).Cast<PUI_ObjectiveTimer>();
		}

		internal void OnLocalPlayerTargeted(LSS sentry)
		{
			m_targetedByLSS.Add(sentry.InstanceIndex);
			if (m_targetedByLSS.Count > 0 && !((Component)m_timerLayer).gameObject.active)
			{
				TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("LSS.OnPlayerTargeted.GUIText");
				SetText((block != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID) : "<color=red>OMG IM SO FKING DEAD</color>");
			}
		}

		internal void OnLocalPlayerUnTargeted(LSS sentry)
		{
			m_targetedByLSS.Remove(sentry.InstanceIndex);
			if (m_targetedByLSS.Count == 0)
			{
				Clear();
			}
		}

		public void SetText(string text)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			((Component)m_timerLayer).gameObject.active = true;
			m_timerLayer.UpdateTimerTitle(text);
			if ((int)GameStateManager.CurrentStateName == 10)
			{
				CoroutineManager.BlinkIn(((Component)m_timerLayer.m_titleText).gameObject, 0f);
			}
		}

		public void Clear()
		{
			((Component)m_timerLayer).gameObject.active = false;
			m_timerLayer.SetTimerTextEnabled(false);
		}

		private void OnLevelCleanup()
		{
			Clear();
			m_targetedByLSS.Clear();
		}

		private PlayerGUIMessageManager()
		{
			LevelAPI.OnBuildStart += OnLevelCleanup;
			LevelAPI.OnLevelCleanup += OnLevelCleanup;
		}

		static PlayerGUIMessageManager()
		{
			Current = new PlayerGUIMessageManager();
		}
	}
}
namespace EOSExt.LevelSpawnedSentry.Patches
{
	[HarmonyPatch]
	internal static class DisableAnalytic
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(AnalyticsManager), "SentryEventsPayload")]
		private static bool Pre_(SentryGunInstance __instance)
		{
			return (Object)(object)__instance != (Object)null && (Object)(object)((Item)__instance).Owner != (Object)null;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SentryPlaced), "OnGameEvent")]
		private static bool Pre_(GameEventData data)
		{
			return (Object)(object)data.player != (Object)null;
		}
	}
	[HarmonyPatch]
	internal static class DisableWarp
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(SentryGunInstance), "OnWarp")]
		private static bool Pre_(SentryGunInstance __instance)
		{
			return (Object)(object)((Component)__instance).gameObject.GetComponent<LSSComp>() == (Object)null;
		}
	}
	[HarmonyPatch]
	internal static class Firing
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "FireBullet")]
		private static bool Pre_FireBullet(SentryGunInstance_Firing_Bullets __instance, bool doDamage, bool targetIsTagged)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00a1: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			iSentrygunInstanceCore core = __instance.m_core;
			SentryGunInstance val = ((core != null) ? ((Il2CppObjectBase)core).TryCast<SentryGunInstance>() : null);
			LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null);
			if ((Object)(object)lSSComp == (Object)null)
			{
				return true;
			}
			LSSSyncState state = lSSComp.LSS.State;
			WeaponHitData val2 = (SentryGunInstance_Firing_Bullets.s_weaponRayData = new WeaponHitData
			{
				randomSpread = __instance.m_archetypeData.HipFireSpread,
				fireDir = __instance.MuzzleAlign.forward
			});
			Vector3 val4 = default(Vector3);
			if (__instance.m_archetypeData.Sentry_FireTowardsTargetInsteadOfForward && __instance.m_core.TryGetTargetAimPos(ref val4))
			{
				WeaponHitData s_weaponRayData = SentryGunInstance_Firing_Bullets.s_weaponRayData;
				Vector3 val5 = val4 - __instance.MuzzleAlign.position;
				s_weaponRayData.fireDir = ((Vector3)(ref val5)).normalized;
			}
			if (Weapon.CastWeaponRay(__instance.MuzzleAlign, ref val2, LayerManager.MASK_SENTRYGUN_RAY))
			{
				SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = __instance.m_core.Owner;
				GameObject target = val.m_detection.Target;
				PlayerAgent val6 = ((target != null) ? target.GetComponent<PlayerAgent>() : null);
				if (val.m_detection.HasTarget && (Object)(object)val6 != (Object)null)
				{
					SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = val.m_detection.Target.GetComponent<PlayerAgent>();
				}
				else
				{
					SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = LocalPlayer.Agent;
				}
				SentryGunInstance_Firing_Bullets.s_weaponRayData.damage = (targetIsTagged ? (__instance.m_archetypeData.Damage * __instance.m_archetypeData.Sentry_DamageTagMulti) : __instance.m_archetypeData.Damage);
				SentryGunInstance_Firing_Bullets.s_weaponRayData.staggerMulti = __instance.m_archetypeData.GetSentryStaggerDamage(targetIsTagged);
				SentryGunInstance_Firing_Bullets.s_weaponRayData.precisionMulti = __instance.m_archetypeData.PrecisionDamageMulti;
				SentryGunInstance_Firing_Bullets.s_weaponRayData.damageFalloff = __instance.m_archetypeData.DamageFalloff;
				SentryGunInstance_Firing_Bullets.s_weaponRayData.vfxBulletHit = __instance.m_vfxBulletHit;
				BulletWeapon.BulletHit(SentryGunInstance_Firing_Bullets.s_weaponRayData, doDamage, 0f, 0u, true);
				RaycastHit rayHit = SentryGunInstance_Firing_Bullets.s_weaponRayData.rayHit;
				FX_Manager.EffectTargetPosition = ((RaycastHit)(ref rayHit)).point;
				Vector3 position = __instance.MuzzleAlign.position;
				rayHit = SentryGunInstance_Firing_Bullets.s_weaponRayData.rayHit;
				Debug.DrawLine(position, ((RaycastHit)(ref rayHit)).point, Color.yellow);
			}
			else
			{
				FX_Manager.EffectTargetPosition = __instance.MuzzleAlign.position + __instance.MuzzleAlign.forward * 50f;
				Debug.DrawLine(__instance.MuzzleAlign.position, __instance.MuzzleAlign.position + __instance.MuzzleAlign.forward * 10f, Color.green);
			}
			Action onBulletFired = __instance.OnBulletFired;
			if (onBulletFired != null)
			{
				onBulletFired.Invoke();
			}
			((FX_EffectBase)SentryGunInstance_Firing_Bullets.s_tracerPool.AquireEffect()).Play((FX_Trigger)null, __instance.MuzzleAlign.position, Quaternion.LookRotation(SentryGunInstance_Firing_Bullets.s_weaponRayData.fireDir));
			EX_SpriteMuzzleFlash muzzleFlash = __instance.m_muzzleFlash;
			if ((Object)(object)muzzleFlash != (Object)null)
			{
				muzzleFlash.Play();
			}
			WeaponShellManager.EjectShell((ShellTypes)3, 1f, (float)Random.RandomRangeInt(3, 5), __instance.ShellEjectAlign);
			__instance.m_fireBulletTimer = Clock.Time + __instance.m_archetypeData.GetSentryShotDelay(__instance.m_core.Owner, targetIsTagged);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "UpdateFireShotgunSemi")]
		private static bool Pre_UpdateFireShotgunSemi(SentryGunInstance_Firing_Bullets __instance, bool isMaster, bool targetIsTagged)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			iSentrygunInstanceCore core = __instance.m_core;
			SentryGunInstance val = ((core != null) ? ((Il2CppObjectBase)core).TryCast<SentryGunInstance>() : null);
			LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null);
			if ((Object)(object)lSSComp == (Object)null)
			{
				return true;
			}
			LSSSyncState state = lSSComp.LSS.State;
			if (Clock.Time > __instance.m_fireBulletTimer)
			{
				Vector3 position = __instance.MuzzleAlign.position;
				__instance.TriggerSingleFireAudio();
				for (int i = 0; i < __instance.m_archetypeData.ShotgunBulletCount; i++)
				{
					float num = __instance.m_segmentSize * (float)i;
					float num2 = 0f;
					float num3 = 0f;
					if (i > 0)
					{
						num2 += (float)__instance.m_archetypeData.ShotgunConeSize * Mathf.Cos(num);
						num3 += (float)__instance.m_archetypeData.ShotgunConeSize * Mathf.Sin(num);
					}
					WeaponHitData val2 = (SentryGunInstance_Firing_Bullets.s_weaponRayData = new WeaponHitData
					{
						maxRayDist = __instance.MaxRayDist,
						angOffsetX = num2,
						angOffsetY = num3,
						randomSpread = __instance.m_archetypeData.ShotgunBulletSpread,
						fireDir = __instance.MuzzleAlign.forward
					});
					if (Weapon.CastWeaponRay(__instance.MuzzleAlign, ref val2, position, LayerManager.MASK_SENTRYGUN_RAY))
					{
						SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = __instance.m_core.Owner;
						GameObject target = val.m_detection.Target;
						PlayerAgent val4 = ((target != null) ? target.GetComponent<PlayerAgent>() : null);
						if (val.m_detection.HasTarget && (Object)(object)val4 != (Object)null)
						{
							SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = val.m_detection.Target.GetComponent<PlayerAgent>();
						}
						else
						{
							SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = LocalPlayer.Agent;
						}
						SentryGunInstance_Firing_Bullets.s_weaponRayData.damage = (targetIsTagged ? (__instance.m_archetypeData.Damage * __instance.m_archetypeData.Sentry_DamageTagMulti) : __instance.m_archetypeData.Damage);
						SentryGunInstance_Firing_Bullets.s_weaponRayData.staggerMulti = __instance.m_archetypeData.GetSentryStaggerDamage(targetIsTagged);
						SentryGunInstance_Firing_Bullets.s_weaponRayData.precisionMulti = __instance.m_archetypeData.PrecisionDamageMulti;
						SentryGunInstance_Firing_Bullets.s_weaponRayData.damageFalloff = __instance.m_archetypeData.DamageFalloff;
						BulletWeapon.BulletHit(SentryGunInstance_Firing_Bullets.s_weaponRayData, isMaster, 0f, 0u, true);
						RaycastHit rayHit = SentryGunInstance_Firing_Bullets.s_weaponRayData.rayHit;
						FX_Manager.EffectTargetPosition = ((RaycastHit)(ref rayHit)).point;
					}
					else
					{
						FX_Manager.EffectTargetPosition = __instance.MuzzleAlign.position + __instance.MuzzleAlign.forward * 50f;
					}
					FX_Manager.PlayLocalVersion = false;
					((FX_EffectBase)SentryGunInstance_Firing_Bullets.s_tracerPool.AquireEffect()).Play((FX_Trigger)null, __instance.MuzzleAlign.position, Quaternion.LookRotation(SentryGunInstance_Firing_Bullets.s_weaponRayData.fireDir));
				}
				__instance.UpdateAmmo(-1);
				Action onBulletFired = __instance.OnBulletFired;
				if (onBulletFired != null)
				{
					onBulletFired.Invoke();
				}
				__instance.m_fireBulletTimer = Clock.Time + (targetIsTagged ? (__instance.m_archetypeData.ShotDelay * __instance.m_archetypeData.Sentry_ShotDelayTagMulti) : __instance.m_archetypeData.ShotDelay);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class OnLSSSpawned
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SentryGunInstance), "OnSpawn")]
		private static void Post_(SentryGunInstance __instance, pGearSpawnData spawnData)
		{
			string data = spawnData.gearIDRange.publicName.data;
			if (data.StartsWith("E0$L$$"))
			{
				List<LSS> lSSInstances = LevelSpawnedSentryManager.Current.LSSInstances;
				if (!int.TryParse(data.Split('_')[1], out var result) || result < 0 || result >= lSSInstances.Count)
				{
					EOSLogger.Error("SentryGunInstance.OnSpawn: got publicName '" + data + "' with in valid instanceIndex");
					return;
				}
				LSS lSS = lSSInstances[result];
				LevelSpawnedSentryManager.Current.LSSInstances[result].AssignInstance(((Component)__instance).gameObject.AddComponent<LSSComp>().Setup(lSS));
				Interact_Timed val = ((Il2CppObjectBase)((Item)__instance).PickupInteraction).Cast<Interact_Timed>();
				((Behaviour)val).enabled = false;
				Dimension.RemoveWarpable(((Il2CppObjectBase)__instance).Cast<IWarpableObject>());
				EOSLogger.Warning("LSS OnSpawn: " + lSS.Def.WorldEventObjectFilter);
			}
		}
	}
	[HarmonyPatch]
	internal static class OnSetup
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SentryGunInstance), "CheckIsSetup")]
		private static void Post_CheckSetup(SentryGunInstance __instance)
		{
			LSSComp component = ((Component)__instance).gameObject.GetComponent<LSSComp>();
			if ((Object)(object)component != (Object)null)
			{
				EOSLogger.Warning("LSS CheckSetup: " + component.Def.WorldEventObjectFilter);
				component.UpdateVisuals();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SentryGunInstance_Detection), "Setup")]
		private static void Post_D_Setup(SentryGunInstance_Detection __instance)
		{
			SentryGunInstance obj = ((Il2CppObjectBase)__instance.m_core).TryCast<SentryGunInstance>();
			LSSComp lSSComp = ((obj != null) ? ((Component)obj).gameObject.GetComponent<LSSComp>() : null);
			if (!((Object)(object)lSSComp == (Object)null))
			{
				__instance.m_targetPlayers = lSSComp.LSS.State.TargetPlayer;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SentryGunInstance_ScannerVisuals_Plane), "Setup")]
		private static void Post_V_Setup(SentryGunInstance_ScannerVisuals_Plane __instance)
		{
			if ((Object)(object)__instance.m_scannerPlane == (Object)null || (Object)(object)__instance.m_targetingAlign == (Object)null)
			{
				EOSLogger.Error("SentryGunInstance_ScannerVisuals_Plane.Setup: got a null scannerPlane / targetingAlign?");
			}
			SentryGunInstance obj = ((Il2CppObjectBase)__instance.m_core).TryCast<SentryGunInstance>();
			LSSComp lSSComp = ((obj != null) ? ((Component)obj).gameObject.GetComponent<LSSComp>() : null);
			if (!((Object)(object)lSSComp == (Object)null))
			{
				lSSComp.UpdateVisuals();
			}
		}
	}
	[HarmonyPatch]
	internal static class OnPlayerGuiLayerSetup
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerGuiLayer), "Setup")]
		private static void Post_(PlayerGuiLayer __instance, Transform root, string name)
		{
			PlayerGUIMessageManager.Current.Setup(root);
		}
	}
	[HarmonyPatch]
	internal static class ReceiveToolRefill
	{
	}
	[HarmonyPatch]
	[HarmonyPatch]
	[HarmonyPatch]
	internal static class Targeting
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(SentryGunInstance_Sync), "UpdateMaster")]
		private static void Post_UpdateMaster(SentryGunInstance_Sync __instance)
		{
			if (!(Clock.Time - __instance.m_lastSyncTime <= 0.5f))
			{
				SentryGunInstance val = ((Il2CppObjectBase)__instance.m_core).TryCast<SentryGunInstance>();
				LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null);
				if (!((Object)(object)lSSComp == (Object)null))
				{
					lSSComp.LSS.OnUpdateMaster();
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(SentryGunInstance_Sync), "UpdateClient")]
		private static void Post_UpdateClient(SentryGunInstance_Sync __instance)
		{
			if (Clock.Time - __instance.m_lastSyncTime > __instance.m_syncTimeout)
			{
				SentryGunInstance val = ((Il2CppObjectBase)__instance.m_core).TryCast<SentryGunInstance>();
				LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null);
				if (!((Object)(object)lSSComp == (Object)null))
				{
					lSSComp.LSS.OnTargetedPlayer(null);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SentryGunInstance), "UpdateMaster")]
		private static void Post_UpdateMaster(SentryGunInstance __instance)
		{
			LSSComp lSSComp = ((__instance != null) ? ((Component)__instance).gameObject.GetComponent<LSSComp>() : null);
			if ((Object)(object)lSSComp == (Object)null)
			{
				return;
			}
			if (!lSSComp.LSS.State.Enabled || !lSSComp.LSS.State.TargetPlayer || !__instance.m_detection.HasTarget || (Object)(object)__instance.m_detection.Target == (Object)null)
			{
				PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS);
				lSSComp.LSS.OnTargetedPlayer(null);
				return;
			}
			PlayerAgent component = __instance.m_detection.Target.GetComponent<PlayerAgent>();
			if ((Object)(object)component == (Object)null)
			{
				PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS);
				lSSComp.LSS.OnTargetedPlayer(null);
				return;
			}
			if (((Agent)component).IsLocallyOwned)
			{
				PlayerGUIMessageManager.Current.OnLocalPlayerTargeted(lSSComp.LSS);
			}
			else
			{
				PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS);
			}
			lSSComp.LSS.OnTargetedPlayer(component);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SentryGunInstance), "UpdateClient")]
		private static void Post_UpdateClient(SentryGunInstance __instance)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			LSSComp lSSComp = ((__instance != null) ? ((Component)__instance).gameObject.GetComponent<LSSComp>() : null);
			if (!((Object)(object)lSSComp == (Object)null))
			{
				LocalPlayerAgent val = default(LocalPlayerAgent);
				if (!lSSComp.LSS.State.Enabled || !lSSComp.LSS.State.TargetPlayer || !__instance.m_sync.LastSyncData.hasTarget)
				{
					PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS);
				}
				else if (!LocalPlayer.TryGetLocalAgent(ref val))
				{
					EOSLogger.Error("Post_UpdateClient: Cannot get local player agent!");
				}
				else if (lSSComp.LSS.LastSyncedTargetedPlayer == ((PlayerAgent)val).Owner.PlayerSlotIndex())
				{
					PlayerGUIMessageManager.Current.OnLocalPlayerTargeted(lSSComp.LSS);
				}
				else
				{
					PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(SentryGunInstance), "WantToScan")]
		private static bool Pre_WantToScan(SentryGunInstance __instance, ref bool __result)
		{
			LSSComp component = ((Component)__instance).gameObject.GetComponent<LSSComp>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (!component.LSS.State.Enabled)
			{
				__result = false;
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(SentryGunInstance_Detection), "UpdateDetection")]
		private static bool Pre_UpdateDetection_OnlyTargetPlayer_Master(SentryGunInstance_Detection __instance)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			iSentrygunInstanceCore core = __instance.m_core;
			SentryGunInstance val = ((core != null) ? ((Il2CppObjectBase)core).TryCast<SentryGunInstance>() : null);
			LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null);
			if ((Object)(object)val == (Object)null || (Object)(object)lSSComp == (Object)null)
			{
				return true;
			}
			if (!lSSComp.LSS.State.Enabled)
			{
				PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS);
				return false;
			}
			if (lSSComp.LSS.State.TargetEnemy)
			{
				return true;
			}
			if (Clock.Time > __instance.m_scanningTimer)
			{
				Vector3 forward = ((Component)__instance.DetectionSource).transform.forward;
				Vector3 position = ((Component)__instance.DetectionSource).transform.position;
				if (__instance.m_core.Ammo >= __instance.m_core.CostOfBullet)
				{
					__instance.Target = null;
					__instance.TargetAimTrans = null;
					__instance.TargetIsTagged = false;
					if (__instance.m_targetPlayers)
					{
						PlayerAgent val2 = SentryGunInstance_Detection.CheckForPlayerTarget(__instance.m_archetypeData, __instance.DetectionSource, __instance.Target);
						if ((Object)(object)val2 != (Object)null)
						{
							__instance.Target = ((Component)val2).gameObject;
							__instance.TargetAimTrans = ((Agent)val2).TentacleTarget;
						}
					}
				}
				if ((Object)(object)__instance.Target != (Object)null)
				{
					Vector3 position2 = __instance.Target.transform.position;
					if (!__instance.HasTarget)
					{
						__instance.HasTarget = true;
						Action onFoundTarget = __instance.OnFoundTarget;
						if (onFoundTarget != null)
						{
							onFoundTarget.Invoke();
						}
					}
					Debug.DrawLine(position, position2);
				}
				else
				{
					__instance.HasTarget = false;
					__instance.TargetIsTagged = false;
				}
			}
			return false;
		}
	}
}
namespace EOSExt.LevelSpawnedSentry.Impl
{
	public class LSSComp : MonoBehaviour
	{
		public LSS LSS { get; private set; }

		public LevelSpawnedSentryDefinition Def => LSS.Def;

		public SentryGunInstance_ScannerVisuals_Plane Visuals => ((Component)this).gameObject.GetComponent<SentryGunInstance_ScannerVisuals_Plane>();

		public SentryGunInstance Sentry => ((Component)this).gameObject.GetComponent<SentryGunInstance>();

		public NavMarker marker { get; private set; }

		public bool IsSetup => LSS != null;

		internal LSSComp Setup(LSS lss)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!IsSetup)
			{
				LSS = lss;
				LevelSpawnedSentryDefinition def = Def;
				marker = GuiManager.NavMarkerLayer.PrepareGenericMarker(((Component)this).gameObject);
				if ((Object)(object)marker != (Object)null)
				{
					Color scanningColor = LSS.GetScanningColor(def.InitialState.TargetEnemy, def.InitialState.TargetPlayer);
					marker.SetStyle((eNavMarkerStyle)0);
					marker.SetColor(scanningColor);
					marker.SetVisible(def.InitialState.Enabled);
					marker.SetTitle(LSS.GetMarkerText(def.InitialState.TargetEnemy, def.InitialState.TargetPlayer));
				}
				UpdateVisuals();
				SetCanRefill(def.InitialState.CanRefill);
			}
			return this;
		}

		public void SetCanRefill(bool canRefill)
		{
			Sentry.AmmoMaxCap = (canRefill ? Def.AmmoCap : 0f);
		}

		internal void OnStateChanged(LSSSyncState oldState, LSSSyncState newState, bool isRecall)
		{
			EOSLogger.Debug($"LSSOnStateChanged \"{Def.WorldEventObjectFilter}\"! OldState: [{oldState}], NewState: {newState}");
			SentryGunInstance sentry = Sentry;
			if (newState.Enabled)
			{
				sentry.m_isSetup = true;
				sentry.m_isScanning = false;
				sentry.m_startScanTimer = Clock.Time + sentry.m_initialScanDelay;
				((ItemEquippable)sentry).Sound.Post(EVENTS.SENTRYGUN_LOW_AMMO_WARNING, true);
			}
			else
			{
				if (sentry.m_isFiring)
				{
					sentry.StopFiring();
				}
				if (sentry.m_isScanning)
				{
					sentry.StopScanning();
				}
				sentry.m_isSetup = false;
				((ItemEquippable)sentry).Sound.Post(EVENTS.SENTRYGUN_STOP_ALL_LOOPS, true);
			}
			iSentrygunInstance_Detection detection = sentry.m_detection;
			SentryGunInstance_Detection val = ((detection != null) ? ((Il2CppObjectBase)detection).TryCast<SentryGunInstance_Detection>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.m_targetPlayers = newState.TargetPlayer;
			}
			SetCanRefill(newState.CanRefill);
			UpdateVisuals();
		}

		internal void UpdateVisuals()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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)
			LSSSyncState state = LSS.State;
			SentryGunInstance_ScannerVisuals_Plane visuals = Visuals;
			Color color = (visuals.m_scanningColor = LSS.GetScanningColor(state.TargetEnemy, state.TargetPlayer));
			if (state.Enabled)
			{
				if (visuals.m_core != null)
				{
					visuals.SetVisualStatus((eSentryGunStatus)1, true);
				}
				if (state.MarkerVisible)
				{
					NavMarker obj = marker;
					if (obj != null)
					{
						obj.SetColor(color);
					}
					NavMarker obj2 = marker;
					if (obj2 != null)
					{
						obj2.SetVisible(true);
					}
					NavMarker obj3 = marker;
					if (obj3 != null)
					{
						obj3.SetTitle(LSS.GetMarkerText(state.TargetEnemy, state.TargetPlayer));
					}
				}
				else
				{
					NavMarker obj4 = marker;
					if (obj4 != null)
					{
						obj4.SetVisible(false);
					}
				}
			}
			else
			{
				if (visuals.m_core != null)
				{
					visuals.m_scannerPlane.SetColor(LSS.OffColor);
					visuals.UpdateLightProps(LSS.OffColor, false);
				}
				NavMarker obj5 = marker;
				if (obj5 != null)
				{
					obj5.SetVisible(false);
				}
			}
		}

		private void OnDestroy()
		{
			GuiManager.NavMarkerLayer.RemoveMarker(marker);
			marker = null;
		}

		static LSSComp()
		{
			ClassInjector.RegisterTypeInIl2Cpp<LSSComp>();
		}
	}
	public struct LSSTargeted
	{
		public int LSSInstanceIndex { get; set; }

		public int PlayerSlotIndex { get; set; }

		public LSSTargeted()
		{
			LSSInstanceIndex = -1;
			PlayerSlotIndex = -1;
		}

		public LSSTargeted(LSSTargeted o)
		{
			LSSInstanceIndex = -1;
			PlayerSlotIndex = -1;
			LSSInstanceIndex = o.LSSInstanceIndex;
			PlayerSlotIndex = o.PlayerSlotIndex;
		}
	}
}
namespace EOSExt.LevelSpawnedSentry.Definition
{
	public class LevelSpawnedSentryDefinition
	{
		public string WorldEventObjectFilter { get; set; } = string.Empty;

		public uint PlayerOfflineGearDBId { get; set; }

		public eDimensionIndex DimensionIndex { get; set; }

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

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

		public LSSState InitialState { get; set; } = new LSSState();

		public float InitialAmmo { get; set; } = 0.5f;

		public float AmmoCap { get; set; } = 1f;
	}
	public class LSSState
	{
		public bool Enabled { get; set; } = true;

		public bool TargetEnemy { get; set; } = true;

		public bool TargetPlayer { get; set; } = false;

		public bool MarkerVisible { get; set; } = true;

		public bool CanRefill { get; set; } = true;

		public LSSState()
		{
		}

		public LSSState(LSSSyncState o)
		{
			Enabled = o.Enabled;
			TargetEnemy = o.TargetEnemy;
			TargetPlayer = o.TargetPlayer;
			MarkerVisible = o.MarkerVisible;
			CanRefill = o.CanRefill;
		}

		public LSSState(LSSState o)
		{
			Enabled = o.Enabled;
			TargetEnemy = o.TargetEnemy;
			TargetPlayer = o.TargetPlayer;
			MarkerVisible = o.MarkerVisible;
			CanRefill = o.CanRefill;
		}

		public override string ToString()
		{
			return $"Enabled: {Enabled}, TargetEnemy/Player: {TargetEnemy}/{TargetPlayer}, CanRefill: {CanRefill}";
		}
	}
	public struct LSSSyncState
	{
		public bool Enabled { get; set; }

		public bool TargetEnemy { get; set; }

		public bool TargetPlayer { get; set; }

		public bool MarkerVisible { get; set; }

		public bool CanRefill { get; set; }

		public float Ammo { get; set; }

		public LSSSyncState()
		{
			Enabled = true;
			TargetEnemy = true;
			TargetPlayer = false;
			MarkerVisible = true;
			CanRefill = true;
			Ammo = 0.5f;
		}

		public LSSSyncState(LSSSyncState o)
		{
			Enabled = true;
			TargetEnemy = true;
			TargetPlayer = false;
			MarkerVisible = true;
			CanRefill = true;
			Ammo = 0.5f;
			Enabled = o.Enabled;
			TargetEnemy = o.TargetEnemy;
			TargetPlayer = o.TargetPlayer;
			MarkerVisible = o.MarkerVisible;
			CanRefill = o.CanRefill;
			Ammo = o.Ammo;
		}

		public LSSSyncState(LSSState o)
		{
			Enabled = true;
			TargetEnemy = true;
			TargetPlayer = false;
			MarkerVisible = true;
			CanRefill = true;
			Ammo = 0.5f;
			Enabled = o.Enabled;
			TargetEnemy = o.TargetEnemy;
			TargetPlayer = o.TargetPlayer;
			MarkerVisible = o.MarkerVisible;
			CanRefill = o.CanRefill;
		}

		public override string ToString()
		{
			return $"Enabled: {Enabled}, TargetEnemy/Player: {TargetEnemy}/{TargetPlayer}, CanRefill: {CanRefill}";
		}
	}
}

plugins/Inas07.EOSExt.NavigationalSpline.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AssetShards;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using EOSExt.NavigationalSpline.Definition;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Utils;
using GTFO.API;
using GameData;
using HarmonyLib;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.NavigationalSpline
{
	internal static class Asset
	{
		public static GameObject SplineGeneratorGO { get; private set; }

		internal static void Init()
		{
			SplineGeneratorGO = AssetAPI.GetLoadedAsset<GameObject>("Assets/EOSAssets/LG_ChainedPuzzleSplineGenerator.prefab");
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.EOSExt.NavigationalSpline", "EOSExt.NavigationalSpline", "1.1.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.NavigationalSpline";

		public const string VERSION = "1.1.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			SetupManagers();
			m_Harmony = new Harmony("EOSExt.NavigationalSpline");
			m_Harmony.PatchAll();
			EOSLogger.Log("ExtraObjectiveSetup.NavigationalSpline loaded.");
		}

		private void SetupManagers()
		{
			((GenericExpeditionDefinitionManager<NavigationalSplineDefinition>)NavigationalSplineManager.Current).Init();
		}
	}
	public class NavigationalSplineManager : GenericExpeditionDefinitionManager<NavigationalSplineDefinition>
	{
		public enum WardenEvents_NavigationalSpline
		{
			ToggleSplineState = 610
		}

		public static NavigationalSplineManager Current { get; private set; }

		protected override string DEFINITION_NAME => "NavigationalSpline";

		private Dictionary<string, GameObject> SplineGroups { get; } = new Dictionary<string, GameObject>();

		private void InstantiateSplines()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			if (!base.definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out var value))
			{
				return;
			}
			foreach (NavigationalSplineDefinition definition in value.Definitions)
			{
				if (SplineGroups.ContainsKey(definition.WorldEventObjectFilter))
				{
					EOSLogger.Error("NavigationalSplineManager: duplicate 'WorldEventObjectFilter': " + definition.WorldEventObjectFilter + ", won't build");
					continue;
				}
				GameObject val = new GameObject("NavigationalSpline_" + definition.WorldEventObjectFilter);
				for (int i = 0; i < definition.Splines.Count; i++)
				{
					Spline spline = definition.Splines[i];
					GameObject val2 = new GameObject($"NavigationalSpline_{definition.WorldEventObjectFilter}_{i}");
					val2.transform.SetParent(val.transform);
					CP_Holopath_Spline val3 = val2.AddComponent<CP_Holopath_Spline>();
					val3.m_splineGeneratorPrefab = Asset.SplineGeneratorGO;
					val3.Setup(false);
					val3.GeneratePath(spline.From.ToVector3(), spline.To.ToVector3());
					if (definition.RevealSpeedMulti > 0f)
					{
						val3.m_revealSpeed *= definition.RevealSpeedMulti;
					}
				}
				SplineGroups[definition.WorldEventObjectFilter] = val;
			}
		}

		internal void ToggleSplineState(string WorldEventObjectFilter, int state)
		{
			if (!SplineGroups.TryGetValue(WorldEventObjectFilter, out var value))
			{
				EOSLogger.Error("NavigationalSplineManager: cannot find Spline Group with name '" + WorldEventObjectFilter);
				return;
			}
			switch (state)
			{
			case 0:
			{
				for (int j = 0; j < value.transform.childCount; j++)
				{
					CP_Holopath_Spline component2 = ((Component)value.transform.GetChild(j)).gameObject.GetComponent<CP_Holopath_Spline>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.SetSplineProgress(0f);
						component2.Reveal(0f);
					}
				}
				break;
			}
			case 1:
			{
				for (int k = 0; k < value.transform.childCount; k++)
				{
					CP_Holopath_Spline component3 = ((Component)value.transform.GetChild(k)).gameObject.GetComponent<CP_Holopath_Spline>();
					if ((Object)(object)component3 != (Object)null)
					{
						component3.SetSplineProgress(0.95f);
						component3.Reveal(0f);
					}
				}
				break;
			}
			case 2:
			{
				for (int i = 0; i < value.transform.childCount; i++)
				{
					CP_Holopath_Spline component = ((Component)value.transform.GetChild(i)).gameObject.GetComponent<CP_Holopath_Spline>();
					if ((Object)(object)component != (Object)null)
					{
						component.SetVisible(false);
					}
				}
				break;
			}
			}
		}

		private void Clear()
		{
			foreach (GameObject value in SplineGroups.Values)
			{
				Object.Destroy((Object)(object)value);
			}
			SplineGroups.Clear();
		}

		private NavigationalSplineManager()
		{
			LevelAPI.OnBuildDone += InstantiateSplines;
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
			EOSWardenEventManager.Current.AddEventDefinition(WardenEvents_NavigationalSpline.ToggleSplineState.ToString(), 610u, (Action<WardenObjectiveEventData>)delegate(WardenObjectiveEventData e)
			{
				ToggleSplineState(e.WorldEventObjectFilter, e.Count);
			});
		}

		static NavigationalSplineManager()
		{
			Current = new NavigationalSplineManager();
			AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)Asset.Init);
		}
	}
}
namespace EOSExt.NavigationalSpline.Definition
{
	public class Spline
	{
		public Vec3 From { get; set; } = new Vec3();

		public Vec3 To { get; set; } = new Vec3();
	}
	public class NavigationalSplineDefinition
	{
		public string WorldEventObjectFilter { get; set; } = string.Empty;

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

		public List<Spline> Splines { get; set; } = new List<Spline>
		{
			new Spline()
		};
	}
}

plugins/Inas07.EOSExt.Reactor.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json.Serialization;
using AIGraph;
using AK;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using EOSExt.Reactor.Component;
using EOSExt.Reactor.Definition;
using EOSExt.Reactor.Managers;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.BaseClasses.CustomTerminalDefinition;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Instances;
using ExtraObjectiveSetup.Tweaks.TerminalTweak;
using ExtraObjectiveSetup.Utils;
using GTFO.API;
using GameData;
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 SNetwork;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.Reactor
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.EOSExt.Reactor", "EOSExt.Reactor", "1.1.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.Reactor";

		public const string VERSION = "1.1.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			m_Harmony = new Harmony("EOSExt.Reactor");
			m_Harmony.PatchAll();
			SetupManagers();
			SetupExtraWardenEventDefinitions();
			ClassInjector.RegisterTypeInIl2Cpp<OverrideReactorComp>();
			EOSLogger.Log("ExtraObjectiveSetup.Reactor loaded.");
		}

		private void SetupManagers()
		{
			((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).Init();
			((InstanceDefinitionManager<ReactorStartupOverride>)ReactorStartupOverrideManager.Current).Init();
		}

		private void SetupExtraWardenEventDefinitions()
		{
			EOSWardenEventManager.Current.AddEventDefinition(WardenEvents.EventType.ReactorStartup.ToString(), 150u, (Action<WardenObjectiveEventData>)WardenEvents.ReactorStartup);
			EOSWardenEventManager.Current.AddEventDefinition(WardenEvents.EventType.CompleteCurrentVerify.ToString(), 151u, (Action<WardenObjectiveEventData>)WardenEvents.CompleteCurrentVerify);
		}
	}
}
namespace EOSExt.Reactor.Patches
{
	[HarmonyPatch]
	internal class CommandInterpreter_ReactorVerify
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReactorVerify")]
		private static bool Pre_LG_ComputerTerminalCommandInterpreter_ReactorVerify(LG_ComputerTerminalCommandInterpreter __instance, string param1)
		{
			LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor;
			if ((Object)(object)connectedReactor == (Object)null)
			{
				EOSLogger.Error("ReactorVerify: connected reactor is null - bug detected");
				return true;
			}
			if (connectedReactor.m_isWardenObjective)
			{
				return true;
			}
			if (connectedReactor.ReadyForVerification && param1 == connectedReactor.CurrentStateOverrideCode)
			{
				__instance.m_terminal.ChangeState((TERM_State)7);
			}
			else
			{
				__instance.AddOutput("", true);
				__instance.AddOutput((TerminalLineType)3, Text.Get(2195342028u), 4f, (TerminalSoundType)0, (TerminalSoundType)0);
				__instance.AddOutput("", true);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(LG_GenericTerminalItem), "GetDetailedInfo")]
	internal static class GenericTerminalItem_GetDetailedInfo
	{
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void Post_GetDetailedInfo(LG_GenericTerminalItem __instance, List<string> defaultDetails, ref List<string> __result)
		{
			if (__result != null && __result.Count > 0)
			{
				return;
			}
			string terminalItemKey = __instance.TerminalItemKey;
			if (terminalItemKey == null || !terminalItemKey.StartsWith("REACTOR_"))
			{
				return;
			}
			List<string> val = new List<string>();
			val.Add("----------------------------------------------------------------");
			val.Add("MAIN POWER REACTOR");
			if (defaultDetails != null)
			{
				Enumerator<string> enumerator = defaultDetails.GetEnumerator();
				while (enumerator.MoveNext())
				{
					string current = enumerator.Current;
					val.Add(current);
				}
			}
			val.Add("----------------------------------------------------------------");
			__result = val;
		}
	}
	[HarmonyPatch]
	internal class OnTerminalStartupSequenceVerify
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnTerminalStartupSequenceVerify")]
		private static void Post_ExecuteEventsOnEndOnClientSide(LG_WardenObjective_Reactor __instance)
		{
			if (!SNet.IsMaster)
			{
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
			}
		}
	}
	[HarmonyPatch]
	internal class Reactor_CommandInterpreter
	{
		private static bool Handle_ReactorShutdown(LG_ComputerTerminalCommandInterpreter __instance)
		{
			LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor;
			uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(connectedReactor);
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(connectedReactor);
			ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex);
			if (definition == null)
			{
				EOSLogger.Error("ReactorVerify: found built custom reactor shutdown but its definition is missing, what happened?");
				return true;
			}
			__instance.AddOutput((TerminalLineType)3, Text.Get(3436726297u), 4f, (TerminalSoundType)0, (TerminalSoundType)0);
			if ((Object)(object)definition.ChainedPuzzleToActiveInstance != (Object)null)
			{
				__instance.AddOutput(Text.Get(2277987284u), true);
				if (SNet.IsMaster)
				{
					definition.ChainedPuzzleToActiveInstance.AttemptInteract((eChainedPuzzleInteraction)0);
				}
			}
			else
			{
				connectedReactor.AttemptInteract((eReactorInteraction)6, 0f);
			}
			return false;
		}

		private static bool Handle_ReactorStartup_SpecialCommand(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor;
			if (__instance.m_terminal.CommandIsHidden(cmd))
			{
				return true;
			}
			string itemKey = __instance.m_terminal.ItemKey;
			OverrideReactorComp component = ((Component)connectedReactor).gameObject.GetComponent<OverrideReactorComp>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (!connectedReactor.ReadyForVerification)
			{
				__instance.AddOutput("", true);
				__instance.AddOutput((TerminalLineType)3, ReactorStartupOverrideManager.NotReadyForVerificationOutputText, 4f, (TerminalSoundType)0, (TerminalSoundType)0);
				__instance.AddOutput("", true);
				return false;
			}
			if (component.IsCorrectTerminal(__instance.m_terminal))
			{
				EOSLogger.Log("Reactor Verify Correct!");
				if (SNet.IsMaster)
				{
					if (connectedReactor.m_currentWaveCount == connectedReactor.m_waveCountMax)
					{
						connectedReactor.AttemptInteract((eReactorInteraction)5, 0f);
					}
					else
					{
						connectedReactor.AttemptInteract((eReactorInteraction)3, 0f);
					}
				}
				else
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(connectedReactor.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				}
				__instance.AddOutput(ReactorStartupOverrideManager.CorrectTerminalOutputText, true);
			}
			else
			{
				EOSLogger.Log("Reactor Verify Incorrect!");
				__instance.AddOutput("", true);
				__instance.AddOutput((TerminalLineType)3, ReactorStartupOverrideManager.IncorrectTerminalOutputText, 4f, (TerminalSoundType)0, (TerminalSoundType)0);
				__instance.AddOutput("", true);
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")]
		private static bool Pre_ReceiveCommand(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, string inputLine, string param1, string param2)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor;
			if ((Object)(object)connectedReactor == (Object)null)
			{
				return true;
			}
			if ((int)cmd == 23 && !connectedReactor.m_isWardenObjective)
			{
				return Handle_ReactorShutdown(__instance);
			}
			if ((int)cmd == 42)
			{
				return Handle_ReactorStartup_SpecialCommand(__instance, cmd);
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal class Reactor_OnBuildDone
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")]
		private static void Pre_LG_WardenObjective_Reactor_OnBuildDone(LG_WardenObjective_Reactor __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock);
			if (WardenObjectiveManager.TryGetWardenObjectiveDataForLayer(__instance.SpawnNode.LayerType, __instance.WardenObjectiveChainIndex, ref val) && ((val != null) ? val.ReactorWaves : null) != null && __instance.m_overrideCodes != null)
			{
				int count = ((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes).Count;
				string[] array = new string[Mathf.Max(count, val.ReactorWaves.Count)];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = ((i < count) ? ((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes)[i] : SerialGenerator.GetCodeWord());
				}
				__instance.m_overrideCodes = Il2CppStringArray.op_Implicit(array);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")]
		private static void Post_LG_WardenObjective_Reactor_OnBuildDone(LG_WardenObjective_Reactor __instance)
		{
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: 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_0036: 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_0067: 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_00a0: Invalid comparison between Unknown and I4
			uint num = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).Register(__instance);
			if (__instance.m_isWardenObjective)
			{
				ReactorStartupOverride definition = ((InstanceDefinitionManager<ReactorStartupOverride>)ReactorStartupOverrideManager.Current).GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, num);
				if (definition == null)
				{
					return;
				}
				WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock);
				if (!WardenObjectiveManager.TryGetWardenObjectiveDataForLayer(__instance.SpawnNode.LayerType, __instance.WardenObjectiveChainIndex, ref val) || val == null)
				{
					EOSLogger.Error("Failed to get WardenObjectiveData for this reactor");
					return;
				}
				if ((int)val.Type != 1)
				{
					EOSLogger.Error($"Reactor Instance {(((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance), num)} is not setup as vanilla ReactorStartup, cannot override");
					return;
				}
				definition.ObjectiveDB = val;
				ReactorStartupOverrideManager.Current.Build(__instance, definition);
			}
			else
			{
				ReactorShutdownDefinition definition2 = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, num);
				if (definition2 != null)
				{
					ReactorShutdownObjectiveManager.Current.Build(__instance, definition2);
					EOSLogger.Debug($"Reactor Shutdown Instance {(((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance), num)}: custom setup complete");
				}
			}
			if ((Object)(object)__instance.m_terminal != (Object)null)
			{
				TerminalInstanceManager.Current.RegisterReactorTerminal(__instance);
			}
		}
	}
	[HarmonyPatch]
	internal class Reactor_OnStateChange
	{
		private static void Startup_OnStateChange(LG_WardenObjective_Reactor reactor, pReactorState oldState, pReactorState newState, bool isDropinState)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (isDropinState)
			{
				return;
			}
			uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(reactor);
			ReactorStartupOverride definition = ((InstanceDefinitionManager<ReactorStartupOverride>)ReactorStartupOverrideManager.Current).GetDefinition(reactor.SpawnNode.m_dimension.DimensionIndex, reactor.OriginLayer, reactor.SpawnNode.m_zone.LocalIndex, zoneInstanceIndex);
			if (definition != null && (int)oldState.status == 0 && (Object)(object)reactor.m_chainedPuzzleToStartSequence != (Object)null)
			{
				definition.EventsOnActive.ForEach(delegate(WardenObjectiveEventData e)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
				});
			}
		}

		private static void Shutdown_OnStateChange(LG_WardenObjective_Reactor reactor, pReactorState oldState, pReactorState newState, bool isDropinState, ReactorShutdownDefinition def)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected I4, but got Unknown
			eReactorStatus status = newState.status;
			eReactorStatus val = status;
			switch (val - 6)
			{
			case 0:
				GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", Text.Get(1080u), false, 200f, 8f, (Action)null);
				reactor.m_progressUpdateEnabled = true;
				reactor.m_currentDuration = 15f;
				reactor.m_lightCollection.SetMode(false);
				reactor.m_sound.Stop();
				def.EventsOnActive.ForEach(delegate(WardenObjectiveEventData e)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
				});
				break;
			case 1:
				GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", Text.Get(1081u), false, 200f, 8f, (Action)null);
				reactor.m_progressUpdateEnabled = false;
				reactor.ReadyForVerification = true;
				break;
			case 2:
				reactor.m_progressUpdateEnabled = false;
				if ((Object)(object)def.ChainedPuzzleOnVerificationInstance != (Object)null)
				{
					GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", Text.Get(1082u), false, 200f, 8f, (Action)null);
					def.ChainedPuzzleOnVerificationInstance.AttemptInteract((eChainedPuzzleInteraction)0);
				}
				def.EventsOnShutdownPuzzleStarts.ForEach(delegate(WardenObjectiveEventData e)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
				});
				break;
			case 3:
				reactor.m_progressUpdateEnabled = false;
				reactor.m_objectiveCompleteTimer = Clock.Time + 5f;
				def.EventsOnComplete.ForEach(delegate(WardenObjectiveEventData e)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
				});
				break;
			}
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")]
		private static bool Pre_LG_WardenObjective_Reactor_OnStateChange(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState, bool isDropinState)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.m_isWardenObjective)
			{
				if (ReactorInstanceManager.Current.IsStartupReactor(__instance))
				{
					Startup_OnStateChange(__instance, oldState, newState, isDropinState);
				}
				return true;
			}
			if (oldState.stateCount != newState.stateCount)
			{
				__instance.OnStateCountUpdate(newState.stateCount);
			}
			if (oldState.stateProgress != newState.stateProgress)
			{
				__instance.OnStateProgressUpdate(newState.stateProgress);
			}
			if (oldState.status == newState.status)
			{
				return false;
			}
			__instance.ReadyForVerification = false;
			if (ReactorInstanceManager.Current.IsShutdownReactor(__instance))
			{
				uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(__instance);
				(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance);
				ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex);
				if (definition == null)
				{
					EOSLogger.Error("Reactor_OnStateChange: found built custom reactor but its definition is missing, what happened?");
					return false;
				}
				Shutdown_OnStateChange(__instance, oldState, newState, isDropinState, definition);
				__instance.m_currentState = newState;
				return false;
			}
			EOSLogger.Error("Reactor_OnStateChange: found built custom reactor but it's not a shutdown reactor, what happened?");
			return false;
		}
	}
	[HarmonyPatch]
	internal class Reactor_OnStateCountUpdate
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateCountUpdate")]
		private static bool Pre_LG_WardenObjective_Reactor_OnStateCountUpdate(LG_WardenObjective_Reactor __instance, int count)
		{
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			if (__instance.m_isWardenObjective)
			{
				return true;
			}
			uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(__instance);
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance);
			if (ReactorInstanceManager.Current.IsStartupReactor(__instance))
			{
				return true;
			}
			if (ReactorInstanceManager.Current.IsShutdownReactor(__instance))
			{
				ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex);
				if (definition == null)
				{
					EOSLogger.Error("Reactor_OnStateCountUpdate: found built custom reactor but its definition is missing, what happened?");
					return true;
				}
				__instance.m_currentWaveCount = count;
				if (definition.PutVerificationCodeOnTerminal)
				{
					LG_ComputerTerminal instance = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstance(((GlobalZoneIndex)definition.VerificationCodeTerminal).GlobalZoneIndexTuple(), definition.VerificationCodeTerminal.InstanceIndex);
					__instance.m_currentWaveData = new ReactorWaveData
					{
						HasVerificationTerminal = (definition.PutVerificationCodeOnTerminal && (Object)(object)instance != (Object)null),
						VerificationTerminalSerial = (((Object)(object)instance != (Object)null) ? instance.ItemKey : string.Empty),
						Warmup = 1f,
						WarmupFail = 1f,
						Wave = 1f,
						Verify = 1f,
						VerifyFail = 1f
					};
				}
				else
				{
					__instance.m_currentWaveData = new ReactorWaveData
					{
						HasVerificationTerminal = false,
						VerificationTerminalSerial = string.Empty,
						Warmup = 1f,
						WarmupFail = 1f,
						Wave = 1f,
						Verify = 1f,
						VerifyFail = 1f
					};
				}
				if (__instance.m_overrideCodes != null && !string.IsNullOrEmpty(((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes)[0]))
				{
					__instance.CurrentStateOverrideCode = ((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes)[0];
				}
				else
				{
					EOSLogger.Error("Reactor_OnStateCountUpdate: code is not built?");
				}
				return false;
			}
			EOSLogger.Error("Reactor_OnStateCountUpdate: found built custom reactor but it's neither a startup nor shutdown reactor, what happen?");
			return true;
		}
	}
	[HarmonyPatch]
	internal class Reactor_Update
	{
		private static bool _checked;

		private static TextDataBlock shutdownVerification_GUIText;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Update")]
		private static bool Pre_LG_WardenObjective_Reactor_Update(LG_WardenObjective_Reactor __instance)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (__instance.m_isWardenObjective || (int)__instance.m_currentState.status != 7)
			{
				return true;
			}
			if (!_checked)
			{
				shutdownVerification_GUIText = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.ExtraObjectiveSetup_ReactorShutdown.SecurityVerificationRequired");
				_checked = true;
			}
			string empty = string.Empty;
			empty = ((!__instance.m_currentWaveData.HasVerificationTerminal) ? string.Format(Text.Get(1107u), "<color=orange>" + __instance.CurrentStateOverrideCode + "</color>") : string.Format((shutdownVerification_GUIText != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)shutdownVerification_GUIText).persistentID) : "SECURITY VERIFICATION REQUIRED. USE COMMAND <color=orange>REACTOR_VERIFY</color> AND FIND CODE ON <color=orange>{0}</color>.", __instance.m_currentWaveData.VerificationTerminalSerial));
			__instance.SetGUIMessage(true, empty, (ePUIMessageStyle)3, false, "", "");
			return false;
		}
	}
}
namespace EOSExt.Reactor.Patches.Shutdown
{
	[HarmonyPatch]
	internal class Reactor_OnReactorShutdownVerifyChaosDone
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "OnReactorShutdownVerifyChaosDone")]
		private static bool Pre_LG_ComputerTerminalCommandInterpreter_OnReactorShutdownVerifyChaosDone(LG_ComputerTerminalCommandInterpreter __instance)
		{
			LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor;
			if ((Object)(object)connectedReactor == (Object)null || connectedReactor.m_isWardenObjective)
			{
				return true;
			}
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(connectedReactor);
			uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(connectedReactor);
			ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex);
			if (definition == null)
			{
				EOSLogger.Error("OnReactorShutdownVerifyChaosDone: found built custom reactor shutdown but its definition is missing, what happened?");
				return false;
			}
			connectedReactor.AttemptInteract((eReactorInteraction)(((Object)(object)definition.ChainedPuzzleOnVerificationInstance != (Object)null) ? 8 : 9), 0f);
			return false;
		}
	}
}
namespace EOSExt.Reactor.Managers
{
	public sealed class ReactorInstanceManager : InstanceManager<LG_WardenObjective_Reactor>
	{
		private HashSet<IntPtr> startupReactor = new HashSet<IntPtr>();

		private HashSet<IntPtr> shutdownReactor = new HashSet<IntPtr>();

		public static ReactorInstanceManager Current { get; private set; }

		public override (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GetGlobalZoneIndex(LG_WardenObjective_Reactor instance)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			return (instance.SpawnNode.m_dimension.DimensionIndex, instance.SpawnNode.LayerType, instance.SpawnNode.m_zone.LocalIndex);
		}

		public void MarkAsStartupReactor(LG_WardenObjective_Reactor reactor)
		{
			if (shutdownReactor.Contains(((Il2CppObjectBase)reactor).Pointer))
			{
				throw new ArgumentException("Invalid: cannot mark a reactor both as startup and shutdown reactor");
			}
			startupReactor.Add(((Il2CppObjectBase)reactor).Pointer);
		}

		public void MarkAsShutdownReactor(LG_WardenObjective_Reactor reactor)
		{
			if (startupReactor.Contains(((Il2CppObjectBase)reactor).Pointer))
			{
				throw new ArgumentException("Invalid: cannot mark a reactor both as startup and shutdown reactor");
			}
			shutdownReactor.Add(((Il2CppObjectBase)reactor).Pointer);
		}

		public bool IsStartupReactor(LG_WardenObjective_Reactor reactor)
		{
			return startupReactor.Contains(((Il2CppObjectBase)reactor).Pointer);
		}

		public bool IsShutdownReactor(LG_WardenObjective_Reactor reactor)
		{
			return shutdownReactor.Contains(((Il2CppObjectBase)reactor).Pointer);
		}

		private void Clear()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			foreach (IntPtr item in startupReactor)
			{
				LG_WardenObjective_Reactor val = new LG_WardenObjective_Reactor(item);
				if (val != null)
				{
					CellSoundPlayer sound = val.m_sound;
					if (sound != null)
					{
						sound.Recycle();
					}
				}
			}
			foreach (IntPtr item2 in shutdownReactor)
			{
				LG_WardenObjective_Reactor val2 = new LG_WardenObjective_Reactor(item2);
				if (val2 != null)
				{
					CellSoundPlayer sound2 = val2.m_sound;
					if (sound2 != null)
					{
						sound2.Recycle();
					}
				}
			}
			startupReactor.Clear();
			shutdownReactor.Clear();
		}

		public void SetupReactorTerminal(LG_WardenObjective_Reactor reactor, TerminalDefinition reactorTerminalData)
		{
			reactor.SpawnNode.m_zone.TerminalsSpawnedInZone.Add(reactor.m_terminal);
			if (reactorTerminalData != null)
			{
				reactorTerminalData.LocalLogFiles?.ForEach(delegate(TerminalLogFileData log)
				{
					reactor.m_terminal.AddLocalLog(log, true);
				});
				reactorTerminalData.UniqueCommands?.ForEach(delegate(CustomCommand cmd)
				{
					EOSTerminalUtils.AddUniqueCommand(reactor.m_terminal, cmd);
				});
				EOSTerminalUtils.BuildPassword(reactor.m_terminal, reactorTerminalData.PasswordData);
			}
		}

		public static LG_WardenObjective_Reactor FindVanillaReactor(LG_LayerType layer, int count)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			if (count < 0)
			{
				EOSLogger.Error($"FindVanillaReactor: Count should be non-negative, but got {count}!");
				return null;
			}
			LG_WardenObjective_Reactor val = null;
			int num = count;
			Enumerator<LayerChainIndex, iWardenObjectiveItem> enumerator = WardenObjectiveManager.Current.m_wardenObjectiveItem.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<LayerChainIndex, iWardenObjectiveItem> current = enumerator.Current;
				if (current.Key.Layer != layer)
				{
					continue;
				}
				iWardenObjectiveItem value = current.Value;
				val = ((value != null) ? ((Il2CppObjectBase)value).TryCast<LG_WardenObjective_Reactor>() : null);
				if (!((Object)(object)val == (Object)null))
				{
					if (num <= 0)
					{
						break;
					}
					val = null;
					num--;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				EOSLogger.Error($"FindVanillaReactor: reactor not found with index(Count) {num} in {layer}!");
			}
			return val;
		}

		private ReactorInstanceManager()
		{
			LevelAPI.OnLevelCleanup += Clear;
		}

		static ReactorInstanceManager()
		{
			Current = new ReactorInstanceManager();
		}
	}
	internal class ReactorShutdownObjectiveManager : InstanceDefinitionManager<ReactorShutdownDefinition>
	{
		private List<ReactorShutdownDefinition> builtShutdownPuzzles = new List<ReactorShutdownDefinition>();

		public static ReactorShutdownObjectiveManager Current { get; private set; }

		protected override string DEFINITION_NAME => "ReactorShutdown";

		private void GenericObjectiveSetup(LG_WardenObjective_Reactor reactor, ReactorShutdownDefinition def)
		{
			//IL_0057: 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)
			reactor.m_serialNumber = SerialGenerator.GetUniqueSerialNo();
			reactor.m_itemKey = "REACTOR_" + reactor.m_serialNumber;
			reactor.m_terminalItem = GOUtil.GetInterfaceFromComp<iTerminalItem>(reactor.m_terminalItemComp);
			reactor.m_terminalItem.Setup(reactor.m_itemKey, (AIG_CourseNode)null);
			reactor.m_terminalItem.FloorItemStatus = EnumUtil.GetRandomValue<eFloorInventoryObjectStatus>();
			reactor.m_overrideCodes = Il2CppStringArray.op_Implicit(new string[1] { SerialGeneratorManager.GetCodeWord(def.CodeWordLength) });
			reactor.m_terminal = GOUtil.SpawnChildAndGetComp<LG_ComputerTerminal>(reactor.m_terminalPrefab, reactor.m_terminalAlign);
			reactor.m_terminal.Setup((TerminalStartStateData)null, (TerminalPlacementData)null);
			reactor.m_terminal.ConnectedReactor = reactor;
			ReactorInstanceManager.Current.SetupReactorTerminal(reactor, def.ReactorTerminal);
		}

		private void OnLateBuildJob(LG_WardenObjective_Reactor reactor, BaseReactorDefinition reactorDefinition)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			reactor.m_stateReplicator = SNet_StateReplicator<pReactorState, pReactorInteraction>.Create(new iSNet_StateReplicatorProvider<pReactorState, pReactorInteraction>(((Il2CppObjectBase)reactor).Pointer), (eSNetReplicatorLifeTime)1, default(pReactorState), (SNet_ChannelType)2);
			GenericObjectiveSetup(reactor, (ReactorShutdownDefinition)reactorDefinition);
			reactor.m_sound = new CellSoundPlayer(reactor.m_terminalAlign.position);
			reactor.m_sound.Post(EVENTS.REACTOR_POWER_LEVEL_1_LOOP, true);
			reactor.m_sound.SetRTPCValue(GAME_PARAMETERS.REACTOR_POWER, 100f);
			reactor.m_terminal.m_command.SetupReactorCommands(false, true);
		}

		internal void Build(LG_WardenObjective_Reactor reactor, ReactorShutdownDefinition def)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Expected O, but got Unknown
			//IL_01cb: Expected O, but got Unknown
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			if (reactor.m_isWardenObjective)
			{
				EOSLogger.Error($"ReactorShutdown: Reactor definition for reactor {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex} is already setup by vanilla, won't build.");
				return;
			}
			OnLateBuildJob(reactor, def);
			reactor.m_lightCollection = LG_LightCollection.Create(reactor.m_reactorArea.m_courseNode, reactor.m_terminalAlign.position, (LG_LightCollectionSorting)1, float.MaxValue);
			reactor.m_lightCollection.SetMode(true);
			if (def.PutVerificationCodeOnTerminal)
			{
				LG_ComputerTerminal instance = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstance(((GlobalZoneIndex)def.VerificationCodeTerminal).GlobalZoneIndexTuple(), def.VerificationCodeTerminal.InstanceIndex);
				if ((Object)(object)instance == (Object)null)
				{
					EOSLogger.Error($"ReactorShutdown: PutVerificationCodeOnTerminal is specified but could NOT find terminal {def.VerificationCodeTerminal}, will show verification code upon shutdown initiation");
				}
				else
				{
					string fileName = "reactor_ver" + SerialGeneratorManager.GetCodeWordPrefix(def.UseHardLogFilenameSuffix, false) + ".log";
					TerminalLogFileData val = new TerminalLogFileData
					{
						FileName = fileName,
						FileContent = new LocalizedText
						{
							UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase<string>)(object)reactor.m_overrideCodes)[0].ToUpperInvariant()),
							Id = 0u
						}
					};
					instance.AddLocalLog(val, true);
					instance.m_command.ClearOutputQueueAndScreenBuffer();
					instance.m_command.AddInitialTerminalOutput();
				}
			}
			if (reactor.SpawnNode != null && reactor.m_terminalItem != null)
			{
				reactor.m_terminalItem.SpawnNode = reactor.SpawnNode;
				reactor.m_terminalItem.FloorItemLocation = reactor.SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7);
			}
			if (def.ChainedPuzzleToActive != 0)
			{
				ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(def.ChainedPuzzleToActive);
				if (block == null)
				{
					EOSLogger.Error("ReactorShutdown: ChainedPuzzleToActive is specified but could not find its ChainedPuzzleDatablock definition!");
				}
				else
				{
					Vector3 position = ((Component)reactor).transform.position;
					def.ChainedPuzzleToActiveInstance = ChainedPuzzleManager.CreatePuzzleInstance(block, reactor.SpawnNode.m_area, reactor.m_chainedPuzzleAlign.position, ((Component)reactor).transform);
					ChainedPuzzleInstance chainedPuzzleToActiveInstance = def.ChainedPuzzleToActiveInstance;
					chainedPuzzleToActiveInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate
					{
						if (SNet.IsMaster)
						{
							reactor.AttemptInteract((eReactorInteraction)6, 0f);
						}
					});
				}
			}
			else
			{
				EOSLogger.Debug("ReactorShutdown: Reactor has no ChainedPuzzleToActive, will start shutdown sequence on shutdown command initiation.");
			}
			if (def.ChainedPuzzleOnVerification != 0)
			{
				ChainedPuzzleDataBlock block2 = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(def.ChainedPuzzleOnVerification);
				if (block2 == null)
				{
					EOSLogger.Error("ReactorShutdown: ChainedPuzzleOnVerification is specified but could not find its ChainedPuzzleDatablock definition! Will complete shutdown on verification");
				}
				Vector3 position2 = ((Component)reactor).transform.position;
				def.ChainedPuzzleOnVerificationInstance = ChainedPuzzleManager.CreatePuzzleInstance(block2, reactor.SpawnNode.m_area, reactor.m_chainedPuzzleAlign.position, ((Component)reactor).transform);
				ChainedPuzzleInstance chainedPuzzleOnVerificationInstance = def.ChainedPuzzleOnVerificationInstance;
				chainedPuzzleOnVerificationInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate
				{
					if (SNet.IsMaster)
					{
						reactor.AttemptInteract((eReactorInteraction)9, 0f);
					}
				});
			}
			else
			{
				EOSLogger.Debug("ReactorShutdown: ChainedPuzzleOnVerification unspecified, will complete shutdown on verification.");
			}
			LG_ComputerTerminal terminal = reactor.m_terminal;
			iLG_SpawnedInNodeHandler val2 = ((terminal != null) ? ((Component)terminal).GetComponent<iLG_SpawnedInNodeHandler>() : null);
			if (val2 != null)
			{
				val2.SpawnNode = reactor.SpawnNode;
			}
			reactor.SetLightsEnabled(reactor.m_lightsWhenOff, false);
			reactor.SetLightsEnabled(reactor.m_lightsWhenOn, true);
			builtShutdownPuzzles.Add(def);
			ReactorInstanceManager.Current.MarkAsShutdownReactor(reactor);
			EOSLogger.Debug($"ReactorShutdown: {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex}, custom setup completed");
		}

		private void OnLevelCleanup()
		{
			builtShutdownPuzzles.ForEach(delegate(ReactorShutdownDefinition def)
			{
				ChainedPuzzleInstance chainedPuzzleOnVerificationInstance = (def.ChainedPuzzleToActiveInstance = null);
				def.ChainedPuzzleOnVerificationInstance = chainedPuzzleOnVerificationInstance;
			});
			builtShutdownPuzzles.Clear();
		}

		private ReactorShutdownObjectiveManager()
		{
			LevelAPI.OnLevelCleanup += OnLevelCleanup;
			LevelAPI.OnBuildStart += OnLevelCleanup;
		}

		static ReactorShutdownObjectiveManager()
		{
			Current = new ReactorShutdownObjectiveManager();
		}
	}
	internal class ReactorStartupOverrideManager : InstanceDefinitionManager<ReactorStartupOverride>
	{
		private List<ReactorStartupOverride> builtOverride = new List<ReactorStartupOverride>();

		public static uint SpecialCmdVerifyTextID { get; private set; }

		public static uint MainTerminalTextID { get; private set; }

		public static uint CooldownCommandDescTextID { get; private set; }

		public static uint InfiniteWaveVerifyTextID { get; private set; }

		public static uint NotReadyForVerificationOutputTextID { get; private set; }

		public static uint IncorrectTerminalOutputTextID { get; private set; }

		public static uint CorrectTerminalOutputTextID { get; private set; }

		public static string CoolDownCommandDesc => (CooldownCommandDescTextID != 0) ? Text.Get(CooldownCommandDescTextID) : "Confirm Reactor Startup Cooling Protocol";

		public static string MainTerminalText => (MainTerminalTextID != 0) ? Text.Get(MainTerminalTextID) : "Main Terminal";

		public static string SpecialCmdVerifyText => (SpecialCmdVerifyTextID != 0) ? Text.Get(SpecialCmdVerifyTextID) : "REACTOR COOLING REQUIRED ({0}/{1})\nMANUAL OVERRIDE REQUIRED. USE COMMAND <color=orange>REACTOR_COOLDOWN</color> AT {2}";

		public static string InfiniteWaveVerifyText => (InfiniteWaveVerifyTextID != 0) ? Text.Get(InfiniteWaveVerifyTextID) : "VERIFICATION ({0}/{1}).";

		public static string NotReadyForVerificationOutputText => (NotReadyForVerificationOutputTextID != 0) ? Text.Get(NotReadyForVerificationOutputTextID) : "<color=red>Reactor intensive test in progress, cannot initate cooldown</color>";

		public static string CorrectTerminalOutputText => (CorrectTerminalOutputTextID != 0) ? Text.Get(CorrectTerminalOutputTextID) : "<color=red>Reactor stage cooldown completed</color>";

		public static string IncorrectTerminalOutputText => (IncorrectTerminalOutputTextID != 0) ? Text.Get(IncorrectTerminalOutputTextID) : "<color=red>Incorrect terminal, cannot initate cooldown</color>";

		public static ReactorStartupOverrideManager Current { get; private set; }

		protected override string DEFINITION_NAME => "ReactorStartup";

		public static void FetchOverrideTextDB()
		{
			SpecialCmdVerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownVerification");
			MainTerminalTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownMainTerminalName");
			CooldownCommandDescTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CommandDesc");
			InfiniteWaveVerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.Verification.InfiniteWave");
			NotReadyForVerificationOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.Not_ReadyForVerification_Output");
			IncorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.IncorrectTerminal_Output");
			CorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CorrectTerminal_Output");
		}

		protected override void AddDefinitions(InstanceDefinitionsForLevel<ReactorStartupOverride> definitions)
		{
			definitions.Definitions.ForEach(delegate(ReactorStartupOverride def)
			{
				def.Overrides.Sort((WaveOverride o1, WaveOverride o2) => o1.WaveIndex.CompareTo(o2.WaveIndex));
			});
			base.AddDefinitions(definitions);
		}

		internal void Build(LG_WardenObjective_Reactor reactor, ReactorStartupOverride def)
		{
			if (!reactor.m_isWardenObjective)
			{
				EOSLogger.Error($"ReactorStartup: Reactor Override for reactor {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex} is not setup by vanilla, won't override");
				return;
			}
			OverrideReactorComp overrideReactorComp = ((Component)reactor).gameObject.AddComponent<OverrideReactorComp>();
			overrideReactorComp.ChainedReactor = reactor;
			overrideReactorComp.overrideData = def;
			overrideReactorComp.UsingLightEffect = false;
			overrideReactorComp.Init();
			ReactorInstanceManager.Current.MarkAsStartupReactor(reactor);
			ReactorInstanceManager.Current.SetupReactorTerminal(reactor, def.ReactorTerminal);
			def.ChainedPuzzleToActiveInstance = reactor.m_chainedPuzzleToStartSequence;
			if ((Object)(object)def.ChainedPuzzleToActiveInstance != (Object)null)
			{
			}
			builtOverride.Add(def);
			EOSLogger.Debug($"ReactorStartup: {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex}, override completed");
		}

		private void OnLevelCleanup()
		{
			builtOverride.ForEach(delegate(ReactorStartupOverride def)
			{
				def.ChainedPuzzleToActiveInstance = null;
			});
			builtOverride.Clear();
		}

		private ReactorStartupOverrideManager()
		{
			LevelAPI.OnLevelCleanup += OnLevelCleanup;
			LevelAPI.OnBuildStart += OnLevelCleanup;
		}

		static ReactorStartupOverrideManager()
		{
			SpecialCmdVerifyTextID = 0u;
			MainTerminalTextID = 0u;
			CooldownCommandDescTextID = 0u;
			InfiniteWaveVerifyTextID = 0u;
			NotReadyForVerificationOutputTextID = 0u;
			IncorrectTerminalOutputTextID = 0u;
			CorrectTerminalOutputTextID = 0u;
			Current = new ReactorStartupOverrideManager();
			EventAPI.OnExpeditionStarted += FetchOverrideTextDB;
		}
	}
}
namespace EOSExt.Reactor.Definition
{
	public class BaseReactorDefinition : BaseInstanceDefinition
	{
		[JsonPropertyOrder(-9)]
		public TerminalDefinition ReactorTerminal { get; set; } = new TerminalDefinition();

		[JsonPropertyOrder(-9)]
		public List<WardenObjectiveEventData> EventsOnActive { get; set; } = new List<WardenObjectiveEventData>();

		public CodeWordLength CodeWordLength { get; set; } = (CodeWordLength)4;

		public bool UseHardLogFilenameSuffix { get; set; } = false;

		[JsonIgnore]
		public ChainedPuzzleInstance ChainedPuzzleToActiveInstance { get; set; } = null;
	}
	public class ReactorShutdownDefinition : BaseReactorDefinition
	{
		[JsonPropertyOrder(-9)]
		public uint ChainedPuzzleToActive { get; set; } = 0u;

		public bool PutVerificationCodeOnTerminal { get; set; } = false;

		public BaseInstanceDefinition VerificationCodeTerminal { get; set; } = new BaseInstanceDefinition();

		public uint ChainedPuzzleOnVerification { get; set; } = 0u;

		[JsonIgnore]
		public ChainedPuzzleInstance ChainedPuzzleOnVerificationInstance { get; set; } = null;

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

		public List<WardenObjectiveEventData> EventsOnComplete { get; set; } = new List<WardenObjectiveEventData>();
	}
	public enum EOSReactorVerificationType
	{
		NORMAL,
		BY_SPECIAL_COMMAND,
		BY_WARDEN_EVENT
	}
	public class WaveOverride
	{
		public int WaveIndex { get; set; } = -1;

		public EOSReactorVerificationType VerificationType { get; set; } = EOSReactorVerificationType.NORMAL;

		public bool HideVerificationTimer { get; set; } = false;

		public bool ChangeVerifyZone { get; set; } = false;

		public BaseInstanceDefinition VerifyZone { get; set; } = new BaseInstanceDefinition();

		public bool UseCustomVerifyText { get; set; } = false;

		public LocalizedText VerifySequenceText { get; set; } = null;

		[JsonIgnore]
		public LG_ComputerTerminal VerifyTerminal { get; set; } = null;
	}
	public class ReactorStartupOverride : BaseReactorDefinition
	{
		public bool StartupOnDrop { get; set; } = false;

		[JsonIgnore]
		public WardenObjectiveDataBlock ObjectiveDB { get; set; } = null;

		public List<WaveOverride> Overrides { get; set; } = new List<WaveOverride>
		{
			new WaveOverride()
		};
	}
	internal class WardenEvents
	{
		public enum EventType
		{
			ReactorStartup = 150,
			CompleteCurrentVerify
		}

		internal static void ReactorStartup(WardenObjectiveEventData e)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster)
			{
				return;
			}
			LG_WardenObjective_Reactor val = ReactorInstanceManager.FindVanillaReactor(e.Layer, e.Count);
			WardenObjectiveDataBlock val2 = default(WardenObjectiveDataBlock);
			if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(e.Layer, ref val2) || val2 == null)
			{
				EOSLogger.Error("CompleteCurrentReactorWave: Cannot get WardenObjectiveDataBlock");
				return;
			}
			if ((int)val2.Type != 1)
			{
				EOSLogger.Error($"CompleteCurrentReactorWave: {e.Layer} is not ReactorStartup. CompleteCurrentReactorWave is invalid.");
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				EOSLogger.Error($"ReactorStartup: Cannot find reactor in {e.Layer}.");
				return;
			}
			eReactorStatus status = val.m_currentState.status;
			eReactorStatus val3 = status;
			if ((int)val3 == 0)
			{
				if (SNet.IsMaster)
				{
					val.AttemptInteract((eReactorInteraction)0, 0f);
				}
				val.m_terminal.TrySyncSetCommandHidden((TERM_Command)21);
			}
			EOSLogger.Debug($"ReactorStartup: Current reactor wave for {e.Layer} completed");
		}

		internal static void CompleteCurrentVerify(WardenObjectiveEventData e)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock);
			if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(e.Layer, ref val) || val == null)
			{
				EOSLogger.Error("CompleteCurrentReactorWave: Cannot get WardenObjectiveDataBlock");
				return;
			}
			if ((int)val.Type != 1)
			{
				EOSLogger.Error($"CompleteCurrentReactorWave: {e.Layer} is not ReactorStartup. CompleteCurrentReactorWave is invalid.");
				return;
			}
			LG_WardenObjective_Reactor val2 = ReactorInstanceManager.FindVanillaReactor(e.Layer, e.Count);
			if ((Object)(object)val2 == (Object)null)
			{
				EOSLogger.Error($"CompleteCurrentReactorWave: Cannot find reactor in {e.Layer}.");
				return;
			}
			if (SNet.IsMaster)
			{
				if (val2.m_currentWaveCount == val2.m_waveCountMax)
				{
					val2.AttemptInteract((eReactorInteraction)5, 0f);
				}
				else
				{
					val2.AttemptInteract((eReactorInteraction)3, 0f);
				}
			}
			else
			{
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(val2.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
			}
			EOSLogger.Debug($"CompleteCurrentReactorWave: Current reactor verify for {e.Layer} completed");
		}
	}
}
namespace EOSExt.Reactor.Component
{
	public class OverrideReactorComp : MonoBehaviour
	{
		private static Color LowTemperature;

		private static Color HighTemperature;

		private LG_Light[] _lights;

		private float _updateTimer;

		private List<WaveOverride> WaveData = new List<WaveOverride>();

		public LG_WardenObjective_Reactor ChainedReactor { get; internal set; }

		public ReactorStartupOverride overrideData { get; internal set; }

		public bool UsingLightEffect { get; set; } = true;

		public WardenObjectiveDataBlock ObjectiveData => overrideData?.ObjectiveDB;

		public void Init()
		{
			if ((Object)(object)ChainedReactor == (Object)null || overrideData == null)
			{
				EOSLogger.Error("ReactorOverride not properly initialized!");
				return;
			}
			for (int i = 0; i < overrideData.Overrides.Count; i++)
			{
				WaveOverride waveOverride = overrideData.Overrides[i];
				WaveOverride waveOverride2 = ((i - 1 >= 0) ? overrideData.Overrides[i - 1] : null);
				if (waveOverride2 != null && waveOverride.WaveIndex == waveOverride2.WaveIndex)
				{
					EOSLogger.Error($"Found duplicate wave index {waveOverride.WaveIndex}, this could lead to reactor override exception!");
					continue;
				}
				for (int j = ((waveOverride2 != null) ? (waveOverride2.WaveIndex + 1) : 0); j < waveOverride.WaveIndex; j++)
				{
					WaveData.Add(new WaveOverride
					{
						WaveIndex = j
					});
				}
				WaveData.Add(waveOverride);
			}
			if (WaveData.Count != ObjectiveData.ReactorWaves.Count)
			{
				EOSLogger.Error($"WaveData.Count({WaveData.Count}) != ObjectiveData.ReactorWaves.Count({ObjectiveData.ReactorWaves.Count})");
			}
			LevelAPI.OnEnterLevel += OnEnterLevel;
		}

		private void OnEnterLevel()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			LG_WardenObjective_Reactor chainedReactor = ChainedReactor;
			LG_ComputerTerminal terminal = ChainedReactor.m_terminal;
			if ((int)ObjectiveData.Type != 1)
			{
				EOSLogger.Error("Only Reactor Startup is supported");
				((Behaviour)this).enabled = false;
				return;
			}
			if (UsingLightEffect)
			{
				_lights = ((IEnumerable<LG_Light>)chainedReactor.SpawnNode.m_lightsInNode).Where((LG_Light x) => (int)x.m_category == 3).ToArray();
				chainedReactor.m_lightCollection.RemoveLights(Il2CppReferenceArray<LG_Light>.op_Implicit(_lights));
			}
			if (overrideData.StartupOnDrop && SNet.IsMaster)
			{
				chainedReactor.AttemptInteract((eReactorInteraction)0, 0f);
				terminal.TrySyncSetCommandHidden((TERM_Command)21);
			}
			SetupVerifyZoneOverrides();
			SetupWaves();
			ApplyCodeWordOverrides();
		}

		private void SetupVerifyZoneOverrides()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Expected O, but got Unknown
			//IL_049d: Expected O, but got Unknown
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val = default(LG_Zone);
			foreach (WaveOverride waveDatum in WaveData)
			{
				if (!waveDatum.ChangeVerifyZone)
				{
					continue;
				}
				if (waveDatum.VerificationType == EOSReactorVerificationType.BY_WARDEN_EVENT)
				{
					EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Verification Type is {2}, which doesn't work with VerifyZoneOverride");
					continue;
				}
				BaseInstanceDefinition verifyZone = waveDatum.VerifyZone;
				if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(((GlobalZoneIndex)verifyZone).DimensionIndex, ((GlobalZoneIndex)verifyZone).LayerType, ((GlobalZoneIndex)verifyZone).LocalIndex, ref val) || (Object)(object)val == (Object)null)
				{
					EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Cannot find target zone {((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple()}.");
					continue;
				}
				if (val.TerminalsSpawnedInZone == null || val.TerminalsSpawnedInZone.Count <= 0)
				{
					EOSLogger.Error($"VerifyZoneOverrides: No spawned terminal found in target zone {((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple()}.");
					continue;
				}
				LG_ComputerTerminal val2 = null;
				if (verifyZone.InstanceIndex >= 0)
				{
					val2 = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstance(((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple(), verifyZone.InstanceIndex);
				}
				else
				{
					List<LG_ComputerTerminal> instancesInZone = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstancesInZone(((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple());
					int index = Builder.SessionSeedRandom.Range(0, instancesInZone.Count, "NO_TAG");
					val2 = instancesInZone[index];
				}
				if ((Object)(object)val2 == (Object)null)
				{
					EOSLogger.Error($"VerifyZoneOverride: cannot find target terminal with Terminal Instance Index: {waveDatum}");
				}
				waveDatum.VerifyTerminal = val2;
				ReactorWaveData waveData = ObjectiveData.ReactorWaves[waveDatum.WaveIndex];
				TerminalLogFileData val3 = null;
				if (waveData.VerifyInOtherZone)
				{
					List<LG_ComputerTerminal> list = EOSTerminalUtils.FindTerminal(ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, waveData.ZoneForVerification, (Predicate<LG_ComputerTerminal>)((LG_ComputerTerminal x) => x.ItemKey == waveData.VerificationTerminalSerial));
					if (list == null || list.Count < 1)
					{
						EOSLogger.Error($"Wave_{waveDatum.WaveIndex}: cannot find vanilla verification terminal in {(ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, waveData.ZoneForVerification)}, unable to override");
						continue;
					}
					LG_ComputerTerminal val4 = list[0];
					if ((Object)(object)val4 == (Object)null)
					{
						EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Cannot find log terminal");
						continue;
					}
					string text = waveData.VerificationTerminalFileName.ToUpperInvariant();
					val3 = EOSTerminalUtils.GetLocalLog(val4, text);
					if (val3 == null)
					{
						EOSLogger.Error("VerifyZoneOverrides: Cannot find vanilla-generated reactor verify log on terminal...");
						continue;
					}
					val4.RemoveLocalLog(text);
					EOSTerminalUtils.ResetInitialOutput(val4);
				}
				else
				{
					waveData.VerificationTerminalFileName = "reactor_ver" + SerialGenerator.GetCodeWordPrefix() + ".log";
					val3 = new TerminalLogFileData
					{
						FileName = waveData.VerificationTerminalFileName,
						FileContent = new LocalizedText
						{
							UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase<string>)(object)ChainedReactor.m_overrideCodes)[waveDatum.WaveIndex].ToUpper()),
							Id = 0u
						}
					};
					EOSLogger.Debug($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Log generated.");
				}
				waveData.HasVerificationTerminal = true;
				waveData.VerificationTerminalSerial = val2.ItemKey;
				val2.AddLocalLog(val3, true);
				EOSTerminalUtils.ResetInitialOutput(val2);
				EOSLogger.Debug($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} verification overriden");
			}
		}

		private void SetupWaves()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			LG_WardenObjective_Reactor chainedReactor = ChainedReactor;
			eDimensionIndex dimensionIndex = chainedReactor.SpawnNode.m_dimension.DimensionIndex;
			LG_LayerType layerType = chainedReactor.SpawnNode.LayerType;
			int num = 0;
			for (int i = 0; i < WaveData.Count; i++)
			{
				ReactorWaveData reactorWave = ObjectiveData.ReactorWaves[i];
				WaveOverride waveOverride = WaveData[i];
				switch (waveOverride.VerificationType)
				{
				case EOSReactorVerificationType.BY_SPECIAL_COMMAND:
					if (!reactorWave.HasVerificationTerminal)
					{
						waveOverride.VerifyTerminal = ChainedReactor.m_terminal;
						AddVerifyCommand(ChainedReactor.m_terminal);
					}
					else
					{
						LG_ComputerTerminal val = waveOverride.VerifyTerminal;
						if ((Object)(object)val == (Object)null)
						{
							val = EOSTerminalUtils.FindTerminal(dimensionIndex, layerType, reactorWave.ZoneForVerification, (Predicate<LG_ComputerTerminal>)((LG_ComputerTerminal terminal) => terminal.ItemKey.Equals(reactorWave.VerificationTerminalSerial, StringComparison.InvariantCultureIgnoreCase)))?[0];
							if ((Object)(object)val == (Object)null)
							{
								EOSLogger.Error($"SetupWaves: cannot find verify terminal for Wave_{i}, skipped");
								break;
							}
							waveOverride.VerifyTerminal = val;
						}
						val.ConnectedReactor = chainedReactor;
						val.RemoveLocalLog(reactorWave.VerificationTerminalFileName.ToUpperInvariant());
						AddVerifyCommand(val);
						EOSTerminalUtils.ResetInitialOutput(val);
					}
					num++;
					EOSLogger.Debug($"WaveOverride: Setup as Wave Verification {1} for Wave_{i}");
					break;
				default:
					EOSLogger.Error($"Unimplemented Verification Type {waveOverride.VerificationType}");
					break;
				case EOSReactorVerificationType.NORMAL:
				case EOSReactorVerificationType.BY_WARDEN_EVENT:
					break;
				}
			}
			if (num == ObjectiveData.ReactorWaves.Count)
			{
				ChainedReactor.m_terminal.TrySyncSetCommandHidden((TERM_Command)22);
			}
		}

		private void ApplyCodeWordOverrides()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: 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_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected O, but got Unknown
			//IL_0295: Expected O, but got Unknown
			bool flag = (int)overrideData.CodeWordLength != 4;
			bool useHardLogFilenameSuffix = overrideData.UseHardLogFilenameSuffix;
			if (!flag && !useHardLogFilenameSuffix)
			{
				return;
			}
			if (flag)
			{
				string[] array = new string[((Il2CppArrayBase<string>)(object)ChainedReactor.m_overrideCodes).Length];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = SerialGeneratorManager.GetCodeWord(overrideData.CodeWordLength);
				}
				ChainedReactor.m_overrideCodes = Il2CppStringArray.op_Implicit(array);
			}
			foreach (WaveOverride waveDatum in WaveData)
			{
				if (waveDatum.WaveIndex < 0 || waveDatum.WaveIndex >= ObjectiveData.ReactorWaves.Count)
				{
					continue;
				}
				ReactorWaveData waveData = ObjectiveData.ReactorWaves[waveDatum.WaveIndex];
				if (!waveData.HasVerificationTerminal)
				{
					continue;
				}
				LG_ComputerTerminal val = waveDatum.VerifyTerminal;
				if ((Object)(object)val == (Object)null)
				{
					List<LG_ComputerTerminal> list = EOSTerminalUtils.FindTerminal(ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, waveData.ZoneForVerification, (Predicate<LG_ComputerTerminal>)((LG_ComputerTerminal x) => x.ItemKey.Equals(waveData.VerificationTerminalSerial, StringComparison.InvariantCultureIgnoreCase)));
					if (list == null || list.Count == 0)
					{
						EOSLogger.Error($"ApplyCodeWordOverrides: cannot find verify terminal for Wave_{waveDatum.WaveIndex}, skipped");
						continue;
					}
					val = list[0];
				}
				val.RemoveLocalLog(waveData.VerificationTerminalFileName.ToUpperInvariant());
				if (useHardLogFilenameSuffix)
				{
					waveData.VerificationTerminalFileName = "reactor_ver" + SerialGeneratorManager.GetCodeWordPrefix(true, false) + ".log";
				}
				TerminalLogFileData val2 = new TerminalLogFileData
				{
					FileName = waveData.VerificationTerminalFileName.ToUpperInvariant(),
					FileContent = new LocalizedText
					{
						UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase<string>)(object)ChainedReactor.m_overrideCodes)[waveDatum.WaveIndex].ToUpperInvariant()),
						Id = 0u
					}
				};
				val.AddLocalLog(val2, true);
				EOSTerminalUtils.ResetInitialOutput(val);
			}
		}

		private void AddVerifyCommand(LG_ComputerTerminal terminal)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			LG_ComputerTerminalCommandInterpreter command = terminal.m_command;
			if (command.HasRegisteredCommand((TERM_Command)42))
			{
				EOSLogger.Debug("TERM_Command.UniqueCommand5 already registered. If this terminal is specified as objective terminal for 2 waves and the number of commands in 'UniqueCommands' on this terminal isn't more than 4, simply ignore this message.");
				return;
			}
			command.AddCommand((TERM_Command)42, "REACTOR_COOLDOWN", new LocalizedText
			{
				UntranslatedText = ReactorStartupOverrideManager.CoolDownCommandDesc,
				Id = 0u
			}, (TERM_CommandRule)0);
			terminal.TrySyncSetCommandRule((TERM_Command)42, (TERM_CommandRule)0);
		}

		public bool IsCorrectTerminal(LG_ComputerTerminal terminal)
		{
			int num = ChainedReactor.m_currentWaveCount - 1;
			if (num >= 0)
			{
				EOSLogger.Debug($"Index: {num}");
				EOSLogger.Debug("Comp Terminal Key1: " + terminal.ItemKey);
				EOSLogger.Debug("Comp Terminal Key2: " + (((Object)(object)WaveData[num].VerifyTerminal != (Object)null) ? WaveData[num].VerifyTerminal.ItemKey : "empty"));
				if (WaveData[num].VerifyTerminal.ItemKey != null && WaveData[num].VerifyTerminal.ItemKey.Equals(terminal.ItemKey, StringComparison.InvariantCultureIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		public void SetIdle()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ChainedReactor == (Object)null))
			{
				pReactorState state = new pReactorState
				{
					status = (eReactorStatus)0,
					stateCount = 0,
					stateProgress = 0f,
					verifyFailed = false
				};
				ChainedReactor.m_stateReplicator.State = state;
			}
		}

		private void OnDestroy()
		{
			LevelAPI.OnEnterLevel -= OnEnterLevel;
			ChainedReactor = null;
			overrideData = null;
		}

		private void LateUpdate()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)GameStateManager.CurrentStateName == 10)
			{
				eReactorStatus status = ChainedReactor.m_currentState.status;
				if (UsingLightEffect)
				{
					UpdateLight(status, ChainedReactor.m_currentWaveProgress);
				}
				UpdateGUIText(status);
			}
		}

		private void UpdateGUIText(eReactorStatus status)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Invalid comparison between Unknown and I4
			int num = ChainedReactor.m_currentWaveCount - 1;
			if (num < 0)
			{
				return;
			}
			WaveOverride waveOverride = WaveData[num];
			string format = string.Empty;
			if (waveOverride.UseCustomVerifyText)
			{
				format = ((waveOverride.VerifySequenceText.Id != 0) ? Text.Get(waveOverride.VerifySequenceText.Id) : waveOverride.VerifySequenceText.UntranslatedText);
			}
			if ((int)status != 4)
			{
				return;
			}
			switch (waveOverride.VerificationType)
			{
			case EOSReactorVerificationType.NORMAL:
				if (ChainedReactor.m_currentWaveData.HasVerificationTerminal)
				{
					if (!waveOverride.UseCustomVerifyText)
					{
						format = Text.Get(1103u);
					}
					ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "<color=orange>" + ChainedReactor.m_currentWaveData.VerificationTerminalSerial + "</color>"), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>");
				}
				else
				{
					if (!waveOverride.UseCustomVerifyText)
					{
						format = Text.Get(1105u);
					}
					ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "<color=orange>" + ChainedReactor.CurrentStateOverrideCode + "</color>"), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>");
				}
				break;
			case EOSReactorVerificationType.BY_SPECIAL_COMMAND:
			{
				string text = (ChainedReactor.m_currentWaveData.HasVerificationTerminal ? ChainedReactor.m_currentWaveData.VerificationTerminalSerial : ReactorStartupOverrideManager.MainTerminalText);
				if (!waveOverride.UseCustomVerifyText)
				{
					format = ReactorStartupOverrideManager.SpecialCmdVerifyText;
				}
				ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "<color=orange>" + text + "</color>"), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>");
				break;
			}
			case EOSReactorVerificationType.BY_WARDEN_EVENT:
				if (!waveOverride.UseCustomVerifyText)
				{
					format = ReactorStartupOverrideManager.InfiniteWaveVerifyText;
				}
				ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>");
				break;
			}
		}

		private void UpdateLight(eReactorStatus status, float progress)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected I4, but got Unknown
			//IL_004b: 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)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if (!(_updateTimer > Clock.Time))
			{
				_updateTimer = Clock.Time + 0.15f;
				switch (status - 1)
				{
				case 0:
					SetLightColor(Color.black);
					break;
				case 1:
					SetLightColor(Color.Lerp(LowTemperature, HighTemperature, progress));
					break;
				case 2:
					SetLightColor(Color.Lerp(HighTemperature, LowTemperature, progress));
					break;
				case 3:
					SetLightColor(LowTemperature);
					break;
				case 4:
					SetLightColor(LowTemperature);
					break;
				}
			}
		}

		private void SetLightColor(Color color)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (UsingLightEffect && _lights != null)
			{
				for (int i = 0; i < _lights.Length; i++)
				{
					_lights[i].ChangeColor(color);
				}
			}
		}

		static OverrideReactorComp()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			LowTemperature = ColorExt.Hex("#23E4F2") * 2.5f;
			HighTemperature = ColorExt.Hex("#F63838") * 12f;
		}
	}
}

plugins/Inas07.EOSExt.SecDoor.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using EOSExt.SecDoor.Definition;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.Utils;
using GTFO.API;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Il2CppSystem.Text;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.SecDoor
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.EOSExt.SecDoor", "EOSExt.SecDoor", "1.1.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.SecDoor";

		public const string VERSION = "1.1.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			SetupManagers();
			m_Harmony = new Harmony("EOSExt.SecDoor");
			m_Harmony.PatchAll();
			EOSLogger.Log("ExtraObjectiveSetup.SecDoor loaded.");
		}

		private void SetupManagers()
		{
			((ZoneDefinitionManager<SecDoorIntTextOverride>)SecDoorIntTextOverrideManager.Current).Init();
		}
	}
	public class InteractGlitchManager : MonoBehaviour
	{
		private const string HEX_CHARPOOL = "0123456789ABCDEF";

		private const string ERR_CHARPOOL = "$#/-01";

		private Random Random = new Random();

		private float _Timer;

		private uint START_SECURITY_SCAN_SEQUENCE_TEXT_ID;

		private uint HOLD_TEXT_ID;

		private uint SCAN_UNKNOWN_TEXT_DB;

		public static InteractGlitchManager Current { get; }

		internal bool Enabled { get; set; }

		internal bool CanInteract { get; set; }

		private StringBuilder _StrBuilder { get; } = new StringBuilder();

		internal GlitchMode Mode { get; set; }

		private Dictionary<IntPtr, LG_SecurityDoor> DoorLocks { get; } = new Dictionary<IntPtr, LG_SecurityDoor>();

		private void Update()
		{
			if (Enabled && !(_Timer > Clock.Time) && GuiManager.InteractionLayer != null && Mode != GlitchMode.None)
			{
				switch (Mode)
				{
				case GlitchMode.Style1:
					GuiManager.InteractionLayer.SetInteractPrompt(GetFormat1(), CanInteract ? Text.Format(HOLD_TEXT_ID, (Object[])(object)new Object[1] { Object.op_Implicit(InputMapper.GetBindingName((InputAction)6)) }) : string.Empty, (ePUIMessageStyle)0);
					GuiManager.InteractionLayer.InteractPromptVisible = true;
					_Timer = Clock.Time + 0.05f;
					break;
				case GlitchMode.Style2:
				{
					string format = GetFormat2(Text.Get(START_SECURITY_SCAN_SEQUENCE_TEXT_ID));
					string format2 = GetFormat2(Text.Get(SCAN_UNKNOWN_TEXT_DB));
					GuiManager.InteractionLayer.SetInteractPrompt(format + "<color=red>" + format2 + "</color>", CanInteract ? Text.Format(HOLD_TEXT_ID, (Object[])(object)new Object[1] { Object.op_Implicit(InputMapper.GetBindingName((InputAction)6)) }) : string.Empty, (ePUIMessageStyle)0);
					GuiManager.InteractionLayer.InteractPromptVisible = true;
					_Timer = Clock.Time + 0.075f;
					break;
				}
				}
			}
		}

		private string GetFormat1()
		{
			return "<color=red>://Decryption E_RR at: [" + GetRandomHex() + GetRandomHex() + "-" + GetRandomHex() + GetRandomHex() + "-" + GetRandomHex() + GetRandomHex() + "-" + GetRandomHex() + GetRandomHex() + "]</color>";
		}

		private string GetFormat2(string baseMessage)
		{
			_StrBuilder.Clear();
			foreach (char c in baseMessage)
			{
				if (Random.NextDouble() > 0.009999999776482582 || c == ':')
				{
					_StrBuilder.Append(c);
				}
				else
				{
					_StrBuilder.Append("$#/-01"[Random.Next(0, "$#/-01".Length)]);
				}
			}
			return _StrBuilder.ToString();
		}

		private string GetRandomHex()
		{
			return string.Format("{0}{1}", "0123456789ABCDEF"[Random.Next(0, "0123456789ABCDEF".Length)], "0123456789ABCDEF"[Random.Next(0, "0123456789ABCDEF".Length)]);
		}

		internal void RegisterDoorLocks(LG_SecurityDoor_Locks locks)
		{
			DoorLocks[((Il2CppObjectBase)locks.m_intCustomMessage).Pointer] = locks.m_door;
			DoorLocks[((Il2CppObjectBase)locks.m_intOpenDoor).Pointer] = locks.m_door;
		}

		public GlitchMode GetGlitchMode(Interact_Base interact)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (!DoorLocks.TryGetValue(((Il2CppObjectBase)interact).Pointer, out var value))
			{
				return GlitchMode.None;
			}
			eDimensionIndex dimensionIndex = value.Gate.DimensionIndex;
			LG_LayerType linksToLayerType = value.LinksToLayerType;
			eLocalZoneIndex localIndex = value.LinkedToZoneData.LocalIndex;
			return ((ZoneDefinitionManager<SecDoorIntTextOverride>)SecDoorIntTextOverrideManager.Current).GetDefinition(dimensionIndex, linksToLayerType, localIndex)?.GlitchMode ?? GlitchMode.None;
		}

		private void Clear()
		{
			DoorLocks.Clear();
		}

		private InteractGlitchManager()
		{
			START_SECURITY_SCAN_SEQUENCE_TEXT_ID = ((GameDataBlockBase<TextDataBlock>)(object)GameDataBlockBase<TextDataBlock>.GetBlock("InGame.InteractionPrompt.SecurityDoor.StartSecurityScanSequence"))?.persistentID ?? 0;
			HOLD_TEXT_ID = ((GameDataBlockBase<TextDataBlock>)(object)GameDataBlockBase<TextDataBlock>.GetBlock("InGame.InteractionPrompt.Hold_X"))?.persistentID ?? 0;
			SCAN_UNKNOWN_TEXT_DB = ((GameDataBlockBase<TextDataBlock>)(object)GameDataBlockBase<TextDataBlock>.GetBlock("InGame.InteractionPrompt.SecurityDoor.StartSecurityScanSequence_ScanUnknown"))?.persistentID ?? 0;
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}

		static InteractGlitchManager()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			ClassInjector.RegisterTypeInIl2Cpp<InteractGlitchManager>();
			GameObject val = new GameObject("CONST_InteractGlitchManager");
			Object.DontDestroyOnLoad((Object)(object)val);
			Current = val.AddComponent<InteractGlitchManager>();
		}
	}
	public class SecDoorIntTextOverrideManager : ZoneDefinitionManager<SecDoorIntTextOverride>
	{
		public static SecDoorIntTextOverrideManager Current { get; }

		protected override string DEFINITION_NAME => "SecDoorIntText";

		private SecDoorIntTextOverrideManager()
		{
		}

		static SecDoorIntTextOverrideManager()
		{
			Current = new SecDoorIntTextOverrideManager();
		}
	}
}
namespace EOSExt.SecDoor.Patches
{
	[HarmonyPatch]
	internal class CustomizeSecDoorInteractionText
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_SecurityDoor), "Setup")]
		private static void Post_Customize_SecDoor_Interaction_Text(LG_SecurityDoor __instance)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			eDimensionIndex dimensionIndex = __instance.Gate.DimensionIndex;
			LG_LayerType linksToLayerType = __instance.LinksToLayerType;
			eLocalZoneIndex localIndex = __instance.LinkedToZoneData.LocalIndex;
			SecDoorIntTextOverride def = ((ZoneDefinitionManager<SecDoorIntTextOverride>)SecDoorIntTextOverrideManager.Current).GetDefinition(dimensionIndex, linksToLayerType, localIndex);
			LG_SecurityDoor_Locks obj = ((Il2CppObjectBase)__instance.m_locks).Cast<LG_SecurityDoor_Locks>();
			Interact_Timed intOpenDoor = ((obj != null) ? obj.m_intOpenDoor : null);
			if ((Object)(object)intOpenDoor == (Object)null || def == null || def.GlitchMode != GlitchMode.None)
			{
				return;
			}
			__instance.m_sync.OnDoorStateChange += Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)delegate
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Expected O, but got Unknown
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: 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)
				string text = (string.IsNullOrEmpty(LocalizedText.op_Implicit(def.TextToReplace)) ? intOpenDoor.InteractionMessage : LocalizedText.op_Implicit(def.TextToReplace));
				StringBuilder val = new StringBuilder();
				if (!string.IsNullOrEmpty(LocalizedText.op_Implicit(def.Prefix)))
				{
					val.Append(LocalizedText.op_Implicit(def.Prefix)).AppendLine();
				}
				val.Append(text);
				if (!string.IsNullOrEmpty(LocalizedText.op_Implicit(def.Postfix)))
				{
					val.AppendLine().Append(LocalizedText.op_Implicit(def.Postfix));
				}
				intOpenDoor.InteractionMessage = ((Object)val).ToString();
				EOSLogger.Debug($"SecDoorIntTextOverride: Override IntText. {((GlobalZoneIndex)def).LocalIndex}, {((GlobalZoneIndex)def).LayerType}, {((GlobalZoneIndex)def).DimensionIndex}");
			});
		}
	}
	[HarmonyPatch]
	internal class InteractGlitch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Interact_Timed), "OnSelectedChange")]
		private static void Post_Interact_Timed_OnSelectedChange(Interact_Timed __instance, bool selected)
		{
			Handle((Interact_Base)(object)__instance, selected, canInteract: true);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Interact_MessageOnScreen), "OnSelectedChange")]
		private static void Post_Interact_MessageOnScreen_OnSelectedChange(Interact_MessageOnScreen __instance, bool selected)
		{
			Handle((Interact_Base)(object)__instance, selected, canInteract: false);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_SecurityDoor_Locks), "Setup", new Type[] { typeof(LG_SecurityDoor) })]
		private static void Post_LG_SecurityDoor_Locks_Setup(LG_SecurityDoor_Locks __instance, LG_SecurityDoor door)
		{
			InteractGlitchManager.Current.RegisterDoorLocks(__instance);
		}

		private static void Handle(Interact_Base interact, bool selected, bool canInteract)
		{
			if (selected)
			{
				if (!((Object)(object)interact == (Object)null))
				{
					switch (InteractGlitchManager.Current.GetGlitchMode(interact))
					{
					case GlitchMode.Style1:
						InteractGlitchManager.Current.Enabled = true;
						InteractGlitchManager.Current.CanInteract = canInteract;
						InteractGlitchManager.Current.Mode = GlitchMode.Style1;
						GuiManager.InteractionLayer.InteractPromptVisible = false;
						break;
					case GlitchMode.Style2:
						InteractGlitchManager.Current.Enabled = true;
						InteractGlitchManager.Current.CanInteract = canInteract;
						InteractGlitchManager.Current.Mode = GlitchMode.Style2;
						GuiManager.InteractionLayer.InteractPromptVisible = false;
						break;
					}
				}
			}
			else
			{
				InteractGlitchManager.Current.Enabled = false;
			}
		}
	}
}
namespace EOSExt.SecDoor.Definition
{
	public enum GlitchMode
	{
		None,
		Style1,
		Style2
	}
	public class SecDoorIntTextOverride : GlobalZoneIndex
	{
		public LocalizedText Prefix { get; set; } = null;

		public LocalizedText Postfix { get; set; } = null;

		public LocalizedText TextToReplace { get; set; } = null;

		public GlitchMode GlitchMode { get; set; } = GlitchMode.None;
	}
}

plugins/Inas07.EOSExt.SecuritySensor.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Agents;
using AmorLib.Networking;
using AmorLib.Networking.StateReplicators;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using EOSExt.SecuritySensor.Component;
using EOSExt.SecuritySensor.Definition;
using ExtraObjectiveSetup;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Utils;
using GTFO.API;
using GTFO.API.Extensions;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using TMPro;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.SecuritySensor
{
	internal static class Assets
	{
		public static GameObject CircleSensor { get; private set; }

		public static GameObject MovableSensor { get; private set; }

		public static void Init()
		{
			CircleSensor = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/CircleSensor.prefab");
			MovableSensor = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/MovableSensor.prefab");
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.EOSExt.SecuritySensor", "EOSExt.SecuritySensor", "1.2.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.SecuritySensor";

		public const string VERSION = "1.2.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			SetupManagers();
			AssetAPI.OnAssetBundlesLoaded += Assets.Init;
			m_Harmony = new Harmony("EOSExt.SecuritySensor");
			m_Harmony.PatchAll();
			ClassInjector.RegisterTypeInIl2Cpp<SensorCollider>();
			EOSLogger.Log("ExtraObjectiveSetup.SecuritySensor loaded.");
		}

		private void SetupManagers()
		{
			((GenericExpeditionDefinitionManager<SensorGroupSettings>)SecuritySensorManager.Current).Init();
		}
	}
	public class MovableSensor
	{
		public GameObject movableGO { get; private set; }

		public CP_BasicMovable movingComp { get; private set; }

		private GameObject graphicsGO
		{
			get
			{
				GameObject obj = movableGO;
				return (obj != null) ? ((Component)obj.transform.GetChild(0)).gameObject : null;
			}
		}

		public static MovableSensor Instantiate(SensorSettings sensorSetting)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			if (sensorSetting.MovingPosition.Count < 1)
			{
				EOSLogger.Error("SensorGroup.Instantiate: At least 1 moving position required to setup T-Sensor!");
				return null;
			}
			if (EOSNetworking.AllotReplicatorID() == 0)
			{
				EOSLogger.Error("SensorGroup.Instantiate: replicator ID depleted, cannot create StateReplicator...");
				return null;
			}
			MovableSensor movableSensor = new MovableSensor();
			movableSensor.movableGO = Object.Instantiate<GameObject>(Assets.MovableSensor);
			movableSensor.movingComp = movableSensor.movableGO.GetComponent<CP_BasicMovable>();
			movableSensor.movingComp.Setup();
			Vector3 element = sensorSetting.Position.ToVector3();
			Vector3 val = sensorSetting.MovingPosition.First().ToVector3();
			Vector3 val2 = sensorSetting.MovingPosition.Last().ToVector3();
			IEnumerable<Vector3> source = sensorSetting.MovingPosition.ConvertAll((Vec3 e) => e.ToVector3()).AsEnumerable();
			if (!((Vector3)(ref element)).Equals(val))
			{
				source = source.Prepend(element);
			}
			if (!((Vector3)(ref element)).Equals(val2))
			{
				source = source.Append(element);
			}
			movableSensor.movingComp.ScanPositions = ListExtensions.ToIl2Cpp<Vector3>(source.ToList());
			movableSensor.movingComp.m_amountOfPositions = source.Count() - 1;
			if (sensorSetting.MovingSpeedMulti > 0f)
			{
				CP_BasicMovable obj = movableSensor.movingComp;
				obj.m_movementSpeed *= sensorSetting.MovingSpeedMulti;
			}
			return movableSensor;
		}

		public void StartMoving()
		{
			graphicsGO.SetActive(true);
			movingComp.SyncUpdate();
			movingComp.StartMoving();
		}

		public void ResumeMoving()
		{
			graphicsGO.SetActive(true);
			movingComp.ResumeMovement();
		}

		public void StopMoving()
		{
			movingComp.StopMoving();
			graphicsGO.SetActive(false);
		}

		public void PauseMoving()
		{
			movingComp.PauseMovement();
			graphicsGO.SetActive(false);
		}

		public void Destroy()
		{
			Object.Destroy((Object)(object)movableGO);
			movableGO = null;
			movingComp = null;
		}

		private MovableSensor()
		{
		}
	}
	public enum SensorEventType
	{
		ToggleSensorGroupState = 400,
		ToggleAllSensorGroups
	}
	public sealed class SecuritySensorManager : GenericExpeditionDefinitionManager<SensorGroupSettings>
	{
		private List<SensorGroup> sensorGroups = new List<SensorGroup>();

		internal static readonly SensorSync SyncTrigger;

		public static SecuritySensorManager Current { get; private set; }

		protected override string DEFINITION_NAME => "SecuritySensor";

		public void BuildSensorGroup(SensorGroupSettings sensorGroupSettings)
		{
			int num = ((sensorGroupSettings.Index == uint.MaxValue) ? sensorGroups.Count : ((int)sensorGroupSettings.Index));
			SensorGroup item = SensorGroup.Instantiate(sensorGroupSettings, num);
			sensorGroups.Add(item);
			EOSLogger.Debug($"SensorGroup_{num} built");
		}

		private SensorGroup FindSensorGroup(int groupIndex)
		{
			return sensorGroups.Find((SensorGroup sg) => sg.SensorGroupIndex == groupIndex);
		}

		internal void TriggerSensor(int groupIndex)
		{
			SensorGroup sensorGroup = FindSensorGroup(groupIndex);
			if (sensorGroup == null)
			{
				EOSLogger.Error($"TriggerSensor: invalid SensorGroup index {groupIndex}");
				return;
			}
			sensorGroup.Settings.EventsOnTrigger.ForEach(delegate(WardenObjectiveEventData e)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, e.Trigger, true, 0f);
			});
			EOSLogger.Warning($"TriggerSensor: SensorGroup_{groupIndex} triggered");
		}

		private void BuildSecuritySensor()
		{
			if (base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData))
			{
				base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.ForEach(BuildSensorGroup);
			}
		}

		private void Clear()
		{
			sensorGroups.ForEach(delegate(SensorGroup sg)
			{
				sg.Destroy();
			});
			sensorGroups.Clear();
		}

		private void ToggleSensorGroup(WardenObjectiveEventData e)
		{
			int count = e.Count;
			SensorGroup sensorGroup = FindSensorGroup(count);
			if (sensorGroup == null)
			{
				EOSLogger.Error($"ToggleSensorGroup: invalid SensorGroup index {count}");
			}
			else
			{
				sensorGroup.ChangeToState(e.Enabled ? ActiveState.ENABLED : ActiveState.DISABLED);
			}
		}

		private void ToggleAllSensorGroups(WardenObjectiveEventData e)
		{
			ActiveState state = (e.Enabled ? ActiveState.ENABLED : ActiveState.DISABLED);
			sensorGroups.ForEach(delegate(SensorGroup sg)
			{
				sg.ChangeToState(state);
			});
		}

		private SecuritySensorManager()
		{
			LevelAPI.OnBuildStart += delegate
			{
				Clear();
				BuildSecuritySensor();
			};
			LevelAPI.OnLevelCleanup += Clear;
			EventAPI.OnExpeditionStarted += delegate
			{
				sensorGroups.ForEach(delegate(SensorGroup sg)
				{
					sg.StartMovingMovables();
				});
			};
			EOSWardenEventManager.Current.AddEventDefinition(SensorEventType.ToggleSensorGroupState.ToString(), 400u, (Action<WardenObjectiveEventData>)ToggleSensorGroup);
			EOSWardenEventManager.Current.AddEventDefinition(SensorEventType.ToggleAllSensorGroups.ToString(), 401u, (Action<WardenObjectiveEventData>)ToggleAllSensorGroups);
		}

		static SecuritySensorManager()
		{
			Current = new SecuritySensorManager();
			SyncTrigger = new SensorSync();
			if (!((SyncedEvent<int>)SyncTrigger).IsSetup)
			{
				((SyncedEvent<int>)SyncTrigger).Setup();
			}
		}
	}
	public class SensorGroup
	{
		private List<GameObject> basicSensors = new List<GameObject>();

		private List<MovableSensor> movableSensors = new List<MovableSensor>();

		public int SensorGroupIndex { get; private set; }

		public SensorGroupSettings Settings { get; private set; }

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

		public IEnumerable<GameObject> BasicSensors => basicSensors;

		public IEnumerable<MovableSensor> MovableSensors => movableSensors;

		public ActiveState State => StateReplicator?.State.status ?? ActiveState.ENABLED;

		public void ChangeToState(ActiveState status)
		{
			ChangeToStateUnsynced(new SensorGroupState
			{
				status = status
			});
			EOSLogger.Debug($"ChangeState: SecuritySensorGroup_{SensorGroupIndex} changed to state {status}");
			if (SNet.IsMaster)
			{
				StateReplicator?.SetState(new SensorGroupState
				{
					status = status
				});
			}
		}

		private void OnStateChanged(SensorGroupState oldState, SensorGroupState newState, bool isRecall)
		{
			EOSLogger.Warning($"OnStateChanged: isRecall ? {isRecall}");
			if (isRecall)
			{
				EOSLogger.Debug($"Recalling: SecuritySensorGroup_{SensorGroupIndex} changed to state {newState.status}");
				ChangeToStateUnsynced(newState);
			}
			else if (oldState.status != newState.status)
			{
				ChangeToStateUnsynced(newState);
			}
		}

		private void ChangeToStateUnsynced(SensorGroupState newState)
		{
			switch (newState.status)
			{
			case ActiveState.ENABLED:
				basicSensors.ForEach(delegate(GameObject sensorGO)
				{
					sensorGO.SetActive(true);
				});
				ResumeMovingMovables();
				break;
			case ActiveState.DISABLED:
				PauseMovingMovables();
				basicSensors.ForEach(delegate(GameObject sensorGO)
				{
					sensorGO.SetActive(false);
				});
				break;
			}
		}

		public static SensorGroup Instantiate(SensorGroupSettings sensorGroupSettings, int sensorGroupIndex)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			SensorGroup sensorGroup = new SensorGroup();
			sensorGroup.SensorGroupIndex = sensorGroupIndex;
			sensorGroup.Settings = sensorGroupSettings;
			foreach (SensorSettings item in sensorGroupSettings.SensorGroup)
			{
				Vector3 val = item.Position.ToVector3();
				if (val == Vector3.zeroVector)
				{
					continue;
				}
				GameObject val2 = null;
				switch (item.SensorType)
				{
				case SensorType.BASIC:
					val2 = Object.Instantiate<GameObject>(Assets.CircleSensor);
					sensorGroup.basicSensors.Add(val2);
					break;
				case SensorType.MOVABLE:
				{
					MovableSensor movableSensor = MovableSensor.Instantiate(item);
					if (movableSensor == null)
					{
						EOSLogger.Error("ERROR: failed to build movable sensor");
						continue;
					}
					val2 = movableSensor.movableGO;
					sensorGroup.movableSensors.Add(movableSensor);
					break;
				}
				default:
					EOSLogger.Error($"Unsupported SensorType {item.SensorType}, skipped");
					continue;
				}
				val2.transform.SetPositionAndRotation(val, Quaternion.identityQuaternion);
				float num = 0.16216217f;
				val2.transform.localScale = new Vector3(item.Radius, item.Radius, item.Radius);
				Transform transform = val2.transform;
				transform.localPosition += Vector3.up * num;
				SensorCollider sensorCollider = val2.AddComponent<SensorCollider>();
				sensorCollider.Setup(item, sensorGroup);
				((Component)val2.transform.GetChild(0).GetChild(1)).gameObject.GetComponentInChildren<Renderer>().material.SetColor("_ColorA", item.Color.ToUnityColor());
				Transform child = val2.transform.GetChild(0).GetChild(2);
				GameObject gameObject = ((Component)child.GetChild(0)).gameObject;
				gameObject.transform.SetParent((Transform)null);
				Object.Destroy((Object)(object)gameObject);
				GameObject val3 = VanillaTMPPros.Instantiate(((Component)child).gameObject);
				TextMeshPro component = val3.GetComponent<TextMeshPro>();
				if ((Object)(object)component != (Object)null)
				{
					((TMP_Text)component).SetText(LocalizedText.op_Implicit(item.Text), true);
					Color32 val4 = (((TMP_Text)component).m_fontColor32 = Color32.op_Implicit(item.TextColor.ToUnityColor()));
					((TMP_Text)component).m_fontColor = Color32.op_Implicit(val4);
				}
				else
				{
					EOSLogger.Error("NO TEXT!");
				}
				val2.SetActive(true);
			}
			uint num2 = EOSNetworking.AllotReplicatorID();
			if (num2 == 0)
			{
				EOSLogger.Error("SensorGroup.Instantiate: replicator ID depleted, cannot create StateReplicator...");
			}
			else
			{
				sensorGroup.StateReplicator = StateReplicator<SensorGroupState>.Create(num2, new SensorGroupState
				{
					status = ActiveState.ENABLED
				}, (LifeTimeType)1, (IStateReplicatorHolder<SensorGroupState>)null);
				sensorGroup.StateReplicator.OnStateChanged += sensorGroup.OnStateChanged;
			}
			return sensorGroup;
		}

		public void StartMovingMovables()
		{
			movableSensors.ForEach(delegate(MovableSensor movable)
			{
				movable.StartMoving();
			});
		}

		public void PauseMovingMovables()
		{
			movableSensors.ForEach(delegate(MovableSensor movable)
			{
				movable.PauseMoving();
			});
		}

		public void ResumeMovingMovables()
		{
			movableSensors.ForEach(delegate(MovableSensor movable)
			{
				movable.ResumeMoving();
			});
		}

		public void Destroy()
		{
			basicSensors.ForEach((Action<GameObject>)Object.Destroy);
			basicSensors.Clear();
			movableSensors.ForEach(delegate(MovableSensor m)
			{
				m.Destroy();
			});
			movableSensors.Clear();
			StateReplicator = null;
			Settings = null;
		}

		private SensorGroup()
		{
		}
	}
	public enum ActiveState
	{
		DISABLED,
		ENABLED
	}
	public struct SensorGroupState
	{
		public ActiveState status;

		public SensorGroupState()
		{
			status = ActiveState.DISABLED;
		}

		public SensorGroupState(SensorGroupState o)
		{
			status = o.status;
		}

		public SensorGroupState(ActiveState status)
		{
			this.status = status;
		}
	}
	public struct MovableSensorLerp
	{
		public float lerp;

		public MovableSensorLerp()
		{
			lerp = 0f;
		}

		public MovableSensorLerp(MovableSensorLerp o)
		{
			lerp = o.lerp;
		}

		public MovableSensorLerp(float lerp)
		{
			this.lerp = lerp;
		}
	}
	internal sealed class SensorSync : SyncedEvent<int>
	{
		public override string GUID => "EOS-SensorTrigger";

		protected override void Receive(int packet)
		{
			SecuritySensorManager.Current.TriggerSensor(packet);
		}

		protected override void ReceiveLocal(int packet)
		{
			((SyncedEvent<int>)this).Receive(packet);
		}
	}
}
namespace EOSExt.SecuritySensor.Patches
{
	[HarmonyPatch]
	internal class Debug
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_CollisionWorldEventTrigger), "Update")]
		private static void Post(LG_CollisionWorldEventTrigger __instance)
		{
		}

		static Debug()
		{
		}
	}
}
namespace EOSExt.SecuritySensor.Definition
{
	public class SensorGroupSettings
	{
		public uint Index { get; set; } = uint.MaxValue;

		public List<SensorSettings> SensorGroup { get; set; } = new List<SensorSettings>
		{
			new SensorSettings()
		};

		public List<WardenObjectiveEventData> EventsOnTrigger { get; set; } = new List<WardenObjectiveEventData>();
	}
	public enum SensorType
	{
		BASIC,
		MOVABLE
	}
	public class SensorSettings
	{
		public Vec3 Position { get; set; } = new Vec3();

		public float Radius { get; set; } = 2.3f;

		public EOSColor Color { get; set; } = new EOSColor
		{
			r = 99f / 106f,
			g = 0.1055641f,
			b = 0f,
			a = 0.2627451f
		};

		public LocalizedText Text { get; set; } = new LocalizedText
		{
			Id = 0u,
			UntranslatedText = "S:_EC/uR_ITY S:/Ca_N"
		};

		public EOSColor TextColor { get; set; } = new EOSColor
		{
			r = 0.8862745f,
			g = 46f / 51f,
			b = 0.8980392f,
			a = 0.70980394f
		};

		public SensorType SensorType { get; set; } = SensorType.BASIC;

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

		public List<Vec3> MovingPosition { get; set; } = new List<Vec3>
		{
			new Vec3()
		};
	}
}
namespace EOSExt.SecuritySensor.Component
{
	public class SensorCollider : MonoBehaviour
	{
		private float nextCheckTime = float.NaN;

		private SensorSettings settings;

		private int last_playersInSensor = 0;

		public static float CHECK_INTERVAL { get; } = 0.1f;

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

		public SensorGroup Parent { get; internal set; }

		internal void Setup(SensorSettings sensorSettings, SensorGroup parent)
		{
			settings = sensorSettings;
			Parent = parent;
		}

		private void Update()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if ((int)GameStateManager.CurrentStateName != 10 || (!float.IsNaN(nextCheckTime) && Clock.Time < nextCheckTime))
			{
				return;
			}
			nextCheckTime = Clock.Time + CHECK_INTERVAL;
			if (Parent.State != ActiveState.ENABLED)
			{
				return;
			}
			int num = 0;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (!current.Owner.IsBot && ((Agent)current).Alive)
				{
					Vector3 val = Position - ((Agent)current).Position;
					if (((Vector3)(ref val)).magnitude < settings.Radius)
					{
						num++;
					}
				}
			}
			if (num > last_playersInSensor)
			{
				((SyncedEvent<int>)SecuritySensorManager.SyncTrigger).Send(Parent.SensorGroupIndex, (SNet_Player)null, (SNet_ChannelType)2);
			}
			last_playersInSensor = num;
		}

		private void OnDestroy()
		{
			Parent = null;
			settings = null;
		}
	}
}

plugins/Inas07.LogsCollector.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using LogsCollector.Collector;
using LogsCollector.Patches;
using Microsoft.CodeAnalysis;
using SSS.UnityFileDebug;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LogsCollector
{
	[BepInPlugin("LogsCollector.Plugin", "LogsCollector", "1.0.0")]
	public class Plugin : BasePlugin
	{
		public const string PluginGuid = "LogsCollector.Plugin";

		public const string PluginName = "LogsCollector";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource LogSource;

		internal static ConfigEntry<bool> Enabled;

		public override void Load()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			LogSource = ((BasePlugin)this).Log;
			Enabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "Copy the GTFO session log and the BepInEx logs into BepInEx/logs/<timestamp>/ on every UnityFileDebug.WriteLogToDisk call.");
			if (!Enabled.Value)
			{
				LogSource.LogInfo((object)"Disabled by config, no patch applied.");
				return;
			}
			bool flag = default(bool);
			try
			{
				Harmony val = new Harmony("LogsCollector.Plugin");
				val.PatchAll(typeof(WriteLogToDiskPatch));
				ManualLogSource logSource = LogSource;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("LogsCollector");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("1.0.0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded.");
				}
				logSource.LogInfo(val2);
			}
			catch (Exception ex)
			{
				ManualLogSource logSource2 = LogSource;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(38, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Failed to apply WriteLogToDisk patch: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				logSource2.LogError(val3);
			}
		}
	}
}
namespace LogsCollector.Patches
{
	[HarmonyPatch]
	internal static class WriteLogToDiskPatch
	{
		private static HashSet<string> _before;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(UnityFileDebug), "WriteLogToDisk")]
		private static void Pre_WriteLogToDisk()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			try
			{
				_before = LogCopier.SnapshotGameLogs();
			}
			catch (Exception ex)
			{
				_before = null;
				ManualLogSource logSource = Plugin.LogSource;
				if (logSource != null)
				{
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Snapshot of game logs failed: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					logSource.LogWarning(val);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UnityFileDebug), "WriteLogToDisk")]
		private static void Post_WriteLogToDisk()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			HashSet<string> before = _before;
			_before = null;
			try
			{
				LogCopier.Collect(before);
			}
			catch (Exception ex)
			{
				ManualLogSource logSource = Plugin.LogSource;
				if (logSource != null)
				{
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Collect failed: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					logSource.LogError(val);
				}
			}
		}
	}
}
namespace LogsCollector.Collector
{
	internal static class LogCopier
	{
		private const string GameLogPattern = "GTFO.*.txt";

		private const string SettingsFileName = "GTFO_Settings.txt";

		private const string LogsFolderName = "logs";

		private static readonly TimeSpan FallbackWindow = TimeSpan.FromSeconds(60.0);

		private static readonly string[] BepInExLogFiles = new string[2] { "LogOutput.log", "ErrorLog.log" };

		internal static string GameLogDirectory => Application.persistentDataPath;

		internal static HashSet<string> SnapshotGameLogs()
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			string gameLogDirectory = GameLogDirectory;
			if (!Directory.Exists(gameLogDirectory))
			{
				return hashSet;
			}
			string[] files = Directory.GetFiles(gameLogDirectory, "GTFO.*.txt", SearchOption.TopDirectoryOnly);
			foreach (string path in files)
			{
				string fileName = Path.GetFileName(path);
				if (!string.Equals(fileName, "GTFO_Settings.txt", StringComparison.OrdinalIgnoreCase))
				{
					hashSet.Add(fileName);
				}
			}
			return hashSet;
		}

		internal static void Collect(HashSet<string> before)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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
			string text = FindProducedLog(before);
			string root = Path.Combine(Paths.BepInExRootPath, "logs");
			string text2 = EnsureUniqueDirectory(root, BuildDirectoryName(DateTimeOffset.Now));
			Directory.CreateDirectory(text2);
			bool flag = default(bool);
			if (text == null)
			{
				ManualLogSource logSource = Plugin.LogSource;
				if (logSource != null)
				{
					logSource.LogWarning((object)"No GTFO session log found for this call, only BepInEx logs were copied.");
				}
			}
			else if (TryCopyFile(text, text2))
			{
				ManualLogSource logSource2 = Plugin.LogSource;
				if (logSource2 != null)
				{
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Copied game log: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Path.GetFileName(text));
					}
					logSource2.LogInfo(val);
				}
			}
			else
			{
				ManualLogSource logSource3 = Plugin.LogSource;
				if (logSource3 != null)
				{
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to copy game log: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
					}
					logSource3.LogWarning(val2);
				}
			}
			string[] bepInExLogFiles = BepInExLogFiles;
			foreach (string text3 in bepInExLogFiles)
			{
				string text4 = Path.Combine(Paths.BepInExRootPath, text3);
				if (!File.Exists(text4))
				{
					continue;
				}
				if (TryCopyFile(text4, text2))
				{
					ManualLogSource logSource4 = Plugin.LogSource;
					if (logSource4 != null)
					{
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Copied: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3);
						}
						logSource4.LogInfo(val);
					}
					continue;
				}
				ManualLogSource logSource5 = Plugin.LogSource;
				if (logSource5 != null)
				{
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(16, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to copy: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text4);
					}
					logSource5.LogWarning(val2);
				}
			}
			ManualLogSource logSource6 = Plugin.LogSource;
			if (logSource6 != null)
			{
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Logs collected into: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
				}
				logSource6.LogInfo(val);
			}
		}

		internal static string FindProducedLog(HashSet<string> before)
		{
			string gameLogDirectory = GameLogDirectory;
			if (!Directory.Exists(gameLogDirectory))
			{
				return null;
			}
			string text = null;
			DateTime dateTime = DateTime.MinValue;
			string text2 = null;
			DateTime dateTime2 = DateTime.MinValue;
			DateTime utcNow = DateTime.UtcNow;
			string[] files = Directory.GetFiles(gameLogDirectory, "GTFO.*.txt", SearchOption.TopDirectoryOnly);
			foreach (string text3 in files)
			{
				string fileName = Path.GetFileName(text3);
				if (!string.Equals(fileName, "GTFO_Settings.txt", StringComparison.OrdinalIgnoreCase))
				{
					DateTime lastWriteTimeUtc;
					try
					{
						lastWriteTimeUtc = File.GetLastWriteTimeUtc(text3);
					}
					catch
					{
						continue;
					}
					if ((before == null || !before.Contains(fileName)) && lastWriteTimeUtc > dateTime)
					{
						dateTime = lastWriteTimeUtc;
						text = text3;
					}
					if (lastWriteTimeUtc > dateTime2 && utcNow - lastWriteTimeUtc <= FallbackWindow)
					{
						dateTime2 = lastWriteTimeUtc;
						text2 = text3;
					}
				}
			}
			return text ?? text2;
		}

		internal static string BuildDirectoryName(DateTimeOffset now)
		{
			string text = now.ToString("yyyy-MM-dd_HH-mm-ss", CultureInfo.InvariantCulture);
			string text2 = now.ToString("zzz", CultureInfo.InvariantCulture).Replace(':', '-');
			return text + "_" + text2;
		}

		internal static string EnsureUniqueDirectory(string root, string name)
		{
			string text = Path.Combine(root, name);
			if (!Directory.Exists(text))
			{
				return text;
			}
			for (int i = 2; i < 1000; i++)
			{
				text = Path.Combine(root, $"{name}_{i}");
				if (!Directory.Exists(text))
				{
					return text;
				}
			}
			return Path.Combine(root, $"{name}_{Guid.NewGuid():N}");
		}

		internal static bool TryCopyFile(string source, string targetDirectory)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			try
			{
				if (!File.Exists(source))
				{
					return false;
				}
				string path = Path.Combine(targetDirectory, Path.GetFileName(source));
				using FileStream fileStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
				using FileStream fileStream2 = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
				fileStream.CopyTo(fileStream2);
				fileStream2.Flush();
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource logSource = Plugin.LogSource;
				if (logSource != null)
				{
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(16, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Copy '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(source);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' failed: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					logSource.LogWarning(val);
				}
				return false;
			}
		}
	}
}

plugins/Inas07.ThermalSights.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.Expedition.Gears;
using ExtraObjectiveSetup.JSON;
using ExtraObjectiveSetup.Utils;
using FirstPersonItem;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using ThermalSights.Definition;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ThermalSights
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.ThermalSights", "ThermalSights", "1.1.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "ThermalSights";

		public const string VERSION = "1.1.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			SetupManagers();
			m_Harmony = new Harmony("ThermalSights");
			m_Harmony.PatchAll();
			EOSLogger.Log("ThermalSights loaded.");
		}

		private void SetupManagers()
		{
		}
	}
	public class TSAManager : GenericDefinitionManager<TSADefinition>
	{
		public class PuzzleVisualWrapper
		{
			public GameObject GO { get; set; }

			public Renderer Renderer { get; set; }

			public float Intensity { get; set; }

			public float BehindWallIntensity { get; set; }

			public void SetIntensity(float t)
			{
				if (GO.active)
				{
					if (Intensity > 0f)
					{
						Renderer.material.SetFloat("_Intensity", Intensity * t);
					}
					if (BehindWallIntensity > 0f)
					{
						Renderer.material.SetFloat("_BehindWallIntensity", BehindWallIntensity * t);
					}
				}
			}
		}

		private const bool OUTPUT_THERMAL_SHADER_SETTINGS_ON_WIELD = false;

		private List<PuzzleVisualWrapper> PuzzleVisuals { get; } = new List<PuzzleVisualWrapper>();

		public static TSAManager Current { get; }

		protected override string DEFINITION_NAME => "ThermalSight";

		private Dictionary<uint, Renderer[]> InLevelGearThermals { get; } = new Dictionary<uint, Renderer[]>();

		private HashSet<uint> ModifiedInLevelGearThermals { get; } = new HashSet<uint>();

		private HashSet<uint> ThermalOfflineGears { get; } = new HashSet<uint>();

		public uint CurrentGearPID { get; private set; } = 0u;

		public void RegisterPuzzleVisual(CP_Bioscan_Core core)
		{
			Il2CppArrayBase<Renderer> componentsInChildren = ((Component)core).gameObject.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren == null)
			{
				return;
			}
			List<Renderer> list = ((IEnumerable<Renderer>)componentsInChildren).Where((Renderer comp) => ((Object)((Component)comp).gameObject).name.Equals("Zone")).ToList();
			foreach (Renderer item2 in list)
			{
				GameObject gameObject = ((Component)item2).gameObject;
				float intensity = item2.material.GetFloat("_Intensity");
				float behindWallIntensity = item2.material.GetFloat("_BehindWallIntensity");
				PuzzleVisualWrapper item = new PuzzleVisualWrapper
				{
					GO = gameObject,
					Renderer = item2,
					Intensity = intensity,
					BehindWallIntensity = behindWallIntensity
				};
				PuzzleVisuals.Add(item);
			}
		}

		public void RegisterPuzzleVisual(PuzzleVisualWrapper wrapper)
		{
			PuzzleVisuals.Add(wrapper);
		}

		public void SetPuzzleVisualsIntensity(float t)
		{
			PuzzleVisuals.ForEach(delegate(PuzzleVisualWrapper v)
			{
				v.SetIntensity(t);
			});
		}

		private void CleanupPuzzleVisuals()
		{
			PuzzleVisuals.Clear();
		}

		protected override void FileChanged(LiveEditEventArgs e)
		{
			base.FileChanged(e);
			InitThermalOfflineGears();
			CleanupInLevelGearThermals(keepCurrentGear: true);
			TrySetThermalSightRenderer(CurrentGearPID);
		}

		public override void Init()
		{
			InitThermalOfflineGears();
		}

		private void InitThermalOfflineGears()
		{
			ThermalOfflineGears.Clear();
			foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocks())
			{
				if (((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).internalEnabled && ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).name.ToLowerInvariant().EndsWith("_t"))
				{
					ThermalOfflineGears.Add(((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).persistentID);
				}
			}
			EOSLogger.Debug($"Found OfflineGear with thermal sight, count: {ThermalOfflineGears.Count}");
		}

		private bool TryGetInLevelGearThermalRenderersFromItem(ItemEquippable item, uint gearPID, out Renderer[] renderers)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			renderers = null;
			if (item.GearIDRange == null)
			{
				return false;
			}
			if (gearPID == 0)
			{
				gearPID = ExpeditionGearManager.GetOfflineGearPID(item.GearIDRange);
			}
			if (gearPID == 0 || !IsGearWithThermal(gearPID))
			{
				return false;
			}
			bool flag = false;
			if (!InLevelGearThermals.ContainsKey(gearPID))
			{
				flag = true;
			}
			else
			{
				try
				{
					Vector3 position = ((Component)InLevelGearThermals[gearPID][0]).gameObject.transform.position;
					flag = false;
				}
				catch
				{
					ModifiedInLevelGearThermals.Remove(gearPID);
					flag = true;
				}
			}
			if (flag)
			{
				renderers = (from x in ((IEnumerable<Renderer>)((Component)item).GetComponentsInChildren<Renderer>(true))?.Where((Renderer x) => (Object)(object)x.sharedMaterial != (Object)null && (Object)(object)x.sharedMaterial.shader != (Object)null)
					where ((Object)x.sharedMaterial.shader).name.ToLower().Contains("Thermal".ToLower())
					select x).ToArray() ?? null;
				if (renderers != null)
				{
					if (renderers.Length != 1)
					{
						EOSLogger.Warning(((Item)item).PublicName + " contains more than 1 thermal renderers!");
					}
					InLevelGearThermals[gearPID] = renderers;
					return true;
				}
				EOSLogger.Debug(((Item)item).PublicName + ": thermal renderer not found");
				return false;
			}
			renderers = InLevelGearThermals[gearPID];
			return true;
		}

		internal bool TrySetThermalSightRenderer(uint gearPID = 0u)
		{
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			if (gearPID == 0)
			{
				gearPID = CurrentGearPID;
			}
			if (!IsGearWithThermal(gearPID))
			{
				return false;
			}
			if (ModifiedInLevelGearThermals.Contains(gearPID))
			{
				return true;
			}
			if (base.definitions.TryGetValue(gearPID, out var value) && InLevelGearThermals.TryGetValue(gearPID, out var value2))
			{
				TSADefinition definition = value.Definition;
				TSShader shader = definition.Shader;
				Renderer[] array = value2;
				foreach (Renderer val in array)
				{
					PropertyInfo[] properties = shader.GetType().GetProperties();
					foreach (PropertyInfo propertyInfo in properties)
					{
						Type type = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
						string text = "_" + propertyInfo.Name;
						if (type == typeof(float))
						{
							val.material.SetFloat(text, (float)propertyInfo.GetValue(shader));
						}
						else if (type == typeof(EOSColor))
						{
							EOSColor val2 = (EOSColor)propertyInfo.GetValue(shader);
							val.material.SetVector(text, Color.op_Implicit(val2.ToUnityColor()));
						}
						else if (type == typeof(bool))
						{
							bool flag = (bool)propertyInfo.GetValue(shader);
							val.material.SetFloat(text, flag ? 1f : 0f);
						}
						else if (type == typeof(Vec4))
						{
							Vec4 val3 = (Vec4)propertyInfo.GetValue(shader);
							val.material.SetVector(text, val3.ToVector4());
						}
					}
				}
				ModifiedInLevelGearThermals.Add(gearPID);
				return true;
			}
			return false;
		}

		internal void OnPlayerItemWielded(FirstPersonItemHolder fpsItemHolder, ItemEquippable item)
		{
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Expected O, but got Unknown
			if (item.GearIDRange == null)
			{
				CurrentGearPID = 0u;
				return;
			}
			CurrentGearPID = ExpeditionGearManager.GetOfflineGearPID(item.GearIDRange);
			TryGetInLevelGearThermalRenderersFromItem(item, CurrentGearPID, out var _);
			if (TrySetThermalSightRenderer(CurrentGearPID) || 0 == 0 || !InLevelGearThermals.TryGetValue(CurrentGearPID, out var value))
			{
				return;
			}
			Renderer[] array = value;
			foreach (Renderer val in array)
			{
				TSShader tSShader = new TSShader();
				PropertyInfo[] properties = tSShader.GetType().GetProperties();
				foreach (PropertyInfo propertyInfo in properties)
				{
					Type type = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
					string text = "_" + propertyInfo.Name;
					if (type == typeof(float))
					{
						propertyInfo.SetValue(tSShader, val.material.GetFloat(text));
					}
					else if (type == typeof(EOSColor))
					{
						Vector4 vector = val.material.GetVector(text);
						propertyInfo.SetValue(tSShader, (object?)new EOSColor
						{
							r = vector.x,
							g = vector.y,
							b = vector.z,
							a = vector.w
						});
					}
					else if (type == typeof(bool))
					{
						propertyInfo.SetValue(tSShader, val.material.GetFloat(text) == 1f);
					}
					else if (type == typeof(Vec4))
					{
						Vector4 vector2 = val.material.GetVector(text);
						propertyInfo.SetValue(tSShader, (object?)new Vec4
						{
							x = vector2.x,
							y = vector2.y,
							z = vector2.z,
							w = vector2.w
						});
					}
				}
				EOSLogger.Log($"GearPID: {CurrentGearPID}, shader setting:\n{EOSJson.Serialize<TSShader>(tSShader)}");
			}
		}

		public bool IsGearWithThermal(uint gearPID)
		{
			return ThermalOfflineGears.Contains(gearPID);
		}

		private void CleanupInLevelGearThermals(bool keepCurrentGear = false)
		{
			if (!keepCurrentGear || !InLevelGearThermals.ContainsKey(CurrentGearPID))
			{
				InLevelGearThermals.Clear();
			}
			else
			{
				Renderer[] value = InLevelGearThermals[CurrentGearPID];
				InLevelGearThermals.Clear();
				InLevelGearThermals[CurrentGearPID] = value;
			}
			ModifiedInLevelGearThermals.Clear();
		}

		internal void SetCurrentThermalSightSettings(float t)
		{
			if (InLevelGearThermals.TryGetValue(CurrentGearPID, out var value) && base.definitions.TryGetValue(CurrentGearPID, out var value2))
			{
				Renderer[] array = value;
				foreach (Renderer val in array)
				{
					float zoom = value2.Definition.Shader.Zoom;
					float offAimPixelZoom = value2.Definition.OffAimPixelZoom;
					float num = Mathf.Lerp(zoom, offAimPixelZoom, t);
					val.material.SetFloat("_Zoom", num);
				}
			}
		}

		private void Clear()
		{
			CurrentGearPID = 0u;
			CleanupInLevelGearThermals();
			CleanupPuzzleVisuals();
		}

		private TSAManager()
		{
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}

		static TSAManager()
		{
			Current = new TSAManager();
		}
	}
}
namespace ThermalSights.Patches
{
	internal static class CP_Bioscan_Core_Setup
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")]
		private static void Post_CaptureBioscanVisual(CP_Bioscan_Core __instance)
		{
			TSAManager.Current.RegisterPuzzleVisual(__instance);
		}
	}
	[HarmonyPatch]
	internal static class FPIS_Aim_Update
	{
		public static event Action<FPIS_Aim, float> OnAimUpdate;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FPIS_Aim), "Update")]
		private static void Post_Aim_Update(FPIS_Aim __instance)
		{
			if (!((Object)(object)((FPItemState)__instance).Holder.WieldedItem == (Object)null))
			{
				float num = 1f - FirstPersonItemHolder.m_transitionDelta;
				if (!TSAManager.Current.IsGearWithThermal(TSAManager.Current.CurrentGearPID))
				{
					num = Math.Max(0.05f, num);
				}
				else
				{
					TSAManager.Current.SetCurrentThermalSightSettings(num);
				}
				TSAManager.Current.SetPuzzleVisualsIntensity(num);
				FPIS_Aim_Update.OnAimUpdate?.Invoke(__instance, num);
			}
		}
	}
	[HarmonyPatch]
	internal static class FirstPersonItemHolder_SetWieldedItem
	{
		public static event Action<FirstPersonItemHolder, ItemEquippable> OnItemWielded;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FirstPersonItemHolder), "SetWieldedItem")]
		private static void Post_SetWieldedItem(FirstPersonItemHolder __instance, ItemEquippable item)
		{
			TSAManager.Current.OnPlayerItemWielded(__instance, item);
			TSAManager.Current.SetPuzzleVisualsIntensity(1f);
			TSAManager.Current.SetCurrentThermalSightSettings(1f);
			FirstPersonItemHolder_SetWieldedItem.OnItemWielded?.Invoke(__instance, item);
		}
	}
}
namespace ThermalSights.Definition
{
	public class TSADefinition
	{
		public float OffAimPixelZoom { get; set; } = 1f;

		public TSShader Shader { get; set; } = new TSShader();
	}
	public class TSShader
	{
		[JsonPropertyName("DistanceFalloff")]
		[Range(0.0, 1.0)]
		public float HeatFalloff { get; set; } = 0.01f;

		[Range(0.0, 1.0)]
		public float FogFalloff { get; set; } = 0.1f;

		[JsonPropertyName("PixelZoom")]
		[Range(0.0, 1.0)]
		public float Zoom { get; set; } = 0.8f;

		[JsonPropertyName("AspectRatioAdjust")]
		[Range(0.0, 2.0)]
		public float RatioAdjust { get; set; } = 1f;

		[Range(0.0, 1.0)]
		public float DistortionCenter { get; set; } = 0.5f;

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

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

		public float DistortionSignalSpeed { get; set; } = 0.025f;

		[Range(0.0, 1.0)]
		public float DistortionMin { get; set; } = 0.01f;

		[Range(0.0, 1.0)]
		public float DistortionMax { get; set; } = 0.4f;

		[JsonPropertyName("AmbientTemperature")]
		[Range(0.0, 1.0)]
		public float AmbientTemp { get; set; } = 0.15f;

		[JsonPropertyName("BackgroundTemperature")]
		[Range(0.0, 1.0)]
		public float BackgroundTemp { get; set; } = 0.05f;

		[Range(0.0, 10.0)]
		public float AlbedoColorFactor { get; set; } = 0.5f;

		[Range(0.0, 10.0)]
		public float AmbientColorFactor { get; set; } = 5f;

		public float OcclusionHeat { get; set; } = 0.5f;

		public float BodyOcclusionHeat { get; set; } = 2.5f;

		[Range(0.0, 1.0)]
		public float ScreenIntensity { get; set; } = 0.2f;

		[Range(0.0, 1.0)]
		public float OffAngleFade { get; set; } = 0.95f;

		[Range(0.0, 1.0)]
		public float Noise { get; set; } = 0.1f;

		[JsonPropertyName("MinShadowEnemyDistortion")]
		[Range(0.0, 1.0)]
		public float DistortionMinShadowEnemies { get; set; } = 0.2f;

		[JsonPropertyName("MaxShadowEnemyDistortion")]
		[Range(0.0, 1.0)]
		public float DistortionMaxShadowEnemies { get; set; } = 1f;

		[Range(0.0, 1.0)]
		public float DistortionSignalSpeedShadowEnemies { get; set; } = 1f;

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

		[Range(0.0, 1.0)]
		public float ShadowEnemyHeat { get; set; } = 0.1f;

		public EOSColor ReticuleColorA { get; set; } = new EOSColor
		{
			r = 1f,
			g = 1f,
			b = 1f,
			a = 1f
		};

		public EOSColor ReticuleColorB { get; set; } = new EOSColor
		{
			r = 1f,
			g = 1f,
			b = 1f,
			a = 1f
		};

		public EOSColor ReticuleColorC { get; set; } = new EOSColor
		{
			r = 1f,
			g = 1f,
			b = 1f,
			a = 1f
		};

		[Range(0.0, 20.0)]
		public float SightDirt { get; set; } = 0f;

		public bool LitGlass { get; set; } = false;

		public bool ClipBorders { get; set; } = true;

		public Vec4 AxisX { get; set; } = new Vec4();

		public Vec4 AxisY { get; set; } = new Vec4();

		public Vec4 AxisZ { get; set; } = new Vec4();

		public bool Flip { get; set; } = true;

		[JsonPropertyName("Distance1")]
		[Range(0.0, 100.0)]
		public float ProjDist1 { get; set; } = 100f;

		[JsonPropertyName("Distance2")]
		[Range(0.0, 100.0)]
		public float ProjDist2 { get; set; } = 66f;

		[JsonPropertyName("Distance3")]
		[Range(0.0, 100.0)]
		public float ProjDist3 { get; set; } = 33f;

		[JsonPropertyName("Size1")]
		[Range(0.0, 3.0)]
		public float ProjSize1 { get; set; } = 1f;

		[JsonPropertyName("Size2")]
		[Range(0.0, 3.0)]
		public float ProjSize2 { get; set; } = 1f;

		[JsonPropertyName("Size3")]
		[Range(0.0, 3.0)]
		public float ProjSize3 { get; set; } = 1f;

		[JsonPropertyName("Zeroing")]
		[Range(-1.0, 1.0)]
		public float ZeroOffset { get; set; } = 0f;
	}
}