Decompiled source of Recall v1.0.0

plugins/net6/FloLib.dll

Decompiled 4 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
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 AIGraph;
using AK;
using Agents;
using AssetShards;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using BepInEx.Unity.IL2CPP.Utils;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using FloLib.Attributes;
using FloLib.Events;
using FloLib.Infos;
using FloLib.Infos.Comps;
using FloLib.Networks;
using FloLib.Networks.Inject;
using FloLib.Networks.PayloadStructs;
using FloLib.Utils;
using FloLib.Utils.Comps;
using FloLib.Utils.Extensions;
using GTFO.API;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.InteropTypes.Fields;
using Il2CppInterop.Runtime.Runtime;
using Il2CppSystem;
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.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("FloLib")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+gitd7090d7-dirty-master")]
[assembly: AssemblyProduct("FloLib")]
[assembly: AssemblyTitle("FloLib")]
[assembly: TargetPlatform("Windows7.0")]
[assembly: SupportedOSPlatform("Windows7.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FloLib
{
	public static class Automation
	{
		private const BindingFlags ALL = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenStartGame;

		private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenStartupAssetLoaded;

		private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenEnemyAssetLoaded;

		private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenSharedAssetLoaded;

		private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenAllAssetsLoaded;

		static Automation()
		{
			_InvokeWhenStartGame = new Queue<(MethodInfo, object[])>();
			_InvokeWhenStartupAssetLoaded = new Queue<(MethodInfo, object[])>();
			_InvokeWhenEnemyAssetLoaded = new Queue<(MethodInfo, object[])>();
			_InvokeWhenSharedAssetLoaded = new Queue<(MethodInfo, object[])>();
			_InvokeWhenAllAssetsLoaded = new Queue<(MethodInfo, object[])>();
			StartGameEvent.OnGameLoaded += delegate
			{
				(MethodInfo, object[]) result5;
				while (_InvokeWhenStartGame.TryDequeue(out result5))
				{
					RunMethod(result5.Item1, result5.Item2);
				}
			};
			AssetEvent.OnStartupAssetLoaded += delegate
			{
				(MethodInfo, object[]) result4;
				while (_InvokeWhenStartupAssetLoaded.TryDequeue(out result4))
				{
					RunMethod(result4.Item1, result4.Item2);
				}
			};
			AssetEvent.OnEnemyAssetLoaded += delegate
			{
				(MethodInfo, object[]) result3;
				while (_InvokeWhenEnemyAssetLoaded.TryDequeue(out result3))
				{
					RunMethod(result3.Item1, result3.Item2);
				}
			};
			AssetEvent.OnSharedAssetLoaded += delegate
			{
				(MethodInfo, object[]) result2;
				while (_InvokeWhenSharedAssetLoaded.TryDequeue(out result2))
				{
					RunMethod(result2.Item1, result2.Item2);
				}
			};
			AssetEvent.OnAllAssetsLoaded += delegate
			{
				(MethodInfo, object[]) result;
				while (_InvokeWhenAllAssetsLoaded.TryDequeue(out result))
				{
					RunMethod(result.Item1, result.Item2);
				}
			};
		}

		public static void RegisterTypes()
		{
			Assembly obj = new StackFrame(1).GetMethod()?.GetType()?.Assembly ?? null;
			if (obj == null)
			{
				throw new NullReferenceException("Caller Assembly was null");
			}
			RegisterTypes(obj);
		}

		public static void RegisterTypes(Type target)
		{
			if (target == null)
			{
				throw new ArgumentNullException("target");
			}
			RegisterTypes(target.Assembly);
		}

		public static void RegisterTypes(Assembly target)
		{
			if (target == null)
			{
				throw new ArgumentNullException("target");
			}
			InjectAll(target);
			AddAutoInvokes(target);
		}

		private static void InjectAll(Assembly assem)
		{
			//IL_0069: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			foreach (Type item in assem.GetTypes()?.Where((Type x) => Attribute.IsDefined(x, typeof(AutoInjectAttribute))) ?? Enumerable.Empty<Type>())
			{
				AutoInjectAttribute autoInjectAttribute = (AutoInjectAttribute)Attribute.GetCustomAttribute(item, typeof(AutoInjectAttribute));
				if (autoInjectAttribute.Interfaces.Length != 0)
				{
					RegisterTypeOptions val = new RegisterTypeOptions();
					val.set_Interfaces(Il2CppInterfaceCollection.op_Implicit(autoInjectAttribute.Interfaces));
					val.set_LogSuccess(RegisterTypeOptions.Default.LogSuccess);
					ClassInjector.RegisterTypeInIl2Cpp(item, val);
				}
				else
				{
					ClassInjector.RegisterTypeInIl2Cpp(item);
				}
			}
		}

		private static void AddAutoInvokes(Assembly assem)
		{
			foreach (MethodInfo item in assem.GetTypes()?.SelectMany((Type x) => x.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.Where((MethodInfo x) => x.IsStatic && Attribute.IsDefined(x, typeof(AutoInvokeAttribute))) ?? Enumerable.Empty<MethodInfo>())
			{
				AutoInvokeAttribute obj = (AutoInvokeAttribute)Attribute.GetCustomAttribute(item, typeof(AutoInvokeAttribute));
				object[] arguments = obj.Arguments;
				switch (obj.When)
				{
				case InvokeWhen.PluginLoaded:
					RunMethod(item, arguments);
					break;
				case InvokeWhen.StartGame:
					_InvokeWhenStartGame.Enqueue((item, arguments));
					break;
				case InvokeWhen.StartupAssetLoaded:
					_InvokeWhenStartupAssetLoaded.Enqueue((item, arguments));
					break;
				case InvokeWhen.EnemyAssetLoaded:
					_InvokeWhenEnemyAssetLoaded.Enqueue((item, arguments));
					break;
				case InvokeWhen.SharedAssetLoaded:
					_InvokeWhenSharedAssetLoaded.Enqueue((item, arguments));
					break;
				case InvokeWhen.AllAssetsLoaded:
					_InvokeWhenAllAssetsLoaded.Enqueue((item, arguments));
					break;
				}
			}
		}

		private static void RunMethod(MethodInfo method, params object[] args)
		{
			if (method.IsConstructor)
			{
				RuntimeHelpers.RunClassConstructor(method.DeclaringType.TypeHandle);
			}
			else
			{
				method.Invoke(null, args);
			}
		}
	}
	[BepInPlugin("GTFO.FloLib", "FloLib", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class EntryPoint : BasePlugin
	{
		private Harmony _Harmony;

		public override void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_Harmony = new Harmony("FloLib.Harmony");
			_Harmony.PatchAll();
			Automation.RegisterTypes(((object)this).GetType());
		}

		public override bool Unload()
		{
			_Harmony.UnpatchSelf();
			return ((BasePlugin)this).Unload();
		}
	}
	internal static class Logger
	{
		internal static bool LogExceptionInDetail;

		private static readonly ManualLogSource _Logger;

		static Logger()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_Logger = new ManualLogSource("FloLib");
			Logger.Sources.Add((ILogSource)(object)_Logger);
		}

		private static string Format(object msg)
		{
			return msg.ToString();
		}

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

		public static void Info(string str)
		{
			_Logger.LogMessage((object)str);
		}

		public static void Info(object data)
		{
			_Logger.LogMessage((object)Format(data));
		}

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

		public static void Debug(string str)
		{
			_Logger.LogDebug((object)str);
		}

		public static void Debug(object data)
		{
			_Logger.LogDebug((object)Format(data));
		}

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

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

		public static void Error(object data)
		{
			_Logger.LogError((object)Format(data));
		}

		public static void Fatal(BepInExFatalLogInterpolatedStringHandler handler)
		{
			_Logger.LogFatal(handler);
		}

		public static void Fatal(string str)
		{
			_Logger.LogFatal((object)str);
		}

		public static void Fatal(object data)
		{
			_Logger.LogFatal((object)Format(data));
		}

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

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

		public static void Warn(object data)
		{
			_Logger.LogWarning((object)Format(data));
		}

		[Conditional("DEBUG")]
		public static void DebugOnly(object data)
		{
		}

		public static void Exception(Exception e)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if (LogExceptionInDetail)
			{
				_Logger.LogError((object)e.ToString());
				return;
			}
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(2, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.GetType().Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.Message);
			}
			_Logger.LogError(val);
		}
	}
	internal static class TaskQueue
	{
		public const float INTERVAL = 0.15f;

		private static readonly ConcurrentQueue<(Action action, string? name)> q;

		public static Coroutine mainCoroutine { get; private set; }

		private static IEnumerator MainLoop()
		{
			while (true)
			{
				if (q.TryDequeue(out (Action, string) result))
				{
					CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(ExecuteTask(result.Item1, (result.Item2 == null) ? "unnamed" : result.Item2)), (Action)null);
				}
				yield return (object)new WaitForSeconds(0.15f);
			}
		}

		private static IEnumerator ExecuteTask(Action task, string name)
		{
			bool flag = default(bool);
			try
			{
				task?.Invoke();
			}
			catch (Exception ex)
			{
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(46, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Exception occurred during execution of task ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				Logger.Error(val);
			}
			finally
			{
				BepInExDebugLogInterpolatedStringHandler val2 = new BepInExDebugLogInterpolatedStringHandler(11, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Task ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ended");
				}
				Logger.Debug(val2);
			}
			yield break;
		}

		public static void AddTask(Action task, string name = null)
		{
			q.Enqueue((task, name));
		}

		static TaskQueue()
		{
			q = new ConcurrentQueue<(Action, string)>();
			Logger.Debug("TaskQueue: Coroutine started");
			mainCoroutine = CoroutineManager.StartPersistantCoroutine(CollectionExtensions.WrapToIl2Cpp(MainLoop()));
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.1.3+git35c0c2a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "FloLib";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "gitd7090d7-dirty-master";

		public const string SemVer = "1.0.0+gitd7090d7-dirty-master";

		public const string GitRevShort = "d7090d7-dirty";

		public const string GitRevLong = "d7090d7625ec9ea5a37260ec10ba96729e107216-dirty";

		public const string GitBranch = "master";

		public const string GitTag = null;

		public const int GitCommitsSinceTag = 0;

		public const bool GitIsDirty = true;
	}
}
namespace FloLib.Utils
{
	public enum CoroutineLifeTime
	{
		Forever,
		Lobby,
		Level,
		BetweenRecall
	}
	public static class Coroutines
	{
		private static MonoBehaviour _Runner;

		private static readonly Queue<Coroutine> _Coroutines_Lobby = new Queue<Coroutine>();

		private static readonly Queue<Coroutine> _Coroutines_Level = new Queue<Coroutine>();

		private static readonly Queue<Coroutine> _Coroutines_CPLoad = new Queue<Coroutine>();

		[AutoInvoke(InvokeWhen.StartGame)]
		internal static void Init()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject();
			Object.DontDestroyOnLoad((Object)val);
			_Runner = (MonoBehaviour)(object)val.AddComponent<EmptyMB>();
			LevelAPI.OnLevelCleanup += LevelAPI_OnLevelCleanup;
			Inject_SNet_Capture.OnBufferRecalled += Inject_SNet_Capture_OnBufferRecalled;
		}

		private static void Inject_SNet_Capture_OnBufferRecalled(eBufferType obj)
		{
			StopAll(CoroutineLifeTime.BetweenRecall);
		}

		private static void LevelAPI_OnLevelCleanup()
		{
			StopAll();
			StopAll(CoroutineLifeTime.BetweenRecall);
		}

		public static void StopAll(CoroutineLifeTime lifeTime = CoroutineLifeTime.Level)
		{
			Queue<Coroutine> queue = lifeTime switch
			{
				CoroutineLifeTime.Lobby => _Coroutines_Lobby, 
				CoroutineLifeTime.Level => _Coroutines_Level, 
				CoroutineLifeTime.BetweenRecall => _Coroutines_CPLoad, 
				_ => throw new NotSupportedException($"{"CoroutineLifeTime"}: {lifeTime} is not supported!"), 
			};
			Coroutine result;
			while (queue.TryDequeue(out result))
			{
				_Runner.StopCoroutine(result);
			}
		}

		public static void Stop(Coroutine coroutine)
		{
			_Runner.StopCoroutine(coroutine);
		}

		public static Coroutine Start(IEnumerator coroutine, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever)
		{
			switch (lifeTime)
			{
			case CoroutineLifeTime.Forever:
				return MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine);
			case CoroutineLifeTime.Lobby:
			{
				Coroutine val = MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine);
				_Coroutines_Lobby.Enqueue(val);
				return val;
			}
			case CoroutineLifeTime.Level:
			{
				Coroutine val = MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine);
				_Coroutines_Level.Enqueue(val);
				return val;
			}
			case CoroutineLifeTime.BetweenRecall:
			{
				Coroutine val = MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine);
				_Coroutines_CPLoad.Enqueue(val);
				return val;
			}
			default:
				throw new NotSupportedException($"{"CoroutineLifeTime"}: {lifeTime} is not supported!!");
			}
		}

		public static Coroutine DoWait(float delay, Action onDone, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever)
		{
			return Start(Wait(delay, onDone), lifeTime);
		}

		public static Coroutine DoWaitRealtime(float delay, Action onDone, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever)
		{
			return Start(WaitRealtime(delay, onDone), lifeTime);
		}

		public static Coroutine DoBlink(BlinkInfo blinkInfo, Action<bool> onBlinkChanged, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever)
		{
			return Start(Blink(blinkInfo, onBlinkChanged), lifeTime);
		}

		public static Coroutine DoLerp(LerpInfo lerpInfo, Action<float> onValueChanged, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever)
		{
			return Start(Lerp(lerpInfo, onValueChanged), lifeTime);
		}

		public static IEnumerator Wait(float delay, Action onDone)
		{
			yield return (object)new WaitForSeconds(delay);
			onDone?.Invoke();
		}

		public static IEnumerator WaitRealtime(float delay, Action onDone)
		{
			yield return (object)new WaitForSecondsRealtime(delay);
			onDone?.Invoke();
		}

		public static IEnumerator Blink(BlinkInfo info, Action<bool> onBlinkChanged)
		{
			float time = 0f;
			bool lastCond = false;
			onBlinkChanged?.Invoke(obj: false);
			while (time < info.Duration)
			{
				bool flag = BlinkByProgress(Mathf.Repeat(time * info.Speed, 1f));
				if (flag != lastCond)
				{
					onBlinkChanged?.Invoke(flag);
					lastCond = flag;
				}
				time += Time.deltaTime;
				yield return null;
			}
			onBlinkChanged?.Invoke(info.EndBlinkState);
		}

		public static IEnumerator Lerp(LerpInfo info, Action<float> onValueChanged)
		{
			float time = 0f;
			onValueChanged?.Invoke(info.From);
			while (time < info.Duration)
			{
				float num = info.Easing.Evaluate(time / info.Duration);
				float obj = Mathf.Lerp(info.From, info.To, num);
				onValueChanged?.Invoke(obj);
				time += Time.deltaTime;
				yield return null;
			}
			onValueChanged?.Invoke(info.To);
		}

		private static bool BlinkByProgress(float progress)
		{
			return progress % 0.25f < 0.125f;
		}
	}
	public struct BlinkInfo
	{
		public bool EndBlinkState;

		public float Speed;

		public float Duration;

		public static readonly BlinkInfo InDefault = new BlinkInfo
		{
			Duration = 0.33f,
			Speed = 3f,
			EndBlinkState = true
		};

		public static readonly BlinkInfo OutDefault = new BlinkInfo
		{
			Duration = 0.33f,
			Speed = 3f,
			EndBlinkState = false
		};
	}
	public struct LerpInfo
	{
		public float From;

		public float To;

		public float Duration;

		public EaseFunc.Type Easing;

		public LerpInfo(float from, float to, float duration, EaseFunc.Type ease = EaseFunc.Type.Linear)
		{
			From = from;
			To = to;
			Duration = duration;
			Easing = ease;
		}
	}
	public static class EaseFunc
	{
		public enum Type : byte
		{
			Linear,
			Zero,
			One,
			InQuad,
			OutQuad,
			InOutQuad,
			InCubic,
			OutCubic,
			InOutCubic,
			InQuart,
			OutQuart,
			InOutQuart,
			InQuint,
			OutQuint,
			InOutQuint,
			InSine,
			OutSine,
			InOutSine,
			InExpo,
			OutExpo,
			InOutExpo,
			InCirc,
			OutCirc,
			InOutCirc,
			InElastic,
			OutElastic,
			InOutElastic,
			InBack,
			OutBack,
			InOutBack,
			InBounce,
			OutBounce,
			InOutBounce
		}

		public static float Evaluate(this Type type, float t)
		{
			t = Mathf.Clamp01(t);
			return type switch
			{
				Type.Linear => t, 
				Type.Zero => 0f, 
				Type.One => 1f, 
				Type.InQuad => InQuad(t), 
				Type.OutQuad => OutQuad(t), 
				Type.InOutQuad => InOutQuad(t), 
				Type.InCubic => InCubic(t), 
				Type.OutCubic => OutCubic(t), 
				Type.InOutCubic => InOutCubic(t), 
				Type.InQuart => InQuart(t), 
				Type.OutQuart => OutQuart(t), 
				Type.InOutQuart => InOutQuart(t), 
				Type.InQuint => InQuint(t), 
				Type.OutQuint => OutQuint(t), 
				Type.InOutQuint => InOutQuint(t), 
				Type.InSine => InSine(t), 
				Type.OutSine => OutSine(t), 
				Type.InOutSine => InOutSine(t), 
				Type.InExpo => InExpo(t), 
				Type.OutExpo => OutExpo(t), 
				Type.InOutExpo => InOutExpo(t), 
				Type.InCirc => InCirc(t), 
				Type.OutCirc => OutCirc(t), 
				Type.InOutCirc => InOutCirc(t), 
				Type.InElastic => InElastic(t), 
				Type.OutElastic => OutElastic(t), 
				Type.InOutElastic => InOutElastic(t), 
				Type.InBack => InBack(t), 
				Type.OutBack => OutBack(t), 
				Type.InOutBack => InOutBack(t), 
				Type.InBounce => InBounce(t), 
				Type.OutBounce => OutBounce(t), 
				Type.InOutBounce => InOutBounce(t), 
				_ => throw new ArgumentOutOfRangeException("type", "Given type was invalid!"), 
			};
		}

		public static float InQuad(float t)
		{
			return t * t;
		}

		public static float OutQuad(float t)
		{
			return 1f - InQuad(1f - t);
		}

		public static float InOutQuad(float t)
		{
			if ((double)t < 0.5)
			{
				return InQuad(t * 2f) / 2f;
			}
			return 1f - InQuad((1f - t) * 2f) / 2f;
		}

		public static float InCubic(float t)
		{
			return t * t * t;
		}

		public static float OutCubic(float t)
		{
			return 1f - InCubic(1f - t);
		}

		public static float InOutCubic(float t)
		{
			if ((double)t < 0.5)
			{
				return InCubic(t * 2f) / 2f;
			}
			return 1f - InCubic((1f - t) * 2f) / 2f;
		}

		public static float InQuart(float t)
		{
			return t * t * t * t;
		}

		public static float OutQuart(float t)
		{
			return 1f - InQuart(1f - t);
		}

		public static float InOutQuart(float t)
		{
			if ((double)t < 0.5)
			{
				return InQuart(t * 2f) / 2f;
			}
			return 1f - InQuart((1f - t) * 2f) / 2f;
		}

		public static float InQuint(float t)
		{
			return t * t * t * t * t;
		}

		public static float OutQuint(float t)
		{
			return 1f - InQuint(1f - t);
		}

		public static float InOutQuint(float t)
		{
			if ((double)t < 0.5)
			{
				return InQuint(t * 2f) / 2f;
			}
			return 1f - InQuint((1f - t) * 2f) / 2f;
		}

		public static float InSine(float t)
		{
			return (float)(0.0 - Math.Cos((double)t * Math.PI / 2.0));
		}

		public static float OutSine(float t)
		{
			return (float)Math.Sin((double)t * Math.PI / 2.0);
		}

		public static float InOutSine(float t)
		{
			return (float)(Math.Cos((double)t * Math.PI) - 1.0) / -2f;
		}

		public static float InExpo(float t)
		{
			return (float)Math.Pow(2.0, 10f * (t - 1f));
		}

		public static float OutExpo(float t)
		{
			return 1f - InExpo(1f - t);
		}

		public static float InOutExpo(float t)
		{
			if ((double)t < 0.5)
			{
				return InExpo(t * 2f) / 2f;
			}
			return 1f - InExpo((1f - t) * 2f) / 2f;
		}

		public static float InCirc(float t)
		{
			return 0f - ((float)Math.Sqrt(1f - t * t) - 1f);
		}

		public static float OutCirc(float t)
		{
			return 1f - InCirc(1f - t);
		}

		public static float InOutCirc(float t)
		{
			if ((double)t < 0.5)
			{
				return InCirc(t * 2f) / 2f;
			}
			return 1f - InCirc((1f - t) * 2f) / 2f;
		}

		public static float InElastic(float t)
		{
			return 1f - OutElastic(1f - t);
		}

		public static float OutElastic(float t)
		{
			float num = 0.3f;
			return (float)Math.Pow(2.0, -10f * t) * (float)Math.Sin((double)(t - num / 4f) * (Math.PI * 2.0) / (double)num) + 1f;
		}

		public static float InOutElastic(float t)
		{
			if ((double)t < 0.5)
			{
				return InElastic(t * 2f) / 2f;
			}
			return 1f - InElastic((1f - t) * 2f) / 2f;
		}

		public static float InBack(float t)
		{
			float num = 1.70158f;
			return t * t * ((num + 1f) * t - num);
		}

		public static float OutBack(float t)
		{
			return 1f - InBack(1f - t);
		}

		public static float InOutBack(float t)
		{
			if ((double)t < 0.5)
			{
				return InBack(t * 2f) / 2f;
			}
			return 1f - InBack((1f - t) * 2f) / 2f;
		}

		public static float InBounce(float t)
		{
			return 1f - OutBounce(1f - t);
		}

		public static float OutBounce(float t)
		{
			float num = 2.75f;
			float num2 = 7.5625f;
			if (t < 1f / num)
			{
				return num2 * t * t;
			}
			if (t < 2f / num)
			{
				t -= 1.5f / num;
				return num2 * t * t + 0.75f;
			}
			if ((double)t < 2.5 / (double)num)
			{
				t -= 2.25f / num;
				return num2 * t * t + 0.9375f;
			}
			t -= 2.625f / num;
			return num2 * t * t + 63f / 64f;
		}

		public static float InOutBounce(float t)
		{
			if ((double)t < 0.5)
			{
				return InBounce(t * 2f) / 2f;
			}
			return 1f - InBounce((1f - t) * 2f) / 2f;
		}
	}
	public static class EasyDetour
	{
		public unsafe delegate void StaticVoidDelegate(Il2CppMethodInfo* methodInfo);

		public unsafe delegate void InstanceVoidDelegate(IntPtr instancePtr, Il2CppMethodInfo* methodInfo);

		public static bool TryCreate<T>(DetourDescriptor descriptor, T to, out T originalCall, out INativeDetour detourInstance) where T : Delegate
		{
			try
			{
				nint methodPointer = descriptor.GetMethodPointer();
				detourInstance = INativeDetour.CreateAndApply<T>((IntPtr)methodPointer, to, ref originalCall);
				return detourInstance != null;
			}
			catch (Exception ex)
			{
				Logger.Error("Exception Thrown while creating Detour:");
				Logger.Error(ex.ToString());
			}
			originalCall = null;
			detourInstance = null;
			return false;
		}
	}
	public struct DetourDescriptor
	{
		public Type Type;

		public Type ReturnType;

		public Type[] ArgTypes;

		public string MethodName;

		public bool IsGeneric;

		public unsafe nint GetMethodPointer()
		{
			if (Type == null)
			{
				throw new MissingFieldException("Field Type is not set!");
			}
			if (ReturnType == null)
			{
				throw new MissingFieldException("Field ReturnType is not set! If you mean 'void' do typeof(void)");
			}
			if (string.IsNullOrEmpty(MethodName))
			{
				throw new MissingFieldException("Field MethodName is not set or valid!");
			}
			Il2CppType.From(Type, true);
			IntPtr nativeClassPointer = Il2CppClassPointerStore.GetNativeClassPointer(Type);
			string fullName = GetFullName(ReturnType);
			string[] array;
			if (ArgTypes == null || ArgTypes.Length == 0)
			{
				array = Array.Empty<string>();
			}
			else
			{
				int num = ArgTypes.Length;
				array = new string[num];
				for (int i = 0; i < num; i++)
				{
					Type type = ArgTypes[i];
					array[i] = GetFullName(type);
				}
			}
			void** ptr = (void**)IL2CPP.GetIl2CppMethod(nativeClassPointer, IsGeneric, MethodName, fullName, array).ToPointer();
			if (ptr == null)
			{
				return (nint)ptr;
			}
			return (nint)(*ptr);
		}

		private static string GetFullName(Type type)
		{
			bool isPointer = type.IsPointer;
			if (isPointer)
			{
				type = type.GetElementType();
			}
			if (type.IsPrimitive || type == typeof(string))
			{
				if (isPointer)
				{
					return type.MakePointerType().FullName;
				}
				return type.FullName;
			}
			Type val = Il2CppType.From(type, true);
			if (isPointer)
			{
				return val.MakePointerType().FullName;
			}
			return val.FullName;
		}
	}
	public struct HalfColor
	{
		public Half R;

		public Half G;

		public Half B;

		public Half A;

		public HalfColor()
		{
			R = (Half)0f;
			G = (Half)0f;
			B = (Half)0f;
			A = (Half)0f;
		}

		public HalfColor(float r, float g, float b, float a)
		{
			R = (Half)r;
			G = (Half)g;
			B = (Half)b;
			A = (Half)a;
		}

		public static implicit operator Color(HalfColor halfCol)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return new Color((float)halfCol.R, (float)halfCol.G, (float)halfCol.B, (float)halfCol.A);
		}

		public static implicit operator HalfColor(Color col)
		{
			//IL_0009: 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_002d: 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)
			HalfColor result = new HalfColor();
			result.R = (Half)col.r;
			result.G = (Half)col.g;
			result.B = (Half)col.b;
			result.A = (Half)col.a;
			return result;
		}
	}
	public struct HalfRGBColor
	{
		public Half R;

		public Half G;

		public Half B;

		public static implicit operator Color(HalfRGBColor halfCol)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			return new Color((float)halfCol.R, (float)halfCol.G, (float)halfCol.B);
		}

		public static implicit operator HalfRGBColor(Color col)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			HalfRGBColor result = default(HalfRGBColor);
			result.R = (Half)col.r;
			result.G = (Half)col.g;
			result.B = (Half)col.b;
			return result;
		}
	}
	public class RNG
	{
		private const int Float01Precision = 2000000000;

		private const float Float01Inv = 5E-10f;

		private static uint _UniqueIDForRandomSeed = 0u;

		private Random _Rand;

		private int _Seed;

		public static GlobalRNG Global { get; private set; } = new GlobalRNG();


		public float Float01 => (float)_Rand.Next(0, 2000000001) * 5E-10f;

		public float FloatMinusOneToPlusOne => (float)_Rand.Next(-2000000000, 2000000001) * 5E-10f;

		public int Int0ToPositive => _Rand.Next(0, int.MaxValue);

		public int Int0ToNegative => _Rand.Next(int.MinValue, 1);

		public int Int => _Rand.Next(int.MinValue, int.MaxValue);

		public RNG()
		{
			if (_UniqueIDForRandomSeed == uint.MaxValue)
			{
				_UniqueIDForRandomSeed = 0u;
			}
			else
			{
				_UniqueIDForRandomSeed++;
			}
			_Seed = $"{_UniqueIDForRandomSeed} {Environment.TickCount64}".GetHashCode();
			_Rand = new Random(_Seed);
		}

		public RNG(int seed)
		{
			_Seed = seed;
			_Rand = new Random(seed);
		}

		public virtual void Reset(int? newSeed = null)
		{
			if (newSeed.HasValue)
			{
				_Seed = newSeed.Value;
			}
			_Rand = new Random(_Seed);
		}

		public bool Probability(float probability)
		{
			if (probability <= 0f)
			{
				return false;
			}
			if (probability >= 1f)
			{
				return true;
			}
			return Float01 < probability;
		}

		public bool OneIn(int cases)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			if (cases <= 0)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(46, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("RNG");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("OneIn");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" received ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(cases);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (0 or negative); fallback to false");
				}
				Logger.Warn(val);
				return false;
			}
			if (cases == 1)
			{
				return true;
			}
			return _Rand.Next(0, cases) == 0;
		}

		public T Choice<T>(params T[] items)
		{
			return Choice((IEnumerable<T>)items);
		}

		public T Choice<T>(IEnumerable<T> items)
		{
			if (IsChoiceHaveSimpleScenarioValue(items, out var value))
			{
				return value;
			}
			int maxValue = items.Count();
			int index = _Rand.Next(0, maxValue);
			return items.ElementAt(index);
		}

		public T[] Choice<T>(IEnumerable<T> items, int count)
		{
			if (IsChoiceHaveSimpleScenarioValue(items, out var value))
			{
				return new T[1] { value };
			}
			return items.OrderBy((T x) => _Rand.NextDouble()).Take(count).ToArray();
		}

		public T WeightedChoice<T>(IEnumerable<(T item, float weight)> itemTuples)
		{
			if (IsChoiceHaveSimpleScenarioValue<(T, float)>(itemTuples, out var value))
			{
				return value.Item1;
			}
			T[] array = itemTuples.Select(((T item, float weight) x) => x.item).ToArray();
			float[] array2 = itemTuples.Select(((T item, float weight) x) => x.weight).ToArray();
			float num = 0f;
			for (int i = 0; i < array2.Length; i++)
			{
				float num2 = array2[i];
				if (num2 <= 0f)
				{
					array2[i] = -1f;
				}
				else
				{
					num = (array2[i] = num + num2);
				}
			}
			if (num <= 0f)
			{
				return Choice(array);
			}
			float num3 = Float01 * num;
			for (int j = 0; j < array2.Length; j++)
			{
				if (j == array2.Length - 1 || num3 <= array2[j])
				{
					return array[j];
				}
			}
			throw new InvalidOperationException("What? this should never happen");
		}

		private static bool IsChoiceHaveSimpleScenarioValue<T>(IEnumerable<T> items, out T value)
		{
			int num = items.Count();
			if (num <= 0)
			{
				throw new ArgumentException("Argument Item Count is 0!", "items");
			}
			if (num == 1)
			{
				value = items.First();
				return true;
			}
			value = default(T);
			return false;
		}
	}
	public sealed class GlobalRNG : RNG
	{
		public sealed override void Reset(int? newSeed = null)
		{
			Logger.Warn("Resetting Seed Value is not allowed on RNG.Global");
		}
	}
}
namespace FloLib.Utils.Extensions
{
	public static class ColorExtension
	{
		public static string ToHex(this Color input)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return "#" + ColorUtility.ToHtmlStringRGB(input);
		}

		public static string ToHexRGBA(this Color input)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return "#" + ColorUtility.ToHtmlStringRGBA(input);
		}

		public static void GetColorInfo(this Color input, out Color baseColor, out float colorMultiplier)
		{
			//IL_000c: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			float num = 0f;
			float num2 = 0f;
			float r = input.r;
			float g = input.g;
			float b = input.b;
			float num3 = Mathf.Abs(r);
			float num4 = Mathf.Abs(g);
			float num5 = Mathf.Abs(b);
			if (num3 > num2)
			{
				num2 = num3;
				num = r;
			}
			if (num4 > num2)
			{
				num2 = num4;
				num = g;
			}
			if (num5 > num2)
			{
				num2 = num5;
				num = b;
			}
			if (num2 > 0f)
			{
				baseColor = new Color(r / num, g / num, b / num, 1f);
				colorMultiplier = num;
			}
			else
			{
				baseColor = Color.black;
				colorMultiplier = 1f;
			}
		}
	}
	public static class ComponentExtension
	{
		public static bool TryGetComp<T>(this Component comp, out T component)
		{
			component = comp.GetComponent<T>();
			return component != null;
		}

		public static bool TryGetVirtualScene(this Component comp, out GUIX_VirtualScene scene)
		{
			GUIX_VirtualSceneLink component = comp.GetComponent<GUIX_VirtualSceneLink>();
			if ((Object)(object)component == (Object)null)
			{
				scene = null;
				return false;
			}
			scene = component.m_virtualScene;
			return (Object)(object)scene != (Object)null;
		}

		public static string GetGameObjectPath(this Component comp)
		{
			return comp.gameObject.GetPath();
		}
	}
	public static class GameObjectExtension
	{
		public static bool TryGetComp<T>(this GameObject obj, out T component)
		{
			component = obj.GetComponent<T>();
			return component != null;
		}

		public static T GetCompInParentOrChild<T>(this GameObject obj)
		{
			T val = obj.GetComponentInParent<T>();
			if (val == null)
			{
				val = obj.GetComponentInChildren<T>();
				if (val == null)
				{
					obj.GetComponent<T>();
				}
			}
			return val;
		}

		public static string GetPath(this GameObject obj)
		{
			string text = "/" + ((Object)obj).name;
			while ((Object)(object)obj.transform.parent != (Object)null)
			{
				obj = ((Component)obj.transform.parent).gameObject;
				text = "/" + ((Object)obj).name + text;
			}
			return text;
		}
	}
	public static class Il2CppBoxingExtension
	{
		public static Object BoxToIl2CppObject(this bool value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Boolean val = default(Boolean);
			val.m_value = value;
			return ((Boolean)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this byte value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Byte val = default(Byte);
			val.m_value = value;
			return ((Byte)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this sbyte value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			SByte val = default(SByte);
			val.m_value = value;
			return ((SByte)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this char value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Char val = default(Char);
			val.m_value = value;
			return ((Char)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this short value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Int16 val = default(Int16);
			val.m_value = value;
			return ((Int16)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this ushort value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			UInt16 val = default(UInt16);
			val.m_value = value;
			return ((UInt16)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this int value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Int32 val = default(Int32);
			val.m_value = value;
			return ((Int32)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this uint value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			UInt32 val = default(UInt32);
			val.m_value = value;
			return ((UInt32)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this long value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Int64 val = default(Int64);
			val.m_value = value;
			return ((Int64)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this ulong value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			UInt64 val = default(UInt64);
			val.m_value = value;
			return ((UInt64)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this float value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Single val = default(Single);
			val.m_value = value;
			return ((Single)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this double value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Double val = default(Double);
			val.m_value = value;
			return ((Double)(ref val)).BoxIl2CppObject();
		}

		public static Object BoxToIl2CppObject(this nint value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			IntPtr val = default(IntPtr);
			val.m_value = value;
			return ((IntPtr)(ref val)).BoxIl2CppObject();
		}
	}
	public static class Il2CppObjectExtension
	{
		public static bool CanCastToType<T>(this Il2CppObjectBase obj) where T : Il2CppObjectBase
		{
			return obj.TryCast<T>() != null;
		}

		public static bool TryCastToType<T>(this Il2CppObjectBase obj, out T result) where T : Il2CppObjectBase
		{
			result = obj.TryCast<T>();
			return result != null;
		}
	}
	public static class LGLightExtension
	{
		public static void SetColor(this IEnumerable<LG_Light> lights, Color color)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			foreach (LG_Light light in lights)
			{
				light.ChangeColor(color);
			}
		}

		public static void SetEnabled(this IEnumerable<LG_Light> lights, bool enabled)
		{
			foreach (LG_Light light in lights)
			{
				light.SetEnabled(enabled);
			}
		}

		public static bool Is(this LG_Light light, LightCategory lightCategory)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			return (int)light.m_category == (int)lightCategory;
		}

		public static bool IsAny(this LG_Light light, params LightCategory[] categories)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			for (int i = 0; i < categories.Length; i++)
			{
				if ((int)light.m_category == (int)categories[i])
				{
					return true;
				}
			}
			return false;
		}
	}
	public enum LightCategory
	{
		General = 0,
		Special = 1,
		Independent = 3,
		Sign = 5,
		Door = 4,
		DoorImportant = 6,
		Emergency = 2
	}
	public static class TerminalExtension
	{
		public static void SetPowered(this LG_ComputerTerminal terminal, bool isPowered)
		{
			terminal.OnProximityExit();
			Interact_ComputerTerminal componentInChildren = ((Component)terminal).GetComponentInChildren<Interact_ComputerTerminal>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Behaviour)componentInChildren).enabled = isPowered;
				((Interact_Base)componentInChildren).SetActive(isPowered);
			}
			GUIX_VirtualSceneLink component = ((Component)terminal).GetComponent<GUIX_VirtualSceneLink>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_virtualScene != (Object)null)
			{
				GUIX_VirtualCamera virtualCamera = component.m_virtualScene.virtualCamera;
				float num = (isPowered ? 0.3f : 0f);
				float num2 = (isPowered ? 1000f : 0f);
				virtualCamera.SetFovAndClip(virtualCamera.paramCamera.fieldOfView, num, num2);
			}
			if ((Object)(object)terminal.m_text != (Object)null)
			{
				((Behaviour)terminal.m_text).enabled = isPowered;
			}
			if (!isPowered)
			{
				PlayerAgent localInteractionSource = terminal.m_localInteractionSource;
				if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger)
				{
					terminal.ExitFPSView();
				}
			}
		}
	}
	public static class VectorExtension
	{
		public static string ToFormattedString(this Vector2 vector)
		{
			//IL_0017: 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)
			return $"x: {vector.x:0.0000}, y: {vector.y:0.0000}";
		}

		public static string ToFormattedString(this Vector3 vector)
		{
			//IL_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			return $"x: {vector.x:0.0000}, y: {vector.y:0.0000} z: {vector.z:0.0000}";
		}

		public static string ToFormattedString(this Vector4 vector)
		{
			//IL_0018: 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_0054: 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)
			return $"x: {vector.x:0.0000}, y: {vector.y:0.0000} z: {vector.z:0.0000} w: {vector.w:0.0000}";
		}
	}
}
namespace FloLib.Utils.Comps
{
	[AutoInject]
	internal sealed class EmptyMB : MonoBehaviour
	{
	}
}
namespace FloLib.Networks
{
	public static class GlobalNetAction<P> where P : struct
	{
		private static string _EventName;

		private static bool _IsSetup;

		public static SNet_ChannelType SendChannel { get; set; }

		public static SNet_Player LastSender { get; private set; }

		public static ulong LastSenderID { get; private set; }

		public static event Action<ulong, P> OnReceive;

		public static event Action<ulong, P> OnReceiveLocally;

		static GlobalNetAction()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			SendChannel = (SNet_ChannelType)2;
			_IsSetup = false;
			Setup();
		}

		public static void Setup()
		{
			if (!_IsSetup)
			{
				_EventName = UName.Get(typeof(P), "NA");
				NetworkAPI.RegisterEvent<P>(_EventName, (Action<ulong, P>)Received);
				_IsSetup = true;
			}
		}

		public static void Send(P payload)
		{
			if (!_IsSetup)
			{
				Logger.Error("Action Wasn't Setup!");
				return;
			}
			SendToLocal(payload);
			TaskQueue.AddTask(delegate
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel);
			}, "GlobalNetAction.Send");
		}

		public static void SendTo(P payload, SNet_Player target)
		{
			if (!_IsSetup)
			{
				Logger.Error("Action Wasn't Setup!");
				return;
			}
			if (target.IsLocal)
			{
				SendToLocal(payload);
				return;
			}
			TaskQueue.AddTask(delegate
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel);
			}, "GlobalNetAction.SendTo");
		}

		public static void SendTo(P payload, SNet_SendGroup group)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!_IsSetup)
			{
				Logger.Error("Action Wasn't Setup!");
				return;
			}
			Enumerator<SNet_Player> enumerator = SNet_PlayerSendGroupManager.GetGroup(group).GetEnumerator();
			while (enumerator.MoveNext())
			{
				SNet_Player current = enumerator.Current;
				SendTo(payload, current);
			}
		}

		private static void SendToLocal(P payload)
		{
			if (!_IsSetup)
			{
				Logger.Error("Action Wasn't Setup!");
				return;
			}
			SNet_Player val = (LastSender = SNet.LocalPlayer);
			if ((Object)(object)val != (Object)null)
			{
				LastSenderID = val.Lookup;
			}
			GlobalNetAction<P>.OnReceive?.Invoke(LastSenderID, payload);
			GlobalNetAction<P>.OnReceiveLocally?.Invoke(LastSenderID, payload);
		}

		private static void Received(ulong sender, P payload)
		{
			if (!_IsSetup)
			{
				Logger.Error("Action Wasn't Setup!");
				return;
			}
			SNet_Player lastSender = default(SNet_Player);
			if (!SNet.Core.TryGetPlayer(sender, ref lastSender, false))
			{
				LastSender = null;
				LastSenderID = 0uL;
				Logger.Error("NetAction sender was invalid!");
			}
			LastSender = lastSender;
			LastSenderID = sender;
			GlobalNetAction<P>.OnReceive?.Invoke(sender, payload);
		}
	}
	public static class GlobalNetMasterAction<P> where P : struct
	{
		public static Func<ulong, P, bool> IsActionValid;

		private static string _AskEventName;

		private static string _EventName;

		private static bool _IsSetup;

		public static SNet_ChannelType SendChannel { get; set; }

		public static SNet_Player LastSender { get; private set; }

		public static ulong LastSenderID { get; private set; }

		public static event Action<ulong, P> OnReceive;

		public static event Action<ulong, P> OnMasterReceive;

		static GlobalNetMasterAction()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			SendChannel = (SNet_ChannelType)2;
			IsActionValid = (ulong sender, P p) => true;
			_IsSetup = false;
			Setup();
		}

		public static void Setup()
		{
			if (!_IsSetup)
			{
				_AskEventName = UName.Get(typeof(P), "NMA0");
				_EventName = UName.Get(typeof(P), "NMA1");
				NetworkAPI.RegisterEvent<P>(_AskEventName, (Action<ulong, P>)ReceivedAsk);
				NetworkAPI.RegisterEvent<P>(_EventName, (Action<ulong, P>)Received);
				_IsSetup = true;
			}
		}

		public static void Ask(P payload)
		{
			if (!_IsSetup)
			{
				Logger.Error("Action Wasn't Setup!");
			}
			else
			{
				if (!SNet.HasMaster)
				{
					return;
				}
				if (SNet.IsMaster)
				{
					Func<ulong, P, bool> isActionValid = IsActionValid;
					if (isActionValid == null || isActionValid(SNet.LocalPlayer.Lookup, payload))
					{
						TaskQueue.AddTask(delegate
						{
							//IL_000b: Unknown result type (might be due to invalid IL or missing references)
							NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel);
						}, "GlobalNetMasterAction.Master");
						GlobalNetMasterAction<P>.OnReceive?.Invoke(SNet.LocalPlayer.Lookup, payload);
						GlobalNetMasterAction<P>.OnMasterReceive?.Invoke(SNet.LocalPlayer.Lookup, payload);
					}
				}
				else
				{
					TaskQueue.AddTask(delegate
					{
						//IL_0010: Unknown result type (might be due to invalid IL or missing references)
						NetworkAPI.InvokeEvent<P>(_AskEventName, payload, SNet.Master, SendChannel);
					}, "GlobalNetMasterAction.Ask.Client");
				}
			}
		}

		private static void ReceivedAsk(ulong sender, P payload)
		{
			if (!_IsSetup)
			{
				Logger.Error("Action Wasn't Setup!");
				return;
			}
			if (!SNet.IsMaster)
			{
				Logger.Error("Non Master Received Ask Action!");
				return;
			}
			Func<ulong, P, bool> isActionValid = IsActionValid;
			if (isActionValid == null || isActionValid(sender, payload))
			{
				TaskQueue.AddTask(delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel);
				}, "GlobalNetMasterAction.ReceivedAsk.Master");
				GlobalNetMasterAction<P>.OnReceive?.Invoke(SNet.LocalPlayer.Lookup, payload);
				GlobalNetMasterAction<P>.OnMasterReceive?.Invoke(sender, payload);
			}
		}

		private static void Received(ulong sender, P payload)
		{
			if (!_IsSetup)
			{
				Logger.Error("Action Wasn't Setup!");
				return;
			}
			SNet_Player lastSender = default(SNet_Player);
			if (!SNet.Core.TryGetPlayer(sender, ref lastSender, false))
			{
				LastSender = null;
				LastSenderID = 0uL;
				Logger.Error("NetMasterAction sender was invalid!");
				return;
			}
			LastSender = lastSender;
			LastSenderID = sender;
			if (!LastSender.IsMaster)
			{
				Logger.Error("Sender was not a master");
			}
			else
			{
				GlobalNetMasterAction<P>.OnReceive?.Invoke(sender, payload);
			}
		}
	}
	internal static class UName
	{
		private static readonly SHA1 SHA = SHA1.Create();

		public static string Get(Type type, string prefix)
		{
			return prefix + GetHash(type.FullName);
		}

		public static string GetHash(string text)
		{
			return Convert.ToBase64String(SHA.ComputeHash(Encoding.Unicode.GetBytes(text + "this is salt text, Awesome!")));
		}
	}
}
namespace FloLib.Networks.Replications
{
	public interface IStateReplicatorHolder<S> where S : struct
	{
		StateReplicator<S> Replicator { get; }

		void OnStateChange(S oldState, S state, bool isRecall);
	}
	public sealed class ReplicatorHandshake
	{
		public delegate void ClientRequestedSyncDel(SNet_Player requestedPlayer);

		public struct Packet
		{
			public uint replicatorID;

			public PacketAction action;
		}

		public enum PacketAction : byte
		{
			Created,
			Destroyed,
			SyncRequest
		}

		public sealed class Data
		{
			public bool SetupOnHost;

			public bool SetupOnClient;
		}

		private readonly Dictionary<uint, Data> _Lookup = new Dictionary<uint, Data>();

		public string EventName { get; private set; }

		public bool IsReadyToSync { get; private set; }

		public event ClientRequestedSyncDel OnClientSyncRequested;

		public static ReplicatorHandshake Create(string guid)
		{
			if (string.IsNullOrWhiteSpace(guid))
			{
				return null;
			}
			string text = "RHs" + guid;
			if (!NetworkAPI.IsEventRegistered(text))
			{
				return new ReplicatorHandshake(text);
			}
			return null;
		}

		private ReplicatorHandshake(string eventName)
		{
			EventName = eventName;
			NetworkAPI.RegisterEvent<Packet>(eventName, (Action<ulong, Packet>)OnSyncAction);
			Inject_OnRecallDone.OnRecallDone += delegate
			{
				foreach (uint replicatorID in _Lookup.Keys)
				{
					TaskQueue.AddTask(delegate
					{
						NetworkAPI.InvokeEvent<Packet>(EventName, new Packet
						{
							replicatorID = replicatorID,
							action = PacketAction.SyncRequest
						}, SNet.Master, (SNet_ChannelType)2);
					}, $"SyncReplicatorID_{replicatorID}");
				}
			};
		}

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

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

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

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

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

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

		private void UpdateSyncState(uint id)
		{
			bool isReadyToSync = IsReadyToSync;
			if (_Lookup.TryGetValue(id, out var value))
			{
				IsReadyToSync = value.SetupOnHost && value.SetupOnClient;
			}
			else
			{
				IsReadyToSync = false;
			}
			if (IsReadyToSync && isReadyToSync != IsReadyToSync && SNet.HasMaster && !SNet.IsMaster)
			{
				TaskQueue.AddTask(delegate
				{
					NetworkAPI.InvokeEvent<Packet>(EventName, new Packet
					{
						replicatorID = id,
						action = PacketAction.SyncRequest
					}, SNet.Master, (SNet_ChannelType)2);
				}, "Client.UpdateSyncState.SyncRequest");
			}
		}
	}
	public delegate void OnReceiveDel<S>(ulong sender, uint replicatorID, S newState) where S : struct;
	public static class StatePayloads
	{
		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
		}

		public static Size GetSizeType(int size)
		{
			Size size2 = Size.State8Byte;
			foreach (object value in Enum.GetValues(typeof(Size)))
			{
				if (size <= (int)value && (int)size2 < (int)value)
				{
					size2 = (Size)value;
					break;
				}
			}
			return size2;
		}

		public static IReplicatorEvent<S> CreateEvent<S>(Size size, string eventName, OnReceiveDel<S> onReceiveCallback) where S : struct
		{
			return size switch
			{
				Size.State4Byte => ReplicatorPayloadWrapper<S, StatePayload4Byte>.Create(eventName, onReceiveCallback), 
				Size.State8Byte => ReplicatorPayloadWrapper<S, StatePayload8Byte>.Create(eventName, onReceiveCallback), 
				Size.State16Byte => ReplicatorPayloadWrapper<S, StatePayload16Byte>.Create(eventName, onReceiveCallback), 
				Size.State32Byte => ReplicatorPayloadWrapper<S, StatePayload32Byte>.Create(eventName, onReceiveCallback), 
				Size.State48Byte => ReplicatorPayloadWrapper<S, StatePayload48Byte>.Create(eventName, onReceiveCallback), 
				Size.State64Byte => ReplicatorPayloadWrapper<S, StatePayload64Byte>.Create(eventName, onReceiveCallback), 
				Size.State80Byte => ReplicatorPayloadWrapper<S, StatePayload80Byte>.Create(eventName, onReceiveCallback), 
				Size.State96Byte => ReplicatorPayloadWrapper<S, StatePayload96Byte>.Create(eventName, onReceiveCallback), 
				Size.State128Byte => ReplicatorPayloadWrapper<S, StatePayload128Byte>.Create(eventName, onReceiveCallback), 
				Size.State196Byte => ReplicatorPayloadWrapper<S, StatePayload196Byte>.Create(eventName, onReceiveCallback), 
				Size.State256Byte => ReplicatorPayloadWrapper<S, StatePayload256Byte>.Create(eventName, onReceiveCallback), 
				_ => null, 
			};
		}

		public static S Get<S>(byte[] bytes, int bytesLength) where S : struct
		{
			int num = Marshal.SizeOf(typeof(S));
			if (num > bytesLength)
			{
				throw new ArgumentException($"StateData Exceed size of {bytesLength} : Unable to Deserialize", "S");
			}
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			Marshal.Copy(bytes, 0, intPtr, num);
			S result = (S)Marshal.PtrToStructure(intPtr, typeof(S));
			Marshal.FreeHGlobal(intPtr);
			return result;
		}

		public static void Set<S>(S stateData, int size, ref byte[] payloadBytes) where S : struct
		{
			if (Marshal.SizeOf(stateData) > size)
			{
				throw new ArgumentException($"StateData Exceed size of {size} : Unable to Serialize", "S");
			}
			byte[] array = new byte[size];
			IntPtr intPtr = Marshal.AllocHGlobal(size);
			Marshal.StructureToPtr(stateData, intPtr, fDeleteOld: false);
			Marshal.Copy(intPtr, array, 0, size);
			Marshal.FreeHGlobal(intPtr);
			payloadBytes = array;
		}
	}
	public interface IReplicatorEvent<S> where S : struct
	{
		string Name { get; }

		bool IsRegistered { get; }

		void Invoke(uint replicatorID, S data);

		void Invoke(uint replicatorID, S data, SNet_ChannelType channelType);

		void Invoke(uint replicatorID, S data, SNet_Player target);

		void Invoke(uint replicatorID, S data, SNet_Player target, SNet_ChannelType channelType);
	}
	public class ReplicatorPayloadWrapper<S, P> : IReplicatorEvent<S> where S : struct where P : struct, IStatePayload
	{
		public string Name { get; private set; }

		public bool IsRegistered { get; private set; }

		public static IReplicatorEvent<S> Create(string eventName, OnReceiveDel<S> onReceiveCallback)
		{
			ReplicatorPayloadWrapper<S, P> replicatorPayloadWrapper = new ReplicatorPayloadWrapper<S, P>();
			replicatorPayloadWrapper.Register(eventName, onReceiveCallback);
			if (!replicatorPayloadWrapper.IsRegistered)
			{
				return null;
			}
			return replicatorPayloadWrapper;
		}

		public void Register(string eventName, OnReceiveDel<S> onReceiveCallback)
		{
			if (!IsRegistered && !NetworkAPI.IsEventRegistered(eventName))
			{
				NetworkAPI.RegisterEvent<P>(eventName, (Action<ulong, P>)delegate(ulong sender, P payload)
				{
					onReceiveCallback?.Invoke(sender, payload.ID, payload.Get<S>());
				});
				IsRegistered = true;
				Name = eventName;
			}
		}

		public void Invoke(uint replicatorID, S data)
		{
			P payload = new P
			{
				ID = replicatorID
			};
			payload.Set(data);
			TaskQueue.AddTask(delegate
			{
				NetworkAPI.InvokeEvent<P>(Name, payload, (SNet_ChannelType)2);
			}, "ReplicatorPayloadWrapper.Invoke(uint, S)");
		}

		public void Invoke(uint replicatorID, S data, SNet_ChannelType channelType)
		{
			//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)
			P payload = new P
			{
				ID = replicatorID
			};
			payload.Set(data);
			TaskQueue.AddTask(delegate
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				NetworkAPI.InvokeEvent<P>(Name, payload, channelType);
			}, "ReplicatorPayloadWrapper.Invoke(uint, S, SNet_ChannelType)");
		}

		public void Invoke(uint replicatorID, S data, SNet_Player target)
		{
			P payload = new P
			{
				ID = replicatorID
			};
			payload.Set(data);
			TaskQueue.AddTask(delegate
			{
				NetworkAPI.InvokeEvent<P>(Name, payload, target, (SNet_ChannelType)2);
			}, "ReplicatorPayloadWrapper.Invoke(uint, S, SNet_Player)");
		}

		public void Invoke(uint replicatorID, S data, SNet_Player target, SNet_ChannelType channelType)
		{
			//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)
			P payload = new P
			{
				ID = replicatorID
			};
			payload.Set(data);
			TaskQueue.AddTask(delegate
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				NetworkAPI.InvokeEvent<P>(Name, payload, target, channelType);
			}, "ReplicatorPayloadWrapper.Invoke(uint, S, SNet_Player, SNet_ChannelType)");
		}
	}
	public interface IStatePayload
	{
		uint ID { get; set; }

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

		void Set<S>(S stateData) where S : struct;
	}
	public struct StatePayload4Byte : IStatePayload
	{
		public const int Size = 4;

		private uint id;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
		public byte[] PayloadBytes;

		public uint ID
		{
			get
			{
				return id;
			}
			set
			{
				id = value;
			}
		}

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 4);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 4, ref PayloadBytes);
		}
	}
	public struct StatePayload8Byte : IStatePayload
	{
		public const int Size = 8;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 8);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 8, ref PayloadBytes);
		}
	}
	public struct StatePayload16Byte : IStatePayload
	{
		public const int Size = 16;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 16);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 16, ref PayloadBytes);
		}
	}
	public struct StatePayload32Byte : IStatePayload
	{
		public const int Size = 32;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 32);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 32, ref PayloadBytes);
		}
	}
	public struct StatePayload48Byte : IStatePayload
	{
		public const int Size = 48;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 48);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 48, ref PayloadBytes);
		}
	}
	public struct StatePayload64Byte : IStatePayload
	{
		public const int Size = 64;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 64);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 64, ref PayloadBytes);
		}
	}
	public struct StatePayload80Byte : IStatePayload
	{
		public const int Size = 80;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 80);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 80, ref PayloadBytes);
		}
	}
	public struct StatePayload96Byte : IStatePayload
	{
		public const int Size = 96;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 96);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 96, ref PayloadBytes);
		}
	}
	public struct StatePayload128Byte : IStatePayload
	{
		public const int Size = 128;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 128);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 128, ref PayloadBytes);
		}
	}
	public struct StatePayload196Byte : IStatePayload
	{
		public const int Size = 196;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 196)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 196);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 196, ref PayloadBytes);
		}
	}
	public struct StatePayload256Byte : IStatePayload
	{
		public const int Size = 256;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
		public byte[] PayloadBytes;

		[field: MarshalAs(UnmanagedType.U4)]
		public uint ID { get; set; }

		public S Get<S>() where S : struct
		{
			return StatePayloads.Get<S>(PayloadBytes, 256);
		}

		public void Set<S>(S stateData) where S : struct
		{
			StatePayloads.Set(stateData, 256, ref PayloadBytes);
		}
	}
	public enum LifeTimeType
	{
		Forever,
		Level
	}
	public sealed class StateReplicator<S> where S : struct
	{
		private 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 int StateSize;

		public static readonly StatePayloads.Size StateSizeType;

		private static readonly IReplicatorEvent<S> _C_RequestEvent;

		private static readonly IReplicatorEvent<S> _H_SetStateEvent;

		private static readonly IReplicatorEvent<S> _H_SetRecallStateEvent;

		private static readonly ReplicatorHandshake _Handshake;

		private 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 bool ClientSendStateAllowed { get; set; } = true;


		public bool CanSendToClient
		{
			get
			{
				if (SNet.IsInLobby)
				{
					return SNet.IsMaster;
				}
				return false;
			}
		}

		public bool CanSendToHost
		{
			get
			{
				if (SNet.IsInLobby && !SNet.IsMaster && SNet.HasMaster)
				{
					return ClientSendStateAllowed;
				}
				return false;
			}
		}

		public bool IsHandshakeSetup { get; private set; }

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

		public void SetupHandshake()
		{
			if (!IsInvalid && !IsHandshakeSetup)
			{
				_Handshake.UpdateCreated(ID);
				IsHandshakeSetup = true;
			}
		}

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

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

		public void Unload()
		{
			if (IsValid)
			{
				_Replicators.Remove(ID);
				_RecallStateSnapshots.Clear();
				_Handshake.UpdateDestroyed(ID);
				IsHandshakeSetup = false;
				ID = 0u;
			}
		}

		private void DoSync(S newState)
		{
			if (!IsInvalid)
			{
				if (CanSendToClient)
				{
					_H_SetStateEvent.Invoke(ID, newState);
					Internal_ChangeState(newState, isRecall: false);
				}
				else if (CanSendToHost)
				{
					_C_RequestEvent.Invoke(ID, newState, SNet.Master);
				}
			}
		}

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

		private void SendDropInState(SNet_Player target)
		{
			if (!IsInvalid)
			{
				if ((Object)(object)target == (Object)null)
				{
					Logger.Error("SendDropInState::Target was null??");
				}
				else
				{
					_H_SetRecallStateEvent.Invoke(ID, State, target);
				}
			}
		}

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

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

		private void RestoreSnapshot(eBufferType type)
		{
			//IL_0017: 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: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (IsInvalid || !CanSendToClient)
			{
				return;
			}
			if (_RecallStateSnapshots.TryGetValue(type, out var value))
			{
				_H_SetRecallStateEvent.Invoke(ID, value);
				Internal_ChangeState(value, isRecall: true);
				return;
			}
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 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 = StatePayloads.GetSizeType(StateSize);
			using (MD5.Create())
			{
				HashName = UName.GetHash(typeof(S).FullName);
				ClientRequestEventName = "SRs" + Name + "-" + HashName;
				HostSetStateEventName = "SRr" + Name + "-" + HashName;
				HostSetRecallStateEventName = "SRre" + Name + "-" + HashName;
				_C_RequestEvent = StatePayloads.CreateEvent<S>(StateSizeType, ClientRequestEventName, ClientRequestEventCallback);
				_H_SetStateEvent = StatePayloads.CreateEvent<S>(StateSizeType, HostSetStateEventName, HostSetStateEventCallback);
				_H_SetRecallStateEvent = StatePayloads.CreateEvent<S>(StateSizeType, HostSetRecallStateEventName, HostSetRecallStateEventCallback);
				_Handshake = ReplicatorHandshake.Create(Name + "-" + HashName);
				_Handshake.OnClientSyncRequested += ClientSyncRequested;
				Inject_SNet_Capture.OnBufferCapture += BufferStored;
				Inject_SNet_Capture.OnBufferRecalled += BufferRecalled;
				LevelAPI.OnLevelCleanup += LevelCleanedUp;
			}
		}

		public static void Setup()
		{
		}

		private static void ClientSyncRequested(SNet_Player requestedPlayer)
		{
			foreach (StateReplicator<S> value in _Replicators.Values)
			{
				if (value.IsValid)
				{
					value.SendDropInState(requestedPlayer);
				}
			}
		}

		private static void BufferStored(eBufferType type)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			foreach (StateReplicator<S> value in _Replicators.Values)
			{
				if (value.IsValid)
				{
					value.SaveSnapshot(type);
				}
			}
		}

		private static void BufferRecalled(eBufferType type)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			foreach (StateReplicator<S> value in _Replicators.Values)
			{
				if (value.IsValid)
				{
					value.RestoreSnapshot(type);
				}
			}
		}

		private static void LevelCleanedUp()
		{
			UnloadSessionReplicator();
		}

		private StateReplicator()
		{
		}

		public static StateReplicator<S> Create(uint replicatorID, S startState, LifeTimeType lifeTime, IStateReplicatorHolder<S> owner = null)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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 = owner,
				State = startState
			};
			switch (lifeTime)
			{
			case LifeTimeType.Forever:
				stateReplicator.IsHandshakeSetup = true;
				break;
			case LifeTimeType.Level:
				stateReplicator.SetupHandshake();
				break;
			default:
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LifeTime is invalid!: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LifeTimeType>(lifeTime);
				}
				Logger.Error(val);
				return null;
			}
			}
			_Replicators[replicatorID] = stateReplicator;
			return stateReplicator;
		}

		public static void UnloadSessionReplicator()
		{
			List<uint> list = new List<uint>();
			foreach (StateReplicator<S> value in _Replicators.Values)
			{
				if (value.LifeTime == LifeTimeType.Level)
				{
					list.Add(value.ID);
					value.Unload();
				}
			}
			foreach (uint item in list)
			{
				_Replicators.Remove(item);
			}
			_Handshake.Reset();
		}

		private static void ClientRequestEventCallback(ulong sender, uint replicatorID, S newState)
		{
			if (SNet.IsMaster && _Replicators.TryGetValue(replicatorID, out var value))
			{
				value.SetState(newState);
			}
		}

		private static void HostSetStateEventCallback(ulong sender, uint replicatorID, S newState)
		{
			if (SNet.HasMaster && SNet.Master.Lookup == sender && _Replicators.TryGetValue(replicatorID, out var value))
			{
				value.Internal_ChangeState(newState, isRecall: false);
			}
		}

		private static void HostSetRecallStateEventCallback(ulong sender, uint replicatorID, S newState)
		{
			if (SNet.HasMaster && SNet.Master.Lookup == sender && _Replicators.TryGetValue(replicatorID, out var value))
			{
				value.Internal_ChangeState(newState, isRecall: true);
			}
		}
	}
}
namespace FloLib.Networks.PayloadStructs
{
	public struct PL_Agent
	{
		public ushort AgentID;

		public PL_Agent()
		{
			AgentID = 0;
		}

		public PL_Agent(Agent agent)
		{
			AgentID = agent.GlobalID;
		}

		public void Set(Agent agent)
		{
			AgentID = agent.GlobalID;
		}

		public bool TryGet(out Agent agent)
		{
			IReplicator val = default(IReplicator);
			if (!SNet_Replication.TryGetReplicator(AgentID, ref val))
			{
				agent = null;
				return false;
			}
			if (val == null)
			{
				agent = null;
				return false;
			}
			if (val.ReplicatorSupplier == null)
			{
				agent = null;
				return false;
			}
			MonoBehaviour val2 = ((Il2CppObjectBase)val.ReplicatorSupplier).TryCast<MonoBehaviour>();
			if ((Object)(object)val2 == (Object)null)
			{
				agent = null;
				return false;
			}
			agent = ((Component)val2).GetComponent<Agent>();
			return (Object)(object)agent != (Object)null;
		}
	}
}
namespace FloLib.Networks.Inject
{
	[HarmonyPatch]
	internal class Inject_OnRecallDone
	{
		public static event Action OnRecallDone;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SNet_SyncManager), "OnRecallDone")]
		private static void Post_OnRecallDone(SNet_SyncManager __instance)
		{
			Inject_OnRecallDone.OnRecallDone?.Invoke();
		}
	}
	[HarmonyPatch(typeof(SNet_Capture))]
	internal static class Inject_SNet_Capture
	{
		public static event Action<eBufferType> OnBufferCapture;

		public static event Action<eBufferType> OnBufferRecalled;

		[HarmonyPatch("TriggerCapture")]
		[HarmonyPrefix]
		private static void Pre_TriggerCapture(SNet_Capture __instance)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			eBufferType primedBufferType = __instance.PrimedBufferType;
			Inject_SNet_Capture.OnBufferCapture?.Invoke(primedBufferType);
		}

		[HarmonyPatch("RecallBuffer")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void Post_RecallBuffer(SNet_Capture __instance, eBufferType bufferType)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.IsRecalling)
			{
				Inject_SNet_Capture.OnBufferRecalled?.Invoke(bufferType);
			}
		}
	}
}
namespace FloLib.Infos
{
	public sealed class ComponentList<T> : IEnumerable<T>, IEnumerable where T : Component
	{
		private readonly List<T> _InternalList = new List<T>();

		private T[] _ArrayCache = Array.Empty<T>();

		public T[] Items => _ArrayCache;

		internal void Add(T itemToAdd)
		{
			int id = ((Object)(object)itemToAdd).GetInstanceID();
			if (!_InternalList.Any((T t) => ((Object)(object)t).GetInstanceID() == id))
			{
				_InternalList.Add(itemToAdd);
				_ArrayCache = _InternalList.ToArray();
			}
		}

		internal void AddRange(IEnumerable<T> itemsToAdd)
		{
			foreach (T item in itemsToAdd)
			{
				Add(item);
			}
		}

		internal void Remove(T itemToRemove)
		{
			int id = ((Object)(object)itemToRemove).GetInstanceID();
			int num = _InternalList.FindIndex((T i) => ((Object)(object)i).GetInstanceID() == id);
			if (num > -1)
			{
				_InternalList.RemoveAt(num);
				_ArrayCache = _InternalList.ToArray();
			}
		}

		internal void Clear()
		{
			_InternalList.Clear();
			_ArrayCache = Array.Empty<T>();
		}

		public IEnumerator<T> GetEnumerator()
		{
			return _InternalList.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return _InternalList.GetEnumerator();
		}
	}
	public static class LG_LightInfo
	{
		public struct Data
		{
			public float PrefabIntensity;

			public LightMode SpawnedMode;

			public float SpawnedIntensity;

			public Color SpawnedColor;
		}

		public static bool TryGetLightData(LG_Light light, out Data data)
		{
			if ((Object)(object)light == (Object)null)
			{
				data = default(Data);
				return false;
			}
			if (!((Component)(object)light).TryGetComp<LightData>(out var component))
			{
				data = default(Data);
				return false;
			}
			data = component.CreateData();
			return true;
		}

		public static void RevertToSpawnedState(LG_Light light)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)light == (Object)null) && ((Component)(object)light).TryGetComp<LightData>(out var component))
			{
				light.ChangeColor(component.SpawnedColor);
				light.ChangeIntensity(component.SpawnedIntensity);
			}
		}
	}
	public enum LightMode
	{
		Off,
		On,
		Broken_Flickering
	}
	public static class LG_Objects
	{
		public static ComponentList<LG_SecurityDoor> SecurityDoors { get; private set; } = new ComponentList<LG_SecurityDoor>();


		public static ComponentList<LG_WeakDoor> WeakDoors { get; private set; } = new ComponentList<LG_WeakDoor>();


		public static ComponentList<LG_Light> Lights { get; private set; } = new ComponentList<LG_Light>();


		public static ComponentList<LG_ComputerTerminal> Terminals { get; private set; } = new ComponentList<LG_ComputerTerminal>();


		public static ComponentList<LG_LabDisplay> LabDisplays { get; private set; } = new ComponentList<LG_LabDisplay>();


		public static ComponentList<LG_DoorButton> DoorButtons { get; private set; } = new ComponentList<LG_DoorButton>();


		public static ComponentList<LG_WeakLock> WeakLocks { get; private set; } = new ComponentList<LG_WeakLock>();


		public static ComponentList<LG_HSUActivator_Core> HSUActivators { get; private set; } = new ComponentList<LG_HSUActivator_Core>();


		public static ComponentList<CarryItemPickup_Core> CarryItems { get; private set; } = new ComponentList<CarryItemPickup_Core>();


		public static ComponentList<GenericSmallPickupItem_Core> PickupItems { get; private set; } = new ComponentList<GenericSmallPickupItem_Core>();


		public static ComponentList<LG_Ladder> Ladders { get; private set; } = new ComponentList<LG_Ladder>();


		public static ComponentList<LG_WardenObjective_Reactor> Reactors { get; private set; } = new ComponentList<LG_WardenObjective_Reactor>();


		public static ComponentList<LG_PowerGeneratorCluster> GeneratorClusters { get; private set; } = new ComponentList<LG_PowerGeneratorCluster>();


		public static ComponentList<LG_PowerGenerator_Core> Generators { get; private set; } = new ComponentList<LG_PowerGenerator_Core>();


		[AutoInvoke(InvokeWhen.PluginLoaded)]
		internal static void Init()
		{
			LevelAPI.OnLevelCleanup += OnLevelCleanup;
		}

		private static void OnLevelCleanup()
		{
			SecurityDoors.Clear();
			WeakDoors.Clear();
			Lights.Clear();
			Terminals.Clear();
			LabDisplays.Clear();
			DoorButtons.Clear();
			WeakLocks.Clear();
			HSUActivators.Clear();
			CarryItems.Clear();
			PickupItems.Clear();
			Ladders.Clear();
			Reactors.Clear();
			GeneratorClusters.Clear();
			Generators.Clear();
		}

		public static O FindObjectInLevel<O>(bool includeInactive = false) where O : Object
		{
			return ((Component)Builder.CurrentFloor).GetComponentInChildren<O>(includeInactive);
		}

		public static IEnumerable<O> FindObjectsInLevel<O>(bool includeInactive = false) where O : Object
		{
			return (IEnumerable<O>)((Component)Builder.CurrentFloor).GetComponentsInChildren<O>(includeInactive);
		}

		public static LG_SecurityDoor FindSecurityDoor(LG_LayerType layer, eLocalZoneIndex localindex)
		{
			//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)
			return FindSecurityDoor((eDimensionIndex)0, layer, localindex);
		}

		public static LG_SecurityDoor FindSecurityDoor(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localindex)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val = default(LG_Zone);
			Builder.CurrentFloor.TryGetZoneByLocalIndex(dim, layer, localindex, ref val);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			if ((Object)(object)val.m_sourceGate == (Object)null)
			{
				return null;
			}
			if (val.m_sourceGate.SpawnedDoor == null)
			{
				return null;
			}
			return ((Il2CppObjectBase)val.m_sourceGate.SpawnedDoor).TryCast<LG_SecurityDoor>();
		}
	}
	public static class LocalPlayer
	{
		private static int? _InstanceID;

		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_0012: 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)
			if (HasAgent)
			{
				return ((Agent)Agent).Position;
			}
			return Vector3.zero;
		}

		public static Vector3 GetPosition(Vector3 fallback)
		{
			//IL_0012: 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)
			if (HasAgent)
			{
				return ((Agent)Agent).Position;
			}
			return fallback;
		}

		public static Vector3 GetEyePosition()
		{
			//IL_0012: 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)
			if (HasAgent)
			{
				return ((Agent)Agent).EyePosition;
			}
			return Vector3.zero;
		}

		public static Vector3 GetEyePosition(Vector3 fallback)
		{
			//IL_0012: 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)
			if (HasAgent)
			{
				return ((Agent)Agent).EyePosition;
			}
			return fallback;
		}

		[AutoInvoke(InvokeWhen.StartupAssetLoaded)]
		internal static void Init()
		{
			Coroutines.Start(UpdatePlayerInfo());
		}

		private static IEnumerator UpdatePlayerInfo()
		{
			while (true)
			{
				if (PlayerManager.HasLocalPlayerAgent())
				{
					PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
					int instanceID = ((Object)localPlayerAgent).GetInstanceID();
					if (!_InstanceID.HasValue || _InstanceID.Value != instanceID)
					{
						Agent = localPlayerAgent;
						LocalAgent = ((Il2CppObjectBase)localPlayerAgent).Cast<LocalPlayerAgent>();
						_InstanceID = ((Object)localPlayerAgent).GetInstanceID();
						HasAgent = true;
					}
				}
				else
				{
					Agent = null;
					LocalAgent = null;
					_InstanceID = null;
					HasAgent = false;
				}
				yield return null;
			}
		}
	}
}
namespace FloLib.Infos.Inject
{
	[HarmonyPatch(typeof(Builder), "BuildDone")]
	internal static class Inject_Builder
	{
		[HarmonyPriority(800)]
		private static void Postfix()
		{
			LG_Objects.Terminals.AddRange(Find<LG_ComputerTerminal>());
			LG_Objects.LabDisplays.AddRange(Find<LG_LabDisplay>());
			LG_Objects.DoorButtons.AddRange(Find<LG_DoorButton>());
			LG_Objects.WeakLocks.AddRange(Find<LG_WeakLock>());
			LG_Objects.HSUActivators.AddRange(Find<LG_HSUActivator_Core>());
			LG_Objects.CarryItems.AddRange(Find<CarryItemPickup_Core>());
			LG_Objects.PickupItems.AddRange(Find<GenericSmallPickupItem_Core>());
			LG_Objects.Ladders.AddRange(Find<LG_Ladder>());
			LG_Objects.Reactors.AddRange(Find<LG_WardenObjective_Reactor>());
			LG_Objects.GeneratorClusters.AddRange(Find<LG_PowerGeneratorCluster>());
			LG_Objects.Generators.AddRange(Find<LG_PowerGenerator_Core>());
		}

		private static IEnumerable<T> Find<T>() where T : Object
		{
			return LG_Objects.FindObjectsInLevel<T>();
		}
	}
	[HarmonyPatch(typeof(LG_BuildZoneLightsJob), "Build")]
	internal static class Inject_LG_LightBuild
	{
		[HarmonyPriority(0)]
		private static void Prefix(LG_BuildZoneLightsJob __instance, out List<LG_Light> __state)
		{
			__state = new List<LG_Light>();
			Enumerator<AIG_CourseNode> enumerator = __instance.m_zone.m_courseNodes.GetEnumerator();
			while (enumerator.MoveNext())
			{
				foreach (LG_Light componentsInChild in ((Component)enumerator.Current.m_area).GetComponentsInChildren<LG_Light>())
				{
					LightData lightData = ((Component)componentsInChild).gameObject.AddComponent<LightData>();
					LG_PointLight result2;
					if (((Il2CppObjectBase)(object)componentsInChild).TryCastToType<LG_SpotLight>(out LG_SpotLight result))
					{
						lightData.PrefabIntensity.Set(result.m_spotLight.intensity);
					}
					else if (((Il2CppObjectBase)(object)componentsInChild).TryCastToType<LG_PointLight>(out result2))
					{
						lightData.PrefabIntensity.Set(result2.m_pointLight.intensity);
					}
					else
					{
						if (!((Il2CppObjectBase)(object)componentsInChild).TryCastToType<LG_SpotLightAmbient>(out LG_SpotLightAmbient result3))
						{
							continue;
						}
						lightData.PrefabIntensity.Set(result3.m_spotLight.intensity);
					}
					__state.Add(componentsInChild);
				}
			}
			LG_Objects.Lights.AddRange(__state);
		}

		[HarmonyPriority(0)]
		private static void Postfix(List<LG_Light> __state)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			bool flag = default(bool);
			foreach (LG_Light item in __state)
			{
				LightData component = ((Component)item).GetComponent<LightData>();
				if ((Object)(object)component == (Object)null)
				{
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Found Light without ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("LightData");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Component! ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Component)(object)item).GetGameObjectPath());
					}
					Logger.Error(val);
				}
				else
				{
					component.SpawnedIntensity = item.m_intensity;
					component.SpawnedColor = item.m_color;
					component.SpawnedMode = GetLightMode(item);
				}
			}
			__state.Clear();
		}

		private static LightMode GetLightMode(LG_Light light)
		{
			if (light.GetC_Light().LightUpdator != null)
			{
				return LightMode.Broken_Flickering;
			}
			if (((Component)light).gameObject.active)
			{
				return LightMode.On;
			}
			return LightMode.Off;
		}
	}
	[HarmonyPatch(typeof(LG_SecurityDoor), "Setup")]
	internal static class Inject_LG_SecDoor
	{
		private static void Postfix(LG_SecurityDoor __instance)
		{
			LG_Objects.SecurityDoors.Add(__instance);
		}
	}
	[HarmonyPatch(typeof(LG_WeakDoor), "Setup")]
	internal static class Inject_LG_WeakDoor
	{
		private static void Postfix(LG_WeakDoor __instance)
		{
			LG_Objects.WeakDoors.Add(__instance);
		}
	}
}
namespace FloLib.Infos.Comps
{
	[AutoInject]
	internal sealed class LightData : MonoBehaviour
	{
		public Il2CppValueField<float> PrefabIntensity;

		public LightMode SpawnedMode;

		public float SpawnedIntensity;

		public Color SpawnedColor;

		public LG_LightInfo.Data CreateData()
		{
			//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)
			LG_LightInfo.Data result = default(LG_LightInfo.Data);
			result.PrefabIntensity = Il2CppValueField<float>.op_Implicit(PrefabIntensity);
			result.SpawnedMode = SpawnedMode;
			result.SpawnedIntensity = SpawnedIntensity;
			result.SpawnedColor = SpawnedColor;
			return result;
		}
	}
}
namespace FloLib.Game.ScreenShakes
{
	public sealed class ScreenShake
	{
		[AutoInvoke(InvokeWhen.StartupAssetLoaded)]
		internal static void Init()
		{
			GlobalNetAction<ScreenShakeDescriptor>.OnReceive += OnReceive;
		}

		public static void Trigger(ScreenShakeDescriptor data)
		{
			GlobalNetAction<ScreenShakeDescriptor>.Send(data);
		}

		private static void OnReceive(ulong sender, ScreenShakeDescriptor data)
		{
			if (LocalPlayer.TryGetAgent(out var agent))
			{
				FPSCamera fPSCamera = agent.FPSCamera;
				MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)fPSCamera, DoShake(fPSCamera, data));
			}
		}

		private static IEnumerator DoShake(FPSCamera camera, ScreenShakeDescriptor data)
		{
			float time = 0f;
			while (time < data.Duration)
			{
				float num = 1f;
				if (data.Mode == ScreenShakeMode.PositionFalloff)
				{
					float num2 = Vector3.Distance(data.Position, camera.Position);
					num = Mathf.InverseLerp(data.FalloffEnd, data.FalloffStart, num2);
				}
				float t = data.Modifier switch
				{
					ScreenShakeModifier.PingPong => Mathf.PingPong(Mathf.InverseLerp(data.Duration, 0f, time) * 2f, 1f), 
					ScreenShakeModifier.Increase => Mathf.InverseLerp(0f, data.Duration, time), 
					ScreenShakeModifier.Decrease => Mathf.InverseLerp(data.Duration, 0f, time), 
					_ => 1f, 
				};
				t = data.IntensityEasing.Evaluate(t);
				float constantCameraShakeAmount = num * t * data.Intensity;
				camera.SetConstantCameraShakeAmount(constantCameraShakeAmount);
				time += Time.deltaTime;
				yield return null;
			}
			camera.SetConstantCameraShakeAmount(0f);
		}
	}
	public struct ScreenShakeDescriptor
	{
		public ScreenShakeMode Mode;

		public ScreenShakeModifier Modifier;

		public Vector3 Position;

		public float Intensity;

		public float Duration;

		public float FalloffStart;

		public float FalloffEnd;

		public EaseFunc.Type IntensityEasing;
	}
	public enum ScreenShakeMode : byte
	{
		Global,
		PositionFalloff
	}
	public enum ScreenShakeModifier : byte
	{
		PingPong,
		Increase,
		Decrease,
		Constant
	}
}
namespace FloLib.Game.Projectiles
{
	public class Projectile : MonoBehaviour
	{
	}
}
namespace FloLib.Game.Explosions
{
	public sealed class Explosion
	{
		public static readonly Color DefaultFlashColor = new Color(1f, 0.2f, 0f, 1f);

		[AutoInvoke(InvokeWhen.StartupAssetLoaded)]
		internal static void Init()
		{
			ExplosionEffectPooling.Initialize();
			GlobalNetAction<ExplosionDescriptor>.OnReceive += OnReceive;
		}

		private static void OnReceive(ulong sender, ExplosionDescriptor data)
		{
			Internal_TriggerExplosion(data);
		}

		public static void Trigger(ExplosionDescriptor data)
		{
			GlobalNetAction<ExplosionDescriptor>.Send(data);
		}

		internal static void Internal_TriggerExplosion(ExplosionDescriptor data)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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)
			CellSound.Post(EVENTS.STICKYMINEEXPLODE, data.Position);
			LightFlash(data.Position, data.MaxDamageRange, data.LightColor);
			if (!SNet.IsMaster)
			{
				return;
			}
			Il2CppReferenceArray<Collider> val = Physics.OverlapSphere(data.Position, data.MaxDamageRange, LayerManager.MASK_EXPLOSION_TARGETS);
			if (((Il2CppArrayBase<Collider>)(object)val).Count < 1)
			{
				return;
			}
			DamageUtil.IncrementSearchID();
			uint searchID = DamageUtil.SearchID;
			foreach (Collider item in (Il2CppArrayBase<Collider>)(object)val)
			{
				ProcessExplosion(data, item, searchID);
			}
		}

		private static void ProcessExplosion(ExplosionDescriptor data, Collider target, uint searchID)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_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_0112: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null || (Object)(object)((Component)target).gameObject == (Object)null || !((Component)target).gameObject.TryGetComp<IDamageable>(out var component))
			{
				return;
			}
			component = component.GetBaseDamagable();
			if (component == null || component.TempSearchID == searchID)
			{
				return;
			}
			Vector3 damagablePosition = GetDamagablePosition(component);
			component.TempSearchID = searchID;
			float distance = Vector3.Distance(data.Position, damagablePosition);
			if (!IsExplosionBlocked(data.Position, damagablePosition, target))
			{
				float num = CalcBaseRangeDamage(data.MaxDamage, distance, data.MaxDamageRange, data.MinDamageRange);
				if ((Object)(object)((Il2CppObjectBase)component).TryCast<Dam_EnemyDamageBase>() != (Object)null)
				{
					num *= (float)data.DamageMultiplierToEnemy;
				}
				else if ((Object)(object)((Il2CppObjectBase)component).TryCast<Dam_PlayerDamageBase>() != (Object)null)
				{
					num *= (float)data.DamageMultiplierToPlayer;
				}
				Agent baseAgent = component.GetBaseAgent();
				if ((Object)(object)baseAgent != (Object)null && baseAgent.GlobalID == data.Inflictor.AgentID)
				{
					num *= (float)data.DamageMultiplierToInflictor;
				}
				if (Mathf.Abs(num) > float.Epsilon)
				{
					component.ExplosionDamage(num, data.Position, Vector3.up * 1000f, 0u);
				}
			}
		}

		private static Vector3 GetDamagablePosition(IDamageable damagable)
		{
			//IL_0018: 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)
			Agent baseAgent = damagable.GetBaseAgent();
			if ((Object)(object)baseAgent != (Object)null)
			{
				return baseAgent.EyePosition;
			}
			return damagable.DamageTargetPos;
		}

		private static bool IsExplosionBlocked(Vector3 pos1, Vector3 pos2, Collider targetCollider)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Linecast(pos1, pos2, ref val, LayerManager.MASK_EXPLOSION_BLOCKERS))
			{
				if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null)
				{
					return

plugins/net6/Flowaria.MeltdownReactor.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using GTFO.API;
using GTFO.API.Extensions;
using GTFO.API.JSON.Converters;
using GTFO.API.Utilities;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using MTFO.Managers;
using MeltdownReactor.Json;
using MeltdownReactor.Json.PartialData;
using MeltdownReactor.ReactorData;
using Microsoft.CodeAnalysis;
using SNetwork;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MeltdownReactor
{
	[BepInPlugin("Flowaria.MeltdownReactor", "MeltdownReactor", "2.1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("Inas.EOSExt.Reactor")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class EntryPoint : BasePlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static LiveEditEventHandler <0>__Listener_FileChanged1;
		}

		public const string PLUGIN_NAME = "MeltdownReactor";

		public const string AUTHOR = "Flowaria";

		public const string GUID = "Flowaria.MeltdownReactor";

		public const string VERSION = "2.1.4";

		public static string REACTOR_OVERRIDE_DATA_PATH = Path.Combine(MTFOUtil.CustomPath, "MeltdownReactor");

		public static readonly Dictionary<uint, ReactorOverrideData> ReactorOverrideDatas = new Dictionary<uint, ReactorOverrideData>();

		private Harmony m_Harmony;

		private LiveEditListener listener;

		public override void Load()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0133: 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_013e: Expected O, but got Unknown
			MeltdownReactorLogger.Debug("This plugin is dev-ed based on Flowaria.MeltdownReactor, which is only used in rundowns Flowaria.Modulation and Flowaria.Paradigm");
			MeltdownReactorLogger.Debug("All credits belong to Flowaria.");
			if (!Directory.Exists(REACTOR_OVERRIDE_DATA_PATH))
			{
				Directory.CreateDirectory(REACTOR_OVERRIDE_DATA_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(REACTOR_OVERRIDE_DATA_PATH, "Template.json"));
				streamWriter.WriteLine(JSON.Serialize(new ReactorOverrideData()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			ClassInjector.RegisterTypeInIl2Cpp<MeltdownReactor>();
			m_Harmony = new Harmony("Flowaria.MeltdownReactor");
			m_Harmony.PatchAll();
			foreach (string item in Directory.EnumerateFiles(REACTOR_OVERRIDE_DATA_PATH, "*.json", SearchOption.AllDirectories))
			{
				JSON.Load<ReactorOverrideData>(item, out var config);
				if (ReactorOverrideDatas.ContainsKey(config.ObjectiveDataID))
				{
					MeltdownReactorLogger.Error($"Duplicate ObjectiveDataID {config.ObjectiveDataID}");
				}
				else
				{
					ReactorOverrideDatas.Add(config.ObjectiveDataID, config);
				}
			}
			listener = LiveEdit.CreateListener(REACTOR_OVERRIDE_DATA_PATH, "*.json", true);
			LiveEditListener obj = listener;
			object obj2 = <>O.<0>__Listener_FileChanged1;
			if (obj2 == null)
			{
				LiveEditEventHandler val = Listener_FileChanged1;
				<>O.<0>__Listener_FileChanged1 = val;
				obj2 = (object)val;
			}
			obj.FileChanged += (LiveEditEventHandler)obj2;
		}

		private static void Listener_FileChanged1(LiveEditEventArgs e)
		{
			MeltdownReactorLogger.Warning("LiveEdit File Changed: " + e.FullPath + ".");
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				ReactorOverrideData reactorOverrideData = JSON.Deserialize<ReactorOverrideData>(content);
				if (!ReactorOverrideDatas.ContainsKey(reactorOverrideData.ObjectiveDataID))
				{
					MeltdownReactorLogger.Error("Changing ObjectiveDataID is not allowed, will not update.");
				}
				else
				{
					ReactorOverrideDatas[reactorOverrideData.ObjectiveDataID] = reactorOverrideData;
					MeltdownReactorLogger.Warning($"Updated override data with ObjectiveDataID {reactorOverrideData.ObjectiveDataID}");
				}
			});
		}
	}
	public class MeltdownReactor : MonoBehaviour
	{
		private const string MAINTERMINAL_NAME = "Main Terminal";

		private const float HIDE_TIMER_THRESHOLD = 43200f;

		private static Color LowTemperature;

		private static Color HighTemperature;

		private static uint VerifyTextID;

		private static uint MainTerminalTextID;

		private static uint CooldownCommandDescTextID;

		private static uint InfiniteWaveVerifyTextID;

		internal static uint NotReadyForVerificationOutputTextID;

		internal static uint IncorrectTerminalOutputTextID;

		internal static uint CorrectTerminalOutputTextID;

		private LG_Light[] _lights;

		private float _updateTimer;

		private Dictionary<int, LG_ComputerTerminal> verifyZoneOverrideTerminals = new Dictionary<int, LG_ComputerTerminal>();

		internal ReactorOverrideData overrideData;

		private Dictionary<int, string> meltdownWaveTerminalKeys;

		private HashSet<int> infiniteWaveIndices;

		private WardenObjectiveDataBlock objectiveDataBlock;

		private Dictionary<TERM_Command, List<WardenObjectiveEventData>> commandEventMap = new Dictionary<TERM_Command, List<WardenObjectiveEventData>>();

		private Dictionary<TERM_Command, List<TerminalOutput>> commandPostOutputMap = new Dictionary<TERM_Command, List<TerminalOutput>>();

		internal LG_WardenObjective_Reactor ChainedReactor { get; set; }

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


		public bool IsCorrectTerminal(LG_ComputerTerminal terminal)
		{
			int num = ChainedReactor.m_currentWaveCount - 1;
			if (num >= 0)
			{
				MeltdownReactorLogger.Error($"Index: {num}");
				MeltdownReactorLogger.Error("Comp Terminal Key1: " + terminal.ItemKey);
				MeltdownReactorLogger.Error("Comp Terminal Key2: " + (meltdownWaveTerminalKeys.ContainsKey(num) ? meltdownWaveTerminalKeys[num] : "empty"));
				if (meltdownWaveTerminalKeys.ContainsKey(num) && meltdownWaveTerminalKeys[num].Equals(terminal.ItemKey, StringComparison.InvariantCultureIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		public void Init()
		{
			if (overrideData == null)
			{
				MeltdownReactorLogger.Error("ReactorOverrideData is null!");
				return;
			}
			meltdownWaveTerminalKeys = new Dictionary<int, string>();
			overrideData.MeltdownWaveIndices.ForEach(delegate(int index)
			{
				meltdownWaveTerminalKeys.TryAdd(index, string.Empty);
			});
			infiniteWaveIndices = overrideData.InfiniteWaveIndices.ToHashSet();
			LevelAPI.OnEnterLevel += OnDrop;
			if (VerifyTextID == 0)
			{
				VerifyTextID = 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");
			}
		}

		private void OnDrop()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			LG_WardenObjective_Reactor chainedReactor = ChainedReactor;
			LG_ComputerTerminal terminal = ChainedReactor.m_terminal;
			objectiveDataBlock = GameDataBlockBase<WardenObjectiveDataBlock>.GetBlock(overrideData.ObjectiveDataID);
			if (objectiveDataBlock == null)
			{
				MeltdownReactorLogger.Error($"Failed to get the Reactor Startup objective for layer {chainedReactor.SpawnNode.LayerType}");
				return;
			}
			if ((int)objectiveDataBlock.Type != 1)
			{
				MeltdownReactorLogger.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);
			}
			SetupVerifyZoneOverride();
			SetupMeltdownAndInfiniteWave();
			if (overrideData.ReactorTerminal != null && overrideData.ReactorTerminal.TerminalPassword.PasswordProtected)
			{
				BuildReactorTerminalPassword();
			}
		}

		private void SetupVerifyZoneOverride()
		{
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: 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_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val3 = default(LG_Zone);
			foreach (VerifyZoneOverride verifyZoneOverride in overrideData.VerifyZoneOverrides)
			{
				if (verifyZoneOverrideTerminals.ContainsKey(verifyZoneOverride.WaveIndex))
				{
					MeltdownReactorLogger.Error($"VerifyZoneOverrides: Duplicate Wave Index {verifyZoneOverride.WaveIndex}");
					continue;
				}
				if (infiniteWaveIndices.Contains(verifyZoneOverride.WaveIndex))
				{
					MeltdownReactorLogger.Error($"VerifyZoneOverrides: Wave Index {verifyZoneOverride.WaveIndex} is specified as Infinite Wave but VerifyZoneOverride is specified! Will not process");
					continue;
				}
				if (verifyZoneOverride.WaveIndex < 0 || verifyZoneOverride.WaveIndex >= objectiveDataBlock.ReactorWaves.Count)
				{
					MeltdownReactorLogger.Error($"VerifyZoneOverrides: Invalid Wave Index {verifyZoneOverride.WaveIndex}. Valid value for this reactor is: [0, {objectiveDataBlock.ReactorWaves.Count - 1}]");
					continue;
				}
				ReactorWaveData val = objectiveDataBlock.ReactorWaves[verifyZoneOverride.WaveIndex];
				if (!val.VerifyInOtherZone)
				{
					MeltdownReactorLogger.Error($"VerifyZoneOverrides: `VerifyInOtherZone` is false for wave {verifyZoneOverride.WaveIndex}. You need to set it to true to generate the log, and thereby enabling moving the log.");
					continue;
				}
				LG_ComputerTerminal val2 = Utils.FindTerminalWithTerminalSerial(val.VerificationTerminalSerial, ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, val.ZoneForVerification);
				if ((Object)(object)val2 == (Object)null)
				{
					MeltdownReactorLogger.Error($"VerifyZoneOverrides: Cannot find wave log terminal. Wave index: {verifyZoneOverride.WaveIndex}");
					continue;
				}
				TargetZone targetZone = verifyZoneOverride.TargetZone;
				if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(targetZone.DimensionIndex, targetZone.LayerType, targetZone.LocalIndex, ref val3) || (Object)(object)val3 == (Object)null)
				{
					MeltdownReactorLogger.Error($"VerifyZoneOverrides: Cannot find target zone {targetZone.LocalIndex}, {targetZone.LayerType}, {targetZone.DimensionIndex}.");
					continue;
				}
				if (val3.TerminalsSpawnedInZone == null || val3.TerminalsSpawnedInZone.Count < 0)
				{
					MeltdownReactorLogger.Error($"VerifyZoneOverrides: No spawned terminal found in target zone {targetZone.LocalIndex}, {targetZone.LayerType}, {targetZone.DimensionIndex}..");
					continue;
				}
				int num = Builder.SessionSeedRandom.Seed;
				if (num < 0)
				{
					num = ((num != int.MinValue) ? (-num) : int.MaxValue);
				}
				int num2 = num % val3.TerminalsSpawnedInZone.Count;
				LG_ComputerTerminal val4 = val3.TerminalsSpawnedInZone[num2];
				string text = val.VerificationTerminalFileName.ToUpperInvariant();
				TerminalLogFileData localLog = val2.GetLocalLog(text);
				if (localLog == null)
				{
					MeltdownReactorLogger.Error("VerifyZoneOverrides: Cannot find reactor verify log on terminal.");
					continue;
				}
				val2.RemoveLocalLog(text);
				val4.AddLocalLog(localLog, true);
				val.VerificationTerminalSerial = val4.ItemKey;
				val2.ResetInitialOutput();
				val4.ResetInitialOutput();
				MeltdownReactorLogger.Debug($"VerifyZoneOverrides: moved wave {verifyZoneOverride.WaveIndex} verify log from {val2.ItemKey} to {val4.ItemKey}");
				verifyZoneOverrideTerminals.Add(verifyZoneOverride.WaveIndex, val4);
			}
		}

		private void SetupMeltdownAndInfiniteWave()
		{
			//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_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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			LG_WardenObjective_Reactor chainedReactor = ChainedReactor;
			LG_ComputerTerminal terminal = ChainedReactor.m_terminal;
			eDimensionIndex dimensionIndex = chainedReactor.SpawnNode.m_dimension.DimensionIndex;
			LG_LayerType layerType = chainedReactor.SpawnNode.LayerType;
			LG_Zone val3 = default(LG_Zone);
			for (int i = 0; i < objectiveDataBlock.ReactorWaves.Count; i++)
			{
				if (!meltdownWaveTerminalKeys.ContainsKey(i) && !infiniteWaveIndices.Contains(i))
				{
					continue;
				}
				ReactorWaveData val = objectiveDataBlock.ReactorWaves[i];
				if (!val.HasVerificationTerminal)
				{
					_ = terminal.m_command;
					if (meltdownWaveTerminalKeys.ContainsKey(i))
					{
						meltdownWaveTerminalKeys[i] = terminal.ItemKey;
						AddVerifyCommand(terminal);
						MeltdownReactorLogger.Debug($"MeltdownWave: Setup as Meltdown Wave for wave index {i}");
					}
					else
					{
						MeltdownReactorLogger.Debug($"InfiniteWave: Setup as Infinite Wavefor wave index {i}");
					}
					continue;
				}
				LG_ComputerTerminal val2 = null;
				if (verifyZoneOverrideTerminals.ContainsKey(i))
				{
					val2 = verifyZoneOverrideTerminals[i];
				}
				else
				{
					if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, val.ZoneForVerification, ref val3))
					{
						MeltdownReactorLogger.Error($"Cannot find LG_Zone {dimensionIndex}, {layerType}, {val.ZoneForVerification}");
						continue;
					}
					for (int j = 0; j < val3.TerminalsSpawnedInZone.Count; j++)
					{
						LG_ComputerTerminal val4 = val3.TerminalsSpawnedInZone[j];
						if (val4.ItemKey.Equals(val.VerificationTerminalSerial, StringComparison.InvariantCultureIgnoreCase))
						{
							val2 = val4;
							break;
						}
					}
				}
				if ((Object)(object)val2 == (Object)null)
				{
					MeltdownReactorLogger.Error($"MeltdownWave: cannot find verify terminal for wave index {i}");
					continue;
				}
				val2.ConnectedReactor = chainedReactor;
				val2.RemoveLocalLog(val.VerificationTerminalFileName.ToUpperInvariant());
				if (meltdownWaveTerminalKeys.ContainsKey(i))
				{
					meltdownWaveTerminalKeys[i] = val2.ItemKey;
					AddVerifyCommand(val2);
					MeltdownReactorLogger.Debug($"MeltdownWave: Setup as Meltdown Wave for wave index {i}");
				}
				else
				{
					MeltdownReactorLogger.Debug($"InfiniteWave: Setup as Infinite Wave for wave index {i}");
				}
				val2.ResetInitialOutput();
			}
			if (meltdownWaveTerminalKeys.Count == objectiveDataBlock.ReactorWaves.Count)
			{
				terminal.TrySyncSetCommandHidden((TERM_Command)22);
			}
		}

		private void AddVerifyCommand(LG_ComputerTerminal terminal)
		{
			//IL_0024: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			LG_ComputerTerminalCommandInterpreter command = terminal.m_command;
			if (command.HasRegisteredCommand((TERM_Command)42))
			{
				MeltdownReactorLogger.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 = ((CooldownCommandDescTextID == 0) ? "Confirm Reactor Startup Cooling Protocol" : Text.Get(CooldownCommandDescTextID)),
				Id = 0u
			}, (TERM_CommandRule)0);
			terminal.TrySyncSetCommandRule((TERM_Command)42, (TERM_CommandRule)0);
		}

		private void SetIdle()
		{
			//IL_0011: 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_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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ChainedReactor == (Object)null))
			{
				pReactorState val = default(pReactorState);
				val.status = (eReactorStatus)0;
				val.stateCount = 0;
				val.stateProgress = 0f;
				val.verifyFailed = false;
				pReactorState state = val;
				ChainedReactor.m_stateReplicator.State = state;
			}
		}

		private void OnDestroy()
		{
			LevelAPI.OnEnterLevel -= OnDrop;
			ChainedReactor = null;
			infiniteWaveIndices?.Clear();
			meltdownWaveTerminalKeys?.Clear();
			verifyZoneOverrideTerminals?.Clear();
			commandEventMap?.Clear();
			commandPostOutputMap?.Clear();
			infiniteWaveIndices = null;
			meltdownWaveTerminalKeys = null;
			overrideData = null;
			objectiveDataBlock = null;
			verifyZoneOverrideTerminals = null;
			commandEventMap = null;
			commandPostOutputMap = null;
		}

		private void LateUpdate()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_001a: 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_0024: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			int num = ChainedReactor.m_currentWaveCount - 1;
			if (num < 0)
			{
				return;
			}
			bool flag = ChainedReactor.m_currentWaveData.Verify < 43200f;
			if ((int)status != 4)
			{
				return;
			}
			if (meltdownWaveTerminalKeys.ContainsKey(num))
			{
				string text = ((MainTerminalTextID == 0) ? "Main Terminal" : Text.Get(MainTerminalTextID));
				if (ChainedReactor.m_currentWaveData.HasVerificationTerminal)
				{
					text = ChainedReactor.m_currentWaveData.VerificationTerminalSerial;
				}
				ChainedReactor.SetGUIMessage(true, FormatText(VerifyTextID, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "<color=orange>" + text + "</color>"), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>");
			}
			else if (infiniteWaveIndices.Contains(num))
			{
				ChainedReactor.SetGUIMessage(true, string.Format(Text.Get(InfiniteWaveVerifyTextID), ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>");
			}
			else if (ChainedReactor.m_currentWaveData.HasVerificationTerminal)
			{
				ChainedReactor.SetGUIMessage(true, Text.Format(1103u, (Object[])(object)new Object[3]
				{
					Object.op_Implicit(ChainedReactor.m_currentWaveCount),
					Object.op_Implicit(ChainedReactor.m_waveCountMax),
					Object.op_Implicit("<color=orange>" + ChainedReactor.m_currentWaveData.VerificationTerminalSerial + "</color>")
				}), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>");
			}
			else
			{
				ChainedReactor.SetGUIMessage(true, Text.Format(1105u, (Object[])(object)new Object[3]
				{
					Object.op_Implicit(ChainedReactor.m_currentWaveCount),
					Object.op_Implicit(ChainedReactor.m_waveCountMax),
					Object.op_Implicit("<color=orange>" + ChainedReactor.CurrentStateOverrideCode + "</color>")
				}), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>");
			}
		}

		private void UpdateLight(eReactorStatus status, float progress)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected I4, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0060: 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_006b: 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_0083: 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_001d: 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);
				}
			}
		}

		private void BuildReactorTerminalPassword()
		{
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Expected O, but got Unknown
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Expected O, but got Unknown
			LG_ComputerTerminal terminal = ChainedReactor.m_terminal;
			TerminalPassword terminalPassword = overrideData.ReactorTerminal.TerminalPassword;
			if (!terminalPassword.GeneratePassword)
			{
				terminal.LockWithPassword(terminalPassword.Password, new string[1] { "" });
				return;
			}
			if (terminalPassword.TerminalZoneSelectionDatas.Count <= 0)
			{
				MeltdownReactorLogger.Error("Tried to generate a password for terminal " + terminal.PublicName + " with no " + typeof(TerminalZoneSelectionData).Name + "!! This is not allowed.");
				return;
			}
			string codeWord = SerialGenerator.GetCodeWord();
			string passwordHintText = terminalPassword.PasswordHintText;
			string text = "<b>[Forgot your password?]</b> Backup security key(s) located in logs on ";
			int num = terminalPassword.PasswordPartCount;
			if (codeWord.Length % num != 0)
			{
				MeltdownReactorLogger.Error($"Build() password.Length ({codeWord.Length}) not divisible by passwordParts ({terminalPassword.PasswordPartCount}). 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 (terminalPassword.ShowPasswordPartPositions)
			{
				for (int i = 0; i < array[0].Length; i++)
				{
					text2 += "-";
				}
			}
			HashSet<LG_ComputerTerminal> hashSet = new HashSet<LG_ComputerTerminal>();
			for (int j = 0; j < num; j++)
			{
				int index = j % terminalPassword.TerminalZoneSelectionDatas.Count;
				LG_ComputerTerminal val = Utils.SelectTerminalFromSelectionData(terminalPassword.TerminalZoneSelectionDatas[index][Builder.SessionSeedRandom.Range(0, terminalPassword.TerminalZoneSelectionDatas[index].Count, "NO_TAG")]);
				if ((Object)(object)val != (Object)null)
				{
					string text3 = "";
					string text4;
					if (terminalPassword.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 text5 = (terminalPassword.ShowPasswordPartPositions ? ("0" + (j + 1)) : ("0" + Builder.SessionSeedRandom.Range(0, 9, "NO_TAG")));
					TerminalLogFileData val2 = new TerminalLogFileData();
					val2.FileName = "key" + text5 + "_" + terminal.m_serialNumber + (val.HasPasswordPart ? "_1" : "") + ".LOG";
					val2.FileContent = new LocalizedText
					{
						UntranslatedText = string.Format(Text.Get((num == 1) ? 1431221909u : 2260297836u), text4),
						Id = 0u
					};
					TerminalLogFileData val3 = val2;
					val.AddLocalLog(val3, true);
					if (!hashSet.Contains(val))
					{
						if (j > 0)
						{
							text += ", ";
						}
						text = text + val.PublicName + " in " + val.SpawnNode.m_zone.AliasName;
					}
					hashSet.Add(val);
					val.HasPasswordPart = true;
				}
				else
				{
					MeltdownReactorLogger.Error($"Build() CRITICAL ERROR, could not get a LG_ComputerTerminal for password part ({j + 1}/{num}) for {terminal.PublicName} backup log.");
				}
			}
			string text6 = text + ".";
			if (terminalPassword.ShowPasswordLength)
			{
				terminal.LockWithPassword(codeWord, new string[3]
				{
					passwordHintText,
					text6,
					"Char[" + codeWord.Length + "]"
				});
			}
			else
			{
				terminal.LockWithPassword(codeWord, new string[2] { passwordHintText, text6 });
			}
			foreach (LG_ComputerTerminal item in hashSet)
			{
				item.ResetInitialOutput();
			}
		}

		private void BuildReactorTerminalCustomCommands()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			LG_ComputerTerminal terminal = ChainedReactor.m_terminal;
			List<ReactorCustomTerminalCommand> uniqueCommands = overrideData.ReactorTerminal.UniqueCommands;
			TERM_Command val = default(TERM_Command);
			for (int i = 0; i < uniqueCommands.Count; i++)
			{
				ReactorCustomTerminalCommand reactorCustomTerminalCommand = uniqueCommands[i];
				if (terminal.m_command.TryGetUniqueCommandSlot(ref val))
				{
					terminal.m_command.AddCommand(val, reactorCustomTerminalCommand.Command, reactorCustomTerminalCommand.CommandDesc, reactorCustomTerminalCommand.SpecialCommandRule, ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(reactorCustomTerminalCommand.CommandEvents), ListExtensions.ToIl2Cpp<TerminalOutput>(reactorCustomTerminalCommand.PostCommandOutputs));
					for (int j = 0; j < reactorCustomTerminalCommand.CommandEvents.Count; j++)
					{
						WardenObjectiveEventData val2 = reactorCustomTerminalCommand.CommandEvents[j];
						if (val2.ChainPuzzle != 0)
						{
							ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(val2.ChainPuzzle);
							if (block != null)
							{
								ChainedPuzzleInstance val3 = ChainedPuzzleManager.CreatePuzzleInstance(block, terminal.ConnectedReactor.SpawnNode.m_area, terminal.ConnectedReactor.m_chainedPuzzleAlign.position, terminal.ConnectedReactor.m_chainedPuzzleAlign, val2.UseStaticBioscanPoints);
								terminal.SetChainPuzzleForCommand(val, j, val3);
							}
						}
					}
				}
				else
				{
					MeltdownReactorLogger.Error($"LG_ComputerTerminal: Could not get any more unique command slots for this terminal!! Have you added too many unique commands to this terminal? (Yours: {uniqueCommands.Count}, Max: 5)");
				}
			}
			ChainedPuzzleInstance val6 = default(ChainedPuzzleInstance);
			for (int k = 38; k <= 42; k++)
			{
				TERM_Command val4 = (TERM_Command)(byte)k;
				if (!commandEventMap.TryGetValue(val4, out var value) || value == null)
				{
					continue;
				}
				ChainedPuzzleInstance val5 = null;
				for (int l = 0; l < value.Count; l++)
				{
					WardenObjectiveEventData eventData = value[l];
					if (eventData == null)
					{
						continue;
					}
					if (ChainedReactor.m_terminal.TryGetChainPuzzleForCommand(val4, l, ref val6) && (Object)(object)val6 != (Object)null)
					{
						ChainedPuzzleInstance obj = val6;
						obj.OnPuzzleSolved += Action.op_Implicit((Action)delegate
						{
							WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(eventData, (eWardenObjectiveEventTrigger)0, true, 0f);
						});
						val5 = val6;
					}
					else if ((Object)(object)val5 != (Object)null)
					{
						ChainedPuzzleInstance obj2 = val5;
						obj2.OnPuzzleSolved += Action.op_Implicit((Action)delegate
						{
							WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(eventData, (eWardenObjectiveEventTrigger)0, true, 0f);
						});
					}
				}
			}
			MeltdownReactorLogger.Warning("CustomCommand built!");
		}

		private static string FormatText(uint id, params object[] objs)
		{
			return string.Format(Text.Get(id), objs);
		}

		static MeltdownReactor()
		{
			//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;
			VerifyTextID = 0u;
			MainTerminalTextID = 0u;
			CooldownCommandDescTextID = 0u;
			InfiniteWaveVerifyTextID = 0u;
			NotReadyForVerificationOutputTextID = 0u;
			IncorrectTerminalOutputTextID = 0u;
			CorrectTerminalOutputTextID = 0u;
		}
	}
	internal static class MeltdownReactorLogger
	{
		private static readonly ManualLogSource _logger = Logger.CreateLogSource("MeltdownReactor");

		private static string Format(object msg)
		{
			return msg.ToString();
		}

		public static void Info(object data)
		{
			_logger.LogMessage((object)Format(data));
		}

		public static void Verbose(object data)
		{
		}

		public static void Debug(object data)
		{
			_logger.LogDebug((object)Format(data));
		}

		public static void Error(object data)
		{
			_logger.LogError((object)Format(data));
		}

		public static void Warning(object data)
		{
			_logger.LogWarning((object)Format(data));
		}
	}
	internal static class Utils
	{
		public static LG_ComputerTerminal FindTerminalWithTerminalSerial(string itemKey, eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex)
		{
			//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)
			LG_Zone val = null;
			if (Builder.CurrentFloor.TryGetZoneByLocalIndex(dim, layer, localIndex, ref val) && (Object)(object)val != (Object)null)
			{
				Enumerator<LG_ComputerTerminal> enumerator = val.TerminalsSpawnedInZone.GetEnumerator();
				while (enumerator.MoveNext())
				{
					LG_ComputerTerminal current = enumerator.Current;
					if (current.ItemKey.Equals(itemKey, StringComparison.InvariantCultureIgnoreCase))
					{
						return current;
					}
				}
			}
			return null;
		}

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

		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 LG_ComputerTerminal SelectTerminalFromSelectionData(PasswordTerminalZoneSelectionData selectionData)
		{
			//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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected I4, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			TargetZone targetZone = selectionData.TargetZone;
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(targetZone.DimensionIndex, targetZone.LayerType, targetZone.LocalIndex, ref val) || (Object)(object)val == (Object)null)
			{
				MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() Could NOT find zone with " + targetZone);
				return null;
			}
			if (val.TerminalsSpawnedInZone.Count <= 0)
			{
				MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() Could not find any terminals in zone with " + targetZone?.ToString() + ". At least one terminal required!!");
				return null;
			}
			List<LG_ComputerTerminal> list = new List<LG_ComputerTerminal>();
			if ((int)selectionData.SeedType != 0)
			{
				Enumerator<LG_ComputerTerminal> enumerator = val.TerminalsSpawnedInZone.GetEnumerator();
				while (enumerator.MoveNext())
				{
					LG_ComputerTerminal current = enumerator.Current;
					if (!current.HasPasswordPart)
					{
						list.Add(current);
					}
				}
				if (list.Count <= 0)
				{
					eLocalZoneIndex localIndex = targetZone.LocalIndex;
					MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() Could not find any terminals without a password part in zone with " + ((object)(eLocalZoneIndex)(ref localIndex)).ToString() + ". Putting the password on random (session) already used terminal.");
					return val.TerminalsSpawnedInZone[Builder.SessionSeedRandom.Range(0, val.TerminalsSpawnedInZone.Count, "NO_TAG")];
				}
			}
			eSeedType seedType = selectionData.SeedType;
			switch ((int)seedType)
			{
			case 0:
				return val.TerminalsSpawnedInZone[Mathf.Clamp(0, val.TerminalsSpawnedInZone.Count - 1, selectionData.TerminalIndex)];
			case 1:
				return list[Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG")];
			case 2:
				return list[Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG")];
			case 3:
				Random.InitState(selectionData.StaticSeed);
				return list[Random.Range(0, list.Count)];
			default:
				MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() did not have a valid SeedType!!");
				return null;
			}
		}
	}
}
namespace MeltdownReactor.ReactorData
{
	public class PasswordTerminalZoneSelectionData
	{
		public TargetZone TargetZone { get; set; } = new TargetZone();


		public eSeedType SeedType { get; set; }

		public int TerminalIndex { get; set; }

		public int StaticSeed { get; set; }

		public PasswordTerminalZoneSelectionData()
		{
			SeedType = (eSeedType)1;
		}

		public override string ToString()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			string[] obj = new string[7]
			{
				TargetZone?.ToString(),
				" ",
				null,
				null,
				null,
				null,
				null
			};
			eSeedType seedType = SeedType;
			obj[2] = ((object)(eSeedType)(ref seedType)).ToString();
			obj[3] = " ";
			obj[4] = TerminalIndex.ToString();
			obj[5] = " ";
			obj[6] = StaticSeed.ToString();
			return string.Concat(obj);
		}
	}
	public class ReactorCustomTerminalCommand
	{
		public string Command { get; set; }

		public LocalizedText CommandDesc { get; set; }

		public List<TerminalOutput> PostCommandOutputs { get; set; }

		public List<WardenObjectiveEventData> CommandEvents { get; set; }

		public TERM_CommandRule SpecialCommandRule { get; set; }

		public ReactorCustomTerminalCommand()
		{
			PostCommandOutputs = new List<TerminalOutput>();
			CommandEvents = new List<WardenObjectiveEventData>();
		}
	}
	public class ReactorOverrideData
	{
		public uint ObjectiveDataID { get; set; }

		public bool StartupOnDrop { get; set; }

		public List<int> MeltdownWaveIndices { get; set; } = new List<int>();


		public List<int> InfiniteWaveIndices { get; set; } = new List<int>();


		public ReactorTerminalSetting ReactorTerminal { get; set; } = new ReactorTerminalSetting();


		public List<VerifyZoneOverride> VerifyZoneOverrides { get; set; } = new List<VerifyZoneOverride>
		{
			new VerifyZoneOverride()
		};

	}
	public class ReactorTerminalSetting
	{
		public List<ReactorCustomTerminalCommand> UniqueCommands { get; set; } = new List<ReactorCustomTerminalCommand>();


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

	}
	public class TargetZone
	{
		public eDimensionIndex DimensionIndex { get; set; }

		public LG_LayerType LayerType { get; set; }

		public eLocalZoneIndex LocalIndex { get; set; }

		public override string ToString()
		{
			//IL_000c: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			return $"{LocalIndex}, {LayerType}, {DimensionIndex}";
		}
	}
	public class TerminalPassword
	{
		public bool PasswordProtected { get; set; }

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


		public string PasswordHintText { get; set; } = "Password Required.";


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


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


		public bool ShowPasswordLength { get; set; }

		public bool ShowPasswordPartPositions { get; set; }

		public List<List<PasswordTerminalZoneSelectionData>> TerminalZoneSelectionDatas { get; set; } = new List<List<PasswordTerminalZoneSelectionData>>
		{
			new List<PasswordTerminalZoneSelectionData>()
		};

	}
	public class VerifyZoneOverride
	{
		public int WaveIndex { get; set; } = -1;


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

	}
}
namespace MeltdownReactor.Patches
{
	[HarmonyPatch]
	internal static class Patch_LG_ComputerTerminal
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminal), "OnStateChange")]
		private static bool Pre_OnStateChange(LG_ComputerTerminal __instance, bool isRecall)
		{
			if (__instance.SpawnNode != null || !isRecall)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")]
	internal static class Patch_Meltdown_Reactor_Terminal
	{
		private static bool Prefix(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_0022: 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 || (int)cmd != 42)
			{
				return true;
			}
			if (__instance.m_terminal.CommandIsHidden(cmd))
			{
				return true;
			}
			_ = __instance.m_terminal.ItemKey;
			MeltdownReactor component = ((Component)connectedReactor).gameObject.GetComponent<MeltdownReactor>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (!connectedReactor.ReadyForVerification)
			{
				__instance.AddOutput("", true);
				__instance.AddOutput((TerminalLineType)3, Text.Get(MeltdownReactor.NotReadyForVerificationOutputTextID), 4f, (TerminalSoundType)0, (TerminalSoundType)0);
				__instance.AddOutput("", true);
				return false;
			}
			if (component.IsCorrectTerminal(__instance.m_terminal))
			{
				MeltdownReactorLogger.Info("Reactor Verify Correct!");
				if (SNet.IsMaster)
				{
					if (connectedReactor.m_currentWaveCount == connectedReactor.m_waveCountMax)
					{
						connectedReactor.AttemptInteract((eReactorInteraction)5, 0f);
					}
					else
					{
						connectedReactor.AttemptInteract((eReactorInteraction)3, 0f);
					}
				}
				__instance.AddOutput(Text.Get(MeltdownReactor.CorrectTerminalOutputTextID), true);
			}
			else
			{
				MeltdownReactorLogger.Info("Reactor Verify Incorrect!");
				__instance.AddOutput("", true);
				__instance.AddOutput((TerminalLineType)3, Text.Get(MeltdownReactor.IncorrectTerminalOutputTextID), 4f, (TerminalSoundType)0, (TerminalSoundType)0);
				__instance.AddOutput("", true);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class Patch_Meltdown_Reactor
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")]
		private static void Post_BuildDone(LG_WardenObjective_Reactor __instance)
		{
			//IL_000d: 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_0051: Invalid comparison between Unknown and I4
			WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock);
			if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val))
			{
				MeltdownReactorLogger.Error("Failed to get WardenObjectiveData for this reactor");
			}
			else if (EntryPoint.ReactorOverrideDatas.ContainsKey(((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID))
			{
				ReactorOverrideData overrideData = EntryPoint.ReactorOverrideDatas[((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID];
				if ((int)val.Type != 1)
				{
					MeltdownReactorLogger.Error($"ObjectiveDataID {((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID} is not reactor startup, which is unsupported.");
					return;
				}
				MeltdownReactor meltdownReactor = ((Component)__instance).gameObject.AddComponent<MeltdownReactor>();
				meltdownReactor.ChainedReactor = __instance;
				meltdownReactor.UsingLightEffect = false;
				meltdownReactor.overrideData = overrideData;
				meltdownReactor.Init();
				MeltdownReactorLogger.Warning($"Override Reactor Data for ObjectiveID {((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID}");
			}
		}
	}
}
namespace MeltdownReactor.Json
{
	internal static class JSON
	{
		private static readonly JsonSerializerOptions s_SerializerOptions;

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

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

		static JSON()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			s_SerializerOptions = new JsonSerializerOptions
			{
				AllowTrailingCommas = true,
				ReadCommentHandling = JsonCommentHandling.Skip,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true
			};
			s_SerializerOptions.Converters.Add(new JsonStringEnumConverter());
			if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
			{
				s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
				s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter);
				MeltdownReactorLogger.Info("PartialData Support Found!");
			}
			else
			{
				s_SerializerOptions.Converters.Add((JsonConverter)new LocalizedTextConverter());
			}
		}

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

		public static JsonConverter PersistentIDConverter { get; private set; }

		public static JsonConverter LocalizedTextConverter { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool Initialized { get; private set; }

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

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

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

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

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

plugins/net6/Inas07.EOSExt.EMP.dll

Decompiled 4 months 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 BepInEx;
using BepInEx.Unity.IL2CPP;
using EOSExt.EMP.Definition;
using EOSExt.EMP.EMPComponent;
using EOSExt.EMP.Impl;
using EOSExt.EMP.Impl.Handlers;
using ExtraObjectiveSetup;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Utils;
using FloLib.Networks.Replications;
using GTFO.API;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Inas07.EOSExt.EMP")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[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]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.EMP
{
	public class EMPManager : GenericExpeditionDefinitionManager<pEMPDefinition>
	{
		public struct pEMPState
		{
			public uint pEMPIndex;

			public bool enabled;

			public pEMPState()
			{
				pEMPIndex = 0u;
				enabled = false;
			}

			public pEMPState(pEMPState o)
			{
				pEMPIndex = 0u;
				enabled = false;
				o.pEMPIndex = pEMPIndex;
				o.enabled = enabled;
			}
		}

		private readonly Dictionary<uint, pEMP> _pEMPs = new Dictionary<uint, pEMP>();

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

		protected override string DEFINITION_NAME => "PersistentEMP";

		private List<EMPController> _empTargets { get; } = new List<EMPController>();


		private List<EMPShock> _activeEMPShock { get; } = new List<EMPShock>();


		public static EMPManager Current { get; private set; }

		public PlayerAgent LocalPlayerAgent { get; private set; }

		public IEnumerable<EMPController> EMPTargets => _empTargets;

		internal void SetupHUDAndFlashlight()
		{
			if ((Object)(object)LocalPlayerAgent == (Object)null)
			{
				EOSLogger.Error($"{"SetupHUDAndFlashlight": LocalPlayerAgent is not set!}");
			}
			else if (!((Object)(object)((Component)LocalPlayerAgent).gameObject.GetComponent<EMPController>() != (Object)null))
			{
				((Component)LocalPlayerAgent).gameObject.AddComponent<EMPController>().AssignHandler(new EMPPlayerHudHandler());
				((Component)LocalPlayerAgent).gameObject.AddComponent<EMPController>().AssignHandler(new EMPPlayerFlashLightHandler());
				EOSLogger.Log("pEMP: PlayerHUD & flashlight setup completed");
			}
		}

		internal void SetupAmmoWeaponHandlers(InventorySlot slot)
		{
			//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)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0006: 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)
			if (slot - 1 <= 1)
			{
				SetupAmmoWeaponHandlerForSlot(slot);
				EOSLogger.Log($"pEMP: Backpack {slot} setup completed");
			}
			static void SetupAmmoWeaponHandlerForSlot(InventorySlot slot)
			{
				//IL_0005: 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)
				BackpackItem val = default(BackpackItem);
				if (PlayerBackpackManager.LocalBackpack.TryGetBackpackItem(slot, ref val))
				{
					if (!((Object)(object)((Component)val.Instance).gameObject.GetComponent<EMPController>() != (Object)null))
					{
						((Component)val.Instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPGunSightHandler());
					}
				}
				else
				{
					EOSLogger.Warning($"Couldn't get item for slot {slot}!");
				}
			}
		}

		internal void SetupToolHandler()
		{
			BackpackItem val = default(BackpackItem);
			if (PlayerBackpackManager.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.Warning($"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);
				_pEMPs[pEMPIndex].ChangeState(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()
		{
			_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!");
				}
				else
				{
					pEMP.SetupReplicator(num);
					EOSLogger.Debug($"SetuppEMPReplicators: replicator_{num} setup! ");
				}
				EOSLogger.Warning($"pEMP_{definition.pEMPIndex} initialized");
			}
		}

		internal void SetLocalPlayerAgent(PlayerAgent localPlayerAgent)
		{
			LocalPlayerAgent = localPlayerAgent;
			PlayerpEMPComponent.Current = ((Component)localPlayerAgent).gameObject.AddComponent<PlayerpEMPComponent>();
			PlayerpEMPComponent.Current.player = localPlayerAgent;
			EOSLogger.Debug("LocalPlayerAgent setup completed");
		}

		internal void OnLocalPlayerAgentDestroy()
		{
			PlayerpEMPComponent.Current = null;
			EOSLogger.Debug("LocalPlayerAgent Destroyed");
		}

		public void AddTarget(EMPController target)
		{
			_empTargets.Add(target);
		}

		public void RemoveTarget(EMPController target)
		{
			_empTargets.Remove(target);
		}

		public void ActivateEMPShock(Vector3 position, float range, float duration)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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;
			}
			_activeEMPShock.Add(new EMPShock(position, range, duration));
			foreach (EMPController empTarget in _empTargets)
			{
				if (Vector3.Distance(position, empTarget.Position) < range)
				{
					empTarget.AddTime(duration);
				}
			}
		}

		public float DurationFromPosition(Vector3 position)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			_activeEMPShock.RemoveAll((EMPShock e) => Mathf.Round(e.RemainingTime) <= 0f);
			float num = 0f;
			foreach (EMPShock item in _activeEMPShock)
			{
				if (item.InRange(position))
				{
					num += item.RemainingTime;
				}
			}
			return num;
		}

		private void Clear()
		{
			_empTargets.Clear();
			_activeEMPShock.Clear();
			EMPHandler.Cleanup();
		}

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

		private EMPManager()
		{
		}

		static EMPManager()
		{
			Current = new EMPManager();
			ClassInjector.RegisterTypeInIl2Cpp<EMPController>();
			ClassInjector.RegisterTypeInIl2Cpp<PlayerpEMPComponent>();
		}
	}
	internal static class EMPWardenEvents
	{
		public enum EMPEvents
		{
			Instant_Shock = 300,
			Toggle_PEMP_State
		}

		internal static void InstantShock(WardenObjectiveEventData e)
		{
			//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_001a: 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);
		}
	}
	public static class Events
	{
		public static Action<GearPartFlashlight> FlashLightWielded;

		public static Action<InventorySlot> InventoryWielded;

		public static Action EnterGSInLevel;
	}
	[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.0.4")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.EMP";

		public const string VERSION = "1.0.4";

		private Harmony m_Harmony;

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

		private void SetupManagers()
		{
			((GenericExpeditionDefinitionManager<pEMPDefinition>)EMPManager.Current).Init();
		}
	}
}
namespace EOSExt.EMP.Patches
{
	[HarmonyPatch(typeof(EnemyScanner))]
	internal static class Inject_EnemyScanner
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("UpdateDetectedEnemies")]
		internal static bool Pre_UpdateDetectedEnemies()
		{
			return !EMPHandler.IsLocalPlayerDisabled;
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("UpdateTagProgress")]
		internal static bool Pre_UpdateTagProgress(EnemyScanner __instance)
		{
			//IL_0061: 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)
			if (EMPHandler.IsLocalPlayerDisabled)
			{
				((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(typeof(LG_Light))]
	internal static class Inject_LG_Light
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("Start")]
		internal static void Pre_Start(LG_Light __instance)
		{
			((Component)__instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPLightHandler());
		}
	}
	[HarmonyPatch(typeof(PlayerAgent))]
	internal static class Inject_PlayerAgent
	{
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch("Setup")]
		internal static void Post_Setup(PlayerAgent __instance)
		{
			if (((Agent)__instance).IsLocallyOwned)
			{
				EMPManager.Current.SetLocalPlayerAgent(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerGuiLayer))]
	internal static class Inject_PlayerGuiLayer
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("UpdateGUIElementsVisibility")]
		internal static bool Pre_UpdateGUIElementsVisibility()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			if (EMPHandler.IsLocalPlayerDisabled)
			{
				foreach (EMPPlayerHudHandler handler in EMPPlayerHudHandler.Handlers)
				{
					handler.ForceState(EMPState.Off);
				}
				return false;
			}
			if ((int)GameStateManager.CurrentStateName == 10)
			{
				foreach (EMPPlayerHudHandler handler2 in EMPPlayerHudHandler.Handlers)
				{
					handler2.ForceState(EMPState.On);
				}
			}
			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_000b: 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(typeof(PlayerSync))]
	internal static class Inject_PlayerSync
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("WantsToSetFlashlightEnabled")]
		internal static bool Pre_WantsToSetFlashlightEnabled(PlayerSync __instance, bool enable)
		{
			if (EMPHandler.IsLocalPlayerDisabled)
			{
				return false;
			}
			if (enable != __instance.m_agent.Inventory.FlashlightEnabled)
			{
				return true;
			}
			__instance.WantsToSetFlashlightEnabled(!__instance.m_agent.Inventory.FlashlightEnabled, false);
			return false;
		}
	}
	[HarmonyPatch(typeof(SentryGunFirstPerson))]
	internal static class Inject_SentryGunFirstPerson
	{
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("CheckCanPlace")]
		internal static bool Pre_CheckCanPlace(ref bool __result)
		{
			if (!EMPHandler.IsLocalPlayerDisabled)
			{
				return true;
			}
			__result = false;
			return 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.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 class pEMPDefinition
	{
		public uint pEMPIndex { get; set; }

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


		public float Range { get; set; }

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


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


		public pEMPDefinition(pEMPDefinition other)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//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_003f: 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_0066: 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
			};
		}
	}
}
namespace EOSExt.EMP.EMPComponent
{
	public class PlayerpEMPComponent : MonoBehaviour
	{
		private float nextUpdateTime = float.NaN;

		public const float UPDATE_INTERVAL = 0.2f;

		public static PlayerpEMPComponent Current { get; internal set; }

		public bool InAnypEMP { get; private set; }

		public PlayerAgent player { get; internal set; }

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

		private void Update()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_00b1: 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();
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			ItemToDisable itemToDisable = new ItemToDisable
			{
				BioTracker = false,
				PlayerFlashLight = false,
				PlayerHUD = false,
				EnvLight = false,
				GunSight = false,
				Sentry = false
			};
			InAnypEMP = false;
			foreach (pEMP pEMP in EMPManager.Current.pEMPs)
			{
				if (pEMP.State == ActiveState.ENABLED && pEMP.InRange(((Agent)player).Position))
				{
					itemToDisable.BioTracker = itemToDisable.BioTracker || pEMP.ItemToDisable.BioTracker;
					itemToDisable.PlayerFlashLight = itemToDisable.PlayerFlashLight || pEMP.ItemToDisable.PlayerFlashLight;
					itemToDisable.PlayerHUD = itemToDisable.PlayerHUD || pEMP.ItemToDisable.PlayerHUD;
					itemToDisable.GunSight = itemToDisable.GunSight || pEMP.ItemToDisable.GunSight;
					itemToDisable.Sentry = itemToDisable.Sentry || pEMP.ItemToDisable.Sentry;
					InAnypEMP = true;
				}
			}
			if (itemToDisable.BioTracker)
			{
				foreach (EMPBioTrackerHandler handler in EMPBioTrackerHandler.Handlers)
				{
					handler?.controller?.AddTime(float.PositiveInfinity);
				}
			}
			else
			{
				foreach (EMPBioTrackerHandler handler2 in EMPBioTrackerHandler.Handlers)
				{
					handler2?.controller?.ClearTime();
				}
			}
			if (itemToDisable.PlayerFlashLight)
			{
				foreach (EMPPlayerFlashLightHandler handler3 in EMPPlayerFlashLightHandler.Handlers)
				{
					handler3?.controller?.AddTime(float.PositiveInfinity);
				}
			}
			else
			{
				foreach (EMPPlayerFlashLightHandler handler4 in EMPPlayerFlashLightHandler.Handlers)
				{
					handler4?.controller?.ClearTime();
				}
			}
			if (itemToDisable.PlayerHUD)
			{
				foreach (EMPPlayerHudHandler handler5 in EMPPlayerHudHandler.Handlers)
				{
					handler5?.controller?.AddTime(float.PositiveInfinity);
				}
			}
			else
			{
				foreach (EMPPlayerHudHandler handler6 in EMPPlayerHudHandler.Handlers)
				{
					handler6?.controller?.ClearTime();
				}
			}
			if (itemToDisable.GunSight)
			{
				foreach (EMPGunSightHandler handler7 in EMPGunSightHandler.Handlers)
				{
					handler7?.controller?.AddTime(float.PositiveInfinity);
				}
			}
			else
			{
				foreach (EMPGunSightHandler handler8 in EMPGunSightHandler.Handlers)
				{
					handler8?.controller?.ClearTime();
				}
			}
			if (itemToDisable.Sentry)
			{
				foreach (EMPSentryHandler handler9 in EMPSentryHandler.Handlers)
				{
					handler9?.controller?.AddTime(float.PositiveInfinity);
				}
				return;
			}
			foreach (EMPSentryHandler handler10 in EMPSentryHandler.Handlers)
			{
				handler10?.controller?.ClearTime();
			}
		}

		private void OnDestroy()
		{
			EMPManager.Current.OnLocalPlayerAgentDestroy();
			player = null;
		}

		static PlayerpEMPComponent()
		{
		}
	}
}
namespace EOSExt.EMP.Impl
{
	public sealed class EMPController : MonoBehaviour
	{
		private bool _hasHandler;

		private bool _setup;

		public EMPHandler Handler { get; private set; }

		public float endTime { get; private set; }

		[HideFromIl2Cpp]
		private bool IsEMPActive => endTime > Clock.Time;

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

		private void Awake()
		{
			EMPManager.Current.AddTarget(this);
		}

		private void OnEnable()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)GameStateManager.CurrentStateName == 10 && _setup)
			{
				if (endTime > Clock.Time)
				{
					Handler.ForceState(EMPState.Off);
				}
				else
				{
					Handler.ForceState(EMPState.On);
				}
			}
		}

		private void Update()
		{
			if (_hasHandler)
			{
				Handler.Tick(IsEMPActive);
			}
		}

		[HideFromIl2Cpp]
		public void AddTime(float time)
		{
			endTime = Clock.Time + time;
		}

		[HideFromIl2Cpp]
		public void ClearTime()
		{
			endTime = Clock.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()
		{
			EMPManager.Current.RemoveTarget(this);
			Handler.OnDespawn();
			Handler = null;
		}
	}
	public abstract class EMPHandler
	{
		protected enum DeviceState
		{
			On,
			Off,
			Unknown
		}

		protected DeviceState _deviceState;

		protected float _stateTimer;

		private static bool _isLocalPlayerDisabled;

		private float _delayTimer;

		private bool _destroyed;

		protected static Random _rand = new Random();

		public EMPState State { get; protected set; }

		public EMPController controller { get; protected set; }

		public GameObject gameObject { get; protected set; }

		public static bool IsLocalPlayerDisabled
		{
			get
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Invalid comparison between Unknown and I4
				if (_isLocalPlayerDisabled)
				{
					return (int)GameStateManager.CurrentStateName == 10;
				}
				return false;
			}
		}

		protected virtual float FlickerDuration => 0.2f;

		protected virtual float MinDelay => 0f;

		protected virtual float MaxDelay => 1.5f;

		protected virtual bool IsDeviceOnPlayer => false;

		public virtual void Setup(GameObject gameObject, EMPController controller)
		{
			this.gameObject = gameObject;
			this.controller = controller;
		}

		public static void Cleanup()
		{
			_isLocalPlayerDisabled = false;
		}

		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(bool isEMPD)
		{
			if (_destroyed)
			{
				return;
			}
			if (isEMPD && State == EMPState.On)
			{
				float randomDelay = GetRandomDelay(MinDelay, MaxDelay);
				State = EMPState.FlickerOff;
				_delayTimer = Clock.Time + randomDelay;
				_stateTimer = Clock.Time + FlickerDuration + randomDelay;
			}
			if (!isEMPD && State == EMPState.Off)
			{
				float randomDelay2 = GetRandomDelay(0f, 1.5f);
				State = EMPState.FlickerOn;
				_delayTimer = Clock.Time + randomDelay2;
				_stateTimer = Clock.Time + FlickerDuration + randomDelay2;
			}
			switch (State)
			{
			case EMPState.On:
				if (_deviceState != 0)
				{
					DeviceOn();
					_deviceState = DeviceState.On;
					if (IsDeviceOnPlayer)
					{
						_isLocalPlayerDisabled = false;
					}
				}
				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;
					if (IsDeviceOnPlayer)
					{
						_isLocalPlayerDisabled = true;
					}
				}
				break;
			case EMPState.FlickerOn:
				if (!(_delayTimer > Clock.Time))
				{
					if (Clock.Time < _stateTimer)
					{
						FlickerDevice();
					}
					else
					{
						State = EMPState.On;
					}
				}
				break;
			}
		}

		public void OnDespawn()
		{
			_destroyed = true;
		}

		protected abstract void FlickerDevice();

		protected abstract void DeviceOn();

		protected abstract void DeviceOff();

		protected static float GetRandomDelay(float min, float max)
		{
			return (float)((double)min + _rand.NextDouble() * (double)(max - min));
		}

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

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

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

		protected static bool FlickerUtil(int oneInX = 2)
		{
			return Index(oneInX) == 0;
		}
	}
	public class EMPShock
	{
		public Vector3 position { get; internal set; }

		public float range { get; internal set; }

		public float endTime { get; internal set; }

		public float RemainingTime => endTime - Clock.Time;

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

		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 enum EMPState
	{
		On,
		FlickerOff,
		Off,
		FlickerOn
	}
	public enum ActiveState
	{
		DISABLED,
		ENABLED
	}
	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;
		}
	}
	public class pEMP : EMPShock
	{
		public readonly ItemToDisable DISABLE_NOTHING = new ItemToDisable
		{
			BioTracker = false,
			PlayerFlashLight = false,
			PlayerHUD = false,
			Sentry = false,
			EnvLight = false,
			GunSight = false
		};

		public pEMPDefinition def { get; private set; }

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

		public ActiveState State
		{
			get
			{
				if (StateReplicator == null)
				{
					return ActiveState.DISABLED;
				}
				return StateReplicator.State.status;
			}
		}

		public ItemToDisable ItemToDisable
		{
			get
			{
				if (def == null)
				{
					return DISABLE_NOTHING;
				}
				return def.ItemToDisable;
			}
		}

		public void OnStateChanged(pEMPState oldState, pEMPState newState, bool isRecall)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			if (def == null || oldState.status == newState.status)
			{
				return;
			}
			EOSLogger.Debug($"pEMP_{def.pEMPIndex} Change state: {oldState.status} -> {newState.status}");
			switch (newState.status)
			{
			case ActiveState.DISABLED:
				base.endTime = float.NegativeInfinity;
				break;
			case ActiveState.ENABLED:
				base.endTime = float.PositiveInfinity;
				break;
			default:
				throw new NotImplementedException();
			}
			foreach (EMPController eMPTarget in EMPManager.Current.EMPTargets)
			{
				if ((Object)(object)((Component)eMPTarget).GetComponent<LG_Light>() == (Object)null)
				{
					continue;
				}
				switch (newState.status)
				{
				case ActiveState.DISABLED:
					eMPTarget.ClearTime();
					break;
				case ActiveState.ENABLED:
					if (InRange(eMPTarget.Position))
					{
						eMPTarget.AddTime(float.PositiveInfinity);
					}
					else
					{
						eMPTarget.ClearTime();
					}
					break;
				default:
					throw new NotImplementedException();
				}
			}
		}

		public void ChangeState(ActiveState newState)
		{
			StateReplicator?.SetState(new pEMPState
			{
				status = newState
			});
		}

		internal void SetupReplicator(uint 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_003c: Unknown result type (might be due to invalid IL or missing references)
			this.def = new pEMPDefinition(def);
		}

		internal void Destroy()
		{
			StateReplicator = null;
			def = null;
		}
	}
}
namespace EOSExt.EMP.Impl.Handlers
{
	public class EMPBioTrackerHandler : EMPHandler
	{
		private static List<EMPBioTrackerHandler> handlers;

		private EnemyScanner _scanner;

		public static IEnumerable<EMPBioTrackerHandler> Handlers => handlers;

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

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

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			base.Setup(gameObject, controller);
			_scanner = gameObject.GetComponent<EnemyScanner>();
			if ((Object)(object)_scanner == (Object)null)
			{
				EOSLogger.Error("Couldn't get bio-tracker component!");
			}
			handlers.Add(this);
		}

		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 = EMPHandler.FlickerUtil();
		}
	}
	public class EMPGunSightHandler : EMPHandler
	{
		private static List<EMPGunSightHandler> handlers;

		public GameObject[] _sightPictures;

		public static IEnumerable<EMPGunSightHandler> Handlers => handlers;

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

		private void SetupGunSights()
		{
			Il2CppArrayBase<Renderer> componentsInChildren = base.gameObject.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.gameObject).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(EMPHandler.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 List<EMPLightHandler> handlers;

		private LG_Light _light;

		private float _originalIntensity;

		private Color _originalColor;

		public static IEnumerable<EMPLightHandler> Handlers => handlers;

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

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

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			//IL_0046: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			base.Setup(gameObject, controller);
			_light = gameObject.GetComponent<LG_Light>();
			if ((Object)(object)_light == (Object)null)
			{
				EOSLogger.Warning("No Light!");
			}
			else
			{
				_originalIntensity = _light.GetIntensity();
				_originalColor = new Color(_light.m_color.r, _light.m_color.g, _light.m_color.b, _light.m_color.a);
				base.State = EMPState.On;
			}
			handlers.Add(this);
		}

		protected override void FlickerDevice()
		{
			if (!((Object)(object)_light == (Object)null))
			{
				_light.ChangeIntensity(EMPHandler.GetRandom01() * _originalIntensity);
			}
		}

		protected override void DeviceOn()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_light == (Object)null))
			{
				_light.ChangeIntensity(_originalIntensity);
				_light.ChangeColor(_originalColor);
			}
		}

		protected override void DeviceOff()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_light == (Object)null))
			{
				_light.ChangeIntensity(0f);
				_light.ChangeColor(Color.black);
			}
		}
	}
	public class EMPPlayerFlashLightHandler : EMPHandler
	{
		private static List<EMPPlayerFlashLightHandler> handlers;

		private PlayerInventoryBase _inventory;

		private float _originalIntensity;

		private bool _originalFlashlightState;

		public static IEnumerable<EMPPlayerFlashLightHandler> Handlers => handlers;

		protected override bool IsDeviceOnPlayer => true;

		private bool FlashlightEnabled => _inventory.FlashlightEnabled;

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

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

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			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));
			}
			handlers.Add(this);
		}

		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 = EMPHandler.GetRandom01() * _originalIntensity;
			}
		}
	}
	public class EMPPlayerHudHandler : EMPHandler
	{
		private static List<EMPPlayerHudHandler> handlers;

		private readonly List<RectTransformComp> _targets = new List<RectTransformComp>();

		public static IEnumerable<EMPPlayerHudHandler> Handlers => handlers;

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

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

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			_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);
			handlers.Add(this);
		}

		protected override void DeviceOff()
		{
			foreach (RectTransformComp target in _targets)
			{
				((Component)target).gameObject.SetActive(false);
			}
		}

		protected override void DeviceOn()
		{
			foreach (RectTransformComp target in _targets)
			{
				((Component)target).gameObject.SetActive(true);
			}
		}

		protected override void FlickerDevice()
		{
			foreach (RectTransformComp target in _targets)
			{
				target.SetVisible(EMPHandler.FlickerUtil());
			}
		}
	}
	public class EMPSentryHandler : EMPHandler
	{
		private static List<EMPSentryHandler> handlers;

		private static Color _offColor;

		private SentryGunInstance _sentry;

		private SentryGunInstance_ScannerVisuals_Plane _visuals;

		public static IEnumerable<EMPSentryHandler> Handlers => handlers;

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

		static EMPSentryHandler()
		{
			//IL_000c: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			handlers = new List<EMPSentryHandler>();
			_offColor = new Color
			{
				r = 0f,
				g = 0f,
				b = 0f,
				a = 0f
			};
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}

		public override void Setup(GameObject gameObject, EMPController controller)
		{
			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}");
			}
			handlers.Add(this);
		}

		protected override void DeviceOff()
		{
			//IL_000b: 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)
			_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 = EMPHandler.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;
			}
		}
	}
}

plugins/net6/Inas07.EOSExt.Reactor.dll

Decompiled 4 months 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.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;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Inas07.EOSExt.Reactor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[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]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace 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.0.4")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.Reactor";

		public const string VERSION = "1.0.4";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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]
	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_OnBuildDone
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")]
		private static void Post_LG_WardenObjective_Reactor_OnBuildDone(LG_WardenObjective_Reactor __instance)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0032: 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_0058: 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_0081: 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)
		{
		}

		private static void Shutdown_OnStateChange(LG_WardenObjective_Reactor reactor, pReactorState oldState, pReactorState newState, bool isDropinState, ReactorShutdownDefinition def)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected I4, but got Unknown
			eReactorStatus status = newState.status;
			switch (status - 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]
		[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_000a: 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_0024: 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_0019: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_00a6: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.m_isWardenObjective)
			{
				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;
			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_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 neither startup nor 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			//IL_0091: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_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_0014: 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;
		}
	}
	[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_0012: 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;
			}
			_ = __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_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
			//IL_0031: 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;
		}
	}
}
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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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)
			foreach (IntPtr item in startupReactor)
			{
				LG_WardenObjective_Reactor val = new LG_WardenObjective_Reactor(item);
				if ((int)val != 0)
				{
					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 ((int)val2 != 0)
				{
					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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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 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
		{
			get
			{
				if (CooldownCommandDescTextID == 0)
				{
					return "Confirm Reactor Startup Cooling Protocol";
				}
				return Text.Get(CooldownCommandDescTextID);
			}
		}

		public static string MainTerminalText
		{
			get
			{
				if (MainTerminalTextID == 0)
				{
					return "Main Terminal";
				}
				return Text.Get(MainTerminalTextID);
			}
		}

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

		public static string InfiniteWaveVerifyText
		{
			get
			{
				if (InfiniteWaveVerifyTextID == 0)
				{
					return "VERIFICATION ({0}/{1}).";
				}
				return Text.Get(InfiniteWaveVerifyTextID);
			}
		}

		public static string NotReadyForVerificationOutputText
		{
			get
			{
				if (NotReadyForVerificationOutputTextID == 0)
				{
					return "<color=red>Reactor intensive test in progress, cannot initate cooldown</color>";
				}
				return Text.Get(NotReadyForVerificationOutputTextID);
			}
		}

		public static string CorrectTerminalOutputText
		{
			get
			{
				if (CorrectTerminalOutputTextID == 0)
				{
					return "<color=red>Reactor stage cooldown completed</color>";
				}
				return Text.Get(CorrectTerminalOutputTextID);
			}
		}

		public static string IncorrectTerminalOutputText
		{
			get
			{
				if (IncorrectTerminalOutputTextID == 0)
				{
					return "<color=red>Incorrect terminal, cannot initate cooldown</color>";
				}
				return Text.Get(IncorrectTerminalOutputTextID);
			}
		}

		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 >= o2.WaveIndex) ? ((o1.WaveIndex > o2.WaveIndex) ? 1 : 0) : (-1));
			});
			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)
			{
				ChainedPuzzleInstance chainedPuzzleToActiveInstance = def.ChainedPuzzleToActiveInstance;
				chainedPuzzleToActiveInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate
				{
					def.EventsOnActive.ForEach(delegate(WardenObjectiveEventData e)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
					});
				});
			}
			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;
		}
	}
	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, TerminalDefinition reactorTerminalData)
		{
			//IL_0052: 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] { SerialGenerator.GetCodeWord() });
			reactor.m_terminalItem.OnWantDetailedInfo = Func<List<string>, List<string>>.op_Implicit((Func<List<string>, List<string>>)delegate(List<string> defaultDetails)
			{
				List<string> list = new List<string> { "----------------------------------------------------------------", "MAIN POWER REACTOR" };
				Enumerator<string> enumerator = defaultDetails.GetEnumerator();
				while (enumerator.MoveNext())
				{
					string current = enumerator.Current;
					list.Add(current);
				}
				list.Add("----------------------------------------------------------------");
				return ListExtensions.ToIl2Cpp<string>(list);
			});
			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, reactorTerminalData);
		}

		private void OnLateBuildJob(LG_WardenObjective_Reactor reactor, BaseReactorDefinition reactorDefinition)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0044: Expected O, but got Unknown
			//IL_0066: 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, reactorDefinition.ReactorTerminal);
			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_009d: 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_015e: 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_0164: 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_019b: Expected O, but got Unknown
			//IL_019d: Expected O, but got Unknown
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: 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_0315: 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" + SerialGenerator.GetCodeWordPrefix() + ".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
				{
					_ = ((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");
				}
				_ = ((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();
		}
	}
}
namespace EOSExt.Reactor.Definition
{
	public enum EOSReactorVerificationType
	{
		NORMAL,
		BY_SPECIAL_COMMAND,
		BY_WARDEN_EVENT
	}
	public class WaveOverride
	{
		public int WaveIndex { get; set; } = -1;


		public EOSReactorVerificationType VerificationType { get; set; }

		public bool HideVerificationTimer { get; set; }

		public bool ChangeVerifyZone { get; set; }

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


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

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

		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_0009: 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)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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)
			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;
			}
			if ((int)val.m_currentState.status == 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_0006: 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_0029: Invalid comparison between Unknown and I4
			//IL_0068: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			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");
		}
	}
	public class BaseReactorDefinition : BaseInstanceDefinition
	{
		[JsonPropertyOrder(-9)]
		public TerminalDefinition ReactorTerminal { get; set; } = new TerminalDefinition();


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


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

		public bool PutVerificationCodeOnTerminal { get; set; }

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


		public uint ChainedPuzzleOnVerification { get; set; }

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

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


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

	}
}
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;
			}
			int i;
			for (i = 0; i < ObjectiveData.ReactorWaves.Count; i++)
			{
				int num = overrideData.Overrides.FindIndex((WaveOverride o) => o.WaveIndex == i);
				if (num != -1)
				{
					WaveData.Add(new WaveOverride
					{
						WaveIndex = i,
						VerificationType = overrideData.Overrides[num].VerificationType,
						HideVerificationTimer = overrideData.Overrides[num].HideVerificationTimer,
						ChangeVerifyZone = overrideData.Overrides[num].ChangeVerifyZone,
						VerifyZone = overrideData.Overrides[num].VerifyZone
					});
				}
				else
				{
					WaveData.Add(new WaveOverride
					{
						WaveIndex = i
					});
				}
			}
			LevelAPI.OnEnterLevel += OnEnterLevel;
		}

		private void OnEnterLevel()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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();
		}

		private void SetupVerifyZoneOverrides()
		{
			//IL_0094: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Expected O, but got Unknown
			//IL_041f: Expected O, but got Unknown
			//IL_0240: 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_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: 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_02e0: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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 AddVerifyCommand(LG_ComputerTerminal terminal)
		{
			//IL_0024: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0011: 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_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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ChainedReactor == (Object)null))
			{
				pReactorState val = default(pReactorState);
				val.status = (eReactorStatus)0;
				val.stateCount = 0;
				val.stateProgress = 0f;
				val.verifyFailed = false;
				pReactorState state = val;
				ChainedReactor.m_stateReplicator.State = state;
			}
		}

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

		private void LateUpdate()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_001a: 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_0024: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			int num = ChainedReactor.m_currentWaveCount - 1;
			if (num < 0)
			{
				return;
			}
			WaveOverride waveOverride = WaveData[num];
			if ((int)status != 4)
			{
				return;
			}
			switch (waveOverride.VerificationType)
			{
			case EOSReactorVerificationType.NORMAL:
				if (ChainedReactor.m_currentWaveData.HasVerificationTerminal)
				{
					ChainedReactor.SetGUIMessage(true, Text.Format(1103u, (Object[])(object)new Object[3]
					{
						Object.op_Implicit(ChainedReactor.m_currentWaveCount),
						Object.op_Implicit(ChainedReactor.m_waveCountMax),
						Object.op_Implicit("<color=orange>" + ChainedReactor.m_currentWaveData.VerificationTerminalSerial + "</color>")
					}), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>");
				}
				else
				{
					ChainedReactor.SetGUIMessage(true, Text.Format(1105u, (Object[])(object)new Object[3]
					{
						Object.op_Implicit(ChainedReactor.m_currentWaveCount),
						Object.op_Implicit(ChainedReactor.m_waveCountMax),
						Object.op_Implicit("<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);
				ChainedReactor.SetGUIMessage(true, string.Format(ReactorStartupOverrideManager.SpecialCmdVerifyText, 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:
				ChainedReactor.SetGUIMessage(true, string.Format(ReactorStartupOverrideManager.InfiniteWaveVerifyText, 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected I4, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0060: 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_006b: 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_0083: 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_001d: 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/net6/Inas07.EOSExt.SecurityDoorTerminal.dll

Decompiled 4 months 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 BepInEx;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using EOSExt.SecurityDoorTerminal.Definition;
using ExtraObjectiveSetup;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.BaseClasses.CustomTerminalDefinition;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Utils;
using GTFO.API;
using GTFO.API.Extensions;
using GameData;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SecDoorTerminalInterface;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EOSExt.SecurityDoorTerminal
{
	[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.SecurityDoorTerminal", "EOSExt.SecurityDoorTerminal", "1.0.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.SecurityDoorTerminal";

		public const string VERSION = "1.0.0";

		public override void Load()
		{
			SetupManagers();
			EOSLogger.Log("ExtraObjectiveSetup.SecurityDoorTerminal loaded.");
		}

		private void SetupManagers()
		{
			((ZoneDefinitionManager<SecurityDoorTerminalDefinition>)SecurityDoorTerminalManager.Current).Init();
		}
	}
	public sealed class SecurityDoorTerminalManager : ZoneDefinitionManager<SecurityDoorTerminalDefinition>
	{
		private enum SDTWardenEvents
		{
			ADD_OVERRIDE_COMMAND = 1000
		}

		private const string OVERRIDE_COMMAND = "ACCESS_OVERRIDE";

		private List<(SecDoorTerminal sdt, SecurityDoorTerminalDefinition def)> levelSDTs = new List<(SecDoorTerminal, SecurityDoorTerminalDefinition)>();

		public static SecurityDoorTerminalManager Current { get; private set; }

		protected override string DEFINITION_NAME => "SecDoorTerminal";

		public bool TryGetZoneEntranceSecDoor(LG_Zone zone, out LG_SecurityDoor door)
		{
			if ((Object)(object)zone == (Object)null)
			{
				door = null;
				return false;
			}
			if ((Object)(object)zone.m_sourceGate == (Object)null)
			{
				door = null;
				return false;
			}
			if (zone.m_sourceGate.SpawnedDoor == null)
			{
				door = null;
				return false;
			}
			door = ((Il2CppObjectBase)zone.m_sourceGate.SpawnedDoor).TryCast<LG_SecurityDoor>();
			return (Object)(object)door != (Object)null;
		}

		protected override void AddDefinitions(ZoneDefinitionsForLevel<SecurityDoorTerminalDefinition> definitions)
		{
			base.Sort(definitions);
			base.AddDefinitions(definitions);
		}

		private void AddOverrideCommandWithAlarmText(SecDoorTerminal sdt)
		{
			if (sdt.CmdProcessor.HasRegisteredCommand((TERM_Command)254))
			{
				return;
			}
			string text = "<color=orange>" + Text.Get(841u) + "</color>";
			if ((Object)(object)sdt.LinkedDoorLocks.ChainedPuzzleToSolve != (Object)null && sdt.LinkedDoorLocks.ChainedPuzzleToSolve.Data.TriggerAlarmOnActivate)
			{
				string format = Text.Get(840u);
				ChainedPuzzleInstance chainedPuzzleToSolve = sdt.LinkedDoorLocks.ChainedPuzzleToSolve;
				text = "<color=orange>" + string.Format(format, (chainedPuzzleToSolve != null) ? chainedPuzzleToSolve.Data.PublicAlarmName : null) + "</color>";
				int num = text.IndexOf('[');
				if (num >= 0 && num < text.Length)
				{
					text = text.Insert(num, "\n");
				}
			}
			sdt.AddOverrideCommand("ACCESS_OVERRIDE", text, (Action<LG_ComputerTerminalCommandInterpreter>)null);
		}

		private void BuildSDT_UniqueCommands(SecDoorTerminal sdt, SecurityDoorTerminalDefinition def)
		{
			def.TerminalSettings.UniqueCommands.ForEach(delegate(CustomCommand cmd)
			{
				EOSTerminalUtils.AddUniqueCommand(sdt.ComputerTerminal, cmd);
			});
		}

		private void BuildLevelSDTs_UniqueCommands()
		{
			levelSDTs.ForEach(delegate((SecDoorTerminal sdt, SecurityDoorTerminalDefinition def) tp)
			{
				BuildSDT_UniqueCommands(tp.sdt, tp.def);
			});
		}

		private void BuildLevelSDTs_Passwords()
		{
			levelSDTs.ForEach(delegate((SecDoorTerminal sdt, SecurityDoorTerminalDefinition def) tp)
			{
				EOSTerminalUtils.BuildPassword(tp.sdt.ComputerTerminal, tp.def.TerminalSettings.PasswordData);
			});
		}

		private void WardenEvent_AddOverrideCommand(WardenObjectiveEventData e)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			int num = levelSDTs.FindIndex(delegate((SecDoorTerminal sdt, SecurityDoorTerminalDefinition def) tp)
			{
				//IL_0021: 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_0034: 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_004c: 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)
				AIG_CourseNode courseNode = ((LG_ZoneExpander)tp.sdt.LinkedDoor.Gate).m_linksTo.m_courseNode;
				return courseNode.m_dimension.DimensionIndex == e.DimensionIndex && courseNode.LayerType == e.Layer && courseNode.m_zone.LocalIndex == e.LocalIndex;
			});
			if (num == -1)
			{
				EOSLogger.Error($"SDT_AddOverrideCommand: SDT not found on door to {(e.DimensionIndex, e.Layer, e.LocalIndex)}");
			}
			else
			{
				SecDoorTerminal item = levelSDTs[num].sdt;
				AddOverrideCommandWithAlarmText(item);
				EOSLogger.Debug($"SDT_AddOverrideCommand: added for SDT {(e.DimensionIndex, e.Layer, e.LocalIndex)}");
			}
		}

		private SecDoorTerminal BuildSDT_Instantiation(SecurityDoorTerminalDefinition def)
		{
			//IL_0020: 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: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_003a: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected I4, but got Unknown
			var (val, val2, val3) = ((GlobalZoneIndex)def).GlobalZoneIndexTuple();
			LG_Zone val4 = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(val, val2, val3, ref val4) || (Object)(object)val4 == (Object)null)
			{
				EOSLogger.Error($"SecDoorTerminal: Cannot find target zone {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}");
				return null;
			}
			if (!TryGetZoneEntranceSecDoor(val4, out var door) || (Object)(object)door == (Object)null)
			{
				EOSLogger.Error($"SecDoorTerminal: Cannot find spawned sec-door for zone {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}");
				return null;
			}
			SecDoorTerminal sdt = SecDoorTerminal.Place(door, new TerminalStartStateData
			{
				StartingState = (TERM_State)0
			}, (TerminalPlacementData)null);
			sdt.BioscanScanSolvedBehaviour = def.StateSettings.OnPuzzleSolved;
			if (sdt == null)
			{
				EOSLogger.Error("Build failed: Can only attach SDT to regular security door");
				return null;
			}
			((LG_ZoneExpander)val4.m_sourceGate).m_linksFrom.m_zone.TerminalsSpawnedInZone.Add(sdt.ComputerTerminal);
			sdt.BioscanScanSolvedBehaviour = def.StateSettings.OnPuzzleSolved;
			def.TerminalSettings.LocalLogFiles.ForEach(delegate(TerminalLogFileData log)
			{
				sdt.ComputerTerminal.AddLocalLog(log, true);
			});
			eDoorStatus status = sdt.LinkedDoor.m_sync.GetCurrentSyncState().status;
			switch (status - 1)
			{
			case 2:
				if (def.StateSettings.LockedStateSetting.AccessibleWhenLocked)
				{
					sdt.LinkedDoorLocks.m_gateKeyItemNeeded.keyPickupCore.m_interact.OnPickedUpByPlayer += Action<PlayerAgent>.op_Implicit((Action<PlayerAgent>)delegate
					{
						sdt.SetTerminalActive(false);
					});
					sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked);
					List<string> list4 = new List<string> { string.Format("<color=orange>" + Text.Get(849u) + "</color>", sdt.LinkedDoorLocks.m_gateKeyItemNeeded.PublicName) };
					sdt.ComputerTerminal.m_command.AddOutput(ListExtensions.ToIl2Cpp<string>(list4));
				}
				break;
			case 5:
				sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked);
				if (def.StateSettings.LockedStateSetting.AccessibleWhenLocked)
				{
					List<string> list2 = new List<string> { string.Format("<color=orange>" + Text.Get(842u) + "</color>", sdt.LinkedDoorLocks.m_powerGeneratorNeeded.PublicName) };
					sdt.ComputerTerminal.m_command.AddOutput(ListExtensions.ToIl2Cpp<string>(list2));
				}
				break;
			case 14:
				sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked);
				if (def.StateSettings.LockedStateSetting.AccessibleWhenLocked)
				{
					List<string> list = new List<string> { string.Format("<color=orange>" + Text.Get(843u) + "</color>", sdt.LinkedDoorLocks.m_bulkheadDCNeeded.PublicName) };
					sdt.ComputerTerminal.m_command.AddOutput(ListExtensions.ToIl2Cpp<string>(list));
				}
				break;
			case 6:
				sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked);
				if (def.StateSettings.LockedStateSetting.AccessibleWhenLocked)
				{
					List<string> list3 = new List<string> { sdt.LinkedDoorLocks.m_intCustomMessage.m_message };
					sdt.ComputerTerminal.m_command.AddOutput(ListExtensions.ToIl2Cpp<string>(list3));
				}
				else
				{
					sdt.SetCustomMessageActive(true);
				}
				break;
			case 0:
			case 3:
			case 4:
			case 8:
				if (def.StateSettings.OverrideCommandAccessibility != OverrideCmdAccess.ADDED_BY_WARDEN_EVENT)
				{
					AddOverrideCommandWithAlarmText(sdt);
				}
				sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenUnlocked);
				break;
			}
			sdt.LinkedDoor.m_sync.OnDoorStateChange += Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)delegate(pDoorState state, bool isDropin)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Expected I4, but got Unknown
				//IL_0064: 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_006b: Invalid comparison between Unknown and I4
				eDoorStatus status3 = state.status;
				switch (status3 - 3)
				{
				case 0:
				case 3:
				case 4:
				case 12:
					sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked);
					if ((int)state.status == 7)
					{
						sdt.SetCustomMessageActive(true);
					}
					break;
				case 1:
				case 2:
				case 6:
					sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenUnlocked);
					break;
				case 5:
				case 7:
				case 8:
				case 9:
				case 10:
				case 11:
					break;
				}
			});
			switch (def.StateSettings.OverrideCommandAccessibility)
			{
			case OverrideCmdAccess.ALWAYS:
				AddOverrideCommandWithAlarmText(sdt);
				break;
			case OverrideCmdAccess.ON_UNLOCK:
				sdt.LinkedDoor.m_sync.OnDoorStateChange += Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)delegate(pDoorState state, bool isDropin)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_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_0009: Unknown result type (might be due to invalid IL or missing references)
					//IL_000b: Invalid comparison between Unknown and I4
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Invalid comparison between Unknown and I4
					eDoorStatus status2 = state.status;
					if (status2 - 4 <= 1 || (int)status2 == 9)
					{
						AddOverrideCommandWithAlarmText(sdt);
					}
				});
				break;
			}
			return sdt;
		}

		public override void Init()
		{
			base.Init();
		}

		private void BuildLevelSDTs_Instantiation()
		{
			if (!base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData))
			{
				return;
			}
			foreach (SecurityDoorTerminalDefinition definition in base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions)
			{
				SecDoorTerminal item = BuildSDT_Instantiation(definition);
				levelSDTs.Add((item, definition));
			}
		}

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

		private SecurityDoorTerminalManager()
		{
			EOSWardenEventManager.Current.AddEventDefinition(SDTWardenEvents.ADD_OVERRIDE_COMMAND.ToString(), 1000u, (Action<WardenObjectiveEventData>)WardenEvent_AddOverrideCommand);
			BatchBuildManager.Current.Add_OnBatchDone((BatchName)75, (Action)BuildLevelSDTs_Instantiation);
			BatchBuildManager.Current.Add_OnBatchDone((BatchName)76, (Action)BuildLevelSDTs_Passwords);
			LevelAPI.OnBuildDone += BuildLevelSDTs_UniqueCommands;
			LevelAPI.OnLevelCleanup += OnLevelCleanup;
		}

		static SecurityDoorTerminalManager()
		{
			Current = new SecurityDoorTerminalManager();
		}
	}
}
namespace EOSExt.SecurityDoorTerminal.Definition
{
	public enum OverrideCmdAccess
	{
		ALWAYS,
		ON_UNLOCK,
		ADDED_BY_WARDEN_EVENT
	}
	public class SDTStateSetting_Locked
	{
		public bool AccessibleWhenLocked { get; set; }

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

	}
	public class SDTStateSetting
	{
		public SDTStateSetting_Locked LockedStateSetting { get; set; } = new SDTStateSetting_Locked();


		public OverrideCmdAccess OverrideCommandAccessibility { get; set; } = OverrideCmdAccess.ON_UNLOCK;


		public CPSolvedBehaviour OnPuzzleSolved { get; set; } = (CPSolvedBehaviour)1;

	}
	public class SecurityDoorTerminalDefinition : GlobalZoneIndex
	{
		public SDTStateSetting StateSettings { get; set; } = new SDTStateSetting();


		public TerminalDefinition TerminalSettings { get; set; } = new TerminalDefinition();

	}
}

plugins/net6/Inas07.EOSExt.SecuritySensor.dll

Decompiled 4 months 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 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 FloLib.Networks.Replications;
using GTFO.API;
using GTFO.API.Extensions;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Inas07.EOSExt.SecuritySensor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[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]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace 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.1.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "EOSExt.SecuritySensor";

		public const string VERSION = "1.1.0";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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();
		}
	}
	internal class MovableSensor
	{
		public GameObject movableGO { get; private set; }

		public CP_BasicMovable movingComp { get; private set; }

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

		public static MovableSensor Instantiate(SensorSettings sensorSetting)
		{
			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();
			List<Vector3> scanPositions = ListExtensions.ToIl2Cpp<Vector3>(sensorSetting.MovingPosition.Prepend(sensorSetting.Position).ToList().ConvertAll((Vec3 vec3) => vec3.ToVector3()));
			movableSensor.movingComp.ScanPositions = scanPositions;
			movableSensor.movingComp.m_amountOfPositions = sensorSetting.MovingPosition.Count;
			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
	}
	public sealed class SecuritySensorManager : GenericExpeditionDefinitionManager<SensorGroupSettings>
	{
		private List<(SensorGroupSettings settings, SensorGroup sensorGroup)> securitySensorGroups = new List<(SensorGroupSettings, SensorGroup)>();

		private Dictionary<IntPtr, int> sensorGroupIndex = new Dictionary<IntPtr, int>();

		public static SecuritySensorManager Current { get; private set; }

		protected override string DEFINITION_NAME => "SecuritySensor";

		public void BuildSensorGroup(SensorGroupSettings sensorGroupSettings)
		{
			int count = securitySensorGroups.Count;
			SensorGroup sensorGroup = SensorGroup.Instantiate(sensorGroupSettings, count);
			securitySensorGroups.Add((sensorGroupSettings, sensorGroup));
			foreach (GameObject sensorGO in sensorGroup.SensorGOs)
			{
				sensorGroupIndex[((Il2CppObjectBase)sensorGO).Pointer] = count;
			}
			foreach (MovableSensor movableSensor in sensorGroup.MovableSensors)
			{
				sensorGroupIndex[((Il2CppObjectBase)movableSensor.movableGO).Pointer] = count;
			}
			EOSLogger.Debug($"SensorGroup_{count} built");
		}

		internal void TriggerSensor(IntPtr pointer)
		{
			if (!sensorGroupIndex.ContainsKey(pointer))
			{
				EOSLogger.Error("Triggering a sensor but doesn't find its corresponding sensor group! This should not happen!");
				return;
			}
			int num = sensorGroupIndex[pointer];
			if (num < 0 || num >= securitySensorGroups.Count)
			{
				EOSLogger.Error($"TriggerSensor: invalid SensorGroup index {num}");
				return;
			}
			securitySensorGroups[num].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_{num} triggered");
		}

		private void BuildSecuritySensor()
		{
			if (base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData))
			{
				base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.ForEach(BuildSensorGroup);
			}
		}

		private void Clear()
		{
			securitySensorGroups.ForEach(delegate((SensorGroupSettings settings, SensorGroup sensorGroup) builtSensorGroup)
			{
				builtSensorGroup.sensorGroup.Destroy();
			});
			securitySensorGroups.Clear();
			sensorGroupIndex.Clear();
		}

		private void ToggleSensorGroup(WardenObjectiveEventData e)
		{
			int count = e.Count;
			bool enabled = e.Enabled;
			if (count < 0 || count >= securitySensorGroups.Count)
			{
				EOSLogger.Error($"ToggleSensorGroup: invalid SensorGroup index {count}");
			}
			else
			{
				securitySensorGroups[count].sensorGroup.ChangeState(enabled ? ActiveState.ENABLED : ActiveState.DISABLED);
			}
		}

		private SecuritySensorManager()
		{
			LevelAPI.OnBuildStart += delegate
			{
				Clear();
				BuildSecuritySensor();
			};
			LevelAPI.OnLevelCleanup += Clear;
			EventAPI.OnExpeditionStarted += delegate
			{
				securitySensorGroups.ForEach(delegate((SensorGroupSettings settings, SensorGroup sensorGroup) tuple)
				{
					tuple.sensorGroup.StartMovingMovables();
				});
			};
			EOSWardenEventManager.Current.AddEventDefinition(SensorEventType.ToggleSensorGroupState.ToString(), 400u, (Action<WardenObjectiveEventData>)ToggleSensorGroup);
		}

		static SecuritySensorManager()
		{
			Current = new SecuritySensorManager();
		}
	}
	internal class SensorGroup
	{
		private List<GameObject> GOSensorGroup = new List<GameObject>();

		private List<MovableSensor> movableSensors = new List<MovableSensor>();

		public int sensorGroupIndex { get; private set; }

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

		public IEnumerable<GameObject> SensorGOs => GOSensorGroup;

		public IEnumerable<MovableSensor> MovableSensors => movableSensors;

		public void ChangeState(ActiveState status)
		{
			switch (status)
			{
			case ActiveState.ENABLED:
				GOSensorGroup.ForEach(delegate(GameObject sensorGO)
				{
					sensorGO.SetActiveRecursively(true);
				});
				ResumeMovingMovables();
				break;
			case ActiveState.DISABLED:
				PauseMovingMovables();
				GOSensorGroup.ForEach(delegate(GameObject sensorGO)
				{
					sensorGO.SetActiveRecursively(false);
				});
				break;
			}
			EOSLogger.Debug($"ChangeState: SecuritySensorGroup_{sensorGroupIndex} changed to state {status}");
			StateReplicator.SetState(new SensorGroupState
			{
				status = status
			});
		}

		private void OnStateChanged(SensorGroupState oldState, SensorGroupState newState, bool isRecall)
		{
			EOSLogger.Warning($"OnStateChanged: isRecall ? {isRecall}");
			if (!isRecall)
			{
				return;
			}
			EOSLogger.Debug($"Recalling: SecuritySensorGroup_{sensorGroupIndex} changed to state {newState.status}");
			switch (newState.status)
			{
			case ActiveState.ENABLED:
				GOSensorGroup.ForEach(delegate(GameObject sensorGO)
				{
					sensorGO.SetActiveRecursively(true);
				});
				ResumeMovingMovables();
				break;
			case ActiveState.DISABLED:
				PauseMovingMovables();
				GOSensorGroup.ForEach(delegate(GameObject sensorGO)
				{
					sensorGO.SetActiveRecursively(false);
				});
				break;
			}
		}

		public static SensorGroup Instantiate(SensorGroupSettings sensorGroupSettings, int sensorGroupIndex)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			SensorGroup sensorGroup = new SensorGroup();
			sensorGroup.sensorGroupIndex = sensorGroupIndex;
			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.GOSensorGroup.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;
				val2.AddComponent<SensorCollider>().Setup(item);
				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()
		{
			GOSensorGroup.ForEach((Action<GameObject>)Object.Destroy);
			GOSensorGroup.Clear();
			movableSensors.ForEach(delegate(MovableSensor m)
			{
				m.Destroy();
			});
			movableSensors.Clear();
			StateReplicator = 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;
		}
	}
}
namespace EOSExt.SecuritySensor.Component
{
	public class SensorCollider : MonoBehaviour
	{
		private float nextCheckTime = float.NaN;

		private SensorSettings sensorSettings;

		private int last_playersInSensor;

		public static float CHECK_INTERVAL { get; } = 0.1f;


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

		internal void Setup(SensorSettings sensorSettings)
		{
			this.sensorSettings = sensorSettings;
		}

		private void Update()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0062: 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_006d: 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)
			if ((int)GameStateManager.CurrentStateName != 10 || (!float.IsNaN(nextCheckTime) && Clock.Time < nextCheckTime))
			{
				return;
			}
			nextCheckTime = Clock.Time + CHECK_INTERVAL;
			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 < sensorSettings.Radius)
					{
						num++;
					}
				}
			}
			if (num > last_playersInSensor)
			{
				SecuritySensorManager.Current.TriggerSensor(((Il2CppObjectBase)((Component)this).gameObject).Pointer);
			}
			last_playersInSensor = num;
		}
	}
}
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 SensorColor
	{
		public float r { get; set; }

		public float g { get; set; }

		public float b { get; set; }

		public float a { get; set; }

		public Color toColor()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Color(r, g, b, a);
		}
	}
	public class SensorGroupSettings
	{
		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 SensorType SensorType { get; set; }

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


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

	}
}

plugins/net6/Inas07.ExtraObjectiveSetup.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using AIGraph;
using AK;
using Agents;
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.JSON;
using ExtraObjectiveSetup.Objectives.ActivateSmallHSU;
using ExtraObjectiveSetup.Objectives.GeneratorCluster;
using ExtraObjectiveSetup.Objectives.IndividualGenerator;
using ExtraObjectiveSetup.Objectives.TerminalUplink;
using ExtraObjectiveSetup.Tweaks.BossEvents;
using ExtraObjectiveSetup.Tweaks.Scout;
using ExtraObjectiveSetup.Tweaks.TerminalPosition;
using ExtraObjectiveSetup.Utils;
using FloLib.Networks.Replications;
using GTFO.API;
using GTFO.API.Extensions;
using GTFO.API.JSON.Converters;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
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.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Inas07.ExtraObjectiveSetup")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[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]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace 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> OnBatchDone = new Dictionary<BatchName, Action>();

		public static BatchBuildManager Current { get; private set; }

		public void Init()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (OnBatchDone.Count > 0)
			{
				return;
			}
			foreach (object value in Enum.GetValues(typeof(BatchName)))
			{
				OnBatchDone[(BatchName)value] = 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];
		}

		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.*/)]
	[BepInPlugin("Inas.ExtraObjectiveSetup", "ExtraObjectiveSetup", "1.4.4")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "ExtraObjectiveSetup";

		public const string VERSION = "1.4.4";

		private Harmony m_Harmony;

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

		private void SetupManagers()
		{
			BatchBuildManager.Current.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();
		}
	}
}
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_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_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_0033: 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_0073: 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)
			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();
			if (!localLogs.ContainsKey(logName))
			{
				return null;
			}
			return localLogs[logName];
		}

		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 LG_ComputerTerminal SelectPasswordTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, eSeedType seedType, int staticSeed = 1)
		{
			//IL_0000: 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)
			//IL_001b: 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_0073: 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_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_012d: Expected I4, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: 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_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Expected O, but got Unknown
			//IL_04ce: 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 = SerialGenerator.GetCodeWord();
			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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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)
			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, cmd.SpecialCommandRule, ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents), ListExtensions.ToIl2Cpp<TerminalOutput>(cmd.PostCommandOutputs));
			for (int i = 0; i < cmd.CommandEvents.Count; i++)
			{
				WardenObjectiveEventData val2 = cmd.CommandEvents[i];
				if (val2.ChainPuzzle == 0)
				{
					continue;
				}
				ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(val2.ChainPuzzle);
				if (block != null)
				{
					ChainedPuzzleInstance val3 = ChainedPuzzleManager.CreatePuzzleInstance(block, terminal.SpawnNode.m_area, terminal.m_wardenObjectiveSecurityScanAlign.position, terminal.m_wardenObjectiveSecurityScanAlign, val2.UseStaticBioscanPoints);
					List<WardenObjectiveEventData> events = ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents.GetRange(i, cmd.CommandEvents.Count - i));
					val3.OnPuzzleSolved += Action.op_Implicit((Action)delegate
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(events, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
					});
					terminal.SetChainPuzzleForCommand(val, i, val3);
				}
			}
		}
	}
	public static class Helper
	{
	}
	public class Vec3
	{
		public float x { get; set; }

		public float y { get; set; }

		public float z { get; set; }

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

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

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

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

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

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

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

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

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

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)32, (object)str);
			}
		}
	}
}
namespace ExtraObjectiveSetup.Tweaks.TerminalPosition
{
	public class TerminalPosition : BaseInstanceDefinition
	{
		public Vec3 Position { get; set; } = new Vec3();


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

	}
	internal class TerminalPositionOverrideManager : InstanceDefinitionManager<TerminalPosition>
	{
		public static TerminalPositionOverrideManager Current;

		protected override string DEFINITION_NAME => "TerminalPosition";

		private TerminalPositionOverrideManager()
		{
		}

		static TerminalPositionOverrideManager()
		{
			Current = new TerminalPositionOverrideManager();
		}
	}
}
namespace ExtraObjectiveSetup.Tweaks.Scout
{
	public class EventsOnZoneScoutScream : GlobalZoneIndex
	{
		public bool SuppressVanillaScoutWave { get; set; }

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

	}
	internal class ScoutScreamEventManager : ZoneDefinitionManager<EventsOnZoneScoutScream>
	{
		public static ScoutScreamEventManager Current;

		protected override string DEFINITION_NAME => "EventsOnScoutScream";

		private ScoutScreamEventManager()
		{
		}

		static ScoutScreamEventManager()
		{
			Current = new ScoutScreamEventManager();
		}
	}
}
namespace ExtraObjectiveSetup.Tweaks.BossEvents
{
	public class EventsOnZoneBossDeath : GlobalZoneIndex
	{
		public bool ApplyToHibernate { get; set; } = true;


		public int ApplyToHibernateCount { get; set; } = int.MaxValue;


		public bool ApplyToWave { get; set; }

		public int ApplyToWaveCount { get; set; } = int.MaxValue;


		public List<uint> BossIDs { get; set; } = new List<uint> { 29u, 36u, 37u };


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

	}
	internal class BossDeathEventManager : ZoneDefinitionManager<EventsOnZoneBossDeath>
	{
		public enum Mode
		{
			HIBERNATE,
			WAVE
		}

		public static BossDeathEventManager Current;

		private ConcurrentDictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex, Mode), int> InLevelBDEventsExecution = new ConcurrentDictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex, Mode), int>();

		protected override string DEFINITION_NAME => "EventsOnBossDeath";

		public void RegisterInLevelBDEventsExecution(EventsOnZoneBossDeath def, Mode mode)
		{
			//IL_0003: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex, Mode) key = (def.DimensionIndex, def.LayerType, def.LocalIndex, mode);
			if (!InLevelBDEventsExecution.ContainsKey(key))
			{
				switch (mode)
				{
				case Mode.HIBERNATE:
					InLevelBDEventsExecution[key] = def.ApplyToHibernateCount;
					return;
				case Mode.WAVE:
					InLevelBDEventsExecution[key] = def.ApplyToWaveCount;
					return;
				}
				EOSLogger.Error($"BossDeathEventManager.RegisterInLevelBDEventsExecution: unimplemented mode: {mode}");
			}
		}

		public bool TryConsumeBDEventsExecutionTimes(EventsOnZoneBossDeath def, Mode mode)
		{
			//IL_0002: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			return TryConsumeBDEventsExecutionTimes(def.DimensionIndex, def.LayerType, def.LocalIndex, mode);
		}

		public bool TryConsumeBDEventsExecutionTimes(eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex, Mode mode)
		{
			//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_0052: 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)
			//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)
			//IL_0076: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!InLevelBDEventsExecution.ContainsKey((dimensionIndex, layer, localIndex, mode)))
			{
				EOSLogger.Error($"BossDeathEventManager: got an unregistered entry: {(dimensionIndex, layer, localIndex, mode)}");
				return false;
			}
			int num = InLevelBDEventsExecution[(dimensionIndex, layer, localIndex, mode)];
			if (num == int.MaxValue)
			{
				return true;
			}
			if (num > 0)
			{
				InLevelBDEventsExecution[(dimensionIndex, layer, localIndex, mode)] = num - 1;
				return true;
			}
			return false;
		}

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

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

		static BossDeathEventManager()
		{
			Current = new BossDeathEventManager();
		}
	}
}
namespace ExtraObjectiveSetup.Patches
{
	[HarmonyPatch]
	internal class Patch_CheckAndExecuteEventsOnTrigger
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(WardenObjectiveManager), "CheckAndExecuteEventsOnTrigger", new Type[]
		{
			typeof(WardenObjectiveEventData),
			typeof(eWardenObjectiveEventTrigger),
			typeof(bool),
			typeof(float)
		})]
		private static bool Pre_CheckAndExecuteEventsOnTrigger(WardenObjectiveEventData eventToTrigger, eWardenObjectiveEventTrigger trigger, bool ignoreTrigger, float currentDuration)
		{
			//IL_0007: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected I4, but got Unknown
			if (eventToTrigger == null || (!ignoreTrigger && eventToTrigger.Trigger != trigger) || ((double)currentDuration != 0.0 && eventToTrigger.Delay <= currentDuration))
			{
				return true;
			}
			uint num = (uint)(int)eventToTrigger.Type;
			if (!EOSWardenEventManager.Current.HasEventDefinition(num))
			{
				return true;
			}
			string value = (EOSWardenEventManager.Current.IsVanillaEventID(num) ? "overriding vanilla event implementation..." : "executing...");
			EOSLogger.Debug($"WardenEvent: found definition for event ID {num}, {value}");
			EOSWardenEventManager.Current.ExecuteEvent(eventToTrigger, currentDuration);
			return false;
		}
	}
	[HarmonyPatch]
	internal class Patch_EventsOnBossDeath
	{
		private static HashSet<ushort> ExecutedForInstances;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EnemySync), "OnSpawn")]
		private static void Post_SpawnEnemy(EnemySync __instance, pEnemySpawnData spawnData)
		{
			//IL_0034: 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_0045: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Invalid comparison between Unknown and I4
			//IL_00a2: 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_00a9: Invalid comparison between Unknown and I4
			//IL_00b9: 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_00c0: Invalid comparison between Unknown and I4
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			AIG_CourseNode val = null;
			if (!((pCourseNode)(ref spawnData.courseNode)).TryGet(ref val) || val == null)
			{
				EOSLogger.Error("Failed to get spawnnode for a boss! Skipped EventsOnBossDeath for it");
				return;
			}
			LG_Zone zone = val.m_zone;
			EventsOnZoneBossDeath def = BossDeathEventManager.Current.GetDefinition(zone.DimensionIndex, zone.Layer.m_type, zone.LocalIndex);
			if (def == null)
			{
				return;
			}
			EnemyAgent enemy = __instance.m_agent;
			if (!def.BossIDs.Contains(((GameDataBlockBase<EnemyDataBlock>)(object)enemy.EnemyData).persistentID) || (((int)spawnData.mode != 4 || !def.ApplyToHibernate) && ((int)spawnData.mode != 1 || !def.ApplyToWave)))
			{
				return;
			}
			BossDeathEventManager.Mode mode = (((int)spawnData.mode != 4) ? BossDeathEventManager.Mode.WAVE : BossDeathEventManager.Mode.HIBERNATE);
			BossDeathEventManager.Current.RegisterInLevelBDEventsExecution(def, mode);
			if (!BossDeathEventManager.Current.TryConsumeBDEventsExecutionTimes(def, mode))
			{
				EOSLogger.Debug($"EventsOnBossDeath: execution times depleted for {def.GlobalZoneIndexTuple()}, {mode}");
				return;
			}
			enemy.OnDeadCallback += Action.op_Implicit((Action)delegate
			{
				ushort globalID = ((Agent)enemy).GlobalID;
				if (ExecutedForInstances.Contains(globalID))
				{
					ExecutedForInstances.Remove(globalID);
				}
				else
				{
					def.EventsOnBossDeath.ForEach(delegate(WardenObjectiveEventData e)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
					});
					ExecutedForInstances.Add(globalID);
				}
			});
			EOSLogger.Debug($"EventsOnBossDeath: added for enemy with id  {((GameDataBlockBase<EnemyDataBlock>)(object)enemy.EnemyData).persistentID}, mode: {spawnData.mode}");
		}

		static Patch_EventsOnBossDeath()
		{
			ExecutedForInstances = new HashSet<ushort>();
			LevelAPI.OnLevelCleanup += ExecutedForInstances.Clear;
		}
	}
	[HarmonyPatch]
	internal class Patch_EventsOnZoneScoutScream
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")]
		private static bool Pre_ES_ScoutScream_CommonUpdate(ES_ScoutScream __instance)
		{
			//IL_0017: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0153: 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)
			AIG_CourseNode courseNode = ((Agent)((ES_Base)__instance).m_enemyAgent).CourseNode;
			EventsOnZoneScoutScream definition = ScoutScreamEventManager.Current.GetDefinition(courseNode.m_dimension.DimensionIndex, courseNode.LayerType, courseNode.m_zone.LocalIndex);
			if (definition == null)
			{
				return true;
			}
			if ((int)__instance.m_state != 3 || __instance.m_stateDoneTimer >= Clock.Time)
			{
				return true;
			}
			if (definition.EventsOnScoutScream != null && definition.EventsOnScoutScream.Count > 0)
			{
				EOSLogger.Debug($"EventsOnZoneScoutScream: found config for {definition.GlobalZoneIndexTuple()}, executing events.");
				definition.EventsOnScoutScream.ForEach(delegate(WardenObjectiveEventData e)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
				});
			}
			if (!definition.SuppressVanillaScoutWave)
			{
				if (SNet.IsMaster && ((Agent)((ES_Base)__instance).m_enemyAgent).CourseNode != null)
				{
					if (RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings != 0 && RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation != 0)
					{
						ushort num = default(ushort);
						Mastermind.Current.TriggerSurvivalWave(((Agent)((ES_Base)__instance).m_enemyAgent).CourseNode, RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings, RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation, ref num, (SurvivalWaveSpawnType)0, 0f, 2f, true, false, default(Vector3), "");
					}
					else
					{
						Debug.LogError(Object.op_Implicit("ES_ScoutScream, a scout is screaming but we can't spawn a wave because the the scout settings are not set for this expedition! ScoutWaveSettings: " + RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings + " ScoutWavePopulation: " + RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation));
					}
				}
			}
			else
			{
				EOSLogger.Debug("Vanilla scout wave suppressed.");
			}
			if (SNet.IsMaster)
			{
				((ES_Base)__instance).m_enemyAgent.AI.m_behaviour.ChangeState((EB_States)5);
			}
			((MachineState<ES_Base>)(object)__instance).m_machine.ChangeState(2);
			__instance.m_state = (ScoutScreamState)4;
			return false;
		}
	}
	[HarmonyPatch]
	internal class Patch_LG_ComputerTerminal_Setup
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_ComputerTerminal), "Setup")]
		private static void Post_LG_ComputerTerminal_Setup(LG_ComputerTerminal __instance)
		{
			//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_008e: 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_00c0: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			uint instanceIndex = TerminalInstanceManager.Current.Register(__instance);
			if (__instance.SpawnNode == null)
			{
				return;
			}
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(__instance);
			TerminalPosition definition = TerminalPositionOverrideManager.Current.GetDefinition(globalZoneIndex, instanceIndex);
			if (definition != null)
			{
				if (definition.Position.ToVector3() != Vector3.zeroVector)
				{
					((Component)__instance).transform.position = definition.Position.ToVector3();
					((Component)__instance).transform.rotation = definition.Rotation.ToQuaternion();
				}
				EOSLogger.Debug($"TerminalPositionOverride: {definition.LocalIndex}, {definition.LayerType}, {definition.DimensionIndex}, TerminalIndex {definition.InstanceIndex}");
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_LG_PowerGeneratorCluster
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_PowerGeneratorCluster), "Setup")]
		private static void Post_PowerGeneratorCluster_Setup(LG_PowerGeneratorCluster __instance)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			uint instanceIndex = GeneratorClusterInstanceManager.Current.Register(__instance);
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = GeneratorClusterInstanceManager.Current.GetGlobalZoneIndex(__instance);
			GeneratorClusterDefinition def = GeneratorClusterObjectiveManager.Current.GetDefinition(globalZoneIndex, instanceIndex);
			if (def == null)
			{
				return;
			}
			if ((int)WardenObjectiveManager.Current.m_activeWardenObjectives[__instance.SpawnNode.LayerType].Type == 9)
			{
				EOSLogger.Error("Found built Warden Objective LG_PowerGeneratorCluster but there's also a config for it! Won't apply this config");
				EOSLogger.Error($"{globalZoneIndex}");
				return;
			}
			EOSLogger.Debug("Found LG_PowerGeneratorCluster and its definition! Building this Generator cluster...");
			__instance.m_serialNumber = SerialGenerator.GetUniqueSerialNo();
			__instance.m_itemKey = "GENERATOR_CLUSTER_" + __instance.m_serialNumber;
			__instance.m_terminalItem = GOUtil.GetInterfaceFromComp<iTerminalItem>(__instance.m_terminalItemComp);
			__instance.m_terminalItem.Setup(__instance.m_itemKey, (AIG_CourseNode)null);
			__instance.m_terminalItem.FloorItemStatus = (eFloorInventoryObjectStatus)4;
			if (__instance.SpawnNode != null)
			{
				__instance.m_terminalItem.FloorItemLocation = __instance.SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7);
			}
			List<Transform> list = new List<Transform>((IEnumerable<Transform>)__instance.m_generatorAligns);
			uint numberOfGenerators = def.NumberOfGenerators;
			__instance.m_generators = Il2CppReferenceArray<LG_PowerGenerator_Core>.op_Implicit((LG_PowerGenerator_Core[])(object)new LG_PowerGenerator_Core[numberOfGenerators]);
			if (list.Count >= numberOfGenerators)
			{
				for (int i = 0; i < numberOfGenerators; i++)
				{
					int index = Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG");
					LG_PowerGenerator_Core val = GOUtil.SpawnChildAndGetComp<LG_PowerGenerator_Core>(__instance.m_generatorPrefab, list[index]);
					((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators)[i] = val;
					val.SpawnNode = __instance.SpawnNode;
					PowerGeneratorInstanceManager.Current.MarkAsGCGenerator(val);
					val.Setup();
					val.SetCanTakePowerCell(true);
					val.OnSyncStatusChanged += Action<ePowerGeneratorStatus>.op_Implicit((Action<ePowerGeneratorStatus>)delegate(ePowerGeneratorStatus status)
					{
						//IL_0021: Unknown result type (might be due to invalid IL or missing references)
						//IL_0041: Unknown result type (might be due to invalid IL or missing references)
						//IL_0046: Unknown result type (might be due to invalid IL or missing references)
						Debug.Log(Object.op_Implicit("LG_PowerGeneratorCluster.powerGenerator.OnSyncStatusChanged! status: " + ((object)(ePowerGeneratorStatus)(ref status)).ToString()));
						if ((int)status == 0)
						{
							uint num = 0u;
							for (int j = 0; j < ((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators).Length; j++)
							{
								if ((int)((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators)[j].m_stateReplicator.State.status == 0)
								{
									num++;
								}
							}
							EOSLogger.Log($"Generator Cluster PowerCell inserted ({num} / {((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators).Count})");
							List<List<WardenObjectiveEventData>> eventsOnInsertCell = def.EventsOnInsertCell;
							int num2 = (int)(num - 1);
							if (num2 >= 0 && num2 < eventsOnInsertCell.Count)
							{
								EOSLogger.Log($"Executing events ({num} / {((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators).Count}). Event count: {eventsOnInsertCell[num2].Count}");
								eventsOnInsertCell[num2].ForEach(delegate(WardenObjectiveEventData e)
								{
									WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
								});
							}
							if (num == ((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators).Count && !__instance.m_endSequenceTriggered)
							{
								EOSLogger.Log("All generators powered, executing end sequence");
								((MonoBehaviour)__instance).StartCoroutine(__instance.ObjectiveEndSequence());
								__instance.m_endSequenceTriggered = true;
							}
						}
					});
					Debug.Log(Object.op_Implicit("Spawning generator at alignIndex: " + index));
					list.RemoveAt(index);
				}
			}
			else
			{
				Debug.LogError(Object.op_Implicit("LG_PowerGeneratorCluster does NOT have enough generator aligns to support the warden objective! Has " + list.Count + " needs " + numberOfGenerators));
			}
			__instance.ObjectiveItemSolved = true;
			if (def.EndSequenceChainedPuzzle != 0)
			{
				GeneratorClusterObjectiveManager.Current.RegisterForChainedPuzzleBuild(__instance, def);
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_LG_PowerGenerator_Core
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_PowerGenerator_Core), "Setup")]
		private static void Post_PowerGenerator_Setup(LG_PowerGenerator_Core __instance)
		{
			//IL_0052: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (PowerGeneratorInstanceManager.Current.IsGCGenerator(__instance))
			{
				return;
			}
			uint num = PowerGeneratorInstanceManager.Current.Register(__instance);
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = PowerGeneratorInstanceManager.Current.GetGlobalZoneIndex(__instance);
			IndividualGeneratorDefinition def = IndividualGeneratorObjectiveManager.Current.GetDefinition(globalZoneIndex, num);
			if (def == null)
			{
				return;
			}
			Vector3 val = def.Position.ToVector3();
			Quaternion rotation = def.Rotation.ToQuaternion();
			if (val != Vector3.zero)
			{
				((Component)__instance).transform.position = val;
				((Component)__instance).transform.rotation = rotation;
				__instance.m_sound.UpdatePosition(val);
				EOSLogger.Debug("LG_PowerGenerator_Core: modified position / rotation");
			}
			if (def.ForceAllowPowerCellInsertion)
			{
				__instance.SetCanTakePowerCell(true);
			}
			List<WardenObjectiveEventData> eventsOnInsertCell = def.EventsOnInsertCell;
			if (eventsOnInsertCell != null && eventsOnInsertCell.Count > 0)
			{
				__instance.OnSyncStatusChanged += Action<ePowerGeneratorStatus>.op_Implicit((Action<ePowerGeneratorStatus>)delegate(ePowerGeneratorStatus status)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					if ((int)status == 0)
					{
						def.EventsOnInsertCell.ForEach(delegate(WardenObjectiveEventData e)
						{
							WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
						});
					}
				});
			}
			EOSLogger.Debug($"LG_PowerGenerator_Core: overriden, instance {num} in {globalZoneIndex}");
		}
	}
}
namespace ExtraObjectiveSetup.Patches.Uplink
{
	[HarmonyPatch]
	internal class CorruptedUplinkConfirm
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalCorruptedUplinkConfirm")]
		private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalCorruptedUplinkConfirm(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result)
		{
			LG_ComputerTerminal receiver = __instance.m_terminal;
			LG_ComputerTerminal sender = __instance.m_terminal.CorruptedUplinkReceiver;
			if ((Object)(object)sender == (Object)null)
			{
				EOSLogger.Error("TerminalCorruptedUplinkConfirm() critical failure because terminal does not have a CorruptedUplinkReceiver (sender).");
				__result = false;
				return false;
			}
			if (sender.m_isWardenObjective)
			{
				return true;
			}
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(sender);
			uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(sender);
			UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex);
			receiver.m_command.AddOutput((TerminalLineType)0, string.Format(Text.Get(2816126705u), sender.PublicName), 0f, (TerminalSoundType)0, (TerminalSoundType)0);
			if ((Object)(object)sender.ChainedPuzzleForWardenObjective != (Object)null)
			{
				ChainedPuzzleInstance chainedPuzzleForWardenObjective = sender.ChainedPuzzleForWardenObjective;
				chainedPuzzleForWardenObjective.OnPuzzleSolved += Action.op_Implicit((Action)delegate
				{
					receiver.m_command.StartTerminalUplinkSequence(string.Empty, true);
					UplinkObjectiveManager.Current.ChangeState(sender, new UplinkState
					{
						Status = UplinkStatus.InProgress,
						CurrentRoundIndex = 0
					});
				});
				sender.m_command.AddOutput("", true);
				sender.m_command.AddOutput(Text.Get(3268596368u), true);
				sender.m_command.AddOutput(Text.Get(2277987284u), true);
				receiver.m_command.AddOutput("", true);
				receiver.m_command.AddOutput(Text.Get(3268596368u), true);
				receiver.m_command.AddOutput(Text.Get(2277987284u), true);
				if (SNet.IsMaster)
				{
					sender.ChainedPuzzleForWardenObjective.AttemptInteract((eChainedPuzzleInteraction)0);
				}
			}
			else
			{
				receiver.m_command.StartTerminalUplinkSequence(string.Empty, true);
				UplinkObjectiveManager.Current.ChangeState(sender, new UplinkState
				{
					Status = UplinkStatus.InProgress,
					CurrentRoundIndex = 0
				});
			}
			__result = true;
			return false;
		}
	}
	[HarmonyPatch]
	internal class CorruptedUplinkConnect
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalCorruptedUplinkConnect")]
		private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalCorruptedUplinkConnect(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result)
		{
			//IL_01b4: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			LG_ComputerTerminal terminal = __instance.m_terminal;
			if (terminal.m_isWardenObjective)
			{
				return true;
			}
			__result = false;
			LG_ComputerTerminal corruptedUplinkReceiver = terminal.CorruptedUplinkReceiver;
			if ((Object)(object)corruptedUplinkReceiver == (Object)null)
			{
				EOSLogger.Error("TerminalCorruptedUplinkConnect() critical failure because terminal does not have a CorruptedUplinkReceiver.");
				return false;
			}
			if (LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != 0 && LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != terminal.SyncID)
			{
				__instance.AddOngoingUplinkOutput();
				__result = false;
				return false;
			}
			LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = terminal.SyncID;
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(terminal);
			uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(terminal);
			UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex);
			if (definition.UseUplinkAddress)
			{
				param1 = param1.ToUpper();
				EOSLogger.Debug("TerminalCorruptedUplinkConnect, param1: " + param1 + ", TerminalUplink: " + ((Object)terminal.UplinkPuzzle).ToString());
			}
			else
			{
				param1 = terminal.UplinkPuzzle.TerminalUplinkIP.ToUpper();
				EOSLogger.Debug("TerminalCorruptedUplinkConnect, not using uplink address, TerminalUplink: " + ((Object)terminal.UplinkPuzzle).ToString());
			}
			if (!definition.UseUplinkAddress || param1 == terminal.UplinkPuzzle.TerminalUplinkIP)
			{
				if (corruptedUplinkReceiver.m_command.HasRegisteredCommand((TERM_Command)27))
				{
					terminal.m_command.AddUplinkCorruptedOutput();
				}
				else
				{
					terminal.m_command.AddUplinkCorruptedOutput();
					terminal.m_command.AddOutput("", true);
					terminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(3492863045u), corruptedUplinkReceiver.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0);
					terminal.m_command.AddOutput((TerminalLineType)0, Text.Get(2761366063u), 0.6f, (TerminalSoundType)0, (TerminalSoundType)0);
					terminal.m_command.AddOutput("", true);
					terminal.m_command.AddOutput((TerminalLineType)0, Text.Get(3435969025u), 0.8f, (TerminalSoundType)0, (TerminalSoundType)0);
					corruptedUplinkReceiver.m_command.AddCommand((TERM_Command)27, "UPLINK_CONFIRM", new LocalizedText
					{
						UntranslatedText = Text.Get(112719254u),
						Id = 0u
					}, (TERM_CommandRule)2);
					corruptedUplinkReceiver.m_command.AddOutput((TerminalLineType)0, string.Format(Text.Get(1173595354u), terminal.PublicName), 0f, (TerminalSoundType)0, (TerminalSoundType)0);
				}
			}
			else
			{
				terminal.m_command.AddUplinkWrongAddressError(param1);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal class StartTerminalUplinkSequence
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "StartTerminalUplinkSequence")]
		private static bool Pre_LG_ComputerTerminalCommandInterpreter_StartTerminalUplinkSequence(LG_ComputerTerminalCommandInterpreter __instance, string uplinkIp, bool corrupted)
		{
			if (!corrupted)
			{
				LG_ComputerTerminal uplinkTerminal = __instance.m_terminal;
				if (uplinkTerminal.m_isWardenObjective)
				{
					return true;
				}
				(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(uplinkTerminal);
				uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(uplinkTerminal);
				UplinkDefinition uplinkConfig = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex);
				uplinkTerminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2583360288u), uplinkIp), 3f, (TerminalSoundType)0, (TerminalSoundType)0);
				__instance.TerminalUplinkSequenceOutputs(uplinkTerminal, false);
				uplinkTerminal.m_command.OnEndOfQueue = Action.op_Implicit((Action)delegate
				{
					EOSLogger.Debug("UPLINK CONNECTION DONE!");
					uplinkTerminal.UplinkPuzzle.Connected = true;
					uplinkTerminal.UplinkPuzzle.CurrentRound.ShowGui = true;
					uplinkTerminal.UplinkPuzzle.OnStartSequence();
					uplinkConfig.EventsOnCommence.ForEach(delegate(WardenObjectiveEventData e)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
					});
					int num2 = uplinkConfig.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == 0);
					((num2 != -1) ? uplinkConfig.RoundOverrides[num2] : null)?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f);
					});
				});
			}
			else
			{
				LG_ComputerTerminal terminal = __instance.m_terminal;
				LG_ComputerTerminal sender = __instance.m_terminal.CorruptedUplinkReceiver;
				if (sender.m_isWardenObjective)
				{
					return true;
				}
				(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex2 = TerminalInstanceManager.Current.GetGlobalZoneIndex(sender);
				uint zoneInstanceIndex2 = TerminalInstanceManager.Current.GetZoneInstanceIndex(sender);
				UplinkDefinition uplinkConfig2 = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex2, zoneInstanceIndex2);
				sender.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2056072887u), sender.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0);
				sender.m_command.AddOutput("", true);
				terminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2056072887u), sender.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0);
				terminal.m_command.AddOutput("", true);
				terminal.m_command.TerminalUplinkSequenceOutputs(sender, false);
				terminal.m_command.TerminalUplinkSequenceOutputs(terminal, true);
				terminal.m_command.OnEndOfQueue = Action.op_Implicit((Action)delegate
				{
					EOSLogger.Debug("UPLINK CONNECTION DONE!");
					sender.UplinkPuzzle.Connected = true;
					sender.UplinkPuzzle.CurrentRound.ShowGui = true;
					sender.UplinkPuzzle.OnStartSequence();
					uplinkConfig2.EventsOnCommence.ForEach(delegate(WardenObjectiveEventData e)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
					});
					int num = uplinkConfig2.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == 0);
					((num != -1) ? uplinkConfig2.RoundOverrides[num] : null)?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f);
					});
				});
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal class TerminalUplinkConnect
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkConnect")]
		private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkConnect(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result)
		{
			LG_ComputerTerminal terminal = __instance.m_terminal;
			if (terminal.m_isWardenObjective)
			{
				return true;
			}
			if (LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != 0 && LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != terminal.SyncID)
			{
				__instance.AddOngoingUplinkOutput();
				return false;
			}
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(__instance.m_terminal);
			uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(terminal);
			UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex);
			if (!definition.UseUplinkAddress)
			{
				param1 = __instance.m_terminal.UplinkPuzzle.TerminalUplinkIP;
			}
			if (!definition.UseUplinkAddress || param1 == __instance.m_terminal.UplinkPuzzle.TerminalUplinkIP)
			{
				__instance.m_terminal.TrySyncSetCommandRule((TERM_Command)25, (TERM_CommandRule)1);
				if ((Object)(object)__instance.m_terminal.ChainedPuzzleForWardenObjective != (Object)null)
				{
					ChainedPuzzleInstance chainedPuzzleForWardenObjective = __instance.m_terminal.ChainedPuzzleForWardenObjective;
					chainedPuzzleForWardenObjective.OnPuzzleSolved += Action.op_Implicit((Action)delegate
					{
						__instance.StartTerminalUplinkSequence(param1, false);
					});
					__instance.AddOutput("", true);
					__instance.AddOutput(Text.Get(3268596368u), true);
					__instance.AddOutput(Text.Get(3041541194u), true);
					if (SNet.IsMaster)
					{
						__instance.m_terminal.ChainedPuzzleForWardenObjective.AttemptInteract((eChainedPuzzleInteraction)0);
					}
				}
				else
				{
					__instance.StartTerminalUplinkSequence(param1, false);
				}
				__result = true;
			}
			else
			{
				__instance.AddUplinkWrongAddressError(param1);
				__result = false;
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal class TerminalUplinkSequenceOutput
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkSequenceOutputs")]
		private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkSequenceOutputs(LG_ComputerTerminal terminal, bool corrupted)
		{
			if (terminal.m_isWardenObjective)
			{
				return true;
			}
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(terminal);
			uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(terminal);
			UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex);
			if (definition == null)
			{
				if (!((Object)(object)terminal.CorruptedUplinkReceiver != (Object)null))
				{
					return true;
				}
				LG_ComputerTerminal corruptedUplinkReceiver = terminal.CorruptedUplinkReceiver;
				globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(corruptedUplinkReceiver);
				zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(corruptedUplinkReceiver);
				definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex);
				if (definition == null || definition.DisplayUplinkWarning)
				{
					return true;
				}
			}
			terminal.m_command.AddOutput((TerminalLineType)3, Text.Get(3418104670u), 3f, (TerminalSoundType)0, (TerminalSoundType)0);
			terminal.m_command.AddOutput("", true);
			if (!corrupted)
			{
				terminal.m_command.AddOutput(string.Format(Text.Get(947485599u), terminal.UplinkPuzzle.CurrentRound.CorrectPrefix), true);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal class TerminalUplinkVerify
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkVerify")]
		private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkVerify(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result)
		{
			if (__instance.m_terminal.m_isWardenObjective)
			{
				return true;
			}
			TerminalUplinkPuzzle uplinkPuzzle = __instance.m_terminal.UplinkPuzzle;
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(__instance.m_terminal);
			uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(__instance.m_terminal);
			UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex);
			int CurrentRoundIndex = uplinkPuzzle.m_roundIndex;
			int num = definition.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == CurrentRoundIndex);
			UplinkRound roundOverride = ((num != -1) ? definition.RoundOverrides[num] : null);
			TimeSettings timeSettings = ((num != -1) ? roundOverride.OverrideTimeSettings : definition.DefaultTimeSettings);
			float num2 = ((timeSettings.TimeToStartVerify >= 0f) ? timeSettings.TimeToStartVerify : definition.DefaultTimeSettings.TimeToStartVerify);
			float timeToCompleteVerify = ((timeSettings.TimeToCompleteVerify >= 0f) ? timeSettings.TimeToCompleteVerify : definition.DefaultTimeSettings.TimeToCompleteVerify);
			float num3 = ((timeSettings.TimeToRestoreFromFail >= 0f) ? timeSettings.TimeToRestoreFromFail : definition.DefaultTimeSettings.TimeToRestoreFromFail);
			if (uplinkPuzzle.Connected)
			{
				__instance.AddOutput((TerminalLineType)3, Text.Get(2734004688u), num2, (TerminalSoundType)0, (TerminalSoundType)0);
				if (!uplinkPuzzle.Solved && uplinkPuzzle.CurrentRound.CorrectCode.ToUpper() == param1.ToUpper())
				{
					__instance.AddOutput(string.Format(Text.Get(1221800228u), uplinkPuzzle.CurrentProgress), true);
					if (uplinkPuzzle.TryGoToNextRound())
					{
						int newRoundIndex = uplinkPuzzle.m_roundIndex;
						int num4 = definition.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == newRoundIndex);
						UplinkRound newRoundOverride = ((num4 != -1) ? definition.RoundOverrides[num4] : null);
						roundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e)
						{
							WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)2, false, 0f);
						});
						if (roundOverride != null && (Object)(object)roundOverride.ChainedPuzzleToEndRoundInstance != (Object)null)
						{
							TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.UplinkTerminal.ScanRequiredToProgress");
							if (block != null)
							{
								__instance.AddOutput((TerminalLineType)4, Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID), 0f, (TerminalSoundType)0, (TerminalSoundType)0);
							}
							ChainedPuzzleInstance chainedPuzzleToEndRoundInstance = roundOverride.ChainedPuzzleToEndRoundInstance;
							chainedPuzzleToEndRoundInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate
							{
								__instance.AddOutput((TerminalLineType)4, Text.Get(27959760u), timeToCompleteVerify, (TerminalSoundType)0, (TerminalSoundType)0);
								__instance.AddOutput("", true);
								__instance.AddOutput(string.Format(Text.Get(4269617288u), uplinkPuzzle.CurrentProgress, uplinkPuzzle.CurrentRound.CorrectPrefix), true);
								__instance.OnEndOfQueue = Action.op_Implicit((Action)delegate
								{
									EOSLogger.Log("UPLINK VERIFICATION GO TO NEXT ROUND!");
									uplinkPuzzle.CurrentRound.ShowGui = true;
									newRoundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e)
									{
										WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f);
									});
									UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState
									{
										Status = UplinkStatus.InProgress,
										CurrentRoundIndex = uplinkPuzzle.m_roundIndex
									});
								});
							});
							if (SNet.IsMaster)
							{
								roundOverride.ChainedPuzzleToEndRoundInstance.AttemptInteract((eChainedPuzzleInteraction)0);
							}
						}
						else
						{
							__instance.AddOutput((TerminalLineType)4, Text.Get(27959760u), timeToCompleteVerify, (TerminalSoundType)0, (TerminalSoundType)0);
							__instance.AddOutput("", true);
							__instance.AddOutput(string.Format(Text.Get(4269617288u), uplinkPuzzle.CurrentProgress, uplinkPuzzle.CurrentRound.CorrectPrefix), true);
							__instance.OnEndOfQueue = Action.op_Implicit((Action)delegate
							{
								EOSLogger.Log("UPLINK VERIFICATION GO TO NEXT ROUND!");
								uplinkPuzzle.CurrentRound.ShowGui = true;
								newRoundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e)
								{
									WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f);
								});
								UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState
								{
									Status = UplinkStatus.InProgress,
									CurrentRoundIndex = uplinkPuzzle.m_roundIndex
								});
							});
						}
					}
					else
					{
						__instance.AddOutput((TerminalLineType)3, Text.Get(1780488547u), 3f, (TerminalSoundType)0, (TerminalSoundType)0);
						__instance.AddOutput("", true);
						__instance.OnEndOfQueue = Action.op_Implicit((Action)delegate
						{
							roundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e)
							{
								WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)2, false, 0f);
							});
							uplinkPuzzle.CurrentRound.ShowGui = false;
							if (roundOverride != null && (Object)(object)roundOverride.ChainedPuzzleToEndRoundInstance != (Object)null)
							{
								ChainedPuzzleInstance chainedPuzzleToEndRoundInstance2 = roundOverride.ChainedPuzzleToEndRoundInstance;
								chainedPuzzleToEndRoundInstance2.OnPuzzleSolved += Action.op_Implicit((Action)delegate
								{
									__instance.AddOutput((TerminalLineType)0, string.Format(Text.Get(3928683780u), uplinkPuzzle.TerminalUplinkIP), 2f, (TerminalSoundType)0, (TerminalSoundType)0);
									__instance.AddOutput("", true);
									__instance.OnEndOfQueue = Action.op_Implicit((Action)delegate
									{
										EOSLogger.Error("UPLINK VERIFICATION SEQUENCE DONE!");
										LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = 0u;
										uplinkPuzzle.Solved = true;
										Action onPuzzleSolved2 = uplinkPuzzle.OnPuzzleSolved;
										if (onPuzzleSolved2 != null)
										{
											onPuzzleSolved2.Invoke();
										}
										UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState
										{
											Status = UplinkStatus.Finished,
											CurrentRoundIndex = uplinkPuzzle.m_roundIndex
										});
									});
								});
								if (SNet.IsMaster)
								{
									roundOverride.ChainedPuzzleToEndRoundInstance.AttemptInteract((eChainedPuzzleInteraction)0);
								}
							}
							else
							{
								__instance.AddOutput((TerminalLineType)0, string.Format(Text.Get(3928683780u), uplinkPuzzle.TerminalUplinkIP), 2f, (TerminalSoundType)0, (TerminalSoundType)0);
								__instance.AddOutput("", true);
								EOSLogger.Error("UPLINK VERIFICATION SEQUENCE DONE!");
								LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = 0u;
								uplinkPuzzle.Solved = true;
								Action onPuzzleSolved = uplinkPuzzle.OnPuzzleSolved;
								if (onPuzzleSolved != null)
								{
									onPuzzleSolved.Invoke();
								}
								UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState
								{
									Status = UplinkStatus.Finished,
									CurrentRoundIndex = uplinkPuzzle.m_roundIndex
								});
							}
						});
					}
				}
				else if (uplinkPuzzle.Solved)
				{
					__instance.AddOutput("", true);
					__instance.AddOutput((TerminalLineType)1, Text.Get(4080876165u), 0f, (TerminalSoundType)0, (TerminalSoundType)0);
					__instance.AddOutput((TerminalLineType)0, Text.Get(4104839742u), 6f, (TerminalSoundType)0, (TerminalSoundType)0);
				}
				else
				{
					__instance.AddOutput("", true);
					__instance.AddOutput((TerminalLineType)1, string.Format(Text.Get(507647514u), uplinkPuzzle.CurrentRound.CorrectPrefix), 0f, (TerminalSoundType)0, (TerminalSoundType)0);
					__instance.AddOutput((TerminalLineType)0, Text.Get(4104839742u), num3, (TerminalSoundType)0, (TerminalSoundType)0);
				}
			}
			else
			{
				__instance.AddOutput("", true);
				__instance.AddOutput(Text.Get(403360908u), true);
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch]
	internal class UplinkGUI_Update
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_ComputerTerminal), "Update")]
		private static void Post_LG_ComputerTerminal_Update(LG_ComputerTerminal __instance)
		{
			if (!__instance.m_isWardenObjective && __instance.UplinkPuzzle != null)
			{
				__instance.UplinkPuzzle.UpdateGUI(false);
			}
		}
	}
}
namespace ExtraObjectiveSetup.Patches.LGFactory
{
	[HarmonyPatch]
	internal class Patch_LG_Factory_NextBatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_Factory), "NextBatch")]
		private static void Post_LG_Factory_NextBatch(LG_Factory __instance)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			int num = __instance.m_batchStep - 1;
			if (num >= 0)
			{
				BatchName batchName = ((Il2CppArrayBase<LG_FactoryBatch>)(object)__instance.m_batches)[num].m_batchName;
				Action action = BatchBuildManager.Current.Get_OnBatchDone(batchName);
				if (action != null)
				{
					EOSLogger.Warning($"On Batch '{batchName}' Done: {action.GetInvocationList().Length} injected jobs");
					action();
				}
			}
		}
	}
}
namespace ExtraObjectiveSetup.Patches.HSUActivator
{
	[HarmonyPatch]
	internal class SetupFromCustomGeomorph
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_HSUActivator_Core), "SetupFromCustomGeomorph")]
		private static void Post_LG_HSUActivator_Core_SetupFromCustomGeomorph(LG_HSUActivator_Core __instance)
		{
			//IL_0034: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			uint instanceIndex = HSUActivatorInstanceManager.Current.Register(__instance);
			HSUActivatorDefinition def = HSUActivatorObjectiveManager.Current.GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, instanceIndex);
			if (def == null)
			{
				return;
			}
			if (__instance.m_isWardenObjective)
			{
				EOSLogger.Error("BuildCustomHSUActivator: the HSUActivator has been set up by vanilla! Aborting custom setup...");
				EOSLogger.Error($"HSUActivator in {__instance.SpawnNode.m_zone.LocalIndex}, {__instance.SpawnNode.LayerType}, {__instance.SpawnNode.m_dimension.DimensionIndex}");
				return;
			}
			__instance.m_linkedItemGoingIn = __instance.SpawnPickupItemOnAlign(def.ItemFromStart, __instance.m_itemGoingInAlign, false, -1);
			__instance.m_linkedItemComingOut = __instance.SpawnPickupItemOnAlign(def.ItemAfterActivation, __instance.m_itemComingOutAlign, false, -1);
			LG_LevelInteractionManager.DeregisterTerminalItem(((Component)__instance.m_linkedItemGoingIn).GetComponentInChildren<iTerminalItem>());
			LG_LevelInteractionManager.DeregisterTerminalItem(((Component)__instance.m_linkedItemComingOut).GetComponentInChildren<iTerminalItem>());
			__instance.m_linkedItemGoingIn.SetPickupInteractionEnabled(false);
			__instance.m_linkedItemComingOut.SetPickupInteractionEnabled(false);
			__instance.m_insertHSUInteraction.OnInteractionSelected = Action<PlayerAgent>.op_Implicit((Action<PlayerAgent>)delegate
			{
			});
			__instance.m_sequencerInsertItem.OnSequenceDone = Action.op_Implicit((Action)delegate
			{
				//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_0011: 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)
				pHSUActivatorState state2 = __instance.m_stateReplicator.State;
				if (!state2.isSequenceIncomplete)
				{
					EOSLogger.Error(">>>>>> HSUInsertSequenceDone! Sequence was already complete");
				}
				state2.isSequenceIncomplete = false;
				__instance.m_stateReplicator.SetStateUnsynced(state2);
				EOSLogger.Error(">>>>>> HSUInsertSequenceDone!");
				if (__instance.m_triggerExtractSequenceRoutine != null)
				{
					((MonoBehaviour)__instance).StopCoroutine(__instance.m_triggerExtractSequenceRoutine);
				}
				ChainedPuzzleInstance chainedPuzzleOnActivationInstance = def.ChainedPuzzleOnActivationInstance;
				if ((Object)(object)chainedPuzzleOnActivationInstance == (Object)null)
				{
					if (def.TakeOutItemAfterActivation)
					{
						__instance.m_triggerExtractSequenceRoutine = ((MonoBehaviour)__instance).StartCoroutine(__instance.TriggerRemoveSequence());
					}
				}
				else
				{
					chainedPuzzleOnActivationInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate
					{
						if (def.TakeOutItemAfterActivation)
						{
							__instance.m_triggerExtractSequenceRoutine = ((MonoBehaviour)__instance).StartCoroutine(__instance.TriggerRemoveSequence());
						}
						def.EventsOnActivationScanSolved.ForEach(delegate(WardenObjectiveEventData e)
						{
							WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
						});
					});
					if (SNet.IsMaster)
					{
						chainedPuzzleOnActivationInstance.AttemptInteract((eChainedPuzzleInteraction)0);
					}
				}
			});
			__instance.m_sequencerExtractItem.OnSequenceDone = Action.op_Implicit((Action)delegate
			{
				//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_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				SNet_StateReplicator<pHSUActivatorState, pHSUActivatorInteraction> stateReplicator = __instance.m_stateReplicator;
				pHSUActivatorState state = __instance.m_stateReplicator.State;
				state.isSequenceIncomplete = true;
				stateReplicator.SetStateUnsynced(state);
				if (SNet.IsMaster)
				{
					__instance.AttemptInteract(new pHSUActivatorInteraction
					{
						type = (eHSUActivatorInteractionType)2
					});
				}
			});
			EOSLogger.Debug($"HSUActivator: {(def.DimensionIndex, def.LayerType, def.LocalIndex, def.InstanceIndex)}, custom setup complete");
		}
	}
	[HarmonyPatch]
	internal class SyncStatusChanged
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_HSUActivator_Core), "SyncStatusChanged")]
		private static bool Pre_LG_HSUActivator_Core_SyncStatusChanged(LG_HSUActivator_Core __instance, ref pHSUActivatorState newState, bool isRecall)
		{
			//IL_0060: 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_007b: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected I4, but got Unknown
			if (__instance.m_isWardenObjective)
			{
				return true;
			}
			uint zoneInstanceIndex = HSUActivatorInstanceManager.Current.GetZoneInstanceIndex(__instance);
			if (zoneInstanceIndex == uint.MaxValue)
			{
				EOSLogger.Error($"Found unregistered HSUActivator!! {HSUActivatorInstanceManager.Current.GetGlobalZoneIndex(__instance)}");
				return true;
			}
			HSUActivatorDefinition definition = HSUActivatorObjectiveManager.Current.GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, zoneInstanceIndex);
			if (definition == null)
			{
				return true;
			}
			if (__instance.m_triggerExtractSequenceRoutine != null)
			{
				((MonoBehaviour)__instance).StopCoroutine(__instance.m_triggerExtractSequenceRoutine);
			}
			bool goingInVisibleForPostCulling = __instance.m_goingInVisibleForPostCulling;
			bool comingOutVisibleForPostCulling = __instance.m_comingOutVisibleForPostCulling;
			EOSLogger.Debug("LG_HSUActivator_Core.OnSyncStatusChanged " + ((object)(eHSUActivatorStatus)(ref newState.status)).ToString());
			eHSUActivatorStatus status = newState.status;
			switch ((int)status)
			{
			case 0:
				__instance.m_insertHSUInteraction.SetActive(true);
				__instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, false, false, true, ref goingInVisibleForPostCulling);
				__instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, false, false, true, ref comingOutVisibleForPostCulling);
				__instance.m_sequencerWaitingForItem.StartSequence();
				__instance.m_sequencerInsertItem.StopSequence();
				__instance.m_sequencerExtractItem.StopSequence();
				__instance.m_sequencerExtractionDone.StopSequence();
				break;
			case 1:
				__instance.m_insertHSUInteraction.SetActive(false);
				__instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, true, false, true, ref goingInVisibleForPostCulling);
				__instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, false, false, true, ref comingOutVisibleForPostCulling);
				__instance.m_sequencerWaitingForItem.StopSequence();
				__instance.m_sequencerInsertItem.StartSequence();
				__instance.m_sequencerExtractItem.StopSequence();
				__instance.m_sequencerExtractionDone.StopSequence();
				definition?.EventsOnHSUActivation.ForEach(delegate(WardenObjectiveEventData e)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
				});
				break;
			case 2:
				__instance.m_insertHSUInteraction.SetActive(false);
				__instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, !__instance.m_showItemComingOut, false, true, ref goingInVisibleForPostCulling);
				__instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, __instance.m_showItemComingOut, false, true, ref comingOutVisibleForPostCulling);
				__instance.m_sequencerWaitingForItem.StopSequence();
				__instance.m_sequencerInsertItem.StopSequence();
				__instance.m_sequencerExtractItem.StartSequence();
				__instance.m_sequencerExtractionDone.StopSequence();
				break;
			case 3:
				__instance.m_insertHSUInteraction.SetActive(false);
				__instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, !__instance.m_showItemComingOut, false, true, ref goingInVisibleForPostCulling);
				__instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, __instance.m_showItemComingOut, definition.TakeOutItemAfterActivation, false, ref comingOutVisibleForPostCulling);
				__instance.m_sequencerWaitingForItem.StopSequence();
				__instance.m_sequencerInsertItem.StopSequence();
				__instance.m_sequencerExtractItem.StopSequence();
				__instance.m_sequencerExtractionDone.StartSequence();
				if (newState.isSequenceIncomplete)
				{
					__instance.HSUInsertSequenceDone();
				}
				break;
			}
			return false;
		}
	}
}
namespace ExtraObjectiveSetup.Patches.Expedition
{
	[HarmonyPatch]
	internal class GearManager_LoadOfflineGearDatas
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(GearManager), "LoadOfflineGearDatas")]
		private static void Post_GearManager_LoadOfflineGearDatas(GearManager __instance)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected I4, but got Unknown
			ExpeditionGearManager.Current.vanillaGearManager = __instance;
			foreach (var gearSlot in ExpeditionGearManager.Current.gearSlots)
			{
				Enumerator<GearIDRange> enumerator2 = ((Il2CppArrayBase<List<GearIDRange>>)(object)__instance.m_gearPerSlot)[(int)gearSlot.inventorySlot].GetEnumerator();
				while (enumerator2.MoveNext())
				{
					GearIDRange current2 = enumerator2.Current;
					uint offlineGearPID = ExpeditionGearManager.GetOfflineGearPID(current2);
					gearSlot.loadedGears.Add(offlineGearPID, current2);
				}
			}
		}
	}
	[HarmonyPatch]
	internal class RundownManager_SetActiveExpedition
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(RundownManager), "SetActiveExpedition")]
		private static void Post_RundownManager_SetActiveExpedition(RundownManager __instance, pActiveExpedition expPackage, ExpeditionInTierData expTierData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)expPackage.tier != 99)
			{
				ExpeditionGearManager.Current.SetupAllowedGearsForActiveExpedition();
			}
		}
	}
}
namespace ExtraObjectiveSetup.Instances
{
	public sealed class HSUActivatorInstanceManager : InstanceManager<LG_HSUActivator_Core>
	{
		public static HSUActivatorInstanceManager Current { get; private set; }

		public override (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GetGlobalZoneIndex(LG_HSUActivator_Core 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);
		}

		private HSUActivatorInstanceManager()
		{
		}

		static HSUActivatorInstanceManager()
		{
			Current = new HSUActivatorInstanceManager();
		}
	}
	public sealed class GeneratorClusterInstanceManager : InstanceManager<LG_PowerGeneratorCluster>
	{
		public static GeneratorClusterInstanceManager Current { get; private set; }

		public override (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GetGlobalZoneIndex(LG_PowerGeneratorCluster 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);
		}

		static GeneratorClusterInstanceManager()
		{
			Current = new GeneratorClusterInstanceManager();
		}
	}
	public sealed class PowerGeneratorInstanceManager : InstanceManager<LG_PowerGenerator_Core>
	{
		private HashSet<IntPtr> gcGenerators = new HashSet<IntPtr>();

		public static PowerGeneratorInstanceManager Current { get; private set; }

		public override (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GetGlobalZoneIndex(LG_PowerGenerator_Core 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 override uint Register((eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex, LG_PowerGenerator_Core instance)
		{
			if (gcGenerators.Contains(((Il2CppObjectBase)instance).Pointer))
			{
				EOSLogger.Error("PowerGeneratorInstanceManager: Trying to register a GC Generator, which is an invalid operation");
				return uint.MaxValue;
			}
			return base.Register(globalZoneIndex, instance);
		}

		public void MarkAsGCGenerator(LG_PowerGenerator_Core instance)
		{
			if (IsRegistered(instance))
			{
				EOSLogger.Error("PowerGeneratorInstanceManager: Trying to mark a registered Generator as GC Generator, which is an invalid operation");
			}
			else
			{
				gcGenerators.Add(((Il2CppObjectBase)instance).Pointer);
			}
		}

		public bool IsGCGenerator(LG_PowerGenerator_Core instance)
		{
			return gcGenerators.Contains(((Il2CppObjectBase)instance).Pointer);
		}

		private void OutputLevelInstanceInfo()
		{
			//IL_0038: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine();
			foreach (var item in RegisteredZones())
			{
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder3 = stringBuilder2;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(8, 3, stringBuilder2);
				handler.AppendFormatted<eLocalZoneIndex>(item.zone);
				handler.AppendLiteral(", ");
				handler.AppendFormatted<LG_LayerType>(item.layer);
				handler.AppendLiteral(", Dim ");
				handler.AppendFormatted<eDimensionIndex>(item.dim);
				stringBuilder3.AppendLine(ref handler);
				List<LG_PowerGenerator_Core> instancesInZone = GetInstancesInZone(item);
				for (int i = 0; i < instancesInZone.Count; i++)
				{
					LG_PowerGenerator_Core val = instancesInZone[i];
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder4 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(28, 2, stringBuilder2);
					handler.AppendLiteral("GENERATOR_");
					handler.AppendFormatted(val.m_serialNumber);
					handler.AppendLiteral(". Instance index: ");
					handler.AppendFormatted(i);
					stringBuilder4.AppendLine(ref handler);
				}
				stringBuilder.AppendLine();
			}
			if (!string.IsNullOrWhiteSpace(stringBuilder.ToString()))
			{
				EOSLogger.Debug(stringBuilder.ToString());
			}
		}

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

		private PowerGeneratorInstanceManager()
		{
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
			LevelAPI.OnEnterLevel += OutputLevelInstanceInfo;
		}

		static PowerGeneratorInstanceManager()
		{
			Current = new PowerGeneratorInstanceManager();
		}
	}
	public sealed class TerminalInstanceManager : InstanceManager<LG_ComputerTerminal>
	{
		public static TerminalInstanceManager Current { get; private set; }

		public override (eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex zone) GetGlobalZoneIndex(LG_ComputerTerminal instance)
		{
			//IL_001e: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			if (instance.SpawnNode == null)
			{
				throw new ArgumentException("LG_ComputerTerminal.SpawnNode == null! This is a reactor terminal.");
			}
			return (instance.SpawnNode.m_dimension.DimensionIndex, instance.SpawnNode.LayerType, instance.SpawnNode.m_zone.LocalIndex);
		}

		public override uint Register(LG_ComputerTerminal instance)
		{
			if (instance.SpawnNode == null)
			{
				EOSLogger.Error("Trying to register reactor terminal. Use TerminalInstanceManager.RegisterReactorTerminal instead.");
				return uint.MaxValue;
			}
			return Register(GetGlobalZoneIndex(instance), instance);
		}

		public uint RegisterReactorTerminal(LG_WardenObjective_Reactor reactor)
		{
			//IL_0026: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)reactor.m_terminal == (Object)null)
			{
				EOSLogger.Error("RegisterReactorTerminal: reactor has no terminal");
				return uint.MaxValue;
			}
			uint num = Register((reactor.SpawnNode.m_dimension.DimensionIndex, reactor.SpawnNode.LayerType, reactor.SpawnNode.m_zone.LocalIndex), reactor.m_terminal);
			EOSLogger.Debug($"Registered reactor terminal, {reactor.PublicName} - {reactor.m_terminal.PublicName}, instance index: {num}");
			return num;
		}

		private void Clear()
		{
		}

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

		static TerminalInstanceManager()
		{
			Current = new TerminalInstanceManager();
		}
	}
}
namespace ExtraObjectiveSetup.Objectives.TerminalUplink
{
	public enum UplinkTerminal
	{
		SENDER,
		RECEIVER
	}
	public class Terminal
	{
		public eDimensionIndex DimensionIndex { get; set; }

		public LG_LayerType LayerType { get; set; }

		public eLocalZoneIndex LocalIndex { get; set; }

		public uint InstanceIndex { get; set; } = uint.MaxValue;

	}
	public class UplinkRound
	{
		public int RoundIndex { get; set; } = -1;


		public uint ChainedPuzzleToEndRound { get; set; }

		public UplinkTerminal BuildChainedPuzzleOn { get; set; }

		[JsonIgnore]
		public ChainedPuzzleInstance ChainedPuzzleToEndRoundInstance { get; set; }

		public TimeSettings OverrideTimeSettings { get; set; } = new TimeSettings
		{
			TimeToStartVerify = -1f,
			TimeToCompleteVerify = -1f,
			TimeToRestoreFromFail = -1f
		};


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

	}
	public class TimeSettings
	{
		public float TimeToStartVerify { get; set; } = 5f;


		public float TimeToCompleteVerify { get; set; } = 6f;


		public float TimeToRestoreFromFail { get; set; } = 6f;

	}
	public class UplinkDefinition : BaseInstanceDefinition
	{
		public bool DisplayUplinkWarning { get; set; } = true;


		public bool SetupAsCorruptedUplink { get; set; }

		public Terminal CorruptedUplinkReceiver { get; set; } = new Terminal();


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


		public Terminal UplinkAddressLogPosition { get; set; } = new Terminal();


		public uint ChainedPuzzleToStartUplink { get; set; }

		public uint NumberOfVerificationRounds { get; set; } = 1u;


		public TimeSettings DefaultTimeSettings { get; set; } = new TimeSettings();


		public List<UplinkRound> RoundOverrides { get; set; } = new List<UplinkRound>
		{
			new UplinkRound()
		};


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


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

	}
	internal sealed class UplinkObjectiveManager : InstanceDefinitionManager<UplinkDefinition>
	{
		private TextDataBlock UplinkAddrLogContentBlock;

		private Dictionary<IntPtr, StateReplicator<UplinkState>> stateReplicators = new Dictionary<IntPtr, StateReplicator<UplinkState>>();

		private List<UplinkRound> builtRoundPuzzles = new List<UplinkRound>();

		public static UplinkObjectiveManager Current { get; private set; }

		protected override string DEFINITION_NAME { get; } = "TerminalUplink";


		protected override void AddDefinitions(InstanceDefinitionsForLevel<UplinkDefinition> definitions)
		{
			Sort(definitions);
			definitions.Definitions.ForEach(delegate(UplinkDefinition u)
			{
				u.RoundOverrides.Sort(delegate(UplinkRound r1, UplinkRound r2)
				{
					if (r1.RoundIndex == r2.RoundIndex)
					{
						return 0;
					}
					return (r1.RoundIndex >= r2.RoundIndex) ? 1 : (-1);
				});
			});
			base.AddDefinitions(definitions);
		}

		private void Build(UplinkDefinition def)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0089: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_01b0: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			//IL_0203: 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_0223: 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_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Expected O, but got Unknown
			//IL_02ed: Expected O, but got Unknown
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0568: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			LG_ComputerTerminal instance = TerminalInstanceManager.Current.GetInstance(def.DimensionIndex, def.LayerType, def.LocalIndex, def.InstanceIndex);
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (instance.m_isWardenObjective && instance.UplinkPuzzle != null)
			{
				EOSLogger.Error("BuildUplink: terminal uplink already built (by vanilla or custom build), aborting!");
				return;
			}
			if (def.SetupAsCorruptedUplink)
			{
				LG_ComputerTerminal instance2 = TerminalInstanceManager.Current.GetInstance(def.CorruptedUplinkReceiver.DimensionIndex, def.CorruptedUplinkReceiver.LayerType, def.CorruptedUplinkReceiver.LocalIndex, def.CorruptedUplinkReceiver.InstanceIndex);
				if ((Object)(object)instance2 == (Object)null)
				{
					EOSLogger.Error("BuildUplink: SetupAsCorruptedUplink specified but didn't find the receiver terminal, will fall back to normal uplink instead");
					return;
				}
				if (((Il2CppObjectBase)instance2).Pointer == ((Il2CppObjectBase)instance).Pointer)
				{
					EOSLogger.Error("BuildUplink: Don't specify uplink sender and receiver on the same terminal");
					return;
				}
				instance.CorruptedUplinkReceiver = instance2;
				instance2.CorruptedUplinkReceiver = instance;
			}
			instance.UplinkPuzzle = new TerminalUplinkPuzzle();
			SetupUplinkPuzzle(instance.UplinkPuzzle, instance, def);
			TerminalUplinkPuzzle uplinkPuzzle = instance.UplinkPuzzle;
			uplinkPuzzle.OnPuzzleSolved += Action.op_Implicit((Action)delegate
			{
				def.EventsOnComplete?.ForEach(delegate(WardenObjectiveEventData e)
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f);
				});
			});
			instance.m_command.AddCommand((TERM_Command)(((Object)(object)instance.CorruptedUplinkReceiver == (Object)null) ? 25 : 33), def.UseUplinkAddress ? "UPLINK_CONNECT" : "UPLINK_ESTABLISH", new LocalizedText
			{
				UntranslatedText = Text.Get(3914968919u),
				Id = 3914968919u
			}, (TERM_CommandRule)0);
			instance.m_command.AddCommand((TERM_Command)26, "UPLINK_VERIFY", new LocalizedText
			{
				UntranslatedText = Text.Get(1728022075u),
				Id = 1728022075u
			}, (TERM_CommandRule)0);
			if (def.UseUplinkAddress)
			{
				LG_ComputerTerminal val = null;
				EOSLogger.Debug("BuildUplinkOverride: UseUplinkAddress");
				val = TerminalInstanceManager.Current.GetInstance(def.UplinkAddressLogPosition.DimensionIndex, def.UplinkAddressLogPosition.LayerType, def.UplinkAddressLogPosition.LocalIndex, def.UplinkAddressLogPosition.InstanceIndex);
				if ((Object)(object)val == (Object)null)
				{
					EOSLogger.Error("BuildUplinkOverride: didn't find the terminal to put the uplink address log, will put on uplink terminal");
					val = instance;
				}
				val.AddLocalLog(new TerminalLogFileData
				{
					FileName = $"UPLINK_ADDR_{instance.m_serialNumber}.LOG",
					FileContent = new LocalizedText
					{
						UntranslatedText = string.Format((UplinkAddrLogContentBlock != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)UplinkAddrLogContentBlock).persistentID) : "Available uplink address for TERMINAL_{0}: {1}", instance.m_serialNumber, instance.UplinkPuzzle.TerminalUplinkIP),
						Id = 0u
					}
				}, true);
				val.m_command.ClearOutputQueueAndScreenBuffer();
				val.m_command.AddInitialTerminalOutput();
			}
			if (def.ChainedPuzzleToStartUplink != 0)
			{
				ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(def.ChainedPuzzleToStartUplink);
				if (block == null)
				{
					EOSLogger.Error($"BuildTerminalUplink: ChainedPuzzleToActive with id {def.ChainedPuzzleToStartUplink} is specified but no ChainedPuzzleDataBlock definition is found... Won't build");
					instance.m_chainPuzzleForWardenObjective = null;
				}
				else
				{
					instance.m_chainPuzzleForWardenObjective = ChainedPuzzleManager.CreatePuzzleInstance(block, instance.SpawnNode.m_area, instance.m_wardenObjectiveSecurityScanAlign.position, instance.m_wardenObjectiveSecurityScanAlign);
				}
			}
			foreach (UplinkRound roundOverride in def.RoundOverrides)
			{
				if (roundOverride.ChainedPuzzleToEndRound == 0)
				{
					continue;
				}
				ChainedPuzzleDataBlock block2 = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(roundOverride.ChainedPuzzleToEndRound);
				if (block2 != null)
				{
					LG_ComputerTerminal val2 = null;
					switch (roundOverride.BuildChainedPuzzleOn)
					{
					case UplinkTerminal.SENDER:
						val2 = instance;
						break;
					case UplinkTerminal.RECEIVER:
						if (def.SetupAsCorruptedUplink && (Object)(object)instance.CorruptedUplinkReceiver != (Object)null)
						{
							val2 = instance.CorruptedUplinkReceiver;
							break;
						}
						EOSLogger.Error($"ChainedPuzzleToEndRound: {roundOverride.ChainedPuzzleToEndRound} specified to build on receiver but this is not a properly setup-ed corr-uplink! Will build ChainedPuzzle on sender side");
						val2 = instance;
						break;
					default:
						EOSLogger.Error($"Unimplemented enum UplinkTerminal type {roundOverride.BuildChainedPuzzleOn}");
						continue;
					}
					roundOverride.ChainedPuzzleToEndRoundInstance = ChainedPuzzleManager.CreatePuzzleInstance(block2, val2.SpawnNode.m_area, val2.m_wardenObjectiveSecurityScanAlign.position, val2.m_wardenObjectiveSecurityScanAlign);
					builtRoundPuzzles.Add(roundOverride);
				}
				else
				{
					EOSLogger.Error($"ChainedPuzzleToEndRound: {roundOverride.ChainedPuzzleToEndRound} specified but didn't find its ChainedPuzzleDatablock definition! Will not build!");
				}
			}
			SetupUplinkReplicator(instance);
			EOSLogger.Debug($"BuildUplink: built on {(def.DimensionIndex, def.LayerType, def.LocalIndex, def.InstanceIndex)}");
		}

		private void SetupUplinkPuzzle(TerminalUplinkPuzzle uplinkPuzzle, LG_ComputerTerminal terminal, UplinkDefinition def)
		{
			//IL_0030: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			uplinkPuzzle.m_rounds = ListExtensions.ToIl2Cpp<TerminalUplinkPuzzleRound>(new List<TerminalUplinkPuzzleRound>());
			uplinkPuzzle.TerminalUplinkIP = SerialGenerator.GetIpAddress();
			uplinkPuzzle.m_roundIndex = 0;
			uplinkPuzzle.m_lastRoundIndexToUpdateGui = -1;
			uplinkPuzzle.m_position = ((Comp

plugins/net6/Inas07.ExtraSurvivalWaveSettings.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
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.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using GTFO.API;
using GameData;
using HarmonyLib;
using Il2CppSystem;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;

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

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

		public const string PLUGIN_NAME = "ExtraSurvivalWaveSettings";

		public const string VERSION = "1.1.1";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			m_Harmony = new Harmony("ExtraSurvivalWaveSettings");
			m_Harmony.PatchAll();
		}
	}
	public class SurvivalWaveManager
	{
		public static readonly SurvivalWaveManager Current;

		private ConcurrentDictionary<string, List<ushort>> WaveEventsMap = new ConcurrentDictionary<string, List<ushort>>();

		public void SpawnWave(WardenObjectiveEventData e)
		{
			//IL_006c: 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_0073: 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_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Invalid comparison between Unknown and I4
			//IL_02ae: 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_00b4: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Invalid comparison between Unknown and I4
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: 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_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Invalid comparison between Unknown and I4
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Invalid comparison between Unknown and I4
			//IL_00e8: 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_00f1: Invalid comparison between Unknown and I4
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Invalid comparison between Unknown and I4
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Invalid comparison between Unknown and I4
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Invalid comparison between Unknown and I4
			//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_013f: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster)
			{
				return;
			}
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			if ((Object)(object)localPlayerAgent == (Object)null)
			{
				ESWSLogger.Error("SpawnWave: LocalPlayerAgent is null, wtf?");
				return;
			}
			GenericEnemyWaveData enemyWaveData = e.EnemyWaveData;
			if (enemyWaveData.WaveSettings == 0 || enemyWaveData.WavePopulation == 0)
			{
				ESWSLogger.Error("SpawnWave: WaveSettings or WavePopulation is 0");
				return;
			}
			SurvivalWaveSettingsDataBlock block = GameDataBlockBase<SurvivalWaveSettingsDataBlock>.GetBlock(enemyWaveData.WaveSettings);
			SurvivalWavePopulationDataBlock block2 = GameDataBlockBase<SurvivalWavePopulationDataBlock>.GetBlock(enemyWaveData.WavePopulation);
			if (block == null || block2 == null)
			{
				return;
			}
			AIG_CourseNode val = ((Agent)localPlayerAgent).CourseNode;
			SurvivalWaveSpawnType val2 = (SurvivalWaveSpawnType)0;
			Vector3 val3 = Vector3.zero;
			if (block.m_overrideWaveSpawnType)
			{
				LG_Zone val4 = default(LG_Zone);
				if ((int)block.m_survivalWaveSpawnType != 1 && (int)block.m_survivalWaveSpawnType != 2 && (int)block.m_survivalWaveSpawnType != 3)
				{
					val2 = block.m_survivalWaveSpawnType;
				}
				else if (Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val4) && (Object)(object)val4 != (Object)null)
				{
					val = val4.m_courseNodes[0];
					val2 = (SurvivalWaveSpawnType)1;
					if ((int)block.m_survivalWaveSpawnType == 2 || (int)block.m_survivalWaveSpawnType == 3)
					{
						if (e.Count < val4.m_courseNodes.Count)
						{
							val = val4.m_courseNodes[e.Count];
							val2 = (SurvivalWaveSpawnType)2;
							if ((int)block.m_survivalWaveSpawnType == 3)
							{
								val3 = e.Position;
								val2 = (SurvivalWaveSpawnType)3;
							}
						}
						else
						{
							ESWSLogger.Error($"SpawnWave: SpawnType InSuppliedCourseNode(_OnPosition) is specified but cannot find AREA_{(ushort)(65 + e.Count)} in ({e.DimensionIndex}, {e.Layer}, {e.LocalIndex}), falling back to SpawnType: InSuppliedCourseNodeZone");
						}
					}
				}
				else
				{
					ESWSLogger.Error($"SpawnWave: Failed to find zone with GlobalIndex ({e.DimensionIndex}, {e.Layer}, {e.LocalIndex}), falling back to default spawn type");
				}
			}
			Mastermind current = Mastermind.Current;
			AIG_CourseNode obj = val;
			uint waveSettings = enemyWaveData.WaveSettings;
			uint wavePopulation = enemyWaveData.WavePopulation;
			SurvivalWaveSpawnType val5 = val2;
			float spawnDelay = enemyWaveData.SpawnDelay;
			Vector3 val6 = val3;
			ushort num = default(ushort);
			if (!current.TriggerSurvivalWave(obj, waveSettings, wavePopulation, ref num, val5, spawnDelay, (float)enemyWaveData.AreaDistance, val6, true, false, default(Vector3), ""))
			{
				ESWSLogger.Error("SpawnWave: Critical ERROR! Failed spawning enemy wave");
				return;
			}
			WardenObjectiveManager.RegisterSurvivalWaveID(num);
			ESWSLogger.Log($"SpawnWave: Enemy wave spawned ({val2}) with eventID {num}");
			if (enemyWaveData.TriggerAlarm)
			{
				WardenObjectiveManager.Current.m_sound.UpdatePosition(val.Position);
				WardenObjectiveManager.Current.m_sound.Post(EVENTS.APEX_PUZZLE_START_ALARM, true);
				ESWSLogger.Debug("SpawnWave: Trigger Alarm (prolly bugged when there're multiple alarms)");
			}
			if (!string.IsNullOrEmpty(LocalizedText.op_Implicit(enemyWaveData.IntelMessage)))
			{
				GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", LocalizedText.op_Implicit(enemyWaveData.IntelMessage), false, 200f, 8f, (Action)null);
			}
			if ((int)val2 == 1)
			{
				ESWSLogger.Log($"Spawning in: ({e.DimensionIndex}, {e.Layer}, {e.LocalIndex})");
			}
			else if ((int)val2 == 2)
			{
				ESWSLogger.Log($"Spawning in: ({e.DimensionIndex}, {e.Layer}, {e.LocalIndex}, AREA_{(ushort)(65 + e.Count)})");
			}
			string worldEventObjectFilter = e.WorldEventObjectFilter;
			if (!string.IsNullOrEmpty(worldEventObjectFilter))
			{
				if (!WaveEventsMap.ContainsKey(worldEventObjectFilter))
				{
					WaveEventsMap[worldEventObjectFilter] = new List<ushort>();
				}
				WaveEventsMap[worldEventObjectFilter].Add(num);
				ESWSLogger.Debug($"SpawnWave: Registered wave with filter {worldEventObjectFilter}, number of waves assigned: {WaveEventsMap[worldEventObjectFilter].Count}");
			}
		}

		public void StopNamedWaves(string waveName)
		{
			if (string.IsNullOrEmpty(waveName))
			{
				return;
			}
			if (!WaveEventsMap.Remove(waveName, out var value))
			{
				ESWSLogger.Error("Wave Filter " + waveName + " is unregistered, cannot stop wave.");
				return;
			}
			ESWSLogger.Debug($"StopNamedWaves: Stopping waves with name {waveName}, wave count: {value.Count}");
			value.ForEach(delegate(ushort eventID)
			{
				MastermindEvent val = default(MastermindEvent);
				if (Mastermind.Current.TryGetEvent(eventID, ref val))
				{
					val.StopEvent();
				}
				else
				{
					ESWSLogger.Error($"Wave with ID {eventID}: cannot find event. Are you debugging a level?");
				}
			});
		}

		internal void OnStopAllWave()
		{
			WaveEventsMap.Clear();
		}

		public void Clear()
		{
			WaveEventsMap.Clear();
		}

		private SurvivalWaveManager()
		{
		}

		static SurvivalWaveManager()
		{
			Current = new SurvivalWaveManager();
			LevelAPI.OnLevelCleanup += Current.Clear;
		}
	}
	internal static class ESWSLogger
	{
		private static ManualLogSource logger = Logger.CreateLogSource("ExtraSurvivalWaveSettings");

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

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

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

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

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

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

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

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)32, (object)str);
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_CheckAndExecuteEventsOnTrigger
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(WardenObjectiveManager), "CheckAndExecuteEventsOnTrigger", new Type[]
		{
			typeof(WardenObjectiveEventData),
			typeof(eWardenObjectiveEventTrigger),
			typeof(bool),
			typeof(float)
		})]
		private static bool Pre_CheckAndExecuteEventsOnTrigger(WardenObjectiveEventData eventToTrigger, eWardenObjectiveEventTrigger trigger, bool ignoreTrigger, float currentDuration)
		{
			//IL_0007: 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_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_0030: 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_0035: Invalid comparison between Unknown and I4
			if (eventToTrigger == null || (!ignoreTrigger && eventToTrigger.Trigger != trigger) || ((double)currentDuration != 0.0 && eventToTrigger.Delay <= currentDuration))
			{
				return true;
			}
			bool flag = false;
			eWardenObjectiveEventType type = eventToTrigger.Type;
			if (type - 9 <= 1)
			{
				flag = true;
				Coroutine val = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Handle(eventToTrigger, 0f)), (Action)null);
				WorldEventManager.m_worldEventEventCoroutines.Add(val);
			}
			return !flag;
		}

		internal static IEnumerator Handle(WardenObjectiveEventData e, float currentDuration)
		{
			float num = Mathf.Max(e.Delay - currentDuration, 0f);
			if (num > 0f)
			{
				yield return (object)new WaitForSeconds(num);
			}
			if (e.Condition.ConditionIndex >= 0 && WorldEventManager.GetCondition(e.Condition.ConditionIndex) != e.Condition.IsTrue)
			{
				yield break;
			}
			WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel);
			if (e.DialogueID != 0)
			{
				PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false);
			}
			if (e.SoundID != 0)
			{
				WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true);
				string text = ((Object)e.SoundSubtitle).ToString();
				if (!string.IsNullOrWhiteSpace(text))
				{
					GuiManager.PlayerLayer.ShowMultiLineSubtitle(text);
				}
			}
			eWardenObjectiveEventType type = e.Type;
			if ((int)type != 9)
			{
				if ((int)type == 10)
				{
					if (string.IsNullOrEmpty(e.WorldEventObjectFilter))
					{
						WardenObjectiveManager.StopAlarms();
						WardenObjectiveManager.StopAllWardenObjectiveEnemyWaves();
						WardenObjectiveManager.Current.m_sound.Post(EVENTS.ALARM_AMBIENT_STOP, true);
						SurvivalWaveManager.Current.OnStopAllWave();
					}
					else
					{
						SurvivalWaveManager.Current.StopNamedWaves(e.WorldEventObjectFilter);
					}
				}
			}
			else
			{
				SurvivalWaveManager.Current.SpawnWave(e);
			}
		}
	}
}

plugins/net6/Inas07.FixEndScreen.dll

Decompiled 4 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Microsoft.CodeAnalysis;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FixEndScreen
{
	[BepInPlugin("Inas.FixEndScreen", "FixEndScreen", "1.0.0")]
	public class EntryPoint : BasePlugin
	{
		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			m_Harmony = new Harmony("FixEndScreen");
			m_Harmony.PatchAll();
		}
	}
}
namespace FixEndScreen.Patches
{
	[HarmonyPatch]
	internal class Patch_DiscordManager
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(DiscordManager), "UpdateDiscordDetails")]
		private static bool Pre_UpdateDiscordDetails()
		{
			return false;
		}
	}
}

plugins/net6/Inas07.LocalProgression.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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.Logging;
using BepInEx.Unity.IL2CPP;
using BoosterImplants;
using CellMenu;
using DropServer;
using GTFO.API;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LocalProgression.Data;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LocalProgression
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.LocalProgression", "LocalProgression", "1.1.10")]
	public class EntryPoint : BasePlugin
	{
		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			m_Harmony = new Harmony("LocalProgression");
			m_Harmony.PatchAll();
			EventAPI.OnManagersSetup += LocalProgressionManager.Current.Init;
		}
	}
	public class LocalProgressionManager
	{
		public static readonly LocalProgressionManager Current;

		public static readonly string DirPath;

		private CM_PageRundown_New rundownPage;

		private RundownProgressionData CurrentRundownProgressionData { get; } = new RundownProgressionData();


		internal RundownProgData nativeProgData { get; private set; }

		private static string RundownLocalProgressionFilePath(string rundownName)
		{
			char[] invalidPathChars = Path.GetInvalidPathChars();
			foreach (char oldChar in invalidPathChars)
			{
				rundownName = rundownName.Replace(oldChar, '_');
			}
			return Path.Combine(DirPath, rundownName);
		}

		private static Dictionary<string, ExpeditionProgressionData> ReadRundownLocalProgressionData(string rundownName)
		{
			string path = RundownLocalProgressionFilePath(rundownName);
			Dictionary<string, ExpeditionProgressionData> dictionary = new Dictionary<string, ExpeditionProgressionData>();
			if (File.Exists(path))
			{
				using FileStream input = File.Open(path, FileMode.Open);
				using BinaryReader binaryReader = new BinaryReader(input, Encoding.UTF8, leaveOpen: false);
				int num = 0;
				num = binaryReader.ReadInt32();
				for (int i = 0; i < num; i++)
				{
					ExpeditionProgressionData expeditionProgressionData = new ExpeditionProgressionData();
					expeditionProgressionData.ExpeditionKey = binaryReader.ReadString();
					expeditionProgressionData.MainCompletionCount = binaryReader.ReadInt32();
					expeditionProgressionData.SecondaryCompletionCount = binaryReader.ReadInt32();
					expeditionProgressionData.ThirdCompletionCount = binaryReader.ReadInt32();
					expeditionProgressionData.AllClearCount = binaryReader.ReadInt32();
					dictionary.Add(expeditionProgressionData.ExpeditionKey, expeditionProgressionData);
				}
			}
			return dictionary;
		}

		internal RundownProgressionData GetLocalProgressionDataForCurrentRundown()
		{
			return CurrentRundownProgressionData;
		}

		private void SaveRundownProgressionDataToDisk()
		{
			string text = RundownLocalProgressionFilePath(CurrentRundownProgressionData.RundownName);
			LPLogger.Warning("SaveData: saving to " + text);
			using FileStream output = File.Open(text, FileMode.Create);
			using BinaryWriter binaryWriter = new BinaryWriter(output, Encoding.UTF8, leaveOpen: false);
			Dictionary<string, ExpeditionProgressionData> localProgressionDict = CurrentRundownProgressionData.LocalProgressionDict;
			binaryWriter.Write(localProgressionDict.Count);
			foreach (string key in CurrentRundownProgressionData.LocalProgressionDict.Keys)
			{
				ExpeditionProgressionData expeditionProgressionData = localProgressionDict[key];
				binaryWriter.Write(key);
				binaryWriter.Write(expeditionProgressionData.MainCompletionCount);
				binaryWriter.Write(expeditionProgressionData.SecondaryCompletionCount);
				binaryWriter.Write(expeditionProgressionData.ThirdCompletionCount);
				binaryWriter.Write(expeditionProgressionData.AllClearCount);
			}
		}

		public void RecordExpeditionSuccessForCurrentRundown(string expeditionKey, bool mainLayerCleared, bool secondaryLayerCleared, bool thirdLayerCleared)
		{
			if (RundownManager.ActiveExpedition.ExcludeFromProgression)
			{
				return;
			}
			bool flag = mainLayerCleared && secondaryLayerCleared && thirdLayerCleared;
			Dictionary<string, ExpeditionProgressionData> localProgressionDict = CurrentRundownProgressionData.LocalProgressionDict;
			if (!localProgressionDict.ContainsKey(expeditionKey))
			{
				localProgressionDict[expeditionKey] = new ExpeditionProgressionData
				{
					ExpeditionKey = expeditionKey,
					MainCompletionCount = (mainLayerCleared ? 1 : 0),
					SecondaryCompletionCount = (secondaryLayerCleared ? 1 : 0),
					ThirdCompletionCount = (thirdLayerCleared ? 1 : 0),
					AllClearCount = (flag ? 1 : 0)
				};
				CurrentRundownProgressionData.MainClearCount += (mainLayerCleared ? 1 : 0);
				CurrentRundownProgressionData.SecondaryClearCount += (secondaryLayerCleared ? 1 : 0);
				CurrentRundownProgressionData.ThirdClearCount += (thirdLayerCleared ? 1 : 0);
				CurrentRundownProgressionData.AllClearCount += (flag ? 1 : 0);
			}
			else
			{
				ExpeditionProgressionData expeditionProgressionData = localProgressionDict[expeditionKey];
				if (expeditionProgressionData.MainCompletionCount == 0 && mainLayerCleared)
				{
					CurrentRundownProgressionData.MainClearCount++;
				}
				if (expeditionProgressionData.SecondaryCompletionCount == 0 && secondaryLayerCleared)
				{
					CurrentRundownProgressionData.SecondaryClearCount++;
				}
				if (expeditionProgressionData.ThirdCompletionCount == 0 && thirdLayerCleared)
				{
					CurrentRundownProgressionData.ThirdClearCount++;
				}
				if (expeditionProgressionData.AllClearCount == 0 && flag)
				{
					CurrentRundownProgressionData.AllClearCount++;
				}
				expeditionProgressionData.MainCompletionCount += (mainLayerCleared ? 1 : 0);
				expeditionProgressionData.SecondaryCompletionCount += (secondaryLayerCleared ? 1 : 0);
				expeditionProgressionData.ThirdCompletionCount += (thirdLayerCleared ? 1 : 0);
				expeditionProgressionData.AllClearCount += (flag ? 1 : 0);
			}
			SaveRundownProgressionDataToDisk();
		}

		public void UpdateLocalProgressionDataToActiveRundown()
		{
			string activeRundownKey = RundownManager.ActiveRundownKey;
			uint num = default(uint);
			if (!RundownManager.TryGetIdFromLocalRundownKey(activeRundownKey, ref num) || num == 0)
			{
				LPLogger.Debug("OnRundownProgressionUpdated: cannot find rundown with rundown key `" + activeRundownKey + "`!");
				return;
			}
			LPLogger.Warning($"Update LPData to rundown_id: {num}");
			CurrentRundownProgressionData.Reset();
			RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(num);
			if (block == null)
			{
				LPLogger.Error($"Didn't find Rundown Datablock with rundown id {num}");
				return;
			}
			Dictionary<string, ExpeditionProgressionData> dictionary = ReadRundownLocalProgressionData(((GameDataBlockBase<RundownDataBlock>)(object)block).name);
			CurrentRundownProgressionData.RundownID = num;
			CurrentRundownProgressionData.RundownName = ((GameDataBlockBase<RundownDataBlock>)(object)block).name;
			CurrentRundownProgressionData.LocalProgressionDict = dictionary;
			foreach (ExpeditionProgressionData value in dictionary.Values)
			{
				CurrentRundownProgressionData.MainClearCount += ((value.MainCompletionCount > 0) ? 1 : 0);
				CurrentRundownProgressionData.SecondaryClearCount += ((value.SecondaryCompletionCount > 0) ? 1 : 0);
				CurrentRundownProgressionData.ThirdClearCount += ((value.ThirdCompletionCount > 0) ? 1 : 0);
				CurrentRundownProgressionData.AllClearCount += ((value.AllClearCount > 0) ? 1 : 0);
			}
		}

		internal void Init()
		{
			if (!Directory.Exists(DirPath))
			{
				Directory.CreateDirectory(DirPath);
			}
			RundownManager.OnRundownProgressionUpdated += Action.op_Implicit((Action)OnNativeRundownProgressionUpdated);
		}

		internal void OnNativeRundownProgressionUpdated()
		{
			UpdateLocalProgressionDataToActiveRundown();
			if (!((Object)(object)rundownPage == (Object)null) && ((CM_PageBase)rundownPage).m_isActive)
			{
				UpdateRundownPageExpeditionIconProgression();
			}
		}

		internal void SetCurrentRundownPageInstance(CM_PageRundown_New __instance)
		{
			rundownPage = __instance;
		}

		private void UpdateRundownPageExpeditionIconProgression()
		{
			//IL_0066: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00e8: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: 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_0235: 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_02bf: 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_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rundownPage == (Object)null)
			{
				return;
			}
			uint rundownID = CurrentRundownProgressionData.RundownID;
			if (rundownID == 0)
			{
				LPLogger.Warning("UpdateRundownPageExpeditionIconProgression: rundown_id == 0!");
				return;
			}
			RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(rundownID);
			LPLogger.Log($"CM_PageRundown_New.UpdateRundownExpeditionProgression, overwrite with LocalProgression Data, RundownID {CurrentRundownProgressionData.RundownID}");
			nativeProgData = ComputeLocalProgressionDataToRundownProgData();
			if ((Object)(object)rundownPage.m_tierMarker1 != (Object)null)
			{
				rundownPage.m_tierMarker1.SetProgression(nativeProgData, new RundownTierProgressionData());
				if (rundownPage.m_expIconsTier1 != null)
				{
					UpdateTierIconsWithProgression(rundownPage.m_expIconsTier1, rundownPage.m_tierMarker1, thisTierUnlocked: true);
				}
			}
			if ((Object)(object)rundownPage.m_tierMarker2 != (Object)null)
			{
				rundownPage.m_tierMarker2.SetProgression(nativeProgData, block.ReqToReachTierB);
				if (rundownPage.m_expIconsTier2 != null)
				{
					UpdateTierIconsWithProgression(rundownPage.m_expIconsTier2, rundownPage.m_tierMarker2, nativeProgData.tierBUnlocked && block.UseTierUnlockRequirements);
				}
			}
			if ((Object)(object)rundownPage.m_tierMarker3 != (Object)null)
			{
				rundownPage.m_tierMarker3.SetProgression(nativeProgData, block.ReqToReachTierC);
				if (rundownPage.m_expIconsTier3 != null)
				{
					UpdateTierIconsWithProgression(rundownPage.m_expIconsTier3, rundownPage.m_tierMarker3, nativeProgData.tierCUnlocked && block.UseTierUnlockRequirements);
				}
			}
			if ((Object)(object)rundownPage.m_tierMarker4 != (Object)null)
			{
				rundownPage.m_tierMarker4.SetProgression(nativeProgData, block.ReqToReachTierD);
				if (rundownPage.m_expIconsTier4 != null)
				{
					UpdateTierIconsWithProgression(rundownPage.m_expIconsTier4, rundownPage.m_tierMarker4, nativeProgData.tierDUnlocked && block.UseTierUnlockRequirements);
				}
			}
			if ((Object)(object)rundownPage.m_tierMarker5 != (Object)null)
			{
				rundownPage.m_tierMarker5.SetProgression(nativeProgData, block.ReqToReachTierE);
				if (rundownPage.m_expIconsTier5 != null)
				{
					UpdateTierIconsWithProgression(rundownPage.m_expIconsTier5, rundownPage.m_tierMarker5, nativeProgData.tierEUnlocked && block.UseTierUnlockRequirements);
				}
			}
			if ((Object)(object)rundownPage.m_tierMarkerSectorSummary != (Object)null)
			{
				rundownPage.m_tierMarkerSectorSummary.SetSectorIconTextForMain($"<color=orange>[{nativeProgData.clearedMain}/{nativeProgData.totalMain}]</color>", "#FFFFFFCC");
				rundownPage.m_tierMarkerSectorSummary.SetSectorIconTextForSecondary($"<color=orange>[{nativeProgData.clearedSecondary}/{nativeProgData.totalSecondary}]</color>", "#CCCCCCCC");
				rundownPage.m_tierMarkerSectorSummary.SetSectorIconTextForThird($"<color=orange>[{nativeProgData.clearedThird}/{nativeProgData.totalThird}]</color>", "#CCCCCCCC");
				rundownPage.m_tierMarkerSectorSummary.SetSectorIconTextForAllCleared($"<color=orange>[{nativeProgData.clearedAllClear}/{nativeProgData.totalAllClear}]</color>", "#CCCCCCCC");
			}
		}

		private void UpdateTierIconsWithProgression(List<CM_ExpeditionIcon_New> tierIcons, CM_RundownTierMarker tierMarker, bool thisTierUnlocked)
		{
			//IL_0031: 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)
			if (tierIcons == null || tierIcons.Count == 0)
			{
				if (tierMarker != null)
				{
					tierMarker.SetVisible(false, 0f);
				}
				return;
			}
			for (int i = 0; i < tierIcons.Count; i++)
			{
				CM_ExpeditionIcon_New val = tierIcons[i];
				string rundownProgressionExpeditionKey = RundownManager.GetRundownProgressionExpeditionKey(tierIcons[i].Tier, tierIcons[i].ExpIndex);
				ExpeditionProgressionData value;
				bool flag = CurrentRundownProgressionData.LocalProgressionDict.TryGetValue(rundownProgressionExpeditionKey, out value);
				string text = "0";
				string text2 = (RundownManager.HasSecondaryLayer(tierIcons[i].DataBlock) ? "0" : "-");
				string text3 = (RundownManager.HasThirdLayer(tierIcons[i].DataBlock) ? "0" : "-");
				string text4 = (RundownManager.HasAllCompletetionPossibility(tierIcons[i].DataBlock) ? "0" : "-");
				if (flag)
				{
					if (value.MainCompletionCount > 0)
					{
						text = value.MainCompletionCount.ToString();
					}
					if (value.SecondaryCompletionCount > 0)
					{
						text2 = value.SecondaryCompletionCount.ToString();
					}
					if (value.ThirdCompletionCount > 0)
					{
						text3 = value.ThirdCompletionCount.ToString();
					}
					if (value.AllClearCount > 0)
					{
						text4 = value.AllClearCount.ToString();
					}
				}
				if (CheckExpeditionUnlocked(val.DataBlock, val.Tier))
				{
					if (flag)
					{
						rundownPage.SetIconStatus(val, (eExpeditionIconStatus)4, text, text2, text3, text4, 1f, false, (eExpeditionAccessibility)0);
					}
					else
					{
						rundownPage.SetIconStatus(val, (eExpeditionIconStatus)2, "-", "-", "-", "-", 1f, false, (eExpeditionAccessibility)0);
					}
				}
				else if (flag)
				{
					rundownPage.SetIconStatus(val, (eExpeditionIconStatus)1, text, text2, text3, text4, 1f, false, (eExpeditionAccessibility)0);
				}
				else if (val.DataBlock.HideOnLocked)
				{
					((RectTransformComp)val).SetVisible(false);
				}
				else
				{
					rundownPage.SetIconStatus(val, (eExpeditionIconStatus)0, "-", "-", "-", "-", 1f, false, (eExpeditionAccessibility)0);
				}
			}
			if (thisTierUnlocked)
			{
				if (tierMarker != null)
				{
					tierMarker.SetStatus((eRundownTierMarkerStatus)1);
				}
			}
			else if (tierMarker != null)
			{
				tierMarker.SetStatus((eRundownTierMarkerStatus)0);
			}
		}

		private RundownProgData ComputeLocalProgressionDataToRundownProgData()
		{
			//IL_0002: 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_00e5: 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)
			RundownProgData progressionData = default(RundownProgData);
			if (CurrentRundownProgressionData.RundownID == 0)
			{
				LPLogger.Error("ComputeLocalProgressionDataToRundownProgData: rundown_id == 0...");
				return progressionData;
			}
			RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(CurrentRundownProgressionData.RundownID);
			if (block == null)
			{
				LPLogger.Error($"ComputeLocalProgressionDataToRundownProgData: cannot get rundown datablock with rundown_id: {CurrentRundownProgressionData.RundownID}");
				return progressionData;
			}
			progressionData.clearedMain = CurrentRundownProgressionData.MainClearCount;
			progressionData.clearedSecondary = CurrentRundownProgressionData.SecondaryClearCount;
			progressionData.clearedThird = CurrentRundownProgressionData.ThirdClearCount;
			progressionData.clearedAllClear = CurrentRundownProgressionData.AllClearCount;
			AccumulateTierClearance(block, (eRundownTier)1, ref progressionData);
			AccumulateTierClearance(block, (eRundownTier)2, ref progressionData);
			AccumulateTierClearance(block, (eRundownTier)3, ref progressionData);
			AccumulateTierClearance(block, (eRundownTier)4, ref progressionData);
			AccumulateTierClearance(block, (eRundownTier)5, ref progressionData);
			return progressionData;
		}

		private void AccumulateTierClearance(RundownDataBlock rundownDB, eRundownTier tier, ref RundownProgData progressionData)
		{
			//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_0023: Expected I4, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			List<ExpeditionInTierData> val = rundownDB.TierA;
			switch (tier - 1)
			{
			case 1:
				val = rundownDB.TierB;
				break;
			case 2:
				val = rundownDB.TierC;
				break;
			case 3:
				val = rundownDB.TierD;
				break;
			case 4:
				val = rundownDB.TierE;
				break;
			default:
				LPLogger.Error($"Unsupported eRundownTier {tier}");
				return;
			case 0:
				break;
			}
			int num = 0;
			Enumerator<ExpeditionInTierData> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ExpeditionInTierData current = enumerator.Current;
				if (current.Enabled && (!current.HideOnLocked || CheckExpeditionUnlocked(current, tier)))
				{
					progressionData.totalMain++;
					if (RundownManager.HasSecondaryLayer(current))
					{
						progressionData.totalSecondary++;
					}
					if (RundownManager.HasThirdLayer(current))
					{
						progressionData.totalThird++;
					}
					if (RundownManager.HasAllCompletetionPossibility(current))
					{
						progressionData.totalAllClear++;
					}
					if (current.Descriptive.IsExtraExpedition)
					{
						progressionData.totatlExtra++;
					}
					string uniqueExpeditionKey = RundownManager.GetUniqueExpeditionKey(rundownDB, tier, num);
					if (CurrentRundownProgressionData.LocalProgressionDict.ContainsKey(uniqueExpeditionKey))
					{
						progressionData.clearedExtra++;
					}
					num++;
				}
			}
		}

		private bool CheckTierUnlocked(eRundownTier tier)
		{
			//IL_0013: 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_002f: Expected I4, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(CurrentRundownProgressionData.RundownID);
			RundownTierProgressionData val = null;
			switch (tier - 1)
			{
			case 0:
				return true;
			case 1:
				val = block.ReqToReachTierB;
				break;
			case 2:
				val = block.ReqToReachTierC;
				break;
			case 3:
				val = block.ReqToReachTierD;
				break;
			case 4:
				val = block.ReqToReachTierE;
				break;
			default:
				LPLogger.Error("Unsupporrted tier: {0}", tier);
				return true;
			}
			if (CurrentRundownProgressionData.MainClearCount >= val.MainSectors && CurrentRundownProgressionData.SecondaryClearCount >= val.SecondarySectors && CurrentRundownProgressionData.ThirdClearCount >= val.ThirdSectors)
			{
				return CurrentRundownProgressionData.AllClearCount >= val.AllClearedSectors;
			}
			return false;
		}

		private bool CheckExpeditionUnlocked(ExpeditionInTierData expedition, eRundownTier tier)
		{
			//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_0025: Expected I4, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected I4, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			eExpeditionAccessibility accessibility = expedition.Accessibility;
			switch ((int)accessibility)
			{
			case 1:
			case 3:
				return false;
			case 2:
				return true;
			case 0:
				return CheckTierUnlocked(tier);
			case 4:
			{
				RundownTierProgressionData customProgressionLock = expedition.CustomProgressionLock;
				if (CurrentRundownProgressionData.MainClearCount >= customProgressionLock.MainSectors && CurrentRundownProgressionData.SecondaryClearCount >= customProgressionLock.SecondarySectors && CurrentRundownProgressionData.ThirdClearCount >= customProgressionLock.ThirdSectors)
				{
					return CurrentRundownProgressionData.AllClearCount >= customProgressionLock.AllClearedSectors;
				}
				return false;
			}
			case 5:
			{
				ExpeditionIndex unlockedByExpedition = expedition.UnlockedByExpedition;
				string rundownProgressionExpeditionKey = RundownManager.GetRundownProgressionExpeditionKey(unlockedByExpedition.Tier, (int)unlockedByExpedition.Exp);
				return CurrentRundownProgressionData.LocalProgressionDict.ContainsKey(rundownProgressionExpeditionKey);
			}
			default:
				LPLogger.Warning("Unsupported eExpeditionAccessibility: {0}", expedition.Accessibility);
				return true;
			}
		}

		private void SetNativeRundownProgression()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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_0173: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, Expedition> expeditions = RundownManager.RundownProgression.Expeditions;
			if (expeditions.Count > 0)
			{
				LPLogger.Warning($"Non-empty native rundown progression data! RundownID: {CurrentRundownProgressionData.RundownID}");
				expeditions.Clear();
			}
			Dictionary<string, ExpeditionProgressionData> localProgressionDict = CurrentRundownProgressionData.LocalProgressionDict;
			Layer val2 = default(Layer);
			Layer val3 = default(Layer);
			Layer val4 = default(Layer);
			foreach (string key in localProgressionDict.Keys)
			{
				Expedition val = new Expedition();
				ExpeditionProgressionData expeditionProgressionData = localProgressionDict[key];
				val.AllLayerCompletionCount = expeditionProgressionData.AllClearCount;
				val.Layers = new LayerSet<Layer>();
				val2.CompletionCount = expeditionProgressionData.MainCompletionCount;
				val2.State = (LayerProgressionState)((expeditionProgressionData.MainCompletionCount > 0) ? 3 : 0);
				val3.CompletionCount = expeditionProgressionData.SecondaryCompletionCount;
				val3.State = (LayerProgressionState)((expeditionProgressionData.SecondaryCompletionCount > 0) ? 3 : 0);
				val4.CompletionCount = expeditionProgressionData.ThirdCompletionCount;
				val4.State = (LayerProgressionState)((expeditionProgressionData.ThirdCompletionCount > 0) ? 3 : 0);
				val.Layers.SetLayer((ExpeditionLayers)0, val2);
				val.Layers.SetLayer((ExpeditionLayers)1, val3);
				val.Layers.SetLayer((ExpeditionLayers)2, val4);
				LPLogger.Warning($"{val2.CompletionCount}, {val3.CompletionCount}, {val4.CompletionCount}");
				expeditions[key] = val;
			}
		}

		static LocalProgressionManager()
		{
			Current = new LocalProgressionManager();
			DirPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "GTFO-Modding", "LocalProgression");
		}

		private LocalProgressionManager()
		{
		}
	}
	internal static class LPLogger
	{
		private static ManualLogSource logger = Logger.CreateLogSource("LocalProgression");

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

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

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

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

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

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

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

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)32, (object)str);
			}
		}
	}
	public static class Utils
	{
		public static bool TryGetComponent<T>(this GameObject obj, out T comp)
		{
			comp = obj.GetComponent<T>();
			return comp != null;
		}
	}
}
namespace LocalProgression.Patches
{
	[HarmonyPatch]
	internal class Patches_CM_PageRundown_New
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageRundown_New), "Setup")]
		private static void Post_Setup(CM_PageRundown_New __instance)
		{
			LocalProgressionManager.Current.SetCurrentRundownPageInstance(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageRundown_New), "PlaceRundown")]
		private static void Post_PlaceRundown(CM_PageRundown_New __instance)
		{
			LocalProgressionManager.Current.OnNativeRundownProgressionUpdated();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageRundown_New), "OnEnable")]
		private static void Post_OnEnable(CM_PageRundown_New __instance)
		{
			LocalProgressionManager.Current.OnNativeRundownProgressionUpdated();
		}
	}
	[HarmonyPatch]
	internal class FixEndScreen
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(DiscordManager), "UpdateDiscordDetails")]
		private static bool Pre_UpdateDiscordDetails()
		{
			return false;
		}
	}
	[HarmonyPatch]
	internal class Patches_GS_ExpeditionSuccess
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(GS_ExpeditionSuccess), "Enter")]
		private static void DoChangeState(GS_ExpeditionSuccess __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			pActiveExpedition activeExpeditionData = RundownManager.GetActiveExpeditionData();
			string rundownProgressionExpeditionKey = RundownManager.GetRundownProgressionExpeditionKey(activeExpeditionData.tier, activeExpeditionData.expeditionIndex);
			bool mainLayerCleared = (int)WardenObjectiveManager.CurrentState.main_status == 40;
			bool secondaryLayerCleared = (int)WardenObjectiveManager.CurrentState.second_status == 40;
			bool thirdLayerCleared = (int)WardenObjectiveManager.CurrentState.third_status == 40;
			LPLogger.Debug("Level cleared, recording - " + rundownProgressionExpeditionKey);
			LocalProgressionManager.Current.RecordExpeditionSuccessForCurrentRundown(rundownProgressionExpeditionKey, mainLayerCleared, secondaryLayerCleared, thirdLayerCleared);
		}
	}
}
namespace LocalProgression.Data
{
	public class ExpeditionProgressionData
	{
		public string ExpeditionKey { get; set; } = string.Empty;


		public int MainCompletionCount { get; set; }

		public int SecondaryCompletionCount { get; set; }

		public int ThirdCompletionCount { get; set; }

		public int AllClearCount { get; set; }
	}
	public class RundownProgressionData
	{
		public string RundownName { get; set; } = string.Empty;


		public uint RundownID { get; set; }

		public Dictionary<string, ExpeditionProgressionData> LocalProgressionDict { get; set; } = new Dictionary<string, ExpeditionProgressionData>();


		public int MainClearCount { get; set; }

		public int SecondaryClearCount { get; set; }

		public int ThirdClearCount { get; set; }

		public int AllClearCount { get; set; }

		public void Reset()
		{
			RundownName = string.Empty;
			RundownID = 0u;
			LocalProgressionDict.Clear();
			int num2 = (AllClearCount = 0);
			int num4 = (ThirdClearCount = num2);
			int mainClearCount = (SecondaryClearCount = num4);
			MainClearCount = mainClearCount;
		}
	}
}
namespace LocalProgression.Component
{
	public class ExpeditionSuccess_NoBooster : MonoBehaviour
	{
		private CM_PageExpeditionSuccess expeditionSuccessPage;

		private CM_ExpeditionSectorIcon m_completeWithNoBoosterIcon;

		private float m_time_clearedWithNoBooster = 7.5f;

		public void Setup()
		{
			if ((Object)(object)expeditionSuccessPage != (Object)null && (Object)(object)m_completeWithNoBoosterIcon != (Object)null)
			{
				return;
			}
			EventAPI.OnAssetsLoaded += delegate
			{
				expeditionSuccessPage = ((Component)this).gameObject.GetComponent<CM_PageExpeditionSuccess>();
				if ((Object)(object)expeditionSuccessPage == (Object)null)
				{
					LPLogger.Error("ExpeditionSuccess_NoBooster.Setup: cannot find CM_PageExpeditionSuccess in parent.. Add `PageExpeditionSuccessWithNoBooster` to CM_ExpeditionSuccessPage as component first!");
				}
				else
				{
					m_completeWithNoBoosterIcon = Object.Instantiate<CM_ExpeditionSectorIcon>(expeditionSuccessPage.m_sectorIconAllCompleted);
					if ((Object)(object)m_completeWithNoBoosterIcon == (Object)null)
					{
						LPLogger.Error("ExpeditionSuccess_NoBooster.Setup: cannot instantiate NoBooster icon...");
					}
				}
			};
			((Component)this).gameObject.SetActive(false);
		}

		private void OnEnable()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Invalid comparison between Unknown and I4
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Invalid comparison between Unknown and I4
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			LPLogger.Warning("ExpeditionSuccess_NoBooster: OnEnable");
			((Component)this).gameObject.SetActive(true);
			bool boosterUnused = true;
			foreach (PlayerBoosterImplantState item in (Il2CppArrayBase<PlayerBoosterImplantState>)(object)BoosterImplantManager.Current.m_boosterPlayers)
			{
				if (item == null)
				{
					continue;
				}
				foreach (pBoosterImplantData item2 in (Il2CppArrayBase<pBoosterImplantData>)(object)item.BoosterImplantDatas)
				{
					if (item2.BoosterImplantID != 0)
					{
						boosterUnused = false;
						break;
					}
				}
			}
			int num = 0;
			bool flag = RundownManager.HasSecondaryLayer(RundownManager.ActiveExpedition);
			bool flag2 = RundownManager.HasThirdLayer(RundownManager.ActiveExpedition);
			num += (flag ? 1 : 0);
			num += (flag2 ? 1 : 0);
			num += ((flag && (int)WardenObjectiveManager.CurrentState.second_status == 40 && flag2 && (int)WardenObjectiveManager.CurrentState.second_status == 40) ? 1 : 0);
			SetupNoBoosterUsedIcon(boosterUnused);
			((RectTransformComp)m_completeWithNoBoosterIcon).SetPosition(new Vector2((float)num * 400f, 0f));
			m_completeWithNoBoosterIcon.BlinkIn(m_time_clearedWithNoBooster);
		}

		private void SetupNoBoosterUsedIcon(bool boosterUnused)
		{
			CM_ExpeditionSectorIcon completeWithNoBoosterIcon = m_completeWithNoBoosterIcon;
			completeWithNoBoosterIcon.m_isFinishedAll = true;
			completeWithNoBoosterIcon.m_root = ((Component)expeditionSuccessPage).transform;
			completeWithNoBoosterIcon.SetupIcon(completeWithNoBoosterIcon.m_iconMainSkull, completeWithNoBoosterIcon.m_iconMainBG, false, false, 0.5f, 0.7f);
			completeWithNoBoosterIcon.SetupIcon(completeWithNoBoosterIcon.m_iconSecondarySkull, completeWithNoBoosterIcon.m_iconSecondaryBG, false, false, 0.5f, 0.7f);
			completeWithNoBoosterIcon.SetupIcon(completeWithNoBoosterIcon.m_iconThirdSkull, completeWithNoBoosterIcon.m_iconThirdBG, false, false, 0.5f, 0.7f);
			completeWithNoBoosterIcon.SetupIcon(completeWithNoBoosterIcon.m_iconFinishedAllSkull, completeWithNoBoosterIcon.m_iconFinishedAllBG, true, true, 0.5f, 0.7f);
			completeWithNoBoosterIcon.m_titleVisible = true;
			completeWithNoBoosterIcon.m_isCleared = boosterUnused;
			((Component)completeWithNoBoosterIcon.m_rightSideText).gameObject.SetActive(false);
			((TMP_Text)completeWithNoBoosterIcon.m_title).text = "<color=orange>NO BOOSTER</color>";
			((Graphic)completeWithNoBoosterIcon.m_title).Rebuild((CanvasUpdate)3);
			((Component)completeWithNoBoosterIcon.m_title).gameObject.SetActive(completeWithNoBoosterIcon.m_titleVisible);
		}

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

plugins/net6/InjectLib.dll

Decompiled 4 months ago
using System;
using System.CodeDom.Compiler;
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.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using GTFO.API;
using GTFO.API.JSON;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppJsonNet;
using Il2CppJsonNet.Converters;
using Il2CppJsonNet.Linq;
using Il2CppJsonNet.Serialization;
using Il2CppSystem;
using Il2CppSystem.Runtime.InteropServices;
using InjectLib.FieldInjection;
using InjectLib.JsonNETInjection;
using InjectLib.JsonNETInjection.Converter;
using InjectLib.JsonNETInjection.Detours;
using InjectLib.JsonNETInjection.Handler;
using InjectLib.Utils;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("InjectLib")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+gitc83a124-master")]
[assembly: AssemblyProduct("InjectLib")]
[assembly: AssemblyTitle("InjectLib")]
[assembly: TargetPlatform("Windows7.0")]
[assembly: SupportedOSPlatform("Windows7.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = P_0;
		}
	}
}
namespace InjectLib
{
	[BepInPlugin("GTFO.InjectLib", "InjectLib", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class EntryPoint : BasePlugin
	{
		public override void Load()
		{
			NativeJsonProcessorStore.Initialize();
		}

		public override bool Unload()
		{
			return ((BasePlugin)this).Unload();
		}
	}
	internal static class Logger
	{
		private static readonly ManualLogSource _Logger;

		static Logger()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_Logger = new ManualLogSource("InjectLib");
			Logger.Sources.Add((ILogSource)(object)_Logger);
		}

		private static string Format(object msg)
		{
			return msg.ToString();
		}

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

		public static void Info(string str)
		{
			_Logger.LogMessage((object)str);
		}

		public static void Info(object data)
		{
			_Logger.LogMessage((object)Format(data));
		}

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

		public static void Debug(string str)
		{
			_Logger.LogDebug((object)str);
		}

		public static void Debug(object data)
		{
			_Logger.LogDebug((object)Format(data));
		}

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

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

		public static void Error(object data)
		{
			_Logger.LogError((object)Format(data));
		}

		public static void Fatal(BepInExFatalLogInterpolatedStringHandler handler)
		{
			_Logger.LogFatal(handler);
		}

		public static void Fatal(string str)
		{
			_Logger.LogFatal((object)str);
		}

		public static void Fatal(object data)
		{
			_Logger.LogFatal((object)Format(data));
		}

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

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

		public static void Warn(object data)
		{
			_Logger.LogWarning((object)Format(data));
		}

		[Conditional("DEBUG")]
		public static void DebugOnly(object data)
		{
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.1.3+git35c0c2a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "InjectLib";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "gitc83a124-master";

		public const string SemVer = "1.0.0+gitc83a124-master";

		public const string GitRevShort = "c83a124";

		public const string GitRevLong = "c83a124696b1272397115ca04d902622f35ba87e";

		public const string GitBranch = "master";

		public const string GitTag = null;

		public const int GitCommitsSinceTag = 0;

		public const bool GitIsDirty = false;
	}
}
namespace InjectLib.Utils
{
	internal static class FieldsExtension
	{
		public static void SetNativeJsonProcessor(this DataSetConverter converter, NativeJsonProcessor processor)
		{
			FieldInjector<DataSetConverter>.TrySetManagedField(converter, "m_JsonProcessor", processor);
		}

		public static NativeJsonProcessor GetNativeJsonProcessor(this DataSetConverter converter)
		{
			FieldInjector<DataSetConverter>.TryGetManagedField<NativeJsonProcessor>(converter, "m_JsonProcessor", out var value);
			return value;
		}
	}
	internal static class ObjectCopier
	{
		public static void CopyProperties<T>(T source, T target) where T : Il2CppObjectBase
		{
			PropertyInfo[] properties = typeof(T).GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				Type propertyType = propertyInfo.PropertyType;
				if (!propertyInfo.Name.Contains("_k__BackingField") && !(propertyType == typeof(IntPtr)) && propertyInfo.CanRead && propertyInfo.CanWrite)
				{
					propertyInfo.SetValue(target, propertyInfo.GetValue(source));
				}
			}
		}
	}
}
namespace InjectLib.JsonNETInjection
{
	public static class JsonInjector
	{
		static JsonInjector()
		{
			FieldInjector<DataSetConverter>.DefineManagedField<NativeJsonProcessor>("m_JsonProcessor");
		}

		public static void SetConverter<T>(Il2CppJsonReferenceTypeConverter<T> converter) where T : Il2CppObjectBase
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			if (converter == null)
			{
				throw new ArgumentNullException("converter");
			}
			if (!NativeJsonProcessorStore.Prepare<T>(out var processor))
			{
				return;
			}
			if (processor.Converter != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(76, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Converter (type: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeof(T).FullName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") will be replaced! This would leads to unwanted behaviour!");
				}
				Logger.Warn(val);
				Logger.Warn(" - Suggetion: If your converter does not require to deep-level altering of JSON, consider use Il2CppJsonReferenceTypeHandler instead.");
				val = new BepInExWarningLogInterpolatedStringHandler(19, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Previous Owner: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(processor.Converter.GetType().Assembly.FullName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(processor.Converter.GetType().FullName);
				}
				Logger.Warn(val);
				val = new BepInExWarningLogInterpolatedStringHandler(14, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("New Owner: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(converter.GetType().Assembly.FullName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(converter.GetType().FullName);
				}
				Logger.Warn(val);
			}
			processor.Converter = converter;
		}

		public static void SetConverter<T>(Il2CppJsonUnmanagedTypeConverter<T> converter) where T : unmanaged
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			if (converter == null)
			{
				throw new ArgumentNullException("converter");
			}
			if (!NativeJsonProcessorStore.Prepare<T>(out var processor))
			{
				return;
			}
			if (processor.Converter != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(76, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Converter (type: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeof(T).FullName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") will be replaced! This would leads to unwanted behaviour!");
				}
				Logger.Warn(val);
				Logger.Warn(" - Suggetion: If your converter does not require to deep-level altering of JSON, consider use Il2CppJsonUnmanagedTypeHandler instead.");
				val = new BepInExWarningLogInterpolatedStringHandler(22, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" - Previous Owner: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(processor.Converter.GetType().Assembly.FullName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(processor.Converter.GetType().FullName);
				}
				Logger.Warn(val);
				val = new BepInExWarningLogInterpolatedStringHandler(17, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" - New Owner: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(converter.GetType().Assembly.FullName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(converter.GetType().FullName);
				}
				Logger.Warn(val);
			}
			processor.Converter = converter;
		}

		public static void AddHandler<T>(Il2CppJsonReferenceTypeHandler<T> handler) where T : Il2CppObjectBase
		{
			if (handler == null)
			{
				throw new ArgumentNullException("handler");
			}
			if (NativeJsonProcessorStore.Prepare<T>(out var processor))
			{
				processor.Handlers.Add(handler);
			}
		}

		public static void AddHandler<T>(Il2CppJsonUnmanagedTypeHandler<T> handler) where T : unmanaged
		{
			if (handler == null)
			{
				throw new ArgumentNullException("handler");
			}
			if (NativeJsonProcessorStore.Prepare<T>(out var processor))
			{
				processor.Handlers.Add(handler);
			}
		}
	}
	internal class NativeJsonProcessor
	{
		public Type Type { get; set; }

		public DataSetConverter DummyConverter { get; set; }

		public INativeJsonConverter Converter { get; set; }

		public IList<INativeJsonHandler> Handlers { get; } = new List<INativeJsonHandler>();


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


		public IntPtr ProcessRead(JsonReader reader, IntPtr existingValue, JsonSerializer serializer)
		{
			JToken jToken = JToken.ReadFrom(reader);
			IntPtr pointer;
			if (Converter != null)
			{
				pointer = ((Il2CppObjectBase)Converter.ReadJson(jToken, existingValue, serializer)).Pointer;
			}
			else
			{
				SetUsingContractConverter(serializer, use: false);
				pointer = ((Il2CppObjectBase)serializer.Deserialize(jToken.CreateReader(), Type)).Pointer;
				SetUsingContractConverter(serializer, use: true);
			}
			Object result = PtrToObject(pointer);
			foreach (INativeJsonHandler handler in Handlers)
			{
				handler.OnRead(in result, in jToken);
			}
			return pointer;
		}

		public void ProcessWrite(JsonWriter writer, IntPtr valueToWrite, JsonSerializer serializer)
		{
			if (Converter != null)
			{
				Converter.WriteJson(writer, valueToWrite, serializer);
				return;
			}
			SetUsingContractConverter(serializer, use: false);
			serializer.Serialize(writer, PtrToObject(valueToWrite));
			SetUsingContractConverter(serializer, use: true);
		}

		private static Object PtrToObject(IntPtr ptr)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			if (ptr == IntPtr.Zero)
			{
				return null;
			}
			return new Object(ptr);
		}

		private void SetUsingContractConverter(JsonSerializer serializer, bool use)
		{
			JsonContract val = serializer.ContractResolver.ResolveContract(Type);
			if (use)
			{
				val.Converter = (JsonConverter)(object)DummyConverter;
				val.InternalConverter = (JsonConverter)(object)DummyConverter;
			}
			else
			{
				val.Converter = null;
				val.InternalConverter = null;
			}
		}
	}
	internal static class NativeJsonProcessorStore
	{
		private static readonly Dictionary<IntPtr, NativeJsonProcessor> _RegisteredProcessors = new Dictionary<IntPtr, NativeJsonProcessor>();

		internal static void Initialize()
		{
			Detour_JsonConverterTrampoline.Patch();
			Detour_NativeConverterLink.Patch();
		}

		public static bool Prepare<T>(out NativeJsonProcessor processor)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			Type val = Il2CppType.From(typeof(T));
			if (val != (Type)null && ((Il2CppObjectBase)val).Pointer != IntPtr.Zero)
			{
				if (_RegisteredProcessors.TryGetValue(((Il2CppObjectBase)val).Pointer, out processor))
				{
					return true;
				}
				DataSetConverter val2 = new DataSetConverter();
				NativeJsonProcessor nativeJsonProcessor2 = (_RegisteredProcessors[((Il2CppObjectBase)val).Pointer] = new NativeJsonProcessor());
				processor = nativeJsonProcessor2;
				processor.Type = val;
				processor.DummyConverter = val2;
				val2.SetNativeJsonProcessor(processor);
				return true;
			}
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Type: '");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(typeof(T).Name);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' is not in il2cpp domain!");
			}
			Logger.Error(val3);
			processor = null;
			return false;
		}

		public static bool TryGetConverterPointer(IntPtr typePtr, out IntPtr converterPtr)
		{
			if (TryGetProcessor(typePtr, out var processor) && processor.DummyConverter != null)
			{
				converterPtr = ((Il2CppObjectBase)processor.DummyConverter).Pointer;
				return converterPtr != IntPtr.Zero;
			}
			converterPtr = IntPtr.Zero;
			return false;
		}

		public static bool TryGetProcessor(IntPtr typePtr, out NativeJsonProcessor processor)
		{
			if (_RegisteredProcessors.TryGetValue(typePtr, out processor) && processor != null && processor.Enabled)
			{
				return processor != null;
			}
			processor = null;
			return false;
		}
	}
}
namespace InjectLib.JsonNETInjection.Supports
{
	internal interface IBaseConnector
	{
		NativeJsonProcessor Processor { get; set; }
	}
	public sealed class InjectLibConnector : JsonConverterFactory
	{
		public override bool CanConvert(Type typeToConvert)
		{
			Type val = Il2CppType.From(typeToConvert, false);
			if (val != (Type)null && NativeJsonProcessorStore.TryGetProcessor(((Il2CppObjectBase)val).Pointer, out var _))
			{
				return true;
			}
			return false;
		}

		public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
		{
			if (!NativeJsonProcessorStore.TryGetProcessor(((Il2CppObjectBase)Il2CppType.From(typeToConvert, false)).Pointer, out var processor))
			{
				return null;
			}
			if (typeToConvert.IsAssignableTo(typeof(Il2CppObjectBase)))
			{
				JsonConverter obj = (JsonConverter)Activator.CreateInstance(typeof(ReferenceTypeConnector<>).MakeGenericType(typeToConvert), BindingFlags.Instance | BindingFlags.Public, null, null, null);
				((IBaseConnector)obj).Processor = processor;
				return obj;
			}
			if (typeToConvert.IsValueType)
			{
				JsonConverter obj2 = (JsonConverter)Activator.CreateInstance(typeof(ValueTypeConnector<>).MakeGenericType(typeToConvert), BindingFlags.Instance | BindingFlags.Public, null, null, null);
				((IBaseConnector)obj2).Processor = processor;
				return obj2;
			}
			return null;
		}
	}
	public class InjectLibJSON
	{
		public static JsonSerializerOptions JsonOptions => new JsonSerializerOptions(JsonSerializer.DefaultSerializerSettingsWithLocalizedText)
		{
			Converters = { (JsonConverter)new InjectLibConnector() }
		};

		public static T Deserialize<T>(string json, params JsonConverter[] converters)
		{
			JsonSerializerOptions jsonOptions = JsonOptions;
			if (converters != null)
			{
				foreach (JsonConverter item in converters)
				{
					jsonOptions.Converters.Add(item);
				}
			}
			return JsonSerializer.Deserialize<T>(json, jsonOptions);
		}

		public static object Deserialize(string json, Type type, params JsonConverter[] converters)
		{
			JsonSerializerOptions jsonOptions = JsonOptions;
			if (converters != null)
			{
				foreach (JsonConverter item in converters)
				{
					jsonOptions.Converters.Add(item);
				}
			}
			return JsonSerializer.Deserialize(json, type, jsonOptions);
		}

		public static string Serialize<T>(T obj, params JsonConverter[] converters)
		{
			JsonSerializerOptions jsonOptions = JsonOptions;
			if (converters != null)
			{
				foreach (JsonConverter item in converters)
				{
					jsonOptions.Converters.Add(item);
				}
			}
			return JsonSerializer.Serialize(obj, JsonOptions);
		}

		public static string Serialize(object obj, params JsonConverter[] converters)
		{
			JsonSerializerOptions jsonOptions = JsonOptions;
			if (converters != null)
			{
				foreach (JsonConverter item in converters)
				{
					jsonOptions.Converters.Add(item);
				}
			}
			return JsonSerializer.Serialize(obj, JsonOptions);
		}
	}
	internal class ReferenceTypeConnector<T> : JsonConverter<T>, IBaseConnector where T : Il2CppObjectBase
	{
		public NativeJsonProcessor Processor { get; set; }

		public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			Type val = Il2CppType.From(typeToConvert, false);
			JsonNode jsonNode = JsonNode.Parse(ref reader);
			return (T)Activator.CreateInstance(typeof(T), ((Il2CppObjectBase)JsonConvert.DeserializeObject(jsonNode.ToJsonString(), val, (JsonSerializerSettings)null)).Pointer);
		}

		public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
		{
			JsonSerializer.Serialize(writer, value);
		}
	}
	internal class ValueTypeConnector<T> : JsonConverter<T>, IBaseConnector where T : unmanaged
	{
		public NativeJsonProcessor Processor { get; set; }

		public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			Type val = Il2CppType.From(typeToConvert, false);
			return ((Il2CppObjectBase)JsonConvert.DeserializeObject(JsonNode.Parse(ref reader).ToJsonString(), val, (JsonSerializerSettings)null)).Unbox<T>();
		}

		public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
		{
			JsonSerializer.Serialize(writer, value);
		}
	}
}
namespace InjectLib.JsonNETInjection.Handler
{
	public abstract class Il2CppJsonReferenceTypeHandler<T> : INativeJsonHandler where T : Il2CppObjectBase
	{
		public abstract void OnRead(in Object result, in JToken jToken);
	}
	public abstract class Il2CppJsonUnmanagedTypeHandler<T> : INativeJsonHandler where T : unmanaged
	{
		public abstract void OnRead(in Object result, in JToken jToken);
	}
	internal interface INativeJsonHandler
	{
		void OnRead(in Object result, in JToken jToken);
	}
}
namespace InjectLib.JsonNETInjection.Detours
{
	internal class Detour_JsonConverterTrampoline
	{
		public unsafe delegate IntPtr GetMatchingConverterDel(IntPtr converters, IntPtr objectType, Il2CppMethodInfo* methodInfo);

		private static INativeDetour _Detour;

		private static GetMatchingConverterDel _Original;

		public unsafe static void Patch()
		{
			_Detour = INativeDetour.CreateAndApply<GetMatchingConverterDel>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<JsonSerializer>("GetMatchingConverter", "Newtonsoft.Json.JsonConverter", false, new string[2]
			{
				"System.Collections.Generic.IList<Newtonsoft.Json.JsonConverter>",
				typeof(Type).FullName
			}), (GetMatchingConverterDel)Detour, ref _Original);
		}

		private unsafe static IntPtr Detour(IntPtr converters, IntPtr objectType, Il2CppMethodInfo* methodInfo)
		{
			if (NativeJsonProcessorStore.TryGetConverterPointer(objectType, out var converterPtr))
			{
				return converterPtr;
			}
			return _Original(converters, objectType, methodInfo);
		}
	}
	internal class Detour_NativeConverterLink
	{
		public delegate IntPtr ReadJsonDel(IntPtr _this, IntPtr reader, IntPtr objectType, IntPtr existingValue, IntPtr serializer);

		public delegate void WriteJsonDel(IntPtr _this, IntPtr writer, IntPtr value, IntPtr serializer);

		private static INativeDetour _ReadDetour;

		private static INativeDetour _WriteDetour;

		private static ReadJsonDel _ReadOriginal;

		private static WriteJsonDel _WriteOriginal;

		public unsafe static void Patch()
		{
			void* il2CppMethod = Il2CppAPI.GetIl2CppMethod<DataSetConverter>("ReadJson", "System.Object", false, new string[4] { "Newtonsoft.Json.JsonReader", "System.Type", "System.Object", "Newtonsoft.Json.JsonSerializer" });
			void* il2CppMethod2 = Il2CppAPI.GetIl2CppMethod<DataSetConverter>("WriteJson", typeof(void).FullName, false, new string[3] { "Newtonsoft.Json.JsonWriter", "System.Object", "Newtonsoft.Json.JsonSerializer" });
			_ReadDetour = INativeDetour.CreateAndApply<ReadJsonDel>((IntPtr)(nint)il2CppMethod, (ReadJsonDel)Detour_Read, ref _ReadOriginal);
			_WriteDetour = INativeDetour.CreateAndApply<WriteJsonDel>((IntPtr)(nint)il2CppMethod2, (WriteJsonDel)Detour_Write, ref _WriteOriginal);
		}

		private static IntPtr Detour_Read(IntPtr _this, IntPtr reader, IntPtr objectType, IntPtr existingValue, IntPtr serializer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			NativeJsonProcessor nativeJsonProcessor = FieldsExtension.GetNativeJsonProcessor(new DataSetConverter(_this));
			if (nativeJsonProcessor != null)
			{
				JsonReader reader2 = new JsonReader(reader);
				JsonSerializer serializer2 = new JsonSerializer(serializer);
				return nativeJsonProcessor.ProcessRead(reader2, existingValue, serializer2);
			}
			return _ReadOriginal(_this, reader, objectType, existingValue, serializer);
		}

		private static void Detour_Write(IntPtr _this, IntPtr writer, IntPtr value, IntPtr serializer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			NativeJsonProcessor nativeJsonProcessor = FieldsExtension.GetNativeJsonProcessor(new DataSetConverter(_this));
			if (nativeJsonProcessor != null)
			{
				JsonWriter writer2 = new JsonWriter(writer);
				JsonSerializer serializer2 = new JsonSerializer(serializer);
				nativeJsonProcessor.ProcessWrite(writer2, value, serializer2);
			}
			else
			{
				_WriteOriginal(_this, writer, value, serializer);
			}
		}
	}
}
namespace InjectLib.JsonNETInjection.Converter
{
	public abstract class Il2CppJsonReferenceTypeConverter<T> : INativeJsonConverter where T : Il2CppObjectBase
	{
		public virtual string Name => GetType().Name;

		public Object ReadJson(JToken jToken, IntPtr existingValue, JsonSerializer serializer)
		{
			if (existingValue == IntPtr.Zero)
			{
				return ((Il2CppObjectBase)Read(jToken, default(T), serializer)).Cast<Object>();
			}
			T existingValue2 = (T)Activator.CreateInstance(typeof(T), existingValue);
			return ((Il2CppObjectBase)Read(jToken, existingValue2, serializer)).Cast<Object>();
		}

		public void WriteJson(JsonWriter writer, IntPtr valueToWrite, JsonSerializer serializer)
		{
			if (valueToWrite == IntPtr.Zero)
			{
				Write(writer, default(T), serializer);
				return;
			}
			T value = (T)Activator.CreateInstance(typeof(T), valueToWrite);
			Write(writer, value, serializer);
		}

		protected abstract T Read(JToken jToken, T existingValue, JsonSerializer serializer);

		protected abstract void Write(JsonWriter writer, T value, JsonSerializer serializer);
	}
	public abstract class Il2CppJsonUnmanagedTypeConverter<T> : INativeJsonConverter where T : unmanaged
	{
		public virtual string Name => GetType().Name;

		public Object ReadJson(JToken jToken, IntPtr existingValue, JsonSerializer serializer)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if (existingValue == IntPtr.Zero)
			{
				return ToIl2CppObject(Read(jToken, default(T), serializer));
			}
			Object val = new Object(existingValue);
			return ToIl2CppObject(Read(jToken, ((Il2CppObjectBase)val).Unbox<T>(), serializer));
		}

		public void WriteJson(JsonWriter writer, IntPtr valueToWrite, JsonSerializer serializer)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			if (valueToWrite == IntPtr.Zero)
			{
				Write(writer, default(T), serializer);
				return;
			}
			Object val = new Object(valueToWrite);
			Write(writer, ((Il2CppObjectBase)val).Unbox<T>(), serializer);
		}

		protected abstract T Read(JToken jToken, T existingValue, JsonSerializer serializer);

		protected abstract void Write(JsonWriter writer, T value, JsonSerializer serializer);

		protected abstract Object ToIl2CppObject(T value);
	}
	internal interface INativeJsonConverter
	{
		string Name { get; }

		Object ReadJson(JToken jToken, IntPtr existingValue, JsonSerializer serializer);

		void WriteJson(JsonWriter writer, IntPtr valueToWrite, JsonSerializer serializer);
	}
}
namespace InjectLib.FieldInjection
{
	public static class FieldInjector<Il2CppType> where Il2CppType : Il2CppObjectBase
	{
		private static readonly Dictionary<string, InjectedFieldInfo> _OffsetLookup = new Dictionary<string, InjectedFieldInfo>();

		public static void DefineValueField<Value>(string fieldName) where Value : unmanaged
		{
			if (!_OffsetLookup.ContainsKey(fieldName))
			{
				InjectValueField<Value>(fieldName);
			}
		}

		public static void DefineManagedField<Value>(string fieldName) where Value : class
		{
			if (!_OffsetLookup.ContainsKey(fieldName))
			{
				InjectManagedField<Value>(fieldName);
			}
		}

		private unsafe static void InjectManagedField<Value>(string fieldName) where Value : class
		{
			int num = 8;
			INativeClassStruct val = UnityVersionHandler.Wrap((Il2CppClass*)(void*)Il2CppClassPointerStore<Il2CppType>.NativeClassPtr);
			val.InstanceSize += (uint)num;
			val.ActualSize = val.InstanceSize;
			_OffsetLookup[fieldName] = new InjectedFieldInfo
			{
				FieldOffset = (nint)(val.InstanceSize - num),
				FieldSize = num
			};
		}

		public unsafe static bool TryGetManagedField<Value>(Il2CppType obj, string fieldName, out Value value) where Value : class
		{
			if (obj == null)
			{
				value = null;
				return false;
			}
			if (((Il2CppObjectBase)obj).Pointer == IntPtr.Zero)
			{
				value = null;
				return false;
			}
			if (!_OffsetLookup.TryGetValue(fieldName, out var value2))
			{
				value = null;
				return false;
			}
			if (8 != value2.FieldSize)
			{
				value = null;
				return false;
			}
			ulong num = *(ulong*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset);
			if (num == 0L)
			{
				value = null;
				return false;
			}
			value = ManagedReferenceStore<Il2CppType, Value>.Get(num);
			return value != null;
		}

		public unsafe static bool TrySetManagedField<Value>(Il2CppType obj, string fieldName, Value value) where Value : class
		{
			if (obj == null)
			{
				return false;
			}
			if (((Il2CppObjectBase)obj).Pointer == IntPtr.Zero)
			{
				return false;
			}
			if (!_OffsetLookup.TryGetValue(fieldName, out var value2))
			{
				return false;
			}
			if (8 != value2.FieldSize)
			{
				return false;
			}
			ulong num = *(ulong*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset);
			if (num == 0L)
			{
				ulong uniqueKey = ManagedReferenceStore<Il2CppType, Value>.UniqueKey;
				ManagedReferenceStore<Il2CppType, Value>.Set(uniqueKey, value);
				*(ulong*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset) = uniqueKey;
				return true;
			}
			ManagedReferenceStore<Il2CppType, Value>.Set(num, value);
			return true;
		}

		private static int SizeOfUnmanagedType<Value>() where Value : unmanaged
		{
			if (typeof(Value) == typeof(bool))
			{
				return 1;
			}
			return Marshal.SizeOf<Value>();
		}

		private unsafe static void InjectValueField<Value>(string fieldName) where Value : unmanaged
		{
			int num = SizeOfUnmanagedType<Value>();
			INativeClassStruct val = UnityVersionHandler.Wrap((Il2CppClass*)(void*)Il2CppClassPointerStore<Il2CppType>.NativeClassPtr);
			val.InstanceSize += (uint)num;
			val.ActualSize = val.InstanceSize;
			_OffsetLookup[fieldName] = new InjectedFieldInfo
			{
				FieldOffset = (nint)(val.InstanceSize - num),
				FieldSize = num
			};
		}

		public unsafe static bool TryGetValueField<Value>(Il2CppType obj, string fieldName, out Value value) where Value : unmanaged
		{
			if (obj == null)
			{
				value = default(Value);
				return false;
			}
			if (((Il2CppObjectBase)obj).Pointer == IntPtr.Zero)
			{
				value = default(Value);
				return false;
			}
			if (!_OffsetLookup.TryGetValue(fieldName, out var value2))
			{
				value = default(Value);
				return false;
			}
			if (SizeOfUnmanagedType<Value>() != value2.FieldSize)
			{
				value = default(Value);
				return false;
			}
			value = *(Value*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset);
			return true;
		}

		public unsafe static bool TrySetValueField<Value>(Il2CppType obj, string fieldName, Value value) where Value : unmanaged
		{
			if (obj == null)
			{
				return false;
			}
			if (((Il2CppObjectBase)obj).Pointer == IntPtr.Zero)
			{
				return false;
			}
			if (!_OffsetLookup.TryGetValue(fieldName, out var value2))
			{
				return false;
			}
			if (SizeOfUnmanagedType<Value>() != value2.FieldSize)
			{
				return false;
			}
			*(Value*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset) = value;
			return true;
		}
	}
	internal struct InjectedFieldInfo
	{
		public nint FieldOffset;

		public int FieldSize;
	}
	public static class ManagedReferenceStore<C, T> where C : Il2CppObjectBase where T : class
	{
		private static readonly Dictionary<ulong, T> _Lookup = new Dictionary<ulong, T>();

		private static ulong _Key = 1uL;

		public static ulong UniqueKey => _Key++;

		public static T Get(ulong key)
		{
			_Lookup.TryGetValue(key, out var value);
			return value;
		}

		public static void Set(ulong key, T value)
		{
			_Lookup[key] = value;
		}

		public static void Remove(ulong key)
		{
			_Lookup.Remove(key);
		}
	}
}

plugins/net6/LEGACY.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using AIGraph;
using AK;
using Agents;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using BoosterImplants;
using CellMenu;
using ChainedPuzzles;
using EOSExt.Reactor.Managers;
using Enemies;
using ExtraObjectiveSetup;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Instances;
using ExtraObjectiveSetup.Utils;
using FloLib.Networks.Replications;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LEGACY.ExtraEvents;
using LEGACY.LegacyOverride;
using LEGACY.LegacyOverride.ElevatorCargo;
using LEGACY.LegacyOverride.EnemyTagger;
using LEGACY.LegacyOverride.FogBeacon;
using LEGACY.LegacyOverride.ForceFail;
using LEGACY.LegacyOverride.Music;
using LEGACY.LegacyOverride.SecDoorIntText;
using LEGACY.LegacyOverride.Terminal;
using LEGACY.Utils;
using LEGACY.VanillaFix;
using LevelGeneration;
using Localization;
using MTFO.API;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using ScanPosOverride.JSON;
using ScanPosOverride.Managers;
using TMPro;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[HarmonyPatch(typeof(PUI_Watermark), "UpdateWatermark")]
internal static class Patch_WatermarkUpdateWatermark
{
	private static void Postfix(PUI_Watermark __instance)
	{
		string text = "4.6.1+gitf831086-dirty-main".Remove("x.x.x".Length);
		((TMP_Text)__instance.m_watermarkText).SetText("<color=red>MODDED</color> <color=orange>" + text + "</color>\n" + string.Empty + "<color=#00ae9d>LEGACY</color><color=orange> 3.8.8</color>", true);
	}
}
namespace LEGACY
{
	internal static class Assets
	{
		public static GameObject OBSVisual { get; private set; }

		public static GameObject ObjectiveMarker { get; private set; }

		public static void Init()
		{
			OBSVisual = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/OBSVisual.prefab");
			ObjectiveMarker = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/ObjectiveMarker.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.*/)]
	[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.*/)]
	[BepInIncompatibility("GTFO.AWO")]
	[BepInPlugin("Inas.LEGACY", "LEGACY", "3.8.8")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string RUNDOWN_NAME = "LEGACY";

		public const string VERSION = "3.8.8";

		public const bool TESTING = false;

		public const string TEST_STRING = "TESTING";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			m_Harmony = new Harmony("LEGACY");
			m_Harmony.PatchAll();
			LegacyOverrideManagers.Init();
			LegacyExtraEvents.Init();
			LEGACY.VanillaFix.Debugger.Current.Init();
			AssetAPI.OnAssetBundlesLoaded += Assets.Init;
		}
	}
}
namespace LEGACY.Reactor
{
	[HarmonyPatch]
	internal class Patch_ReactorShutdown
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")]
		private static void Post_OnStateChange(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState)
		{
			//IL_000a: 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_0011: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected I4, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			if ((Object)(object)__instance == (Object)null || oldState.status == newState.status)
			{
				return;
			}
			WardenObjectiveDataBlock val = null;
			if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null)
			{
				LegacyLogger.Error("Patch_ReactorShutdown: ");
				LegacyLogger.Error("Failed to get warden objective");
			}
			else if ((int)val.Type == 2 && !val.OnActivateOnSolveItem)
			{
				eWardenObjectiveEventTrigger val2 = (eWardenObjectiveEventTrigger)0;
				eReactorStatus status = newState.status;
				switch (status - 7)
				{
				default:
					return;
				case 0:
					val2 = (eWardenObjectiveEventTrigger)1;
					break;
				case 1:
					val2 = (eWardenObjectiveEventTrigger)2;
					break;
				case 2:
					val2 = (eWardenObjectiveEventTrigger)3;
					break;
				}
				_ = __instance.SpawnNode.LayerType;
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(val.EventsOnActivate, val2, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")]
		private static void Pre_OnBuildDone_ChainedPuzzleMidObjectiveFix(LG_WardenObjective_Reactor __instance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			WardenObjectiveDataBlock val = null;
			if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null)
			{
				LegacyLogger.Error("Patch_ReactorShutdown: Failed to get warden objective");
			}
			else if (val.ChainedPuzzleMidObjective != 0)
			{
				__instance.m_chainedPuzzleAlignMidObjective = __instance.m_chainedPuzzleAlign;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Update")]
		private static bool Pre_Update(LG_WardenObjective_Reactor __instance)
		{
			//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_000c: Invalid comparison between Unknown and I4
			if ((int)__instance.m_currentState.status != 7)
			{
				return true;
			}
			if (!__instance.m_currentWaveData.HasVerificationTerminal)
			{
				return true;
			}
			__instance.SetGUIMessage(true, Text.Format(3000u, (Object[])(object)new Object[1] { Object.op_Implicit("<color=orange>" + __instance.m_currentWaveData.VerificationTerminalSerial + "</color>") }), (ePUIMessageStyle)3, false, "", "");
			return false;
		}
	}
	[HarmonyPatch]
	internal class Patch_ReactorStartup_ExtraEventsExecution
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")]
		private static void Post_ExecuteOnNoneEventsOnDefenseStart(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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
			if (oldState.status != newState.status && (int)newState.status == 3)
			{
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)0, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")]
		private static void Post_OnBuildDone(LG_WardenObjective_Reactor __instance)
		{
			//IL_0011: 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_004c: Invalid comparison between Unknown and I4
			WardenObjectiveDataBlock db = default(WardenObjectiveDataBlock);
			if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref db) || db == null)
			{
				LegacyLogger.Error("Patch_ReactorStartup_ExtraEventsExecution: ");
				LegacyLogger.Error("Failed to get warden objective");
			}
			else if ((int)db.Type == 1 && !db.OnActivateOnSolveItem)
			{
				ChainedPuzzleInstance chainedPuzzleToStartSequence = __instance.m_chainedPuzzleToStartSequence;
				chainedPuzzleToStartSequence.OnPuzzleSolved += Action.op_Implicit((Action)delegate
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(db.EventsOnActivate, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				});
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_ReactorStartup_OverwriteGUIBehaviour
	{
		private static HashSet<uint> ForceDisableLevels;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")]
		private static bool Pre_HideReactorMessageForInfiniteWave(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//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_0020: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0029: Invalid comparison between Unknown and I4
			//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_0046: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_008d: Expected I4, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			if (oldState.status == newState.status)
			{
				return true;
			}
			if ((int)newState.status != 2 && (int)newState.status != 3 && (int)newState.status != 4)
			{
				return true;
			}
			if (ForceDisable())
			{
				if (oldState.stateCount != newState.stateCount)
				{
					__instance.OnStateCountUpdate(newState.stateCount);
				}
				if (oldState.stateProgress != newState.stateProgress)
				{
					__instance.OnStateProgressUpdate(newState.stateProgress);
				}
				__instance.ReadyForVerification = false;
				eReactorStatus status = newState.status;
				switch (status - 2)
				{
				case 0:
				{
					WardenObjectiveDataBlock val = null;
					if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null)
					{
						LegacyLogger.Error("Patch_ReactorStartup_OverwriteGUIBehaviour: ");
						LegacyLogger.Error("Failed to get warden objective datablock");
						break;
					}
					__instance.m_lightCollection.SetMode(val.LightsOnDuringIntro);
					__instance.m_lightCollection.ResetUpdateValues(true);
					__instance.lcReset = true;
					__instance.m_lightsBlinking = false;
					__instance.m_spawnEnemies = false;
					__instance.m_progressUpdateEnabled = true;
					__instance.m_alarmCountdownPlayed = false;
					__instance.m_currentDuration = ((!newState.verifyFailed) ? __instance.m_currentWaveData.Warmup : __instance.m_currentWaveData.WarmupFail);
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)1, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
					if (__instance.m_currentWaveCount == 1)
					{
						Debug.LogError(Object.op_Implicit("Reactor IDLE START"));
						__instance.m_sound.Post(EVENTS.REACTOR_POWER_LEVEL_1_LOOP, true);
						__instance.m_sound.SetRTPCValue(GAME_PARAMETERS.REACTOR_POWER, 0f);
					}
					else
					{
						Debug.LogError(Object.op_Implicit("Reactor REACTOR_POWER_DOWN"));
						__instance.m_sound.Post(EVENTS.REACTOR_POWER_LEVEL_2_TO_1_TRANSITION, true);
						__instance.m_sound.SetRTPCValue(GAME_PARAMETERS.REACTOR_POWER, 0f);
					}
					break;
				}
				case 1:
					__instance.m_lightCollection.ResetUpdateValues(true);
					__instance.lcReset = true;
					__instance.m_spawnEnemies = true;
					__instance.m_currentEnemyWaveIndex = 0;
					__instance.m_alarmCountdownPlayed = false;
					__instance.m_progressUpdateEnabled = true;
					__instance.m_currentDuration = __instance.m_currentWaveData.Wave;
					__instance.m_sound.Post(EVENTS.REACTOR_POWER_LEVEL_1_TO_3_TRANSITION, true);
					break;
				case 2:
					__instance.m_lightCollection.ResetUpdateValues(false);
					__instance.lcReset = true;
					__instance.m_spawnEnemies = false;
					__instance.m_progressUpdateEnabled = true;
					__instance.ReadyForVerification = true;
					Debug.Log(Object.op_Implicit("Wait for verify! newState.verifyFailed? " + newState.verifyFailed));
					__instance.m_currentDuration = ((!newState.verifyFailed) ? __instance.m_currentWaveData.Verify : __instance.m_currentWaveData.VerifyFail);
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)2, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
					break;
				}
				__instance.m_currentState = newState;
				return false;
			}
			return true;
		}

		private static bool ForceDisable()
		{
			return ForceDisableLevels.Contains(RundownManager.ActiveExpedition.LevelLayoutData);
		}

		static Patch_ReactorStartup_OverwriteGUIBehaviour()
		{
			ForceDisableLevels = new HashSet<uint>();
			LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock("Legacy_L3E2_L1");
			if (block != null)
			{
				ForceDisableLevels.Add(((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID);
			}
			block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock("Legacy_L1E1_L1");
			if (block != null)
			{
				ForceDisableLevels.Add(((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID);
			}
		}
	}
}
namespace LEGACY.HardcodedBehaviours
{
	[HarmonyPatch]
	internal class Patch_PickupItem_Hardcoded
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_Distribute_PickupItemsPerZone), "Build")]
		private static void Pre_LG_Distribute_PickupItemsPerZone(LG_Distribute_PickupItemsPerZone __instance)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock("Legacy_L2E1_Gridlock");
			if (block == null || RundownManager.ActiveExpedition.LevelLayoutData != ((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID)
			{
				return;
			}
			eLocalZoneIndex localIndex = __instance.m_zone.LocalIndex;
			if ((int)localIndex != 10)
			{
				if ((int)localIndex == 11)
				{
					__instance.m_zonePlacementWeights.Start = 0f;
					__instance.m_zonePlacementWeights.Middle = 5000f;
					__instance.m_zonePlacementWeights.End = 5000f;
				}
			}
			else
			{
				__instance.m_zonePlacementWeights.Start = 10000f;
				__instance.m_zonePlacementWeights.Middle = 0f;
				__instance.m_zonePlacementWeights.End = 0f;
			}
		}
	}
}
namespace LEGACY.VanillaFix
{
	[HarmonyPatch]
	internal class Patch_FixHiddenCommandExecution
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")]
		private static void Pre_TerminalInterpreter_ReceiveCommand(LG_ComputerTerminalCommandInterpreter __instance, ref TERM_Command cmd)
		{
			//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_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected I4, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			TERM_Command val = cmd;
			switch (val - 1)
			{
			default:
				if ((int)val != 43)
				{
					break;
				}
				goto case 0;
			case 0:
			case 1:
			case 2:
			case 3:
			case 11:
			case 13:
			case 14:
			case 17:
			case 18:
			case 19:
			case 20:
			case 21:
			case 22:
			case 23:
			case 24:
			case 25:
			case 26:
			case 27:
			case 28:
				if (__instance.m_terminal.CommandIsHidden(cmd))
				{
					cmd = (TERM_Command)10;
				}
				break;
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 12:
			case 15:
			case 16:
				break;
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_FixScoutFreeze
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")]
		private static bool Prefix_Debug(ES_ScoutScream __instance)
		{
			if (((AgentAI)((ES_Base)__instance).m_ai).Target == null)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal class Patch_LG_SecurityDoor_Fix_EventsOnUnlockDoor_Powergenerator
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_SecurityDoor), "OnSyncDoorStatusChange")]
		private static void Pre_OnSyncDoorStatusChange(LG_SecurityDoor __instance, pDoorState state, bool isRecall)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//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_001e: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			eDoorStatus status = state.status;
			if ((status - 4 <= 1 || (int)status == 9) && (int)__instance.m_lastState.status == 6)
			{
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.LinkedToZoneData.EventsOnUnlockDoor, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_LockSecurityDoor_FixCustomText
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_SecurityDoor_Locks), "Setup", new Type[] { typeof(LG_SecurityDoor) })]
		private static void Post_LG_SecurityDoor_Locks_Setup(LG_SecurityDoor door, LG_SecurityDoor_Locks __instance)
		{
			LocalizedText customText = door.LinkedToZoneData.ProgressionPuzzleToEnter.CustomText;
			__instance.m_lockedWithNoKeyInteractionText = customText;
		}
	}
	[HarmonyPatch]
	internal class Debugger
	{
		public static Debugger Current { get; private set; } = new Debugger();


		public bool DEBUGGING { get; private set; }

		private Debugger()
		{
		}

		internal void Init()
		{
			_ = DEBUGGING;
		}
	}
	[HarmonyPatch]
	[HarmonyWrapSafe]
	internal class Patch_RepeatableCommandEventFix
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "SetupCommandEvents")]
		private static void Post_ResetupChainedPuzzleAfterExecution(LG_ComputerTerminalCommandInterpreter __instance)
		{
			//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_0052: Expected I4, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Invalid comparison between Unknown and I4
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Invalid comparison between Unknown and I4
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Invalid comparison between Unknown and I4
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Invalid comparison between Unknown and I4
			//IL_01df: 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_01ae: Invalid comparison between Unknown and I4
			uint num = 0u;
			if ((Object)(object)__instance.m_terminal.ConnectedReactor != (Object)null)
			{
				return;
			}
			if (__instance.m_terminal.SpawnNode.m_dimension.IsMainDimension)
			{
				LG_LayerType layerType = __instance.m_terminal.SpawnNode.LayerType;
				switch ((int)layerType)
				{
				case 0:
					num = RundownManager.ActiveExpedition.LevelLayoutData;
					break;
				case 1:
					num = RundownManager.ActiveExpedition.SecondaryLayout;
					break;
				case 2:
					num = RundownManager.ActiveExpedition.ThirdLayout;
					break;
				default:
					LegacyLogger.Error("Unimplemented layer type.");
					return;
				}
			}
			else
			{
				num = __instance.m_terminal.SpawnNode.m_dimension.DimensionData.LevelLayoutData;
			}
			LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(num);
			List<CustomTerminalCommand> val = null;
			int num2 = __instance.m_terminal.SpawnNode.m_zone.TerminalsSpawnedInZone.IndexOf(__instance.m_terminal);
			ExpeditionZoneData val2 = null;
			Enumerator<ExpeditionZoneData> enumerator = block.Zones.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ExpeditionZoneData current = enumerator.Current;
				if (current.LocalIndex == __instance.m_terminal.SpawnNode.m_zone.LocalIndex)
				{
					val2 = current;
					break;
				}
			}
			if (val2 == null)
			{
				LegacyLogger.Error("Cannot find target zone data.");
				return;
			}
			if (num2 >= val2.TerminalPlacements.Count)
			{
				LegacyLogger.Debug("RepeatableCommand: TerminalDataIndex >= TargetZoneData.TerminalPlacements.Count: found sec-door terminal, skipping");
				return;
			}
			val = val2.TerminalPlacements[num2].UniqueCommands;
			if (val.Count == 0)
			{
				return;
			}
			Enumerator<CustomTerminalCommand> enumerator2 = val.GetEnumerator();
			TERM_Command val3 = default(TERM_Command);
			string text = default(string);
			string text2 = default(string);
			while (enumerator2.MoveNext())
			{
				CustomTerminalCommand current2 = enumerator2.Current;
				if ((int)current2.SpecialCommandRule != 0 || !__instance.TryGetCommand(current2.Command, ref val3, ref text, ref text2) || ((int)val3 != 38 && (int)val3 != 39 && (int)val3 != 40 && (int)val3 != 41 && (int)val3 != 42))
				{
					continue;
				}
				ChainedPuzzleInstance OldCPInstance = null;
				List<WardenObjectiveEventData> commandEvents = current2.CommandEvents;
				for (int i = 0; i < commandEvents.Count && (commandEvents[i].ChainPuzzle == 0 || !__instance.m_terminal.TryGetChainPuzzleForCommand(val3, i, ref OldCPInstance) || !((Object)(object)OldCPInstance != (Object)null)); i++)
				{
				}
				if (!((Object)(object)OldCPInstance == (Object)null))
				{
					ChainedPuzzleInstance obj = OldCPInstance;
					obj.OnPuzzleSolved += Action.op_Implicit((Action)delegate
					{
						Helper.ResetChainedPuzzle(OldCPInstance);
					});
				}
			}
		}
	}
}
namespace LEGACY.Utils
{
	public delegate float EasingFunction(float t, float b, float c, float d);
	public delegate bool BoolCheck();
	internal static class CoroutineEase
	{
		private static IEnumerator DoEaseLocalScale(Transform trans, Vector3 startScale, Vector3 targetScale, float startTime, float duration, EasingFunction ease, Action onDone, BoolCheck checkAbort)
		{
			//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_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)
			bool doAbort = false;
			while (Clock.Time < startTime + duration && !doAbort)
			{
				doAbort = checkAbort?.Invoke() ?? false;
				float num = ease(Clock.Time - startTime, 0f, 1f, duration);
				trans.localScale = Vector3.Lerp(startScale, targetScale, num);
				yield return null;
			}
			trans.localScale = targetScale;
			if (!doAbort)
			{
				onDone?.Invoke();
			}
		}

		private static IEnumerator DoEaseLocalPos(Transform trans, Vector3 sourcePos, Vector3 targetPos, float startTime, float duration, EasingFunction ease, Action onDone, BoolCheck checkAbort)
		{
			//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_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)
			bool doAbort = false;
			while (Clock.Time < startTime + duration && !doAbort)
			{
				doAbort = checkAbort?.Invoke() ?? false;
				float num = ease(Clock.Time - startTime, 0f, 1f, duration);
				trans.localPosition = Vector3.Lerp(sourcePos, targetPos, num);
				yield return null;
			}
			trans.localPosition = targetPos;
			if (!doAbort)
			{
				onDone?.Invoke();
			}
		}

		private static IEnumerator DoEaseLocalRot(Transform trans, Vector3 sourceEuler, Vector3 targetEuler, float startTime, float duration, EasingFunction ease, Action onDone, BoolCheck checkAbort)
		{
			//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_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)
			bool doAbort = false;
			while (Clock.Time < startTime + duration && !doAbort)
			{
				doAbort = checkAbort?.Invoke() ?? false;
				float num = ease(Clock.Time - startTime, 0f, 1f, duration);
				trans.localEulerAngles = Vector3.Lerp(sourceEuler, targetEuler, num);
				yield return null;
			}
			trans.localEulerAngles = targetEuler;
			if (!doAbort)
			{
				onDone?.Invoke();
			}
		}

		internal static Coroutine EaseLocalScale(Transform trans, Vector3 startScale, Vector3 targetScale, float duration, EasingFunction ease = null, Action onDone = null, BoolCheck checkAbort = null)
		{
			//IL_0014: 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)
			EasingFunction ease2 = ease ?? new EasingFunction(Easing.EaseOutExpo);
			return CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DoEaseLocalScale(trans, startScale, targetScale, Clock.Time, duration, ease2, onDone, checkAbort)), (Action)null);
		}

		internal static Coroutine EaseLocalPos(Transform trans, Vector3 sourcePos, Vector3 targetPos, float duration, EasingFunction ease = null, Action onDone = null, BoolCheck checkAbort = null)
		{
			//IL_0014: 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)
			EasingFunction ease2 = ease ?? new EasingFunction(Easing.EaseOutExpo);
			return CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DoEaseLocalPos(trans, sourcePos, targetPos, Clock.Time, duration, ease2, onDone, checkAbort)), (Action)null);
		}

		internal static Coroutine EaseLocalRot(Transform trans, Vector3 sourceEuler, Vector3 targetEuler, float duration, EasingFunction ease = null, Action onDone = null, BoolCheck checkAbort = null)
		{
			//IL_0014: 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)
			EasingFunction ease2 = ease ?? new EasingFunction(Easing.EaseOutExpo);
			return CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DoEaseLocalRot(trans, sourceEuler, targetEuler, Clock.Time, duration, ease2, onDone, checkAbort)), (Action)null);
		}
	}
	public static class Helper
	{
		private static void ResetChild(iChainedPuzzleCore ICore)
		{
			CP_Bioscan_Core val = ((Il2CppObjectBase)ICore).TryCast<CP_Bioscan_Core>();
			if ((Object)(object)val != (Object)null)
			{
				((Il2CppObjectBase)val.m_spline).Cast<CP_Holopath_Spline>().SetSplineProgress(0f);
				((Il2CppObjectBase)val.PlayerScanner).Cast<CP_PlayerScanner>().ResetScanProgression(0f);
				return;
			}
			CP_Cluster_Core val2 = ((Il2CppObjectBase)ICore).TryCast<CP_Cluster_Core>();
			if ((Object)(object)val2 == (Object)null)
			{
				LegacyLogger.Error("ResetChild: found iChainedPuzzleCore that is neither CP_Bioscan_Core nor CP_Cluster_Core...");
				return;
			}
			((Il2CppObjectBase)val2.m_spline).Cast<CP_Holopath_Spline>().SetSplineProgress(0f);
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val2.m_childCores)
			{
				ResetChild(item);
			}
		}

		public static void ResetChainedPuzzle(ChainedPuzzleInstance chainedPuzzleInstance)
		{
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)chainedPuzzleInstance.m_chainedPuzzleCores)
			{
				ResetChild(item);
			}
			if (SNet.IsMaster)
			{
				chainedPuzzleInstance.AttemptInteract((eChainedPuzzleInteraction)2);
			}
		}

		public static bool TryGetComponent<T>(this GameObject obj, out T comp)
		{
			comp = obj.GetComponent<T>();
			return comp != null;
		}

		public static bool IsPlayerInLevel(PlayerAgent player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			return (int)player.Owner.Load<pGameState>().gameState == 10;
		}

		public static ChainedPuzzleInstance GetChainedPuzzleForCommandOnTerminal(LG_ComputerTerminal terminal, string command)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected I4, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Invalid comparison between Unknown and I4
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Invalid comparison between Unknown and I4
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Invalid comparison between Unknown and I4
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Invalid comparison between Unknown and I4
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Invalid comparison between Unknown and I4
			uint num = 0u;
			if (terminal.SpawnNode.m_dimension.IsMainDimension)
			{
				LG_LayerType layerType = terminal.SpawnNode.LayerType;
				switch ((int)layerType)
				{
				case 0:
					num = RundownManager.ActiveExpedition.LevelLayoutData;
					break;
				case 1:
					num = RundownManager.ActiveExpedition.SecondaryLayout;
					break;
				case 2:
					num = RundownManager.ActiveExpedition.ThirdLayout;
					break;
				default:
					LegacyLogger.Error("Unimplemented layer type.");
					return null;
				}
			}
			else
			{
				num = terminal.SpawnNode.m_dimension.DimensionData.LevelLayoutData;
			}
			LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(num);
			List<CustomTerminalCommand> val = null;
			List<LG_ComputerTerminal> terminalsSpawnedInZone = terminal.SpawnNode.m_zone.TerminalsSpawnedInZone;
			int num2 = terminalsSpawnedInZone.IndexOf(terminal);
			ExpeditionZoneData val2 = null;
			Enumerator<ExpeditionZoneData> enumerator = block.Zones.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ExpeditionZoneData current = enumerator.Current;
				if (current.LocalIndex == terminal.SpawnNode.m_zone.LocalIndex)
				{
					val2 = current;
					break;
				}
			}
			if (val2 == null)
			{
				LegacyLogger.Error("Cannot find target zone data.");
				return null;
			}
			if (val2.TerminalPlacements.Count != terminalsSpawnedInZone.Count)
			{
				LegacyLogger.Error("The numbers of terminal placement and spawn, skipped for the zone terminal.");
				return null;
			}
			val = val2.TerminalPlacements[num2].UniqueCommands;
			if (val.Count == 0)
			{
				return null;
			}
			List<WardenObjectiveEventData> val3 = null;
			TERM_Command val4 = (TERM_Command)0;
			Enumerator<CustomTerminalCommand> enumerator2 = val.GetEnumerator();
			string text = default(string);
			string text2 = default(string);
			while (enumerator2.MoveNext())
			{
				CustomTerminalCommand current2 = enumerator2.Current;
				if (current2.Command == command)
				{
					val3 = current2.CommandEvents;
					if (!terminal.m_command.TryGetCommand(current2.Command, ref val4, ref text, ref text2))
					{
						LegacyLogger.Error("Cannot get TERM_COMMAND for command {0} on the specified terminal.");
					}
					break;
				}
			}
			if (val3 == null || (int)val4 == 0)
			{
				return null;
			}
			if ((int)val4 != 38 && (int)val4 != 39 && (int)val4 != 40 && (int)val4 != 41 && (int)val4 != 42)
			{
				return null;
			}
			ChainedPuzzleInstance val5 = null;
			for (int i = 0; i < val3.Count && (val3[i].ChainPuzzle == 0 || !terminal.TryGetChainPuzzleForCommand(val4, i, ref val5) || !((Object)(object)val5 != (Object)null)); i++)
			{
			}
			return val5;
		}

		public static bool TryGetZoneEntranceSecDoor(LG_Zone zone, out LG_SecurityDoor door)
		{
			if ((Object)(object)zone == (Object)null)
			{
				door = null;
				return false;
			}
			if ((Object)(object)zone.m_sourceGate == (Object)null)
			{
				door = null;
				return false;
			}
			if (zone.m_sourceGate.SpawnedDoor == null)
			{
				door = null;
				return false;
			}
			door = ((Il2CppObjectBase)zone.m_sourceGate.SpawnedDoor).TryCast<LG_SecurityDoor>();
			return (Object)(object)door != (Object)null;
		}

		internal static bool isSecDoorToZoneOpened(LG_Zone zone14)
		{
			//IL_001d: 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_0029: Invalid comparison between Unknown and I4
			LG_SecurityDoor door = null;
			if (!TryGetZoneEntranceSecDoor(zone14, out door) || (Object)(object)door == (Object)null)
			{
				return false;
			}
			return (int)door.m_sync.GetCurrentSyncState().status == 10;
		}

		public static List<T> cast<T>(List<T> list)
		{
			List<T> list2 = new List<T>();
			Enumerator<T> enumerator = list.GetEnumerator();
			while (enumerator.MoveNext())
			{
				T current = enumerator.Current;
				list2.Add(current);
			}
			return list2;
		}

		private static eDimensionIndex GetCurrentDimensionIndex()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (PlayerManager.PlayerAgentsInLevel.Count <= 0)
			{
				throw new Exception("? You don't have any player agent in level? How could that happen?");
			}
			return ((Agent)PlayerManager.PlayerAgentsInLevel[0]).DimensionIndex;
		}

		public static void GetMinLayerAndLocalIndex(out LG_LayerType MinLayer, out eLocalZoneIndex MinLocalIndex)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between I4 and Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between I4 and Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected I4, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected I4, but got Unknown
			MinLayer = (LG_LayerType)2;
			MinLocalIndex = (eLocalZoneIndex)20;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (IsPlayerInLevel(current))
				{
					if ((int)MinLayer > (int)current.m_courseNode.LayerType)
					{
						MinLayer = (LG_LayerType)(int)current.m_courseNode.LayerType;
						MinLocalIndex = (eLocalZoneIndex)20;
					}
					if ((int)MinLocalIndex >= (int)current.m_courseNode.m_zone.LocalIndex)
					{
						MinLocalIndex = (eLocalZoneIndex)(int)current.m_courseNode.m_zone.LocalIndex;
					}
				}
			}
		}

		public static void GetMaxLayerAndLocalIndex(out LG_LayerType MaxLayer, out eLocalZoneIndex MaxLocalIndex)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between I4 and Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between I4 and Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected I4, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected I4, but got Unknown
			MaxLayer = (LG_LayerType)0;
			MaxLocalIndex = (eLocalZoneIndex)0;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (IsPlayerInLevel(current))
				{
					if ((int)MaxLayer < (int)current.m_courseNode.LayerType)
					{
						MaxLayer = (LG_LayerType)(int)current.m_courseNode.LayerType;
						MaxLocalIndex = (eLocalZoneIndex)0;
					}
					if ((int)MaxLocalIndex < (int)current.m_courseNode.m_zone.LocalIndex)
					{
						MaxLocalIndex = (eLocalZoneIndex)(int)current.m_courseNode.m_zone.LocalIndex;
					}
				}
			}
		}

		public static int GetMinAreaIndex(LG_Zone zone)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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)
			if ((Object)(object)zone == (Object)null)
			{
				return -1;
			}
			LG_LayerType type = zone.m_layer.m_type;
			eLocalZoneIndex localIndex = zone.LocalIndex;
			GetCurrentDimensionIndex();
			int num = zone.m_areas.Count;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (current.m_courseNode.LayerType != type || current.m_courseNode.m_zone.LocalIndex != localIndex)
				{
					continue;
				}
				int i = 0;
				for (List<LG_Area> areas = zone.m_areas; i < areas.Count; i++)
				{
					if (((Object)((Component)areas[i]).gameObject).GetInstanceID() == ((Object)((Component)current.m_courseNode.m_area).gameObject).GetInstanceID())
					{
						if (num > i)
						{
							num = i;
						}
						break;
					}
				}
			}
			return num;
		}

		public static LG_ComputerTerminal FindTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, int terminalIndex)
		{
			//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_0034: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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)
			LG_Zone val = null;
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val) || (Object)(object)val == (Object)null)
			{
				LegacyLogger.Error($"FindTerminal: Didn't find LG_Zone {dimensionIndex}, {layerType}, {localIndex}");
				return null;
			}
			if (val.TerminalsSpawnedInZone == null || terminalIndex >= val.TerminalsSpawnedInZone.Count)
			{
				LegacyLogger.Error($"FindTerminal: Invalid terminal index {terminalIndex} - {((val.TerminalsSpawnedInZone != null) ? val.TerminalsSpawnedInZone.Count : 0)} terminals are spawned in {dimensionIndex}, {layerType}, {localIndex}");
				return null;
			}
			if (terminalIndex >= 0)
			{
				return val.TerminalsSpawnedInZone[terminalIndex];
			}
			return null;
		}

		public static AIG_NodeCluster GetNodeFromDimensionPosition(eDimensionIndex dimensionIndex, 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_0012: 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)
			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))
			{
				LegacyLogger.Error("TryWarpTo : Position is not valid, try again inside an area.");
				return null;
			}
			return result;
		}
	}
	internal static class Json
	{
		private static readonly JsonSerializerOptions _setting;

		static Json()
		{
			_setting = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = false,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				IgnoreReadOnlyProperties = true
			};
			_setting.Converters.Add(new JsonStringEnumConverter());
			_setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
			_setting.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter);
		}

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

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

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

		public static void Load<T>(string filePath, out T config) where T : new()
		{
			config = Deserialize<T>(File.ReadAllText(filePath));
		}
	}
	internal static class LegacyLogger
	{
		private static ManualLogSource logger = Logger.CreateLogSource("LEGACYCore");

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

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

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

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

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

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

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

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)32, (object)str);
			}
		}
	}
	public class SpawnHibernateEnemiesEvent
	{
		public eWardenObjectiveEventTrigger Trigger { get; set; }

		public int Type { get; set; } = 170;


		public eDimensionIndex DimensionIndex { get; set; }

		public LG_LayerType Layer { get; set; }

		public eLocalZoneIndex LocalIndex { get; set; }

		public string WorldEventObjectFilter { get; set; } = "RANDOM";


		public uint EnemyID { get; set; }

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


		public float Delay { get; set; }

		public float Duration { get; set; } = 2f;

	}
	public class WeightedAreaSelector
	{
		private static readonly Dictionary<LG_Zone, WeightedAreaSelector> dict;

		private WeightedRandomBag<LG_Area> weightedRandomBag;

		public static WeightedAreaSelector Get(LG_Zone zone)
		{
			//IL_0035: 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_003c: 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_0059: Expected I4, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (!dict.ContainsKey(zone))
			{
				WeightedAreaSelector weightedAreaSelector = new WeightedAreaSelector();
				Enumerator<LG_Area> enumerator = zone.m_areas.GetEnumerator();
				while (enumerator.MoveNext())
				{
					LG_Area current = enumerator.Current;
					float num = 0f;
					LG_AreaSize size = current.m_size;
					switch (size - 1)
					{
					case 4:
						num = 7f;
						break;
					case 0:
						num = 20f;
						break;
					case 1:
						num = 30f;
						break;
					case 2:
						num = 35f;
						break;
					case 3:
						num = 45f;
						break;
					default:
						LegacyLogger.Error($"Unhandled LG_AreaSize: {current.m_size}. Won't build.");
						return null;
					}
					weightedAreaSelector.AddEntry(current, num);
				}
				dict.Add(zone, weightedAreaSelector);
			}
			return dict[zone];
		}

		public static WeightedAreaSelector Get(eDimensionIndex eDimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(eDimensionIndex, layerType, localIndex, ref val) || !Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return Get(val);
		}

		private WeightedAreaSelector()
		{
			weightedRandomBag = new WeightedRandomBag<LG_Area>();
		}

		private void AddEntry(LG_Area area, float weight)
		{
			weightedRandomBag.AddEntry(area, weight);
		}

		public LG_Area GetRandom()
		{
			return weightedRandomBag.GetRandom();
		}

		private static void OnBuildDone()
		{
		}

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

		static WeightedAreaSelector()
		{
			dict = new Dictionary<LG_Zone, WeightedAreaSelector>();
			LevelAPI.OnLevelCleanup += dict.Clear;
		}
	}
	public class WeightedRandomBag<T>
	{
		private struct Entry
		{
			public double accumulatedWeight;

			public T item;
		}

		private List<Entry> entries = new List<Entry>();

		private double accumulatedWeight;

		private Random rand = new Random();

		public void AddEntry(T item, double weight)
		{
			if (weight <= 0.0)
			{
				LegacyLogger.Error("AddEntry: no non-positive weight pls.");
				return;
			}
			accumulatedWeight += weight;
			entries.Add(new Entry
			{
				item = item,
				accumulatedWeight = accumulatedWeight
			});
		}

		public T GetRandom()
		{
			double num = rand.NextDouble() * accumulatedWeight;
			foreach (Entry entry in entries)
			{
				if (entry.accumulatedWeight >= num)
				{
					return entry.item;
				}
			}
			return default(T);
		}
	}
}
namespace LEGACY.LegacyOverride
{
	internal class NavMarkerManager
	{
		private Dictionary<string, GameObject> markerVisuals = new Dictionary<string, GameObject>();

		private Dictionary<string, NavMarker> navMarkers = new Dictionary<string, NavMarker>();

		private const bool USE_MARKER_VISUAL = true;

		public static NavMarkerManager Current { get; private set; } = new NavMarkerManager();


		private GameObject InstantiateMarkerVisual()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			GameObject obj = Object.Instantiate<GameObject>(Assets.ObjectiveMarker);
			float num = 0.16216217f;
			Transform transform = obj.transform;
			transform.localPosition += Vector3.up * num;
			return obj;
		}

		public void EnableMarkerAt(string markerName, GameObject target, float scale)
		{
			//IL_0047: 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_00be: 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 (navMarkers.ContainsKey(markerName))
			{
				navMarkers[markerName].SetVisible(true);
			}
			else
			{
				NavMarker val = GuiManager.NavMarkerLayer.PrepareGenericMarker(target);
				if ((Object)(object)val != (Object)null)
				{
					val.SetColor(new Color(0.855f, 0.482f, 0.976f));
					val.SetStyle((eNavMarkerStyle)14);
					val.SetVisible(true);
					navMarkers[markerName] = val;
				}
				else
				{
					LegacyLogger.Error("EnableMarkerAt: got null nav marker");
				}
			}
			GameObject val2 = null;
			if (markerVisuals.ContainsKey(markerName))
			{
				val2 = markerVisuals[markerName];
			}
			else
			{
				val2 = InstantiateMarkerVisual();
				val2.transform.localScale = new Vector3(scale, scale, scale);
				val2.transform.SetPositionAndRotation(target.transform.position, Quaternion.identity);
				markerVisuals[markerName] = val2;
			}
			CoroutineManager.BlinkIn(val2, 0f);
			LegacyLogger.Debug("EnableMarker: marker " + markerName + " enabled");
		}

		public void DisableMakrer(string markerName)
		{
			if (navMarkers.ContainsKey(markerName))
			{
				navMarkers[markerName].SetVisible(false);
			}
			if (!markerVisuals.ContainsKey(markerName))
			{
				LegacyLogger.Error("Marker " + markerName + " is not active");
				return;
			}
			CoroutineManager.BlinkOut(markerVisuals[markerName], 0f);
			LegacyLogger.Debug("DisableMakrer: marker " + markerName + " disabled");
		}

		public void Clear()
		{
			foreach (GameObject value in markerVisuals.Values)
			{
				Object.Destroy((Object)(object)value);
			}
			markerVisuals.Clear();
			navMarkers.Clear();
		}

		public GameObject FindTarget(int objectType, eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex, int instanceIndex)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			GameObject result = null;
			if (objectType == 0)
			{
				LG_ComputerTerminal val = Helper.FindTerminal(dimensionIndex, layer, localIndex, instanceIndex);
				if ((Object)(object)val != (Object)null)
				{
					result = ((Component)val).gameObject;
				}
			}
			else
			{
				LegacyLogger.Error($"Find Object of Type '{objectType}' is not implemented");
			}
			return result;
		}

		private NavMarkerManager()
		{
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}
	}
	internal static class LegacyOverrideManagers
	{
		internal static readonly string LEGACY_CONFIG_PATH = Path.Combine(MTFOPathAPI.CustomPath, "LegacyOverride");

		internal static void Init()
		{
			ElevatorCargoOverrideManager.Current.Init();
			FogBeaconSettingManager.Current.Init();
			EnemyTaggerSettingManager.Current.Init();
			SecDoorIntTextOverrideManager.Current.Init();
			((GenericExpeditionDefinitionManager<DimensionWarpPosition>)DimensionWarpPositionManager.Current).Init();
			ForceFailManager.Current.Init();
		}
	}
}
namespace LEGACY.LegacyOverride.SecDoorIntText
{
	public class PositionAndLookDir
	{
		public Vec3 Position { get; set; } = new Vec3();


		public int LookDir { get; set; }
	}
	public class WarpLocations
	{
		public string WorldEventObjectFilter { get; set; } = string.Empty;


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

	}
	public class DimensionWarpPosition
	{
		public eDimensionIndex DimensionIndex { get; set; }

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

	}
	internal class DimensionWarpPositionManager : GenericExpeditionDefinitionManager<DimensionWarpPosition>
	{
		public readonly List<PositionAndLookDir> DUMB = new List<PositionAndLookDir>();

		public static DimensionWarpPositionManager Current { get; private set; }

		protected override string DEFINITION_NAME => "DimensionWarp";

		public List<PositionAndLookDir> GetWarpPositions(eDimensionIndex dimensionIndex, string worldEventObjectFilter)
		{
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_00b6: 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)
			if ((int)GameStateManager.CurrentStateName != 10 || !base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData))
			{
				LegacyLogger.Error($"GetWarpPositions: Didn't find config with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}");
				return DUMB;
			}
			DimensionWarpPosition dimensionWarpPosition = base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.Find((DimensionWarpPosition def) => def.DimensionIndex == dimensionIndex);
			if (dimensionWarpPosition == null)
			{
				LegacyLogger.Error($"GetWarpPositions: Didn't find config for {dimensionIndex} with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}");
				return DUMB;
			}
			WarpLocations warpLocations = dimensionWarpPosition.WarpLocations.Find((WarpLocations position) => position.WorldEventObjectFilter == worldEventObjectFilter);
			if (warpLocations == null)
			{
				LegacyLogger.Error($"GetWarpPositions: Didn't find config for {worldEventObjectFilter} in {dimensionIndex} with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}");
				return DUMB;
			}
			return warpLocations.Locations;
		}

		private DimensionWarpPositionManager()
		{
		}

		static DimensionWarpPositionManager()
		{
			Current = new DimensionWarpPositionManager();
		}
	}
	public class DoorToZone
	{
		public eDimensionIndex DimensionIndex { get; set; }

		public LG_LayerType LayerType { get; set; }

		public eLocalZoneIndex LocalIndex { get; set; }

		public LocalizedText Prefix { get; set; }

		public LocalizedText Postfix { get; set; }

		public LocalizedText TextToReplace { get; set; }
	}
	public class LevelSecDoorIntTextOverride
	{
		public uint MainLevelLayout { get; set; }

		public List<DoorToZone> doorToZones { get; set; } = new List<DoorToZone>
		{
			new DoorToZone()
		};

	}
	internal class SecDoorIntTextOverrideManager
	{
		public static readonly SecDoorIntTextOverrideManager Current;

		private Dictionary<uint, LevelSecDoorIntTextOverride> SecDoorIntTextOverrides = new Dictionary<uint, LevelSecDoorIntTextOverride>();

		private LiveEditListener liveEditListener;

		private static readonly string CONFIG_PATH;

		internal LevelSecDoorIntTextOverride SettingForCurrentLevel { get; private set; }

		private void AddOverride(LevelSecDoorIntTextOverride _override)
		{
			if (_override != null)
			{
				if (SecDoorIntTextOverrides.ContainsKey(_override.MainLevelLayout))
				{
					LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout);
					SecDoorIntTextOverrides[_override.MainLevelLayout] = _override;
				}
				else
				{
					SecDoorIntTextOverrides.Add(_override.MainLevelLayout, _override);
				}
			}
		}

		public void Init()
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			if (!Directory.Exists(CONFIG_PATH))
			{
				Directory.CreateDirectory(CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(Json.Serialize(new LevelSecDoorIntTextOverride()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				Json.Load<LevelSecDoorIntTextOverride>(item, out var config);
				AddOverride(config);
			}
			LevelAPI.OnBuildStart += UpdateSetting;
			liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true);
			liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				LevelSecDoorIntTextOverride @override = Json.Deserialize<LevelSecDoorIntTextOverride>(content);
				AddOverride(@override);
				if (GameStateManager.IsInExpedition)
				{
					UpdateSetting();
				}
			});
		}

		private void UpdateSetting()
		{
			uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData;
			SettingForCurrentLevel = (SecDoorIntTextOverrides.ContainsKey(levelLayoutData) ? SecDoorIntTextOverrides[levelLayoutData] : null);
		}

		private SecDoorIntTextOverrideManager()
		{
		}

		static SecDoorIntTextOverrideManager()
		{
			CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "SecDoorIntText");
			Current = new SecDoorIntTextOverrideManager();
		}
	}
}
namespace LEGACY.LegacyOverride.Terminal
{
	public struct TerminalState
	{
		public bool Enabled;

		public TerminalState()
		{
			Enabled = true;
		}

		public TerminalState(bool Enabled)
		{
			this.Enabled = true;
			this.Enabled = Enabled;
		}

		public TerminalState(TerminalState o)
		{
			Enabled = true;
			Enabled = o.Enabled;
		}
	}
	public class TerminalStateManager
	{
		private Dictionary<IntPtr, TerminalWrapper> terminals = new Dictionary<IntPtr, TerminalWrapper>();

		public static TerminalStateManager Current { get; private set; } = new TerminalStateManager();


		public void SetupTerminal(LG_ComputerTerminal terminal)
		{
			uint num = EOSNetworking.AllotReplicatorID();
			if (num == 0)
			{
				LegacyLogger.Error("TerminalStateManager: replicator ID depleted, cannot setup terminal...");
				return;
			}
			TerminalWrapper value = TerminalWrapper.Instantiate(terminal, num);
			terminals[((Il2CppObjectBase)terminal).Pointer] = value;
		}

		public TerminalWrapper Get(LG_ComputerTerminal lgTerminal)
		{
			if (!terminals.ContainsKey(((Il2CppObjectBase)lgTerminal).Pointer))
			{
				return null;
			}
			return terminals[((Il2CppObjectBase)lgTerminal).Pointer];
		}

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

		private TerminalStateManager()
		{
			LevelAPI.OnLevelCleanup += Clear;
			LevelAPI.OnBuildStart += Clear;
		}
	}
	public class TerminalWrapper
	{
		public LG_ComputerTerminal lgTerminal { get; private set; }

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

		public void ChangeState(bool enabled)
		{
			stateReplicator.SetState(new TerminalState
			{
				Enabled = enabled
			});
		}

		private void OnStateChanged(TerminalState oldState, TerminalState newState, bool isRecall)
		{
			if (oldState.Enabled == newState.Enabled)
			{
				return;
			}
			LegacyLogger.Debug($"{lgTerminal.ItemKey} state: {newState.Enabled}");
			lgTerminal.OnProximityExit();
			Interact_ComputerTerminal componentInChildren = ((Component)lgTerminal).GetComponentInChildren<Interact_ComputerTerminal>(true);
			bool enabled = newState.Enabled;
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Behaviour)componentInChildren).enabled = enabled;
				((Interact_Base)componentInChildren).SetActive(enabled);
			}
			GUIX_VirtualSceneLink component = ((Component)lgTerminal).GetComponent<GUIX_VirtualSceneLink>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_virtualScene != (Object)null)
			{
				GUIX_VirtualCamera virtualCamera = component.m_virtualScene.virtualCamera;
				virtualCamera.SetFovAndClip(virtualCamera.paramCamera.fieldOfView, enabled ? 0.3f : 0f, enabled ? 1000f : 0f);
			}
			if ((Object)(object)lgTerminal.m_text != (Object)null)
			{
				((Behaviour)lgTerminal.m_text).enabled = enabled;
			}
			if (!enabled)
			{
				PlayerAgent localInteractionSource = lgTerminal.m_localInteractionSource;
				if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger)
				{
					lgTerminal.ExitFPSView();
				}
			}
		}

		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;
			return terminalWrapper;
		}

		private TerminalWrapper()
		{
		}
	}
}
namespace LEGACY.LegacyOverride.FogBeacon
{
	public class RepellerSphereSetting
	{
		public bool InfiniteDuration { get; set; }

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


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


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

	}
	public class FogBeaconSetting
	{
		public uint MainLevelLayout { get; set; }

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


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


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


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

	}
	internal class FogBeaconSettingManager
	{
		public static readonly FogBeaconSettingManager Current;

		private Dictionary<uint, FogBeaconSetting> fogBeaconSettings = new Dictionary<uint, FogBeaconSetting>();

		private LiveEditListener liveEditListener;

		private static readonly string CONFIG_PATH;

		internal FogBeaconSetting SettingForCurrentLevel { get; private set; }

		private void AddOverride(FogBeaconSetting _override)
		{
			if (_override != null)
			{
				if (fogBeaconSettings.ContainsKey(_override.MainLevelLayout))
				{
					LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout);
					fogBeaconSettings[_override.MainLevelLayout] = _override;
				}
				else
				{
					fogBeaconSettings.Add(_override.MainLevelLayout, _override);
				}
			}
		}

		public void Init()
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			if (!Directory.Exists(CONFIG_PATH))
			{
				Directory.CreateDirectory(CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(Json.Serialize(new FogBeaconSetting()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				Json.Load<FogBeaconSetting>(item, out var config);
				AddOverride(config);
			}
			LevelAPI.OnBuildStart += UpdateSetting;
			liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true);
			liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				FogBeaconSetting @override = Json.Deserialize<FogBeaconSetting>(content);
				AddOverride(@override);
				if (GameStateManager.IsInExpedition)
				{
					UpdateSetting();
				}
			});
		}

		private void UpdateSetting()
		{
			uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData;
			SettingForCurrentLevel = (fogBeaconSettings.ContainsKey(levelLayoutData) ? fogBeaconSettings[levelLayoutData] : null);
			LegacyLogger.Debug($"FogBeaconSettingManager: updated setting for level with main level layout id {levelLayoutData}");
		}

		private FogBeaconSettingManager()
		{
		}

		static FogBeaconSettingManager()
		{
			CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "FogBeaconSetting");
			Current = new FogBeaconSettingManager();
		}
	}
}
namespace LEGACY.LegacyOverride.ElevatorCargo
{
	internal class ElevatorCargoOverrideManager
	{
		public static readonly ElevatorCargoOverrideManager Current;

		private Dictionary<uint, LevelElevatorCargo> elevatorCargos = new Dictionary<uint, LevelElevatorCargo>();

		private LiveEditListener liveEditListener;

		private static readonly string CONFIG_PATH;

		private void AddOverride(LevelElevatorCargo _override)
		{
			if (_override != null)
			{
				if (elevatorCargos.ContainsKey(_override.MainLevelLayout))
				{
					LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout);
					elevatorCargos[_override.MainLevelLayout] = _override;
				}
				else
				{
					elevatorCargos.Add(_override.MainLevelLayout, _override);
				}
			}
		}

		public void Init()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			if (!Directory.Exists(CONFIG_PATH))
			{
				Directory.CreateDirectory(CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(Json.Serialize(new LevelElevatorCargo()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				Json.Load<LevelElevatorCargo>(item, out var config);
				AddOverride(config);
			}
			liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true);
			liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				LevelElevatorCargo @override = Json.Deserialize<LevelElevatorCargo>(content);
				AddOverride(@override);
			});
		}

		internal LevelElevatorCargo GetLevelElevatorCargoItems(uint MainLevelLayout)
		{
			if (!elevatorCargos.ContainsKey(MainLevelLayout))
			{
				return null;
			}
			return elevatorCargos[MainLevelLayout];
		}

		private ElevatorCargoOverrideManager()
		{
		}

		static ElevatorCargoOverrideManager()
		{
			CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "ElevatorCargoOverride");
			Current = new ElevatorCargoOverrideManager();
		}
	}
	public enum ItemType
	{
		Consumable,
		BigPickup
	}
	public class ElevatorCargoItem
	{
		public uint ItemID { get; set; }

		public ItemType ItemType { get; set; }
	}
	public class LevelElevatorCargo
	{
		public uint MainLevelLayout { get; set; }

		public bool ForceDisable { get; set; }

		public List<ElevatorCargoItem> ElevatorCargoItems { get; set; } = new List<ElevatorCargoItem>();

	}
}
namespace LEGACY.LegacyOverride.Patches
{
	[HarmonyPatch]
	internal class CustomizeSecDoorInteractionText
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_SecurityDoor_Locks), "OnDoorState")]
		private static void Post_Customize_SecDoor_Interaction_Text(pDoorState state, LG_SecurityDoor_Locks __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_0116: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			LevelSecDoorIntTextOverride settingForCurrentLevel = SecDoorIntTextOverrideManager.Current.SettingForCurrentLevel;
			if (settingForCurrentLevel == null || ((int)state.status != 9 && (int)state.status != 5))
			{
				return;
			}
			int num = settingForCurrentLevel.doorToZones.FindIndex((DoorToZone door) => door.DimensionIndex == __instance.m_door.Gate.DimensionIndex && door.LayerType == __instance.m_door.LinksToLayerType && door.LocalIndex == __instance.m_door.LinkedToZoneData.LocalIndex);
			if (num != -1)
			{
				DoorToZone doorToZone = settingForCurrentLevel.doorToZones[num];
				_ = __instance.m_door;
				Interact_Timed intOpenDoor = __instance.m_intOpenDoor;
				string text = LocalizedText.op_Implicit(doorToZone.Prefix);
				string text2 = LocalizedText.op_Implicit(doorToZone.Postfix);
				string text3 = LocalizedText.op_Implicit(doorToZone.TextToReplace);
				if (string.IsNullOrEmpty(text))
				{
					text = string.Empty;
				}
				if (string.IsNullOrEmpty(text2))
				{
					text2 = string.Empty;
				}
				if (string.IsNullOrEmpty(text3))
				{
					text3 = intOpenDoor.InteractionMessage;
				}
				intOpenDoor.InteractionMessage = text + "\n" + text3 + "\n" + text2;
				LegacyLogger.Debug($"SecDoorIntTextOverride: Override IntText. {doorToZone.LocalIndex}, {doorToZone.LayerType}, {doorToZone.DimensionIndex}");
			}
		}
	}
	[HarmonyPatch]
	internal class RundownSelectionCustomization
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageRundown_New), "Setup")]
		private static void Post_CM_PageRundown_New(CM_PageRundown_New __instance)
		{
			//IL_003f: 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_0069: 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_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)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			GameSetupDataBlock block = GameDataBlockBase<GameSetupDataBlock>.GetBlock(1u);
			if (block.RundownIdsToLoad.Count > 1 && block.RundownIdsToLoad.Count == 2)
			{
				((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions)[0] = new Vector3(-320f, 75f, 0f);
				((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions)[1] = new Vector3(320f, 0f, 0f);
				Vector3 zero = Vector3.zero;
				for (int i = block.RundownIdsToLoad.Count; i < ((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions).Count; i++)
				{
					zero = ((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions)[i];
					((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions)[i] = new Vector3(zero.x, -10000f, zero.z);
				}
				zero = __instance.m_textRundownHeaderTop.transform.position;
				__instance.m_textRundownHeaderTop.transform.position = new Vector3(zero.x, -350f, zero.z);
			}
		}

		private static void SetSelectionScale(CM_PageRundown_New p)
		{
			//IL_0055: 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_007e: 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_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)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0111: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			GameSetupDataBlock block = GameDataBlockBase<GameSetupDataBlock>.GetBlock(1u);
			if (block.RundownIdsToLoad.Count > 1 && block.RundownIdsToLoad.Count == 2)
			{
				CM_RundownSelection obj = p.m_rundownSelections[0];
				CM_RundownSelection val = p.m_rundownSelections[1];
				((Component)obj).transform.localScale = new Vector3(2f, 2f, 2f) * 1.625f;
				((Component)val).transform.localScale = new Vector3(1.25f, 1.25f, 1.25f) * 1.5f;
				Transform transform = obj.m_rundownText.transform;
				Quaternion localRotation = (val.m_rundownText.transform.localRotation = Quaternion.AngleAxis(45f, Vector3.right));
				transform.localRotation = localRotation;
				obj.m_rundownText.transform.localPosition = Vector3.up * 60f + Vector3.right * 20f;
				val.m_rundownText.transform.localPosition = Vector3.up * 85f + Vector3.left * 25f;
				Transform transform2 = ((Component)obj).transform;
				localRotation = (((Component)val).transform.localRotation = Quaternion.AngleAxis(-45f, Vector3.right));
				transform2.localRotation = localRotation;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageRundown_New), "UpdateRundownSelectionButton")]
		private static void Post_UpdateRundownSelectionButton(CM_PageRundown_New __instance)
		{
			SetSelectionScale(__instance);
		}

		private static IEnumerator reverseReveal(CM_PageRundown_New p, bool hosting, Transform guixSurfaceTransform)
		{
			float arrowScale = p.m_tierSpacing * 5f * p.m_tierSpaceToArrowScale;
			if (hosting)
			{
				CoroutineManager.BlinkIn(p.m_buttonConnect, 0f, (Transform)null);
				yield return (object)new WaitForSeconds(0.1f);
				yield return (object)new WaitForSeconds(0.24f);
				((RectTransformComp)p.m_buttonConnect).SetVisible(false);
			}
			CM_PageBase.PostSound(EVENTS.MENU_SURFACE_LEVEL_MOVE_UP, "");
			yield return CoroutineEase.EaseLocalPos(guixSurfaceTransform, Vector3.zero, new Vector3(0f, 650f, 0f), 0.5f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null);
			yield return (object)new WaitForSeconds(0.1f);
			CM_PageBase.PostSound(EVENTS.MENU_SURFACE_LEVEL_SHRINK, "");
			CoroutineEase.EaseLocalScale(p.m_textRundownHeader.transform, Vector3.one, new Vector3(0.6f, 0.6f, 0.6f), 0.2f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null);
			yield return CoroutineEase.EaseLocalScale(guixSurfaceTransform, Vector3.one, new Vector3(0.2f, 0.2f, 0.2f), 0.2f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null);
			yield return (object)new WaitForSeconds(0.1f);
			CoroutineEase.EaseLocalPos(p.m_textRundownHeader.transform, p.m_textRundownHeader.transform.localPosition, p.m_rundownHeaderPos, 0.2f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null);
			CoroutineManager.BlinkIn(p.m_rundownIntelButton, 0f, (Transform)null);
			yield return (object)new WaitForSeconds(0.2f);
			CM_PageBase.PostSound(EVENTS.MENU_SURFACE_LEVEL_TURN, "");
			yield return CoroutineEase.EaseLocalRot(guixSurfaceTransform, Vector3.zero, new Vector3(70f, 0f, 0f), 0.3f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null);
			p.m_verticalArrow.SetActive(true);
			yield return (object)new WaitForSeconds(0.5f);
			CoroutineManager.BlinkIn(((Component)p.m_tierMarkerSectorSummary).gameObject, 0f);
			CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_5, "");
			yield return (object)new WaitForSeconds(0.5f);
			CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_SPINE_START, "");
			CoroutineEase.EaseLocalScale(p.m_verticalArrow.transform, new Vector3(1f, 0f, 1f), new Vector3(1f, arrowScale, 1f), 4.3f, (EasingFunction)Easing.LinearTween, (Action)delegate
			{
				CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_SPINE_STOP, "");
			}, (BoolCheck)null);
			float tierMarkerDelay = 0.6f;
			yield return (object)new WaitForSeconds(0.2f);
			CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_3, "");
			((Component)p.m_guix_Tier3).gameObject.SetActive(true);
			for (int i = 0; i < p.m_expIconsTier3.Count; i++)
			{
				CoroutineManager.BlinkIn(((Component)p.m_expIconsTier3[i]).gameObject, (float)i * 0.1f);
			}
			if (p.m_expIconsTier3.Count > 0)
			{
				p.m_tierMarker3.SetVisible(true, tierMarkerDelay);
			}
			yield return (object)new WaitForSeconds(1f);
			CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_5, "");
			((Component)p.m_guix_Tier5).gameObject.SetActive(true);
			for (int j = 0; j < p.m_expIconsTier5.Count; j++)
			{
				CoroutineManager.BlinkIn(((Component)p.m_expIconsTier5[j]).gameObject, (float)j * 0.1f);
			}
			if (p.m_expIconsTier5.Count > 0)
			{
				p.m_tierMarker5.SetVisible(true, tierMarkerDelay);
			}
			yield return (object)new WaitForSeconds(1f);
			CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_4, "");
			((Component)p.m_guix_Tier4).gameObject.SetActive(true);
			for (int k = 0; k < p.m_expIconsTier4.Count; k++)
			{
				CoroutineManager.BlinkIn(((Component)p.m_expIconsTier4[k]).gameObject, (float)k * 0.1f);
			}
			if (p.m_expIconsTier4.Count > 0)
			{
				p.m_tierMarker4.SetVisible(true, tierMarkerDelay);
			}
			yield return (object)new WaitForSeconds(1f);
			CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_2, "");
			((Component)p.m_guix_Tier2).gameObject.SetActive(true);
			for (int l = 0; l < p.m_expIconsTier2.Count; l++)
			{
				CoroutineManager.BlinkIn(((Component)p.m_expIconsTier2[l]).gameObject, (float)l * 0.1f);
			}
			if (p.m_expIconsTier2.Count > 0)
			{
				p.m_tierMarker2.SetVisible(true, tierMarkerDelay);
			}
			yield return (object)new WaitForSeconds(1f);
			CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_1, "");
			((Component)p.m_guix_Tier1).gameObject.SetActive(true);
			for (int m = 0; m < p.m_expIconsTier1.Count; m++)
			{
				CoroutineManager.BlinkIn(((Component)p.m_expIconsTier1[m]).gameObject, (float)m * 0.1f);
			}
			if (p.m_expIconsTier1.Count > 0)
			{
				p.m_tierMarker1.SetVisible(true, tierMarkerDelay);
			}
			yield return (object)new WaitForSeconds(1f);
			((Component)p.m_joinOnServerIdText).gameObject.SetActive(true);
			CoroutineManager.BlinkIn(p.m_aboutTheRundownButton, 0f, (Transform)null);
			CoroutineManager.BlinkIn(p.m_discordButton, 0.1f, (Transform)null);
			if (SNet.IsMaster || !SNet.IsInLobby)
			{
				CoroutineManager.BlinkIn(p.m_matchmakeAllButton, 0.2f, (Transform)null);
			}
			p.m_selectionIsRevealed = true;
			p.CheckClipboard();
		}
	}
	[HarmonyPatch]
	internal class DisableExpeditionFailPageArtifactDisplay
	{
		private class CustomExpeditionFailedSequence
		{
			private CM_PageExpeditionFail page;

			public CustomExpeditionFailedSequence(CM_PageExpeditionFail page)
			{
				this.page = page;
			}

			public IEnumerator CustomFailedSequence()
			{
				yield return (object)new WaitForSeconds(0.5f);
				((Component)page.m_bgCortex_text).gameObject.SetActive(false);
				page.m_bgCortex_textBoxSmall.SetActive(false);
				page.m_bgCortex_textBoxLarge.SetActive(false);
				((Component)page.m_returnToLobby_text).gameObject.SetActive(false);
				CM_PageBase.PostSound(EVENTS.PLAY_01_FIRST_TEXT_APPEAR, "");
				yield return CoroutineManager.BlinkIn(page.m_bgCortex_logo, 0f);
				yield return (object)new WaitForSeconds(0.3f);
				CM_PageBase.PostSound(EVENTS.PLAY_01_FIRST_TEXT_APPEAR, "");
				yield return CoroutineManager.BlinkIn(page.m_bgCortex_text, 0f, (Transform)null);
				yield return (object)new WaitForSeconds(0.4f);
				CoroutineManager.BlinkIn(page.m_bgCortex_textBoxSmall, 0f);
				CoroutineManager.BlinkIn(page.m_bgCortex_textBoxLarge, 0.15f);
				yield return (object)new WaitForSeconds(0.5f);
				yield return CoroutineManager.BlinkOut(page.m_bgCortex_textBoxLarge, 0f);
				yield return CoroutineManager.BlinkOut(page.m_bgCortex_textBoxSmall, 0f);
				((Component)page.m_bgCortex_text).gameObject.SetActive(false);
				yield return CoroutineManager.BlinkOut(page.m_bgCortex_logo, 0f);
				yield return (object)new WaitForSeconds(1f);
				CM_PageBase.PostSound(EVENTS.PLAY_06_MAIN_MENU_LAUNCH, "");
				((Component)page.m_bgScare).gameObject.SetActive(true);
				page.m_bgScare.Play();
				yield return (object)new WaitForSeconds(0.5f);
				((Component)page.m_bgScare).gameObject.SetActive(false);
				yield return CoroutineManager.BlinkIn(((Component)page.m_missionFailed_text).gameObject, 0f);
				yield return (object)new WaitForSeconds(0.2f);
				yield return CoroutineManager.BlinkIn(((Component)page.m_returnToLobby_text).gameObject, 0f);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CM_PageExpeditionFail), "OnEnable")]
		private static bool Pre_CM_PageExpeditionFail(CM_PageExpeditionFail __instance)
		{
			if (((CM_PageBase)__instance).m_isSetup)
			{
				CellSound.StopAll();
				CellSound.AllSoundsStoppedThisSession = true;
				CM_PageBase.PostSound(EVENTS.MUSIC_EXPEDITION_FAILED, "");
				((RectTransformComp)__instance.m_ArtifactInventoryDisplay).Setup();
				__instance.m_ArtifactInventoryDisplay.SetArtifactValuesFromInventory(BoosterImplantManager.ArtifactInventory);
				((Component)__instance.m_missionFailed_text).gameObject.SetActive(false);
				((Component)__instance.m_artifactInfo_text).gameObject.SetActive(false);
				__instance.m_btnRestartCheckpoint.SetText(Text.Get(916u));
				if (SNet.IsMaster)
				{
					__instance.m_btnRestartCheckpoint.SetButtonEnabled(true);
					__instance.m_btnGoToLobby.SetButtonEnabled(true);
					__instance.m_btnGoToLobby.SetText(Text.Get(917u));
				}
				else
				{
					__instance.m_btnRestartCheckpoint.SetButtonEnabled(false);
					__instance.m_btnGoToLobby.SetButtonEnabled(false);
					__instance.m_btnGoToLobby.SetText(Text.Get(918u));
				}
				((Component)__instance.m_btnGoToLobby).gameObject.SetActive(false);
				((Component)__instance.m_btnRestartCheckpoint).gameObject.SetActive(false);
				__instance.m_lobbyButtonVisible = false;
				__instance.m_showLobbybuttonTimer = Clock.Time + 3f;
				((RectTransformComp)__instance.m_ArtifactInventoryDisplay).SetVisible(false);
				((CM_PageBase)__instance).StartPageTransitionRoutine(CollectionExtensions.WrapToIl2Cpp(new CustomExpeditionFailedSequence(__instance).CustomFailedSequence()));
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal class SetupBigPickupItemWithItemId
	{
		private static List<GameObject> go;

		private static void SetupAsObserver(LG_PickupItem __instance)
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			EnemyTaggerSetting setting = EnemyTaggerSettingManager.Current.SettingForCurrentLevel;
			CarryItemPickup_Core componentInChildren = ((Component)__instance.m_root).GetComponentInChildren<CarryItemPickup_Core>();
			Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>();
			LG_PickupItem_Sync obj = ((Il2CppObjectBase)componentInChildren.m_sync).Cast<LG_PickupItem_Sync>();
			EnemyTaggerComponent tagger = ((Component)componentInChildren).gameObject.AddComponent<EnemyTaggerComponent>();
			tagger.Parent = componentInChildren;
			((Component)tagger).gameObject.SetActive(true);
			((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
			tagger.MaxTagPerScan = setting.MaxTagPerScan;
			tagger.TagInterval = setting.TagInterval;
			tagger.TagRadius = setting.TagRadius;
			tagger.WarmupTime = setting.WarmupTime;
			GameObject obsVisual = null;
			if (setting.UseVisual)
			{
				obsVisual = Object.Instantiate<GameObject>(Assets.OBSVisual, ((Component)__instance).transform);
				obsVisual.transform.localScale = new Vector3(setting.TagRadius, setting.TagRadius, setting.TagRadius);
				obsVisual.SetActive(false);
			}
			obj.OnSyncStateChange += Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>.op_Implicit((Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>)delegate(ePickupItemStatus status, pPickupPlacement placement, PlayerAgent playerAgent, bool isRecall)
			{
				//IL_0000: 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_0005: Invalid comparison between Unknown and I4
				//IL_006a: 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_0070: 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)
				if ((int)status != 0)
				{
					if ((int)status == 1)
					{
						((Component)tagger).gameObject.SetActive(true);
						tagger.PickedByPlayer = playerAgent;
						tagger.ChangeState((!setting.TagWhenHold) ? eEnemyTaggerState.Inactive : eEnemyTaggerState.Active_Warmup);
						((Interact_Timed)interact).InteractDuration = setting.TimeToPlace;
						if ((Object)(object)obsVisual != (Object)null && obsVisual.active)
						{
							CoroutineManager.BlinkOut(obsVisual, 0f);
						}
					}
				}
				else
				{
					tagger.PickedByPlayer = null;
					tagger.ChangeState((!setting.TagWhenPlaced) ? eEnemyTaggerState.Inactive : eEnemyTaggerState.Active_Warmup);
					((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
					if ((Object)(object)obsVisual != (Object)null)
					{
						obsVisual.gameObject.transform.SetPositionAndRotation(placement.position, placement.rotation);
						if (!obsVisual.active)
						{
							CoroutineManager.BlinkIn(obsVisual, tagger.WarmupTime);
						}
					}
				}
			});
		}

		private static void SetupAsFogBeacon(LG_PickupItem __instance)
		{
			//IL_000b: 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_00e0: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: 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)
			FogRepeller_Sphere val = new GameObject("FogInstance_Beacon_Fake").AddComponent<FogRepeller_Sphere>();
			val.InfiniteDuration = false;
			val.LifeDuration = 99999f;
			val.GrowDuration = 99999f;
			val.ShrinkDuration = 99999f;
			val.Range = 1f;
			FogBeaconSetting setting = FogBeaconSettingManager.Current.SettingForCurrentLevel;
			FogRepeller_Sphere fogRepHold = new GameObject("FogInstance_Beacon_SmallLayer").AddComponent<FogRepeller_Sphere>();
			fogRepHold.InfiniteDuration = setting.RSHold.InfiniteDuration;
			fogRepHold.GrowDuration = setting.RSHold.GrowDuration;
			fogRepHold.ShrinkDuration = setting.RSHold.ShrinkDuration;
			fogRepHold.Range = setting.RSHold.Range;
			fogRepHold.Offset = Vector3.zero;
			FogRepeller_Sphere fogRepPlaced = new GameObject("FogInstance_Beacon_BigLayer").AddComponent<FogRepeller_Sphere>();
			fogRepPlaced.InfiniteDuration = setting.RSPlaced.InfiniteDuration;
			fogRepPlaced.GrowDuration = setting.RSPlaced.GrowDuration;
			fogRepPlaced.ShrinkDuration = setting.RSPlaced.ShrinkDuration;
			fogRepPlaced.Range = setting.RSPlaced.Range;
			fogRepPlaced.Offset = Vector3.zero;
			CarryItemPickup_Core componentInChildren = ((Component)__instance.m_root).GetComponentInChildren<CarryItemPickup_Core>();
			HeavyFogRepellerPickup val2 = ((Il2CppObjectBase)componentInChildren).Cast<HeavyFogRepellerPickup>();
			iCarryItemWithGlobalState val3 = default(iCarryItemWithGlobalState);
			byte byteId = default(byte);
			if (CarryItemWithGlobalStateManager.TryCreateItemInstance((eCarryItemWithGlobalStateType)0, __instance.m_root, ref val3, ref byteId))
			{
				pItemData_Custom customData = ((Item)val2).GetCustomData();
				customData.byteId = byteId;
				pItemData_Custom val4 = customData;
				((Item)val2).SetCustomData(val4, true);
			}
			HeavyFogRepellerGlobalState val5 = ((Il2CppObjectBase)val3).Cast<HeavyFogRepellerGlobalState>();
			((Component)fogRepHold).transform.SetParent(((Component)val5).transform, false);
			((Component)fogRepPlaced).transform.SetParent(((Component)val5).transform, false);
			val5.m_repellerSphere = val;
			fogRepHold.m_sphereAllocator = new FogSphereAllocator();
			fogRepPlaced.m_sphereAllocator = new FogSphereAllocator();
			Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>();
			((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
			val5.CallbackOnStateChange += Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>.op_Implicit((Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>)delegate(pCarryItemWithGlobalState_State oldState, pCarryItemWithGlobalState_State newState, bool isRecall)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Invalid comparison between Unknown and I4
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Invalid comparison between Unknown and I4
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				eHeavyFogRepellerStatus val6 = (eHeavyFogRepellerStatus)newState.status;
				if ((int)val6 != 1)
				{
					if ((int)val6 == 2)
					{
						FogRepeller_Sphere obj = fogRepHold;
						if (obj != null)
						{
							obj.StopRepelling();
						}
						FogRepeller_Sphere obj2 = fogRepPlaced;
						if (obj2 != null)
						{
							obj2.StartRepelling();
						}
						((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
					}
				}
				else
				{
					FogRepeller_Sphere obj3 = fogRepHold;
					if (obj3 != null)
					{
						obj3.StartRepelling();
					}
					if (oldState.status != 0)
					{
						FogRepeller_Sphere obj4 = fogRepPlaced;
						if (obj4 != null)
						{
							obj4.StopRepelling();
						}
					}
					((Interact_Timed)interact).InteractDuration = setting.TimeToPlace;
				}
				if (isRecall)
				{
					FogRepeller_Sphere obj5 = fogRepHold;
					if (obj5 != null)
					{
						obj5.KillRepellerInstantly();
					}
					FogRepeller_Sphere obj6 = fogRepPlaced;
					if (obj6 != null)
					{
						obj6.KillRepellerInstantly();
					}
				}
			});
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_PickupItem), "SetupBigPickupItemWithItemId")]
		private static void Post_SetupBigPickupItemWithItemId(LG_PickupItem __instance, uint itemId)
		{
			switch (itemId)
			{
			case 233u:
				SetupAsFogBeacon(__instance);
				break;
			case 234u:
			case 235u:
			case 236u:
				SetupAsObserver(__instance);
				break;
			}
		}

		private static void Clear()
		{
			go.ForEach((Action<GameObject>)Object.Destroy);
			go.Clear();
		}

		static SetupBigPickupItemWithItemId()
		{
			go = new List<GameObject>();
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
		}
	}
	[HarmonyPatch]
	internal class ElevatorCargoOverride
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ElevatorCargoCage), "SpawnObjectiveItemsInLandingArea")]
		private static bool Pre_ElevatorCargoOverride(ElevatorCargoCage __instance)
		{
			LevelElevatorCargo levelElevatorCargoItems = ElevatorCargoOverrideManager.Current.GetLevelElevatorCargoItems(RundownManager.ActiveExpedition.LevelLayoutData);
			if (levelElevatorCargoItems == null)
			{
				return true;
			}
			if (levelElevatorCargoItems.ForceDisable)
			{
				ElevatorRide.Current.m_cargoCageInUse = false;
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ElevatorCargoCage), "SpawnObjectiveItemsInLandingArea")]
		private static void Post_ElevatorCargoOverride(ElevatorCargoCage __instance)
		{
			LevelElevatorCargo levelElevatorCargoItems = ElevatorCargoOverrideManager.Current.GetLevelElevatorCargoItems(RundownManager.ActiveExpedition.LevelLayoutData);
			if (levelElevatorCargoItems == null || levelElevatorCargoItems.ElevatorCargoItems.Count < 1 || levelElevatorCargoItems.ForceDisable)
			{
				return;
			}
			foreach (ElevatorCargoItem elevatorCargoItem 

plugins/net6/LGTuner.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Text.Json.Serialization;
using AssetShards;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Expedition;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LGTuner.Configs;
using LGTuner.Manager;
using LGTuner.Utils;
using LevelGeneration;
using LevelGeneration.Core;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("LGTuner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LGTuner")]
[assembly: AssemblyTitle("LGTuner")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace LGTuner
{
	public static class BuilderInfo
	{
		private static readonly List<Complex> _extraComplexResourceToLoad = new List<Complex>();

		public static IEnumerable<Complex> ExtraComplexResourceToLoad => _extraComplexResourceToLoad;

		public static ComplexResourceSetDataBlock ComplexResourceSet { get; private set; }

		public static int GridSize { get; private set; }

		public static int GridCenter { get; private set; }

		public static int GridZeroOffset { get; private set; }

		public static float AltitudeOffset { get; private set; }

		public static LayoutConfig MainLayer { get; private set; }

		public static LayoutConfig SecondaryLayer { get; private set; }

		public static LayoutConfig ThirdLayer { get; private set; }

		public static LayoutConfig[] DimensionLayer { get; private set; } = Array.Empty<LayoutConfig>();


		internal static void OnResourceSetSelected()
		{
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			ComplexResourceSet = Builder.ComplexResourceSetBlock;
			GridSize = ComplexResourceSet.LevelGenConfig.GridSize;
			GridCenter = GridSize / 2;
			GridZeroOffset = -GridCenter;
			AltitudeOffset = ComplexResourceSet.LevelGenConfig.AltitudeOffset;
			MainLayer = null;
			SecondaryLayer = null;
			ThirdLayer = null;
			DimensionLayer = new LayoutConfig[Enum.GetValues(typeof(eDimensionIndex)).Length];
			_extraComplexResourceToLoad.Clear();
			ExpeditionInTierData activeExpedition = RundownManager.ActiveExpedition;
			if (ConfigManager.TryGetConfig(activeExpedition.LevelLayoutData, out var config))
			{
				MainLayer = config;
			}
			if (activeExpedition.SecondaryLayerEnabled && ConfigManager.TryGetConfig(activeExpedition.SecondaryLayout, out var config2))
			{
				SecondaryLayer = config2;
			}
			if (activeExpedition.ThirdLayerEnabled && ConfigManager.TryGetConfig(activeExpedition.ThirdLayout, out var config3))
			{
				ThirdLayer = config3;
			}
			Enumerator<Dimension> enumerator = Builder.CurrentFloor.m_dimensions.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Dimension current = enumerator.Current;
				if (!current.IsMainDimension && !current.DimensionData.IsStaticDimension)
				{
					LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(current.DimensionData.LevelLayoutData);
					if (block != null && ConfigManager.TryGetConfig(((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID, out var config4))
					{
						config4.Reset(((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)current.Grid).m_sizeX);
						DimensionLayer[current.DimensionIndex] = config4;
					}
				}
			}
			MainLayer?.Reset(GridSize);
			SecondaryLayer?.Reset(GridSize);
			ThirdLayer?.Reset(GridSize);
			AddExtraShard(MainLayer);
			AddExtraShard(SecondaryLayer);
			AddExtraShard(ThirdLayer);
			Array.ForEach(DimensionLayer, delegate(LayoutConfig x)
			{
				AddExtraShard(x);
			});
		}

		private static void AddExtraShard(LayoutConfig layerConfig)
		{
			//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_0025: Unknown result type (might be due to invalid IL or missing references)
			if (layerConfig == null)
			{
				return;
			}
			Complex[] extraComplexResourceToLoad = layerConfig.ExtraComplexResourceToLoad;
			foreach (Complex item in extraComplexResourceToLoad)
			{
				if (!_extraComplexResourceToLoad.Contains(item))
				{
					_extraComplexResourceToLoad.Add(item);
				}
			}
		}

		public static bool TryGetConfig(LG_Zone zone, out LayoutConfig config)
		{
			//IL_0001: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected I4, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Dimension val = default(Dimension);
			if (!Dimension.GetDimension(zone.DimensionIndex, ref val))
			{
				config = null;
				return false;
			}
			if (val.IsMainDimension)
			{
				LG_LayerType type = zone.Layer.m_type;
				switch ((int)type)
				{
				case 0:
					config = MainLayer;
					return MainLayer != null;
				case 1:
					config = SecondaryLayer;
					return SecondaryLayer != null;
				case 2:
					config = ThirdLayer;
					return ThirdLayer != null;
				}
			}
			else if (!val.DimensionData.IsStaticDimension)
			{
				config = DimensionLayer[zone.DimensionIndex];
				return config != null;
			}
			config = null;
			return false;
		}

		public static GameObject GetRandomPlug(uint seed, int plugHeight, SubComplex subcomplex, bool withGate)
		{
			//IL_002d: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			ComplexResourceSetDataBlock complexResourceSet = ComplexResourceSet;
			return (GameObject)(plugHeight switch
			{
				0 => complexResourceSet.GetRandomPrefab(seed, withGate ? complexResourceSet.m_straightPlugsWithGates : complexResourceSet.m_straightPlugsNoGates, subcomplex), 
				1 => complexResourceSet.GetRandomPrefab(seed, withGate ? complexResourceSet.m_singleDropPlugsWithGates : complexResourceSet.m_singleDropPlugsNoGates, subcomplex), 
				2 => complexResourceSet.GetRandomPrefab(seed, withGate ? complexResourceSet.m_doubleDropPlugsWithGates : complexResourceSet.m_doubleDropPlugsNoGates, subcomplex), 
				_ => null, 
			});
		}

		public static uint GetLayoutIdOfZone(LG_Zone zone)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected I4, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			Dimension dimension = zone.Dimension;
			if (dimension.IsMainDimension)
			{
				LG_LayerType type = zone.Layer.m_type;
				ExpeditionInTierData activeExpedition = RundownManager.ActiveExpedition;
				return (int)type switch
				{
					0 => activeExpedition.LevelLayoutData, 
					1 => activeExpedition.SecondaryLayout, 
					2 => activeExpedition.ThirdLayout, 
					_ => throw new NotSupportedException($"LayerType: {type} is not supported!"), 
				};
			}
			return dimension.DimensionData.LevelLayoutData;
		}
	}
	[BepInPlugin("LGTuner", "LGTuner", "1.0.0")]
	[BepInProcess("GTFO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class EntryPoint : BasePlugin
	{
		public Harmony HarmonyInstance { get; private set; }

		public override void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			HarmonyInstance = new Harmony("LGTuner");
			HarmonyInstance.PatchAll();
			ConfigManager.Init();
		}
	}
	public static class LGExtensions
	{
		public static bool IsSame(this LG_GridPosition position, LG_GridPosition other)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (position.x == other.x)
			{
				return position.z == other.z;
			}
			return false;
		}

		public static LG_GridPosition ToNormalGrid(this LG_Tile tile, int gridSize)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return tile.m_shape.m_gridPosition.GetNormal(gridSize);
		}

		public static LG_GridPosition GetNormal(this LG_GridPosition position, int gridSize)
		{
			//IL_003a: 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_0051: 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_0006: 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_0021: 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)
			LG_GridPosition result;
			if (gridSize < 0)
			{
				result = default(LG_GridPosition);
				result.x = position.x + BuilderInfo.GridZeroOffset;
				result.z = position.z + BuilderInfo.GridZeroOffset;
				return result;
			}
			int num = gridSize / 2;
			result = default(LG_GridPosition);
			result.x = position.x - num;
			result.z = position.z - num;
			return result;
		}

		public static Vector3 GetPositionNormal(this LG_Grid grid, int x, int z, int gridSize)
		{
			//IL_0024: 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)
			if (gridSize < 0)
			{
				return ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).GetPosition(x - BuilderInfo.GridZeroOffset, z - BuilderInfo.GridZeroOffset);
			}
			int num = gridSize / 2;
			return ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).GetPosition(x + num, z + num);
		}

		public static int GetGridSize(this Dimension dimension)
		{
			return ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)dimension.Grid).m_sizeX;
		}

		public static bool TryGetDimension(this LG_Floor floor, int dimensionIndex, out Dimension dimension)
		{
			if (Enum.IsDefined(typeof(eDimensionIndex), dimensionIndex))
			{
				return floor.GetDimension((eDimensionIndex)dimensionIndex, ref dimension);
			}
			dimension = null;
			return false;
		}

		public static bool TryGetDimension(this LG_Floor floor, eDimensionIndex dimensionIndex, out Dimension dimension)
		{
			//IL_000a: 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)
			if (Enum.IsDefined(typeof(eDimensionIndex), dimensionIndex))
			{
				return floor.GetDimension(dimensionIndex, ref dimension);
			}
			dimension = null;
			return false;
		}
	}
	public static class RandomExtensions
	{
		public static uint NextUint(this Random random)
		{
			int num = random.Next(1073741824);
			uint num2 = (uint)random.Next(4);
			return (uint)(num << 2) | num2;
		}

		public static float NextFloat(this Random random)
		{
			return Mathf.Clamp01((float)random.NextDouble());
		}

		public static int ToSeed(this uint seed)
		{
			return (int)seed;
		}
	}
	internal static class Logger
	{
		private static readonly ManualLogSource _logger;

		static Logger()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_logger = new ManualLogSource("LGTuner");
			Logger.Sources.Add((ILogSource)(object)_logger);
		}

		private static string Format(object msg)
		{
			return msg.ToString();
		}

		public static void Info(object data)
		{
			_logger.LogMessage((object)Format(data));
		}

		public static void Verbose(object data)
		{
		}

		public static void Debug(object data)
		{
			_logger.LogDebug((object)Format(data));
		}

		public static void Error(object data)
		{
			_logger.LogError((object)Format(data));
		}
	}
	public enum DirectionType
	{
		Unknown,
		Forward,
		Backward,
		Left,
		Right
	}
	public enum RotateType
	{
		None,
		Flip,
		MoveTo_Left,
		MoveTo_Right,
		Towards_Random,
		Towards_Forward,
		Towards_Backward,
		Towards_Left,
		Towards_Right
	}
	public struct LG_PlugInfo
	{
		public static readonly Quaternion NoRotation = Quaternion.AngleAxis(0f, Vector3.up);

		public static readonly Quaternion RightRotation = Quaternion.AngleAxis(90f, Vector3.up);

		public static readonly Quaternion BackwardRotation = Quaternion.AngleAxis(180f, Vector3.up);

		public static readonly Quaternion LeftRotation = Quaternion.AngleAxis(270f, Vector3.up);

		public static readonly Vector3 FrontPlugPosition = Vector3.forward * 32f;

		public static readonly Vector3 BackPlugPosition = Vector3.back * 32f;

		public static readonly Vector3 LeftPlugPosition = Vector3.left * 32f;

		public static readonly Vector3 RightPlugPosition = Vector3.right * 32f;

		public bool IsValid { get; private set; }

		public DirectionType StartDirection { get; private set; }

		public int Count { get; private set; }

		public bool HasFront { get; private set; }

		public bool HasBack { get; private set; }

		public bool HasLeft { get; private set; }

		public bool HasRight { get; private set; }

		public bool TryGetNewRotation(uint seed, RotateType rotate, out Quaternion rotation)
		{
			//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_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)
			DirectionType newDirection = GetNewDirection(seed, StartDirection, rotate);
			if (Count >= 4)
			{
				rotation = GetRotationOfDirection(newDirection);
				return true;
			}
			Logger.Info($"You are rotating {Count} side Geomorph, this could lead to level gen crash!");
			rotation = GetRotationOfDirection(newDirection);
			return true;
		}

		public bool HasPlug(DirectionType direction)
		{
			if (!IsValid)
			{
				return false;
			}
			if (Count >= 4)
			{
				return true;
			}
			return direction switch
			{
				DirectionType.Forward => HasFront, 
				DirectionType.Backward => HasBack, 
				DirectionType.Left => HasLeft, 
				DirectionType.Right => HasRight, 
				_ => false, 
			};
		}

		public static LG_PlugInfo BuildPlugInfo(GameObject geoObject, Quaternion rotation)
		{
			//IL_005e: 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_0065: 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_007e: Expected I4, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)geoObject.GetComponent<LG_Geomorph>() == (Object)null)
			{
				return default(LG_PlugInfo);
			}
			Il2CppArrayBase<LG_Plug> componentsInChildren = geoObject.GetComponentsInChildren<LG_Plug>();
			if (componentsInChildren == null)
			{
				return default(LG_PlugInfo);
			}
			if (componentsInChildren.Length < 1)
			{
				return default(LG_PlugInfo);
			}
			LG_PlugInfo result = default(LG_PlugInfo);
			foreach (LG_Plug item in componentsInChildren)
			{
				LG_PlugDir dir = item.m_dir;
				switch (dir - 2)
				{
				case 0:
					result.HasBack = true;
					result.Count++;
					break;
				case 2:
					result.HasFront = true;
					result.Count++;
					break;
				case 3:
					result.HasLeft = true;
					result.Count++;
					break;
				case 1:
					result.HasRight = true;
					result.Count++;
					break;
				}
			}
			result.IsValid = result.Count > 0;
			float num = Mathf.Round(((Quaternion)(ref rotation)).eulerAngles.y);
			Logger.Verbose($"angle: {num}");
			num = Mathf.Repeat(num, 360f);
			result.StartDirection = Mathf.RoundToInt(num / 90f) switch
			{
				0 => DirectionType.Forward, 
				1 => DirectionType.Right, 
				2 => DirectionType.Backward, 
				3 => DirectionType.Left, 
				_ => DirectionType.Unknown, 
			};
			return result;
		}

		public static DirectionType GetNewDirection(uint seed, DirectionType direction, RotateType rotate)
		{
			if (direction == DirectionType.Unknown)
			{
				return DirectionType.Unknown;
			}
			if (rotate == RotateType.Towards_Random)
			{
				rotate = new Random(seed.ToSeed()).Next(4) switch
				{
					0 => RotateType.Towards_Forward, 
					1 => RotateType.Towards_Backward, 
					2 => RotateType.Towards_Left, 
					3 => RotateType.Towards_Right, 
					_ => throw new IndexOutOfRangeException("Towards_Random: nextIndex was out of range?!"), 
				};
			}
			return rotate switch
			{
				RotateType.None => direction, 
				RotateType.Flip => direction switch
				{
					DirectionType.Forward => DirectionType.Backward, 
					DirectionType.Backward => DirectionType.Forward, 
					DirectionType.Left => DirectionType.Right, 
					DirectionType.Right => DirectionType.Left, 
					_ => throw new ArgumentOutOfRangeException("direction"), 
				}, 
				RotateType.MoveTo_Left => direction switch
				{
					DirectionType.Forward => DirectionType.Left, 
					DirectionType.Backward => DirectionType.Right, 
					DirectionType.Left => DirectionType.Backward, 
					DirectionType.Right => DirectionType.Forward, 
					_ => throw new ArgumentOutOfRangeException("direction"), 
				}, 
				RotateType.MoveTo_Right => direction switch
				{
					DirectionType.Forward => DirectionType.Right, 
					DirectionType.Backward => DirectionType.Left, 
					DirectionType.Left => DirectionType.Forward, 
					DirectionType.Right => DirectionType.Backward, 
					_ => throw new ArgumentOutOfRangeException("direction"), 
				}, 
				RotateType.Towards_Forward => DirectionType.Forward, 
				RotateType.Towards_Backward => DirectionType.Backward, 
				RotateType.Towards_Left => DirectionType.Left, 
				RotateType.Towards_Right => DirectionType.Right, 
				_ => throw new ArgumentOutOfRangeException("direction"), 
			};
		}

		public static Quaternion GetRotationOfDirection(DirectionType direction)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_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_0045: Unknown result type (might be due to invalid IL or missing references)
			return (Quaternion)(direction switch
			{
				DirectionType.Forward => NoRotation, 
				DirectionType.Backward => BackwardRotation, 
				DirectionType.Left => LeftRotation, 
				DirectionType.Right => RightRotation, 
				_ => throw new ArgumentOutOfRangeException("direction"), 
			});
		}
	}
}
namespace LGTuner.Utils
{
	internal static class JSON
	{
		private static readonly JsonSerializerOptions _setting;

		static JSON()
		{
			_setting = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = false,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				IgnoreReadOnlyProperties = true
			};
			_setting.Converters.Add(new JsonStringEnumConverter());
			if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
			{
				_setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
				Logger.Info("PartialData Support Found!");
			}
		}

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

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

		public static string Serialize(object value, Type type)
		{
			return JsonSerializer.Serialize(value, type, _setting);
		}
	}
	public static class MTFOPartialDataUtil
	{
		public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";

		public static JsonConverter PersistentIDConverter { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool Initialized { get; private set; }

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

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

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

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

		static MTFOUtil()
		{
			GameDataPath = string.Empty;
			CustomPath = string.Empty;
			HasCustomContent = false;
			IsLoaded = false;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
			{
				return;
			}
			try
			{
				Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
				FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				Logger.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}");
			}
		}
	}
}
namespace LGTuner.Manager
{
	public static class ConfigManager
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static LiveEditEventHandler <0>__LiveEdit_FileChanged;
		}

		private static readonly List<LayoutConfig> _layouts = new List<LayoutConfig>();

		private static readonly Dictionary<uint, LayoutConfig> _lookup = new Dictionary<uint, LayoutConfig>();

		private static readonly Dictionary<string, LayoutConfig> _fileNameLookup = new Dictionary<string, LayoutConfig>();

		public static IEnumerable<LayoutConfig> Layouts => _layouts;

		public static void Init()
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			if (!MTFOUtil.HasCustomContent)
			{
				return;
			}
			string text = Path.Combine(MTFOUtil.CustomPath, "LGTuner");
			FileInfo[] files = Directory.CreateDirectory(text).GetFiles();
			foreach (FileInfo fileInfo in files)
			{
				string extension = fileInfo.Extension;
				bool flag = extension.Equals(".json", StringComparison.InvariantCultureIgnoreCase);
				bool flag2 = extension.Equals(".jsonc", StringComparison.InvariantCultureIgnoreCase);
				if (flag || flag2)
				{
					LayoutConfig layoutConfig = JSON.Deserialize<LayoutConfig>(File.ReadAllText(fileInfo.FullName));
					if (_lookup.ContainsKey(layoutConfig.LevelLayoutID))
					{
						Logger.Error($"Duplicated ID found!: {fileInfo.Name}, {layoutConfig.LevelLayoutID}");
					}
					else
					{
						_layouts.Add(layoutConfig);
						_lookup.Add(layoutConfig.LevelLayoutID, layoutConfig);
						_fileNameLookup.Add(fileInfo.Name.ToLowerInvariant(), layoutConfig);
					}
				}
			}
			LiveEditListener obj = LiveEdit.CreateListener(text, "*.*", true);
			object obj2 = <>O.<0>__LiveEdit_FileChanged;
			if (obj2 == null)
			{
				LiveEditEventHandler val = LiveEdit_FileChanged;
				<>O.<0>__LiveEdit_FileChanged = val;
				obj2 = (object)val;
			}
			obj.FileChanged += (LiveEditEventHandler)obj2;
			obj.StartListen();
		}

		private static void LiveEdit_FileChanged(LiveEditEventArgs e)
		{
			string key = Path.GetFileName(e.FullPath).ToLowerInvariant();
			string extension = Path.GetExtension(e.FullPath);
			if (!extension.Equals(".json", StringComparison.InvariantCulture) && !extension.Equals(".jsonc", StringComparison.InvariantCulture))
			{
				return;
			}
			Logger.Error($"File Edited: '{key}' '{e.FullPath}'");
			try
			{
				LayoutConfig data = _fileNameLookup[key];
				uint oldID = data.LevelLayoutID;
				LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string json)
				{
					try
					{
						LayoutConfig layoutConfig = JSON.Deserialize<LayoutConfig>(json);
						layoutConfig.LevelLayoutID = oldID;
						_fileNameLookup.Remove(key);
						_lookup.Remove(oldID);
						_layouts.Remove(data);
						_layouts.Add(layoutConfig);
						_lookup.Add(oldID, layoutConfig);
						_fileNameLookup.Add(key, layoutConfig);
					}
					catch (Exception value2)
					{
						Logger.Error($"Error while reading LGTuner Config: {value2}");
					}
				});
			}
			catch (Exception value)
			{
				Logger.Error($"Error while reading LGTuner Config: {value}");
			}
		}

		private static void DumpLevel()
		{
		}

		private static void DumpLayerToConfig()
		{
		}

		public static bool TryGetConfig(uint layoutID, out LayoutConfig config)
		{
			return _lookup.TryGetValue(layoutID, out config);
		}
	}
}
namespace LGTuner.Inject
{
	[HarmonyPatch(typeof(LG_BuildPlugBaseJob), "SpawnPlug")]
	internal static class Inject_BuildPlug
	{
		private static void Prefix(LG_Plug plug, ref GameObject prefab)
		{
			//IL_0023: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected I4, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			Logger.Info($"found plug for zone: {((LG_ZoneExpander)plug).m_linksFrom.m_zone.LocalIndex}{((Object)((LG_ZoneExpander)plug).m_linksFrom).name}->{((LG_ZoneExpander)plug).m_linksTo.m_zone.LocalIndex}{((Object)((LG_ZoneExpander)plug).m_linksTo).name}");
			if (!BuilderInfo.TryGetConfig(((LG_ZoneExpander)plug).m_linksFrom.m_zone, out var config))
			{
				return;
			}
			LG_GridPosition normal = ((LG_ZoneExpander)plug).m_linksFrom.m_geomorph.m_tile.m_shape.m_gridPosition.GetNormal(config.GridSize);
			if (!config.TryGetTileData(normal, out var overrideData))
			{
				return;
			}
			ZoneOverrideData zoneData = overrideData.ZoneData;
			if (zoneData != null && zoneData.OverridePlugs && TryGetPlugPrefab(overrideData.ZoneData.GetNextPlug(), out var prefab2))
			{
				Logger.Info(" - Prefab Replaced by Zone OverridePlugs! " + ((Object)prefab2).name);
				prefab = prefab2;
			}
			LG_PlugDir dir = plug.m_dir;
			GameObject prefab3;
			switch (dir - 2)
			{
			case 0:
				if (TryGetPlugPrefab(overrideData.BackwardPlug, out prefab3))
				{
					Logger.Info(" - Prefab Replaced by BackwardPlug setting! " + ((Object)prefab3).name);
					prefab = prefab3;
					return;
				}
				break;
			case 2:
				if (TryGetPlugPrefab(overrideData.ForwardPlug, out prefab3))
				{
					Logger.Info(" - Prefab Replaced by ForwardPlug setting! " + ((Object)prefab3).name);
					prefab = prefab3;
					return;
				}
				break;
			case 3:
				if (TryGetPlugPrefab(overrideData.LeftPlug, out prefab3))
				{
					Logger.Info(" - Prefab Replaced by LeftPlug setting! " + ((Object)prefab3).name);
					prefab = prefab3;
					return;
				}
				break;
			case 1:
				if (TryGetPlugPrefab(overrideData.RightPlug, out prefab3))
				{
					Logger.Info(" - Prefab Replaced by RightPlug setting! " + ((Object)prefab3).name);
					prefab = prefab3;
					return;
				}
				break;
			}
			if (overrideData.OverridePlugWithNoGateChance)
			{
				Random random = new Random(((LG_ZoneExpander)plug).m_linksFrom.AreaSeed.ToSeed());
				bool withGate = ((LG_ZoneExpander)plug).m_isZoneSource || (!(overrideData.PlugWithNoGateChance >= 1f) && (overrideData.PlugWithNoGateChance <= 0f || random.NextFloat() >= overrideData.PlugWithNoGateChance));
				int dropHeight = GetDropHeight(plug);
				GameObject randomPlug = BuilderInfo.GetRandomPlug(random.NextUint(), dropHeight, GetSubComplexOfPlug(plug), withGate);
				if ((Object)(object)randomPlug == (Object)null)
				{
					Logger.Error($"Plug was null! - Height: {dropHeight}");
				}
				else
				{
					prefab = randomPlug;
				}
			}
		}

		private static SubComplex GetSubComplexOfPlug(LG_Plug plug)
		{
			//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_0008: 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: 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)
			SubComplex result = ((LG_ZoneExpander)plug).m_subComplex;
			if (((LG_ZoneExpander)plug).m_subComplex != ((LG_ZoneExpander)plug.m_pariedWith).m_subComplex)
			{
				result = (SubComplex)8;
			}
			return result;
		}

		private static bool TryGetPlugPrefab(string prefabPath, out GameObject prefab)
		{
			if (string.IsNullOrEmpty(prefabPath))
			{
				prefab = null;
				return false;
			}
			prefab = ((Il2CppObjectBase)AssetAPI.GetLoadedAsset(prefabPath)).Cast<GameObject>();
			return (Object)(object)prefab != (Object)null;
		}

		private static int GetDropHeight(LG_Plug plug)
		{
			//IL_0006: 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)
			return Mathf.RoundToInt(Mathf.Abs(((Component)plug).transform.position.y - ((Component)plug.m_pariedWith).transform.position.y) / BuilderInfo.AltitudeOffset);
		}
	}
	[HarmonyPatch(typeof(LG_LevelBuilder), "PlaceRoot")]
	internal static class Inject_BuildGeomorph
	{
		private static LayoutConfig _configContext;

		private static RotateType _nextRotateType;

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch("BuildFloor")]
		private static void Post_BuildFloor()
		{
			BuilderInfo.OnResourceSetSelected();
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("PlaceRoot")]
		private static void Pre_PlaceRoot(LG_Tile tile, ref GameObject tilePrefab, ref bool forceAlignToVector, ref Vector3 alignVector, LG_Zone zone)
		{
			//IL_000e: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0099: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			_configContext = null;
			_nextRotateType = RotateType.None;
			forceAlignToVector = alignVector != Vector3.zero;
			int gridSize = zone.Dimension.GetGridSize();
			LG_GridPosition val = tile.ToNormalGrid(gridSize);
			Logger.Info($"tile info: {val.x} {val.z} {((Object)tilePrefab).name} for {zone.LocalIndex} : {zone.DimensionIndex}");
			if (!BuilderInfo.TryGetConfig(zone, out _configContext))
			{
				return;
			}
			if (!_configContext.TryGetTileData(val, out var overrideData))
			{
				overrideData = _configContext.PopulateTileOverrideForZone(zone, val);
				if (overrideData == null)
				{
					return;
				}
			}
			if (!string.IsNullOrEmpty(overrideData.Geomorph))
			{
				Object loadedAsset = AssetAPI.GetLoadedAsset(overrideData.Geomorph);
				GameObject val2 = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).Cast<GameObject>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					Logger.Info(" - tile overriden! " + ((Object)val2).name);
					tilePrefab = val2;
				}
			}
			if (overrideData.Rotation != 0)
			{
				_nextRotateType = overrideData.Rotation;
			}
		}

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch("GetTilePosition")]
		private static void Post_GetTilePosition(LG_Tile tile, LG_Floor floor, int dimensionIndex, ref Vector3 __result)
		{
			//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_002c: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_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_007c: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			if (_configContext != null && floor.TryGetDimension(dimensionIndex, out var dimension))
			{
				int gridSize = _configContext.GridSize;
				LG_GridPosition val = tile.ToNormalGrid(gridSize);
				if (_configContext.TryGetTileData(val, out var overrideData) && overrideData.OverrideAltitude)
				{
					Vector3 positionNormal = dimension.Grid.GetPositionNormal(val.x, val.z, gridSize);
					positionNormal += new Vector3(0f, (float)overrideData.Altitude * BuilderInfo.AltitudeOffset, 0f);
					__result = positionNormal;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch("PlaceRoot")]
		private static void Post_PlaceRoot(LG_Tile tile, LG_Zone zone, LG_Geomorph __result)
		{
			//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_00a4: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			if (_configContext == null)
			{
				return;
			}
			if (_nextRotateType != 0)
			{
				GameObject gameObject = ((Component)__result).gameObject;
				LG_PlugInfo lG_PlugInfo = LG_PlugInfo.BuildPlugInfo(gameObject, gameObject.transform.rotation);
				Logger.Info($" - TRYING ROTATION! PLUG COUNT: {lG_PlugInfo.Count}");
				if (lG_PlugInfo.TryGetNewRotation(zone.m_subSeed, _nextRotateType, out var rotation))
				{
					Logger.Info(" - Done!");
					gameObject.transform.rotation = rotation;
				}
				__result.SetPlaced();
			}
			int gridSize = _configContext.GridSize;
			LG_GridPosition normalGridPosition = tile.ToNormalGrid(gridSize);
			if (!_configContext.TryGetTileData(normalGridPosition, out var overrideData) || !overrideData.OverrideAreaSeeds)
			{
				return;
			}
			if (overrideData.AreaSeeds.Length == ((Il2CppArrayBase<LG_Area>)(object)__result.m_areas).Length)
			{
				int length = ((Il2CppArrayBase<LG_Area>)(object)__result.m_areas).Length;
				for (int i = 0; i < length; i++)
				{
					uint num = overrideData.AreaSeeds[i];
					if (num != 0)
					{
						((Il2CppArrayBase<LG_Area>)(object)__result.m_areas)[i].AreaSeed = num;
						Logger.Info($" - new area seed: {((Il2CppArrayBase<LG_Area>)(object)__result.m_areas)[i].m_navInfo}, {num}");
					}
				}
			}
			else
			{
				Logger.Error($" - Area count and AreaSeeds item count mismatched! (CFG: {overrideData.AreaSeeds.Length} != AREA: {((Il2CppArrayBase<LG_Area>)(object)__result.m_areas).Length}) Area seed will not be applied!");
			}
		}
	}
	[HarmonyPatch(typeof(LG_LoadComplexDataSetResourcesJob), "Build")]
	internal static class Inject_LoadComplexShard
	{
		private static int _waitingShared;

		[HarmonyWrapSafe]
		private static void Prefix(LG_LoadComplexDataSetResourcesJob __instance)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			//IL_0032: 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_003a: 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_0041: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.m_loadingStarted)
			{
				return;
			}
			foreach (Complex item in BuilderInfo.ExtraComplexResourceToLoad)
			{
				AssetBundleName val = (AssetBundleName)((int)item switch
				{
					0 => 2, 
					1 => 4, 
					2 => 3, 
					_ => 0, 
				});
				if ((int)val != 0)
				{
					AssetShardManager.LoadAllShardsForBundleAsync(val, Action.op_Implicit((Action)Loaded), 1, (LoadSceneMode)1);
					_waitingShared++;
				}
			}
		}

		private static void Loaded()
		{
			_waitingShared--;
		}

		[HarmonyWrapSafe]
		private static void Postfix(LG_LoadComplexDataSetResourcesJob __instance, ref bool __result)
		{
			if (_waitingShared >= 1)
			{
				__result = false;
			}
		}
	}
}
namespace LGTuner.Configs
{
	public sealed class LayoutConfig
	{
		private TileOverrideData[,] _builtTileOverrides = new TileOverrideData[0, 0];

		public uint LevelLayoutID { get; set; }

		public Complex[] ExtraComplexResourceToLoad { get; set; } = Array.Empty<Complex>();


		public ZoneOverrideData[] ZoneOverrides { get; set; } = Array.Empty<ZoneOverrideData>();


		public TileOverrideData[] TileOverrides { get; set; } = Array.Empty<TileOverrideData>();


		[JsonIgnore]
		public int GridSize { get; private set; }

		[JsonIgnore]
		public int GridSizeHalf { get; private set; }

		public void Reset(int gridSize)
		{
			Array.ForEach(ZoneOverrides, delegate(ZoneOverrideData item)
			{
				item.Clear();
			});
			Array.Clear(_builtTileOverrides, 0, _builtTileOverrides.Length);
			GridSize = gridSize;
			GridSizeHalf = gridSize / 2;
			_builtTileOverrides = new TileOverrideData[GridSize, GridSize];
			TileOverrideData[] tileOverrides = TileOverrides;
			foreach (TileOverrideData tileOverrideData in tileOverrides)
			{
				if (_builtTileOverrides[tileOverrideData.X + GridSizeHalf, tileOverrideData.Z + GridSizeHalf] == null)
				{
					PutOverrideData(tileOverrideData);
					continue;
				}
				Logger.Error($"Duplicate tile data in layout: {LevelLayoutID}, ({tileOverrideData.X}, {tileOverrideData.Z})!");
			}
		}

		public bool TryGetTileData(LG_GridPosition normalGridPosition, out TileOverrideData overrideData)
		{
			//IL_0000: 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)
			int num = normalGridPosition.x + GridSizeHalf;
			if (num >= GridSize)
			{
				Logger.Error($"TryGetTileData grid x was out of range! {num}:{GridSize}");
				overrideData = null;
				return false;
			}
			int num2 = normalGridPosition.z + GridSizeHalf;
			if (num2 >= GridSize)
			{
				Logger.Error($"TryGetTileData grid Z was out of range! {num2}:{GridSize}");
				overrideData = null;
				return false;
			}
			overrideData = _builtTileOverrides[num, num2];
			return overrideData != null;
		}

		public void PutOverrideData(TileOverrideData data)
		{
			_builtTileOverrides[data.X + GridSizeHalf, data.Z + GridSizeHalf] = data;
		}

		public TileOverrideData PopulateTileOverrideForZone(LG_Zone zone, LG_GridPosition normalGridPosition)
		{
			//IL_0002: 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_003b: 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)
			if (!TryGetZoneOverride(zone.LocalIndex, out var data))
			{
				return null;
			}
			if (TryGetTileData(normalGridPosition, out var overrideData))
			{
				overrideData.ZoneData = data;
				TryApplyOverrides(data, overrideData);
				return overrideData;
			}
			TileOverrideData tileOverrideData = new TileOverrideData
			{
				ZoneData = data,
				X = normalGridPosition.x,
				Z = normalGridPosition.z,
				OverridePlugWithNoGateChance = data.OverridePlugWithNoGateChance,
				PlugWithNoGateChance = data.PlugWithNoGateChance
			};
			TryApplyOverrides(data, tileOverrideData);
			PutOverrideData(tileOverrideData);
			return tileOverrideData;
		}

		private void TryApplyOverrides(ZoneOverrideData zoneOverrideData, TileOverrideData tileOverrideData)
		{
			if (zoneOverrideData.OverrideGeomorphs && string.IsNullOrEmpty(tileOverrideData.Geomorph))
			{
				ZoneOverrideData.GeomorphData? nextGeo = zoneOverrideData.GetNextGeo();
				if (nextGeo.HasValue)
				{
					tileOverrideData.Geomorph = nextGeo.Value.Geomorph;
					if (tileOverrideData.Rotation == RotateType.None)
					{
						tileOverrideData.Rotation = ZoneOverrideData.DirectionToRotate(nextGeo.Value.Direction);
					}
				}
			}
			if (zoneOverrideData.OverrideAltitudes && !tileOverrideData.OverrideAltitude)
			{
				int? nextAltitude = zoneOverrideData.GetNextAltitude();
				if (nextAltitude.HasValue)
				{
					tileOverrideData.OverrideAltitude = true;
					tileOverrideData.Altitude = nextAltitude.Value;
				}
			}
		}

		public bool TryGetZoneOverride(eLocalZoneIndex localIndex, out ZoneOverrideData data)
		{
			//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)
			data = ZoneOverrides.SingleOrDefault((ZoneOverrideData z) => z.LocalIndex == localIndex);
			return data != null;
		}
	}
	public sealed class TileOverrideData
	{
		public int X { get; set; }

		public int Z { get; set; }

		public bool OverrideAreaSeeds { get; set; }

		public uint[] AreaSeeds { get; set; } = Array.Empty<uint>();


		public RotateType Rotation { get; set; }

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


		public bool OverrideAltitude { get; set; }

		public int Altitude { get; set; }

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


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


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


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


		public bool OverridePlugWithNoGateChance { get; set; }

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


		[JsonIgnore]
		public ZoneOverrideData ZoneData { get; set; }
	}
	public sealed class ZoneOverrideData
	{
		public enum Direction
		{
			Unchanged,
			Random,
			Forward,
			Backward,
			Left,
			Right
		}

		public struct GeomorphData
		{
			public string Geomorph { get; set; }

			public Direction Direction { get; set; }
		}

		private int _curGeomorphIndex;

		private int _curAltitudeIndex;

		private int _curPlugIndex;

		public eLocalZoneIndex LocalIndex { get; set; }

		public bool OverrideGeomorphs { get; set; }

		public GeomorphData[] Geomorphs { get; set; } = Array.Empty<GeomorphData>();


		public bool OverrideAltitudes { get; set; }

		public int[] Altitudes { get; set; } = Array.Empty<int>();


		public bool OverridePlugs { get; set; }

		public string[] Plugs { get; set; } = Array.Empty<string>();


		public bool OverridePlugWithNoGateChance { get; set; }

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


		public void Clear()
		{
			_curGeomorphIndex = 0;
			_curAltitudeIndex = 0;
			_curPlugIndex = 0;
		}

		public GeomorphData? GetNextGeo()
		{
			if (Geomorphs == null || Geomorphs.Length == 0)
			{
				return null;
			}
			return Geomorphs[_curGeomorphIndex++ % Geomorphs.Length];
		}

		public int? GetNextAltitude()
		{
			if (Altitudes == null || Altitudes.Length == 0)
			{
				return null;
			}
			return Altitudes[_curAltitudeIndex++ % Altitudes.Length];
		}

		public string GetNextPlug()
		{
			if (Plugs == null || Plugs.Length == 0)
			{
				return string.Empty;
			}
			return Plugs[_curPlugIndex++ % Plugs.Length];
		}

		public static RotateType DirectionToRotate(Direction direction)
		{
			return direction switch
			{
				Direction.Unchanged => RotateType.None, 
				Direction.Random => RotateType.Towards_Random, 
				Direction.Forward => RotateType.Towards_Forward, 
				Direction.Backward => RotateType.Towards_Backward, 
				Direction.Left => RotateType.Towards_Left, 
				Direction.Right => RotateType.Towards_Right, 
				_ => throw new NotImplementedException($"DirectionType: {direction} is not supported"), 
			};
		}
	}
}

plugins/net6/MTFO.dll

Decompiled 4 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using AK;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using CellMenu;
using ChainedPuzzles;
using GTFO.API;
using GameData;
using GameEvent;
using Gear;
using Globals;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.InteropTypes.Fields;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MTFO.API;
using MTFO.Custom;
using MTFO.Custom.CCP.Components;
using MTFO.CustomCP;
using MTFO.HotReload;
using MTFO.Managers;
using MTFO.NativeDetours;
using MTFO.Utilities;
using Player;
using SNetwork;
using TMPro;
using UnityEngine;
using UnityEngine.Analytics;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MTFO")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© dakkhuza 2021")]
[assembly: AssemblyFileVersion("4.5.2")]
[assembly: AssemblyInformationalVersion("4.5.2+gitbdd649e-main")]
[assembly: AssemblyProduct("MTFO")]
[assembly: AssemblyTitle("MTFO")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.5.2.0")]
[module: UnverifiableCode]
namespace MTFO
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class ConfigStrings
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("MTFO.ConfigStrings", typeof(ConfigStrings).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static string SECTION_DEBUG => ResourceManager.GetString("SECTION_DEBUG", resourceCulture);

		internal static string SECTION_DEV => ResourceManager.GetString("SECTION_DEV", resourceCulture);

		internal static string SECTION_GENERAL => ResourceManager.GetString("SECTION_GENERAL", resourceCulture);

		internal static string SETTING_DUMPDATA => ResourceManager.GetString("SETTING_DUMPDATA", resourceCulture);

		internal static string SETTING_DUMPDATA_DESC => ResourceManager.GetString("SETTING_DUMPDATA_DESC", resourceCulture);

		internal static string SETTING_DUMPDATA_MODE => ResourceManager.GetString("SETTING_DUMPDATA_MODE", resourceCulture);

		internal static string SETTING_DUMPDATA_MODE_DESC => ResourceManager.GetString("SETTING_DUMPDATA_MODE_DESC", resourceCulture);

		internal static string SETTING_HOTRELOAD => ResourceManager.GetString("SETTING_HOTRELOAD", resourceCulture);

		internal static string SETTING_HOTRELOAD_DESC => ResourceManager.GetString("SETTING_HOTRELOAD_DESC", resourceCulture);

		internal static string SETTING_RUNDOWNPACKAGE => ResourceManager.GetString("SETTING_RUNDOWNPACKAGE", resourceCulture);

		internal static string SETTING_RUNDOWNPACKAGE_DESC => ResourceManager.GetString("SETTING_RUNDOWNPACKAGE_DESC", resourceCulture);

		internal static string SETTING_USE_LEGACY_PATH => ResourceManager.GetString("SETTING_USE_LEGACY_PATH", resourceCulture);

		internal static string SETTING_USE_LEGACY_PATH_DESC => ResourceManager.GetString("SETTING_USE_LEGACY_PATH_DESC", resourceCulture);

		internal static string SETTING_VERBOSE => ResourceManager.GetString("SETTING_VERBOSE", resourceCulture);

		internal static string SETTING_VERBOSE_DESC => ResourceManager.GetString("SETTING_VERBOSE_DESC", resourceCulture);

		internal ConfigStrings()
		{
		}
	}
	[BepInPlugin("com.dak.MTFO", "MTFO", "4.5.2+gitbdd649e-main")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MTFO : BasePlugin
	{
		public const string MODNAME = "MTFO";

		public const string AUTHOR = "dak";

		public const string GUID = "com.dak.MTFO";

		public const string VERSION = "4.5.2+gitbdd649e-main";

		public override void Load()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Analytics.enabled = false;
			Harmony harmony = new Harmony("com.dak.MTFO");
			AssetAPI.OnImplReady += delegate
			{
				if (ConfigManager.IsHotReloadEnabled)
				{
					ClassInjector.RegisterTypeInIl2Cpp<HotReloader>();
					harmony.PatchAll(typeof(HotReloadInjector));
				}
			};
			harmony.PatchAll();
			Detour_DataBlockBase.Patch();
		}
	}
	public static class DataDumperExtensions
	{
		public static int GetStableHashCode(this string str)
		{
			int num = 5381;
			int num2 = num;
			for (int i = 0; i < str.Length && str[i] != 0; i += 2)
			{
				num = ((num << 5) + num) ^ str[i];
				if (i == str.Length - 1 || str[i + 1] == '\0')
				{
					break;
				}
				num2 = ((num2 << 5) + num2) ^ str[i + 1];
			}
			return num + num2 * 1566083941;
		}
	}
	public static class JsonNodeExtension
	{
		private static JsonDocumentOptions _JsonDocumentOptions = new JsonDocumentOptions
		{
			AllowTrailingCommas = true,
			CommentHandling = JsonCommentHandling.Skip
		};

		private static readonly JsonSerializerOptions _JsonSerializerOptions = new JsonSerializerOptions
		{
			AllowTrailingCommas = true,
			ReadCommentHandling = JsonCommentHandling.Skip,
			WriteIndented = true,
			Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
		};

		public static string ToJsonStringIndented(this JsonNode jsonNode)
		{
			return jsonNode.ToJsonString(_JsonSerializerOptions);
		}

		public static bool TryParseToJsonNode(this string json, out JsonNode jsonNode)
		{
			try
			{
				jsonNode = json.ToJsonNode();
				return jsonNode != null;
			}
			catch
			{
				jsonNode = null;
				return false;
			}
		}

		public static bool TryParseJsonNode(this Stream stream, bool dispose, out JsonNode jsonNode)
		{
			try
			{
				jsonNode = stream.ToJsonNode();
				return jsonNode != null;
			}
			catch
			{
				jsonNode = null;
				return false;
			}
			finally
			{
				if (dispose)
				{
					stream.Close();
				}
			}
		}

		public static JsonNode ToJsonNode(this string json)
		{
			return JsonNode.Parse(json, null, _JsonDocumentOptions);
		}

		public static JsonNode ToJsonNode(this Stream jsonStream)
		{
			return JsonNode.Parse(jsonStream, null, _JsonDocumentOptions);
		}

		public static bool TryAddJsonItem(this JsonArray jsonArray, string json)
		{
			try
			{
				if (jsonArray == null)
				{
					throw new Exception();
				}
				if (string.IsNullOrWhiteSpace(json))
				{
					throw new Exception();
				}
				if (!json.TryParseToJsonNode(out var jsonNode))
				{
					throw new Exception();
				}
				jsonArray.Add(jsonNode);
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "MTFO";

		public const string Version = "4.5.2";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "gitbdd649e-main";

		public const string SemVer = "4.5.2+gitbdd649e-main";

		public const string GitRevShort = "bdd649e";

		public const string GitRevLong = "bdd649ecde4cd5fb568e315265e04a3f41a9ab87";

		public const string GitBranch = "main";

		public const string GitTag = "v4.3.0";

		public const bool GitIsDirty = false;
	}
}
namespace MTFO.Utilities
{
	public class JsonSerializer
	{
		public JsonSerializerOptions Options;

		public JsonSerializer()
		{
			Options = new JsonSerializerOptions
			{
				AllowTrailingCommas = true,
				IncludeFields = true,
				PropertyNameCaseInsensitive = true,
				ReadCommentHandling = JsonCommentHandling.Skip,
				WriteIndented = true
			};
			Options.Converters.Add(new JsonStringEnumConverter());
		}

		public JsonSerializer(bool allowTrailingCommas = true, bool includeFields = true, bool propertyNameCaseInsensitive = true, bool writeIndented = true)
		{
			Options = new JsonSerializerOptions
			{
				AllowTrailingCommas = allowTrailingCommas,
				IncludeFields = includeFields,
				PropertyNameCaseInsensitive = propertyNameCaseInsensitive,
				ReadCommentHandling = JsonCommentHandling.Skip,
				WriteIndented = writeIndented
			};
			Options.Converters.Add(new JsonStringEnumConverter());
		}

		public void TryRead<T>(string path, out T output) where T : new()
		{
			if (File.Exists(path))
			{
				string json = File.ReadAllText(path);
				output = Deserialize<T>(json);
			}
			else
			{
				output = new T();
				string json = Serialize(output);
				File.WriteAllText(path, json);
			}
		}

		public string Serialize(object value)
		{
			return System.Text.Json.JsonSerializer.Serialize(value, Options);
		}

		public T Deserialize<T>(string json)
		{
			return System.Text.Json.JsonSerializer.Deserialize<T>(json, Options);
		}
	}
	public static class Log
	{
		private static readonly ManualLogSource logger;

		static Log()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			logger = new ManualLogSource("MTFO");
			Logger.Sources.Add((ILogSource)(object)logger);
		}

		public static void Verbose(object msg)
		{
			if (ConfigManager.IsVerbose)
			{
				logger.LogInfo(msg);
			}
		}

		public static void Debug(object msg)
		{
			logger.LogDebug(msg);
		}

		public static void Message(object msg)
		{
			logger.LogMessage(msg);
		}

		public static void Error(object msg)
		{
			logger.LogError(msg);
		}

		public static void Warn(object msg)
		{
			logger.LogWarning(msg);
		}
	}
	public enum BaseDirectory
	{
		BepInEx,
		Plugins,
		GameData
	}
	public static class PathUtil
	{
		public static string Prepare(BaseDirectory baseDir, params string[] subDirs)
		{
			string text = baseDir switch
			{
				BaseDirectory.BepInEx => Paths.BepInExRootPath, 
				BaseDirectory.Plugins => Paths.PluginPath, 
				BaseDirectory.GameData => Path.Combine(Paths.BepInExRootPath, "GameData"), 
				_ => throw new ArgumentOutOfRangeException("baseDir", string.Format("{0} is not a valid value for Argument: {1}", baseDir, "baseDir")), 
			};
			string obj = ((subDirs == null || subDirs.Length == 0) ? text : Path.Combine(text, Path.Combine(subDirs)));
			Directory.CreateDirectory(obj);
			return obj;
		}

		public static bool CheckCustomFile(string file, out string CombinedPath)
		{
			CombinedPath = Path.Combine(ConfigManager.CustomPath, file);
			if (File.Exists(CombinedPath))
			{
				return true;
			}
			return false;
		}

		public static bool CheckFile(string pathToFile)
		{
			if (File.Exists(pathToFile))
			{
				return true;
			}
			return false;
		}

		[Obsolete]
		public static string MakeRelativeDirectory(string path, bool createPath = true)
		{
			string text = Path.Combine(Path.Combine(Paths.ConfigPath, "Rundowns"), path);
			if (createPath && !Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			return text;
		}

		public static string MakeRelativeDirectory(string path, string folder)
		{
			string text = Path.Combine(path, folder);
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			return text;
		}

		public static void PrepareEmptyDirectory(string path)
		{
			if (Directory.Exists(path))
			{
				Directory.Delete(path, recursive: true);
			}
			Directory.CreateDirectory(path);
		}

		public static Stream OpenUtf8Stream(string filePath)
		{
			return new StreamReader(filePath, Encoding.UTF8).BaseStream;
		}
	}
}
namespace MTFO.Patches
{
	[HarmonyPatch(typeof(AnalyticsManager), "OnGameEvent", new Type[] { typeof(GameEventData) })]
	internal static class Patch_Analytics
	{
		public static bool Prefix(GameEventData data)
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(SNet_Core_STEAM), "SetFriendsData", new Type[]
	{
		typeof(FriendsDataType),
		typeof(string)
	})]
	internal static class Patch_RichPresence2
	{
		public static void Prefix(FriendsDataType type, ref string data, SNet_Core_STEAM __instance)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if ((int)type != 1)
			{
				if ((int)type == 9)
				{
					data = "0";
				}
				else
				{
					Log.Verbose($"Lobby data\nType: {type} Data: {data}");
				}
			}
			else
			{
				data = "MODDED - " + data;
			}
		}
	}
	[HarmonyPatch(typeof(GlowstickInstance), "Update")]
	internal static class Patch_Glowstick
	{
		public static void Postfix(GlowstickInstance __instance)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigManager.HasCustomContent && ConfigManager.CustomContent.GlowstickHolder != null && !((Object)(object)__instance == (Object)null) && (int)__instance.m_state != 3 && (int)__instance.m_state != 4 && ConfigManager.CustomContent.GlowstickHolder.GlowstickLookup.TryGetValue(((Item)__instance).PublicName, out var value) && (Object)(object)__instance.m_light != (Object)null)
			{
				((LightBase)__instance.m_light).Range = value.Range;
				((LightBase)__instance.m_light).Color = value.Color * __instance.m_progression;
				((LightBase)__instance.m_light).UpdateVisibility(true);
			}
		}
	}
	[HarmonyPatch(typeof(CP_Holopath_Spline), "Reveal")]
	internal static class Patch_InstantRevealPuzzlePath
	{
		public static bool Prefix(CP_Holopath_Spline __instance)
		{
			//IL_0030: 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)
			if (__instance.m_revealSpeed < 0f)
			{
				if (!__instance.m_isSetup)
				{
					return false;
				}
				__instance.SetSplineProgress(1f);
				__instance.SetVisible(true);
				__instance.m_sound.UpdatePosition(__instance.TipPos);
				if (!__instance.m_didSetColor)
				{
					__instance.m_didSetColor = __instance.TrySetColor();
				}
				__instance.m_sound.Post(EVENTS.BIOSCAN_TUBE_EMITTER_STOP, true);
				Action onRevealDone = __instance.OnRevealDone;
				if (onRevealDone != null)
				{
					onRevealDone.Invoke();
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CM_PageLoadout), "UpdatePageData")]
	internal static class Patch_PageLoadoutUpdatePageData
	{
		public static void Prefix(CM_PageLoadout __instance)
		{
			((TMP_Text)((Component)((Transform)((CM_PageBase)__instance).m_movingContentHolder).Find("ShareServerId/ShareText")).gameObject.GetComponent<TextMeshPro>()).SetText("<color=red><b>Do not play modded content on the official GTFO server or online matchmake lobbies.</b></color>\n\nFeel free to join the unofficial discord server linked below and ask people to play.", true);
			__instance.m_discordButton.SetText("Mod Server");
			__instance.m_discordButton.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
			{
				Application.OpenURL("https://discord.com/invite/rRMPtv4FAh");
			});
		}
	}
	[HarmonyPatch(typeof(CM_PageLoadout), "UpdatePlayerBars")]
	internal static class Patch_PageLoadoutUpdatePlayerBars
	{
		public static void Prefix(CM_PageLoadout __instance)
		{
			foreach (CM_PlayerLobbyBar item in (Il2CppArrayBase<CM_PlayerLobbyBar>)(object)__instance.m_playerLobbyBars)
			{
				item.m_matchmakeButton.SetOnBtnPressCallback((Action<int>)null);
				item.m_matchmakeButton.SetText("DISABLED");
			}
		}
	}
	[HarmonyPatch(typeof(CM_PageRundown_New), "Intro_RevealRundown")]
	internal static class Patch_PageRundownNew
	{
		public static void Postfix(CM_PageRundown_New __instance)
		{
			__instance.m_discordButton.SetText("MOD SERVER");
			__instance.m_discordButton.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
			{
				Application.OpenURL("https://discord.com/invite/rRMPtv4FAh");
			});
			((RectTransformComp)__instance.m_matchmakeAllButton).SetVisible(false);
			__instance.m_matchmakeAllButton.SetText("MATCHMAKE DISABLED");
			__instance.m_matchmakeAllButton.OnBtnPressCallback = null;
			__instance.m_aboutTheRundownButton.SetText("THUNDERSTORE");
			__instance.m_aboutTheRundownButton.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
			{
				Application.OpenURL("https://gtfo.thunderstore.io/");
			});
		}
	}
	[HarmonyPatch(typeof(CM_PageRundown_New), "PlaceRundown")]
	internal static class Patch_RundownTierMarker
	{
		public static void Postfix(CM_PageRundown_New __instance)
		{
			ContentManager customContent = ConfigManager.CustomContent;
			if (customContent != null)
			{
				__instance.m_tierMarker1.m_name = customContent.TierNames.Tier1;
				__instance.m_tierMarker2.m_name = customContent.TierNames.Tier2;
				__instance.m_tierMarker3.m_name = customContent.TierNames.Tier3;
				__instance.m_tierMarker4.m_name = customContent.TierNames.Tier4;
				__instance.m_tierMarker5.m_name = customContent.TierNames.Tier5;
				__instance.m_tierMarker1.UpdateHeader();
				__instance.m_tierMarker2.UpdateHeader();
				__instance.m_tierMarker3.UpdateHeader();
				__instance.m_tierMarker4.UpdateHeader();
				__instance.m_tierMarker5.UpdateHeader();
			}
		}
	}
	[HarmonyPatch(typeof(PUI_Watermark), "UpdateWatermark")]
	internal static class Patch_WatermarkUpdateWatermark
	{
		public static void Postfix(PUI_Watermark __instance)
		{
			((TMP_Text)__instance.m_watermarkText).SetText("<color=red>MODDED</color> <color=orange>4.5.2</color>", true);
		}
	}
}
namespace MTFO.NativeDetours
{
	internal class DataBlockBaseWrapper
	{
		private static readonly HashSet<string> _PreferPartialDumpBlocks = new HashSet<string>
		{
			"RundownDataBlock".ToLower(),
			"LightSettingsDataBlock".ToLower(),
			"FogSettingsDataBlock".ToLower(),
			"LevelLayoutDataBlock".ToLower(),
			"WardenObjectiveDataBlock".ToLower(),
			"DimensionDataBlock".ToLower(),
			"EnemyDataBlock".ToLower(),
			"EnemySFXDataBlock".ToLower(),
			"EnemyBehaviorDataBlock".ToLower(),
			"EnemyBalancingDataBlock".ToLower(),
			"EnemyMovementDataBlock".ToLower(),
			"ArchetypeDataBlock".ToLower(),
			"PlayerOfflineGearDataBlock".ToLower(),
			"ComplexResourceSetDataBlock".ToLower(),
			"TextDataBlock".ToLower()
		};

		private IntPtr Ptr__m_fileNameNoExt;

		public IntPtr ClassPointer { get; private set; }

		public string FileName { get; private set; }

		public string BinaryFileName { get; private set; }

		public bool PreferPartialBlockOnDump { get; private set; }

		public unsafe DataBlockBaseWrapper(Il2CppMethodInfo* methodInfo)
		{
			INativeClassStruct val = UnityVersionHandler.Wrap(UnityVersionHandler.Wrap(methodInfo).Class);
			ClassPointer = ((INativeStruct)val).Pointer;
			Ptr__m_fileNameNoExt = IL2CPP.GetIl2CppField(((INativeStruct)val).Pointer, "m_fileNameNoExt");
			IntPtr zero = IntPtr.Zero;
			IL2CPP.il2cpp_field_static_get_value(Ptr__m_fileNameNoExt, (void*)(&zero));
			FileName = IL2CPP.Il2CppStringToManaged(zero).Replace('.', '_');
			BinaryFileName = FileName + "_bin";
			if (_PreferPartialDumpBlocks.Contains(FileName.ToLower().Replace("gamedata_", "")))
			{
				PreferPartialBlockOnDump = true;
			}
		}
	}
	internal static class Detour_DataBlockBase
	{
		private unsafe delegate IntPtr GetFileContentsDel(Il2CppMethodInfo* methodInfo);

		private static string _BasePathToDump;

		private static INativeDetour _Detour;

		private static GetFileContentsDel _Original;

		public unsafe static void Patch()
		{
			_BasePathToDump = Path.Combine(Paths.BepInExRootPath, "GameData-Dump", CellBuildData.GetRevision().ToString());
			if (ConfigManager.DumpGameData)
			{
				PathUtil.PrepareEmptyDirectory(_BasePathToDump);
			}
			_Detour = INativeDetour.CreateAndApply<GetFileContentsDel>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<GameDataBlockBase<EnemyDataBlock>>("GetFileContents", typeof(string).FullName, false, Array.Empty<string>()), (GetFileContentsDel)Dtor_GetFileContents, ref _Original);
		}

		private unsafe static IntPtr Dtor_GetFileContents(Il2CppMethodInfo* methodInfo)
		{
			IntPtr intPtr = _Original(methodInfo);
			try
			{
				DataBlockBaseWrapper dataBlockBaseWrapper = new DataBlockBaseWrapper(methodInfo);
				string binaryFileName = dataBlockBaseWrapper.BinaryFileName;
				_ = binaryFileName + ".json";
				if (ConfigManager.DumpGameData)
				{
					DumpContent(dataBlockBaseWrapper, IL2CPP.Il2CppStringToManaged(intPtr));
				}
				Log.Verbose("GetFileContents Call of " + binaryFileName);
				Stream contentStream = GetContentStream(dataBlockBaseWrapper, intPtr);
				JsonNode jsonNode = contentStream.ToJsonNode();
				JsonArray jsonArray = jsonNode["Blocks"].AsArray();
				string path = Path.Combine(ConfigManager.GameDataPath, dataBlockBaseWrapper.FileName);
				if (Directory.Exists(path))
				{
					int num = 0;
					string[] files = Directory.GetFiles(path, "*.json");
					foreach (string text in files)
					{
						Log.Verbose(" - Trying to add PartialData [" + text + "]");
						if (File.Exists(text) && PathUtil.OpenUtf8Stream(text).TryParseJsonNode(dispose: true, out var jsonNode2))
						{
							jsonArray.Add(jsonNode2);
							num++;
						}
					}
					Log.Verbose($" - Added {num} partial data of {binaryFileName}");
				}
				List<string> jsonItemsToInject = new List<string>();
				MTFOGameDataAPI.Invoke_OnGameDataContentLoad(dataBlockBaseWrapper.FileName, contentStream, in jsonItemsToInject);
				foreach (string item2 in jsonItemsToInject)
				{
					try
					{
						JsonNode item = item2.ToJsonNode();
						jsonArray.Add(item);
					}
					catch (Exception ex)
					{
						Log.Error("Exception were found while reading Injected Json Data!");
						Log.Error(ex.ToString());
						Log.Error("Full Json:\n" + item2);
					}
				}
				uint num2 = 0u;
				foreach (JsonNode item3 in jsonNode["Blocks"].AsArray())
				{
					uint num3 = (uint)(JsonNode)item3["persistentID"].AsValue();
					if (num3 > num2)
					{
						num2 = num3;
					}
				}
				jsonNode["LastPersistentID"] = num2;
				string text2 = jsonNode.ToJsonStringIndented();
				IntPtr result = IL2CPP.ManagedStringToIl2Cpp(text2);
				MTFOGameDataAPI.Invoke_OnGameDataContentLoaded(dataBlockBaseWrapper.FileName, text2);
				return result;
			}
			catch (Exception ex2)
			{
				Log.Error("Exception were found while handling Detour;Falling back to original content!");
				Log.Error(ex2.ToString());
				return intPtr;
			}
		}

		private static Stream GetContentStream(DataBlockBaseWrapper datablock, IntPtr originalContentPtr)
		{
			string binaryFileName = datablock.BinaryFileName;
			string path = binaryFileName + ".json";
			string s = IL2CPP.Il2CppStringToManaged(originalContentPtr);
			string text = Path.Combine(ConfigManager.GameDataPath, path);
			if (File.Exists(text))
			{
				Log.Verbose("Opening filestream of [" + binaryFileName + "] from disk...");
				Log.Verbose(text);
				return PathUtil.OpenUtf8Stream(text);
			}
			Log.Verbose("No file found at [" + binaryFileName + "]");
			return new MemoryStream(Encoding.UTF8.GetBytes(s));
		}

		private static void DumpContent(DataBlockBaseWrapper datablock, string json)
		{
			if (!json.TryParseToJsonNode(out var jsonNode))
			{
				Log.Verbose("Unable to dump " + datablock.FileName + ", Invalid Json Content!");
				return;
			}
			bool flag = false;
			switch (ConfigManager.DumpMode)
			{
			case DumpGameDataMode.Single:
				flag = false;
				break;
			case DumpGameDataMode.PartialData:
				flag = datablock.PreferPartialBlockOnDump;
				break;
			case DumpGameDataMode.FullPartialData:
				flag = true;
				break;
			}
			if (flag)
			{
				JsonArray jsonArray = jsonNode["Blocks"].AsArray();
				string text = Path.Combine(path2: datablock.FileName, path1: _BasePathToDump);
				PathUtil.PrepareEmptyDirectory(text);
				foreach (JsonNode item in jsonArray)
				{
					string path = string.Format("{0}__{1}.json", item["persistentID"], item["name"]);
					string text2 = Path.Combine(text, path);
					File.WriteAllText(text2, item.ToJsonStringIndented());
					Log.Verbose(" - Save... " + text2);
				}
				jsonNode["Blocks"] = new JsonArray();
			}
			string path2 = datablock.BinaryFileName + ".json";
			File.WriteAllText(Path.Combine(_BasePathToDump, path2), jsonNode.ToJsonStringIndented());
			Log.Verbose(datablock.FileName + " has dumped to '" + _BasePathToDump + "'");
		}
	}
}
namespace MTFO.Managers
{
	public enum DumpGameDataMode
	{
		Single,
		PartialData,
		FullPartialData
	}
	public static class ConfigManager
	{
		private const string CUSTOM_FOLDER = "Custom";

		private static readonly ConfigEntry<bool> _enableHotReload;

		private static readonly ConfigEntry<bool> _dumpGameData;

		private static readonly ConfigEntry<bool> _isVerbose;

		private static readonly ConfigEntry<DumpGameDataMode> _dumpGameDataMode;

		public static int GAME_VERSION;

		public static ContentManager CustomContent;

		public static readonly string GameDataPath;

		public static readonly string CustomPath;

		public static bool HasGameDataPath;

		public static bool HasCustomContent;

		public static bool IsModded;

		public static bool IsPluginGameDataPath;

		public static bool IsVerbose => _isVerbose.Value;

		public static bool IsHotReloadEnabled => _enableHotReload.Value;

		public static bool DumpGameData => _dumpGameData.Value;

		public static DumpGameDataMode DumpMode => _dumpGameDataMode.Value;

		private static string ResolveGameDataPath(string rootPath)
		{
			foreach (string item in Directory.GetFiles(rootPath, "GameData_*.json", SearchOption.AllDirectories).OrderBy(Path.GetDirectoryName))
			{
				if (Path.GetDirectoryName(item) != GameDataPath)
				{
					HasGameDataPath = true;
					return Path.GetDirectoryName(item);
				}
			}
			return null;
		}

		static ConfigManager()
		{
			//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_0030: 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)
			ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "MTFO.cfg"), true);
			_enableHotReload = val.Bind<bool>(ConfigStrings.SECTION_DEV, ConfigStrings.SETTING_HOTRELOAD, false, ConfigStrings.SETTING_HOTRELOAD_DESC);
			_dumpGameData = val.Bind<bool>(ConfigStrings.SECTION_DEV, ConfigStrings.SETTING_DUMPDATA, false, ConfigStrings.SETTING_DUMPDATA_DESC);
			_dumpGameDataMode = val.Bind<DumpGameDataMode>(ConfigStrings.SECTION_DEV, ConfigStrings.SETTING_DUMPDATA_MODE, DumpGameDataMode.Single, ConfigStrings.SETTING_DUMPDATA_MODE_DESC);
			_isVerbose = val.Bind<bool>(ConfigStrings.SECTION_DEBUG, ConfigStrings.SETTING_VERBOSE, false, ConfigStrings.SETTING_VERBOSE_DESC);
			GAME_VERSION = GetGameVersion();
			GameDataPath = ResolveGameDataPath(PathUtil.Prepare(BaseDirectory.GameData));
			IsPluginGameDataPath = string.IsNullOrEmpty(GameDataPath);
			if (IsPluginGameDataPath)
			{
				GameDataPath = ResolveGameDataPath(Paths.PluginPath);
				Log.Warn("Plugin paths for gamedata are under legacy support and will be removed in the future. Considering migrating to the '\\BepInEx\\GameData' folder.");
			}
			if (HasGameDataPath)
			{
				CustomPath = Path.Combine(GameDataPath, "Custom");
				HasCustomContent = Directory.Exists(CustomPath);
			}
			else
			{
				GameDataPath = string.Empty;
				CustomPath = string.Empty;
				HasCustomContent = false;
				IsPluginGameDataPath = false;
			}
			try
			{
				CustomContent = new ContentManager();
			}
			catch (Exception arg)
			{
				HasCustomContent = false;
				Log.Error($"Failed to init custom content!\nIs your JSON valid?\n---- ERROR MESSAGE ---- {arg} ---- END ERROR MESSAGE ----");
			}
			Log.Debug("---- DEBUG INFO ----");
			Log.Debug($"Time: {DateTime.Now}");
			Log.Debug($"Game Version: {GAME_VERSION}");
			Log.Debug("---- PATHS ----");
			Log.Debug("Path to rundown: " + GameDataPath);
			Log.Debug("Path to custom content: " + CustomPath);
			Log.Debug("---- FLAGS ----");
			Log.Debug($"Has GameData Path? {HasGameDataPath}");
			Log.Debug($"Using plugin GameData path? {IsPluginGameDataPath}");
			Log.Debug($"Has Custom Content? {HasCustomContent}");
			Log.Debug($"Hot Reload Enabled? {IsHotReloadEnabled}");
			Log.Debug($"Verbose Logging? {IsVerbose}");
			Log.Debug($"Dump Game Data? {DumpGameData}");
			Log.Debug("---- DEBUG END ----");
		}

		private static int GetGameVersion()
		{
			return CellBuildData.GetRevision();
		}
	}
	public class ContentManager
	{
		private readonly global::MTFO.Utilities.JsonSerializer json = new global::MTFO.Utilities.JsonSerializer();

		private readonly Dictionary<string, Action<string>> Handlers;

		public ScanHolder ScanHolder;

		public GlowstickHolder GlowstickHolder;

		public TierNames TierNames;

		public ContentManager()
		{
			Handlers = new Dictionary<string, Action<string>>
			{
				{ "puzzletypes.json", SetupChainedPuzzles },
				{ "glowsticks.json", SetupGlowsticks },
				{ "tiernames.json", SetupTierNames }
			};
			Init();
		}

		private void Init()
		{
			if (!ConfigManager.HasCustomContent)
			{
				return;
			}
			foreach (string key in Handlers.Keys)
			{
				if (PathUtil.CheckCustomFile(key, out var CombinedPath))
				{
					Handlers.TryGetValue(key, out var value);
					try
					{
						value?.Invoke(CombinedPath);
					}
					catch (Exception msg)
					{
						Log.Error(msg);
					}
					Log.Debug(CombinedPath);
				}
			}
		}

		public void SetupChainedPuzzles(string path)
		{
			Log.Debug("Custom puzzles found");
			ScanHolder = json.Deserialize<ScanHolder>(File.ReadAllText(path));
		}

		public void SetupGlowsticks(string path)
		{
			Log.Debug("Custom glowsticks found");
			GlowstickHolder = json.Deserialize<GlowstickHolder>(File.ReadAllText(path));
			GlowstickHolder.Setup();
		}

		public void SetupTierNames(string path)
		{
			TierNames = json.Deserialize<TierNames>(File.ReadAllText(path));
		}
	}
}
namespace MTFO.HotReload
{
	internal class HotGameDataManager : IHotManager
	{
		public void OnHotReload(int id)
		{
			GameDataInit.ReInitialize();
			Log.Verbose("Reinitialized GameData");
		}
	}
	internal class HotGearManager : IHotManager
	{
		private readonly int gearSlotsTotal = 3;

		public void OnHotReload(int id)
		{
			GearManager.Current.m_offlineSetupDone = false;
			CleanGearIcons();
			CleanGearSlots();
			GearManager.Current.SetupGearContainers();
			LoadOfflineGearDatas();
			GearManager.GenerateAllGearIcons();
			GearManager.Current.m_offlineSetupDone = true;
			Log.Verbose("Reloaded Gear");
		}

		private void CleanGearIcons()
		{
			GearManager.m_allGearWithPostedIconJobs.Clear();
			foreach (Dictionary<uint, RenderTexture> item in (Il2CppArrayBase<Dictionary<uint, RenderTexture>>)(object)GearManager.Current.m_allGearIconTexturesPerInstanceKey)
			{
				item.Clear();
			}
		}

		[Obsolete]
		private void CleanGearLobbySlots()
		{
			if (!((Object)(object)CM_PageLoadout.Current != (Object)null))
			{
				return;
			}
			foreach (CM_InventorySlotItem componentsInChild in ((Component)CM_PageLoadout.Current.m_popupAlign).gameObject.GetComponentsInChildren<CM_InventorySlotItem>(true))
			{
				Object.Destroy((Object)(object)((Component)componentsInChild).gameObject);
			}
		}

		private void CleanGearSlots()
		{
			for (int i = 0; i < gearSlotsTotal; i++)
			{
				((Il2CppArrayBase<List<GearIDRange>>)(object)GearManager.Current.m_gearPerSlot)[i].Clear();
			}
		}

		private void LoadOfflineGearDatas()
		{
			Il2CppArrayBase<PlayerOfflineGearDataBlock> allBlocks = GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocks();
			if (allBlocks == null)
			{
				Log.Warn("Unable to get Player Offline Gear blocks");
				return;
			}
			Log.Verbose($"Loading {allBlocks.Length} gear");
			foreach (PlayerOfflineGearDataBlock item in allBlocks)
			{
				OfflineGear.Load(item);
			}
		}
	}
	public class HotReloader : MonoBehaviour
	{
		public static HotReloader Current;

		private CM_Item button;

		private readonly string buttonLabel = "Reload Game Data";

		private readonly Vector3 buttonPosition = new Vector3(0f, 77f, 0f);

		private readonly List<IHotManager> managers = new List<IHotManager>();

		public HotReloader(IntPtr intPtr)
			: base(intPtr)
		{
		}//IL_001b: 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)


		private void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).gameObject.transform.localPosition = buttonPosition;
			button = ((Component)this).gameObject.GetComponent<CM_Item>();
			button.SetText(buttonLabel);
			AddOnReloadListener(new HotGameDataManager());
			AddOnReloadListener(new HotRundownManager());
			AddOnReloadListener(new HotGearManager());
			button.OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)delegate
			{
				MTFOHotReloadAPI.HotReloaded();
			});
		}

		public void AddOnReloadListener(IHotManager manager)
		{
			if (!managers.Contains(manager))
			{
				button.OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)manager.OnHotReload);
				managers.Add(manager);
			}
		}

		public void RemoveOnReloadListener(IHotManager manager)
		{
			if (managers.Contains(manager))
			{
				button.OnBtnPressCallback -= Action<int>.op_Implicit((Action<int>)manager.OnHotReload);
				managers.Remove(manager);
			}
		}

		public static void Setup()
		{
			if (!((Object)(object)Current != (Object)null) && !((Object)(object)MainMenuGuiLayer.Current.PageRundownNew == (Object)null))
			{
				GameObject obj = Object.Instantiate<GameObject>(((Component)MainMenuGuiLayer.Current.PageRundownNew.m_discordButton).gameObject, ((Component)MainMenuGuiLayer.Current.PageRundownNew.m_discordButton).transform.parent, false);
				((Object)obj).name = "Button HotReload";
				Current = obj.AddComponent<HotReloader>();
				obj.SetActive(true);
				Log.Verbose("Created hot reload button");
			}
		}
	}
	public class HotReloadInjector
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageRundown_New), "OnEnable")]
		public static void OnEnable()
		{
			HotReloader.Setup();
		}
	}
	internal class HotRundownManager : IHotManager
	{
		private CM_PageRundown_New rundownPage;

		private bool hasValidRundown => GameDataBlockBase<RundownDataBlock>.s_blockByID.ContainsKey(Global.RundownIdToLoad);

		private RundownDataBlock rundownDataCurrent => GameDataBlockBase<RundownDataBlock>.GetBlock(Global.RundownIdToLoad);

		public HotRundownManager()
		{
			rundownPage = MainMenuGuiLayer.Current.PageRundownNew;
		}

		public void OnHotReload(int id)
		{
			if (hasValidRundown)
			{
				rundownPage.m_dataIsSetup = false;
				CleanIconsOfTier();
				TryPlaceRundown();
			}
			else
			{
				Log.Warn($"Failed to place the rundown due to missing Rundown id {Global.RundownIdToLoad}");
			}
			Log.Verbose("Reloaded Rundown");
		}

		private void CleanIconsOfTier()
		{
			CleanIconsOfTier(rundownPage.m_expIconsTier1);
			CleanIconsOfTier(rundownPage.m_expIconsTier2);
			CleanIconsOfTier(rundownPage.m_expIconsTier3);
			CleanIconsOfTier(rundownPage.m_expIconsTier4);
			CleanIconsOfTier(rundownPage.m_expIconsTier5);
		}

		private void CleanIconsOfTier(List<CM_ExpeditionIcon_New> tier)
		{
			Enumerator<CM_ExpeditionIcon_New> enumerator = tier.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Object.Destroy((Object)(object)((Component)enumerator.Current).gameObject);
			}
		}

		private void TryPlaceRundown()
		{
			rundownPage.m_currentRundownData = rundownDataCurrent;
			if (rundownPage.m_currentRundownData != null)
			{
				rundownPage.PlaceRundown(rundownPage.m_currentRundownData);
				rundownPage.m_dataIsSetup = true;
			}
			else
			{
				Log.Warn("Unable to place rundown due to null data during reload");
			}
		}
	}
	public interface IHotManager
	{
		void OnHotReload(int id);
	}
	public class OfflineGear
	{
		private GearIDRange gearIDRange;

		private ItemDataBlock itemData;

		private int inventorySlot;

		private uint persistentID;

		private OfflineGear(PlayerOfflineGearDataBlock block)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (TryParseGearJson(block.GearJSON, out gearIDRange))
			{
				gearIDRange.PlayfabItemId = ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).name;
				gearIDRange.PlayfabItemInstanceId = $"OfflineGear_ID_{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}";
				gearIDRange.OfflineGearType = block.Type;
			}
			if (TryParseGearID(gearIDRange, out itemData, out inventorySlot))
			{
				persistentID = ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID;
			}
			else
			{
				Log.Warn($"Unable to construct Offline Gear [{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}] {((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).name}");
			}
		}

		public static void Load(PlayerOfflineGearDataBlock block)
		{
			if (TryParse(block, out var result) && TryStash(result))
			{
				Log.Verbose($"Loaded offline gear [{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}] {((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).name}");
			}
		}

		private static bool TryParse(PlayerOfflineGearDataBlock block, out OfflineGear result)
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			eOfflineGearType type = block.Type;
			if (type - 1 <= 1)
			{
				result = new OfflineGear(block);
				return true;
			}
			result = null;
			Log.Warn($"Unimplemented Offline Gear Type [{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}] {block.Type}");
			return false;
		}

		private bool TryParseGearID(GearIDRange gearIDRange, out ItemDataBlock itemData, out int inventorySlot)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected I4, but got Unknown
			inventorySlot = 0;
			itemData = null;
			if (gearIDRange == null)
			{
				Log.Warn("Unable to parse GearIDRange due to it being null");
				return false;
			}
			uint compID = gearIDRange.GetCompID((eGearComponent)3);
			itemData = ((compID != 0) ? GameDataBlockBase<ItemDataBlock>.GetBlock(compID) : null);
			if (itemData == null)
			{
				Log.Warn($"Invalid ItemDataBlock for component in offlinear gear [c:{compID}]");
				return false;
			}
			inventorySlot = (int)itemData.inventorySlot;
			return true;
		}

		private bool TryParseGearJson(string gearJson, out GearIDRange gearIDRange)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (string.IsNullOrEmpty(gearJson))
			{
				gearIDRange = null;
				Log.Warn("Unable to assign GearIDRange due to null or empty GearJson");
				return false;
			}
			gearIDRange = new GearIDRange(gearJson);
			if (gearIDRange == null)
			{
				return false;
			}
			return true;
		}

		private static bool TryStash(OfflineGear gear)
		{
			if (gear == null)
			{
				Log.Warn("Unable to stash due to null offline gear");
				return false;
			}
			if (gear.gearIDRange == null)
			{
				Log.Warn($"Unable to stash offline gear due to null GearIDRange [{gear.persistentID}]");
				return false;
			}
			if (gear.itemData == null)
			{
				Log.Warn($"Unable to stash offline gear due to null ItemDataBlock [{gear.persistentID}]");
				return false;
			}
			((Il2CppArrayBase<List<GearIDRange>>)(object)GearManager.Current.m_gearPerSlot)[gear.inventorySlot].Add(gear.gearIDRange);
			return true;
		}
	}
}
namespace MTFO.CustomCP
{
	public static class CustomPuzzleManager
	{
		private static readonly Dictionary<uint, CustomBioScan> s_scanMap = new Dictionary<uint, CustomBioScan>();

		private static readonly Dictionary<uint, CustomClusterScan> s_clusterMap = new Dictionary<uint, CustomClusterScan>();

		private static bool s_initialized = false;

		public static bool TryGetScanByID(uint id, out CustomBioScan scan)
		{
			return s_scanMap.TryGetValue(id, out scan);
		}

		public static bool TryGetClusterByID(uint id, out CustomClusterScan cluster)
		{
			return s_clusterMap.TryGetValue(id, out cluster);
		}

		internal static void Initialize(ChainedPuzzleManager manager)
		{
			if (!s_initialized)
			{
				s_initialized = true;
				ClassInjector.RegisterTypeInIl2Cpp<CorePuzzleData>();
				ClassInjector.RegisterTypeInIl2Cpp<ClusterPuzzleData>();
				if (ConfigManager.CustomContent.ScanHolder != null)
				{
					InitScans(manager);
					InitClusters(manager);
				}
			}
		}

		private static void InitScans(ChainedPuzzleManager manager)
		{
			//IL_00fd: 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)
			if ((Object)(object)manager == (Object)null)
			{
				Log.Error("Attempted to initialize custom bioscans with a null ChainedPuzzleManager. This should not happen!");
				throw new NullReferenceException("ChainedPuzzleManager was null");
			}
			foreach (CustomBioScan scan in ConfigManager.CustomContent.ScanHolder.Scans)
			{
				Log.Debug($"Adding scan with ID of [{scan.PersistentID}]");
				if (!manager.m_puzzleComponentPrefabs.ContainsKey(scan.BaseScan))
				{
					Log.Error($"Custom scan with persistent ID {scan.PersistentID} references a non-existing base scan of persistent ID {scan.BaseScan}");
					continue;
				}
				GameObject val = manager.m_puzzleComponentPrefabs[scan.BaseScan];
				if ((Object)(object)val.GetComponent<CP_Bioscan_Core>() == (Object)null)
				{
					Log.Error(string.Format("BaseScan id: {0} does not have {1} component!", scan.PersistentID, "CP_Bioscan_Core"));
					continue;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val);
				val2.transform.position = new Vector3(10000f, 10000f, 10000f);
				CP_PlayerScanner component = val2.GetComponent<CP_PlayerScanner>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_reduceSpeed = scan.ReduceSpeed;
					component.m_reduceWhenNoPlayer = scan.ReduceWhenNoPlayer;
					component.m_scanRadius = scan.ScanRadius;
					component.m_scanSpeeds = Il2CppStructArray<float>.op_Implicit(scan.PlayersInScanMulti);
					component.m_playerRequirement = scan.PlayerRequirement;
				}
				else
				{
					Log.Warn(string.Format("BaseScan id: {0} does not have {1} component! This will make following setting won't work!", scan.BaseScan, "CP_PlayerScanner"));
					Log.Warn(" - ReduceSpeed");
					Log.Warn(" - ReduceWhenNoPlayer");
					Log.Warn(" - ScanRadius");
					Log.Warn(" - PlayersInScanMulti");
					Log.Warn(" - PlayerRequirement");
				}
				CP_Bioscan_Graphics component2 = val2.GetComponent<CP_Bioscan_Graphics>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.m_radius = scan.BioScanGraphics.Radius;
					component2.m_colors = Il2CppReferenceArray<ColorModeColor>.op_Implicit(ConvertToColorMode(scan.BioScanGraphics.ColorModeColor));
					component2.SetText(scan.BioScanGraphics.ScanText);
				}
				else
				{
					Log.Warn(string.Format("BaseScan id: {0} does not have {1} component! This will make {2} setting won't work!", scan.BaseScan, "CP_Bioscan_Graphics", "BioScanGraphics"));
				}
				val2.GetComponent<CP_Bioscan_Core>().m_playerAgents = new List<PlayerAgent>();
				val2.AddComponent<CorePuzzleData>().PersistentID.Set(scan.PersistentID);
				s_scanMap.Add(scan.PersistentID, scan);
				manager.m_puzzleComponentPrefabs.Add(scan.PersistentID, val2);
			}
		}

		private static void InitClusters(ChainedPuzzleManager manager)
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)manager == (Object)null)
			{
				Log.Error("Attempted to initialize custom clusters with a null ChainedPuzzleManager. This should not happen!");
				throw new NullReferenceException("ChainedPuzzleManager was null");
			}
			foreach (CustomClusterScan cluster in ConfigManager.CustomContent.ScanHolder.Clusters)
			{
				Log.Debug($"Adding cluster with ID of [{cluster.PersistentID}]");
				if (!manager.m_puzzleComponentPrefabs.ContainsKey(cluster.BaseCluster))
				{
					Log.Error($"Custom cluster scan with persistent ID {cluster.PersistentID} references a non-existing base cluster of persistent ID {cluster.BaseCluster}");
					continue;
				}
				if (!manager.m_puzzleComponentPrefabs.ContainsKey(cluster.BioscanID))
				{
					Log.Error($"Custom cluster scan with persistent ID {cluster.PersistentID} references a non-existing bioscan of persistent ID {cluster.BioscanID}");
					continue;
				}
				GameObject val = manager.m_puzzleComponentPrefabs[cluster.BaseCluster];
				if ((Object)(object)val.GetComponent<CP_Cluster_Core>() == (Object)null)
				{
					Log.Error(string.Format("BaseScan id: {0} does not have {1} component!", cluster.PersistentID, "CP_Cluster_Core"));
					continue;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val);
				val2.transform.position = new Vector3(1000f, 1000f, 1000f);
				CP_Cluster_Core component = val2.GetComponent<CP_Cluster_Core>();
				GameObject childPuzzlePrefab = manager.m_puzzleComponentPrefabs[cluster.BioscanID];
				component.m_amountOfPuzzles = cluster.ClusterCount;
				component.m_childPuzzlePrefab = childPuzzlePrefab;
				component.m_distanceBetween = cluster.DistanceBetweenScans;
				component.m_revealWithHoloPath = cluster.RevealWithHoloPath;
				val2.AddComponent<ClusterPuzzleData>().PersistentID.Set(cluster.PersistentID);
				s_clusterMap.Add(cluster.PersistentID, cluster);
				manager.m_puzzleComponentPrefabs.Add(cluster.PersistentID, val2);
			}
		}

		private static ColorModeColor[] ConvertToColorMode(CustomBioScan.BioScanColorByMode[] bioScanColorByModes)
		{
			//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_0031: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			ColorModeColor[] array = (ColorModeColor[])(object)new ColorModeColor[bioScanColorByModes.Length];
			for (int i = 0; i < bioScanColorByModes.Length; i++)
			{
				CustomBioScan.BioScanColorByMode bioScanColorByMode = bioScanColorByModes[i];
				array[i] = new ColorModeColor
				{
					col = new Color(bioScanColorByMode.R, bioScanColorByMode.G, bioScanColorByMode.B, bioScanColorByMode.A),
					mode = bioScanColorByMode.Mode
				};
			}
			return array;
		}
	}
}
namespace MTFO.CustomCP.Patches
{
	[HarmonyPatch(typeof(ChainedPuzzleManager), "OnAssetsLoaded")]
	internal static class Patch_PuzzleManager
	{
		internal static void Postfix(ChainedPuzzleManager __instance)
		{
			CustomPuzzleManager.Initialize(__instance);
		}
	}
	[HarmonyPatch(typeof(CP_Bioscan_Core), "Update")]
	internal static class FixNullRefSpam
	{
		internal static bool Prefix(CP_Bioscan_Core __instance)
		{
			//IL_000b: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			if (((Component)__instance).gameObject.transform.position.x > 9000f && ((Component)__instance).gameObject.transform.position.y > 9000f && ((Component)__instance).gameObject.transform.position.z > 9000f)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class Patch_SetupPuzzleCores
	{
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")]
		public static void SetupSpline(CP_Bioscan_Core __instance)
		{
			CorePuzzleData component = ((Component)__instance).GetComponent<CorePuzzleData>();
			if (!((Object)(object)component == (Object)null) && CustomPuzzleManager.TryGetScanByID(component.PersistentID.Value, out var scan))
			{
				CP_Holopath_Spline val = ((Il2CppObjectBase)__instance.m_spline).TryCast<CP_Holopath_Spline>();
				if ((Object)(object)val != (Object)null)
				{
					scan.ApplySplineRevealSpeed(val);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(CP_Cluster_Core), "Setup")]
		public static void SetupSpline(CP_Cluster_Core __instance)
		{
			ClusterPuzzleData component = ((Component)__instance).GetComponent<ClusterPuzzleData>();
			if (!((Object)(object)component == (Object)null) && CustomPuzzleManager.TryGetClusterByID(component.PersistentID.Value, out var cluster))
			{
				CP_Holopath_Spline val = ((Il2CppObjectBase)__instance.m_spline).TryCast<CP_Holopath_Spline>();
				if ((Object)(object)val != (Object)null)
				{
					cluster.ApplySplineRevealSpeed(val);
				}
			}
		}
	}
}
namespace MTFO.Custom
{
	public class GlowstickHolder
	{
		[JsonIgnore]
		public Dictionary<string, CustomGlowstick> GlowstickLookup;

		public List<GlowstickConfig> Glowsticks { get; set; }

		public void Setup()
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			GlowstickLookup = new Dictionary<string, CustomGlowstick>();
			foreach (GlowstickConfig glowstick in Glowsticks)
			{
				Log.Verbose(glowstick);
				if (GlowstickLookup.TryGetValue(glowstick.Name, out var value))
				{
					Log.Warn("Custom glowstick with name " + glowstick.Name + " already exists in the lookup! Skipping...");
					continue;
				}
				value = default(CustomGlowstick);
				value.Color = new Color(glowstick.r, glowstick.g, glowstick.b, (glowstick.a == 0f) ? 1f : glowstick.a);
				value.Range = ((glowstick.Range == 0f) ? 15f : glowstick.Range);
				CustomGlowstick value2 = value;
				GlowstickLookup.Add(glowstick.Name, value2);
			}
		}
	}
	public struct CustomGlowstick
	{
		public Color Color { get; set; }

		public float Range { get; set; }
	}
	public struct GlowstickConfig
	{
		public string Name { get; set; }

		public float Range { get; set; }

		public float r { get; set; }

		public float g { get; set; }

		public float b { get; set; }

		public float a { get; set; }

		public override string ToString()
		{
			return $"{Name},{Range},{r},{g},{b},{a}";
		}
	}
	public class ScanHolder
	{
		public List<CustomBioScan> Scans { get; set; }

		public List<CustomClusterScan> Clusters { get; set; }
	}
	public enum RevealMode
	{
		ScaleByDistance,
		ConstantTime,
		Instant
	}
	public struct CustomBioScan : IRevealableScanConfig
	{
		public struct BioScanGx
		{
			public bool HideScanText { get; set; }

			public string ScanText { get; set; }

			public float Radius { get; set; }

			public BioScanColorByMode[] ColorModeColor { get; set; }
		}

		public class BioScanColorByMode
		{
			public eChainedPuzzleGraphicsColorMode Mode { get; set; }

			public float R { get; set; }

			public float G { get; set; }

			public float B { get; set; }

			public float A { get; set; }
		}

		public uint BaseScan { get; set; }

		public uint PersistentID { get; set; }

		public PlayerRequirement PlayerRequirement { get; set; }

		public float ScanRadius { get; set; }

		public float[] PlayersInScanMulti { get; set; }

		public float ReduceSpeed { get; set; }

		public bool ReduceWhenNoPlayer { get; set; }

		public float RevealTime { get; set; }

		public RevealMode RevealMode { get; set; }

		public BioScanGx BioScanGraphics { get; set; }
	}
	public struct CustomClusterScan : IRevealableScanConfig
	{
		public uint BaseCluster { get; set; }

		public uint PersistentID { get; set; }

		public int ClusterCount { get; set; }

		public uint BioscanID { get; set; }

		public float DistanceBetweenScans { get; set; }

		public float RevealTime { get; set; }

		public RevealMode RevealMode { get; set; }

		public bool RevealWithHoloPath { get; set; }
	}
	internal interface IRevealableScanConfig
	{
		uint PersistentID { get; }

		float RevealTime { get; }

		RevealMode RevealMode { get; }
	}
	internal static class IRevealibleScanConfigExtensions
	{
		public static void ApplySplineRevealSpeed(this IRevealableScanConfig scan, CP_Holopath_Spline spline)
		{
			float revealTime = scan.RevealTime;
			switch (scan.RevealMode)
			{
			case RevealMode.ConstantTime:
				if (revealTime <= 0f)
				{
					Log.Warn($"Attempted to set a custom scan with persistent id '{scan.PersistentID}' to reveal in less than or equal to 0 seconds. This is not supported. Instead, use RevealMode \"{RevealMode.Instant}\" or integer value {2}");
					break;
				}
				spline.m_splineLength = 1f;
				spline.m_revealSpeed = revealTime;
				break;
			case RevealMode.ScaleByDistance:
				if (revealTime < 0f)
				{
					Log.Warn($"Attempted to set a custom scan with persistent id '{scan.PersistentID}' to reveal in less than 0 seconds. This is not supported.");
				}
				else if (revealTime != 0f)
				{
					spline.m_revealSpeed = revealTime;
				}
				break;
			case RevealMode.Instant:
				spline.m_revealSpeed = -1f;
				break;
			}
		}
	}
	public struct TierNames
	{
		public string Tier1 { get; set; }

		public string Tier2 { get; set; }

		public string Tier3 { get; set; }

		public string Tier4 { get; set; }

		public string Tier5 { get; set; }
	}
}
namespace MTFO.Custom.CCP.Patches
{
	[HarmonyPatch(typeof(CP_Bioscan_Hud))]
	internal static class Patch_Bioscan_Hud
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		internal static void Post_Setup(CP_Bioscan_Hud __instance)
		{
			UpdateText(__instance);
		}

		[HarmonyPatch("SetVisible")]
		[HarmonyPostfix]
		internal static void Post_SetVisible(CP_Bioscan_Hud __instance)
		{
			UpdateText(__instance);
		}

		[HarmonyPatch("UpdateText")]
		[HarmonyPostfix]
		internal static void Post_UpdateText(CP_Bioscan_Hud __instance)
		{
			UpdateText(__instance);
		}

		private static void UpdateText(CP_Bioscan_Hud hud)
		{
			CorePuzzleData component = ((Component)hud).gameObject.GetComponent<CorePuzzleData>();
			if ((Object)(object)component != (Object)null)
			{
				if (!CustomPuzzleManager.TryGetScanByID(component.PersistentID.Value, out var scan))
				{
					Log.Error($"scanData missing... {component.PersistentID.Value}");
				}
				else if (scan.BioScanGraphics.HideScanText)
				{
					((TMP_Text)hud.m_bioscanWorldText).SetText(string.Empty, true);
				}
				else if (!string.IsNullOrWhiteSpace(scan.BioScanGraphics.ScanText))
				{
					((TMP_Text)hud.m_bioscanWorldText).SetText(scan.BioScanGraphics.ScanText, true);
				}
			}
		}
	}
}
namespace MTFO.Custom.CCP.Components
{
	internal sealed class ClusterPuzzleData : MonoBehaviour
	{
		public Il2CppValueField<uint> PersistentID;

		public CP_Bioscan_Hud[] ChildHuds = Array.Empty<CP_Bioscan_Hud>();
	}
	internal sealed class CorePuzzleData : MonoBehaviour
	{
		public Il2CppValueField<uint> PersistentID;
	}
}
namespace MTFO.API
{
	public delegate void GameDataContentLoadEvent(string datablockName, string jsonContent, in List<string> jsonItemsToInject);
	public delegate void GameDataContentLoadedDelegate(string datablockName, string jsonContent);
	public static class MTFOGameDataAPI
	{
		public static event GameDataContentLoadEvent OnGameDataContentLoad;

		public static event GameDataContentLoadedDelegate OnGameDataContentLoaded;

		internal static void Invoke_OnGameDataContentLoad(string datablockName, Stream jsonContentStream, in List<string> jsonItemsToInject)
		{
			if (MTFOGameDataAPI.OnGameDataContentLoad != null)
			{
				MTFOGameDataAPI.OnGameDataContentLoad(datablockName, new StreamReader(jsonContentStream).ReadToEnd(), in jsonItemsToInject);
			}
		}

		internal static void Invoke_OnGameDataContentLoaded(string datablockName, string jsonContent)
		{
			MTFOGameDataAPI.OnGameDataContentLoaded?.Invoke(datablockName, jsonContent);
		}
	}
	public static class MTFOHotReloadAPI
	{
		public static bool HotReloadEnabled => ConfigManager.IsHotReloadEnabled;

		public static event Action OnHotReload;

		internal static void HotReloaded()
		{
			MTFOHotReloadAPI.OnHotReload?.Invoke();
		}
	}
	public static class MTFOPathAPI
	{
		public static string RundownPath => ConfigManager.GameDataPath;

		public static bool HasRundownPath => ConfigManager.HasGameDataPath;

		public static string CustomPath => ConfigManager.CustomPath;

		public static bool HasCustomPath => ConfigManager.HasCustomContent;
	}
}

plugins/net6/MTFO.Ext.PartialData.InjectLib.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using AIGraph;
using AssetShards;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using GTFO.API.Utilities;
using GameData;
using Gear;
using Globals;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppJsonNet;
using Il2CppJsonNet.Linq;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using InjectLib.JsonNETInjection;
using InjectLib.JsonNETInjection.Converter;
using LevelGeneration;
using Localization;
using MTFO.Ext.PartialData.DTO;
using MTFO.Ext.PartialData.DataBlockTypes;
using MTFO.Ext.PartialData.JsonConverters;
using MTFO.Ext.PartialData.JsonInjects;
using MTFO.Ext.PartialData.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MTFO.Ext.PartialData")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("MTFO.Ext.PartialData")]
[assembly: AssemblyTitle("MTFO.Ext.PartialData")]
[assembly: TargetPlatform("Windows7.0")]
[assembly: SupportedOSPlatform("Windows7.0")]
[assembly: AssemblyVersion("0.1.0.0")]
namespace MTFO.Ext.PartialData
{
	[BepInPlugin("MTFO.Extension.PartialBlocks", "MTFO pDataBlock", "1.4.0")]
	[BepInProcess("GTFO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class EntryPoint : BasePlugin
	{
		private bool once;

		public override void Load()
		{
			//IL_001b: 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_0036: Expected O, but got Unknown
			//IL_0036: Expected O, but got Unknown
			//IL_0047: 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_0062: Expected O, but got Unknown
			//IL_0062: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			Logger.LogInstance = ((BasePlugin)this).Log;
			ConfigEntry<bool> val = ((BasePlugin)this).Config.Bind<bool>(new ConfigDefinition("Logging", "UseLog"), false, new ConfigDescription("Using Log Message for Debug?", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<bool> obj = ((BasePlugin)this).Config.Bind<bool>(new ConfigDefinition("Developer", "UseLiveEdit"), false, new ConfigDescription("Using Live Edit?", (AcceptableValueBase)null, Array.Empty<object>()));
			Logger.UsingLog = val.Value;
			PartialDataManager.CanLiveEdit = obj.Value;
			if (!DataBlockTypeManager.Initialize())
			{
				Logger.Error("Unable to Initialize DataBlockTypeCache");
				return;
			}
			if (!PartialDataManager.Initialize())
			{
				Logger.Error("Unable to Initialize PartialData");
				return;
			}
			PersistentIDManager.DumpToFile(Path.Combine(PartialDataManager.PartialDataPath, "_persistentID.json"));
			AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)OnAssetLoaded);
			new Harmony("MTFO.pBlock.Harmony").PatchAll();
			JsonInjector.SetConverter<uint>((Il2CppJsonUnmanagedTypeConverter<uint>)new UintConverter());
		}

		private void OnAssetLoaded()
		{
			//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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (once)
			{
				return;
			}
			once = true;
			PartialDataManager.LoadPartialData();
			GameDataTextLocalizationService val = ((Il2CppObjectBase)Text.TextLocalizationService).Cast<GameDataTextLocalizationService>();
			val.m_textDataBlocks = null;
			val.m_texts.Clear();
			Language currentLanguage = Text.TextLocalizationService.CurrentLanguage;
			TextDataBlock[] array = Il2CppArrayBase<TextDataBlock>.op_Implicit(GameDataBlockBase<TextDataBlock>.GetAllBlocks());
			val.m_textDataBlocks = Il2CppReferenceArray<TextDataBlock>.op_Implicit(array);
			int num = array.Length;
			for (int i = 0; i < num; i++)
			{
				TextDataBlock val2 = array[i];
				string text = val2.GetText(currentLanguage, false);
				if (string.IsNullOrWhiteSpace(text))
				{
					text = val2.English;
				}
				val.m_texts[((GameDataBlockBase<TextDataBlock>)(object)val2).persistentID] = text;
			}
			Text.TextLocalizationService.SetCurrentLanguage(Text.TextLocalizationService.CurrentLanguage);
			Text.UpdateAllTexts();
			PartialDataManager.WriteAllFile(Path.Combine(MTFOUtil.GameDataPath, "CompiledPartialData"));
		}
	}
	public static class LocalizedTextManager
	{
		public static Dictionary<LocalizedText, (uint, string)> _lookup = new Dictionary<LocalizedText, (uint, string)>();

		public static void Register(LocalizedText localizedText, uint id, string unlocalized)
		{
			_lookup[localizedText] = (id, unlocalized);
		}

		public static void Get(LocalizedText localizedText)
		{
		}
	}
	internal class PartialDataCache
	{
		public string Name => DataBlockType.GetShortName();

		public IDataBlockType DataBlockType { get; private set; }

		public Queue<string> JsonsToRead { get; private set; } = new Queue<string>();


		private PartialDataCache()
		{
		}

		public PartialDataCache(IDataBlockType dbTypeCache)
		{
			DataBlockType = dbTypeCache;
		}
	}
	public class PartialDataManager
	{
		private static List<DataBlockDefinition> _Config;

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

		private static readonly List<PartialDataCache> _DataCache = new List<PartialDataCache>();

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

		public static bool Initialized { get; private set; } = false;


		public static bool CanLiveEdit { get; set; } = false;


		public static PersistentIDConverter IDConverter { get; private set; } = new PersistentIDConverter();


		internal static bool Initialize()
		{
			if (Initialized)
			{
				return false;
			}
			if (!MTFOUtil.IsLoaded)
			{
				return false;
			}
			PartialDataPath = Path.GetFullPath(Path.Combine(MTFOUtil.GameDataPath, "PartialData"));
			if (!Directory.Exists(PartialDataPath))
			{
				Logger.Error("Unable to setup PartialData::PartialData folder is missing");
				return false;
			}
			ConfigPath = Path.GetFullPath(Path.Combine(PartialDataPath, "_config.json"));
			if (!File.Exists(ConfigPath))
			{
				Logger.Error("Unable to setup PartialData::Config File (_config.json) is missing");
				return false;
			}
			_AddedFileList.Clear();
			_DataCache.Clear();
			_Config = JSON.Deserialize<List<DataBlockDefinition>>(File.ReadAllText(ConfigPath));
			Initialized = true;
			ReadAndAssignIDs();
			return true;
		}

		private static void ReadAndAssignIDs()
		{
			foreach (DataBlockDefinition item in _Config)
			{
				DataBlockTypeManager.SetIDBuffer(item.TypeName, item.StartFromID, item.IncrementMode);
			}
			foreach (string item2 in from f in Directory.GetFiles(PartialDataPath, "*.json", SearchOption.AllDirectories)
				orderby f
				select f)
			{
				if (Path.GetFileName(item2).StartsWith("_"))
				{
					Logger.Log(item2 + " have discard prefix (_) excluding from loader!");
					continue;
				}
				if (!File.Exists(item2))
				{
					Logger.Error("File (" + item2 + ") is not exist somehow?");
					continue;
				}
				if (_AddedFileList.Contains(item2))
				{
					Logger.Error("File (" + item2 + ") has loaded multiple times!");
					continue;
				}
				_AddedFileList.Add(item2);
				AssignPersistentID(item2);
				Logger.Log(" - " + item2);
			}
		}

		private static void AssignPersistentID(string file)
		{
			using JsonDocument jsonDocument = JsonDocument.Parse(File.ReadAllText(file), new JsonDocumentOptions
			{
				CommentHandling = JsonCommentHandling.Skip,
				AllowTrailingCommas = true
			});
			JsonElement rootElement = jsonDocument.RootElement;
			switch (rootElement.ValueKind)
			{
			case JsonValueKind.Array:
			{
				foreach (JsonElement item in rootElement.EnumerateArray())
				{
					Read(item, assignID: true, file);
				}
				break;
			}
			case JsonValueKind.Object:
				Read(rootElement, assignID: true, file);
				break;
			}
		}

		private static void ReadChangedFile(string content, string debugName)
		{
			using JsonDocument jsonDocument = JsonDocument.Parse(content, new JsonDocumentOptions
			{
				CommentHandling = JsonCommentHandling.Skip,
				AllowTrailingCommas = true
			});
			JsonElement rootElement = jsonDocument.RootElement;
			switch (rootElement.ValueKind)
			{
			case JsonValueKind.Array:
			{
				foreach (JsonElement item in rootElement.EnumerateArray())
				{
					Read(item, assignID: false, debugName);
				}
				break;
			}
			case JsonValueKind.Object:
				Read(rootElement, assignID: false, debugName);
				break;
			}
		}

		private static void ReadChangedFile(string file)
		{
			ReadChangedFile(File.ReadAllText(file), file);
		}

		private static void Read(JsonElement objNode, bool assignID, string debugName)
		{
			if (!objNode.TryGetProperty("persistentID", out var value))
			{
				Logger.Error("persistentID field is missing: " + debugName);
				return;
			}
			if (!objNode.TryGetProperty("datablock", out var value2))
			{
				Logger.Error("datablock field is missing: " + debugName);
				return;
			}
			if (assignID && value.ValueKind == JsonValueKind.String)
			{
				if (!DataBlockTypeManager.TryGetNextID(value2.GetString(), out var id))
				{
					Logger.Error($"datablock field is not valid: {debugName} {objNode}");
					return;
				}
				PersistentIDManager.TryAssignId(value.GetString(), id);
			}
			string datablockName = DataBlockTypeManager.GetBlockName(value2.GetString());
			if (!DataBlockTypeManager.TryFindCache(datablockName, out var cache))
			{
				Logger.Error($"datablock field is not valid: {debugName} {objNode}");
				return;
			}
			PartialDataCache partialDataCache = _DataCache.FirstOrDefault((PartialDataCache x) => x.Name.Equals(datablockName));
			if (partialDataCache == null)
			{
				partialDataCache = new PartialDataCache(cache);
				_DataCache.Add(partialDataCache);
			}
			partialDataCache.JsonsToRead.Enqueue(objNode.ToString());
		}

		internal static void LoadPartialData()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (Initialized)
			{
				if (CanLiveEdit)
				{
					LiveEdit.CreateListener(PartialDataPath, "*.json", true).FileChanged += new LiveEditEventHandler(Listener_FileChanged1);
				}
				AddAllCache();
			}
		}

		private static void Listener_FileChanged1(LiveEditEventArgs e)
		{
			Logger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				ReadChangedFile(content, e.FullPath);
				AddAllCache(isLiveEdit: true);
			});
		}

		internal static void WriteAllFile(string path)
		{
			if (!Directory.Exists(path))
			{
				return;
			}
			foreach (PartialDataCache item in _DataCache)
			{
				string fullPath = Path.GetFullPath(Path.Combine(path, "GameData_" + item.DataBlockType.GetFullName() + "_bin.json"));
				item.DataBlockType.DoSaveToDisk(fullPath);
			}
		}

		private static void AddAllCache(bool isLiveEdit = false)
		{
			foreach (PartialDataCache item in _DataCache)
			{
				bool flag = false;
				while (item.JsonsToRead.Count > 0)
				{
					string json = item.JsonsToRead.Dequeue();
					item.DataBlockType.AddJsonBlock(json);
					flag = true;
				}
				if (flag && isLiveEdit)
				{
					item.DataBlockType.OnChanged();
				}
			}
		}

		public static uint GetID(string guid)
		{
			if (!Initialized)
			{
				return 0u;
			}
			return PersistentIDManager.GetId(guid);
		}
	}
	public class PartialDataPack
	{
		private readonly List<string> _AddedFiles = new List<string>();

		private readonly List<PartialDataCache> _DataCaches = new List<PartialDataCache>();

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


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


		public PartialDataPack()
		{
		}

		public PartialDataPack(string namespaceString)
			: this()
		{
			Namespace = namespaceString;
		}

		public string GetGUIDFormat(string guid)
		{
			if (!string.IsNullOrEmpty(Namespace))
			{
				guid = Namespace + "." + guid;
			}
			return guid;
		}

		public void ClearPack()
		{
			_AddedFiles.Clear();
			_DataCaches.Clear();
		}

		public void ReadPack(string packPath)
		{
			foreach (string item in from f in Directory.GetFiles(packPath, "*.json", SearchOption.AllDirectories)
				orderby f
				select f)
			{
				if (Path.GetFileName(item).StartsWith("_"))
				{
					Logger.Log(item + " have discard prefix (_) excluding from loader!");
					continue;
				}
				if (!File.Exists(item))
				{
					Logger.Error("File (" + item + ") is not exist somehow?");
					continue;
				}
				if (_AddedFiles.Contains(item))
				{
					Logger.Error("File (" + item + ") has loaded multiple times!");
					continue;
				}
				_AddedFiles.Add(item);
				AllocateGUIDFromFile(item);
				Logger.Log(" - " + item);
			}
			_ = CheckFileChange;
		}

		public void AddToGame()
		{
			foreach (PartialDataCache dataCache in _DataCaches)
			{
				while (dataCache.JsonsToRead.Count > 0)
				{
					string json = dataCache.JsonsToRead.Dequeue();
					dataCache.DataBlockType.AddJsonBlock(json);
				}
			}
		}

		public void WriteGameDataFile(string path)
		{
			if (!Directory.Exists(path))
			{
				return;
			}
			foreach (PartialDataCache dataCache in _DataCaches)
			{
				string fullPath = Path.GetFullPath(Path.Combine(path, "GameData_" + dataCache.DataBlockType.GetFullName() + "_bin.json"));
				dataCache.DataBlockType.DoSaveToDisk(fullPath);
			}
		}

		private void AllocateGUIDFromFile(string file)
		{
			using JsonDocument jsonDocument = JsonDocument.Parse(File.ReadAllText(file), new JsonDocumentOptions
			{
				CommentHandling = JsonCommentHandling.Skip,
				AllowTrailingCommas = true
			});
			JsonElement rootElement = jsonDocument.RootElement;
			switch (rootElement.ValueKind)
			{
			case JsonValueKind.Array:
			{
				foreach (JsonElement item in rootElement.EnumerateArray())
				{
					Read(item, assignID: true, file);
				}
				break;
			}
			case JsonValueKind.Object:
				Read(rootElement, assignID: true, file);
				break;
			}
		}

		private void ReadChangedFile(string file)
		{
			using JsonDocument jsonDocument = JsonDocument.Parse(File.ReadAllText(file), new JsonDocumentOptions
			{
				CommentHandling = JsonCommentHandling.Skip,
				AllowTrailingCommas = true
			});
			JsonElement rootElement = jsonDocument.RootElement;
			switch (rootElement.ValueKind)
			{
			case JsonValueKind.Array:
			{
				foreach (JsonElement item in rootElement.EnumerateArray())
				{
					Read(item, assignID: false, file);
				}
				break;
			}
			case JsonValueKind.Object:
				Read(rootElement, assignID: false, file);
				break;
			}
		}

		private void OnDatablockChanged()
		{
			foreach (PartialDataCache dataCache in _DataCaches)
			{
				bool flag = false;
				while (dataCache.JsonsToRead.Count > 0)
				{
					if (dataCache.Name.Equals("Rundown"))
					{
						dataCache.JsonsToRead.Clear();
						Logger.Error("Editing Rundown DataBlock will leads to crash, Ignored");
					}
					else
					{
						string json = dataCache.JsonsToRead.Dequeue();
						dataCache.DataBlockType.AddJsonBlock(json);
						flag = true;
					}
				}
				if (flag)
				{
					dataCache.DataBlockType.OnChanged();
				}
			}
		}

		private void Read(JsonElement objNode, bool assignID, string debugName)
		{
			if (!objNode.TryGetProperty("persistentID", out var value))
			{
				Logger.Error("persistentID field is missing: " + debugName);
				return;
			}
			if (!objNode.TryGetProperty("datablock", out var value2))
			{
				Logger.Error("datablock field is missing: " + debugName);
				return;
			}
			if (assignID && value.ValueKind == JsonValueKind.String)
			{
				if (!DataBlockTypeManager.TryGetNextID(value2.GetString(), out var id))
				{
					Logger.Error($"datablock field is not valid: {debugName} {objNode}");
					return;
				}
				PersistentIDManager.TryAssignId(value.GetString(), id);
			}
			string datablockName = DataBlockTypeManager.GetBlockName(value2.GetString());
			if (!DataBlockTypeManager.TryFindCache(datablockName, out var cache))
			{
				Logger.Error($"datablock field is not valid: {debugName} {objNode}");
				return;
			}
			PartialDataCache partialDataCache = _DataCaches.FirstOrDefault((PartialDataCache x) => x.Name.Equals(datablockName));
			if (partialDataCache == null)
			{
				partialDataCache = new PartialDataCache(cache);
				_DataCaches.Add(partialDataCache);
			}
			string text = objNode.ToString();
			if (partialDataCache.DataBlockType.GetShortName() == "PlayerOfflineGear")
			{
				if (!objNode.TryGetProperty("GearJSON", out var value3))
				{
					Logger.Warning("GearJSON field is missing, Ignore Stuff: " + debugName);
				}
				else if (value3.ValueKind == JsonValueKind.String)
				{
					string @string = value3.GetString();
					if (GearJSONUtil.TryProcessGUID(@string, Namespace, out var processedJson))
					{
						@string = @string.Replace("\"", "\\\"");
						processedJson = processedJson.Replace("\"", "\\\"");
						text = text.Replace(@string, processedJson);
						Logger.Warning(text);
					}
				}
			}
			partialDataCache.JsonsToRead.Enqueue(text);
		}
	}
	internal static class PersistentIDManager
	{
		private static readonly Dictionary<string, uint> _GUIDDict = new Dictionary<string, uint>();

		public static bool TryAssignId(string guid, uint id)
		{
			if (_GUIDDict.ContainsKey(guid))
			{
				Logger.Error("GUID is already used: " + guid);
				return false;
			}
			_GUIDDict.Add(guid, id);
			return true;
		}

		public static uint GetId(string guid)
		{
			if (!_GUIDDict.TryGetValue(guid, out var value))
			{
				Logger.Error("GUID is Missing: " + guid);
				return 0u;
			}
			return value;
		}

		public static bool TryGetId(string guid, out uint id)
		{
			if (_GUIDDict.TryGetValue(guid, out id))
			{
				return true;
			}
			id = 0u;
			return false;
		}

		public static void DumpToFile(string path)
		{
			string text = "[\n\t//AUTO-GENERATED PERSISTENT ID LIST\n";
			foreach (KeyValuePair<string, uint> item in _GUIDDict)
			{
				text = text + "\t{ \"GUID\": \"" + item.Key + "\", \"ID\": " + item.Value + " },\n";
			}
			if (text.Length > 2)
			{
				string text2 = text;
				text = text2.Substring(0, text2.Length - 2);
			}
			text += "\n]";
			File.WriteAllText(path, text);
		}
	}
}
namespace MTFO.Ext.PartialData.Utils
{
	public static class GearJSONUtil
	{
		private const string COMP_CHARS = "abcdefghijklmnopqrst";

		public static bool TryProcessGUID(string gearjson, string namespaceStr, out string processedJson)
		{
			string text = gearjson;
			bool flag = false;
			using JsonDocument jsonDocument = JsonDocument.Parse(gearjson);
			if (!jsonDocument.RootElement.TryGetProperty("Packet", out var value))
			{
				processedJson = string.Empty;
				return false;
			}
			if (!value.TryGetProperty("Comps", out var value2))
			{
				processedJson = string.Empty;
				return false;
			}
			string text2 = "abcdefghijklmnopqrst";
			for (int i = 0; i < text2.Length; i++)
			{
				if (value2.TryGetProperty(text2[i].ToString(), out var value3) && value3.TryGetProperty("v", out var value4) && value4.ValueKind == JsonValueKind.String)
				{
					string @string = value4.GetString();
					Logger.Warning("Found String id: " + @string);
					uint id = PersistentIDManager.GetId(@string);
					if (id != 0)
					{
						text = new Regex("(\"v\")\\s*:\\s*(\"" + @string + "\")").Replace(text, $"\"v\":{id}");
						flag = true;
					}
				}
			}
			if (flag)
			{
				Logger.Warning(gearjson);
				Logger.Warning(text);
				processedJson = text;
				return true;
			}
			processedJson = string.Empty;
			return false;
		}
	}
	public class IDBuffer
	{
		public uint CurrentID { get; set; } = 65535u;


		public IncrementMode IncrementMode { get; set; }

		public uint GetNext()
		{
			if (IncrementMode == IncrementMode.Increment)
			{
				return CurrentID++;
			}
			if (IncrementMode == IncrementMode.Decrement)
			{
				return CurrentID--;
			}
			return 0u;
		}
	}
	public enum IncrementMode
	{
		Decrement,
		Increment
	}
	internal static class JSON
	{
		private static readonly JsonSerializerOptions _Setting;

		static JSON()
		{
			_Setting = CreateSetting();
			_Setting = CreateSetting();
			_Setting.Converters.Add(new PersistentIDConverter());
		}

		private static JsonSerializerOptions CreateSetting()
		{
			return new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = true,
				AllowTrailingCommas = true,
				WriteIndented = true,
				Converters = 
				{
					(JsonConverter)new Il2CppListConverterFactory(),
					(JsonConverter)new ColorConverter(),
					(JsonConverter)new JsonStringEnumConverter(),
					(JsonConverter)new LocalizedTextConverter()
				}
			};
		}

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

		public static object Deserialize(string json, Type type)
		{
			return JsonSerializer.Deserialize(json, type, _Setting);
		}
	}
	internal static class Logger
	{
		public static ManualLogSource LogInstance;

		public static bool UsingLog;

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

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

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

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

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

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

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

		public static void Debug(string str)
		{
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				logInstance.Log((LogLevel)32, (object)str);
			}
		}
	}
	internal static class MTFOUtil
	{
		public const string MTFOGUID = "com.dak.MTFO";

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

		static MTFOUtil()
		{
			GameDataPath = string.Empty;
			CustomPath = string.Empty;
			HasCustomContent = false;
			IsLoaded = false;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var info))
			{
				return;
			}
			try
			{
				Type obj = (AppDomain.CurrentDomain.GetAssemblies().First((Assembly a) => !a.IsDynamic && a.Location == info.Location) ?? throw new Exception("Assembly is Missing!")).GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
				FieldInfo field = obj.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = obj.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo? field3 = obj.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				IsLoaded = true;
			}
			catch (Exception value)
			{
				Console.WriteLine($"Exception thrown while reading path from Data Dumper (MTFO):\n{value}");
			}
		}
	}
}
namespace MTFO.Ext.PartialData.JsonInjects
{
	internal class UintConverter : Il2CppJsonUnmanagedTypeConverter<uint>
	{
		protected override uint Read(JToken jToken, uint existingValue, JsonSerializer serializer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			if ((int)jToken.Type == 6)
			{
				return (uint)jToken;
			}
			if ((int)jToken.Type == 8)
			{
				return PartialDataManager.GetID((string)jToken);
			}
			Logger.Error($"{jToken} is not valid!");
			return existingValue;
		}

		protected override Object ToIl2CppObject(uint value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			UInt32 val = default(UInt32);
			val.m_value = value;
			return ((UInt32)(ref val)).BoxIl2CppObject();
		}

		protected override void Write(JsonWriter writer, uint value, JsonSerializer serializer)
		{
			writer.WriteValue(value);
		}
	}
}
namespace MTFO.Ext.PartialData.JsonConverters
{
	internal class ColorConverter : JsonConverter<Color>
	{
		public override bool HandleNull => false;

		public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0002: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			switch (reader.TokenType)
			{
			case JsonTokenType.StartObject:
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return result;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string? @string = reader.GetString();
					reader.Read();
					switch (@string.ToLower())
					{
					case "r":
						result.r = reader.GetSingle();
						break;
					case "g":
						result.g = reader.GetSingle();
						break;
					case "b":
						result.b = reader.GetSingle();
						break;
					case "a":
						result.a = reader.GetSingle();
						break;
					}
				}
				throw new JsonException("Expected EndObject token");
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				if (ColorUtility.TryParseHtmlString(text, ref result))
				{
					return result;
				}
				throw new JsonException("Color format is not right: " + text);
			}
			default:
				throw new JsonException($"ColorJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			JsonSerializer.Serialize<Color>(writer, value, options);
		}
	}
	internal class Il2CppListConverter<T> : JsonConverter<List<T>>
	{
		public override bool HandleNull => false;

		public override List<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			List<T> val = new List<T>();
			if (reader.TokenType == JsonTokenType.StartArray)
			{
				foreach (T item in JsonSerializer.Deserialize<List<T>>(ref reader, options))
				{
					val.Add(item);
				}
				return val;
			}
			return null;
		}

		public override void Write(Utf8JsonWriter writer, List<T> value, JsonSerializerOptions options)
		{
			writer.WriteStartArray();
			Enumerator<T> enumerator = value.GetEnumerator();
			while (enumerator.MoveNext())
			{
				T current = enumerator.Current;
				JsonSerializer.Serialize(writer, current, options);
			}
			writer.WriteEndArray();
		}
	}
	internal class Il2CppListConverterFactory : JsonConverterFactory
	{
		public override bool CanConvert(Type typeToConvert)
		{
			if (!typeToConvert.IsGenericType)
			{
				return false;
			}
			if (typeToConvert.GetGenericTypeDefinition() != typeof(List<>))
			{
				return false;
			}
			return true;
		}

		public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
		{
			Type type = typeToConvert.GetGenericArguments()[0];
			return (JsonConverter)Activator.CreateInstance(typeof(Il2CppListConverter<>).MakeGenericType(type), BindingFlags.Instance | BindingFlags.Public, null, null, null);
		}
	}
	internal class LocalizedTextConverter : JsonConverter<LocalizedText>
	{
		public override bool HandleNull => false;

		public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_004a: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string @string = reader.GetString();
				if (!PersistentIDManager.TryGetId(@string, out var id))
				{
					return new LocalizedText
					{
						Id = 0u,
						UntranslatedText = @string
					};
				}
				return new LocalizedText
				{
					Id = id,
					UntranslatedText = null
				};
			}
			case JsonTokenType.Number:
				return new LocalizedText
				{
					Id = reader.GetUInt32(),
					UntranslatedText = null
				};
			default:
				throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
		{
			JsonSerializer.Serialize<LocalizedText>(writer, value, options);
		}
	}
	public class PersistentIDConverter : JsonConverter<uint>
	{
		public override uint Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			if (reader.TokenType == JsonTokenType.String)
			{
				return PersistentIDManager.GetId(reader.GetString());
			}
			if (reader.TokenType == JsonTokenType.Number)
			{
				return reader.GetUInt32();
			}
			throw new JsonException("TOKEN IS NOT VALID!");
		}

		public override void Write(Utf8JsonWriter writer, uint value, JsonSerializerOptions options)
		{
			writer.WriteNumberValue(value);
		}
	}
	internal class Vector2Converter : JsonConverter<Vector2>
	{
		public override Vector2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return JsonSerializer.Deserialize<Vector2>(ref reader);
		}

		public override void Write(Utf8JsonWriter writer, Vector2 value, JsonSerializerOptions options)
		{
			//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)
			writer.WriteStartObject();
			writer.WriteNumber("x", value.x);
			writer.WriteNumber("y", value.y);
			writer.WriteEndObject();
		}
	}
}
namespace MTFO.Ext.PartialData.Injects
{
	[HarmonyPatch(typeof(GearManager))]
	internal class Inject_GearManager
	{
		private const string COMP_CHARS = "abcdefghijklmnopqrst";

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("LoadOfflineGearDatas")]
		private static void Pre_LoadOfflineGearDatas()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocks())
			{
				if (!((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).internalEnabled || string.IsNullOrEmpty(allBlock.GearJSON) || ((int)allBlock.Type != 1 && (int)allBlock.Type != 2))
				{
					continue;
				}
				string text = allBlock.GearJSON;
				bool flag = false;
				using JsonDocument jsonDocument = JsonDocument.Parse(allBlock.GearJSON);
				if (!jsonDocument.RootElement.TryGetProperty("Packet", out var value) || !value.TryGetProperty("Comps", out var value2))
				{
					continue;
				}
				string text2 = "abcdefghijklmnopqrst";
				for (int i = 0; i < text2.Length; i++)
				{
					if (value2.TryGetProperty(text2[i].ToString(), out var value3) && value3.TryGetProperty("v", out var value4) && value4.ValueKind == JsonValueKind.String)
					{
						string @string = value4.GetString();
						Logger.Warning("Found String id: " + @string);
						uint id = PersistentIDManager.GetId(@string);
						if (id != 0)
						{
							text = new Regex("(\"v\")\\s*:\\s*(\"" + @string + "\")").Replace(text, $"\"v\":{id}");
							flag = true;
						}
					}
				}
				if (flag)
				{
					Logger.Warning(allBlock.GearJSON);
					Logger.Warning(text);
					allBlock.GearJSON = text;
				}
			}
		}
	}
}
namespace MTFO.Ext.PartialData.DTO
{
	internal class DataBlockDefinition
	{
		public string TypeName { get; set; } = "DataBlock?";


		public uint StartFromID { get; set; } = 65535u;


		public IncrementMode IncrementMode { get; set; }
	}
	internal class DatapackConfig
	{
		public string PackName { get; set; } = string.Empty;


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


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

	}
}
namespace MTFO.Ext.PartialData.DataBlockTypes
{
	internal static class DataBlockTypeManager
	{
		private static readonly List<IDataBlockType> _DataBlockCache = new List<IDataBlockType>();

		private static readonly List<IDBuffer> _DataBlockIdBuffers = new List<IDBuffer>();

		public static bool Initialize()
		{
			try
			{
				Assembly assembly = (from a in AppDomain.CurrentDomain.GetAssemblies()
					where !a.IsDynamic && a.Location.Contains("interop", StringComparison.InvariantCultureIgnoreCase)
					select a).First((Assembly a) => a.Location.EndsWith("Modules-ASM.dll", StringComparison.InvariantCultureIgnoreCase));
				List<Type> list = new List<Type>();
				foreach (Type exportedType in assembly.ExportedTypes)
				{
					if (!(exportedType == null) && !string.IsNullOrEmpty(exportedType.Namespace) && exportedType.Namespace.Equals("GameData"))
					{
						Type baseType = exportedType.BaseType;
						if (!(baseType == null) && baseType.Name.Equals("GameDataBlockBase`1"))
						{
							list.Add(exportedType);
						}
					}
				}
				Type typeFromHandle = typeof(DataBlockTypeWrapper<>);
				foreach (Type item in list)
				{
					IDataBlockType dataBlockType = (IDataBlockType)Activator.CreateInstance(typeFromHandle.MakeGenericType(item));
					AssignForceChangeMethod(dataBlockType);
					_DataBlockCache.Add(dataBlockType);
					_DataBlockIdBuffers.Add(new IDBuffer());
				}
				return true;
			}
			catch (Exception value)
			{
				Logger.Error($"Can't make cache from Modules-ASM.dll!: {value}");
				return false;
			}
		}

		public static void AssignForceChangeMethod(IDataBlockType blockTypeCache)
		{
			switch (blockTypeCache.GetShortName().ToLower())
			{
			case "rundown":
				blockTypeCache.RegisterOnChangeEvent(delegate
				{
					CM_PageRundown_New pageRundownNew = MainMenuGuiLayer.Current.PageRundownNew;
					pageRundownNew.m_dataIsSetup = false;
					try
					{
						clearIcon(pageRundownNew.m_expIconsTier1);
						clearIcon(pageRundownNew.m_expIconsTier2);
						clearIcon(pageRundownNew.m_expIconsTier3);
						clearIcon(pageRundownNew.m_expIconsTier4);
						clearIcon(pageRundownNew.m_expIconsTier5);
						clearIcon(pageRundownNew.m_expIconsTierExt);
					}
					catch (Exception value)
					{
						Logger.Error($"{value}");
					}
					pageRundownNew.m_currentRundownData = GameDataBlockBase<RundownDataBlock>.GetBlock(Global.RundownIdToLoad);
					if (pageRundownNew.m_currentRundownData != null)
					{
						pageRundownNew.PlaceRundown(pageRundownNew.m_currentRundownData);
						pageRundownNew.m_dataIsSetup = true;
					}
				});
				break;
			case "fogsettings":
				blockTypeCache.RegisterOnChangeEvent(delegate
				{
					if (Builder.CurrentFloor.IsBuilt)
					{
						pEnvironmentState state = EnvironmentStateManager.Current.m_stateReplicator.State;
						EnvironmentStateManager.Current.UpdateFogSettingsForState(state);
					}
				});
				break;
			case "lightsettings":
				blockTypeCache.RegisterOnChangeEvent(delegate
				{
					if (Builder.CurrentFloor.IsBuilt)
					{
						Enumerator<LG_Zone> enumerator2 = Builder.CurrentFloor.allZones.GetEnumerator();
						while (enumerator2.MoveNext())
						{
							LG_Zone current2 = enumerator2.Current;
							Enumerator<AIG_CourseNode> enumerator3 = current2.m_courseNodes.GetEnumerator();
							while (enumerator3.MoveNext())
							{
								AIG_CourseNode current3 = enumerator3.Current;
								LG_BuildZoneLightsJob.ApplyLightSettings(0u, current3.m_lightsInNode, current2.m_lightSettings, false);
							}
						}
					}
				});
				break;
			}
			static void clearIcon(List<CM_ExpeditionIcon_New> tier)
			{
				if (tier != null)
				{
					Enumerator<CM_ExpeditionIcon_New> enumerator = tier.GetEnumerator();
					while (enumerator.MoveNext())
					{
						CM_ExpeditionIcon_New current = enumerator.Current;
						if ((Object)(object)((Component)current).gameObject != (Object)null)
						{
							Object.Destroy((Object)(object)((Component)current).gameObject);
						}
					}
				}
			}
		}

		public static bool TryFindCache(string blockTypeName, out IDataBlockType cache)
		{
			int index = GetIndex(blockTypeName);
			if (index != -1)
			{
				cache = _DataBlockCache[index];
				return true;
			}
			cache = null;
			return false;
		}

		public static bool TryGetNextID(string blockTypeName, out uint id)
		{
			int index = GetIndex(blockTypeName);
			if (index != -1)
			{
				id = _DataBlockIdBuffers[index].GetNext();
				return true;
			}
			id = 0u;
			return false;
		}

		public static void SetIDBuffer(string blockTypeName, uint id)
		{
			int index = GetIndex(blockTypeName);
			if (index != -1)
			{
				_DataBlockIdBuffers[index].CurrentID = id;
			}
		}

		public static void SetIDBuffer(string blockTypeName, uint id, IncrementMode mode)
		{
			int index = GetIndex(blockTypeName);
			if (index != -1)
			{
				IDBuffer iDBuffer = _DataBlockIdBuffers[index];
				iDBuffer.CurrentID = id;
				iDBuffer.IncrementMode = mode;
			}
		}

		private static int GetIndex(string blockTypeName)
		{
			blockTypeName = GetBlockName(blockTypeName);
			return _DataBlockCache.FindIndex((IDataBlockType x) => x.GetShortName().Equals(blockTypeName, StringComparison.OrdinalIgnoreCase));
		}

		public static string GetBlockName(string blockTypeName)
		{
			blockTypeName = blockTypeName.Trim();
			if (blockTypeName.EndsWith("DataBlock"))
			{
				string text = blockTypeName;
				blockTypeName = text.Substring(0, text.Length - 9);
			}
			return blockTypeName;
		}
	}
	internal class DataBlockTypeWrapper<T> : IDataBlockType where T : GameDataBlockBase<T>
	{
		public Action OnForceChange;

		public string FullName { get; private set; }

		public string ShortenName { get; private set; }

		public DataBlockTypeWrapper()
		{
			FullName = typeof(T).Name.Trim();
			ShortenName = FullName.Replace("DataBlock", "");
		}

		public void OnChanged()
		{
			OnForceChange?.Invoke();
		}

		public void AddBlock(T block)
		{
			T block2 = GameDataBlockBase<T>.GetBlock(((GameDataBlockBase<T>)block).persistentID);
			if (block2 != null)
			{
				CopyProperties(block, block2);
				Logger.Warning($"Replaced Block: {((GameDataBlockBase<T>)block2).persistentID}, {((GameDataBlockBase<T>)block2).name}");
			}
			else
			{
				GameDataBlockBase<T>.AddBlock(block, -1);
				Logger.Log($"Added Block: {((GameDataBlockBase<T>)block).persistentID}, {((GameDataBlockBase<T>)block).name}");
			}
		}

		public void AddJsonBlock(string json)
		{
			try
			{
				switch (JsonDocument.Parse(json, new JsonDocumentOptions
				{
					CommentHandling = JsonCommentHandling.Skip
				}).RootElement.ValueKind)
				{
				case JsonValueKind.Array:
				{
					T[] array = (T[])JSON.Deserialize(json, typeof(T).MakeArrayType());
					foreach (T block2 in array)
					{
						AddBlock(block2);
					}
					break;
				}
				case JsonValueKind.Object:
				{
					T block = (T)JSON.Deserialize(json, typeof(T));
					AddBlock(block);
					break;
				}
				}
			}
			catch (Exception value)
			{
				Logger.Error($"Error While Adding Block: {value}");
			}
		}

		public void DoSaveToDisk(string fullPath)
		{
			string filePathFull = GameDataBlockBase<T>.m_filePathFull;
			GameDataBlockBase<T>.m_filePathFull = fullPath;
			GameDataBlockBase<T>.DoSaveToDisk(false, false, true);
			GameDataBlockBase<T>.m_filePathFull = filePathFull;
		}

		private static object CopyProperties(object source, object target)
		{
			PropertyInfo[] properties = source.GetType().GetProperties();
			foreach (PropertyInfo sourceProp in properties)
			{
				Type propertyType = sourceProp.PropertyType;
				PropertyInfo propertyInfo = target.GetType().GetProperties().FirstOrDefault((PropertyInfo x) => x.Name == sourceProp.Name && x.PropertyType == sourceProp.PropertyType && x.CanWrite);
				if (propertyInfo != null && !sourceProp.Name.Contains("_k__BackingField"))
				{
					if (propertyType == typeof(IntPtr))
					{
						Logger.Error("Pointer has detected on CopyProperties!!!!");
					}
					else
					{
						propertyInfo.SetValue(target, sourceProp.GetValue(source));
					}
				}
			}
			return target;
		}

		public string GetShortName()
		{
			return ShortenName;
		}

		public string GetFullName()
		{
			return FullName;
		}

		public void RegisterOnChangeEvent(Action onChanged)
		{
			OnForceChange = (Action)Delegate.Combine(OnForceChange, onChanged);
		}
	}
	internal interface IDataBlockType
	{
		string GetShortName();

		string GetFullName();

		void DoSaveToDisk(string fullPath);

		void AddJsonBlock(string json);

		void OnChanged();

		void RegisterOnChangeEvent(Action onChanged);
	}
}

plugins/net6/PrequelCore.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using AIGraph;
using AK;
using Agents;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using ChainedPuzzles;
using EOSExt.Reactor.Managers;
using Enemies;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.ExtendedWardenEvents;
using ExtraObjectiveSetup.Instances;
using GTFO.API;
using GTFO.API.JSON.Converters;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LEGACY.ExtraEvents;
using LEGACY.LegacyOverride;
using LEGACY.LegacyOverride.ElevatorCargo;
using LEGACY.LegacyOverride.EnemyTagger;
using LEGACY.LegacyOverride.ExtraExpeditionSettings;
using LEGACY.LegacyOverride.FogBeacon;
using LEGACY.LegacyOverride.SecDoorIntText;
using LEGACY.Utils;
using LevelGeneration;
using Localization;
using MTFO.API;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using ScanPosOverride.Managers;
using TMPro;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[HarmonyPatch(typeof(PUI_Watermark), "UpdateWatermark")]
internal static class Patch_WatermarkUpdateWatermark
{
	private static void Postfix(PUI_Watermark __instance)
	{
		string text = "4.6.1+gitf831086-dirty-main".Remove("x.x.x".Length);
		((TMP_Text)__instance.m_watermarkText).SetText("<color=red>MODDED</color> <color=orange>" + text + "</color>\n<color=#FF6781>criscriscris</color>", true);
	}
}
namespace LEGACY
{
	[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("Inas07.PREQUELCore", "PREQUELCore", "2.0.1")]
	[BepInIncompatibility("Inas.LEGACY")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas07";

		public const string RUNDOWN_NAME = "PREQUELCore";

		public const string VERSION = "2.0.1";

		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			m_Harmony = new Harmony("LEGACY");
			m_Harmony.PatchAll();
			LegacyOverrideManagers.Init();
			LegacyExtraEvents.Init();
		}
	}
}
namespace LEGACY.Reactor
{
	[HarmonyPatch]
	internal class Patch_ReactorShutdown
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")]
		private static void Post_OnStateChange(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState)
		{
			//IL_000a: 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_0011: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected I4, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			if ((Object)(object)__instance == (Object)null || oldState.status == newState.status)
			{
				return;
			}
			WardenObjectiveDataBlock val = null;
			if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null)
			{
				LegacyLogger.Error("Patch_ReactorShutdown: ");
				LegacyLogger.Error("Failed to get warden objective");
			}
			else if ((int)val.Type == 2 && !val.OnActivateOnSolveItem)
			{
				eWardenObjectiveEventTrigger val2 = (eWardenObjectiveEventTrigger)0;
				eReactorStatus status = newState.status;
				switch (status - 7)
				{
				default:
					return;
				case 0:
					val2 = (eWardenObjectiveEventTrigger)1;
					break;
				case 1:
					val2 = (eWardenObjectiveEventTrigger)2;
					break;
				case 2:
					val2 = (eWardenObjectiveEventTrigger)3;
					break;
				}
				_ = __instance.SpawnNode.LayerType;
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(val.EventsOnActivate, val2, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")]
		private static void Pre_OnBuildDone_ChainedPuzzleMidObjectiveFix(LG_WardenObjective_Reactor __instance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			WardenObjectiveDataBlock val = null;
			if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null)
			{
				LegacyLogger.Error("Patch_ReactorShutdown: Failed to get warden objective");
			}
			else if (val.ChainedPuzzleMidObjective != 0)
			{
				__instance.m_chainedPuzzleAlignMidObjective = __instance.m_chainedPuzzleAlign;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Update")]
		private static bool Pre_Update(LG_WardenObjective_Reactor __instance)
		{
			//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_000c: Invalid comparison between Unknown and I4
			if ((int)__instance.m_currentState.status != 7)
			{
				return true;
			}
			if (!__instance.m_currentWaveData.HasVerificationTerminal)
			{
				return true;
			}
			__instance.SetGUIMessage(true, Text.Format(3000u, (Object[])(object)new Object[1] { Object.op_Implicit("<color=orange>" + __instance.m_currentWaveData.VerificationTerminalSerial + "</color>") }), (ePUIMessageStyle)3, false, "", "");
			return false;
		}
	}
	[HarmonyPatch]
	internal class Patch_ReactorStartup_ExtraEventsExecution
	{
		[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);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")]
		private static void Post_ExecuteOnNoneEventsOnDefenseStart(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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
			if (oldState.status != newState.status && (int)newState.status == 3)
			{
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)0, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")]
		private static void Post_OnBuildDone(LG_WardenObjective_Reactor __instance)
		{
			//IL_0011: 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_004c: Invalid comparison between Unknown and I4
			WardenObjectiveDataBlock db = default(WardenObjectiveDataBlock);
			if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref db) || db == null)
			{
				LegacyLogger.Error("Patch_ReactorStartup_ExtraEventsExecution: ");
				LegacyLogger.Error("Failed to get warden objective");
			}
			else if ((int)db.Type == 1 && !db.OnActivateOnSolveItem)
			{
				ChainedPuzzleInstance chainedPuzzleToStartSequence = __instance.m_chainedPuzzleToStartSequence;
				chainedPuzzleToStartSequence.OnPuzzleSolved += Action.op_Implicit((Action)delegate
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(db.EventsOnActivate, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
				});
			}
		}
	}
}
namespace LEGACY.VanillaFix
{
	[HarmonyPatch]
	internal class Patch_FixHiddenCommandExecution
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")]
		private static void Pre_TerminalInterpreter_ReceiveCommand(LG_ComputerTerminalCommandInterpreter __instance, ref TERM_Command cmd)
		{
			//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_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected I4, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			TERM_Command val = cmd;
			switch (val - 1)
			{
			default:
				if ((int)val != 43)
				{
					break;
				}
				goto case 0;
			case 0:
			case 1:
			case 2:
			case 3:
			case 11:
			case 13:
			case 14:
			case 17:
			case 18:
			case 19:
			case 20:
			case 21:
			case 22:
			case 23:
			case 24:
			case 25:
			case 26:
			case 27:
			case 28:
				if (__instance.m_terminal.CommandIsHidden(cmd))
				{
					cmd = (TERM_Command)10;
				}
				break;
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 12:
			case 15:
			case 16:
				break;
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_FixScoutFreeze
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")]
		private static bool Prefix_Debug(ES_ScoutScream __instance)
		{
			if (((AgentAI)((ES_Base)__instance).m_ai).Target == null)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal class Patch_LG_SecurityDoor_Fix_EventsOnUnlockDoor_Powergenerator
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(LG_SecurityDoor), "OnSyncDoorStatusChange")]
		private static void Pre_OnSyncDoorStatusChange(LG_SecurityDoor __instance, pDoorState state, bool isRecall)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//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_001e: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			eDoorStatus status = state.status;
			if ((status - 4 <= 1 || (int)status == 9) && (int)__instance.m_lastState.status == 6)
			{
				WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.LinkedToZoneData.EventsOnUnlockDoor, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null);
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_LockSecurityDoor_FixCustomText
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_SecurityDoor_Locks), "Setup", new Type[] { typeof(LG_SecurityDoor) })]
		private static void Post_LG_SecurityDoor_Locks_Setup(LG_SecurityDoor door, LG_SecurityDoor_Locks __instance)
		{
			LocalizedText customText = door.LinkedToZoneData.ProgressionPuzzleToEnter.CustomText;
			__instance.m_lockedWithNoKeyInteractionText = customText;
		}
	}
	[HarmonyPatch]
	[HarmonyWrapSafe]
	internal class Patch_RepeatableCommandEventFix
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "SetupCommandEvents")]
		private static void Post_ResetupChainedPuzzleAfterExecution(LG_ComputerTerminalCommandInterpreter __instance)
		{
			//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_0052: Expected I4, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Invalid comparison between Unknown and I4
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Invalid comparison between Unknown and I4
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Invalid comparison between Unknown and I4
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Invalid comparison between Unknown and I4
			//IL_01df: 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_01ae: Invalid comparison between Unknown and I4
			uint num = 0u;
			if ((Object)(object)__instance.m_terminal.ConnectedReactor != (Object)null)
			{
				return;
			}
			if (__instance.m_terminal.SpawnNode.m_dimension.IsMainDimension)
			{
				LG_LayerType layerType = __instance.m_terminal.SpawnNode.LayerType;
				switch ((int)layerType)
				{
				case 0:
					num = RundownManager.ActiveExpedition.LevelLayoutData;
					break;
				case 1:
					num = RundownManager.ActiveExpedition.SecondaryLayout;
					break;
				case 2:
					num = RundownManager.ActiveExpedition.ThirdLayout;
					break;
				default:
					LegacyLogger.Error("Unimplemented layer type.");
					return;
				}
			}
			else
			{
				num = __instance.m_terminal.SpawnNode.m_dimension.DimensionData.LevelLayoutData;
			}
			LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(num);
			List<CustomTerminalCommand> val = null;
			int num2 = __instance.m_terminal.SpawnNode.m_zone.TerminalsSpawnedInZone.IndexOf(__instance.m_terminal);
			ExpeditionZoneData val2 = null;
			Enumerator<ExpeditionZoneData> enumerator = block.Zones.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ExpeditionZoneData current = enumerator.Current;
				if (current.LocalIndex == __instance.m_terminal.SpawnNode.m_zone.LocalIndex)
				{
					val2 = current;
					break;
				}
			}
			if (val2 == null)
			{
				LegacyLogger.Error("Cannot find target zone data.");
				return;
			}
			if (num2 >= val2.TerminalPlacements.Count)
			{
				LegacyLogger.Debug("RepeatableCommand: TerminalDataIndex >= TargetZoneData.TerminalPlacements.Count: found sec-door terminal, skipping");
				return;
			}
			val = val2.TerminalPlacements[num2].UniqueCommands;
			if (val.Count == 0)
			{
				return;
			}
			Enumerator<CustomTerminalCommand> enumerator2 = val.GetEnumerator();
			TERM_Command val3 = default(TERM_Command);
			string text = default(string);
			string text2 = default(string);
			while (enumerator2.MoveNext())
			{
				CustomTerminalCommand current2 = enumerator2.Current;
				if ((int)current2.SpecialCommandRule != 0 || !__instance.TryGetCommand(current2.Command, ref val3, ref text, ref text2) || ((int)val3 != 38 && (int)val3 != 39 && (int)val3 != 40 && (int)val3 != 41 && (int)val3 != 42))
				{
					continue;
				}
				ChainedPuzzleInstance OldCPInstance = null;
				List<WardenObjectiveEventData> commandEvents = current2.CommandEvents;
				for (int i = 0; i < commandEvents.Count && (commandEvents[i].ChainPuzzle == 0 || !__instance.m_terminal.TryGetChainPuzzleForCommand(val3, i, ref OldCPInstance) || !((Object)(object)OldCPInstance != (Object)null)); i++)
				{
				}
				if (!((Object)(object)OldCPInstance == (Object)null))
				{
					ChainedPuzzleInstance obj = OldCPInstance;
					obj.OnPuzzleSolved += Action.op_Implicit((Action)delegate
					{
						Helper.ResetChainedPuzzle(OldCPInstance);
					});
				}
			}
		}
	}
}
namespace LEGACY.Utils
{
	public static class Helper
	{
		private static void ResetChild(iChainedPuzzleCore ICore)
		{
			CP_Bioscan_Core val = ((Il2CppObjectBase)ICore).TryCast<CP_Bioscan_Core>();
			if ((Object)(object)val != (Object)null)
			{
				((Il2CppObjectBase)val.m_spline).Cast<CP_Holopath_Spline>().SetSplineProgress(0f);
				((Il2CppObjectBase)val.PlayerScanner).Cast<CP_PlayerScanner>().ResetScanProgression(0f);
				return;
			}
			CP_Cluster_Core val2 = ((Il2CppObjectBase)ICore).TryCast<CP_Cluster_Core>();
			if ((Object)(object)val2 == (Object)null)
			{
				LegacyLogger.Error("ResetChild: found iChainedPuzzleCore that is neither CP_Bioscan_Core nor CP_Cluster_Core...");
				return;
			}
			((Il2CppObjectBase)val2.m_spline).Cast<CP_Holopath_Spline>().SetSplineProgress(0f);
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val2.m_childCores)
			{
				ResetChild(item);
			}
		}

		public static void ResetChainedPuzzle(ChainedPuzzleInstance chainedPuzzleInstance)
		{
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)chainedPuzzleInstance.m_chainedPuzzleCores)
			{
				ResetChild(item);
			}
			if (SNet.IsMaster)
			{
				chainedPuzzleInstance.AttemptInteract((eChainedPuzzleInteraction)2);
			}
		}

		public static LG_WardenObjective_Reactor FindReactor(LG_LayerType layer)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//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)
			LG_WardenObjective_Reactor val = null;
			Enumerator<LayerChainIndex, iWardenObjectiveItem> enumerator = WardenObjectiveManager.Current.m_wardenObjectiveItem.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<LayerChainIndex, iWardenObjectiveItem> current = enumerator.Current;
				if (current.Key.Layer == layer)
				{
					val = ((Il2CppObjectBase)current.Value).TryCast<LG_WardenObjective_Reactor>();
					if (!((Object)(object)val == (Object)null))
					{
						break;
					}
				}
			}
			return val;
		}

		public static bool TryGetComponent<T>(this GameObject obj, out T comp)
		{
			comp = obj.GetComponent<T>();
			return comp != null;
		}

		public static bool IsPlayerInLevel(PlayerAgent player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			return (int)player.Owner.Load<pGameState>().gameState == 10;
		}

		public static ChainedPuzzleInstance GetChainedPuzzleForCommandOnTerminal(LG_ComputerTerminal terminal, string command)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected I4, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Invalid comparison between Unknown and I4
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Invalid comparison between Unknown and I4
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Invalid comparison between Unknown and I4
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Invalid comparison between Unknown and I4
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Invalid comparison between Unknown and I4
			uint num = 0u;
			if (terminal.SpawnNode.m_dimension.IsMainDimension)
			{
				LG_LayerType layerType = terminal.SpawnNode.LayerType;
				switch ((int)layerType)
				{
				case 0:
					num = RundownManager.ActiveExpedition.LevelLayoutData;
					break;
				case 1:
					num = RundownManager.ActiveExpedition.SecondaryLayout;
					break;
				case 2:
					num = RundownManager.ActiveExpedition.ThirdLayout;
					break;
				default:
					LegacyLogger.Error("Unimplemented layer type.");
					return null;
				}
			}
			else
			{
				num = terminal.SpawnNode.m_dimension.DimensionData.LevelLayoutData;
			}
			LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(num);
			List<CustomTerminalCommand> val = null;
			List<LG_ComputerTerminal> terminalsSpawnedInZone = terminal.SpawnNode.m_zone.TerminalsSpawnedInZone;
			int num2 = terminalsSpawnedInZone.IndexOf(terminal);
			ExpeditionZoneData val2 = null;
			Enumerator<ExpeditionZoneData> enumerator = block.Zones.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ExpeditionZoneData current = enumerator.Current;
				if (current.LocalIndex == terminal.SpawnNode.m_zone.LocalIndex)
				{
					val2 = current;
					break;
				}
			}
			if (val2 == null)
			{
				LegacyLogger.Error("Cannot find target zone data.");
				return null;
			}
			if (val2.TerminalPlacements.Count != terminalsSpawnedInZone.Count)
			{
				LegacyLogger.Error("The numbers of terminal placement and spawn, skipped for the zone terminal.");
				return null;
			}
			val = val2.TerminalPlacements[num2].UniqueCommands;
			if (val.Count == 0)
			{
				return null;
			}
			List<WardenObjectiveEventData> val3 = null;
			TERM_Command val4 = (TERM_Command)0;
			Enumerator<CustomTerminalCommand> enumerator2 = val.GetEnumerator();
			string text = default(string);
			string text2 = default(string);
			while (enumerator2.MoveNext())
			{
				CustomTerminalCommand current2 = enumerator2.Current;
				if (current2.Command == command)
				{
					val3 = current2.CommandEvents;
					if (!terminal.m_command.TryGetCommand(current2.Command, ref val4, ref text, ref text2))
					{
						LegacyLogger.Error("Cannot get TERM_COMMAND for command {0} on the specified terminal.");
					}
					break;
				}
			}
			if (val3 == null || (int)val4 == 0)
			{
				return null;
			}
			if ((int)val4 != 38 && (int)val4 != 39 && (int)val4 != 40 && (int)val4 != 41 && (int)val4 != 42)
			{
				return null;
			}
			ChainedPuzzleInstance val5 = null;
			for (int i = 0; i < val3.Count && (val3[i].ChainPuzzle == 0 || !terminal.TryGetChainPuzzleForCommand(val4, i, ref val5) || !((Object)(object)val5 != (Object)null)); i++)
			{
			}
			return val5;
		}

		public static bool TryGetZoneEntranceSecDoor(LG_Zone zone, out LG_SecurityDoor door)
		{
			if ((Object)(object)zone == (Object)null)
			{
				door = null;
				return false;
			}
			if ((Object)(object)zone.m_sourceGate == (Object)null)
			{
				door = null;
				return false;
			}
			if (zone.m_sourceGate.SpawnedDoor == null)
			{
				door = null;
				return false;
			}
			door = ((Il2CppObjectBase)zone.m_sourceGate.SpawnedDoor).TryCast<LG_SecurityDoor>();
			return (Object)(object)door != (Object)null;
		}

		internal static bool isSecDoorToZoneOpened(LG_Zone zone14)
		{
			//IL_001d: 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_0029: Invalid comparison between Unknown and I4
			LG_SecurityDoor door = null;
			if (!TryGetZoneEntranceSecDoor(zone14, out door) || (Object)(object)door == (Object)null)
			{
				return false;
			}
			return (int)door.m_sync.GetCurrentSyncState().status == 10;
		}

		public static List<T> cast<T>(List<T> list)
		{
			List<T> list2 = new List<T>();
			Enumerator<T> enumerator = list.GetEnumerator();
			while (enumerator.MoveNext())
			{
				T current = enumerator.Current;
				list2.Add(current);
			}
			return list2;
		}

		private static eDimensionIndex GetCurrentDimensionIndex()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (PlayerManager.PlayerAgentsInLevel.Count <= 0)
			{
				throw new Exception("? You don't have any player agent in level? How could that happen?");
			}
			return ((Agent)PlayerManager.PlayerAgentsInLevel[0]).DimensionIndex;
		}

		public static void GetMinLayerAndLocalIndex(out LG_LayerType MinLayer, out eLocalZoneIndex MinLocalIndex)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between I4 and Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between I4 and Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected I4, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected I4, but got Unknown
			MinLayer = (LG_LayerType)2;
			MinLocalIndex = (eLocalZoneIndex)20;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (IsPlayerInLevel(current))
				{
					if ((int)MinLayer > (int)current.m_courseNode.LayerType)
					{
						MinLayer = (LG_LayerType)(int)current.m_courseNode.LayerType;
						MinLocalIndex = (eLocalZoneIndex)20;
					}
					if ((int)MinLocalIndex >= (int)current.m_courseNode.m_zone.LocalIndex)
					{
						MinLocalIndex = (eLocalZoneIndex)(int)current.m_courseNode.m_zone.LocalIndex;
					}
				}
			}
		}

		public static void GetMaxLayerAndLocalIndex(out LG_LayerType MaxLayer, out eLocalZoneIndex MaxLocalIndex)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between I4 and Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between I4 and Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected I4, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected I4, but got Unknown
			MaxLayer = (LG_LayerType)0;
			MaxLocalIndex = (eLocalZoneIndex)0;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (IsPlayerInLevel(current))
				{
					if ((int)MaxLayer < (int)current.m_courseNode.LayerType)
					{
						MaxLayer = (LG_LayerType)(int)current.m_courseNode.LayerType;
						MaxLocalIndex = (eLocalZoneIndex)0;
					}
					if ((int)MaxLocalIndex < (int)current.m_courseNode.m_zone.LocalIndex)
					{
						MaxLocalIndex = (eLocalZoneIndex)(int)current.m_courseNode.m_zone.LocalIndex;
					}
				}
			}
		}

		public static int GetMinAreaIndex(LG_Zone zone)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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)
			if ((Object)(object)zone == (Object)null)
			{
				return -1;
			}
			LG_LayerType type = zone.m_layer.m_type;
			eLocalZoneIndex localIndex = zone.LocalIndex;
			GetCurrentDimensionIndex();
			int num = zone.m_areas.Count;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (current.m_courseNode.LayerType != type || current.m_courseNode.m_zone.LocalIndex != localIndex)
				{
					continue;
				}
				int i = 0;
				for (List<LG_Area> areas = zone.m_areas; i < areas.Count; i++)
				{
					if (((Object)((Component)areas[i]).gameObject).GetInstanceID() == ((Object)((Component)current.m_courseNode.m_area).gameObject).GetInstanceID())
					{
						if (num > i)
						{
							num = i;
						}
						break;
					}
				}
			}
			return num;
		}

		public static LG_ComputerTerminal FindTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, int terminalIndex)
		{
			//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_0034: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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)
			LG_Zone val = null;
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val) || (Object)(object)val == (Object)null)
			{
				LegacyLogger.Error($"FindTerminal: Didn't find LG_Zone {dimensionIndex}, {layerType}, {localIndex}");
				return null;
			}
			if (val.TerminalsSpawnedInZone == null || terminalIndex >= val.TerminalsSpawnedInZone.Count)
			{
				LegacyLogger.Error($"FindTerminal: Invalid terminal index {terminalIndex} - {((val.TerminalsSpawnedInZone != null) ? val.TerminalsSpawnedInZone.Count : 0)} terminals are spawned in {dimensionIndex}, {layerType}, {localIndex}");
				return null;
			}
			if (terminalIndex >= 0)
			{
				return val.TerminalsSpawnedInZone[terminalIndex];
			}
			return null;
		}
	}
	internal static class Json
	{
		private static readonly JsonSerializerOptions _setting;

		static Json()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			_setting = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = false,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				IgnoreReadOnlyProperties = true
			};
			_setting.Converters.Add(new JsonStringEnumConverter());
			_setting.Converters.Add((JsonConverter)new LocalizedTextConverter());
		}

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

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

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

		public static void Load<T>(string filePath, out T config) where T : new()
		{
			config = Deserialize<T>(File.ReadAllText(filePath));
		}
	}
	public class Vec3
	{
		public float x { get; set; }

		public float y { get; set; }

		public float z { get; set; }

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

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

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

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

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

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

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

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

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

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)32, (object)str);
			}
		}
	}
	public class SpawnHibernateEnemiesEvent
	{
		public eWardenObjectiveEventTrigger Trigger { get; set; }

		public int Type { get; set; } = 170;


		public eDimensionIndex DimensionIndex { get; set; }

		public LG_LayerType Layer { get; set; }

		public eLocalZoneIndex LocalIndex { get; set; }

		public string WorldEventObjectFilter { get; set; } = "RANDOM";


		public uint EnemyID { get; set; }

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


		public float Delay { get; set; }

		public float Duration { get; set; } = 2f;

	}
	public class WeightedAreaSelector
	{
		private static readonly Dictionary<LG_Zone, WeightedAreaSelector> dict;

		private WeightedRandomBag<LG_Area> weightedRandomBag;

		public static WeightedAreaSelector Get(LG_Zone zone)
		{
			//IL_0035: 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_003c: 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_0059: Expected I4, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (!dict.ContainsKey(zone))
			{
				WeightedAreaSelector weightedAreaSelector = new WeightedAreaSelector();
				Enumerator<LG_Area> enumerator = zone.m_areas.GetEnumerator();
				while (enumerator.MoveNext())
				{
					LG_Area current = enumerator.Current;
					float num = 0f;
					LG_AreaSize size = current.m_size;
					switch (size - 1)
					{
					case 4:
						num = 7f;
						break;
					case 0:
						num = 20f;
						break;
					case 1:
						num = 30f;
						break;
					case 2:
						num = 35f;
						break;
					case 3:
						num = 45f;
						break;
					default:
						LegacyLogger.Error($"Unhandled LG_AreaSize: {current.m_size}. Won't build.");
						return null;
					}
					weightedAreaSelector.AddEntry(current, num);
				}
				dict.Add(zone, weightedAreaSelector);
			}
			return dict[zone];
		}

		public static WeightedAreaSelector Get(eDimensionIndex eDimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(eDimensionIndex, layerType, localIndex, ref val) || !Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return Get(val);
		}

		private WeightedAreaSelector()
		{
			weightedRandomBag = new WeightedRandomBag<LG_Area>();
		}

		private void AddEntry(LG_Area area, float weight)
		{
			weightedRandomBag.AddEntry(area, weight);
		}

		public LG_Area GetRandom()
		{
			return weightedRandomBag.GetRandom();
		}

		private static void OnBuildDone()
		{
		}

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

		static WeightedAreaSelector()
		{
			dict = new Dictionary<LG_Zone, WeightedAreaSelector>();
			LevelAPI.OnLevelCleanup += dict.Clear;
		}
	}
	public class WeightedRandomBag<T>
	{
		private struct Entry
		{
			public double accumulatedWeight;

			public T item;
		}

		private List<Entry> entries = new List<Entry>();

		private double accumulatedWeight;

		private Random rand = new Random();

		public void AddEntry(T item, double weight)
		{
			if (weight <= 0.0)
			{
				LegacyLogger.Error("AddEntry: no non-positive weight pls.");
				return;
			}
			accumulatedWeight += weight;
			entries.Add(new Entry
			{
				item = item,
				accumulatedWeight = accumulatedWeight
			});
		}

		public T GetRandom()
		{
			double num = rand.NextDouble() * accumulatedWeight;
			foreach (Entry entry in entries)
			{
				if (entry.accumulatedWeight >= num)
				{
					return entry.item;
				}
			}
			return default(T);
		}
	}
}
namespace LEGACY.LegacyOverride
{
	internal static class LegacyOverrideManagers
	{
		internal static readonly string LEGACY_CONFIG_PATH = Path.Combine(MTFOPathAPI.CustomPath, "LegacyOverride");

		internal static void Init()
		{
			ElevatorCargoOverrideManager.Current.Init();
			FogBeaconSettingManager.Current.Init();
			EnemyTaggerSettingManager.Current.Init();
			SecDoorIntTextOverrideManager.Current.Init();
			ExpeditionSettingsManager.Current.Init();
		}
	}
}
namespace LEGACY.LegacyOverride.SecDoorIntText
{
	public class DoorToZone
	{
		public eDimensionIndex DimensionIndex { get; set; }

		public LG_LayerType LayerType { get; set; }

		public eLocalZoneIndex LocalIndex { get; set; }

		public LocalizedText Prefix { get; set; }

		public LocalizedText Postfix { get; set; }

		public LocalizedText TextToReplace { get; set; }
	}
	public class LevelSecDoorIntTextOverride
	{
		public uint MainLevelLayout { get; set; }

		public List<DoorToZone> doorToZones { get; set; } = new List<DoorToZone>
		{
			new DoorToZone()
		};

	}
	internal class SecDoorIntTextOverrideManager
	{
		public static readonly SecDoorIntTextOverrideManager Current;

		private Dictionary<uint, LevelSecDoorIntTextOverride> SecDoorIntTextOverrides = new Dictionary<uint, LevelSecDoorIntTextOverride>();

		private LiveEditListener liveEditListener;

		private static readonly string CONFIG_PATH;

		internal LevelSecDoorIntTextOverride SettingForCurrentLevel { get; private set; }

		private void AddOverride(LevelSecDoorIntTextOverride _override)
		{
			if (_override != null)
			{
				if (SecDoorIntTextOverrides.ContainsKey(_override.MainLevelLayout))
				{
					LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout);
					SecDoorIntTextOverrides[_override.MainLevelLayout] = _override;
				}
				else
				{
					SecDoorIntTextOverrides.Add(_override.MainLevelLayout, _override);
				}
			}
		}

		public void Init()
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			if (!Directory.Exists(CONFIG_PATH))
			{
				Directory.CreateDirectory(CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(Json.Serialize(new LevelSecDoorIntTextOverride()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				Json.Load<LevelSecDoorIntTextOverride>(item, out var config);
				AddOverride(config);
			}
			LevelAPI.OnBuildStart += UpdateSetting;
			liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true);
			liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				LevelSecDoorIntTextOverride @override = Json.Deserialize<LevelSecDoorIntTextOverride>(content);
				AddOverride(@override);
				if (GameStateManager.IsInExpedition)
				{
					UpdateSetting();
				}
			});
		}

		private void UpdateSetting()
		{
			uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData;
			SettingForCurrentLevel = (SecDoorIntTextOverrides.ContainsKey(levelLayoutData) ? SecDoorIntTextOverrides[levelLayoutData] : null);
		}

		private SecDoorIntTextOverrideManager()
		{
		}

		static SecDoorIntTextOverrideManager()
		{
			CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "SecDoorIntText");
			Current = new SecDoorIntTextOverrideManager();
		}
	}
}
namespace LEGACY.LegacyOverride.Patches
{
	[HarmonyPatch]
	internal class Patch_Customize_SecDoor_Interaction_Text
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_SecurityDoor_Locks), "OnDoorState")]
		private static void Post_Customize_SecDoor_Interaction_Text(pDoorState state, LG_SecurityDoor_Locks __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_0116: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			LevelSecDoorIntTextOverride settingForCurrentLevel = SecDoorIntTextOverrideManager.Current.SettingForCurrentLevel;
			if (settingForCurrentLevel == null || ((int)state.status != 9 && (int)state.status != 5))
			{
				return;
			}
			int num = settingForCurrentLevel.doorToZones.FindIndex((DoorToZone door) => door.DimensionIndex == __instance.m_door.Gate.DimensionIndex && door.LayerType == __instance.m_door.LinksToLayerType && door.LocalIndex == __instance.m_door.LinkedToZoneData.LocalIndex);
			if (num != -1)
			{
				DoorToZone doorToZone = settingForCurrentLevel.doorToZones[num];
				_ = __instance.m_door;
				Interact_Timed intOpenDoor = __instance.m_intOpenDoor;
				string text = LocalizedText.op_Implicit(doorToZone.Prefix);
				string text2 = LocalizedText.op_Implicit(doorToZone.Postfix);
				string text3 = LocalizedText.op_Implicit(doorToZone.TextToReplace);
				if (string.IsNullOrEmpty(text))
				{
					text = string.Empty;
				}
				if (string.IsNullOrEmpty(text2))
				{
					text2 = string.Empty;
				}
				if (string.IsNullOrEmpty(text3))
				{
					text3 = intOpenDoor.InteractionMessage;
				}
				intOpenDoor.InteractionMessage = text + "\n" + text3 + "\n" + text2;
				LegacyLogger.Debug($"SecDoorIntTextOverride: Override IntText. {doorToZone.LocalIndex}, {doorToZone.LayerType}, {doorToZone.DimensionIndex}");
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_ElevatorCargoOverride
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ElevatorCargoCage), "SpawnObjectiveItemsInLandingArea")]
		private static bool Pre_ElevatorCargoOverride(ElevatorCargoCage __instance)
		{
			LevelElevatorCargo levelElevatorCargoItems = ElevatorCargoOverrideManager.Current.GetLevelElevatorCargoItems(RundownManager.ActiveExpedition.LevelLayoutData);
			if (levelElevatorCargoItems == null)
			{
				return true;
			}
			if (levelElevatorCargoItems.ForceDisable)
			{
				ElevatorRide.Current.m_cargoCageInUse = false;
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ElevatorCargoCage), "SpawnObjectiveItemsInLandingArea")]
		private static void Post_ElevatorCargoOverride(ElevatorCargoCage __instance)
		{
			LevelElevatorCargo levelElevatorCargoItems = ElevatorCargoOverrideManager.Current.GetLevelElevatorCargoItems(RundownManager.ActiveExpedition.LevelLayoutData);
			if (levelElevatorCargoItems == null || levelElevatorCargoItems.ElevatorCargoItems.Count < 1 || levelElevatorCargoItems.ForceDisable)
			{
				return;
			}
			foreach (ElevatorCargoItem elevatorCargoItem in levelElevatorCargoItems.ElevatorCargoItems)
			{
				LG_PickupItem val = LG_PickupItem.SpawnGenericPickupItem(ElevatorShaftLanding.CargoAlign);
				val.SpawnNode = Builder.GetElevatorArea().m_courseNode;
				switch (elevatorCargoItem.ItemType)
				{
				case ItemType.Consumable:
					val.SetupAsConsumable(Random.Range(0, int.MaxValue), elevatorCargoItem.ItemID);
					break;
				case ItemType.BigPickup:
					val.SetupAsBigPickupItem(Random.Range(0, int.MaxValue), elevatorCargoItem.ItemID, false, 0);
					break;
				default:
					LegacyLogger.Error($"Undefined Item Type {elevatorCargoItem.ItemType}");
					continue;
				}
				__instance.m_itemsToMoveToCargo.Add(((Component)val).transform);
				ElevatorRide.Current.m_cargoCageInUse = true;
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_SetupBigPickupItemWithItemId
	{
		private static void SetupAsObserver(LG_PickupItem __instance)
		{
			EnemyTaggerSetting setting = EnemyTaggerSettingManager.Current.SettingForCurrentLevel;
			CarryItemPickup_Core componentInChildren = ((Component)__instance.m_root).GetComponentInChildren<CarryItemPickup_Core>();
			Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>();
			LG_PickupItem_Sync obj = ((Il2CppObjectBase)componentInChildren.m_sync).Cast<LG_PickupItem_Sync>();
			EnemyTaggerComponent tagger = ((Component)componentInChildren).gameObject.AddComponent<EnemyTaggerComponent>();
			tagger.Parent = componentInChildren;
			((Component)tagger).gameObject.SetActive(true);
			((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
			tagger.MaxTagPerScan = setting.MaxTagPerScan;
			tagger.TagInterval = setting.TagInterval;
			tagger.TagRadius = setting.TagRadius;
			tagger.WarmupTime = setting.WarmupTime;
			obj.OnSyncStateChange += Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>.op_Implicit((Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>)delegate(ePickupItemStatus status, pPickupPlacement placement, PlayerAgent playerAgent, bool isRecall)
			{
				//IL_0000: 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_0005: Invalid comparison between Unknown and I4
				if ((int)status != 0)
				{
					if ((int)status == 1)
					{
						((Component)tagger).gameObject.SetActive(true);
						tagger.PickedByPlayer = playerAgent;
						tagger.ChangeState((!setting.TagWhenHold) ? eEnemyTaggerState.Inactive : eEnemyTaggerState.Active_Warmup);
						((Interact_Timed)interact).InteractDuration = setting.TimeToPlace;
					}
				}
				else
				{
					tagger.PickedByPlayer = null;
					tagger.ChangeState((!setting.TagWhenPlaced) ? eEnemyTaggerState.Inactive : eEnemyTaggerState.Active_Warmup);
					((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
				}
			});
		}

		private static void SetupAsFogBeacon(LG_PickupItem __instance)
		{
			//IL_000b: 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_00e0: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: 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)
			FogRepeller_Sphere val = new GameObject("FogInstance_Beacon_Fake").AddComponent<FogRepeller_Sphere>();
			val.InfiniteDuration = false;
			val.LifeDuration = 99999f;
			val.GrowDuration = 99999f;
			val.ShrinkDuration = 99999f;
			val.Range = 1f;
			FogBeaconSetting setting = FogBeaconSettingManager.Current.SettingForCurrentLevel;
			FogRepeller_Sphere fogRepHold = new GameObject("FogInstance_Beacon_SmallLayer").AddComponent<FogRepeller_Sphere>();
			fogRepHold.InfiniteDuration = setting.RSHold.InfiniteDuration;
			fogRepHold.GrowDuration = setting.RSHold.GrowDuration;
			fogRepHold.ShrinkDuration = setting.RSHold.ShrinkDuration;
			fogRepHold.Range = setting.RSHold.Range;
			fogRepHold.Offset = Vector3.zero;
			FogRepeller_Sphere fogRepPlaced = new GameObject("FogInstance_Beacon_BigLayer").AddComponent<FogRepeller_Sphere>();
			fogRepPlaced.InfiniteDuration = setting.RSPlaced.InfiniteDuration;
			fogRepPlaced.GrowDuration = setting.RSPlaced.GrowDuration;
			fogRepPlaced.ShrinkDuration = setting.RSPlaced.ShrinkDuration;
			fogRepPlaced.Range = setting.RSPlaced.Range;
			fogRepPlaced.Offset = Vector3.zero;
			CarryItemPickup_Core componentInChildren = ((Component)__instance.m_root).GetComponentInChildren<CarryItemPickup_Core>();
			HeavyFogRepellerPickup val2 = ((Il2CppObjectBase)componentInChildren).Cast<HeavyFogRepellerPickup>();
			iCarryItemWithGlobalState val3 = default(iCarryItemWithGlobalState);
			byte byteId = default(byte);
			if (CarryItemWithGlobalStateManager.TryCreateItemInstance((eCarryItemWithGlobalStateType)0, __instance.m_root, ref val3, ref byteId))
			{
				pItemData_Custom customData = ((Item)val2).GetCustomData();
				customData.byteId = byteId;
				pItemData_Custom val4 = customData;
				((Item)val2).SetCustomData(val4, true);
			}
			HeavyFogRepellerGlobalState val5 = ((Il2CppObjectBase)val3).Cast<HeavyFogRepellerGlobalState>();
			((Component)fogRepHold).transform.SetParent(((Component)val5).transform, false);
			((Component)fogRepPlaced).transform.SetParent(((Component)val5).transform, false);
			val5.m_repellerSphere = val;
			fogRepHold.m_sphereAllocator = new FogSphereAllocator();
			fogRepPlaced.m_sphereAllocator = new FogSphereAllocator();
			Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>();
			((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
			val5.CallbackOnStateChange += Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>.op_Implicit((Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>)delegate(pCarryItemWithGlobalState_State oldState, pCarryItemWithGlobalState_State newState, bool isRecall)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Invalid comparison between Unknown and I4
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Invalid comparison between Unknown and I4
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				eHeavyFogRepellerStatus val6 = (eHeavyFogRepellerStatus)newState.status;
				if ((int)val6 != 1)
				{
					if ((int)val6 == 2)
					{
						FogRepeller_Sphere obj = fogRepHold;
						if (obj != null)
						{
							obj.StopRepelling();
						}
						FogRepeller_Sphere obj2 = fogRepPlaced;
						if (obj2 != null)
						{
							obj2.StartRepelling();
						}
						((Interact_Timed)interact).InteractDuration = setting.TimeToPickup;
					}
				}
				else
				{
					FogRepeller_Sphere obj3 = fogRepHold;
					if (obj3 != null)
					{
						obj3.StartRepelling();
					}
					if (oldState.status != 0)
					{
						FogRepeller_Sphere obj4 = fogRepPlaced;
						if (obj4 != null)
						{
							obj4.StopRepelling();
						}
					}
					((Interact_Timed)interact).InteractDuration = setting.TimeToPlace;
				}
				if (isRecall)
				{
					FogRepeller_Sphere obj5 = fogRepHold;
					if (obj5 != null)
					{
						obj5.KillRepellerInstantly();
					}
					FogRepeller_Sphere obj6 = fogRepPlaced;
					if (obj6 != null)
					{
						obj6.KillRepellerInstantly();
					}
				}
			});
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LG_PickupItem), "SetupBigPickupItemWithItemId")]
		private static void Post_SetupBigPickupItemWithItemId(LG_PickupItem __instance, uint itemId)
		{
			switch (itemId)
			{
			case 233u:
				SetupAsFogBeacon(__instance);
				break;
			case 234u:
			case 235u:
				SetupAsObserver(__instance);
				break;
			}
		}
	}
}
namespace LEGACY.LegacyOverride.FogBeacon
{
	public class RepellerSphereSetting
	{
		public bool InfiniteDuration { get; set; }

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


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


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

	}
	public class FogBeaconSetting
	{
		public uint MainLevelLayout { get; set; }

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


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


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


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

	}
	internal class FogBeaconSettingManager
	{
		public static readonly FogBeaconSettingManager Current;

		private Dictionary<uint, FogBeaconSetting> fogBeaconSettings = new Dictionary<uint, FogBeaconSetting>();

		private LiveEditListener liveEditListener;

		private static readonly string CONFIG_PATH;

		internal FogBeaconSetting SettingForCurrentLevel { get; private set; }

		private void AddOverride(FogBeaconSetting _override)
		{
			if (_override != null)
			{
				if (fogBeaconSettings.ContainsKey(_override.MainLevelLayout))
				{
					LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout);
					fogBeaconSettings[_override.MainLevelLayout] = _override;
				}
				else
				{
					fogBeaconSettings.Add(_override.MainLevelLayout, _override);
				}
			}
		}

		public void Init()
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			if (!Directory.Exists(CONFIG_PATH))
			{
				Directory.CreateDirectory(CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(Json.Serialize(new FogBeaconSetting()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				Json.Load<FogBeaconSetting>(item, out var config);
				AddOverride(config);
			}
			LevelAPI.OnBuildStart += UpdateSetting;
			liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true);
			liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				FogBeaconSetting @override = Json.Deserialize<FogBeaconSetting>(content);
				AddOverride(@override);
				if (GameStateManager.IsInExpedition)
				{
					UpdateSetting();
				}
			});
		}

		private void UpdateSetting()
		{
			uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData;
			SettingForCurrentLevel = (fogBeaconSettings.ContainsKey(levelLayoutData) ? fogBeaconSettings[levelLayoutData] : null);
			LegacyLogger.Debug($"FogBeaconSettingManager: updated setting for level with main level layout id {levelLayoutData}");
		}

		private FogBeaconSettingManager()
		{
		}

		static FogBeaconSettingManager()
		{
			CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "FogBeaconSetting");
			Current = new FogBeaconSettingManager();
		}
	}
}
namespace LEGACY.LegacyOverride.ExtraExpeditionSettings
{
	public class ExpeditionSettings
	{
		public uint MainLevelLayout { get; set; }
	}
	internal class ExpeditionSettingsManager
	{
		public static ExpeditionSettingsManager Current;

		private Dictionary<uint, ExpeditionSettings> expSettings = new Dictionary<uint, ExpeditionSettings>();

		private LiveEditListener liveEditListener;

		private static readonly string CONFIG_PATH;

		private void AddOverride(ExpeditionSettings _override)
		{
			if (_override != null)
			{
				if (expSettings.ContainsKey(_override.MainLevelLayout))
				{
					LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout);
					expSettings[_override.MainLevelLayout] = _override;
				}
				else
				{
					expSettings.Add(_override.MainLevelLayout, _override);
				}
			}
		}

		public void Init()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			if (!Directory.Exists(CONFIG_PATH))
			{
				Directory.CreateDirectory(CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(Json.Serialize(new ExpeditionSettings()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				Json.Load<ExpeditionSettings>(item, out var config);
				AddOverride(config);
			}
			liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true);
			liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				ExpeditionSettings @override = Json.Deserialize<ExpeditionSettings>(content);
				AddOverride(@override);
			});
		}

		private void OnBuildDone()
		{
			if (expSettings.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData))
			{
				_ = expSettings[RundownManager.ActiveExpedition.LevelLayoutData];
			}
		}

		private void OnBuildStart()
		{
		}

		private void OnLevelCleanup()
		{
		}

		private void OnEnterLevel()
		{
		}

		private ExpeditionSettingsManager()
		{
		}

		static ExpeditionSettingsManager()
		{
			CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "ExpeditionSettings");
			Current = new ExpeditionSettingsManager();
			LevelAPI.OnBuildStart += Current.OnBuildStart;
			LevelAPI.OnEnterLevel += Current.OnEnterLevel;
			LevelAPI.OnBuildDone += Current.OnBuildDone;
			LevelAPI.OnLevelCleanup += Current.OnLevelCleanup;
		}
	}
}
namespace LEGACY.LegacyOverride.EnemyTagger
{
	public enum eEnemyTaggerState
	{
		Uninitialized,
		Inactive,
		Active_Warmup,
		Active_Tagging
	}
	public class EnemyTaggerComponent : MonoBehaviour
	{
		private const float INACTIVE_SOUND_UPDATE_INTERVAL = 1f;

		internal int MaxTagPerScan = 12;

		internal float TagInterval = 3f;

		internal float TagRadius = 12f;

		internal float WarmupTime = 3f;

		private eEnemyTaggerState CurrentState;

		private CellSoundPlayer m_sound = new CellSoundPlayer();

		private List<EnemyAgent> TaggableEnemies = new List<EnemyAgent>();

		private float UpdateTime;

		internal CarryItemPickup_Core Parent { get; set; }

		internal PlayerAgent PickedByPlayer { get; set; }

		internal Vector3 Position
		{
			get
			{
				//IL_003e: 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_0027: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)Parent == (Object)null))
				{
					if (!((Object)(object)PickedByPlayer == (Object)null))
					{
						return ((Component)PickedByPlayer).transform.position;
					}
					return ((Component)Parent).transform.position;
				}
				return Vector3.zero;
			}
		}

		public void ChangeState(eEnemyTaggerState newState)
		{
			if (CurrentState == newState)
			{
				return;
			}
			switch (newState)
			{
			case eEnemyTaggerState.Uninitialized:
				LegacyLogger.Error("Enemy Tagger changed to state 'uninitialized'?");
				return;
			case eEnemyTaggerState.Inactive:
				UpdateTime = 0f;
				TaggableEnemies.Clear();
				m_sound.Post(EVENTS.BULKHEAD_BUTTON_CLOSE, true);
				break;
			case eEnemyTaggerState.Active_Warmup:
				UpdateTime = 0f;
				m_sound.Post(EVENTS.BUTTONGENERICDEACTIVATE, true);
				break;
			case eEnemyTaggerState.Active_Tagging:
				if (CurrentState != eEnemyTaggerState.Active_Warmup)
				{
					UpdateTime = 0f;
				}
				break;
			default:
				LegacyLogger.Error($"Enemy Tagger: Undefined state {CurrentState}");
				return;
			}
			CurrentState = newState;
		}

		private bool UpdateTaggableEnemies()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			TaggableEnemies.Clear();
			bool result = false;
			Enumerator<EnemyAgent> enumerator = AIG_CourseGraph.GetReachableEnemiesInNodes(((Object)(object)PickedByPlayer == (Object)null) ? ((ItemInLevel)Parent).m_courseNode : ((Agent)PickedByPlayer).CourseNode, 2).GetEnumerator();
			while (enumerator.MoveNext())
			{
				EnemyAgent current = enumerator.Current;
				if (!((Agent)current).Alive)
				{
					continue;
				}
				Vector3 val = ((Component)current).transform.position - Position;
				if (!(((Vector3)(ref val)).magnitude > TagRadius))
				{
					result = true;
					if (!current.IsTagged)
					{
						TaggableEnemies.Add(current);
					}
					if (TaggableEnemies.Count >= MaxTagPerScan)
					{
						break;
					}
				}
			}
			return result;
		}

		private void StartTagging()
		{
			if (!(UpdateTime >= TagInterval))
			{
				return;
			}
			if (SNet.IsMaster)
			{
				UpdateTaggableEnemies();
				foreach (EnemyAgent taggableEnemy in TaggableEnemies)
				{
					ToolSyncManager.WantToTagEnemy(taggableEnemy);
				}
			}
			m_sound.Post(EVENTS.MARKERGUNACTIVATE, true);
			UpdateTime = 0f;
		}

		private void StopTagging()
		{
			if (UpdateTime >= 1f)
			{
				m_sound.Post(EVENTS.BUTTONGENERICDEACTIVATE, true);
				UpdateTime = 0f;
			}
		}

		private void Warmup()
		{
			if (UpdateTime >= WarmupTime)
			{
				ChangeState(eEnemyTaggerState.Active_Tagging);
				UpdateTime = TagInterval;
			}
		}

		private void Update()
		{
			//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)
			if (CurrentState == eEnemyTaggerState.Uninitialized)
			{
				return;
			}
			if ((Object)(object)Parent == (Object)null)
			{
				LegacyLogger.Error("EnemyTagger: null parent");
				return;
			}
			UpdateTime += Time.deltaTime;
			m_sound.UpdatePosition(Position);
			switch (CurrentState)
			{
			case eEnemyTaggerState.Active_Warmup:
				Warmup();
				break;
			case eEnemyTaggerState.Active_Tagging:
				StartTagging();
				break;
			case eEnemyTaggerState.Inactive:
				StopTagging();
				break;
			}
		}

		private void OnDestroy()
		{
			StopTagging();
			TaggableEnemies.Clear();
			TaggableEnemies = null;
			if (m_sound != null)
			{
				m_sound.Stop();
				m_sound.Recycle();
				m_sound = null;
			}
			Parent = null;
		}
	}
	public class EnemyTaggerSetting
	{
		public uint MainLevelLayout { get; set; }

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


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


		public float WarmupTime { get; set; } = 5f;


		public int MaxTagPerScan { get; set; } = 12;


		public float TagInterval { get; set; } = 3f;


		public float TagRadius { get; set; } = 12f;


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


		public bool TagWhenHold { get; set; }
	}
	internal class EnemyTaggerSettingManager
	{
		public static readonly EnemyTaggerSettingManager Current;

		private Dictionary<uint, EnemyTaggerSetting> enemyTaggerSettingSettings = new Dictionary<uint, EnemyTaggerSetting>();

		private LiveEditListener liveEditListener;

		private static readonly string CONFIG_PATH;

		private static readonly EnemyTaggerSetting DEFAULT;

		internal EnemyTaggerSetting SettingForCurrentLevel { get; private set; } = DEFAULT;


		private void AddOverride(EnemyTaggerSetting _override)
		{
			if (_override != null)
			{
				if (enemyTaggerSettingSettings.ContainsKey(_override.MainLevelLayout))
				{
					LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout);
					enemyTaggerSettingSettings[_override.MainLevelLayout] = _override;
				}
				else
				{
					enemyTaggerSettingSettings.Add(_override.MainLevelLayout, _override);
				}
			}
		}

		public void Init()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			if (!Directory.Exists(CONFIG_PATH))
			{
				Directory.CreateDirectory(CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(Json.Serialize(new EnemyTaggerSetting()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				Json.Load<EnemyTaggerSetting>(item, out var config);
				AddOverride(config);
			}
			LevelAPI.OnBuildStart += UpdateSetting;
			ClassInjector.RegisterTypeInIl2Cpp<EnemyTaggerComponent>();
			liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true);
			liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				EnemyTaggerSetting @override = Json.Deserialize<EnemyTaggerSetting>(content);
				AddOverride(@override);
				if (GameStateManager.IsInExpedition)
				{
					UpdateSetting();
				}
			});
		}

		private void UpdateSetting()
		{
			uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData;
			SettingForCurrentLevel = (enemyTaggerSettingSettings.ContainsKey(levelLayoutData) ? enemyTaggerSettingSettings[levelLayoutData] : DEFAULT);
			LegacyLogger.Debug($"EnemyTaggerSettingManager: updated setting for level with main level layout id {levelLayoutData}");
		}

		private EnemyTaggerSettingManager()
		{
		}

		static EnemyTaggerSettingManager()
		{
			CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "EnemyTaggerSetting");
			DEFAULT = new EnemyTaggerSetting();
			Current = new EnemyTaggerSettingManager();
		}
	}
}
namespace LEGACY.LegacyOverride.ElevatorCargo
{
	internal class ElevatorCargoOverrideManager
	{
		public static readonly ElevatorCargoOverrideManager Current;

		private Dictionary<uint, LevelElevatorCargo> elevatorCargos = new Dictionary<uint, LevelElevatorCargo>();

		private LiveEditListener liveEditListener;

		private static readonly string CONFIG_PATH;

		private void AddOverride(LevelElevatorCargo _override)
		{
			if (_override != null)
			{
				if (elevatorCargos.ContainsKey(_override.MainLevelLayout))
				{
					LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout);
					elevatorCargos[_override.MainLevelLayout] = _override;
				}
				else
				{
					elevatorCargos.Add(_override.MainLevelLayout, _override);
				}
			}
		}

		public void Init()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			if (!Directory.Exists(CONFIG_PATH))
			{
				Directory.CreateDirectory(CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(Json.Serialize(new LevelElevatorCargo()));
				streamWriter.Flush();
				streamWriter.Close();
				return;
			}
			foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				Json.Load<LevelElevatorCargo>(item, out var config);
				AddOverride(config);
			}
			liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true);
			liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged);
		}

		private void FileChanged(LiveEditEventArgs e)
		{
			LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath);
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				LevelElevatorCargo @override = Json.Deserialize<LevelElevatorCargo>(content);
				AddOverride(@override);
			});
		}

		internal LevelElevatorCargo GetLevelElevatorCargoItems(uint MainLevelLayout)
		{
			if (!elevatorCargos.ContainsKey(MainLevelLayout))
			{
				return null;
			}
			return elevatorCargos[MainLevelLayout];
		}

		private ElevatorCargoOverrideManager()
		{
		}

		static ElevatorCargoOverrideManager()
		{
			CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "ElevatorCargoOverride");
			Current = new ElevatorCargoOverrideManager();
		}
	}
	public enum ItemType
	{
		Consumable,
		BigPickup
	}
	public class ElevatorCargoItem
	{
		public uint ItemID { get; set; }

		public ItemType ItemType { get; set; }
	}
	public class LevelElevatorCargo
	{
		public uint MainLevelLayout { get; set; }

		public bool ForceDisable { get; set; }

		public List<ElevatorCargoItem> ElevatorCargoItems { get; set; } = new List<ElevatorCargoItem>();

	}
}
namespace LEGACY.ExtraEvents
{
	internal static class LegacyExtraEvents
	{
		private static bool initialized;

		private static void AlertEnemiesInArea(LG_Area area)
		{
			//IL_00c1: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			AIG_CourseNode courseNode = area.m_courseNode;
			if (courseNode.m_enemiesInNode.Count > 0)
			{
				EnemyAgent obj = courseNode.m_enemiesInNode[0];
				PlayerAgent val = null;
				if (PlayerManager.TryGetClosestAlivePlayerAgent(((Agent)obj).CourseNode, ref val) && (Object)(object)val != (Object)null)
				{
					Vector3 position = courseNode.m_enemiesInNode[0].Position;
					NoiseManager.MakeNoise(new NM_NoiseData
					{
						noiseMaker = null,
						position = position,
						radiusMin = 50f,
						radiusMax = 120f,
						yScale = 1f,
						node = courseNode,
						type = (NM_NoiseType)0,
						includeToNeightbourAreas = true,
						raycastFirstNode = false
					});
				}
				else
				{
					LegacyLogger.Error($"AlertEnemies: failed to alert enemies in area in Zone_{area.m_zone.LocalIndex}, {area.m_zone.m_layer.m_type}, {area.m_zone.DimensionIndex}");
				}
			}
		}

		private static void AlertEnemiesInZone(WardenObjectiveEventData e)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null)
			{
				LegacyLogger.Error($"AlertEnemiesInZone: zone not found, {(e.DimensionIndex, e.Layer, e.LocalIndex)}");
				return;
			}
			LegacyLogger.Debug($"AlertEnemiesInZone: {e.LocalIndex}, {e.Layer}, {e.DimensionIndex}");
			Enumerator<LG_Area> enumerator = val.m_areas.GetEnumerator();
			while (enumerator.MoveNext())
			{
				AlertEnemiesInArea(enumerator.Current);
			}
		}

		private static void AlertEnemiesInArea(WardenObjectiveEventData e)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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)
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null)
			{
				LegacyLogger.Error($"AlertEnemiesInArea: zone not found, {(e.DimensionIndex, e.Layer, e.LocalIndex)}");
			}
			else if (e.Count >= val.m_areas.Count && e.Count < 0)
			{
				LegacyLogger.Error($"AlertEnemiesInArea: invalid area index {e.Count} (specified by 'Count')");
			}
			else
			{
				AlertEnemiesInArea(val.m_areas[e.Count]);
			}
		}

		private static void ActivateChainedPuzzle(WardenObjectiveEventData e)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			uint chainPuzzle = e.ChainPuzzle;
			CP_Bioscan_Core bioscanCore = PuzzleOverrideManager.Current.GetBioscanCore(chainPuzzle);
			CP_Cluster_Core clusterCore = PuzzleOverrideManager.Current.GetClusterCore(chainPuzzle);
			iChainedPuzzleOwner val;
			if ((Object)(object)bioscanCore != (Object)null)
			{
				val = PuzzleOverrideManager.Current.ChainedPuzzleInstanceOwner(bioscanCore);
			}
			else
			{
				if (!((Object)(object)clusterCore != (Object)null))
				{
					LegacyLogger.Error($"ActivateChainedPuzzle: Cannot find puzzle with puzzle override index {chainPuzzle}!");
					return;
				}
				val = clusterCore.m_owner;
			}
			ChainedPuzzleInstance val2 = ((Il2CppObjectBase)val).TryCast<ChainedPuzzleInstance>();
			if ((Object)(object)val2 == (Object)null)
			{
				LegacyLogger.Error("ActivateChainedPuzzle: Cannot find ChainedPuzzleInstance!");
				return;
			}
			if (SNet.IsMaster)
			{
				val2.AttemptInteract((eChainedPuzzleInteraction)0);
			}
			LegacyLogger.Debug($"ActivateChainedPuzzle: puzzle override index: {chainPuzzle}");
			LegacyLogger.Debug($"ChainedPuzzleZone: Dim {val2.m_sourceArea.m_zone.DimensionIndex}, {val2.m_sourceArea.m_zone.m_layer.m_type}, Zone {val2.m_sourceArea.m_zone.Alias}");
			LegacyLogger.Debug("ChainedPuzzle Alarm name: " + val2.Data.PublicAlarmName);
		}

		internal static IEnumerator AddReqItem(WardenObjectiveEventData e, float currentDuration)
		{
			uint puzzleOverrideIndex = e.ChainPuzzle;
			int count = e.Count;
			CarryItemPickup_Core itemToAdd = PuzzleReqItemManager.Current.GetBigPickupItem(count);
			if ((Object)(object)itemToAdd == (Object)null)
			{
				LegacyLogger.Error($"AddReqItem: Cannot find BigPickup Item with index {count}");
				yield break;
			}
			CP_Bioscan_Core bioscanCore = PuzzleOverrideManager.Current.GetBioscanCore(puzzleOverrideIndex);
			CP_Cluster_Core clusterCore = PuzzleOverrideManager.Current.GetClusterCore(puzzleOverrideIndex);
			if ((Object)(object)bioscanCore != (Object)null)
			{
				float num = Mathf.Max(e.Delay - currentDuration, 0f);
				if (num > 0f)
				{
					yield return (object)new WaitForSeconds(num);
				}
				WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel);
				if (e.DialogueID != 0)
				{
					PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false);
				}
				if (e.SoundID != 0)
				{
					WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true);
					string text = ((Object)e.SoundSubtitle).ToString();
					if (!string.IsNullOrWhiteSpace(text))
					{
						GuiManager.PlayerLayer.ShowMultiLineSubtitle(text);
					}
				}
				if ((double)e.Duration > 0.0 && (double)e.Duration < 1.0)
				{
					float duration = e.Duration;
					CP_PlayerScanner scanner = ((Il2CppObjectBase)bioscanCore.m_playerScanner).TryCast<CP_PlayerScanner>();
					if ((Object)(object)scanner != (Object)null)
					{
						float CheckInterval = (((double)e.FogTransitionDuration > 0.0) ? e.FogTransitionDuration : 0.5f);
						LegacyLogger.Debug($"AddReqItem: item would be added on scan progression: {duration}, progression check interval: {CheckInterval} (seconds)");
						while (scanner.m_scanProgression < e.Duration)
						{
							yield return (object)new WaitForSeconds(CheckInterval);
						}
					}
					else
					{
						LegacyLogger.Error("AddReqItem: Failed to get scanner for the CP_Bioscan_Core");
					}
				}
				bioscanCore.AddRequiredItems(Il2CppReferenceArray<iWardenObjectiveItem>.op_Implicit((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1]
				{
					new iWardenObjectiveItem(((Il2CppObjectBase)itemToAdd).Pointer)
				}));
				LegacyLogger.Debug($"AddReqItem: puzzle override index: {puzzleOverrideIndex}");
				LegacyLogger.Debug("Item name: " + ((Item)itemToAdd).ItemDataBlock.publicName);
			}
			else if ((Object)(object)clusterCore != (Object)null)
			{
				float num2 = Mathf.Max(e.Delay - currentDuration, 0f);
				if (num2 > 0f)
				{
					yield return (object)new WaitForSeconds(num2);
				}
				WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel);
				if (e.DialogueID != 0)
				{
					PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false);
				}
				if (e.SoundID != 0)
				{
					WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true);
					string text2 = ((Object)e.SoundSubtitle).ToString();
					if (!string.IsNullOrWhiteSpace(text2))
					{
						GuiManager.PlayerLayer.ShowMultiLineSubtitle(text2);
					}
				}
				iWardenObjectiveItem[] array = (iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1]
				{
					new iWardenObjectiveItem(((Il2CppObjectBase)itemToAdd).Pointer)
				};
				foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)clusterCore.m_childCores)
				{
					item.AddRequiredItems(Il2CppReferenceArray<iWardenObjectiveItem>.op_Implicit(array));
				}
				LegacyLogger.Debug($"AddReqItem: puzzle override index: {puzzleOverrideIndex}");
				LegacyLogger.Debug("Item name: " + ((Item)itemToAdd).ItemDataBlock.publicName);
			}
			else
			{
				LegacyLogger.Error($"AddReqItem: cannot find puzzle core with index {puzzleOverrideIndex}");
			}
		}

		internal static IEnumerator RemoveReqItem(WardenObjectiveEventData e, float currentDuration)
		{
			uint puzzleOverrideIndex = e.ChainPuzzle;
			int count = e.Count;
			CarryItemPickup_Core itemToRemove = PuzzleReqItemManager.Current.GetBigPickupItem(count);
			if ((Object)(object)itemToRemove == (Object)null)
			{
				LegacyLogger.Error($"RemoveReqItem: Cannot find BigPickup Item with index {count}");
				yield break;
			}
			CP_Bioscan_Core bioscanCore = PuzzleOverrideManager.Current.GetBioscanCore(puzzleOverrideIndex);
			CP_Cluster_Core clusterCore = PuzzleOverrideManager.Current.GetClusterCore(puzzleOverrideIndex);
			if ((Object)(object)bioscanCore != (Object)null)
			{
				float num = Mathf.Max(e.Delay - currentDuration, 0f);
				if (num > 0f)
				{
					yield return (object)new WaitForSeconds(num);
				}
				WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel);
				if (e.DialogueID != 0)
				{
					PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false);
				}
				if (e.SoundID != 0)
				{
					WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true);
					string text = ((Object)e.SoundSubtitle).ToString();
					if (!string.IsNullOrWhiteSpace(text))
					{
						GuiManager.PlayerLayer.ShowMultiLineSubtitle(text);
					}
				}
				if ((double)e.Duration > 0.0 && (double)e.Duration < 1.0)
				{
					float duration = e.Duration;
					CP_PlayerScanner scanner = ((Il2CppObjectBase)bioscanCore.m_playerScanner).TryCast<CP_PlayerScanner>();
					if ((Object)(object)scanner != (Object)null)
					{
						float CheckInterval = (((double)e.FogTransitionDuration > 0.0) ? e.FogTransitionDuration : 0.5f);
						LegacyLogger.Debug($"RemoveReqItem: item would be added on scan progression: {duration}, progression check interval: {CheckInterval} (seconds)");
						while (scanner.m_scanProgression < e.Duration)
						{
							yield return (object)new WaitForSeconds(CheckInterval);
						}
					}
					else
					{
						LegacyLogger.Error("RemoveReqItem: Failed to get scanner for the CP_Bioscan_Core");
					}
				}
				bioscanCore.RemoveRequiredItems((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1]
				{
					new iWardenObjectiveItem(((Il2CppObjectBase)itemToRemove).Pointer)
				});
				LegacyLogger.Debug($"RemoveReqItem: puzzle override index: {puzzleOverrideIndex}");
				LegacyLogger.Debug("Removed Item name: " + ((Item)itemToRemove).ItemDataBlock.publicName);
			}
			else if ((Object)(object)clusterCore != (Object)null)
			{
				float num2 = Mathf.Max(e.Delay - currentDuration, 0f);
				if (num2 > 0f)
				{
					yield return (object)new WaitForSeconds(num2);
				}
				WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel);
				if (e.DialogueID != 0)
				{
					PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false);
				}
				if (e.SoundID != 0)
				{
					WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true);
					string text2 = ((Object)e.SoundSubtitle).ToString();
					if (!string.IsNullOrWhiteSpace(text2))
					{
						GuiManager.PlayerLayer.ShowMultiLineSubtitle(text2);
					}
				}
				iWardenObjectiveItem[] array = (iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1]
				{
					new iWardenObjectiveItem(((Il2CppObjectBase)itemToRemove).Pointer)
				};
				foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)clusterCore.m_childCores)
				{
					item.RemoveRequiredItems(array);
				}
				LegacyLogger.Debug($"RemoveReqItem: puzzle override index: {puzzleOverrideIndex}");
				LegacyLogger.Debug("Removed Item name: " + ((Item)itemToRemove).ItemDataBlock.publicName);
			}
			else
			{
				LegacyLogger.Error($"RemoveReqItem: cannot find puzzle core with index {puzzleOverrideIndex}");
			}
		}

		internal static void Init()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			if (!initialized)
			{
				LegacyLogger.Log("Adding Legacy warden event definitions...");
				EOSWardenEventManager.Current.AddEventDefinition(EventType.CloseSecurityDoor_Custom.ToString(), 100u, (Action<WardenObjectiveEventData>)CloseSecurityDoor);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.SetTimerTitle.ToString(), 102u, (Action<WardenObjectiveEventData>)SetTimerTitle);
				EOSWardenEventManager current = EOSWardenEventManager.Current;
				eWardenObjectiveEventType val = (eWardenObjectiveEventType)21;
				current.AddEventDefinition(((object)(eWardenObjectiveEventType)(ref val)).ToString(), 21u, (Action<WardenObjectiveEventData>)SetTerminalCommand_Custom);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.AlertEnemiesInArea.ToString(), 108u, (Action<WardenObjectiveEventData>)AlertEnemiesInArea);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.AlertEnemiesInZone.ToString(), 107u, (Action<WardenObjectiveEventData>)AlertEnemiesInZone);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.KillEnemiesInArea.ToString(), 140u, (Action<WardenObjectiveEventData>)KillEnemiesInArea);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.KillEnemiesInZone.ToString(), 141u, (Action<WardenObjectiveEventData>)KillEnemiesInZone);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.KillEnemiesInDimension.ToString(), 142u, (Action<WardenObjectiveEventData>)KillEnemiesInDimension);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.SpawnHibernate.ToString(), 170u, (Action<WardenObjectiveEventData>)SpawnHibernate);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.Info_ZoneHibernate.ToString(), 250u, (Action<WardenObjectiveEventData>)Info_ZoneHibernate);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.Info_LevelHibernate.ToString(), 251u, (Action<WardenObjectiveEventData>)Info_LevelEnemies);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.Output_LevelHibernateSpawnEvent.ToString(), 252u, (Action<WardenObjectiveEventData>)Output_LevelHibernateSpawnEvent);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.PlayGCEndSequence.ToString(), 180u, (Action<WardenObjectiveEventData>)PlayGCEndSequence);
				EOSWardenEventManager current2 = EOSWardenEventManager.Current;
				val = (eWardenObjectiveEventType)22;
				current2.AddEventDefinition(((object)(eWardenObjectiveEventType)(ref val)).ToString(), 22u, (Action<WardenObjectiveEventData>)ActivateChainedPuzzle);
				EOSWardenEventManager.Current.AddEventDefinition(EventType.Terminal_ShowTerminalInfoInZone.ToString(), 130u, (Action<WardenObjectiveEventData>)ShowTerminalInfoInZone);
				LegacyLogger.Log("Legacy warden event definitions setup completed");
				initialized = true;
			}
		}

		private static IEnumerator Play(WardenObjectiveEventData e)
		{
			List<LG_PowerGenerator_Core> gcInZone = ((InstanceManager<LG_PowerGenerator_Core>)(object)PowerGeneratorInstanceManager.Current).GetInstancesInZone(e.DimensionIndex, e.Layer, e.LocalIndex);
			yield return (object)new WaitForSeconds(4f);
			CellSound.Post(EVENTS.DISTANT_EXPLOSION_SEQUENCE);
			yield return (object)new WaitForSeconds(2f);
			EnvironmentStateManager.AttemptSetExpeditionLightMode(false);
			CellSound.Post(EVENTS.LIGHTS_OFF_GLOBAL);
			yield return (object)new WaitForSeconds(3f);
			int g = 0;
			while (g < gcInZone.Count)
			{
				gcInZone[g].TriggerPowerFailureSequence();
				yield return (object)new WaitForSeconds(Random.Range(0.3f, 1f));
				int num = g + 1;
				g = num;
			}
			yield return (object)new WaitForSeconds(4f);
			EnvironmentStateManager.AttemptSetExpeditionLightMode(true);
		}

		private static void PlayGCEndSequence(WardenObjectiveEventData e)
		{
			Coroutine val = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Play(e)), (Action)null);
			WorldEventManager.m_worldEventEventCoroutines.Add(val);
		}

		private static void KillEnemiesInArea(LG_Area area)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			foreach (EnemyAgent item in area.m_courseNode.m_enemiesInNode.ToArray())
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item.Damage != (Object)null)
				{
					item.Damage.MeleeDamage(float.MaxValue, (Agent)null, Vector3.zero, Vector3.up, 0, 1f, 1f, 1f, 1f, false, (DamageNoiseLevel)0, 0u);
				}
			}
		}

		private static void KillEnemiesInArea(WardenObjectiveEventData e)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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)
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null)
			{
				LegacyLogger.Error($"KillEnemiesInArea - Failed to find {(e.DimensionIndex, e.Layer, e.LocalIndex)}");
			}
			else if (e.Count < 0 || e.Count >= val.m_areas.Count)
			{
				LegacyLogger.Error($"KillEnemiesInArea - invalid area index {e.Count} (specified by 'Count')");
			}
			else
			{
				KillEnemiesInArea(val.m_areas[e.Count]);
			}
		}

		private static void KillEnemiesInZone(WardenObjectiveEventData e)
		{
			//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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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)
			if (!SNet.IsMaster)
			{
				return;
			}
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null)
			{
				LegacyLogger.Error($"KillEnemiesInArea - Failed to find {(e.DimensionIndex, e.Layer, e.LocalIndex)}");
			}
			else
			{
				Enumerator<LG_Area> enumerator = val.m_areas.GetEnumerator();
				while (enumerator.MoveNext())
				{
					KillEnemiesInArea(enumerator.Current);
				}
			}
		}

		private static void KillEnemiesInDimension(WardenObjectiveEventData e)
		{
			//IL_0009: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			if (!SNet.IsMaster)
			{
				return;
			}
			Dimension val = default(Dimension);
			if (!Dimension.GetDimension(e.DimensionIndex, ref val))
			{
				LegacyLogger.Error($"KillEnemiesInDimension: invalid dimension index {e.DimensionIndex}");
				return;
			}
			for (int i = 0; i < val.Layers.Count; i++)
			{
				LG_Layer val2 = val.Layers[i];
				for (int j = 0; j < val2.m_zones.Count; j++)
				{
					LG_Zone val3 = val2.m_zones[j];
					Helper.TryGetZoneEntranceSecDoor(val3, out var door);
					if (j == 0 || ((Object)(object)door != (Object)null && (int)door.m_sync.GetCurrentSyncState().status == 10))
					{
						Enumerator<LG_Area> enumerator = val3.m_areas.GetEnumerator();
						while (enumerator.MoveNext())
						{
							KillEnemiesInArea(enumerator.Current);
						}
					}
				}
			}
		}

		private static void CloseSecurityDoor(WardenObjectiveEventData e)
		{
			//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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_009c: 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: Invalid comparison between Unknown and I4
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val = null;
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null)
			{
				LegacyLogger.Error("CloseSecurityDoor_Custom: Failed to get zone {0}, layer {1}, dimensionIndex {2}", e.LocalIndex, e.Layer, e.DimensionIndex);
				return;
			}
			LG_SecurityDoor door = null;
			if (!Helper.TryGetZoneEntranceSecDoor(val, out door) || (Object)(object)door == (Object)null)
			{
				LegacyLogger.Error("CloseSecurityDoor_Custom: failed to get LG_SecurityDoor!");
				return;
			}
			pDoorState currentSyncState = door.m_sync.GetCurrentSyncState();
			if ((int)currentSyncState.status != 10 && (int)currentSyncState.status != 16)
			{
				return;
			}
			LegacyLogger.Debug("Door Closed!");
			LG_Door_Sync val2 = ((Il2CppObjectBase)door.m_sync).TryCast<LG_Door_Sync>();
			if (!((Object)(object)val2 == (Object)null))
			{
				pDoorState currentSyncState2 = val2.GetCurrentSyncState();
				currentSyncState2.status = (eDoorStatus)1;
				currentSyncState2.hasBeenOpenedDuringGame = false;
				pDoorState state = currentSyncState2;
				val2.m_stateReplicator.State = state;
				LG_Gate gate = door.Gate;
				gate.HasBeenOpenedDuringPlay = false;
				gate.IsTraversable = false;
				if (door.ActiveEnemyWaveData != null && door.ActiveEnemyWaveData.HasActiveEnemyWave)
				{
					door.m_sound.Post(EVENTS.MONSTER_RUCKUS_FROM_BEHIND_SECURITY_DOOR_LOOP_START, true);
				}
			}
		}

		private static void SetTerminalCommand_Custom(WardenObjectiveEventData e)
		{
			//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_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_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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_0040: 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_0042: 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_0087: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			LG_LayerType layer = e.Layer;
			eLocalZoneIndex localIndex = e.LocalIndex;
			eDimensionIndex dimensionIndex = e.DimensionIndex;
			TERM_Command terminalCommand = e.TerminalCommand;
			LG_ComputerTerminal val2;
			if (terminalCommand - 21 <= 2)
			{
				LG_WardenObjective_Reactor val = ReactorInstanceManager.FindVanillaReactor(layer, e.Count);
				if ((Object)(object)val == (Object)null)
				{
					val2 = Helper.FindTerminal(dimensionIndex, layer, localIndex, e.Count);
					if ((Object)(object)val2 == (Object)null)
					{
						LegacyLogger.Error($"SetTerminalCommand_Custom: Cannot find reactor for {layer} or instance index ({(dimensionIndex, layer, localIndex, e.Count)})");
						return;
					}
				}
				else
				{
					val2 = val.m_terminal;
				}
			}
			else
			{
				val2 = Helper.FindTerminal(e.DimensionIndex, e.Layer, e.LocalIndex, e.Count);
			}
			if ((Object)(object)val2 == (Object)null)
			{
				LegacyLogger.Error("SetTerminalCommand_Custom: temrinal not found");
				return;
			}
			if (e.Enabled)
			{
				val2.TrySyncSetCommandShow(e.TerminalCommand);
			}
			else
			{
				val2.TrySyncS

plugins/net6/ScanPosOverride.dll

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		private static LiveEditListener listener = null;

		private static Harmony m_Harmony = null;

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

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

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

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

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

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


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


		public bool HideSpline { get; set; }

		public bool ConcurrentCluster { get; set; }

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


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


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


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

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

		public float y { get; set; }

		public float z { get; set; }

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

		public Quaternion ToQuaternion()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.Euler(x, y, z);
		}
	}
}
namespace ScanPosOverride.Patches
{
	[HarmonyPatch]
	internal class Patch_CP_Bioscan_Core_OnSyncStateChange
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Bioscan_Core), "OnSyncStateChange")]
		private static void Post_CP_Bioscan_Core_OnSyncStateChanged(CP_Bioscan_Core __instance, float progress, eBioscanStatus status, List<PlayerAgent> playersInScan)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Invalid comparison between Unknown and I4
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Invalid comparison between Unknown and I4
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Invalid comparison between Unknown and I4
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: 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)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			bool flag = PlayerScannerManager.Current.IsConcurrentCluster(__instance);
			if (flag && __instance.m_reqItemsEnabled)
			{
				SPOLogger.Warning($"OnSyncStateChange: status - {status}, playersInScan - {playersInScan.Count}, progress: {progress}");
			}
			if ((int)status != 3)
			{
				if (flag)
				{
					if ((int)status == 4)
					{
						CP_Cluster_Core parentClusterCore = PlayerScannerManager.Current.GetParentClusterCore(__instance);
						if ((Object)(object)parentClusterCore == (Object)null)
						{
							SPOLogger.Error("Cannot find parent cluster core! The concurrent cluster may fail!");
						}
						else
						{
							PlayerScannerManager.Current.CompleteConcurrentCluster(parentClusterCore);
						}
					}
					else
					{
						PlayerScannerManager.Current.ConcurrentClusterShouldProgress(__instance, IsThisScanShouldProgress: false);
					}
				}
				if (__instance.m_reqItemsEnabled)
				{
					__instance.m_graphics.SetColorMode((eChainedPuzzleGraphicsColorMode)((!__instance.m_hasAlarm) ? 1 : 4));
				}
			}
			else
			{
				if (!__instance.IsMovable && !flag && !__instance.m_reqItemsEnabled)
				{
					return;
				}
				CP_PlayerScanner cacheScanner = PlayerScannerManager.Current.GetCacheScanner(__instance);
				if ((Object)(object)cacheScanner == (Object)null)
				{
					SPOLogger.Error("Null CP_PlayerScanner");
					return;
				}
				int count = playersInScan.Count;
				List<PlayerAgent> playerAgentsInLevel = PlayerManager.PlayerAgentsInLevel;
				float num = 0f;
				float[] cacheOriginalScanSpeed = PlayerScannerManager.Current.GetCacheOriginalScanSpeed(__instance);
				if ((int)__instance.m_playerScanner.ScanPlayersRequired == 0)
				{
					num = ((count <= 0) ? 0f : cacheOriginalScanSpeed[count - 1]);
				}
				else if (((int)cacheScanner.m_playerRequirement == 1 && count == playerAgentsInLevel.Count) || ((int)cacheScanner.m_playerRequirement == 2 && count == 1))
				{
					num = cacheOriginalScanSpeed[0];
				}
				bool flag2 = num > 0f;
				if (flag2 && cacheScanner.m_reqItemsEnabled)
				{
					for (int i = 0; i < ((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems).Length; i++)
					{
						Vector3 val = Vector3.zero;
						if ((int)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickupItemStatus == 0)
						{
							val = ((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].transform.position;
						}
						else if ((int)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickupItemStatus == 1)
						{
							if ((Object)(object)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickedUpByPlayer != (Object)null)
							{
								val = ((Agent)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickedUpByPlayer).Position;
							}
							else
							{
								Debug.LogError(Object.op_Implicit("Playerscanner is looking for an item that has ePickupItemStatus.PickedUp but null player, how come!?"));
							}
						}
						Vector3 val2 = ((Component)cacheScanner).transform.position - val;
						if (((Vector3)(ref val2)).sqrMagnitude >= cacheScanner.m_scanRadiusSqr)
						{
							flag2 = false;
							break;
						}
					}
				}
				if (flag)
				{
					if (flag2)
					{
						flag2 = PlayerScannerManager.Current.ConcurrentClusterShouldProgress(__instance, IsThisScanShouldProgress: true);
					}
					else
					{
						PlayerScannerManager.Current.ConcurrentClusterShouldProgress(__instance, IsThisScanShouldProgress: false);
					}
				}
				if (flag2)
				{
					if (flag)
					{
						CP_Cluster_Core parentClusterCore2 = PlayerScannerManager.Current.GetParentClusterCore(__instance);
						if ((Object)(object)parentClusterCore2 == (Object)null)
						{
							SPOLogger.Error("null clusterParent");
						}
						PlayerScannerManager.Current.RestoreConcurrentClusterScanSpeed(parentClusterCore2);
					}
					if (__instance.IsMovable)
					{
						__instance.m_movingComp.ResumeMovement();
					}
					if (cacheScanner.m_reqItemsEnabled)
					{
						if ((int)cacheScanner.m_playerRequirement == 0)
						{
							((Il2CppArrayBase<float>)(object)cacheScanner.m_scanSpeeds)[0] = ((count > 0) ? cacheOriginalScanSpeed[count - 1] : 0f);
						}
						__instance.m_graphics.SetColorMode((eChainedPuzzleGraphicsColorMode)(__instance.m_hasAlarm ? 5 : 2));
					}
					return;
				}
				if (flag)
				{
					CP_Cluster_Core parentClusterCore3 = PlayerScannerManager.Current.GetParentClusterCore(__instance);
					if ((Object)(object)parentClusterCore3 == (Object)null)
					{
						SPOLogger.Error("null clusterParent");
					}
					PlayerScannerManager.Current.ZeroConcurrentClusterScanSpeed(parentClusterCore3);
				}
				if (__instance.IsMovable)
				{
					__instance.m_movingComp.PauseMovement();
				}
				if (cacheScanner.m_reqItemsEnabled)
				{
					if ((int)cacheScanner.m_playerRequirement == 0)
					{
						PlayerScannerManager.Current.GetCacheOriginalScanSpeed(__instance);
						((Il2CppArrayBase<float>)(object)cacheScanner.m_scanSpeeds)[0] = 0f;
					}
					__instance.m_graphics.SetColorMode((eChainedPuzzleGraphicsColorMode)((!__instance.m_hasAlarm) ? 1 : 4));
				}
			}
		}

		static Patch_CP_Bioscan_Core_OnSyncStateChange()
		{
		}
	}
	[HarmonyPatch]
	internal class Patch_CP_Bioscan_Core_Setup
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")]
		private static void Pre_CP_Bioscan_Core_Setup(CP_Bioscan_Core __instance, int puzzleIndex, iChainedPuzzleOwner owner, ref Vector3 prevPuzzlePos, ref bool revealWithHoloPath, ref bool onlyShowHUDWhenPlayerIsClose)
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_0048: 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_0212: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			ChainedPuzzleInstance val = ((Il2CppObjectBase)owner).TryCast<ChainedPuzzleInstance>();
			if ((Object)(object)val != (Object)null)
			{
				if (puzzleIndex != 0)
				{
					CP_Bioscan_Core val2 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Bioscan_Core>();
					if ((Object)(object)val2 != (Object)null)
					{
						prevPuzzlePos = ((Component)val2).transform.position;
					}
					else
					{
						CP_Cluster_Core val3 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Cluster_Core>();
						if ((Object)(object)val3 == (Object)null)
						{
							SPOLogger.Error($"Cannot cast m_chainedPuzzleCores[{puzzleIndex - 1}] to neither CP_Bioscan_Core or CP_Cluster_Core! WTF???");
						}
						else
						{
							prevPuzzlePos = ((Component)val3).transform.position;
						}
					}
				}
			}
			else
			{
				CP_Cluster_Core val4 = ((Il2CppObjectBase)owner).TryCast<CP_Cluster_Core>();
				if ((Object)(object)val4 == (Object)null)
				{
					SPOLogger.Error("Onwer is not neither ChainedPuzzleInstance nor CP_Cluster_Core. What r u?");
					return;
				}
				prevPuzzlePos = ((Component)val4).transform.position;
				val = ((Il2CppObjectBase)val4.m_owner).TryCast<ChainedPuzzleInstance>();
				if ((Object)(object)val == (Object)null)
				{
					SPOLogger.Error("Failed to cast clusterOwner.m_owner to ChainedPuzzleInstance");
					return;
				}
				if (val.Data.OnlyShowHUDWhenPlayerIsClose)
				{
					onlyShowHUDWhenPlayerIsClose = true;
				}
			}
			uint puzzleIndex2 = PuzzleOverrideManager.Current.Register(__instance);
			PuzzleOverride puzzleOverride = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, puzzleIndex2);
			if (puzzleOverride == null)
			{
				return;
			}
			if ((double)puzzleOverride.Position.x != 0.0 || (double)puzzleOverride.Position.y != 0.0 || (double)puzzleOverride.Position.z != 0.0 || (double)puzzleOverride.Rotation.x != 0.0 || (double)puzzleOverride.Rotation.y != 0.0 || (double)puzzleOverride.Rotation.z != 0.0)
			{
				((Component)__instance).transform.SetPositionAndRotation(puzzleOverride.Position.ToVector3(), puzzleOverride.Rotation.ToQuaternion());
			}
			if (puzzleOverride.EventsOnPuzzleSolved != null && puzzleOverride.EventsOnPuzzleSolved.Count > 0)
			{
				__instance.OnPuzzleDone += Action<int>.op_Implicit((Action<int>)delegate
				{
					foreach (WardenObjectiveEventData item in puzzleOverride.EventsOnPuzzleSolved)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(item, (eWardenObjectiveEventTrigger)0, true, 0f);
					}
				});
			}
			if (puzzleOverride.HideSpline || ((Object)(object)__instance.m_movingComp != (Object)null && __instance.m_movingComp.IsMoveConfigured))
			{
				revealWithHoloPath = false;
			}
			if (puzzleOverride.RequiredItemsIndices != null && puzzleOverride.RequiredItemsIndices.Count > 0)
			{
				PuzzleReqItemManager.Current.QueueForAddingReqItems(__instance, puzzleOverride.RequiredItemsIndices);
			}
			SPOLogger.Warning("Overriding CP_Bioscan_Core." + (((Object)(object)val == (Object)null) ? "" : $"Zone {val.m_sourceArea.m_zone.Alias}, Layer {val.m_sourceArea.m_zone.Layer.m_type}, Dim {val.m_sourceArea.m_zone.DimensionIndex}"));
		}
	}
	[HarmonyPatch]
	internal class Patch_ChainedPuzzleInstance_SetupMovement
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ChainedPuzzleInstance), "SetupMovement")]
		private static bool Pre_SetupMovement(ChainedPuzzleInstance __instance, GameObject gameObject)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			iChainedPuzzleMovable movingComp = gameObject.GetComponent<iChainedPuzzleMovable>();
			if (movingComp == null || !movingComp.UsingStaticBioscanPoints)
			{
				return true;
			}
			CP_BasicMovable val = ((Il2CppObjectBase)movingComp).Cast<CP_BasicMovable>();
			CP_Bioscan_Core val2 = ((Il2CppObjectBase)gameObject.GetComponent<iChainedPuzzleCore>()).TryCast<CP_Bioscan_Core>();
			if ((Object)(object)val2 == (Object)null)
			{
				SPOLogger.Error("Pre_SetupMovement: iChainedPuzzleCore -> CP_Bioscan_Core failed");
				return true;
			}
			uint bioscanCoreOverrideIndex = PuzzleOverrideManager.Current.GetBioscanCoreOverrideIndex(((Il2CppObjectBase)val2).Pointer);
			if (bioscanCoreOverrideIndex == 0)
			{
				SPOLogger.Error("Did not find registered movable override for this movable scan.");
				return true;
			}
			PuzzleOverride @override = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, bioscanCoreOverrideIndex);
			if (@override == null || @override.TPositions.Count < 1)
			{
				SPOLogger.Error("No Override for this T-Scan, falling back to vanilla impl.");
				return true;
			}
			@override.TPositions.ForEach(delegate(Vec3 pos)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				movingComp.ScanPositions.Add(pos.ToVector3());
			});
			gameObject.transform.position = @override.TPositions[0].ToVector3();
			SPOLogger.Warning("Overriding T-Scan pos!");
			val.m_amountOfPositions = @override.TPositions.Count;
			if (@override.TMoveSpeedMulti > 0f)
			{
				val.m_movementSpeed *= @override.TMoveSpeedMulti;
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal class Patch_CarryItemPickup_Core_Setup
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CarryItemPickup_Core), "Setup")]
		private static void Post_CarryItemPickup_Core_Setup(CarryItemPickup_Core __instance)
		{
			PuzzleReqItemManager.Current.Register(__instance);
		}
	}
	[HarmonyPatch]
	internal class Patch_CP_Cluster_Core_Setup
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(CP_Cluster_Core), "Setup")]
		private static void Pre_CP_Cluster_Core_Setup(CP_Cluster_Core __instance, int puzzleIndex, iChainedPuzzleOwner owner, ref Vector3 prevPuzzlePos, ref bool revealWithHoloPath)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_003c: 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_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			ChainedPuzzleInstance val = new ChainedPuzzleInstance(((Il2CppObjectBase)owner).Pointer);
			if (puzzleIndex != 0)
			{
				CP_Bioscan_Core val2 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Bioscan_Core>();
				if ((Object)(object)val2 != (Object)null)
				{
					prevPuzzlePos = ((Component)val2).transform.position;
				}
				else
				{
					CP_Cluster_Core val3 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Cluster_Core>();
					if ((Object)(object)val3 == (Object)null)
					{
						SPOLogger.Error($"Cannot cast m_chainedPuzzleCores[{puzzleIndex - 1}] to neither CP_Bioscan_Core or CP_Cluster_Core! WTF???");
					}
					else
					{
						prevPuzzlePos = ((Component)val3).transform.position;
					}
				}
			}
			uint puzzleIndex2 = PuzzleOverrideManager.Current.Register(__instance);
			PuzzleOverride puzzleOverride = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, puzzleIndex2);
			if (puzzleOverride == null)
			{
				return;
			}
			if ((double)puzzleOverride.Position.x != 0.0 || (double)puzzleOverride.Position.y != 0.0 || (double)puzzleOverride.Position.z != 0.0 || (double)puzzleOverride.Rotation.x != 0.0 || (double)puzzleOverride.Rotation.y != 0.0 || (double)puzzleOverride.Rotation.z != 0.0)
			{
				((Component)__instance).transform.SetPositionAndRotation(puzzleOverride.Position.ToVector3(), puzzleOverride.Rotation.ToQuaternion());
			}
			if (puzzleOverride.EventsOnPuzzleSolved != null && puzzleOverride.EventsOnPuzzleSolved.Count > 0)
			{
				__instance.OnPuzzleDone += Action<int>.op_Implicit((Action<int>)delegate
				{
					foreach (WardenObjectiveEventData item in puzzleOverride.EventsOnPuzzleSolved)
					{
						WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(item, (eWardenObjectiveEventTrigger)0, true, 0f);
					}
				});
			}
			if (puzzleOverride.RequiredItemsIndices != null && puzzleOverride.RequiredItemsIndices.Count > 0)
			{
				PuzzleReqItemManager.Current.QueueForAddingReqItems(__instance, puzzleOverride.RequiredItemsIndices);
			}
			if (puzzleOverride.HideSpline)
			{
				revealWithHoloPath = false;
			}
			SPOLogger.Warning("Overriding CP_Cluster_Core!");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Cluster_Core), "Setup")]
		private static void Post_CP_Cluster_Core_Setup(CP_Cluster_Core __instance)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00da: 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)
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores)
			{
				if (!item.IsMovable)
				{
					continue;
				}
				uint bioscanCoreOverrideIndex = PuzzleOverrideManager.Current.GetBioscanCoreOverrideIndex(((Il2CppObjectBase)item).Pointer);
				if (bioscanCoreOverrideIndex == 0)
				{
					continue;
				}
				PuzzleOverride @override = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, bioscanCoreOverrideIndex);
				if (@override == null || @override.TPositions == null || @override.TPositions.Count < 1)
				{
					SPOLogger.Error("No Override for this T-Scan, falling back to vanilla impl.");
					continue;
				}
				CP_Bioscan_Core val = new CP_Bioscan_Core(((Il2CppObjectBase)item).Pointer);
				if ((Object)(object)val.m_movingComp == (Object)null)
				{
					Debug.LogError(Object.op_Implicit("Chained puzzle instance set to movable but does not include iChainedPuzzleMovable."));
				}
				else if (val.m_movingComp.UsingStaticBioscanPoints)
				{
					foreach (Vec3 tPosition in @override.TPositions)
					{
						val.m_movingComp.ScanPositions.Add(tPosition.ToVector3());
					}
					((Component)val).transform.position = @override.TPositions[0].ToVector3();
					__instance.m_revealWithHoloPath = false;
					SPOLogger.Warning("Overriding T-Scan pos!");
				}
				else
				{
					Debug.LogError(Object.op_Implicit("Unimplemented."));
				}
			}
			uint clusterCoreOverrideIndex = PuzzleOverrideManager.Current.GetClusterCoreOverrideIndex(__instance);
			if (clusterCoreOverrideIndex != 0)
			{
				PuzzleOverride override2 = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, clusterCoreOverrideIndex);
				if (override2 != null && override2.ConcurrentCluster)
				{
					PlayerScannerManager.Current.RegisterConcurrentCluster(__instance);
					SPOLogger.Warning("Setting up CP_Cluster_Core as Concurrent Cluster!");
				}
			}
		}
	}
	[HarmonyPatch]
	internal class Patches_CP_Cluster_Hud_ReqItems
	{
		private static Dictionary<IntPtr, List<bool>> clustersChildrenReqItemEnabled;

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

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

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

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

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

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

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

		private Dictionary<CP_Cluster_Core, List<CP_PlayerScanner>> ConcurrentClusterCores = new Dictionary<CP_Cluster_Core, List<CP_PlayerScanner>>();

		private Dictionary<CP_Cluster_Core, List<CP_Bioscan_Core>> ConcurrentClusterChildCores = new Dictionary<CP_Cluster_Core, List<CP_Bioscan_Core>>();

		private Dictionary<IntPtr, CP_Cluster_Core> ConcurrentScanClusterParents = new Dictionary<IntPtr, CP_Cluster_Core>();

		private Dictionary<CP_Cluster_Core, HashSet<IntPtr>> ConcurrentClusterChildScanState = new Dictionary<CP_Cluster_Core, HashSet<IntPtr>>();

		private Mutex ConcurrentClusterStateMutex;

		private Dictionary<CP_Cluster_Core, float[]> OriginalClusterScanSpeeds = new Dictionary<CP_Cluster_Core, float[]>();

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

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

		private static readonly float[] ZERO_SCAN_SPEED;

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

		internal bool IsConcurrentCluster(CP_Cluster_Core core)
		{
			return ConcurrentClusterCores.ContainsKey(core);
		}

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

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

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

		internal float[] GetCacheOriginalScanSpeed(CP_Bioscan_Core core)
		{
			if (IsConcurrentCluster(core))
			{
				if (!ConcurrentScanClusterParents.ContainsKey(((Il2CppObjectBase)core).Pointer))
				{
					return ZERO_SCAN_SPEED;
				}
				CP_Cluster_Core key = ConcurrentScanClusterParents[((Il2CppObjectBase)core).Pointer];
				if (!OriginalClusterScanSpeeds.ContainsKey(key))
				{
					return ZERO_SCAN_SPEED;
				}
				return OriginalClusterScanSpeeds[key];
			}
			if (OriginalScanSpeed.ContainsKey(((Il2CppObjectBase)core).Pointer))
			{
				return OriginalScanSpeed[((Il2CppObjectBase)core).Pointer];
			}
			CP_PlayerScanner cacheScanner = GetCacheScanner(core);
			if ((Object)(object)cacheScanner == (Object)null)
			{
				SPOLogger.Error("GetCacheOriginalScanSpeed: cannot get scanner for this CP_Bioscan_Core");
				return ZERO_SCAN_SPEED;
			}
			float[] array = new float[4];
			for (int i = 0; i < 4; i++)
			{
				array[i] = ((Il2CppArrayBase<float>)(object)cacheScanner.m_scanSpeeds)[i];
			}
			OriginalScanSpeed.Add(((Il2CppObjectBase)core).Pointer, array);
			return array;
		}

		internal CP_Cluster_Core GetParentClusterCore(CP_Bioscan_Core core)
		{
			if (!ConcurrentScanClusterParents.ContainsKey(((Il2CppObjectBase)core).Pointer))
			{
				return null;
			}
			return ConcurrentScanClusterParents[((Il2CppObjectBase)core).Pointer];
		}

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

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

		internal void CompleteConcurrentCluster(CP_Cluster_Core core)
		{
			if (!ConcurrentClusterChildCores.ContainsKey(core))
			{
				return;
			}
			List<CP_Bioscan_Core> list = ConcurrentClusterChildCores[core];
			ConcurrentClusterChildCores.Remove(core);
			foreach (CP_Bioscan_Core item in list)
			{
				item.m_sync.SetStateData((eBioscanStatus)4, 0f, (List<PlayerAgent>)null, 0, (Il2CppStructArray<bool>)null);
			}
		}

		public void Init()
		{
			ConcurrentClusterStateMutex = new Mutex();
		}

		public void Clear()
		{
			ConcurrentClusterCores.Clear();
			ConcurrentClusterChildCores.Clear();
			ConcurrentScanClusterParents.Clear();
			ConcurrentClusterChildScanState.Clear();
			OriginalClusterScanSpeeds.Clear();
			Scanners.Clear();
			OriginalScanSpeed.Clear();
			if (ConcurrentClusterStateMutex != null)
			{
				ConcurrentClusterStateMutex.Dispose();
			}
			ConcurrentClusterStateMutex = null;
		}

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

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

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

		private int itemIndexCounter = 1;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		private Dictionary<CP_Bioscan_Core, uint> bioscanCore2Index = new Dictionary<CP_Bioscan_Core, uint>();

		private Dictionary<CP_Cluster_Core, uint> clusterCore2Index = new Dictionary<CP_Cluster_Core, uint>();

		private Dictionary<uint, CP_Bioscan_Core> index2BioscanCore = new Dictionary<uint, CP_Bioscan_Core>();

		private Dictionary<uint, CP_Cluster_Core> index2ClusterCore = new Dictionary<uint, CP_Cluster_Core>();

		private Dictionary<IntPtr, uint> bioscanCoreIntPtr2Index = new Dictionary<IntPtr, uint>();

		private Dictionary<IntPtr, uint> clusterCoreIntPtr2Index = new Dictionary<IntPtr, uint>();

		private uint puzzleOverrideIndex = 1u;

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

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

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

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

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

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

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

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

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

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

		public void Clear()
		{
			puzzleOverrideIndex = 1u;
			bioscanCore2Index.Clear();
			clusterCore2Index.Clear();
			bioscanCoreIntPtr2Index.Clear();
			clusterCoreIntPtr2Index.Clear();
			index2BioscanCore.Clear();
			index2ClusterCore.Clear();
		}

		private PuzzleOverrideManager()
		{
		}

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

		public iChainedPuzzleOwner ChainedPuzzleInstanceOwner(CP_Bioscan_Core bioscanCore)
		{
			if ((Object)(object)bioscanCore == (Object)null)
			{
				return null;
			}
			iChainedPuzzleOwner owner = bioscanCore.Owner;
			if ((Object)(object)((Il2CppObjectBase)owner).TryCast<ChainedPuzzleInstance>() != (Object)null)
			{
				return owner;
			}
			CP_Cluster_Core val = ((Il2CppObjectBase)owner).TryCast<CP_Cluster_Core>();
			if ((Object)(object)val != (Object)null)
			{
				return val.m_owner;
			}
			SPOLogger.Error("Failed to find CP_BioScan_Core owner (instance of ChainedPuzzleInstance).");
			return null;
		}
	}
}
namespace ScanPosOverride.JSON
{
	internal class LocalizedTextConverter : JsonConverter<LocalizedText>
	{
		public override bool HandleNull => false;

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

		public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
		{
			JsonSerializer.Serialize<LocalizedText>(writer, value, options);
		}
	}
	internal static class Json
	{
		private static readonly JsonSerializerOptions _setting;

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

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

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

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

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

		public static JsonConverter PersistentIDConverter { get; private set; }

		public static JsonConverter LocalizedTextConverter { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool Initialized { get; private set; }

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

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

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

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

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

plugins/net6/SecDoorTerminalInterface.dll

Decompiled 4 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
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.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using ChainedPuzzles;
using GTFO.API;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using SecDoorTerminalInterface.Inject;
using TMPro;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SecDoorTerminalInterface
{
	internal static class Assets
	{
		public static GameObject SecDoorTerminalPrefab;

		public static void Init()
		{
			SecDoorTerminalPrefab = AssetAPI.GetLoadedAsset<GameObject>("Assets/Modding/SecDoorTerminal/Terminal_SecDoor.prefab");
		}
	}
	public struct CommandDescriptor
	{
		public TERM_Command Type;

		public string Command;

		public string Description;

		public TERM_CommandRule Rule;
	}
	public enum CPSolvedBehaviour
	{
		OpenDoor,
		AddOpenCommand,
		Nothing
	}
	[BepInPlugin("SecDoorTerminalInterface", "SecDoorTerminalInterface", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class EntryPoint : BasePlugin
	{
		private Harmony _Harmony;

		public override void Load()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			AssetAPI.OnAssetBundlesLoaded += AssetAPI_OnAssetBundlesLoaded;
			_Harmony = new Harmony("SecDoorTerminalInterface.Harmony");
			_Harmony.PatchAll();
		}

		private void AssetAPI_OnAssetBundlesLoaded()
		{
			Assets.Init();
		}
	}
	internal static class Logger
	{
		private static readonly ManualLogSource _Logger;

		static Logger()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_Logger = new ManualLogSource("SecDoorTerminalInterface");
			Logger.Sources.Add((ILogSource)(object)_Logger);
		}

		private static string Format(object msg)
		{
			return msg.ToString();
		}

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

		public static void Info(string str)
		{
			_Logger.LogMessage((object)str);
		}

		public static void Info(object data)
		{
			_Logger.LogMessage((object)Format(data));
		}

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

		public static void Debug(string str)
		{
			_Logger.LogDebug((object)str);
		}

		public static void Debug(object data)
		{
			_Logger.LogDebug((object)Format(data));
		}

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

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

		public static void Error(object data)
		{
			_Logger.LogError((object)Format(data));
		}

		public static void Fatal(BepInExFatalLogInterpolatedStringHandler handler)
		{
			_Logger.LogFatal(handler);
		}

		public static void Fatal(string str)
		{
			_Logger.LogFatal((object)str);
		}

		public static void Fatal(object data)
		{
			_Logger.LogFatal((object)Format(data));
		}

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

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

		public static void Warn(object data)
		{
			_Logger.LogWarning((object)Format(data));
		}

		[Conditional("DEBUG")]
		public static void DebugOnly(object data)
		{
		}
	}
	public sealed class SecDoorTerminal
	{
		public const TERM_Command COMMAND_OPEN = 255;

		public const TERM_Command COMMAND_OVERRIDE = 254;

		private LocalizedText _GCTextHolder;

		private Vector3 _SavedIntOpenDoorPos;

		private Vector3 _SavedIntUseKeyPos;

		private Vector3 _SavedIntCustomMessagePos;

		private Vector3 _SavedIntHackPos;

		private SDT_StateBehaviour _StateBehaviour;

		private static readonly Vector3 BEGONE = Vector3.one * 10000f;

		public string OpenCommandName { get; set; } = "OPEN_LINKED";


		public string OpenCommandDescription { get; set; } = "Open the linked security door";


		public LG_SecurityDoor LinkedDoor { get; private set; }

		public LG_SecurityDoor_Locks LinkedDoorLocks { get; private set; }

		public LG_ComputerTerminal ComputerTerminal { get; private set; }

		public LG_ComputerTerminalCommandInterpreter CmdProcessor { get; private set; }

		public Interact_ComputerTerminal Interaction { get; private set; }

		public TextMeshPro IdleText { get; private set; }

		public SpriteRenderer IdleIcon { get; private set; }

		public AIG_CourseNode SpawnNode => ComputerTerminal.m_terminalItem.SpawnNode;

		public bool IsTerminalActive { get; private set; } = true;


		public CPSolvedBehaviour BioscanScanSolvedBehaviour { get; set; } = CPSolvedBehaviour.AddOpenCommand;


		public SDT_StateBehaviour StateBehaviour
		{
			get
			{
				return _StateBehaviour;
			}
			set
			{
				_StateBehaviour?.SetContext(null);
				_StateBehaviour = value;
				_StateBehaviour?.SetContext(this);
			}
		}

		public event Action<TERM_Command, string, string, string> OnCmdUsed;

		private void Setup_CommandModule()
		{
			Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced += OnReceiveCommand;
		}

		private void OnReceiveCommand(LG_ComputerTerminalCommandInterpreter interpreter, TERM_Command cmd, string inputLine, string param1, string param2)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (interpreter.m_terminal.m_syncID == ComputerTerminal.m_syncID)
			{
				this.OnCmdUsed?.Invoke(cmd, inputLine, param1, param2);
			}
		}

		public void AddCommand(CommandDescriptor descriptor, Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed = null)
		{
			//IL_0027: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_009e: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (CmdProcessor.HasRegisteredCommand(descriptor.Type))
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Command Type: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<TERM_Command>(descriptor.Type);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is Already Added!!");
				}
				Logger.Error(val);
				return;
			}
			_GCTextHolder = new LocalizedText
			{
				UntranslatedText = descriptor.Description,
				Id = 0u
			};
			CmdProcessor.AddCommand(descriptor.Type, descriptor.Command, _GCTextHolder, descriptor.Rule);
			OnCmdUsed += delegate(TERM_Command cmdType, string cmdStr, string param1, string param2)
			{
				//IL_0000: 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)
				if (cmdType == descriptor.Type)
				{
					onCommandUsed?.Invoke(CmdProcessor);
				}
			};
		}

		public void AddOverrideCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed = null)
		{
			//IL_0023: 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)
			CommandDescriptor commandDescriptor = default(CommandDescriptor);
			commandDescriptor.Type = (TERM_Command)254;
			commandDescriptor.Command = cmd;
			commandDescriptor.Description = helpText;
			commandDescriptor.Rule = (TERM_CommandRule)1;
			CommandDescriptor descriptor = commandDescriptor;
			AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter)
			{
				onCommandUsed?.Invoke(CmdProcessor);
				interpreter.AddOutput((TerminalLineType)0, "Desired Action: <color=orange>OVERRIDE</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
				interpreter.AddOutput((TerminalLineType)4, "Decrypting Authorize ID..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
				interpreter.AddOutput((TerminalLineType)2, "Sending..", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
				interpreter.AddOutput((TerminalLineType)5, "<color=orange>OVERRIDE</color> Action sent!", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
				SetEndOfQueue(delegate
				{
					if (SNet.IsMaster)
					{
						LinkedDoorLocks.m_intOpenDoor.OnInteractionTriggered.Invoke(PlayerManager.GetLocalPlayerAgent());
					}
				});
			});
		}

		public void AddOpenCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed = null)
		{
			//IL_0023: 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)
			CommandDescriptor commandDescriptor = default(CommandDescriptor);
			commandDescriptor.Type = (TERM_Command)255;
			commandDescriptor.Command = cmd;
			commandDescriptor.Description = helpText;
			commandDescriptor.Rule = (TERM_CommandRule)1;
			CommandDescriptor descriptor = commandDescriptor;
			AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter)
			{
				onCommandUsed?.Invoke(interpreter);
				interpreter.AddOutput((TerminalLineType)0, "Desired Action: <color=orange>OPEN</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
				interpreter.AddOutput((TerminalLineType)4, "Decrypting Authorize ID..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
				interpreter.AddOutput((TerminalLineType)2, "Sending..", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
				interpreter.AddOutput((TerminalLineType)5, "<color=orange>OVERRIDE</color> Action sent!", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
				SetEndOfQueue(delegate
				{
					if (SNet.IsMaster)
					{
						LinkedDoorLocks.m_intOpenDoor.OnInteractionTriggered.Invoke(PlayerManager.GetLocalPlayerAgent());
					}
				});
			});
		}

		public void SetEndOfQueue(Action onEndOfQueue)
		{
			CmdProcessor.OnEndOfQueue = Action.op_Implicit(onEndOfQueue);
		}

		private void Setup()
		{
			Setup_GraphicModule();
			Setup_DoorInteractModule();
			Setup_DoorStateModule();
			Setup_CommandModule();
		}

		public void SetTerminalActive(bool active)
		{
			IsTerminalActive = active;
			((Behaviour)ComputerTerminal).enabled = active;
			Interact_ComputerTerminal componentInChildren = ((Component)ComputerTerminal).GetComponentInChildren<Interact_ComputerTerminal>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Behaviour)componentInChildren).enabled = active;
				((Interact_Base)componentInChildren).SetActive(active);
			}
			if (!active)
			{
				PlayerAgent localInteractionSource = ComputerTerminal.m_localInteractionSource;
				if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger)
				{
					ComputerTerminal.ExitFPSView();
				}
				if (SNet.IsMaster)
				{
					ComputerTerminal.ChangeState((TERM_State)0);
				}
			}
		}

		public void SetSpawnNode(AIG_CourseNode node)
		{
			ComputerTerminal.m_terminalItem.SpawnNode = node;
		}

		public void SetLocationTextToSpawnZone()
		{
			SetLocationText(SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7));
		}

		public void SetLocationText(string text)
		{
			ComputerTerminal.m_terminalItem.FloorItemLocation = text;
		}

		private SecDoorTerminal()
		{
		}

		public void SetOpenInteractActive(bool active)
		{
			//IL_001c: 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)
			Interact_Timed intOpenDoor = LinkedDoorLocks.m_intOpenDoor;
			((Component)intOpenDoor).transform.position = (active ? _SavedIntOpenDoorPos : BEGONE);
			((Interact_Base)intOpenDoor).SetActive(active);
		}

		public void SetUseKeyInteractActive(bool active)
		{
			//IL_001c: 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)
			Interact_RequireKeyItem intUseKeyItem = LinkedDoorLocks.m_intUseKeyItem;
			((Component)intUseKeyItem).transform.position = (active ? _SavedIntUseKeyPos : BEGONE);
			((Interact_Base)intUseKeyItem).SetActive(active);
		}

		public void SetHackingInteractActive(bool active)
		{
			//IL_001c: 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)
			Interact_Hack intHack = LinkedDoorLocks.m_intHack;
			((Component)intHack).transform.position = (active ? _SavedIntHackPos : BEGONE);
			((Interact_Base)intHack).SetActive(active);
		}

		public void SetCustomMessageActive(bool active)
		{
			//IL_001c: 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)
			Interact_MessageOnScreen intCustomMessage = LinkedDoorLocks.m_intCustomMessage;
			((Component)intCustomMessage).transform.position = (active ? _SavedIntCustomMessagePos : BEGONE);
			((Interact_Base)intCustomMessage).SetActive(active);
		}

		public void OpenOrStartChainPuzzle()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			ChainedPuzzleInstance chainedPuzzleToSolve = LinkedDoorLocks.ChainedPuzzleToSolve;
			if ((Object)(object)chainedPuzzleToSolve != (Object)null && !chainedPuzzleToSolve.IsSolved)
			{
				LinkedDoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)4, 0f, 0f, default(Vector3), (Agent)null);
			}
			else
			{
				LinkedDoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)0, 0f, 0f, default(Vector3), (Agent)null);
			}
		}

		public void ForceOpenDoor(float delay)
		{
			if (delay > 0f)
			{
				CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(OpenDoorWithDelay(delay)), (Action)null);
			}
			else
			{
				ForceOpenDoor();
			}
		}

		private IEnumerator OpenDoorWithDelay(float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			LinkedDoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)0, 0f, 0f, default(Vector3), (Agent)null);
		}

		public void ForceOpenDoor()
		{
			//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)
			LinkedDoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)0, 0f, 0f, default(Vector3), (Agent)null);
		}

		private void Setup_DoorInteractModule()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			_SavedIntOpenDoorPos = ((Component)LinkedDoorLocks.m_intOpenDoor).transform.position;
			_SavedIntUseKeyPos = ((Component)LinkedDoorLocks.m_intUseKeyItem).transform.position;
			_SavedIntCustomMessagePos = ((Component)LinkedDoorLocks.m_intCustomMessage).transform.position;
			_SavedIntHackPos = ((Component)LinkedDoorLocks.m_intHack).transform.position;
		}

		private void Setup_DoorStateModule()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			StateBehaviour = new SDT_StateBehaviour();
			LinkedDoor.m_sync.OnDoorStateChange += Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)OnStateChange);
			LinkedDoorLocks.OnChainedPuzzleSolved += Action.op_Implicit((Action)OnChainedPuzzleSolved);
			OnStateChange(LinkedDoor.m_sync.GetCurrentSyncState(), isRecall: false);
		}

		private void OnChainedPuzzleSolved()
		{
			switch (BioscanScanSolvedBehaviour)
			{
			case CPSolvedBehaviour.OpenDoor:
				if (SNet.IsMaster)
				{
					ForceOpenDoor(0.25f);
				}
				break;
			case CPSolvedBehaviour.AddOpenCommand:
				CmdProcessor.AddOutput((TerminalLineType)5, "Bioscan Sequence Completed - <color=orange>" + OpenCommandName + "</color> Command is now accessible!", 0f, (TerminalSoundType)0, (TerminalSoundType)0);
				AddOpenCommand(OpenCommandName, OpenCommandDescription);
				break;
			}
		}

		private void OnStateChange(pDoorState state, bool isRecall)
		{
			//IL_002c: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (StateBehaviour != null)
			{
				ActiveEnemyWaveData activeEnemyWaveData = LinkedDoor.ActiveEnemyWaveData;
				bool isBloodyDoor = activeEnemyWaveData != null && activeEnemyWaveData.HasActiveEnemyWave;
				SecDoorState secDoorState = default(SecDoorState);
				secDoorState.Status = state.status;
				secDoorState.State = state;
				secDoorState.IsBloodyDoor = isBloodyDoor;
				SecDoorState state2 = secDoorState;
				StateBehaviour.UpdateInteractionState(state2, isRecall);
				StateBehaviour.UpdateGraphicState(state2, isRecall);
			}
		}

		private void Setup_GraphicModule()
		{
			CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(ForceScreenOffOnDeactive()), (Action)null);
		}

		private IEnumerator ForceScreenOffOnDeactive()
		{
			while (true)
			{
				if (IsTerminalActive)
				{
					((Behaviour)ComputerTerminal.m_text).enabled = true;
				}
				else
				{
					((Behaviour)ComputerTerminal.m_text).enabled = false;
					ComputerTerminal.m_loginScreen.SetActive(true);
					ComputerTerminal.m_interfaceScreen.SetActive(true);
				}
				yield return null;
			}
		}

		public void SetIdleIconColor(Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			IdleIcon.color = color;
		}

		public void SetIdleText(string text)
		{
			((TMP_Text)IdleText).text = text;
		}

		public void SetIdleTextFontSize(float size)
		{
			((TMP_Text)IdleText).fontSize = size;
		}

		public static SecDoorTerminal Place(LG_SecurityDoor secDoor, TerminalStartStateData startData = null, TerminalPlacementData placementData = null)
		{
			//IL_0001: 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_0082: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)secDoor.m_securityDoorType != 0)
			{
				return null;
			}
			Transform val = CustomExtensions.FindChildRecursive(((Component)secDoor).transform, "InteractionInterface", true);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			((Component)val).gameObject.SetActiveRecursively(false);
			((Component)val).gameObject.SetActive(true);
			GameObject obj = Object.Instantiate<GameObject>(Assets.SecDoorTerminalPrefab, val);
			obj.transform.localPosition = (((int)secDoor.Gate.Type == 0) ? new Vector3(0f, -0.006f, 0f) : new Vector3(0f, -0.026f, 0f));
			obj.transform.localRotation = Quaternion.identity;
			obj.transform.localScale = Vector3.one;
			iTerminalItem componentInChildren = obj.GetComponentInChildren<iTerminalItem>();
			if (componentInChildren != null && TryGetSecDoorSpawnedNode(secDoor, out var spawnedNode))
			{
				componentInChildren.SpawnNode = spawnedNode;
			}
			LG_ComputerTerminal component = obj.GetComponent<LG_ComputerTerminal>();
			component.Setup(startData, placementData);
			MeshFilter[] array = Il2CppArrayBase<MeshFilter>.op_Implicit(((Component)secDoor).GetComponentsInChildren<MeshFilter>(true));
			foreach (MeshFilter val2 in array)
			{
				if (!((Object)(object)val2.sharedMesh == (Object)null))
				{
					string name = ((Object)val2.sharedMesh).name;
					if (!string.IsNullOrEmpty(name) && name.Equals("g_security_door_display"))
					{
						Transform transform = ((Component)val2).gameObject.transform;
						transform.localPosition += BEGONE;
					}
				}
			}
			SecDoorTerminal secDoorTerminal = new SecDoorTerminal();
			secDoorTerminal.LinkedDoor = secDoor;
			secDoorTerminal.LinkedDoorLocks = ((Il2CppObjectBase)secDoor.m_locks).Cast<LG_SecurityDoor_Locks>();
			secDoorTerminal.ComputerTerminal = component;
			secDoorTerminal.CmdProcessor = component.m_command;
			secDoorTerminal.Interaction = ((Component)component).GetComponentInChildren<Interact_ComputerTerminal>(true);
			secDoorTerminal.IdleIcon = component.m_loginScreen.GetComponent<SpriteRenderer>();
			secDoorTerminal.IdleText = component.m_loginScreen.GetComponentInChildren<TextMeshPro>();
			secDoorTerminal.Setup();
			return secDoorTerminal;
		}

		private static bool TryGetSecDoorSpawnedNode(LG_SecurityDoor secDoor, out AIG_CourseNode spawnedNode)
		{
			if ((Object)(object)secDoor == (Object)null)
			{
				spawnedNode = null;
				return false;
			}
			if ((Object)(object)secDoor.Gate == (Object)null)
			{
				spawnedNode = null;
				return false;
			}
			if ((Object)(object)((LG_ZoneExpander)secDoor.Gate).m_linksFrom == (Object)null)
			{
				spawnedNode = null;
				return false;
			}
			spawnedNode = ((LG_ZoneExpander)secDoor.Gate).m_linksFrom.m_courseNode;
			return spawnedNode != null;
		}
	}
	public class SDT_StateBehaviour
	{
		public SecDoorTerminal Context { get; private set; }

		internal void SetContext(SecDoorTerminal secDoorTerminal)
		{
			Context = secDoorTerminal;
		}

		public virtual void UpdateInteractionState(SecDoorState state, bool isRecall)
		{
			//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_0051: Expected I4, but got Unknown
			eDoorStatus status = state.Status;
			switch ((int)status)
			{
			case 0:
			case 1:
			case 2:
			case 4:
			case 5:
			case 7:
			case 9:
			case 12:
			case 13:
			case 14:
				Context.SetTerminalActive(active: true);
				Context.SetOpenInteractActive(active: false);
				Context.SetHackingInteractActive(active: false);
				Context.SetUseKeyInteractActive(active: false);
				Context.SetCustomMessageActive(active: false);
				break;
			case 3:
				Context.SetTerminalActive(active: false);
				Context.SetOpenInteractActive(active: false);
				Context.SetHackingInteractActive(active: false);
				Context.SetUseKeyInteractActive(active: true);
				Context.SetCustomMessageActive(active: false);
				break;
			case 6:
			case 15:
				Context.SetTerminalActive(active: false);
				Context.SetOpenInteractActive(active: false);
				Context.SetHackingInteractActive(active: false);
				Context.SetUseKeyInteractActive(active: false);
				Context.SetCustomMessageActive(active: true);
				break;
			case 8:
			case 10:
			case 11:
			case 16:
				Context.SetTerminalActive(active: false);
				Context.SetOpenInteractActive(active: false);
				Context.SetHackingInteractActive(active: false);
				Context.SetUseKeyInteractActive(active: false);
				Context.SetCustomMessageActive(active: false);
				break;
			}
		}

		public virtual void UpdateGraphicState(SecDoorState state, bool isRecall)
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected I4, but got Unknown
			//IL_0140: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			eDoorStatus status = state.Status;
			string text;
			Color? val;
			switch (status - 1)
			{
			case 14:
				text = "::<color=orange>Bulkhead Override</color> Required::";
				val = Color.yellow;
				break;
			case 2:
				text = "::<color=orange>Keycard</color> Required::";
				val = Color.red;
				break;
			case 4:
				text = "<color=orange>BIOSCAN Protocol</color> pending...";
				val = Color.cyan;
				break;
			case 3:
				text = "<color=orange>BIOSCAN Protocol</color> pending...";
				val = Color.red;
				break;
			case 5:
				text = "BOOT ERR://Power Level - <color=red>LOW</color>";
				val = ColorExt.Hex("#FFA500");
				break;
			case 6:
				text = "<color=orange>LOCKDOWN Protocol</color> engaged!";
				val = Color.red;
				break;
			case 7:
				if (Context.LinkedDoorLocks.ChainedPuzzleToSolve.Data.TriggerAlarmOnActivate)
				{
					text = "<color=red>BIOSCAN Protocol</color> processing!";
					val = Color.red;
				}
				else
				{
					text = "<color=blue>BIOSCAN Protocol</color> processing!";
					val = Color.cyan;
				}
				break;
			case 9:
			case 15:
				text = "::DOOR OVERRIDING::";
				val = Color.cyan;
				break;
			case 0:
				text = "::DOOR LOCKING::";
				val = Color.cyan;
				break;
			default:
				text = "Waiting...";
				val = Color.green;
				break;
			}
			if (val.HasValue)
			{
				Context.SetIdleIconColor(val.Value);
			}
			if (text != null)
			{
				Context.SetIdleText(text);
			}
		}
	}
	public struct SecDoorState
	{
		public eDoorStatus Status;

		public pDoorState State;

		public bool IsBloodyDoor;
	}
	[GeneratedCode("VersionInfoGenerator", "2.1.3+git35c0c2a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "SecDoorTerminalInterface";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "git6952937-master";

		public const string SemVer = "1.0.0+git6952937-master";

		public const string GitRevShort = "6952937";

		public const string GitRevLong = "69529374dcbe6b589a13bfc0c363675c5cd3e803";

		public const string GitBranch = "master";

		public const string GitTag = null;

		public const int GitCommitsSinceTag = 0;

		public const bool GitIsDirty = false;
	}
}
namespace SecDoorTerminalInterface.Inject
{
	[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")]
	internal class Inject_Terminal_ReceiveCmd
	{
		public static event Action<LG_ComputerTerminalCommandInterpreter, TERM_Command, string, string, string> OnCmdUsed_LevelInstanced;

		static Inject_Terminal_ReceiveCmd()
		{
			LevelAPI.OnLevelCleanup += delegate
			{
				Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced = null;
			};
		}

		private static void Prefix(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, string inputLine, string param1, string param2)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced?.Invoke(__instance, cmd, inputLine, param1, param2);
		}
	}
}

plugins/net6/WeaponStatShower.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using GameData;
using Gear;
using HarmonyLib;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using UnityEngine;
using WeaponStatShower.Patches;
using WeaponStatShower.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("WeaponStatShower")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WeaponStatShower")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("052b6857-9abd-4300-b5bd-ceb4b0c295db")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 WeaponStatShower
{
	public static class BIEExtensions
	{
		public static ConfigEntry<T> GetConfigEntry<T>(this ConfigFile configFile, ConfigDefinition definition)
		{
			ConfigEntry<T> result = default(ConfigEntry<T>);
			if (!configFile.TryGetEntry<T>(definition, ref result))
			{
				throw new InvalidOperationException("Config entry has not been added yet.");
			}
			return result;
		}
	}
	[BepInPlugin("WeaponStatShower", "Weapon Stat Shower", "1.2.0")]
	[BepInProcess("GTFO.exe")]
	public class WeaponStatShowerPlugin : BasePlugin
	{
		internal const string ModName = "Weapon Stat Shower";

		internal const string GUID = "WeaponStatShower";

		private const string SectionMain = "Config";

		private static readonly ConfigDefinition configDefinition = new ConfigDefinition("Config", "Version");

		private static readonly ConfigDefinition ConfigGameVersion = new ConfigDefinition("Config", "GameVersion");

		private static Harmony HarmonyInstance;

		private static readonly Dictionary<Type, Patch> RegisteredPatches = new Dictionary<Type, Patch>();

		public static WeaponStatShowerPlugin Instance { get; private set; }

		public WeaponStatShowerPlugin()
		{
			((BasePlugin)this).Config.SaveOnConfigSet = false;
		}

		public override void Load()
		{
			Instance = this;
			((BasePlugin)this).Config.SaveOnConfigSet = true;
			LogInfo("STARTED");
			RegisterPatch<ShowStat>();
			((BasePlugin)this).Config.Save();
		}

		public static void RegisterPatch<T>() where T : Patch, new()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (HarmonyInstance == null)
			{
				HarmonyInstance = new Harmony("WeaponStatShower");
			}
			if (RegisteredPatches.ContainsKey(typeof(T)))
			{
				LogDebug("Ignoring duplicate patch: " + typeof(T).Name);
				return;
			}
			T val = new T
			{
				Harmony = HarmonyInstance
			};
			val.Initialize();
			if (val.Enabled)
			{
				LogInfo("Applying patch: " + val.Name);
				val.Execute();
			}
			RegisteredPatches[typeof(T)] = val;
		}

		public static void LogDebug(object data)
		{
			((BasePlugin)Instance).Log.LogDebug(data);
		}

		public static void LogError(object data)
		{
			((BasePlugin)Instance).Log.LogError(data);
		}

		public static void LogFatal(object data)
		{
			((BasePlugin)Instance).Log.LogFatal(data);
		}

		public static void LogInfo(object data)
		{
			((BasePlugin)Instance).Log.LogInfo(data);
		}

		public static void LogMessage(object data)
		{
			((BasePlugin)Instance).Log.LogMessage(data);
		}

		public static void LogWarning(object data)
		{
			((BasePlugin)Instance).Log.LogWarning(data);
		}
	}
}
namespace WeaponStatShower.Utils
{
	internal class SleepersDatas
	{
		private readonly Dictionary<string, float[]> EnemyDatas = new Dictionary<string, float[]>();

		public SleepersDatas(string[] activatedSleepers)
		{
			foreach (string text in activatedSleepers)
			{
				switch (text.Trim())
				{
				case "NONE":
					EnemyDatas.Clear();
					return;
				case "ALL":
					EnemyDatas.TryAdd("STRK", new float[4] { 20f, 3f, 2f, 0f });
					EnemyDatas.TryAdd("SHTR", new float[4] { 30f, 5f, 2f, 0f });
					EnemyDatas.TryAdd("SCOUT", new float[4] { 42f, 3f, 2f, 0f });
					EnemyDatas.TryAdd("B-STRK", new float[4] { 120f, 1.5f, 2f, 0f });
					EnemyDatas.TryAdd("B-SHTR", new float[4] { 150f, 2f, 2f, 0f });
					EnemyDatas.TryAdd("CHRG", new float[4] { 30f, 1f, 2f, 1f });
					EnemyDatas.TryAdd("C-SCOUT", new float[4] { 60f, 1f, 2f, 1f });
					return;
				case "STRIKER":
					EnemyDatas.TryAdd("STRK", new float[4] { 20f, 3f, 2f, 0f });
					break;
				case "SHOOTER":
					EnemyDatas.TryAdd("SHTR", new float[4] { 30f, 5f, 2f, 0f });
					break;
				case "SCOUT":
					EnemyDatas.TryAdd("SCOUT", new float[4] { 42f, 3f, 2f, 0f });
					break;
				case "BIG_STRIKER":
					EnemyDatas.TryAdd("B-STRK", new float[4] { 120f, 1.5f, 2f, 0f });
					break;
				case "BIG_SHOOTER":
					EnemyDatas.TryAdd("B-SHTR", new float[4] { 150f, 2f, 2f, 0f });
					break;
				case "CHARGER":
					EnemyDatas.TryAdd("CHRG", new float[4] { 30f, 1f, 2f, 1f });
					break;
				case "CHARGER_SCOUT":
					EnemyDatas.TryAdd("C-SCOUT", new float[4] { 60f, 1f, 2f, 1f });
					break;
				default:
					WeaponStatShowerPlugin.LogWarning("You inserted an incorrect value in the config: " + text.Trim());
					break;
				}
			}
		}

		public string VerboseKill(ArchetypeDataBlock archetypeDataBlock)
		{
			StringBuilder stringBuilder = new StringBuilder();
			float damage = archetypeDataBlock.Damage * (float)((archetypeDataBlock.ShotgunBulletCount <= 0) ? 1 : archetypeDataBlock.ShotgunBulletCount);
			float precisionDamageMulti = archetypeDataBlock.PrecisionDamageMulti;
			int num = 0;
			for (int i = 0; i < EnemyDatas.Count; i++)
			{
				string text = EnemyDatas.Keys.ElementAt(i);
				List<char> list = new List<char>();
				float[] currEnemyDatas = EnemyDatas[text];
				if (canKillOnOccipit(damage, precisionDamageMulti, currEnemyDatas))
				{
					list.Add('o');
				}
				if (canKillOnHead(damage, precisionDamageMulti, currEnemyDatas))
				{
					list.Add('h');
				}
				if (canKillOnBack(damage, precisionDamageMulti, currEnemyDatas))
				{
					list.Add('b');
				}
				if (canKillOnChest(damage, currEnemyDatas))
				{
					list.Add('c');
				}
				if (list.Count > 0)
				{
					if (num % 2 == 1)
					{
						stringBuilder.Append(" | ");
					}
					list.Reverse();
					stringBuilder.Append(text + ": [" + string.Join(",", list.ToArray()) + "]");
					if (num++ % 2 == 1 && i != EnemyDatas.Count - 1)
					{
						stringBuilder.Append('\n');
					}
				}
			}
			return stringBuilder.ToString();
		}

		internal string? VerboseKill(MeleeArchetypeDataBlock archeTypeDataBlock)
		{
			StringBuilder stringBuilder = new StringBuilder();
			float num = archeTypeDataBlock.ChargedAttackDamage * archeTypeDataBlock.ChargedSleeperMulti;
			float chargedPrecisionMulti = archeTypeDataBlock.ChargedPrecisionMulti;
			int num2 = 0;
			for (int i = 0; i < EnemyDatas.Count; i++)
			{
				string text = EnemyDatas.Keys.ElementAt(i);
				if (text.Contains("SCOUT"))
				{
					num /= archeTypeDataBlock.ChargedSleeperMulti;
				}
				List<char> list = new List<char>();
				float[] currEnemyDatas = EnemyDatas[text];
				if (canKillOnOccipit(num, chargedPrecisionMulti, currEnemyDatas))
				{
					list.Add('o');
				}
				if (canKillOnHead(num, chargedPrecisionMulti, currEnemyDatas))
				{
					list.Add('h');
				}
				if (canKillOnBack(num, chargedPrecisionMulti, currEnemyDatas))
				{
					list.Add('b');
				}
				if (canKillOnChest(num, currEnemyDatas))
				{
					list.Add('c');
				}
				if (list.Count > 0)
				{
					if (num2 % 2 == 1)
					{
						stringBuilder.Append(" | ");
					}
					list.Reverse();
					stringBuilder.Append(text + ": [" + string.Join(",", list.ToArray()) + "]");
					if (num2++ % 2 == 1 && i != EnemyDatas.Count - 1)
					{
						stringBuilder.Append('\n');
					}
				}
			}
			return stringBuilder.ToString();
		}

		private bool canKillOnChest(float damage, float[] currEnemyDatas)
		{
			if (isArmored(currEnemyDatas))
			{
				return (double)damage * 0.7 >= (double)currEnemyDatas[0];
			}
			return damage >= currEnemyDatas[0];
		}

		private bool canKillOnBack(float damage, float prcsnMultiplier, float[] currEnemyDatas)
		{
			if (isArmored(currEnemyDatas))
			{
				return damage * prcsnMultiplier * currEnemyDatas[2] >= currEnemyDatas[0];
			}
			return damage * currEnemyDatas[2] >= currEnemyDatas[0];
		}

		private bool canKillOnHead(float damage, float prcsnMultiplier, float[] currEnemyDatas)
		{
			if (isArmored(currEnemyDatas))
			{
				return (double)damage * 0.7 * (double)currEnemyDatas[1] >= (double)currEnemyDatas[0];
			}
			return damage * prcsnMultiplier * currEnemyDatas[1] >= currEnemyDatas[0];
		}

		private bool canKillOnOccipit(float damage, float prcsnMultiplier, float[] currEnemyDatas)
		{
			if (isArmored(currEnemyDatas))
			{
				return (double)damage * 0.7 * (double)currEnemyDatas[2] * (double)currEnemyDatas[1] >= (double)currEnemyDatas[0];
			}
			return damage * prcsnMultiplier * currEnemyDatas[2] * currEnemyDatas[1] >= currEnemyDatas[0];
		}

		private bool isArmored(float[] currEnemyDatas)
		{
			return currEnemyDatas[3] == 1f;
		}
	}
	internal class WeaponDescriptionBuilder
	{
		private SleepersDatas sleepersDatas;

		private uint categoryID;

		private GearCategoryDataBlock gearCatBlock;

		private ItemDataBlock itemDataBlock;

		private const string DIVIDER = " | ";

		private const string CLOSE_COLOR_TAG = "</color>";

		private PlayerDataBlock _playerDataBlock { get; set; }

		private GearIDRange idRange { get; set; }

		private static string Short_MeleeLight { get; } = ".Lgt";


		private static string Short_MeleeCharged { get; } = ".Hvy";


		private static string Short_MeleeCanRunWhileCharging { get; } = "Run";


		private static string Short_MeleeSleepingEnemiesMultiplier { get; } = "Slp";


		private static string Short_EnvironmentMultiplier { get; } = "Env";


		private static string Short_Damage { get; } = "Dmg";


		private static string Short_Clip { get; } = "Clp";


		private static string Short_MaxAmmo { get; } = "Max";


		private static string Short_Falloff { get; } = "Dist";


		private static string Short_Reload { get; } = "Rld";


		private static string Short_Stagger { get; } = "Stgr";


		private static string Short_Precision { get; } = "Prcn";


		private static string Short_PierceCount { get; } = "Pierc";


		private static string Short_RateOfFire { get; } = "RoF";


		private static string Short_AimSpread { get; } = "ADS";


		private static string Short_HipSpread { get; } = "HIP";


		public void UpdateSleepersDatas(string[] activatedSleepers)
		{
			if (activatedSleepers[0].Length == 0)
			{
				WeaponStatShowerPlugin.LogWarning("Empty String in the config file, applying Default values");
				activatedSleepers = new string[3] { "STRIKER", "SHOOTER", "SCOUT" };
			}
			sleepersDatas = new SleepersDatas(activatedSleepers);
		}

		public string DescriptionFormatter(string GearDescription)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0057: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			if ((int)itemDataBlock.inventorySlot == 10)
			{
				MeleeArchetypeDataBlock block = GameDataBlockBase<MeleeArchetypeDataBlock>.GetBlock(GearBuilder.GetMeleeArchetypeID(gearCatBlock));
				GearDescription = VerboseDescriptionFormatter(block);
				return GearDescription + "\n\n" + GetFormatedWeaponStats(block, itemDataBlock);
			}
			eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1);
			bool flag = categoryID == 12;
			ArchetypeDataBlock val2 = (flag ? SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val) : GameDataBlockBase<ArchetypeDataBlock>.GetBlock(GearBuilder.GetArchetypeID(gearCatBlock, val)));
			if (val2 == null)
			{
				return GearDescription;
			}
			GearDescription = VerboseDescriptionFormatter(val2, flag);
			return GearDescription + GetFormatedWeaponStats(val2, flag);
		}

		internal string FireRateFormatter(string gearPublicName)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((int)itemDataBlock.inventorySlot == 10)
			{
				MeleeArchetypeDataBlock block = GameDataBlockBase<MeleeArchetypeDataBlock>.GetBlock(GearBuilder.GetMeleeArchetypeID(gearCatBlock));
				return VerbosePublicNameMelee(block);
			}
			eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1);
			ArchetypeDataBlock val2 = ((categoryID == 12) ? SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val) : GameDataBlockBase<ArchetypeDataBlock>.GetBlock(GearBuilder.GetArchetypeID(gearCatBlock, val)));
			if (val2 == null)
			{
				return gearPublicName;
			}
			return VerbosePublicNameFireMode(val2);
		}

		private string VerbosePublicNameMelee(MeleeArchetypeDataBlock meleeArchetypeDataBlock)
		{
			return ((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)meleeArchetypeDataBlock).persistentID switch
			{
				1u => "Hammer - Balanced", 
				2u => "Knife - Fast", 
				4u => "Bat - Fast", 
				3u => "Spear - Slow", 
				_ => "", 
			};
		}

		private string VerbosePublicNameFireMode(ArchetypeDataBlock archetypeDataBlock)
		{
			//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)
			//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_004e: Expected I4, but got Unknown
			StringBuilder stringBuilder = new StringBuilder();
			eWeaponFireMode fireMode = archetypeDataBlock.FireMode;
			eWeaponFireMode val = fireMode;
			switch ((int)val)
			{
			case 2:
			case 11:
				stringBuilder.Append("Full-A (");
				stringBuilder.Append("<#12FF50>");
				stringBuilder.Append(Short_RateOfFire + " ");
				stringBuilder.Append(GetRateOfFire(archetypeDataBlock));
				stringBuilder.Append("</color>");
				stringBuilder.Append(")");
				break;
			case 0:
			case 10:
				stringBuilder.Append("Semi-A (");
				stringBuilder.Append("<#12FF50>");
				stringBuilder.Append(Short_RateOfFire + " ");
				stringBuilder.Append(GetRateOfFire(archetypeDataBlock));
				stringBuilder.Append("</color>");
				stringBuilder.Append(")");
				break;
			case 1:
			case 12:
				if (archetypeDataBlock.BurstShotCount != 1)
				{
					stringBuilder.Append("Burst (");
					stringBuilder.Append("<#704dfa>");
					stringBuilder.Append("#" + archetypeDataBlock.BurstShotCount);
					stringBuilder.Append("</color>");
					stringBuilder.Append(" | ");
					stringBuilder.Append("<#12FF50>");
					stringBuilder.Append(Short_RateOfFire + " ");
					stringBuilder.Append(GetRateOfFire(archetypeDataBlock));
					stringBuilder.Append("</color>");
					stringBuilder.Append(")");
				}
				else
				{
					stringBuilder.Append("Semi-A (");
					stringBuilder.Append("<#12FF50>");
					stringBuilder.Append(Short_RateOfFire + " ");
					stringBuilder.Append(GetRateOfFire(archetypeDataBlock));
					stringBuilder.Append("</color>");
					stringBuilder.Append(")");
				}
				break;
			case 3:
				stringBuilder.Append("S-Burst (");
				stringBuilder.Append("<#12FF50>");
				stringBuilder.Append("#" + archetypeDataBlock.BurstShotCount);
				stringBuilder.Append(" every " + archetypeDataBlock.SpecialSemiBurstCountTimeout + "'");
				stringBuilder.Append("</color>");
				stringBuilder.Append(")");
				break;
			case 13:
				stringBuilder.Append("Shotgun-S (");
				stringBuilder.Append("<#12FF50>");
				stringBuilder.Append(Short_RateOfFire + " ");
				stringBuilder.Append(GetRateOfFire(archetypeDataBlock));
				stringBuilder.Append("</color>");
				stringBuilder.Append(")");
				break;
			default:
				WeaponStatShowerPlugin.LogError("FireMode not found");
				break;
			}
			return stringBuilder.ToString();
		}

		private string VerboseDescriptionFormatter(MeleeArchetypeDataBlock meleeArchetypeDataBlock)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(((double)meleeArchetypeDataBlock.CameraDamageRayLength < 1.76) ? "Short Range" : (((double)meleeArchetypeDataBlock.CameraDamageRayLength < 2.5) ? "Medium Range" : "Long Range"));
			stringBuilder.Append(meleeArchetypeDataBlock.CanHitMultipleEnemies ? "Piercing\n" : "");
			return "".Equals(stringBuilder.ToString()) ? "" : (stringBuilder.ToString() + "\n");
		}

		private string VerboseDescriptionFormatter(ArchetypeDataBlock archetypeDataBlock, bool isSentryGun)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (isSentryGun)
			{
				stringBuilder.AppendLine("Deployable");
			}
			switch (archetypeDataBlock.ShotgunBulletSpread + archetypeDataBlock.ShotgunConeSize)
			{
			case 1:
				stringBuilder.AppendLine("Chocked Spread");
				break;
			case 4:
				stringBuilder.AppendLine("Small Spread");
				break;
			case 5:
				stringBuilder.AppendLine("Medium Spread");
				break;
			case 7:
				stringBuilder.AppendLine("Large Spread");
				break;
			case 9:
				stringBuilder.AppendLine("Huge Spread");
				break;
			default:
				WeaponStatShowerPlugin.LogError(LocalizedText.op_Implicit(archetypeDataBlock.PublicName) + ": spread not considered{" + archetypeDataBlock.ShotgunBulletSpread + "/" + archetypeDataBlock.ShotgunConeSize + "}");
				break;
			case 0:
				break;
			}
			if (archetypeDataBlock.SpecialChargetupTime > 0f)
			{
				stringBuilder.AppendLine(((double)archetypeDataBlock.SpecialChargetupTime > 0.4) ? ("Long Charge-up (" + FormatFloat(archetypeDataBlock.SpecialChargetupTime, 2) + ")") : ("Short Charge-up (" + FormatFloat(archetypeDataBlock.SpecialChargetupTime, 2) + ")"));
			}
			return "".Equals(stringBuilder.ToString()) ? "" : (stringBuilder.ToString() + "\n");
		}

		private string GetFormatedWeaponStats(ArchetypeDataBlock archeTypeDataBlock, bool isSentryGun = false)
		{
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			if (archeTypeDataBlock == null)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			int num = 0;
			stringBuilder.Append("<#9D2929>");
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
			handler.AppendFormatted(Short_Damage);
			handler.AppendLiteral(" ");
			stringBuilder3.Append(ref handler);
			stringBuilder.Append(FormatFloat(archeTypeDataBlock.Damage, 2));
			stringBuilder.Append((archeTypeDataBlock.ShotgunBulletCount > 0) ? ("(x" + archeTypeDataBlock.ShotgunBulletCount + ")") : "");
			stringBuilder.Append("</color>");
			num++;
			if (!isSentryGun)
			{
				stringBuilder.Append(" | ");
				stringBuilder.Append("<color=orange>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder4 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
				handler.AppendFormatted(Short_Clip);
				handler.AppendLiteral(" ");
				stringBuilder4.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.DefaultClipSize);
				stringBuilder.Append("</color>");
				num++;
			}
			stringBuilder.Append(" | ");
			stringBuilder.Append("<#FFD306>");
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
			handler.AppendFormatted(Short_MaxAmmo);
			handler.AppendLiteral(" ");
			stringBuilder5.Append(ref handler);
			stringBuilder.Append(GetTotalAmmo(archeTypeDataBlock, itemDataBlock, isSentryGun));
			stringBuilder.Append("</color>");
			num++;
			if (!isSentryGun)
			{
				stringBuilder.Append(" | ");
				stringBuilder.Append("<#C0FF00>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder6 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
				handler.AppendFormatted(Short_Reload);
				handler.AppendLiteral(" ");
				stringBuilder6.Append(ref handler);
				stringBuilder.Append(FormatFloat(archeTypeDataBlock.DefaultReloadTime, 2));
				stringBuilder.Append("</color>");
				num++;
			}
			if (archeTypeDataBlock.PrecisionDamageMulti != 1f)
			{
				Divider(ref num, stringBuilder);
				stringBuilder.Append("<#18A4A9>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder7 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
				handler.AppendFormatted(Short_Precision);
				handler.AppendLiteral(" ");
				stringBuilder7.Append(ref handler);
				stringBuilder.Append(FormatFloat(archeTypeDataBlock.PrecisionDamageMulti, 2));
				stringBuilder.Append("</color>");
				num++;
			}
			Divider(ref num, stringBuilder);
			stringBuilder.Append("<#6764de>");
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder8 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
			handler.AppendFormatted(Short_Falloff);
			handler.AppendLiteral(" ");
			stringBuilder8.Append(ref handler);
			stringBuilder.Append((int)archeTypeDataBlock.DamageFalloff.x + "m");
			stringBuilder.Append("</color>");
			num++;
			if (archeTypeDataBlock.StaggerDamageMulti != 1f)
			{
				Divider(ref num, stringBuilder);
				stringBuilder.Append("<color=green>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder9 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
				handler.AppendFormatted(Short_Stagger);
				handler.AppendLiteral(" ");
				stringBuilder9.Append(ref handler);
				stringBuilder.Append(FormatFloat(archeTypeDataBlock.StaggerDamageMulti, 2));
				stringBuilder.Append("</color>");
				num++;
			}
			if (archeTypeDataBlock.HipFireSpread != 0f && archeTypeDataBlock.ShotgunBulletCount == 0)
			{
				Divider(ref num, stringBuilder);
				stringBuilder.Append("<#cc9347>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder10 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
				handler.AppendFormatted(Short_HipSpread);
				handler.AppendLiteral(" ");
				stringBuilder10.Append(ref handler);
				stringBuilder.Append(FormatFloat(archeTypeDataBlock.HipFireSpread, 2));
				stringBuilder.Append("</color>");
				num++;
			}
			if (archeTypeDataBlock.AimSpread != 0f && archeTypeDataBlock.ShotgunBulletCount == 0)
			{
				Divider(ref num, stringBuilder);
				stringBuilder.Append("<#e6583c>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder11 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
				handler.AppendFormatted(Short_AimSpread);
				handler.AppendLiteral(" ");
				stringBuilder11.Append(ref handler);
				stringBuilder.Append(FormatFloat(archeTypeDataBlock.AimSpread, 2));
				stringBuilder.Append("</color>");
				num++;
			}
			if (archeTypeDataBlock.PiercingBullets)
			{
				Divider(ref num, stringBuilder);
				stringBuilder.Append("<#097345>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder12 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
				handler.AppendFormatted(Short_PierceCount);
				handler.AppendLiteral(" ");
				stringBuilder12.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.PiercingDamageCountLimit);
				stringBuilder.Append("</color>");
				num++;
			}
			stringBuilder.AppendLine("\n");
			stringBuilder.Append(sleepersDatas.VerboseKill(archeTypeDataBlock));
			return stringBuilder.ToString();
			static void Divider(ref int count, StringBuilder builder)
			{
				if (count >= 4)
				{
					builder.Append("\n");
					count = 0;
				}
				else if (count > 0)
				{
					builder.Append(" | ");
				}
			}
		}

		private string GetFormatedWeaponStats(MeleeArchetypeDataBlock archeTypeDataBlock, ItemDataBlock itemDataBlock)
		{
			if (archeTypeDataBlock == null)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("<#9D2929>");
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
			handler.AppendFormatted(Short_Damage);
			handler.AppendFormatted(Short_MeleeLight);
			handler.AppendLiteral(" ");
			stringBuilder3.Append(ref handler);
			stringBuilder.Append(archeTypeDataBlock.LightAttackDamage);
			stringBuilder.Append("</color>");
			stringBuilder.Append(" | ");
			stringBuilder.Append("<color=orange>");
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
			handler.AppendFormatted(Short_Damage);
			handler.AppendFormatted(Short_MeleeCharged);
			handler.AppendLiteral(" ");
			stringBuilder4.Append(ref handler);
			stringBuilder.Append(archeTypeDataBlock.ChargedAttackDamage);
			stringBuilder.Append("</color>");
			int count2 = 2;
			if (!archeTypeDataBlock.AllowRunningWhenCharging)
			{
				stringBuilder.Append(" | ");
				stringBuilder.Append("<#FFD306>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder5 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
				handler.AppendFormatted(Short_MeleeCanRunWhileCharging);
				handler.AppendLiteral(" ");
				stringBuilder5.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.AllowRunningWhenCharging);
				stringBuilder.Append("</color>");
				count2++;
			}
			if (archeTypeDataBlock.LightStaggerMulti != 1f)
			{
				Divider(ref count2, stringBuilder);
				stringBuilder.Append("<#C0FF00>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder6 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
				handler.AppendFormatted(Short_Stagger);
				handler.AppendFormatted(Short_MeleeLight);
				handler.AppendLiteral(" ");
				stringBuilder6.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.LightStaggerMulti);
				stringBuilder.Append("</color>");
				count2++;
			}
			if (archeTypeDataBlock.ChargedStaggerMulti != 1f)
			{
				Divider(ref count2, stringBuilder);
				stringBuilder.Append("<color=green>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder7 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
				handler.AppendFormatted(Short_Stagger);
				handler.AppendFormatted(Short_MeleeCharged);
				handler.AppendLiteral(" ");
				stringBuilder7.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.ChargedStaggerMulti);
				stringBuilder.Append("</color>");
				count2++;
			}
			if (archeTypeDataBlock.LightPrecisionMulti != 1f)
			{
				Divider(ref count2, stringBuilder);
				stringBuilder.Append("<#004E2C>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder8 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
				handler.AppendFormatted(Short_Precision);
				handler.AppendFormatted(Short_MeleeLight);
				handler.AppendLiteral(" ");
				stringBuilder8.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.LightPrecisionMulti);
				stringBuilder.Append("</color>");
				count2++;
			}
			if (archeTypeDataBlock.ChargedPrecisionMulti != 1f)
			{
				Divider(ref count2, stringBuilder);
				stringBuilder.Append("<#55022B>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder9 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
				handler.AppendFormatted(Short_Precision);
				handler.AppendFormatted(Short_MeleeCharged);
				handler.AppendLiteral(" ");
				stringBuilder9.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.ChargedPrecisionMulti);
				stringBuilder.Append("</color>");
				count2++;
			}
			if (archeTypeDataBlock.LightSleeperMulti != 1f)
			{
				Divider(ref count2, stringBuilder);
				stringBuilder.Append("<#A918A7>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder10 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
				handler.AppendFormatted(Short_MeleeSleepingEnemiesMultiplier);
				handler.AppendFormatted(Short_MeleeLight);
				handler.AppendLiteral(" ");
				stringBuilder10.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.LightSleeperMulti);
				stringBuilder.Append("</color>");
				count2++;
			}
			if (archeTypeDataBlock.ChargedSleeperMulti != 1f)
			{
				Divider(ref count2, stringBuilder);
				stringBuilder.Append("<#025531>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder11 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
				handler.AppendFormatted(Short_MeleeSleepingEnemiesMultiplier);
				handler.AppendFormatted(Short_MeleeCharged);
				handler.AppendLiteral(" ");
				stringBuilder11.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.ChargedSleeperMulti);
				stringBuilder.Append("</color>");
				count2++;
			}
			if (archeTypeDataBlock.LightEnvironmentMulti != 1f)
			{
				Divider(ref count2, stringBuilder);
				stringBuilder.Append("<#18A4A9>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder12 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
				handler.AppendFormatted(Short_EnvironmentMultiplier);
				handler.AppendFormatted(Short_MeleeLight);
				handler.AppendLiteral(" ");
				stringBuilder12.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.LightEnvironmentMulti);
				stringBuilder.Append("</color>");
				count2++;
			}
			if (archeTypeDataBlock.ChargedEnvironmentMulti != 1f)
			{
				Divider(ref count2, stringBuilder);
				stringBuilder.Append("<#75A2AA>");
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder13 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
				handler.AppendFormatted(Short_EnvironmentMultiplier);
				handler.AppendFormatted(Short_MeleeCharged);
				handler.AppendLiteral(" ");
				stringBuilder13.Append(ref handler);
				stringBuilder.Append(archeTypeDataBlock.ChargedEnvironmentMulti);
				stringBuilder.Append("</color>");
				count2++;
			}
			stringBuilder.AppendLine("\n");
			stringBuilder.Append(sleepersDatas.VerboseKill(archeTypeDataBlock));
			return stringBuilder.ToString();
			static void Divider(ref int count, StringBuilder builder)
			{
				if (count >= 3)
				{
					builder.Append("\n");
					count = 0;
				}
				else if (count > 0)
				{
					builder.Append(" | ");
				}
			}
		}

		private static float FormatFloat(float value, int v)
		{
			return (float)Math.Round((decimal)value, v);
		}

		private int GetAmmoMax(ItemDataBlock itemDataBlock)
		{
			//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_000c: 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)
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			AmmoType ammoTypeFromSlot = PlayerAmmoStorage.GetAmmoTypeFromSlot(itemDataBlock.inventorySlot);
			AmmoType val = ammoTypeFromSlot;
			AmmoType val2 = val;
			return (int)val2 switch
			{
				0 => _playerDataBlock.AmmoStandardMaxCap, 
				1 => _playerDataBlock.AmmoSpecialMaxCap, 
				2 => _playerDataBlock.AmmoClassMaxCap, 
				5 => itemDataBlock.ConsumableAmmoMax, 
				_ => -1, 
			};
		}

		private int GetTotalAmmo(ArchetypeDataBlock archetypeDataBlock, ItemDataBlock itemDataBlock, bool isSentryGun = false)
		{
			int ammoMax = GetAmmoMax(itemDataBlock);
			float num = archetypeDataBlock.CostOfBullet;
			if (isSentryGun)
			{
				num *= itemDataBlock.ClassAmmoCostFactor;
				if ((float)archetypeDataBlock.ShotgunBulletCount > 0f)
				{
					num *= (float)archetypeDataBlock.ShotgunBulletCount;
				}
			}
			int num2 = (int)((float)ammoMax / num);
			if (isSentryGun)
			{
				return num2;
			}
			return num2 + archetypeDataBlock.DefaultClipSize;
		}

		private string GetRateOfFire(ArchetypeDataBlock archetypeDataBlock)
		{
			//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)
			//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_0022: Expected I4, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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
			float value = -1f;
			eWeaponFireMode fireMode = archetypeDataBlock.FireMode;
			eWeaponFireMode val = fireMode;
			switch ((int)val)
			{
			default:
				if ((int)val != 12)
				{
					if ((int)val != 13)
					{
						break;
					}
					goto case 0;
				}
				goto case 1;
			case 0:
			case 2:
				value = 1f / (archetypeDataBlock.ShotDelay + archetypeDataBlock.SpecialChargetupTime);
				break;
			case 1:
				if (archetypeDataBlock.BurstShotCount != 1)
				{
					float num = 1f / (archetypeDataBlock.BurstDelay + archetypeDataBlock.SpecialChargetupTime + archetypeDataBlock.ShotDelay * (float)(archetypeDataBlock.BurstShotCount - 1));
					value = num * (float)archetypeDataBlock.BurstShotCount;
				}
				else
				{
					value = 1f / (archetypeDataBlock.ShotDelay + archetypeDataBlock.SpecialChargetupTime);
				}
				break;
			}
			return FormatFloat(value, 1).ToString();
		}

		internal void Inizialize(GearIDRange idRange, PlayerDataBlock playerDataBlock)
		{
			this.idRange = idRange;
			_playerDataBlock = playerDataBlock;
			categoryID = idRange.GetCompID((eGearComponent)2);
			gearCatBlock = GameDataBlockBase<GearCategoryDataBlock>.GetBlock(categoryID);
			itemDataBlock = GameDataBlockBase<ItemDataBlock>.GetBlock(gearCatBlock.BaseItem);
		}
	}
}
namespace WeaponStatShower.Patches
{
	public abstract class Patch
	{
		protected internal Harmony? Harmony { get; set; }

		public virtual string Name { get; }

		public virtual bool Enabled => true;

		public virtual void Initialize()
		{
		}

		public abstract void Execute();

		public void PatchConstructor<TClass>(PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null) where TClass : class
		{
			PatchConstructor<TClass>(null, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchConstructor<TClass>(Type[]? parameters, PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null) where TClass : class
		{
			ConstructorInfo methodBase = AccessTools.Constructor(typeof(TClass), parameters, false);
			PatchMethod<TClass>(methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod<TClass>(string methodName, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			PatchMethod<TClass>(methodName, null, patchType, generics, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod<TClass>(string methodName, Type[] parameters, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			MethodInfo methodBase = AccessTools.Method(typeof(TClass), methodName, parameters, generics);
			PatchMethod<TClass>(methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod<TClass>(MethodBase methodBase, PatchType patchType, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			PatchMethod(typeof(TClass), methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod(Type classType, string methodName, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null)
		{
			PatchMethod(classType, methodName, null, patchType, generics, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod(Type classType, string methodName, Type[] parameters, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null)
		{
			MethodInfo methodBase = AccessTools.Method(classType, methodName, parameters, generics);
			PatchMethod(classType, methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod(Type classType, MethodBase methodBase, PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null)
		{
			//IL_0164: 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_0177: Expected O, but got Unknown
			//IL_0177: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			string text = classType.Name.Replace("`", "__");
			string value = methodBase.ToString();
			string text2 = (methodBase.IsConstructor ? "ctor" : methodBase.Name);
			MethodInfo methodInfo = null;
			MethodInfo methodInfo2 = null;
			if ((patchType & PatchType.Prefix) != 0)
			{
				try
				{
					methodInfo2 = AccessTools.Method(GetType(), prefixMethodName ?? (text + "__" + text2 + "__Prefix"), (Type[])null, (Type[])null);
				}
				catch (Exception value2)
				{
					LogFatal($"Failed to obtain the prefix patch method for {value}): {value2}");
				}
			}
			if ((patchType & PatchType.Postfix) != 0)
			{
				try
				{
					methodInfo = AccessTools.Method(GetType(), postfixMethodName ?? (text + "__" + text2 + "__Postfix"), (Type[])null, (Type[])null);
				}
				catch (Exception value3)
				{
					LogFatal($"Failed to obtain the postfix patch method for {value}): {value3}");
				}
			}
			try
			{
				if (methodInfo2 != null && methodInfo != null)
				{
					Harmony.Patch(methodBase, new HarmonyMethod(methodInfo2), new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else if (methodInfo2 != null)
				{
					Harmony.Patch(methodBase, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else if (methodInfo != null)
				{
					Harmony.Patch(methodBase, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			catch (Exception value4)
			{
				LogError($"Failed to patch method {value}: {value4}");
			}
		}

		public void Log(LogLevel level, object data)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0011: 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_001a: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log;
			bool flag = default(bool);
			BepInExLogInterpolatedStringHandler val = new BepInExLogInterpolatedStringHandler(3, 2, level, ref flag);
			if (flag)
			{
				val.AppendLiteral("<");
				val.AppendFormatted<string>(Name);
				val.AppendLiteral("> ");
				val.AppendFormatted<object>(data);
			}
			log.Log(level, val);
		}

		public void LogDebug(object data)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log;
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(3, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data);
			}
			log.LogDebug(val);
		}

		public void LogError(object data)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log;
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(3, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data);
			}
			log.LogError(val);
		}

		public void LogFatal(object data)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log;
			bool flag = default(bool);
			BepInExFatalLogInterpolatedStringHandler val = new BepInExFatalLogInterpolatedStringHandler(3, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data);
			}
			log.LogFatal(val);
		}

		public void LogInfo(object data)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(3, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data);
			}
			log.LogInfo(val);
		}

		public void LogMessage(object data)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log;
			bool flag = default(bool);
			BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(3, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data);
			}
			log.LogMessage(val);
		}

		public void LogWarning(object data)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(3, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data);
			}
			log.LogWarning(val);
		}
	}
	[Flags]
	public enum PatchType : byte
	{
		Prefix = 1,
		Postfix = 2,
		Both = 3
	}
	internal class ShowStat : Patch
	{
		private const string PatchName = "ShowStat";

		private const PatchType patchType = PatchType.Postfix;

		private static readonly ConfigDefinition ConfigEnabled = new ConfigDefinition("ShowStat", "Enabled");

		private static readonly ConfigDefinition ConfigSleepers = new ConfigDefinition("ShowStat", "SleepersShown");

		private static string CurrShownSleepers;

		private static string PrevShownSleepers = "PLACEHOLDER";

		private static WeaponDescriptionBuilder? _weaponDescriptionBuilder;

		public static Patch Instance { get; private set; }

		public override string Name { get; } = "ShowStat";


		public override bool Enabled => ((BasePlugin)WeaponStatShowerPlugin.Instance).Config.GetConfigEntry<bool>(ConfigEnabled).Value;

		public override void Initialize()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			Instance = this;
			((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Bind<bool>(ConfigEnabled, true, new ConfigDescription("Show the stats of a weapon.", (AcceptableValueBase)null, Array.Empty<object>()));
			((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Bind<string>(ConfigSleepers, "STRIKER, SHOOTER, SCOUT", new ConfigDescription("Select which Sleepers are shown, separeted by a comma.\nAcceptable values: ALL, NONE, STRIKER, SHOOTER, SCOUT, BIG_STRIKER, BIG_SHOOTER, CHARGER, CHARGER_SCOUT", (AcceptableValueBase)null, Array.Empty<object>()));
			_weaponDescriptionBuilder = new WeaponDescriptionBuilder();
		}

		public override void Execute()
		{
			PatchMethod<CM_InventorySlotItem>("LoadData", PatchType.Postfix);
		}

		public static void CM_InventorySlotItem__LoadData__Postfix(CM_InventorySlotItem __instance, GearIDRange idRange, bool clickable, bool detailedInfo)
		{
			if ((Object)(object)__instance == (Object)null || !detailedInfo)
			{
				return;
			}
			if (_weaponDescriptionBuilder == null)
			{
				WeaponStatShowerPlugin.LogError("Something went wrong with the DescriptionBuilder");
				return;
			}
			((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Reload();
			CurrShownSleepers = ((BasePlugin)WeaponStatShowerPlugin.Instance).Config.GetConfigEntry<string>(ConfigSleepers).Value.Trim().ToUpper();
			if (!PrevShownSleepers.Equals(CurrShownSleepers))
			{
				_weaponDescriptionBuilder.UpdateSleepersDatas(CurrShownSleepers.Split(','));
				PrevShownSleepers = CurrShownSleepers;
			}
			_weaponDescriptionBuilder.Inizialize(idRange, GameDataBlockBase<PlayerDataBlock>.GetBlock(1u));
			__instance.GearDescription = _weaponDescriptionBuilder.DescriptionFormatter(__instance.GearDescription);
			__instance.GearPublicName = _weaponDescriptionBuilder.FireRateFormatter(__instance.GearPublicName);
		}
	}
}

plugins/x64/Release/netstandard2.1/Oxygen.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using AK;
using Agents;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using GameEvent;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using MTFO.Managers;
using Microsoft.CodeAnalysis;
using Oxygen.Components;
using Oxygen.Config;
using Oxygen.Utils;
using Oxygen.Utils.PartialData;
using Player;
using SNetwork;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Oxygen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Oxygen")]
[assembly: AssemblyTitle("Oxygen")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Oxygen
{
	[BepInPlugin("Inas.Oxygen", "Oxygen", "1.3.2")]
	[BepInProcess("GTFO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__OnBuildDone;

			public static Action <1>__OnLevelCleanup;

			public static Action <2>__Setup;

			public static Action <3>__OnLevelCleanup;

			public static Action <4>__OnBuildStart;

			public static Action <5>__OnLevelCleanup;

			public static LiveEditEventHandler <6>__Listener_FileChanged1;
		}

		public const string MODNAME = "Oxygen";

		public const string AUTHOR = "Inas";

		public const string GUID = "Inas.Oxygen";

		public const string VERSION = "1.3.2";

		public static readonly string OXYGEN_CONFIG_PATH = Path.Combine(ConfigManager.CustomPath, "Oxygen");

		public static Dictionary<uint, OxygenBlock> lookup = new Dictionary<uint, OxygenBlock>();

		private static LiveEditListener listener = null;

		public override void Load()
		{
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Expected O, but got Unknown
			if (!Directory.Exists(OXYGEN_CONFIG_PATH))
			{
				Directory.CreateDirectory(OXYGEN_CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(OXYGEN_CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(ConfigManager.Serialize(new OxygenConfig()));
				streamWriter.Flush();
				streamWriter.Close();
			}
			ClassInjector.RegisterTypeInIl2Cpp<AirManager>();
			LevelAPI.OnBuildDone += AirManager.OnBuildDone;
			LevelAPI.OnLevelCleanup += AirManager.OnLevelCleanup;
			ClassInjector.RegisterTypeInIl2Cpp<AirBar>();
			LevelAPI.OnBuildStart += AirBar.Setup;
			LevelAPI.OnLevelCleanup += AirBar.OnLevelCleanup;
			ClassInjector.RegisterTypeInIl2Cpp<AirPlane>();
			LevelAPI.OnBuildStart += AirPlane.OnBuildStart;
			LevelAPI.OnLevelCleanup += AirPlane.OnLevelCleanup;
			new Harmony("Inas.Oxygen").PatchAll();
			foreach (string item in Directory.EnumerateFiles(OXYGEN_CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				ConfigManager.Load<OxygenConfig>(item, out var config);
				foreach (OxygenBlock block in config.Blocks)
				{
					foreach (uint fogSetting in block.FogSettings)
					{
						if (!lookup.ContainsKey(fogSetting))
						{
							lookup.Add(fogSetting, block);
						}
					}
				}
			}
			listener = LiveEdit.CreateListener(OXYGEN_CONFIG_PATH, "*.json", true);
			LiveEditListener obj = listener;
			object obj2 = <>O.<6>__Listener_FileChanged1;
			if (obj2 == null)
			{
				LiveEditEventHandler val = Listener_FileChanged1;
				<>O.<6>__Listener_FileChanged1 = val;
				obj2 = (object)val;
			}
			obj.FileChanged += (LiveEditEventHandler)obj2;
		}

		private static void Listener_FileChanged1(LiveEditEventArgs e)
		{
			Log.Warning("LiveEdit File Changed: " + e.FullPath + ".");
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				foreach (OxygenBlock block in ConfigManager.Deserialize<OxygenConfig>(content).Blocks)
				{
					foreach (uint fogSetting in block.FogSettings)
					{
						if (lookup.ContainsKey(fogSetting))
						{
							lookup.Remove(fogSetting);
						}
						lookup.Add(fogSetting, block);
						Log.Warning($"Replaced OxygenConfig for FogSetting: {fogSetting}.");
					}
				}
				if (GameStateManager.IsInExpedition)
				{
					AirManager.Current.UpdateAirConfig(AirManager.Current.FogSetting(), LiveEditForceUpdate: true);
				}
			});
		}
	}
}
namespace Oxygen.Utils
{
	internal static class Extension
	{
		public static T Instantiate<T>(this GameObject gameObject, string name) where T : Component
		{
			GameObject obj = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent, false);
			((Object)obj).name = name;
			return obj.GetComponent<T>();
		}
	}
	internal class LocalizedTextConverter : JsonConverter<LocalizedText>
	{
		public override bool HandleNull => false;

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

		public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
		{
			JsonSerializer.Serialize<LocalizedText>(writer, value, options);
		}
	}
	internal static class Log
	{
		private static ManualLogSource source;

		static Log()
		{
			source = Logger.CreateLogSource("Oxygen");
		}

		public static void Debug(object msg)
		{
			source.LogDebug(msg);
		}

		public static void Error(object msg)
		{
			source.LogError(msg);
		}

		public static void Fatal(object msg)
		{
			source.LogFatal(msg);
		}

		public static void Info(object msg)
		{
			source.LogInfo(msg);
		}

		public static void Message(object msg)
		{
			source.LogMessage(msg);
		}

		public static void Warning(object msg)
		{
			source.LogWarning(msg);
		}
	}
}
namespace Oxygen.Utils.PartialData
{
	public static class MTFOPartialDataUtil
	{
		public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";

		public static JsonConverter PersistentIDConverter { get; private set; }

		public static JsonConverter LocalizedTextConverter { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool Initialized { get; private set; }

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

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

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

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

		static MTFOUtil()
		{
			GameDataPath = string.Empty;
			CustomPath = string.Empty;
			HasCustomContent = false;
			IsLoaded = false;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
			{
				return;
			}
			try
			{
				Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
				FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				Log.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}");
			}
		}
	}
}
namespace Oxygen.Patches
{
	[HarmonyPatch]
	internal class Patches_Dam_PlayerDamageLocal
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveNoAirDamage")]
		public static bool Pre_ReceiveNoAirDamage(Dam_PlayerDamageLocal __instance, pMiniDamageData data)
		{
			//IL_00a1: 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 && !((Dam_SyncedDamageBase)__instance).RegisterDamage(num))
			{
				((Dam_SyncedDamageBase)__instance).SendSetHealth(((Dam_SyncedDamageBase)__instance).Health);
			}
			__instance.Hitreact(((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax), Vector3.zero, true, false, false);
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveBulletDamage")]
		public static void Post_ReceiveBulletDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveMeleeDamage")]
		public static void Post_ReceiveMeleeDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveFireDamage")]
		public static void Post_ReceiveFireDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveShooterProjectileDamage")]
		public static void Post_ReceiveShooterProjectileDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveTentacleAttackDamage")]
		public static void Post_ReceiveTentacleAttackDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceivePushDamage")]
		public static void Post_ReceivePushDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveSetDead")]
		public static void Post_ReceiveSetDead()
		{
			AirManager.Current.ResetHealthToRegen();
		}
	}
	[HarmonyPatch(typeof(EnvironmentStateManager), "UpdateFog")]
	internal class EnvironmentStateManager_UpdateFog
	{
		public static void Prefix(EnvironmentStateManager __instance)
		{
			//IL_0024: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)AirManager.Current == (Object)null)
			{
				return;
			}
			FogState val = ((Il2CppArrayBase<FogState>)(object)__instance.m_stateReplicator.State.FogStates)[__instance.m_latestKnownLocalDimensionCreationIndex];
			if (val.FogDataID != 0)
			{
				AirManager.Current.UpdateAirConfig(val.FogDataID);
				if (!AirManager.Current.HasAirConfig())
				{
					AirManager.Current.StopInfectionLoop();
				}
			}
		}
	}
	[HarmonyPatch(typeof(FogRepeller_Sphere), "StartRepelling")]
	internal class FogRepeller_Sphere_StartRepelling
	{
		public static void Postfix(ref FogRepeller_Sphere __instance)
		{
			if (__instance.m_infectionShield != null)
			{
				EffectVolumeManager.UnregisterVolume((EffectVolume)(object)__instance.m_infectionShield);
				((EffectVolume)__instance.m_infectionShield).contents = (eEffectVolumeContents)0;
				EffectVolumeManager.RegisterVolume((EffectVolume)(object)__instance.m_infectionShield);
			}
		}
	}
	[HarmonyPatch(typeof(LocalPlayerAgentSettings), "UpdateBlendTowardsTargetFogSetting")]
	internal class LocalPlayerAgentSettings_UpdateBlendTowardsTargetFogSetting
	{
		public static void Postfix(LocalPlayerAgentSettings __instance, float amount)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (!AirManager.Current.HasAirConfig())
			{
				AirPlane.Current.Unregister();
			}
			else
			{
				if (__instance.m_targetFogSettings == null || !SNet.LocalPlayer.HasPlayerAgent)
				{
					return;
				}
				PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
				if ((Object)(object)localPlayerAgent.FPSCamera == (Object)null)
				{
					return;
				}
				AirPlane current = AirPlane.Current;
				if (!((Object)(object)current == (Object)null) && RundownManager.ExpeditionIsStarted)
				{
					float num = 0f;
					Dimension val = default(Dimension);
					if (Dimension.GetDimension(((Agent)localPlayerAgent).DimensionIndex, ref val))
					{
						num = val.GroundY;
					}
					PreLitVolume prelitVolume = localPlayerAgent.FPSCamera.PrelitVolume;
					((EffectVolume)current.airPlane).invert = (double)prelitVolume.m_densityHeightMaxBoost > (double)prelitVolume.m_fogDensity;
					((EffectVolume)current.airPlane).contents = (eEffectVolumeContents)1;
					((EffectVolume)current.airPlane).modification = (eEffectVolumeModification)0;
					((EffectVolume)current.airPlane).modificationScale = AirManager.Current.AirLoss();
					current.airPlane.lowestAltitude = prelitVolume.m_densityHeightAltitude + num;
					current.airPlane.highestAltitude = prelitVolume.m_densityHeightAltitude + prelitVolume.m_densityHeightRange + num;
					AirPlane.Current.Register();
				}
			}
		}
	}
	[HarmonyPatch]
	internal class Patch_PlayerAgent
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerAgent), "ReceiveModification")]
		public static void ReceiveModification(PlayerAgent __instance, ref EV_ModificationData data)
		{
			if (AirManager.Current.HasAirConfig())
			{
				if ((double)data.health != 0.0)
				{
					AirManager.Current.RemoveAir(data.health);
				}
				else
				{
					AirManager.Current.AddAir();
				}
				data.health = 0f;
			}
		}

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch(typeof(PlayerAgent), "Setup")]
		internal static void Post_Setup(PlayerAgent __instance)
		{
			if (((Agent)__instance).IsLocallyOwned)
			{
				AirManager.Setup(__instance);
			}
		}
	}
}
namespace Oxygen.Config
{
	public class ConfigManager
	{
		private static readonly JsonSerializerOptions s_SerializerOptions;

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

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

		static ConfigManager()
		{
			s_SerializerOptions = new JsonSerializerOptions
			{
				AllowTrailingCommas = true,
				ReadCommentHandling = JsonCommentHandling.Skip,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true
			};
			s_SerializerOptions.Converters.Add(new JsonStringEnumConverter());
			if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
			{
				s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
				s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter);
				Log.Message("PartialData Support Found!");
			}
			else
			{
				s_SerializerOptions.Converters.Add(new LocalizedTextConverter());
			}
		}

		public static void Load<T>(string file, out T config) where T : new()
		{
			if (file.Length < ".json".Length)
			{
				config = default(T);
				return;
			}
			if (file.Substring(file.Length - ".json".Length) != ".json")
			{
				file += ".json";
			}
			file = File.ReadAllText(Path.Combine(ConfigManager.CustomPath, "Oxygen", file));
			config = Deserialize<T>(file);
		}
	}
	public class AirText
	{
		public float x { get; set; }

		public float y { get; set; }

		public LocalizedText Text { get; set; }
	}
	public class OxygenConfig
	{
		public List<OxygenBlock> Blocks { get; set; } = new List<OxygenBlock>
		{
			new OxygenBlock()
		};

	}
	public class OxygenBlock
	{
		public float AirLoss { get; set; }

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


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


		public float DamageAmount { get; set; }

		public bool ShatterGlass { get; set; }

		public float ShatterAmount { get; set; }

		public float DamageThreshold { get; set; } = 0.1f;


		public bool AlwaysDisplayAirBar { get; set; }

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


		public float TimeToStartHealthRegen { get; set; } = 3f;


		public float TimeToCompleteHealthRegen { get; set; } = 5f;


		public AirText AirText { get; set; }

		public List<uint> FogSettings { get; set; } = new List<uint> { 0u };

	}
}
namespace Oxygen.Components
{
	public class AirBar : MonoBehaviour
	{
		public static AirBar Current;

		private TextMeshPro m_airText;

		private TextMeshPro m_airTextLocalization;

		private float m_airTextX;

		private float m_airTextY;

		private float m_airTextZ;

		private RectTransform m_air1;

		private RectTransform m_air2;

		private SpriteRenderer m_airBar1;

		private SpriteRenderer m_airBar2;

		private float m_airWidth = 100f;

		private float m_barHeightMin = 3f;

		private float m_barHeightMax = 9f;

		private Color m_airLow = new Color(0f, 0.5f, 0.5f);

		private Color m_airHigh = new Color(0f, 0.3f, 0.8f);

		public AirBar(IntPtr value)
			: base(value)
		{
		}//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_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)


		public static void Setup()
		{
			if ((Object)(object)Current == (Object)null)
			{
				Current = ((Component)GuiManager.Current.m_playerLayer.m_playerStatus).gameObject.AddComponent<AirBar>();
				Current.Init();
			}
		}

		private void Init()
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_airText == (Object)null)
			{
				m_airText = ((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_healthText).gameObject.Instantiate<TextMeshPro>("AirText");
				TextMeshPro airText = m_airText;
				((TMP_Text)airText).fontSize = ((TMP_Text)airText).fontSize / 1.25f;
				m_airText.transform.Translate(0f, -30f, 0f);
			}
			if ((Object)(object)m_airTextLocalization == (Object)null)
			{
				m_airTextLocalization = ((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_pulseText).gameObject.Instantiate<TextMeshPro>("AirText Localization");
				((Behaviour)m_airTextLocalization).enabled = true;
				m_airTextLocalization.transform.Translate(300f - m_airWidth, -45f, 0f);
				m_airTextX = m_airTextLocalization.transform.position.x;
				m_airTextY = m_airTextLocalization.transform.position.y;
				m_airTextZ = m_airTextLocalization.transform.position.z;
			}
			if ((Object)(object)m_air1 == (Object)null)
			{
				m_air1 = ((Component)((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_health1).gameObject.transform.parent).gameObject.Instantiate<RectTransform>("AirFill Right");
				((Component)m_air1).transform.Translate(0f, -30f, 0f);
				SpriteRenderer component = ((Component)((Transform)m_air1).GetChild(0)).GetComponent<SpriteRenderer>();
				component.size = new Vector2(m_airWidth, component.size.y);
				m_airBar1 = ((Component)((Transform)m_air1).GetChild(1)).GetComponent<SpriteRenderer>();
				((Renderer)((Component)((Transform)m_air1).GetChild(2)).GetComponent<SpriteRenderer>()).enabled = false;
			}
			if ((Object)(object)m_air2 == (Object)null)
			{
				m_air2 = ((Component)((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_health2).gameObject.transform.parent).gameObject.Instantiate<RectTransform>("AirFill Left");
				((Component)m_air2).transform.Translate(0f, 30f, 0f);
				SpriteRenderer component2 = ((Component)((Transform)m_air2).GetChild(0)).GetComponent<SpriteRenderer>();
				component2.size = new Vector2(m_airWidth, component2.size.y);
				m_airBar2 = ((Component)((Transform)m_air2).GetChild(1)).GetComponent<SpriteRenderer>();
				((Renderer)((Component)((Transform)m_air2).GetChild(2)).GetComponent<SpriteRenderer>()).enabled = false;
			}
			UpdateAirBar(1f);
			SetVisible(vis: false);
		}

		public void UpdateAirBar(float air)
		{
			SetAirPercentageText(air);
			SetAirBar(m_airBar1, air);
			SetAirBar(m_airBar2, air);
		}

		private void SetAirBar(SpriteRenderer bar, float val)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			bar.size = new Vector2(val * m_airWidth, Mathf.Lerp(m_barHeightMin, m_barHeightMax, val));
			bar.color = Color.Lerp(m_airLow, m_airHigh, val);
		}

		private void SetAirPercentageText(float val)
		{
			//IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			Color color = Color.Lerp(m_airLow, m_airHigh, val);
			((TMP_Text)m_airText).text = "O<size=75%>2</size>";
			((Graphic)m_airText).color = color;
			((TMP_Text)m_airText).ForceMeshUpdate(true, false);
			((Graphic)m_airTextLocalization).color = color;
			((TMP_Text)m_airTextLocalization).ForceMeshUpdate(true, false);
		}

		public void UpdateAirText(OxygenBlock config)
		{
			//IL_007d: 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)
			if (config != null)
			{
				string text = LocalizedText.op_Implicit(config.AirText.Text);
				float x = config.AirText.x;
				float y = config.AirText.y;
				((TMP_Text)m_airTextLocalization).text = text;
				((TMP_Text)m_airTextLocalization).ForceMeshUpdate(true, false);
				CoroutineManager.BlinkIn(((Component)m_airTextLocalization).gameObject, 0f);
				m_airTextLocalization.transform.SetPositionAndRotation(new Vector3(m_airTextX + x, m_airTextY + y, m_airTextZ), m_airTextLocalization.transform.rotation);
			}
		}

		public void SetVisible(bool vis)
		{
			((Component)m_airText).gameObject.SetActive(vis);
			((Component)m_airTextLocalization).gameObject.SetActive(vis);
			((Component)m_air1).gameObject.SetActive(vis);
			((Component)m_air2).gameObject.SetActive(vis);
		}

		public static void OnLevelCleanup()
		{
			if (!((Object)(object)Current == (Object)null))
			{
				Current.SetVisible(vis: false);
			}
		}
	}
	public class AirManager : MonoBehaviour
	{
		public static AirManager Current;

		public PlayerAgent m_playerAgent;

		private HUDGlassShatter m_hudGlass;

		private Dam_PlayerDamageBase Damage;

		public OxygenBlock config;

		private uint fogSetting;

		private FogSettingsDataBlock fogSettingDB;

		private float airAmount = 1f;

		private float damageTick;

		private float glassShatterAmount;

		private bool m_isInInfectionLoop;

		private bool isRegeningHealth;

		private float healthToRegen;

		private float healthRegenTick;

		private float tickUntilHealthRegenHealthStart;

		private readonly float regenHealthTickInterval = 0.25f;

		private float healthRegenAmountPerInterval;

		internal bool PlayerShouldCough;

		private readonly float CoughPerLoss = 0.1f;

		private float CoughLoss;

		public AirManager(IntPtr value)
			: base(value)
		{
		}

		public static void Setup(PlayerAgent playerAgent)
		{
			Current = ((Component)playerAgent).gameObject.AddComponent<AirManager>();
		}

		public static void OnBuildDone()
		{
			if (!((Object)(object)Current == (Object)null))
			{
				Current.m_playerAgent = PlayerManager.GetLocalPlayerAgent();
				Current.m_hudGlass = ((Component)Current.m_playerAgent.FPSCamera).GetComponent<HUDGlassShatter>();
				Current.Damage = ((Component)Current.m_playerAgent).gameObject.GetComponent<Dam_PlayerDamageBase>();
				Current.UpdateAirConfig(RundownManager.ActiveExpedition.Expedition.FogSettings);
				AirBar.Current.UpdateAirText(Current.config);
			}
		}

		public static void OnLevelCleanup()
		{
			if (!((Object)(object)Current == (Object)null))
			{
				if (Current.m_isInInfectionLoop)
				{
					Current.StopInfectionLoop();
				}
				Current.config = null;
				Current.fogSetting = 0u;
				Current.fogSettingDB = null;
				Current.airAmount = 0f;
				Current.damageTick = 0f;
				Current.glassShatterAmount = 0f;
				Current.healthToRegen = 0f;
				Current.m_playerAgent = null;
				Current.m_hudGlass = null;
				Current.Damage = null;
			}
		}

		private void Update()
		{
			if (!RundownManager.ExpeditionIsStarted)
			{
				return;
			}
			if (!HasAirConfig())
			{
				AirBar.Current.SetVisible(vis: false);
				return;
			}
			if (airAmount == 1f)
			{
				if (config.AlwaysDisplayAirBar)
				{
					AirBar.Current.SetVisible(vis: true);
				}
				else
				{
					AirBar.Current.SetVisible(vis: false);
				}
			}
			else
			{
				AirBar.Current.SetVisible(vis: true);
			}
			if (airAmount <= config.DamageThreshold)
			{
				damageTick += Time.deltaTime;
				if (damageTick > config.DamageTime && ((Agent)m_playerAgent).Alive)
				{
					AirDamage();
				}
				isRegeningHealth = false;
			}
			else if (healthToRegen > 0f)
			{
				tickUntilHealthRegenHealthStart += Time.deltaTime;
				if (tickUntilHealthRegenHealthStart > config.TimeToStartHealthRegen)
				{
					if (healthRegenAmountPerInterval == 0f)
					{
						healthRegenAmountPerInterval = healthToRegen * (regenHealthTickInterval / config.TimeToCompleteHealthRegen);
					}
					RegenHealth();
					if (!isRegeningHealth)
					{
						Damage.m_nextRegen = Clock.Time + config.TimeToStartHealthRegen + config.TimeToCompleteHealthRegen;
						isRegeningHealth = true;
					}
				}
			}
			else
			{
				isRegeningHealth = false;
			}
		}

		public void AddAir()
		{
			if (HasAirConfig())
			{
				float airGain = config.AirGain;
				airAmount = Mathf.Clamp01(airAmount + airGain);
				AirBar.Current.UpdateAirBar(airAmount);
				if (fogSettingDB.Infection <= 0f && m_isInInfectionLoop)
				{
					StopInfectionLoop();
				}
			}
		}

		public void RemoveAir(float amount)
		{
			if (HasAirConfig())
			{
				amount = config.AirLoss;
				airAmount = Mathf.Clamp01(airAmount - amount);
				AirBar.Current.UpdateAirBar(airAmount);
				if (fogSettingDB.Infection <= 0f && amount > 0f)
				{
					StartInfectionLoop();
				}
			}
		}

		public void AirDamage()
		{
			float health = ((Dam_SyncedDamageBase)Damage).Health;
			float damageAmount = config.DamageAmount;
			Damage.m_nextRegen = Clock.Time + config.TimeToStartHealthRegen;
			if (!(health <= 1f))
			{
				((Dam_SyncedDamageBase)Damage).NoAirDamage(damageAmount);
				if (config.ShatterGlass)
				{
					glassShatterAmount += config.ShatterAmount;
					m_hudGlass.SetGlassShatterProgression(glassShatterAmount);
				}
				damageTick = 0f;
				tickUntilHealthRegenHealthStart = 0f;
				healthRegenAmountPerInterval = 0f;
				healthToRegen += damageAmount * config.HealthRegenProportion;
				CoughLoss += damageAmount;
				if (CoughLoss > CoughPerLoss)
				{
					PlayerShouldCough = true;
					CoughLoss = 0f;
				}
			}
		}

		public void RegenHealth()
		{
			if (healthToRegen <= 0f)
			{
				return;
			}
			tickUntilHealthRegenHealthStart = config.TimeToStartHealthRegen;
			healthRegenTick += Time.deltaTime;
			if (healthRegenTick > regenHealthTickInterval)
			{
				float num = healthRegenAmountPerInterval;
				if (num >= healthToRegen)
				{
					num = healthToRegen;
					healthToRegen = 0f;
					tickUntilHealthRegenHealthStart = 0f;
					healthRegenAmountPerInterval = 0f;
					isRegeningHealth = false;
				}
				else
				{
					healthToRegen -= num;
				}
				((Dam_SyncedDamageBase)Damage).AddHealth(num, (Agent)(object)m_playerAgent);
				healthRegenTick = 0f;
			}
		}

		public void UpdateAirConfig(uint fogsetting, bool LiveEditForceUpdate = false)
		{
			if (fogsetting != 0 && (fogsetting != fogSetting || LiveEditForceUpdate))
			{
				if (Plugin.lookup.ContainsKey(fogsetting))
				{
					config = Plugin.lookup[fogsetting];
				}
				else if (Plugin.lookup.ContainsKey(0u))
				{
					config = Plugin.lookup[0u];
				}
				else
				{
					config = null;
					airAmount = 1f;
				}
				fogSetting = fogsetting;
				fogSettingDB = GameDataBlockBase<FogSettingsDataBlock>.GetBlock(fogsetting);
				if (GameStateManager.IsInExpedition)
				{
					AirBar.Current.UpdateAirText(config);
				}
			}
		}

		public void ResetHealthToRegen()
		{
			healthRegenTick = 0f;
			healthToRegen = 0f;
			tickUntilHealthRegenHealthStart = 0f;
		}

		public float AirLoss()
		{
			if (config != null)
			{
				return config.AirLoss;
			}
			return 0f;
		}

		public bool AlwaysDisplayAirBar()
		{
			if (config != null)
			{
				return config.AlwaysDisplayAirBar;
			}
			return false;
		}

		public uint FogSetting()
		{
			return fogSetting;
		}

		public float HealthToRegen()
		{
			return healthToRegen;
		}

		public string AirText()
		{
			return LocalizedText.op_Implicit((config == null) ? null : config.AirText.Text);
		}

		public float AirTextX()
		{
			if (config != null)
			{
				return config.AirText.x;
			}
			return 0f;
		}

		public float AirTextY()
		{
			if (config != null)
			{
				return config.AirText.y;
			}
			return 0f;
		}

		public bool HasAirConfig()
		{
			return config != null;
		}

		public void StartInfectionLoop()
		{
			if (!m_isInInfectionLoop)
			{
				m_playerAgent.Sound.Post(EVENTS.INFECTION_EFFECT_LOOP_START, true);
				m_isInInfectionLoop = true;
			}
		}

		public void StopInfectionLoop()
		{
			if (m_isInInfectionLoop)
			{
				if ((Object)(object)m_playerAgent != (Object)null && m_playerAgent.Sound != null)
				{
					m_playerAgent.Sound.Post(EVENTS.INFECTION_EFFECT_LOOP_STOP, true);
				}
				m_isInInfectionLoop = false;
			}
		}
	}
	public class AirPlane : MonoBehaviour
	{
		public static AirPlane Current;

		public EV_Plane airPlane;

		private bool isAirPlaneRegistered;

		public AirPlane(IntPtr value)
			: base(value)
		{
		}

		public static void OnBuildStart()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if ((Object)(object)Current == (Object)null)
			{
				Current = ((Component)LocalPlayerAgentSettings.Current).gameObject.AddComponent<AirPlane>();
			}
			Current.airPlane = new EV_Plane();
			uint num = RundownManager.ActiveExpedition.Expedition.FogSettings;
			if (num == 0)
			{
				num = 21u;
			}
			OxygenBlock oxygenBlock = (Plugin.lookup.ContainsKey(num) ? Plugin.lookup[num] : ((!Plugin.lookup.ContainsKey(0u)) ? null : Plugin.lookup[0u]));
			FogSettingsDataBlock block = GameDataBlockBase<FogSettingsDataBlock>.GetBlock(num);
			((EffectVolume)Current.airPlane).invert = block.DensityHeightMaxBoost > block.FogDensity;
			((EffectVolume)Current.airPlane).contents = (eEffectVolumeContents)1;
			((EffectVolume)Current.airPlane).modification = (eEffectVolumeModification)0;
			Current.airPlane.lowestAltitude = block.DensityHeightAltitude;
			Current.airPlane.highestAltitude = block.DensityHeightAltitude + block.DensityHeightRange;
			if (oxygenBlock != null)
			{
				((EffectVolume)Current.airPlane).modificationScale = oxygenBlock.AirLoss;
				Current.Register();
			}
		}

		public static void OnLevelCleanup()
		{
			if (!((Object)(object)Current == (Object)null))
			{
				Current.Unregister();
				Current.isAirPlaneRegistered = false;
				Current.airPlane = null;
			}
		}

		public void Register()
		{
			if (airPlane != null && !isAirPlaneRegistered)
			{
				EffectVolumeManager.RegisterVolume((EffectVolume)(object)airPlane);
				isAirPlaneRegistered = true;
			}
		}

		public void Unregister()
		{
			if (airPlane != null && isAirPlaneRegistered)
			{
				EffectVolumeManager.UnregisterVolume((EffectVolume)(object)airPlane);
				isAirPlaneRegistered = false;
			}
		}
	}
}