Decompiled source of Zoersel v9.7.8

plugins/net6/Hikaria.PlayerSpawnApart_u.dll

Decompiled a week ago
using System;
using System.Collections;
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 Agents;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using CellMenu;
using GTFO.API;
using GTFO.API.JSON;
using GameData;
using HarmonyLib;
using Hikaria.PlayerSpawnApart.API;
using Hikaria.PlayerSpawnApart.Managers;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using MTFO.Managers;
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("Hikaria.PlayerSpawnApart")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2a7852de13d87d53616ee8732a63fbbf5c77ccdc")]
[assembly: AssemblyProduct("Hikaria.PlayerSpawnApart")]
[assembly: AssemblyTitle("Hikaria.PlayerSpawnApart")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Hikaria.PlayerSpawnApart
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Hikaria.PlayerSpawnApart", "PlayerSpawnApart", "1.0.0")]
	public class EntryPoint : BasePlugin
	{
		private static Harmony m_Harmony;

		public static EntryPoint Instance { get; private set; }

		public override void Load()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			Instance = this;
			Directory.CreateDirectory(Path.Combine(ConfigManager.CustomPath, "PlayerSpawnApart"));
			PlayerSpawnApartManager.Setup();
			m_Harmony = new Harmony("Hikaria.PlayerSpawnApart");
			m_Harmony.PatchAll();
			Logs.LogMessage("OK");
		}

		public override bool Unload()
		{
			if (m_Harmony != null)
			{
				m_Harmony.UnpatchSelf();
			}
			return ((BasePlugin)this).Unload();
		}
	}
	internal static class Logs
	{
		public static void LogDebug(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogDebug(data);
		}

		public static void LogError(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogError(data);
		}

		public static void LogFatal(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogFatal(data);
		}

		public static void LogInfo(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogInfo(data);
		}

		public static void LogMessage(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogMessage(data);
		}

		public static void LogWarning(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogWarning(data);
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "Hikaria.PlayerSpawnApart";

		public const string NAME = "PlayerSpawnApart";

		public const string VERSION = "1.0.0";
	}
}
namespace Hikaria.PlayerSpawnApart.Patches
{
	[HarmonyPatch(typeof(CM_MenuBar))]
	public class Patch__CM_MenuBar
	{
		[HarmonyPatch("OnExpeditionUpdated")]
		[HarmonyPostfix]
		private static void CM_MenuBar__OnExpeditionUpdated__Postfix(pActiveExpedition expData, ExpeditionInTierData expInTierData)
		{
			PlayerSpawnApartManager.OnExpeditionUpdated(expData, expInTierData);
		}
	}
	[HarmonyPatch(typeof(GameDataInit))]
	public class Patch__GameDataInit
	{
		[HarmonyPatch("Initialize")]
		[HarmonyPostfix]
		private static void GameDataInit__Initialize__Postfix()
		{
			PlayerSpawnApartManager.OnGameDataInitialized();
		}
	}
	[HarmonyPatch(typeof(GameStateManager))]
	public class Patch__GameStateManager
	{
		[HarmonyPatch("IsEveryoneReady")]
		[HarmonyPostfix]
		private static void GameStateManager__IsEveryoneReady__Postfix(ref bool __result)
		{
			if (SNet.IsMaster && __result)
			{
				__result = PlayerSpawnApartManager.IsEveryoneReady;
			}
		}

		[HarmonyPatch("set_IsReady")]
		[HarmonyPrefix]
		private static void GameStateManager__set_IsReady__Prefix(ref bool value)
		{
			if (!PlayerSpawnApartManager.IsReady)
			{
				if (value)
				{
					GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> <color=red>You must choose a slot before get ready!</color>");
					GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> Type in '/psa help' to show helps.");
				}
				value = false;
			}
		}

		[HarmonyPatch("OnResetSession")]
		[HarmonyPostfix]
		private static void GameStateManager__OnResetSession__Postfix()
		{
			PlayerSpawnApartManager.ResetLocalSpawnApartSlot();
			Logs.LogMessage("ResetLocalSpawnApartSlot: OnResetSession");
		}

		[HarmonyPatch("OnLevelCleanup")]
		[HarmonyPostfix]
		private static void GameStateManager__OnLevelCleanup__Postfix()
		{
			PlayerSpawnApartManager.ResetLocalSpawnApartSlot();
			Logs.LogMessage("ResetLocalSpawnApartSlot: OnLevelCleanup");
		}

		[HarmonyPatch("SendGameState")]
		[HarmonyPostfix]
		private static void GameStateManager__SendGameState__Postfix()
		{
			SNetworkAPI.SendCustomData<pPlayerSpawnApartSlot>();
		}
	}
	[HarmonyPatch]
	public class Patch__PlayerChatManager
	{
		private static bool isSelecting;

		[HarmonyPatch(typeof(PlayerChatManager), "PostMessage")]
		private static void Prefix(PlayerChatManager __instance)
		{
			if (string.IsNullOrEmpty(__instance.m_currentValue))
			{
				return;
			}
			string text = __instance.m_currentValue.ToLowerInvariant();
			if (!isSelecting)
			{
				if (text == "5")
				{
					isSelecting = true;
					GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> Select position mode activated. Use 1, 2, 3, or 4 to choose position. Enter 6 to stop selecting.");
					__instance.m_currentValue = string.Empty;
				}
				else
				{
					if (!text.StartsWith("/psa"))
					{
						return;
					}
					try
					{
						string[] array = text.Split(' ');
						switch (array.Length)
						{
						case 2:
							if (array[1] == "check")
							{
								GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> Slot assignments:");
								PlayerSpawnApartManager.ShowAllAssignedSlots();
								break;
							}
							if (array[1] == "reset")
							{
								if (!PlayerSpawnApartManager.AllowAssign)
								{
									GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> <color=red>Slot assignment is only available when in the lobby.</color>");
									break;
								}
								PlayerSpawnApartManager.ResetLocalSpawnApartSlot();
								Logs.LogMessage("ResetLocalSpawnApartSlot: Manual reset");
								break;
							}
							if (array[1] == "help")
							{
								GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> Commands available:");
								GameEventLogManager.AddLog("/psa assign [slot], assign slot for spawn apart. Range (1-4).");
								GameEventLogManager.AddLog("/psa check, check current slot assignments.");
								GameEventLogManager.AddLog("/psa reset, reset your slot assignment.");
								break;
							}
							goto default;
						case 3:
							if (array[1] == "assign")
							{
								string msg;
								if (!PlayerSpawnApartManager.AllowAssign)
								{
									GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> <color=red>Slot assignment is only available when in the lobby.</color>");
								}
								else if (!PlayerSpawnApartManager.TryAssignSpawnApartSlot(Convert.ToInt32(array[2]), out msg))
								{
									GameEventLogManager.AddLog(msg);
								}
								break;
							}
							goto default;
						default:
							throw new Exception();
						}
						return;
					}
					catch (Exception data)
					{
						Logs.LogError(data);
						GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> <color=red>Wrong input! Type in '/psa help' to show helps.</color>");
						return;
					}
					finally
					{
						__instance.m_currentValue = string.Empty;
					}
				}
				return;
			}
			if (text == "6")
			{
				isSelecting = false;
				GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> Select position mode deactivated.");
				__instance.m_currentValue = string.Empty;
				return;
			}
			try
			{
				int num = int.Parse(text);
				if (num >= 1 && num <= 4)
				{
					if (PlayerSpawnApartManager.TryAssignSpawnApartSlot(num, out var msg2))
					{
						GameEventLogManager.AddLog($"<color=orange>[PlayerSpawnApart]</color> Slot {num} assigned successfully.");
					}
					else
					{
						GameEventLogManager.AddLog(msg2);
					}
				}
				else
				{
					GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> <color=red>Invalid slot. Please enter a number between 1 and 4.</color>");
				}
			}
			catch (Exception data2)
			{
				Logs.LogError(data2);
				GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> <color=red>Invalid input. Please enter a number between 1 and 4.</color>");
			}
			finally
			{
				__instance.m_currentValue = string.Empty;
			}
		}
	}
	[HarmonyPatch(typeof(SNet_SessionHub))]
	public class Patch__SNet_SessionHub
	{
		[HarmonyPatch("AddPlayerToSession")]
		[HarmonyPostfix]
		private static void SNet_SessionHub__AddPlayerToSession__Postfix(SNet_Player player)
		{
			if (player.IsLocal)
			{
				PlayerSpawnApartManager.ResetLocalSpawnApartSlot();
				SNetworkAPI.SendCustomData<pPlayerSpawnApartSlot>();
			}
			else if (!player.IsBot)
			{
				SNetworkAPI.SendCustomData<pPlayerSpawnApartSlot>(player);
			}
		}
	}
}
namespace Hikaria.PlayerSpawnApart.Managers
{
	internal static class GameEventLogManager
	{
		public static void AddLog(string log)
		{
			MainMenuGuiLayer.Current.PageLoadout.m_gameEventLog.AddLogItem(log, (eGameEventChatLogType)2);
			GuiManager.PlayerLayer.m_gameEventLog.AddLogItem(log, (eGameEventChatLogType)2);
		}
	}
	public static class PlayerSpawnApartManager
	{
		private static readonly string PlayerSpawnApartEventName = typeof(pPlayerSpawnApartSlot).FullName;

		private static List<PlayerSpawnApartData> PlayerSpawnApartDataLookup = new List<PlayerSpawnApartData>();

		private static uint LevelLayoutID;

		private static PlayerSpawnApartData ActivatedPlayerSpawnApartData;

		public static bool CanDoSpawnApart { get; set; }

		private static bool HasActivatedPlayerSpawnApartData => ActivatedPlayerSpawnApartData != null;

		public static bool AllowAssign => (int)GameStateManager.CurrentStateName == 5;

		public static bool IsReady
		{
			get
			{
				if (HasActivatedPlayerSpawnApartData && !((Object)(object)SNet.LocalPlayer == (Object)null))
				{
					return IsPlayerReady(SNet.LocalPlayer);
				}
				return true;
			}
		}

		public static bool IsEveryoneReady
		{
			get
			{
				if (!HasActivatedPlayerSpawnApartData)
				{
					return true;
				}
				if (SNet.Slots.SlottedPlayers.Count == 0)
				{
					return false;
				}
				for (int i = 0; i < SNet.Slots.SlottedPlayers.Count; i++)
				{
					SNet_Player val = SNet.Slots.SlottedPlayers[i];
					if (!val.IsBot)
					{
						int slot = val.LoadCustomData<pPlayerSpawnApartSlot>().slot;
						if (!IsValidSlotRange(slot) || slot == -1)
						{
							return false;
						}
					}
				}
				if (CheckAllSpawnApartSlotHasConflict())
				{
					return false;
				}
				return true;
			}
		}

		public static void Setup()
		{
			SNetworkAPI.SetupCustomData<pPlayerSpawnApartSlot>(PlayerSpawnApartEventName, OnPlayerSpawnApartSlotChanged);
			LevelAPI.OnEnterLevel += ApplySpawnApartData;
		}

		private static bool IsPlayerReady(SNet_Player player)
		{
			if (!HasActivatedPlayerSpawnApartData)
			{
				return true;
			}
			if ((Object)(object)player == (Object)null || player.IsBot)
			{
				return true;
			}
			int slot = player.LoadCustomData<pPlayerSpawnApartSlot>().slot;
			if (slot != -1)
			{
				return IsValidSlotRange(slot);
			}
			return false;
		}

		public static void OnGameDataInitialized()
		{
			new JsonSerializerOptions
			{
				IncludeFields = false,
				ReadCommentHandling = JsonCommentHandling.Skip,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				Converters = { (JsonConverter)new JsonStringEnumConverter() }
			};
			PlayerSpawnApartDataLookup = JsonSerializer.Deserialize<List<PlayerSpawnApartData>>(File.ReadAllText(Path.Combine(ConfigManager.CustomPath, "PlayerSpawnApart", "SpawnApartData.json")), (JsonSerializerOptions)null);
		}

		public static void ApplySpawnApartData()
		{
			if (HasActivatedPlayerSpawnApartData)
			{
				CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DoSpawnApart()), (Action)null);
			}
		}

		private static IEnumerator DoSpawnApart()
		{
			PlayerAgent playerAgent = PlayerManager.GetLocalPlayerAgent();
			int slot = playerAgent.Owner.LoadCustomData<pPlayerSpawnApartSlot>().slot;
			Vector3 pos;
			switch (slot)
			{
			case 1:
				pos = ActivatedPlayerSpawnApartData.Slot1;
				break;
			case 2:
				pos = ActivatedPlayerSpawnApartData.Slot2;
				break;
			case 3:
				pos = ActivatedPlayerSpawnApartData.Slot3;
				break;
			case 4:
				pos = ActivatedPlayerSpawnApartData.Slot4;
				break;
			default:
				GameEventLogManager.AddLog($"<color=orange>[PlayerSpawnApart]</color> <color=red>Illegal Slot[{slot}]!</color>");
				yield break;
			}
			Dimension val = default(Dimension);
			Dimension.GetDimension((eDimensionIndex)0, ref val);
			playerAgent.TryWarpTo((eDimensionIndex)0, val.GetStartCourseNode().Position, ((Agent)playerAgent).TargetLookDir, (WarpOptions)0);
			yield return (object)new WaitForFixedUpdate();
			eDimensionIndex dimensionIndex = Dimension.GetDimensionFromPos(pos).DimensionIndex;
			if ((int)dimensionIndex != 0)
			{
				playerAgent.RequestWarpToSync(dimensionIndex, pos, ((Agent)playerAgent).TargetLookDir, (WarpOptions)0);
			}
			else
			{
				playerAgent.TeleportTo(pos);
			}
		}

		private static bool AssignSlotValidate(SNet_Player player, int slot)
		{
			if (!IsValidSlotRange(slot))
			{
				return false;
			}
			if (slot == -1)
			{
				return true;
			}
			for (int i = 0; i < SNet.Slots.SlottedPlayers.Count; i++)
			{
				SNet_Player val = SNet.Slots.SlottedPlayers[i];
				if (!((Object)(object)val == (Object)(object)player) && val.LoadCustomData<pPlayerSpawnApartSlot>().slot == slot)
				{
					return false;
				}
			}
			return true;
		}

		private static bool IsValidSlotRange(int slot)
		{
			if (slot != -1)
			{
				if (slot >= 1)
				{
					return slot <= 4;
				}
				return false;
			}
			return true;
		}

		public static void ResetLocalSpawnApartSlot()
		{
			pPlayerSpawnApartSlot pPlayerSpawnApartSlot2 = new pPlayerSpawnApartSlot(SNet.LocalPlayer, -1);
			SNetworkAPI.SetLocalCustomData(pPlayerSpawnApartSlot2);
			OnPlayerSpawnApartSlotChanged(SNet.LocalPlayer, pPlayerSpawnApartSlot2);
		}

		private static bool LocalCheckSpawnApartSlotHasConflict()
		{
			int slot = SNet.LocalPlayer.LoadCustomData<pPlayerSpawnApartSlot>().slot;
			if (slot == -1)
			{
				return false;
			}
			for (int i = 0; i < SNet.Slots.SlottedPlayers.Count; i++)
			{
				SNet_Player val = SNet.Slots.SlottedPlayers[i];
				if (!val.IsBot && !val.IsLocal && val.LoadCustomData<pPlayerSpawnApartSlot>().slot == slot)
				{
					return true;
				}
			}
			return false;
		}

		private static bool CheckAllSpawnApartSlotHasConflict()
		{
			List<SNet_Player> players = ((IEnumerable<SNet_Player>)SNet.Slots.SlottedPlayers.ToArray()).ToList();
			if (players.Any((SNet_Player p) => p.LoadCustomData<pPlayerSpawnApartSlot>().slot != -1 && players.Any((SNet_Player q) => (Object)(object)p != (Object)(object)q && p.LoadCustomData<pPlayerSpawnApartSlot>().slot == q.LoadCustomData<pPlayerSpawnApartSlot>().slot)))
			{
				return true;
			}
			return false;
		}

		public static bool TryAssignSpawnApartSlot(int slot, out string msg)
		{
			msg = string.Empty;
			if (!IsValidSlotRange(slot))
			{
				msg = "<color=orange>[PlayerSpawnApart]</color> <color=red>Illegal slot range. Range (1-4).</color>";
				return false;
			}
			if (!AssignSlotValidate(SNet.LocalPlayer, slot))
			{
				msg = $"<color=orange>[PlayerSpawnApart]</color> <color=red>Slot[{slot}] is not avaliable!</color>";
				return false;
			}
			pPlayerSpawnApartSlot pPlayerSpawnApartSlot2 = new pPlayerSpawnApartSlot(SNet.LocalPlayer, slot);
			SNetworkAPI.SetLocalCustomData(pPlayerSpawnApartSlot2);
			OnPlayerSpawnApartSlotChanged(SNet.LocalPlayer, pPlayerSpawnApartSlot2);
			return true;
		}

		public static void OnExpeditionUpdated(pActiveExpedition expData, ExpeditionInTierData expInTierData)
		{
			LevelLayoutID = expInTierData.LevelLayoutData;
			for (int i = 0; i < PlayerSpawnApartDataLookup.Count; i++)
			{
				PlayerSpawnApartData playerSpawnApartData = PlayerSpawnApartDataLookup[i];
				if (playerSpawnApartData.MainLevelLayoutID == LevelLayoutID && playerSpawnApartData.InternalEnabled)
				{
					ActivatedPlayerSpawnApartData = playerSpawnApartData;
					return;
				}
			}
			ActivatedPlayerSpawnApartData = null;
		}

		private static void OnPlayerSpawnApartSlotChanged(SNet_Player player, pPlayerSpawnApartSlot data)
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Invalid comparison between Unknown and I4
			if (!HasActivatedPlayerSpawnApartData)
			{
				return;
			}
			if (player.IsLocal && LocalCheckSpawnApartSlotHasConflict())
			{
				GameEventLogManager.AddLog($"<color=orange>[PlayerSpawnApart]</color> <color=red>Slot[{data.slot}] has a conflict, please reassign!</color>");
				return;
			}
			if (data.slot == -1)
			{
				GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> " + player.NickName + "</color> reset slot.");
			}
			else
			{
				GameEventLogManager.AddLog($"<color=orange>[PlayerSpawnApart]</color> {player.NickName}</color> assign slot[{data.slot}].");
			}
			if ((int)GameStateManager.CurrentStateName == 5)
			{
				if (IsEveryoneReady)
				{
					GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> <color=green>All players are ready:</color>");
					ShowAllAssignedSlots();
				}
				else if (CheckAllSpawnApartSlotHasConflict())
				{
					GameEventLogManager.AddLog("<color=orange>[PlayerSpawnApart]</color> <color=red>Slot assignments conflict, please review!</color>");
					ShowAllAssignedSlots();
				}
			}
		}

		public static void ShowAllAssignedSlots()
		{
			for (int i = 0; i < SNet.Slots.SlottedPlayers.Count; i++)
			{
				SNet_Player val = SNet.Slots.SlottedPlayers[i];
				if (!val.IsBot)
				{
					GameEventLogManager.AddLog($"{val.NickName}</color>: Slot[{val.LoadCustomData<pPlayerSpawnApartSlot>().slot}]");
				}
			}
		}
	}
	public class PlayerSpawnApartData
	{
		public Vector3 Slot1 { get; set; }

		public Vector3 Slot2 { get; set; }

		public Vector3 Slot3 { get; set; }

		public Vector3 Slot4 { get; set; }

		public uint MainLevelLayoutID { get; set; }

		public bool InternalEnabled { get; set; }

		public string DebugName { get; set; }
	}
	public struct pPlayerSpawnApartSlot : IReplicatedPlayerData
	{
		public pPlayer PlayerData { get; set; }

		public int slot { get; set; }

		public pPlayerSpawnApartSlot()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			PlayerData = default(pPlayer);
			slot = -1;
		}

		public pPlayerSpawnApartSlot(SNet_Player player, int slot)
		{
			//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)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			PlayerData = default(pPlayer);
			this.slot = -1;
			this.slot = slot;
			pPlayer playerData = PlayerData;
			((pPlayer)(ref playerData)).SetPlayer(player);
		}
	}
}
namespace Hikaria.PlayerSpawnApart.API
{
	public interface IReplicatedPlayerData
	{
		pPlayer PlayerData { get; set; }
	}
	public static class SNetworkAPI
	{
		public abstract class DataWrapper
		{
			public abstract void Send(SNet_Player fromPlayer, SNet_Player toPlayer = null);
		}

		public class DataWrapper<A> : DataWrapper where A : struct
		{
			private A m_data;

			public A Load()
			{
				return m_data;
			}

			public void Store(SNet_Player player, A data)
			{
				m_data = data;
				SNet_ReplicatedPlayerData<A>.SendData(player, m_data);
			}

			public override void Send(SNet_Player fromPlayer, SNet_Player toPlayer = null)
			{
				SNet_ReplicatedPlayerData<A>.SendData(fromPlayer, m_data, toPlayer);
			}
		}

		private static Dictionary<ulong, Dictionary<Type, DataWrapper>> DataWrappersLookup = new Dictionary<ulong, Dictionary<Type, DataWrapper>>();

		public static void SetupCustomData<A>(string eventName, Action<SNet_Player, A> callback) where A : struct, IReplicatedPlayerData
		{
			SNet_ReplicatedPlayerData<A>.Setup(eventName, callback);
		}

		public static void SetLocalCustomData<A>(A data) where A : struct
		{
			if ((Object)(object)SNet.LocalPlayer != (Object)null)
			{
				SNet.LocalPlayer.StoreCustomData(data);
			}
		}

		public static void SendCustomData<A>(SNet_Player toPlayer = null) where A : struct
		{
			if ((Object)(object)toPlayer != (Object)null && toPlayer.IsBot)
			{
				return;
			}
			if ((Object)(object)SNet.LocalPlayer != (Object)null)
			{
				SNet_ReplicatedPlayerData<A>.SendData(SNet.LocalPlayer, GetLocalCustomData<A>(), toPlayer);
			}
			if (!SNet.IsMaster || !((Object)(object)toPlayer != (Object)null) || toPlayer.IsBot)
			{
				return;
			}
			List<SNet_Player> allBots = SNet.Core.GetAllBots(true);
			for (int i = 0; i < allBots.Count; i++)
			{
				SNet_Player val = allBots[i];
				if ((Object)(object)val != (Object)null && val.IsBot)
				{
					SNet_ReplicatedPlayerData<A>.SendData(val, val.LoadCustomData<A>(), toPlayer);
				}
			}
		}

		public static A GetLocalCustomData<A>() where A : struct
		{
			if ((Object)(object)SNet.LocalPlayer != (Object)null)
			{
				return SNet.LocalPlayer.LoadCustomData<A>();
			}
			return new A();
		}

		public static A LoadCustomData<A>(this SNet_Player player) where A : struct
		{
			Type typeFromHandle = typeof(A);
			if (!DataWrappersLookup.TryGetValue(player.Lookup, out var value))
			{
				DataWrappersLookup[player.Lookup] = new Dictionary<Type, DataWrapper>();
				value = DataWrappersLookup[player.Lookup];
			}
			DataWrapper<A> dataWrapper;
			if (!value.TryGetValue(typeFromHandle, out var value2))
			{
				dataWrapper = new DataWrapper<A>();
				value.Add(typeFromHandle, dataWrapper);
			}
			else
			{
				dataWrapper = (DataWrapper<A>)value2;
			}
			return dataWrapper.Load();
		}

		public static void StoreCustomData<A>(this SNet_Player player, A data) where A : struct
		{
			Type typeFromHandle = typeof(A);
			if (!DataWrappersLookup.TryGetValue(player.Lookup, out var value))
			{
				DataWrappersLookup[player.Lookup] = new Dictionary<Type, DataWrapper>();
				value = DataWrappersLookup[player.Lookup];
			}
			DataWrapper<A> dataWrapper;
			if (!value.TryGetValue(typeFromHandle, out var value2))
			{
				dataWrapper = new DataWrapper<A>();
				value.Add(typeFromHandle, dataWrapper);
			}
			else
			{
				dataWrapper = (DataWrapper<A>)value2;
			}
			dataWrapper.Store(player, data);
		}
	}
	public class SNet_Packet<T> where T : struct
	{
		private T m_data = new T();

		private bool m_hasValidateAction;

		public string EventName { get; set; }

		private Action<T> ValidateAction { get; set; }

		private Action<ulong, T> ReceiveAction { get; set; }

		public void Setup(string eventName)
		{
			EventName = eventName;
			NetworkAPI.RegisterEvent<T>(eventName, (Action<ulong, T>)OnReceiveData);
		}

		public static SNet_Packet<T> Create(string eventName, Action<ulong, T> receiveAction, Action<T> validateAction = null)
		{
			SNet_Packet<T> sNet_Packet = new SNet_Packet<T>
			{
				EventName = eventName,
				ReceiveAction = receiveAction,
				ValidateAction = validateAction,
				m_hasValidateAction = (validateAction != null)
			};
			NetworkAPI.RegisterEvent<T>(eventName, (Action<ulong, T>)sNet_Packet.OnReceiveData);
			return sNet_Packet;
		}

		public void Ask(T data, SNet_ChannelType channelType = 0)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (SNet.IsMaster)
			{
				ValidateAction(data);
			}
			else if (SNet.HasMaster)
			{
				Send(data, channelType, SNet.Master);
			}
		}

		public void Send(T data, SNet_ChannelType type, SNet_Player player = null)
		{
			//IL_001f: 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)
			if ((Object)(object)player == (Object)null)
			{
				NetworkAPI.InvokeEvent<T>(EventName, data, type);
			}
			else
			{
				NetworkAPI.InvokeEvent<T>(EventName, data, player, type);
			}
		}

		public void OnReceiveData(ulong sender, T data)
		{
			m_data = data;
			if (m_hasValidateAction && SNet.IsMaster)
			{
				ValidateAction(m_data);
			}
			else
			{
				ReceiveAction(sender, m_data);
			}
		}
	}
	public class SNet_ReplicatedPlayerData<A> where A : struct
	{
		public delegate bool delegateComparisonAction(A playerData, SNet_Player player, A comparisonData);

		private static SNet_ReplicatedPlayerData<A> s_singleton;

		private SNet_Packet<A> m_syncPacket;

		private Action<SNet_Player, A> m_onChangeCallback;

		public static void Setup(string eventName, Action<SNet_Player, A> callback)
		{
			if (s_singleton == null)
			{
				s_singleton = new SNet_ReplicatedPlayerData<A>();
				s_singleton.m_syncPacket = SNet_Packet<A>.Create(eventName, OnReceiveData);
			}
			s_singleton.m_onChangeCallback = callback;
		}

		private static void OnReceiveData(ulong sender, A wrappedData)
		{
			//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)
			pPlayer playerData = ((IReplicatedPlayerData)(object)wrappedData).PlayerData;
			SNet_Player val = default(SNet_Player);
			if (((pPlayer)(ref playerData)).TryGetPlayer(ref val) && !val.IsLocal)
			{
				val.StoreCustomData(wrappedData);
				s_singleton.m_onChangeCallback?.Invoke(val, wrappedData);
			}
		}

		public static void SendData(SNet_Player player, A data, SNet_Player toPlayer = null)
		{
			//IL_0023: 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 ((!((Object)(object)toPlayer != (Object)null) || !toPlayer.IsBot) && (player.IsLocal || SNet.IsMaster))
			{
				pPlayer playerData = default(pPlayer);
				((pPlayer)(ref playerData)).SetPlayer(player);
				IReplicatedPlayerData obj = (IReplicatedPlayerData)(object)data;
				obj.PlayerData = playerData;
				data = (A)obj;
				if ((Object)(object)toPlayer != (Object)null)
				{
					s_singleton.m_syncPacket.Send(data, (SNet_ChannelType)0, toPlayer);
				}
				else
				{
					s_singleton.m_syncPacket.Send(data, (SNet_ChannelType)0);
				}
			}
		}

		public static bool Compare(delegateComparisonAction comparisonAction, A comparisonValue, eComparisonGroup group, bool includeBots = false)
		{
			//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
			List<SNet_Player> val;
			if ((int)group != 0)
			{
				if ((int)group != 1)
				{
					return false;
				}
				val = SNet.Slots.PlayersSynchedWithGame;
			}
			else
			{
				val = SNet.Slots.SlottedPlayers;
			}
			int count = val.Count;
			for (int i = 0; i < count; i++)
			{
				SNet_Player val2 = val[i];
				if (includeBots || !val2.IsBot)
				{
					A playerData = val2.LoadCustomData<A>();
					if (!comparisonAction(playerData, val2, comparisonValue))
					{
						return false;
					}
				}
			}
			return true;
		}
	}
}

plugins/net6/ExtraWeaponCustomization.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
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.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using CharacterDestruction;
using CullingSystem;
using EWC.API;
using EWC.CustomWeapon;
using EWC.CustomWeapon.KillTracker;
using EWC.CustomWeapon.ObjectWrappers;
using EWC.CustomWeapon.Properties;
using EWC.CustomWeapon.Properties.Effects;
using EWC.CustomWeapon.Properties.Effects.Heal;
using EWC.CustomWeapon.Properties.Effects.Hit.DOT;
using EWC.CustomWeapon.Properties.Effects.Hit.DOT.DOTGlowFX;
using EWC.CustomWeapon.Properties.Effects.Hit.Explosion;
using EWC.CustomWeapon.Properties.Effects.Hit.Explosion.EEC_ExplosionFX;
using EWC.CustomWeapon.Properties.Effects.Hit.Explosion.EEC_ExplosionFX.Handlers;
using EWC.CustomWeapon.Properties.Effects.Triggers;
using EWC.CustomWeapon.Properties.Traits;
using EWC.CustomWeapon.Properties.Traits.CustomProjectile;
using EWC.CustomWeapon.Properties.Traits.CustomProjectile.Components;
using EWC.CustomWeapon.Properties.Traits.CustomProjectile.Managers;
using EWC.CustomWeapon.WeaponContext;
using EWC.CustomWeapon.WeaponContext.Contexts;
using EWC.CustomWeapon.WeaponContext.Contexts.Triggers;
using EWC.Dependencies;
using EWC.JSON;
using EWC.JSON.Converters;
using EWC.Networking;
using EWC.Networking.Structs;
using EWC.Patches;
using EWC.Patches.Melee;
using EWC.Patches.Native;
using EWC.Utils;
using EWC.Utils.Log;
using EndskApi.Api;
using EndskApi.Enums.EnemyKill;
using EndskApi.Information.EnemyKill;
using Enemies;
using ExtraRecoilData.API;
using ExtraRecoilData.CustomRecoil;
using FX_EffectSystem;
using FirstPersonItem;
using GTFO.API;
using GTFO.API.JSON.Converters;
using GTFO.API.Utilities;
using GTFuckingXP.Extensions;
using GTFuckingXP.Information.Level;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppSystem;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Generic;
using KillIndicatorFix;
using LevelGeneration;
using LevelGeneration.Core;
using MTFO.API;
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("ExtraWeaponCustomization")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+16b848dbb3fb9a320168c055bc44cb68cd68a9a1")]
[assembly: AssemblyProduct("ExtraWeaponCustomization")]
[assembly: AssemblyTitle("ExtraWeaponCustomization")]
[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]
	[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 EWC
{
	internal static class Configuration
	{
		private static readonly ConfigFile configFile;

		private static ConfigEntry<bool> ForceCreateTemplate { get; set; }

		public static bool ShowExplosionEffect { get; set; }

		public static bool PlayExplosionSFX { get; set; }

		public static float ExplosionSFXCooldown { get; set; }

		public static int ExplosionSFXShotOverride { get; set; }

		public static float AutoAimTickDelay { get; set; }

		public static float HomingTickDelay { get; set; }

		static Configuration()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			ShowExplosionEffect = true;
			PlayExplosionSFX = true;
			ExplosionSFXCooldown = 0.08f;
			ExplosionSFXShotOverride = 8;
			AutoAimTickDelay = 0.1f;
			HomingTickDelay = 0.1f;
			configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "ExtraWeaponCustomization.cfg"), true);
			BindAll(configFile);
		}

		internal static void Init()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			LiveEdit.CreateListener(Paths.ConfigPath, "ExtraWeaponCustomization.cfg", false).FileChanged += new LiveEditEventHandler(OnFileChanged);
		}

		private static void OnFileChanged(LiveEditEventArgs _)
		{
			configFile.Reload();
			string text = "Auto Aim Settings";
			AutoAimTickDelay = (float)configFile[text, "Search Cooldown"].BoxedValue;
			text = "Explosion Settings";
			ShowExplosionEffect = (bool)configFile[text, "Show Effect"].BoxedValue;
			PlayExplosionSFX = (bool)configFile[text, "Play Sound"].BoxedValue;
			ExplosionSFXCooldown = (float)configFile[text, "SFX Cooldown"].BoxedValue;
			ExplosionSFXShotOverride = (int)configFile[text, "Shots to Override SFX Cooldown"].BoxedValue;
			text = "Projectile Settings";
			HomingTickDelay = (float)configFile[text, "Homing Search Cooldown"].BoxedValue;
			CheckAndRefreshTemplate();
		}

		[MemberNotNull("ForceCreateTemplate")]
		private static void BindAll(ConfigFile config)
		{
			string text = "Auto Aim Settings";
			AutoAimTickDelay = config.Bind<float>(text, "Search Cooldown", AutoAimTickDelay, "Time between attempted searches to acquire targets.").Value;
			text = "Explosion Settings";
			ShowExplosionEffect = config.Bind<bool>(text, "Show Effect", ShowExplosionEffect, "Enables explosion visual FX.").Value;
			PlayExplosionSFX = config.Bind<bool>(text, "Play Sound", PlayExplosionSFX, "Enables explosion sound FX.").Value;
			ExplosionSFXCooldown = config.Bind<float>(text, "SFX Cooldown", ExplosionSFXCooldown, "Minimum time between explosion sound effects, to prevent obnoxiously loud sounds.").Value;
			ExplosionSFXShotOverride = config.Bind<int>(text, "Shots to Override SFX Cooldown", ExplosionSFXShotOverride, "Amount of shots fired before another explosion sound effect is forced, regardless of cooldown.\nSmaller numbers let fast-firing weapons and shotguns make more sounds in a short span of time.").Value;
			text = "Projectile Settings";
			HomingTickDelay = config.Bind<float>(text, "Homing Search Cooldown", HomingTickDelay, "Minimum time between attempted searches to acquire a new target.").Value;
			text = "Tools";
			ForceCreateTemplate = config.Bind<bool>(text, "Force Create Template", false, "Creates the template file again.");
		}

		private static void CheckAndRefreshTemplate()
		{
			if (ForceCreateTemplate.Value)
			{
				ForceCreateTemplate.Value = false;
				CustomWeaponManager.Current.CreateTemplate();
				configFile.Save();
			}
		}
	}
	[BepInPlugin("Dinorush.ExtraWeaponCustomization", "ExtraWeaponCustomization", "2.14.0")]
	[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.*/)]
	internal sealed class EntryPoint : BasePlugin
	{
		public const string MODNAME = "ExtraWeaponCustomization";

		public static bool Loaded { get; private set; }

		public override void Load()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			EWCLogger.Log("Loading ExtraWeaponCustomization");
			if (!MTFOAPIWrapper.HasCustomContent)
			{
				EWCLogger.Error("No MTFO datablocks detected. Not loading EWC...");
				return;
			}
			Loaded = true;
			new Harmony("ExtraWeaponCustomization").PatchAll();
			EnemyDetectionPatches.ApplyNativePatch();
			Configuration.Init();
			LevelAPI.OnLevelCleanup += LevelAPI_OnLevelCleanup;
			LevelAPI.OnEnterLevel += LevelAPI_OnLevelEnter;
			AssetAPI.OnStartupAssetsLoaded += AssetAPI_OnStartupAssetsLoaded;
			EWCLogger.Log("Loaded ExtraWeaponCustomization");
		}

		private void LevelAPI_OnLevelCleanup()
		{
			CustomWeaponManager.Current.ResetCWCs(activate: false);
			EWCProjectileManager.Reset();
			DOTDamageManager.Reset();
		}

		private void LevelAPI_OnLevelEnter()
		{
			CustomWeaponManager.Current.ActivateCWCs();
		}

		private void AssetAPI_OnStartupAssetsLoaded()
		{
			ClassInjector.RegisterTypeInIl2Cpp<DOTGlowHandler>();
			ClassInjector.RegisterTypeInIl2Cpp<ExplosionEffectHandler>();
			ClassInjector.RegisterTypeInIl2Cpp<CustomWeaponComponent>();
			ClassInjector.RegisterTypeInIl2Cpp<EWCProjectileComponentBase>();
			ClassInjector.RegisterTypeInIl2Cpp<EWCProjectileComponentShooter>();
			LayerUtil.Init();
			ExplosionManager.Init();
			DOTDamageManager.Init();
			HealManager.Init();
			TriggerManager.Init();
			KillAPIWrapper.Init();
			EWCProjectileManager.Init();
			CustomWeaponManager.Current.GetCustomGunData(0u);
		}
	}
}
namespace EWC.Utils
{
	internal static class DamageableUtil
	{
		private static IntPtr _cachedExpedition = default(IntPtr);

		private static float _cachedHealth = 15f;

		public static float LockHealth
		{
			get
			{
				if (RundownManager.ActiveExpedition != null && ((Il2CppObjectBase)RundownManager.ActiveExpedition).Pointer != _cachedExpedition)
				{
					_cachedExpedition = ((Il2CppObjectBase)RundownManager.ActiveExpedition).Pointer;
					_cachedHealth = RundownManager.ActiveExpeditionBalanceData.WeakDoorLockHealth;
				}
				return _cachedHealth;
			}
		}

		public static IDamageable? GetDamageableFromRayHit(RaycastHit rayHit)
		{
			if (!((Object)(object)((RaycastHit)(ref rayHit)).collider == (Object)null))
			{
				return GetDamageableFromCollider(((RaycastHit)(ref rayHit)).collider);
			}
			return null;
		}

		public static IDamageable? GetDamageableFromCollider(Collider? collider)
		{
			if (!((Object)(object)collider == (Object)null))
			{
				return GetDamageableFromGO(((Component)collider).gameObject);
			}
			return null;
		}

		public static IDamageable? GetDamageableFromGO(GameObject? go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return null;
			}
			ColliderMaterial component = go.GetComponent<ColliderMaterial>();
			IDamageable val = ((component != null) ? component.Damageable : null);
			if (val != null)
			{
				return val;
			}
			return go.GetComponent<IDamageable>();
		}
	}
	public sealed class DelayedCallback
	{
		private readonly Func<float> _getDelay;

		private readonly Action? _onStart;

		private readonly Action? _onRefresh;

		private readonly Action? _onEnd;

		private float _endTime;

		private Coroutine? _routine;

		public DelayedCallback(Func<float> getDelay, Action? onEnd)
		{
			_getDelay = getDelay;
			_onEnd = onEnd;
		}

		public DelayedCallback(Func<float> getDelay, Action? onStart, Action? onEnd)
		{
			_getDelay = getDelay;
			_onStart = onStart;
			_onEnd = onEnd;
		}

		public DelayedCallback(Func<float> getDelay, Action? onStart, Action? onRefresh, Action? onEnd)
		{
			_getDelay = getDelay;
			_onStart = onStart;
			_onRefresh = onRefresh;
			_onEnd = onEnd;
		}

		public void Start()
		{
			_endTime = Clock.Time + _getDelay();
			_onRefresh?.Invoke();
			if (_routine == null)
			{
				_routine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Update()), (Action)null);
			}
		}

		public IEnumerator Update()
		{
			_onStart?.Invoke();
			while (_endTime > Clock.Time)
			{
				yield return (object)new WaitForSeconds(_endTime - Clock.Time);
			}
			_routine = null;
			_onEnd?.Invoke();
		}

		public void Stop()
		{
			if (_routine != null)
			{
				CoroutineManager.StopCoroutine(_routine);
				_routine = null;
				_onEnd?.Invoke();
			}
		}

		public void Cancel()
		{
			if (_routine != null)
			{
				CoroutineManager.StopCoroutine(_routine);
				_routine = null;
			}
		}
	}
	internal static class DictExtensions
	{
		public static bool TryGetValueAs<Key, Value, ValueAs>(this IDictionary<Key, Value> dict, Key key, [MaybeNullWhen(false)] out ValueAs valueAs) where Key : notnull where ValueAs : Value
		{
			if (dict.TryGetValue(key, out Value value))
			{
				valueAs = (ValueAs)(object)value;
				return true;
			}
			valueAs = default(ValueAs);
			return false;
		}
	}
	public sealed class HitData
	{
		public float damage;

		public Vector2 damageFalloff;

		public float falloff;

		public float precisionMulti;

		public float staggerMulti;

		public float maxRayDist;

		public PlayerAgent owner;

		public Vector3 fireDir;

		public Vector3 hitPos;

		public IDamageable? damageable;

		private RaycastHit _rayHit;

		private WeaponHitData? _weaponHitData;

		private MeleeWeaponFirstPerson? _meleeWeapon;

		public RaycastHit RayHit
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _rayHit;
			}
			set
			{
				//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_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_001a: Unknown result type (might be due to invalid IL or missing references)
				_rayHit = value;
				hitPos = ((RaycastHit)(ref _rayHit)).point;
				damageable = DamageableUtil.GetDamageableFromRayHit(_rayHit);
			}
		}

		public HitData(WeaponHitData hitData, float additionalDist = 0f)
		{
			Setup(hitData, additionalDist);
		}

		public HitData(MeleeWeaponFirstPerson melee, MeleeWeaponDamageData hitData)
		{
			Setup(melee, hitData);
		}

		public HitData()
		{
		}

		public void Setup(WeaponHitData hitData, float additionalDist = 0f)
		{
			//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_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_0064: Unknown result type (might be due to invalid IL or missing references)
			_weaponHitData = hitData;
			_meleeWeapon = null;
			damage = hitData.damage;
			damageFalloff = hitData.damageFalloff;
			precisionMulti = hitData.precisionMulti;
			staggerMulti = hitData.staggerMulti;
			owner = hitData.owner;
			fireDir = hitData.fireDir;
			maxRayDist = hitData.maxRayDist;
			RayHit = hitData.rayHit;
			SetFalloff(additionalDist);
		}

		public void Setup(MeleeWeaponFirstPerson melee, MeleeWeaponDamageData hitData)
		{
			//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_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_0056: 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)
			_weaponHitData = null;
			_meleeWeapon = melee;
			damage = melee.m_damageToDeal;
			precisionMulti = melee.m_precisionMultiToDeal;
			staggerMulti = melee.m_staggerMultiToDeal;
			falloff = 1f;
			fireDir = hitData.hitPos - hitData.sourcePos;
			hitPos = hitData.hitPos;
			damageable = DamageableUtil.GetDamageableFromGO(hitData.damageGO);
		}

		public void Apply()
		{
			if (_weaponHitData != null)
			{
				Apply(_weaponHitData);
			}
			else if ((Object)(object)_meleeWeapon != (Object)null)
			{
				Apply(_meleeWeapon);
			}
		}

		public WeaponHitData Apply(WeaponHitData hitData)
		{
			//IL_0032: 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)
			hitData.owner = owner;
			hitData.damage = damage;
			hitData.precisionMulti = precisionMulti;
			hitData.staggerMulti = staggerMulti;
			hitData.rayHit = RayHit;
			hitData.fireDir = fireDir;
			hitData.maxRayDist = maxRayDist;
			return hitData;
		}

		public MeleeWeaponFirstPerson Apply(MeleeWeaponFirstPerson melee)
		{
			melee.m_damageToDeal = damage;
			melee.m_precisionMultiToDeal = precisionMulti;
			melee.m_staggerMultiToDeal = staggerMulti;
			return melee;
		}

		public void SetFalloff(float additionalDist = 0f)
		{
			//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)
			RaycastHit rayHit = RayHit;
			falloff = (((RaycastHit)(ref rayHit)).distance + additionalDist).Map(damageFalloff.x, damageFalloff.y, 1f, BulletWeapon.s_falloffMin);
		}

		public WeaponHitData ToWeaponHitData()
		{
			//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_0011: 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_001d: 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_0035: 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_0043: 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_004f: 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_0066: Expected O, but got Unknown
			return new WeaponHitData
			{
				damage = damage,
				damageFalloff = damageFalloff,
				precisionMulti = precisionMulti,
				staggerMulti = staggerMulti,
				owner = owner,
				rayHit = RayHit,
				fireDir = fireDir,
				maxRayDist = maxRayDist
			};
		}
	}
	public static class LayerUtil
	{
		public static int MaskDynamic { get; private set; }

		public static int MaskEntityAndWorld { get; private set; }

		public static int MaskEntityAndWorld3P { get; private set; }

		public static int MaskWorld { get; private set; }

		public static int MaskWorldExcProj { get; private set; }

		public static int MaskDecalValid { get; private set; }

		public static int MaskEntityDynamic3P { get; private set; }

		public static int MaskEntity { get; private set; }

		public static int MaskEntity3P { get; private set; }

		public static int MaskOwner { get; private set; }

		public static int MaskFriendly { get; private set; }

		public static int MaskEnemy { get; private set; }

		public static int MaskEnemyDynamic { get; private set; }

		internal static void Init()
		{
			MaskOwner = LayerMask.GetMask(new string[1] { "PlayerMover" });
			MaskFriendly = LayerMask.GetMask(new string[1] { "PlayerSynced" });
			MaskEnemy = LayerMask.GetMask(new string[1] { "EnemyDamagable" });
			MaskDynamic = LayerMask.GetMask(new string[1] { "Dynamic" });
			MaskEnemyDynamic = MaskEnemy | MaskDynamic;
			MaskEntity3P = MaskFriendly | MaskEnemy;
			MaskEntity = MaskOwner | MaskEntity3P;
			MaskDecalValid = LayerMask.GetMask(new string[3] { "Default", "Default_NoGraph", "Default_BlockGraph" });
			MaskWorldExcProj = MaskDecalValid | MaskDynamic;
			MaskWorld = MaskWorldExcProj | LayerMask.GetMask(new string[1] { "ProjectileBlocker" });
			MaskEntityAndWorld = MaskEntity | MaskWorld;
			MaskEntityDynamic3P = MaskEntity3P | MaskDynamic;
			MaskEntityAndWorld3P = MaskEntity3P | MaskWorld;
		}
	}
	internal static class NumExtensions
	{
		public static float Map(this float orig, float fromMin, float fromMax, float toMin, float toMax, float exponent = 1f)
		{
			if (fromMin == fromMax)
			{
				if (!(orig < fromMin))
				{
					return toMax;
				}
				return toMin;
			}
			orig = Math.Clamp(orig, fromMin, fromMax);
			if (exponent != 1f)
			{
				return (float)Math.Pow((orig - fromMin) / (fromMax - fromMin), exponent) * (toMax - toMin) + toMin;
			}
			return (orig - fromMin) / (fromMax - fromMin) * (toMax - toMin) + toMin;
		}

		public static float MapInverted(this float orig, float fromMin, float fromMax, float toMax, float toMin, float exponent = 1f)
		{
			if (fromMin == fromMax)
			{
				if (!(orig < fromMin))
				{
					return toMin;
				}
				return toMax;
			}
			orig = Math.Clamp(orig, fromMin, fromMax);
			if (exponent != 1f)
			{
				return (float)Math.Pow((fromMax - orig) / (fromMax - fromMin), exponent) * (toMax - toMin) + toMin;
			}
			return (fromMax - orig) / (fromMax - fromMin) * (toMax - toMin) + toMin;
		}

		public static float Lerp(this float t, float min, float max)
		{
			return (max - min) * Math.Clamp(t, 0f, 1f) + min;
		}

		public static float Lerp(this double t, float min, float max)
		{
			return (max - min) * (float)Math.Clamp(t, 0.0, 1.0) + min;
		}
	}
	[Flags]
	internal enum SearchSetting
	{
		None = 0,
		Alloc = 1,
		CacheHit = 2,
		CheckLOS = 4,
		CheckDoors = 8,
		CheckOwner = 0x10,
		CheckFriendly = 0x20,
		IgnoreDupes = 0x40
	}
	internal static class SearchUtil
	{
		private static readonly List<EnemyAgent> s_enemyCache = new List<EnemyAgent>();

		private static readonly List<(EnemyAgent, RaycastHit)> s_combinedCache = new List<(EnemyAgent, RaycastHit)>();

		private static readonly List<(PlayerAgent, RaycastHit)> s_combinedCachePlayer = new List<(PlayerAgent, RaycastHit)>();

		private static readonly Queue<AIG_CourseNode> s_nodeQueue = new Queue<AIG_CourseNode>();

		private static readonly List<RaycastHit> s_lockCache = new List<RaycastHit>();

		public static HashSet<IntPtr>? DupeCheckSet;

		public static int SightBlockLayer = 0;

		public const float WeakspotBufferDist = 0.1f;

		private static Ray s_ray;

		private static RaycastHit s_rayHit;

		private const float Epsilon = 1E-05f;

		private static Vector3 ClosestPointOnBounds(Bounds bounds, Vector3 point)
		{
			//IL_0000: 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_0023: 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_0037: 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_004e: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(Math.Clamp(point.x, ((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.x), Math.Clamp(point.y, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.y), Math.Clamp(point.z, ((Bounds)(ref bounds)).min.z, ((Bounds)(ref bounds)).max.z));
		}

		private static bool PortalInRange(Ray ray, float range, float angle, AIG_CoursePortal portal)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0019: 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_0021: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0069: 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_008b: 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_0098: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			Bounds portalBounds = portal.m_cullPortal.m_portalBounds;
			Vector3 val = ClosestPointOnBounds(portalBounds, ((Ray)(ref ray)).origin);
			Vector3 val2 = ((Ray)(ref ray)).origin - val;
			if (((Vector3)(ref val2)).sqrMagnitude > range * range)
			{
				return false;
			}
			if (angle >= 180f || ((Bounds)(ref portalBounds)).Contains(((Ray)(ref ray)).origin))
			{
				return true;
			}
			Vector3 val3 = portal.m_cullPortal.m_center - ((Ray)(ref ray)).origin;
			float num = Vector3.Dot(val3, ((Ray)(ref ray)).direction);
			if (angle == 90f)
			{
				return num >= 0f;
			}
			val = Vector3.Project(val3, ((Ray)(ref ray)).direction);
			Bounds portalBounds2 = portal.m_cullPortal.m_portalBounds;
			val2 = ((Bounds)(ref portalBounds2)).extents;
			float magnitude = ((Vector3)(ref val2)).magnitude;
			float num2 = ((Vector3)(ref val)).magnitude * (float)Math.Tan(angle * (MathF.PI / 180f));
			if (num2 < 0f)
			{
				if (num >= 0f)
				{
					return true;
				}
				num2 = Math.Max(0f, num2 + magnitude);
				val2 = val3 - val;
				return ((Vector3)(ref val2)).sqrMagnitude >= num2 * num2;
			}
			if (num <= 0f)
			{
				return false;
			}
			num2 += magnitude;
			val2 = val3 - val;
			return ((Vector3)(ref val2)).sqrMagnitude <= num2 * num2;
		}

		private static bool RaycastEnsured(Collider collider, Vector3 backupOrigin, float range, out RaycastHit hit)
		{
			//IL_0001: 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_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_001e: 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)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007f: Unknown result type (might be due to invalid IL or missing references)
			if (collider.Raycast(s_ray, ref hit, range))
			{
				return true;
			}
			Vector3 val = collider.ClosestPoint(backupOrigin);
			Bounds bounds = collider.bounds;
			Vector3 val2 = val - ((Bounds)(ref bounds)).center;
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			bounds = collider.bounds;
			((Ray)(ref s_ray)).origin = ((Bounds)(ref bounds)).center + val2 + normalized * Math.Min(0.1f, range / 2f);
			((Ray)(ref s_ray)).direction = -normalized;
			return collider.Raycast(s_ray, ref hit, range);
		}

		private static bool TryGetClosestHit(Ray ray, float range, float angle, Agent agent, out RaycastHit hit, SearchSetting settings)
		{
			//IL_0002: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Invalid comparison between Unknown and I4
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_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_0123: 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: Invalid comparison between Unknown and I4
			//IL_016a: 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)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: 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_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)
			//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_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			hit = default(RaycastHit);
			if ((Object)(object)agent == (Object)null || !agent.Alive)
			{
				return false;
			}
			if (settings.HasFlag(SearchSetting.IgnoreDupes))
			{
				if ((int)agent.Type == 1)
				{
					HashSet<IntPtr>? dupeCheckSet = DupeCheckSet;
					if (dupeCheckSet != null && dupeCheckSet.Contains(((Il2CppObjectBase)((Il2CppObjectBase)agent).Cast<EnemyAgent>().Damage).Pointer))
					{
						return false;
					}
				}
				if ((int)agent.Type == 0)
				{
					HashSet<IntPtr>? dupeCheckSet2 = DupeCheckSet;
					if (dupeCheckSet2 != null && dupeCheckSet2.Contains(((Il2CppObjectBase)((Il2CppObjectBase)agent).Cast<PlayerAgent>().Damage).Pointer))
					{
						return false;
					}
				}
			}
			((Ray)(ref s_ray)).origin = ((Ray)(ref ray)).origin;
			float num = range * range;
			float num2 = num;
			Collider val = null;
			bool flag = false;
			foreach (Collider componentsInChild in ((Component)agent).GetComponentsInChildren<Collider>())
			{
				Dam_EnemyDamageLimb val2 = null;
				if ((int)agent.Type == 1)
				{
					val2 = ((Component)componentsInChild).GetComponent<Dam_EnemyDamageLimb>();
					if ((Object)(object)val2 == (Object)null || val2.IsDestroyed)
					{
						continue;
					}
				}
				else if ((int)agent.Type == 0 && ((Component)componentsInChild).GetComponent<IDamageable>() == null)
				{
					continue;
				}
				Vector3 val3 = componentsInChild.ClosestPoint(((Ray)(ref ray)).origin);
				Vector3 direction = val3 - ((Ray)(ref ray)).origin;
				float num3 = ((Vector3)(ref direction)).sqrMagnitude;
				float num4 = num3;
				if (val2 != null && (int)val2.m_type == 1 && num3 < num)
				{
					float num5 = Math.Max(((Vector3)(ref direction)).magnitude - 0.1f, 0f);
					num3 = num5 * num5;
				}
				if (!(num3 < num2) || !(Vector3.Angle(((Ray)(ref ray)).direction, val3 - ((Ray)(ref ray)).origin) <= angle) || (settings.HasFlag(SearchSetting.CheckLOS) && Physics.Linecast(((Ray)(ref ray)).origin, val3, SightBlockLayer)))
				{
					continue;
				}
				num2 = num3;
				val = componentsInChild;
				if (!settings.HasFlag(SearchSetting.CacheHit))
				{
					break;
				}
				if (num2 < 1E-05f)
				{
					if (!(num4 > 1E-05f))
					{
						((Ray)(ref s_ray)).origin = ((Ray)(ref s_ray)).origin - ((Ray)(ref ray)).direction * Math.Min(0.1f, range / 2f);
						((Ray)(ref s_ray)).direction = val3 - ((Ray)(ref s_ray)).origin;
						if (RaycastEnsured(componentsInChild, ((Ray)(ref ray)).origin, range, out hit))
						{
							((RaycastHit)(ref hit)).point = val3;
							((RaycastHit)(ref hit)).distance = 0f;
							flag = true;
						}
						else
						{
							val = null;
						}
					}
					break;
				}
				((Ray)(ref s_ray)).direction = direction;
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (settings.HasFlag(SearchSetting.CacheHit) && !flag && !RaycastEnsured(val, ((Ray)(ref ray)).origin, range, out hit))
			{
				return false;
			}
			return true;
		}

		private static void CacheEnemiesInRange(Ray ray, float range, float angle, AIG_CourseNode origin, SearchSetting settings)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_010b: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			AIG_SearchID.IncrementSearchID();
			ushort searchID = AIG_SearchID.SearchID;
			float num = range * range;
			s_nodeQueue.Enqueue(origin);
			((AIG_CourseGraphMember)origin).m_searchID = searchID;
			s_combinedCache.Clear();
			AIG_CourseNode result;
			while (s_nodeQueue.TryDequeue(out result))
			{
				Enumerator<AIG_CoursePortal> enumerator = result.m_portals.GetEnumerator();
				while (enumerator.MoveNext())
				{
					AIG_CoursePortal current = enumerator.Current;
					AIG_CourseNode oppositeNode = current.GetOppositeNode(result);
					if ((!settings.HasFlag(SearchSetting.CheckDoors) || current.IsTraversable) && ((AIG_CourseGraphMember)oppositeNode).m_searchID != searchID && PortalInRange(ray, range, angle, current))
					{
						((AIG_CourseGraphMember)oppositeNode).m_searchID = searchID;
						s_nodeQueue.Enqueue(oppositeNode);
					}
				}
				Enumerator<EnemyAgent> enumerator2 = result.m_enemiesInNode.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					EnemyAgent current2 = enumerator2.Current;
					if (!((Object)(object)current2 == (Object)null) && ((Agent)current2).Alive && !(((Dam_SyncedDamageBase)current2.Damage).Health <= 0f))
					{
						Vector3 val = ClosestPointOnBounds(((C_Cullable)current2.MovingCuller.Culler).Bounds, ((Ray)(ref ray)).origin) - ((Ray)(ref ray)).origin;
						if (!(((Vector3)(ref val)).sqrMagnitude > num) && TryGetClosestHit(ray, range, angle, (Agent)(object)current2, out s_rayHit, settings))
						{
							s_combinedCache.Add((current2, s_rayHit));
						}
					}
				}
			}
		}

		public static List<EnemyAgent> GetEnemiesInRange(Ray ray, float range, float angle, AIG_CourseNode origin, SearchSetting settings = SearchSetting.None)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			s_enemyCache.Clear();
			if (range == 0f || angle == 0f)
			{
				if (!settings.HasFlag(SearchSetting.Alloc))
				{
					return s_enemyCache;
				}
				return new List<EnemyAgent>();
			}
			CacheEnemiesInRange(ray, range, angle, origin, settings);
			if (settings.HasFlag(SearchSetting.Alloc))
			{
				return s_combinedCache.ConvertAll(((EnemyAgent, RaycastHit) pair) => pair.Item1);
			}
			foreach (var item2 in s_combinedCache)
			{
				EnemyAgent item = item2.Item1;
				s_enemyCache.Add(item);
			}
			return s_enemyCache;
		}

		public static List<(EnemyAgent enemy, RaycastHit hit)> GetEnemyHitsInRange(Ray ray, float range, float angle, AIG_CourseNode origin, SearchSetting settings = SearchSetting.CacheHit)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (range == 0f || angle == 0f)
			{
				s_combinedCache.Clear();
				if (!settings.HasFlag(SearchSetting.Alloc))
				{
					return s_combinedCache;
				}
				return new List<(EnemyAgent, RaycastHit)>();
			}
			settings |= SearchSetting.CacheHit;
			CacheEnemiesInRange(ray, range, angle, origin, settings);
			if (settings.HasFlag(SearchSetting.Alloc))
			{
				return new List<(EnemyAgent, RaycastHit)>(s_combinedCache);
			}
			return s_combinedCache;
		}

		public static List<RaycastHit> GetLockHitsInRange(Ray ray, float range, float angle, SearchSetting settings = SearchSetting.None)
		{
			//IL_003b: 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_0105: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			s_lockCache.Clear();
			if (range == 0f || angle == 0f)
			{
				if (!settings.HasFlag(SearchSetting.Alloc))
				{
					return s_lockCache;
				}
				return new List<RaycastHit>();
			}
			Collider[] array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(((Ray)(ref ray)).origin, range, LayerUtil.MaskDynamic));
			Vector3 direction = ((Ray)(ref ray)).direction;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				IDamageable damageableFromCollider = DamageableUtil.GetDamageableFromCollider(val);
				if (damageableFromCollider == null)
				{
					continue;
				}
				if (settings.HasFlag(SearchSetting.IgnoreDupes))
				{
					HashSet<IntPtr>? dupeCheckSet = DupeCheckSet;
					if (dupeCheckSet != null && dupeCheckSet.Contains(((Il2CppObjectBase)damageableFromCollider.GetBaseDamagable()).Pointer))
					{
						continue;
					}
				}
				if (!settings.HasFlag(SearchSetting.CheckLOS) || !Physics.Linecast(((Ray)(ref ray)).origin, damageableFromCollider.DamageTargetPos, ref s_rayHit, SightBlockLayer) || !(((Il2CppObjectBase)((Component)((RaycastHit)(ref s_rayHit)).collider).gameObject).Pointer != ((Il2CppObjectBase)((Component)val).gameObject).Pointer))
				{
					((Ray)(ref ray)).direction = damageableFromCollider.DamageTargetPos - ((Ray)(ref ray)).origin;
					if (val.Raycast(ray, ref s_rayHit, range) && Vector3.Angle(((Ray)(ref ray)).direction, direction) < angle)
					{
						s_lockCache.Add(s_rayHit);
					}
				}
			}
			if (settings.HasFlag(SearchSetting.Alloc))
			{
				return new List<RaycastHit>(s_lockCache);
			}
			return s_lockCache;
		}

		public static List<(PlayerAgent, RaycastHit)> GetPlayerHitsInRange(Ray ray, float range, float angle, SearchSetting settings = SearchSetting.CheckOwner | SearchSetting.CheckFriendly)
		{
			//IL_0076: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_0122: 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)
			s_combinedCachePlayer.Clear();
			if (range == 0f || angle == 0f)
			{
				if (!settings.HasFlag(SearchSetting.Alloc))
				{
					return s_combinedCachePlayer;
				}
				return new List<(PlayerAgent, RaycastHit)>();
			}
			float num = range * range;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if ((Object)(object)current == (Object)null || !((Agent)current).Alive)
				{
					continue;
				}
				Vector3 val = ClosestPointOnBounds(((C_Cullable)current.m_movingCuller.Culler).Bounds, ((Ray)(ref ray)).origin) - ((Ray)(ref ray)).origin;
				if (((Vector3)(ref val)).sqrMagnitude > num)
				{
					continue;
				}
				if (((Agent)current).IsLocallyOwned)
				{
					if (!settings.HasFlag(SearchSetting.CheckOwner))
					{
						continue;
					}
					((Ray)(ref s_ray)).origin = ((Ray)(ref ray)).origin;
					((Ray)(ref s_ray)).direction = ((Dam_SyncedDamageBase)current.Damage).DamageTargetPos - ((Ray)(ref ray)).origin;
					if (!((Component)current).GetComponent<Collider>().Raycast(s_ray, ref s_rayHit, range) || (settings.HasFlag(SearchSetting.CheckLOS) && Physics.Linecast(((Ray)(ref ray)).origin, ((RaycastHit)(ref s_rayHit)).point, SightBlockLayer)))
					{
						continue;
					}
				}
				else if (!settings.HasFlag(SearchSetting.CheckFriendly) || !TryGetClosestHit(ray, range, angle, (Agent)(object)current, out s_rayHit, settings))
				{
					continue;
				}
				s_combinedCachePlayer.Add((current, s_rayHit));
			}
			if (settings.HasFlag(SearchSetting.Alloc))
			{
				return new List<(PlayerAgent, RaycastHit)>(s_combinedCachePlayer);
			}
			return s_combinedCachePlayer;
		}

		private static bool HasCluster(AIG_VoxelNodePillar pillar)
		{
			Enumerator<AIG_VoxelNode> enumerator = pillar.m_nodes.GetEnumerator();
			AIG_NodeCluster val = default(AIG_NodeCluster);
			while (enumerator.MoveNext())
			{
				AIG_VoxelNode current = enumerator.Current;
				if (current.ClusterID != 0 && AIG_NodeCluster.TryGetNodeCluster(current.ClusterID, ref val))
				{
					return true;
				}
			}
			return false;
		}

		public static AIG_CourseNode GetCourseNode(Vector3 position, Agent agent)
		{
			//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_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_0022: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			Vector3 position2 = agent.Position;
			if (TryGetGeomorphVolumeSilent(Dimension.GetDimensionFromPos(position).DimensionIndex, position, out AIG_GeomorphNodeVolume resultingGeoVolume))
			{
				position.y = ((AIG_NodeVolume)resultingGeoVolume).Position.y;
				position2.y = position.y;
				Vector3 val = position2 - position;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				AIG_VoxelNodePillar val2 = null;
				for (int i = 0; i < 10; i++)
				{
					if (((AIG_NodeVolume)resultingGeoVolume).m_voxelNodeVolume.TryGetPillar(position, ref val2) && HasCluster(val2))
					{
						break;
					}
					position += normalized;
				}
				if (val2 == null)
				{
					return agent.CourseNode;
				}
				Enumerator<AIG_VoxelNode> enumerator = val2.m_nodes.GetEnumerator();
				AIG_NodeCluster val3 = default(AIG_NodeCluster);
				while (enumerator.MoveNext())
				{
					AIG_VoxelNode current = enumerator.Current;
					if (current.ClusterID != 0 && AIG_NodeCluster.TryGetNodeCluster(current.ClusterID, ref val3) && val3.CourseNode != null)
					{
						return val3.CourseNode;
					}
				}
			}
			return agent.CourseNode;
		}

		private static bool TryGetGeomorphVolumeSilent(eDimensionIndex dimensionIndex, Vector3 pos, [MaybeNullWhen(false)] out AIG_GeomorphNodeVolume resultingGeoVolume)
		{
			//IL_001a: 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)
			resultingGeoVolume = null;
			LG_Floor currentFloor = Builder.Current.m_currentFloor;
			if ((Object)(object)currentFloor == (Object)null)
			{
				return false;
			}
			Dimension val = default(Dimension);
			if (!currentFloor.GetDimension(dimensionIndex, ref val))
			{
				return false;
			}
			if (val.Grid == null || !TryGetCell(val.Grid, pos, out LG_Cell cell))
			{
				return false;
			}
			if (((CellBase<LG_Tile, LG_Cell>)(object)cell).m_grouping == null || (Object)(object)((CellBase<LG_Tile, LG_Cell>)(object)cell).m_grouping.m_geoRoot == (Object)null)
			{
				return false;
			}
			resultingGeoVolume = ((Il2CppObjectBase)((CellBase<LG_Tile, LG_Cell>)(object)cell).m_grouping.m_geoRoot.m_nodeVolume).TryCast<AIG_GeomorphNodeVolume>();
			return (Object)(object)resultingGeoVolume != (Object)null;
		}

		private static bool TryGetCell(LG_Grid grid, Vector3 pos, [MaybeNullWhen(false)] out LG_Cell cell)
		{
			//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_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_000e: 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)
			pos -= ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_gridPosition;
			int num = (int)Math.Round((pos.x - ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDimHalf) / ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDim);
			int num2 = (int)Math.Round((pos.z - ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDimHalf) / ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDim);
			if (num < 0 || num2 < 0 || num >= ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_sizeX || num2 >= ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_sizeZ)
			{
				cell = null;
				return false;
			}
			cell = ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).GetCell(num, num2);
			return true;
		}
	}
	internal static class SortUtil
	{
		private static List<(RaycastHit hit, float distance)> s_limbCache = new List<(RaycastHit, float)>();

		private static List<(EnemyAgent enemy, float value)> s_enemyTupleCache = new List<(EnemyAgent, float)>();

		public static int Rayhit(RaycastHit x, RaycastHit y)
		{
			if (((RaycastHit)(ref x)).distance == ((RaycastHit)(ref y)).distance)
			{
				return 0;
			}
			if (!(((RaycastHit)(ref x)).distance < ((RaycastHit)(ref y)).distance))
			{
				return 1;
			}
			return -1;
		}

		public static int EnemyRayhit((EnemyAgent, RaycastHit hit) x, (EnemyAgent, RaycastHit hit) y)
		{
			if (((RaycastHit)(ref x.hit)).distance == ((RaycastHit)(ref y.hit)).distance)
			{
				return 0;
			}
			if (!(((RaycastHit)(ref x.hit)).distance < ((RaycastHit)(ref y.hit)).distance))
			{
				return 1;
			}
			return -1;
		}

		public static void SortWithWeakspotBuffer(IList<RaycastHit> list)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0059: 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_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 (RaycastHit item in list)
			{
				RaycastHit current = item;
				IDamageable? damageableFromRayHit = DamageableUtil.GetDamageableFromRayHit(current);
				int num;
				if (damageableFromRayHit == null)
				{
					num = 0;
				}
				else
				{
					Dam_EnemyDamageLimb obj = ((Il2CppObjectBase)damageableFromRayHit).TryCast<Dam_EnemyDamageLimb>();
					num = ((((obj != null) ? new eLimbDamageType?(obj.m_type) : null) == (eLimbDamageType?)1) ? 1 : 0);
				}
				bool flag = (byte)num != 0;
				s_limbCache.Add((current, flag ? Math.Max(((RaycastHit)(ref current)).distance - 0.1f, 0f) : ((RaycastHit)(ref current)).distance));
			}
			s_limbCache.Sort(FloatTuple);
			CopySortedList(s_limbCache, list);
			s_limbCache.Clear();
		}

		public static void CopySortedList<T>(IList<(T, float)> sortedList, IList<T> list)
		{
			for (int i = 0; i < list.Count; i++)
			{
				list[i] = sortedList[i].Item1;
			}
		}

		public static void CopySortedList<T>(IList<(T, float, float)> sortedList, IList<T> list)
		{
			for (int i = 0; i < list.Count; i++)
			{
				list[i] = sortedList[i].Item1;
			}
		}

		public static int FloatTuple<T>((T, float val) x, (T, float val) y)
		{
			if (x.val == y.val)
			{
				return 0;
			}
			if (!(x.val < y.val))
			{
				return 1;
			}
			return -1;
		}

		public static int FloatTuple<T>((T, float val1, float val2) x, (T, float val1, float val2) y)
		{
			if (x.val1 == y.val1)
			{
				if (x.val2 == y.val2)
				{
					return 0;
				}
				if (!(x.val2 < y.val2))
				{
					return 1;
				}
				return -1;
			}
			if (!(x.val1 < y.val1))
			{
				return 1;
			}
			return -1;
		}
	}
	internal static class StringExtensions
	{
		public static T ToEnum<T>(this string? value, T defaultValue) where T : struct
		{
			if (string.IsNullOrEmpty(value))
			{
				return defaultValue;
			}
			if (!Enum.TryParse<T>(value.Replace(" ", null), ignoreCase: true, out var result))
			{
				return defaultValue;
			}
			return result;
		}
	}
}
namespace EWC.Utils.Log
{
	internal static class EWCLogger
	{
		private static ManualLogSource logger = Logger.CreateLogSource("ExtraWeaponCustomization");

		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 EWC.Patches
{
	[HarmonyPatch]
	internal static class EnemyLimbPatches
	{
		private static float _cachedArmor;

		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "BulletDamage")]
		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "MeleeDamage")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void Pre_Damage(Dam_EnemyDamageLimb __instance)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			ContextController cachedHitCC = WeaponPatches.CachedHitCC;
			if (cachedHitCC != null && (int)__instance.m_type == 2)
			{
				_cachedArmor = __instance.m_armorDamageMulti;
				__instance.m_armorDamageMulti = cachedHitCC.Invoke(new WeaponArmorContext(_cachedArmor)).ArmorMulti;
			}
		}

		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "BulletDamage")]
		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "MeleeDamage")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_Damage(Dam_EnemyDamageLimb __instance)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if (WeaponPatches.CachedHitCC != null && (int)__instance.m_type == 2)
			{
				__instance.m_armorDamageMulti = _cachedArmor;
			}
		}

		[HarmonyPatch(typeof(Dam_EnemyDamageLimb_Custom), "ApplyWeakspotAndArmorModifiers")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static bool Pre_WeakspotModifiers(Dam_EnemyDamageLimb_Custom __instance, float dam, float precisionMulti, ref float __result)
		{
			if (!WeaponPatches.CachedBypassTumorCap)
			{
				return true;
			}
			__result = dam * Math.Max(((Dam_EnemyDamageLimb)__instance).m_weakspotDamageMulti * precisionMulti, 1f) * ((Dam_EnemyDamageLimb)__instance).m_armorDamageMulti;
			return false;
		}
	}
	[HarmonyPatch]
	internal static class FPISPatches
	{
		private static CustomWeaponComponent? _cachedCWC;

		[HarmonyPatch(typeof(FPIS_Aim), "Enter")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_AimEnter(FPIS_Aim __instance)
		{
			_cachedCWC = ((Component)((FPItemState)__instance).Holder.WieldedItem).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)_cachedCWC == (Object)null))
			{
				_cachedCWC.Invoke(StaticContext<WeaponAimContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(FPIS_Aim), "Exit")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_AimExit()
		{
			if (!((Object)(object)_cachedCWC == (Object)null))
			{
				_cachedCWC.Invoke(StaticContext<WeaponAimEndContext>.Instance);
			}
		}
	}
	[HarmonyPatch]
	internal static class PlayerInventoryPatches
	{
		private static bool _allowReload = true;

		[HarmonyPatch(typeof(PUI_Inventory), "SetSlotAmmo")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void SetAmmoUICallback(PUI_Inventory __instance, InventorySlot slot, ref int clipAbs, ref int inPackAbs, ref float inPackRel)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if ((int)slot == 0)
			{
				return;
			}
			SNet_Player owner = __instance.m_owner;
			object obj;
			if (owner == null)
			{
				obj = null;
			}
			else
			{
				SNet_IPlayerAgent playerAgent = owner.PlayerAgent;
				if (playerAgent == null)
				{
					obj = null;
				}
				else
				{
					PlayerAgent obj2 = ((Il2CppObjectBase)playerAgent).TryCast<PlayerAgent>();
					if (obj2 == null)
					{
						obj = null;
					}
					else
					{
						FirstPersonItemHolder fPItemHolder = obj2.FPItemHolder;
						if (fPItemHolder == null)
						{
							obj = null;
						}
						else
						{
							ItemEquippable wieldedItem = fPItemHolder.WieldedItem;
							if (wieldedItem == null)
							{
								obj = null;
							}
							else
							{
								BulletWeapon obj3 = ((Il2CppObjectBase)wieldedItem).TryCast<BulletWeapon>();
								obj = ((obj3 != null) ? ((Component)obj3).GetComponent<CustomWeaponComponent>() : null);
							}
						}
					}
				}
			}
			CustomWeaponComponent customWeaponComponent = (CustomWeaponComponent)obj;
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				PUI_InventoryItem val = __instance.m_inventorySlots[slot];
				WeaponPreAmmoUIContext weaponPreAmmoUIContext = new WeaponPreAmmoUIContext(clipAbs, inPackAbs, inPackRel, val.ShowAmmoClip, val.ShowAmmoPack, val.ShowAmmoTotalRel, val.ShowAmmoInfinite);
				customWeaponComponent.Invoke(weaponPreAmmoUIContext);
				clipAbs = weaponPreAmmoUIContext.Clip;
				inPackAbs = weaponPreAmmoUIContext.Reserve;
				inPackRel = weaponPreAmmoUIContext.TotalRel;
				val.ShowAmmoClip = weaponPreAmmoUIContext.ShowClip;
				val.ShowAmmoPack = weaponPreAmmoUIContext.ShowReserve;
				val.ShowAmmoTotalRel = weaponPreAmmoUIContext.ShowRel;
				val.ShowAmmoInfinite = weaponPreAmmoUIContext.ShowInfinite;
			}
		}

		private static InventorySlot AmmoToSlot(AmmoType ammo)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0021: Unknown result type (might be due to invalid IL or missing references)
			return (InventorySlot)((int)ammo switch
			{
				0 => 1, 
				1 => 2, 
				2 => 3, 
				_ => 0, 
			});
		}

		[HarmonyPatch(typeof(PlayerAmmoStorage), "PickupAmmo")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void AmmoPackCallback(PlayerAmmoStorage __instance, AmmoType ammoType, ref float ammoAmount)
		{
			//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)
			BackpackItem val = default(BackpackItem);
			if (__instance.m_playerBackpack.TryGetBackpackItem(AmmoToSlot(ammoType), ref val))
			{
				Item instance = val.Instance;
				CustomWeaponComponent customWeaponComponent = ((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null);
				if ((Object)(object)customWeaponComponent != (Object)null)
				{
					ammoAmount = customWeaponComponent.Invoke(new WeaponPreAmmoPackContext(ammoAmount)).AmmoAmount;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerAmmoStorage), "PickupAmmo")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostAmmoPackCallback(PlayerAmmoStorage __instance, AmmoType ammoType)
		{
			//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)
			BackpackItem val = default(BackpackItem);
			if (__instance.m_playerBackpack.TryGetBackpackItem(AmmoToSlot(ammoType), ref val))
			{
				Item instance = val.Instance;
				((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null)?.Invoke(new WeaponPostAmmoPackContext(__instance));
			}
		}

		[HarmonyPatch(typeof(PlayerInventoryLocal), "DoReload")]
		[HarmonyPatch(typeof(PlayerInventoryBase), "DoReload")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ReloadCallback(PlayerInventoryBase __instance)
		{
			ItemEquippable wieldedItem = __instance.m_wieldedItem;
			CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				customWeaponComponent.Invoke(StaticContext<WeaponPostReloadContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(PlayerInventoryLocal), "TriggerReload")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static bool ReloadPreStartCallback(PlayerInventoryLocal __instance)
		{
			_allowReload = true;
			ItemEquippable wieldedItem = ((PlayerInventoryBase)__instance).m_wieldedItem;
			CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
			if ((Object)(object)customWeaponComponent == (Object)null)
			{
				return true;
			}
			_allowReload = customWeaponComponent.Invoke(new WeaponPreReloadContext()).Allow;
			return _allowReload;
		}

		[HarmonyPatch(typeof(PlayerInventoryLocal), "TriggerReload")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ReloadStartCallback(PlayerInventoryLocal __instance)
		{
			if (_allowReload)
			{
				ItemEquippable wieldedItem = ((PlayerInventoryBase)__instance).m_wieldedItem;
				CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
				if (!((Object)(object)customWeaponComponent == (Object)null) && customWeaponComponent.Weapon.IsReloading)
				{
					customWeaponComponent.Invoke(StaticContext<WeaponReloadStartContext>.Instance);
				}
			}
		}

		[HarmonyPatch(typeof(PlayerAmmoStorage), "FillAllClips")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostFillAllClipsCallback(PlayerAmmoStorage __instance)
		{
			BackpackItem val = default(BackpackItem);
			if (__instance.m_playerBackpack.TryGetBackpackItem((InventorySlot)1, ref val))
			{
				Item instance = val.Instance;
				((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null)?.Invoke(new WeaponPostAmmoInitContext(__instance, __instance.StandardAmmo));
			}
			BackpackItem val2 = default(BackpackItem);
			if (__instance.m_playerBackpack.TryGetBackpackItem((InventorySlot)2, ref val2))
			{
				Item instance2 = val2.Instance;
				((instance2 != null) ? ((Component)instance2).GetComponent<CustomWeaponComponent>() : null)?.Invoke(new WeaponPostAmmoInitContext(__instance, __instance.SpecialAmmo));
			}
		}
	}
	[HarmonyPatch]
	internal static class ShotgunPatches
	{
		[HarmonyPatch(typeof(Shotgun), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void Pre_Fire(Shotgun __instance)
		{
			WeaponRayPatches.CachedWeapon = (BulletWeapon?)(object)__instance;
		}

		[HarmonyPatch(typeof(Shotgun), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_Fire(Shotgun __instance)
		{
			WeaponRayPatches.CachedWeapon = null;
		}
	}
	[HarmonyPatch]
	internal static class WeaponArchetypePatches
	{
		[HarmonyPatch(typeof(BulletWeaponArchetype), "SetOwner")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetupCallback(BulletWeaponArchetype __instance, PlayerAgent owner)
		{
			if (!((Object)(object)owner == (Object)null))
			{
				CustomWeaponComponent component = ((Component)__instance.m_weapon).GetComponent<CustomWeaponComponent>();
				if (!((Object)(object)component == (Object)null))
				{
					component.OwnerInit();
				}
			}
		}

		[HarmonyPatch(typeof(BWA_Burst), "OnStartFiring")]
		[HarmonyPatch(typeof(BWA_Auto), "OnStartFiring")]
		[HarmonyPatch(typeof(BulletWeaponArchetype), "OnStartFiring")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static bool StartFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if ((Object)(object)customWeaponComponent == (Object)null)
			{
				return true;
			}
			customWeaponComponent.CancelShot = false;
			WeaponPreStartFireContext weaponPreStartFireContext = new WeaponPreStartFireContext();
			customWeaponComponent.Invoke(weaponPreStartFireContext);
			customWeaponComponent.UpdateStoredFireRate();
			if (!weaponPreStartFireContext.Allow)
			{
				customWeaponComponent.StoreCancelShot();
			}
			return weaponPreStartFireContext.Allow;
		}

		[HarmonyPatch(typeof(BWA_Burst), "OnStartFiring")]
		[HarmonyPatch(typeof(BWA_Auto), "OnStartFiring")]
		[HarmonyPatch(typeof(BulletWeaponArchetype), "OnStartFiring")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostStartFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				if (customWeaponComponent.ResetShotIfCancel(__instance))
				{
					customWeaponComponent.CancelShot = false;
					__instance.m_readyToFire = false;
				}
				else
				{
					customWeaponComponent.Invoke(StaticContext<WeaponPostStartFireContext>.Instance);
				}
			}
		}

		[HarmonyPatch(typeof(BWA_Auto), "OnFireShot")]
		[HarmonyPatch(typeof(BWA_Burst), "OnFireShot")]
		[HarmonyPatch(typeof(BWA_Semi), "OnFireShot")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static bool PreFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if ((Object)(object)customWeaponComponent == (Object)null)
			{
				return true;
			}
			if (customWeaponComponent.CancelShot)
			{
				return false;
			}
			WeaponFireCancelContext weaponFireCancelContext = new WeaponFireCancelContext();
			customWeaponComponent.Invoke(weaponFireCancelContext);
			if (!weaponFireCancelContext.Allow)
			{
				customWeaponComponent.StoreCancelShot();
			}
			else
			{
				customWeaponComponent.Invoke(StaticContext<WeaponPreFireContext>.Instance);
			}
			return weaponFireCancelContext.Allow;
		}

		[HarmonyPatch(typeof(BWA_Auto), "OnFireShot")]
		[HarmonyPatch(typeof(BWA_Burst), "OnFireShot")]
		[HarmonyPatch(typeof(BWA_Semi), "OnFireShot")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null) && !customWeaponComponent.CancelShot)
			{
				customWeaponComponent.Invoke(StaticContext<WeaponPostFireContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(BulletWeaponArchetype), "PostFireCheck")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void PrePostFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				customWeaponComponent.ResetShotIfCancel(__instance);
			}
		}

		[HarmonyPatch(typeof(BulletWeaponArchetype), "PostFireCheck")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostPostFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				if (customWeaponComponent.CancelShot)
				{
					customWeaponComponent.CancelShot = false;
					return;
				}
				customWeaponComponent.UpdateStoredFireRate();
				customWeaponComponent.ModifyFireRate();
			}
		}

		[HarmonyPatch(typeof(BWA_Burst), "OnStopFiring")]
		[HarmonyPatch(typeof(BWA_Auto), "OnStopFiring")]
		[HarmonyPatch(typeof(BulletWeaponArchetype), "OnStopFiring")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void StopFiringCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				customWeaponComponent.Invoke(StaticContext<WeaponPostStopFiringContext>.Instance);
			}
		}
	}
	[HarmonyPatch]
	internal static class WeaponPatches
	{
		private static uint s_lastSearchID = 0u;

		private static float s_origHitDamage = 0f;

		private static float s_origHitPrecision = 0f;

		private static readonly HitData s_hitData = new HitData();

		private static ContextController? _cachedHitCC = null;

		public static ContextController? CachedHitCC
		{
			get
			{
				return _cachedHitCC;
			}
			set
			{
				_cachedHitCC = value;
				CachedBypassTumorCap = false;
			}
		}

		public static bool CachedBypassTumorCap { get; private set; } = false;


		[HarmonyPatch(typeof(BulletWeapon), "OnGearSpawnComplete")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetupCallback(BulletWeapon __instance)
		{
			CustomWeaponManager.Current.AddWeaponListener((ItemEquippable)(object)__instance);
			CustomWeaponData customGunData = CustomWeaponManager.Current.GetCustomGunData(((GameDataBlockBase<ArchetypeDataBlock>)(object)((ItemEquippable)__instance).ArchetypeData).persistentID);
			if (customGunData != null && !((Object)(object)((Component)__instance).gameObject.GetComponent<CustomWeaponComponent>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<CustomWeaponComponent>().Register(customGunData);
			}
		}

		[HarmonyPatch(typeof(BulletWeapon), "OnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void UpdateCurrentWeapon(BulletWeapon __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponWieldContext>.Instance);
				component.RefreshSoundDelay();
				s_lastSearchID = 0u;
			}
		}

		[HarmonyPatch(typeof(BulletWeapon), "OnUnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void UpdateWeaponUnwielded(BulletWeapon __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponUnWieldContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(BulletWeapon), "BulletHit")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void HitCallback(ref WeaponHitData weaponRayData, bool doDamage, float additionalDis, uint damageSearchID, ref bool allowDirectionalBonus)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Invalid comparison between Unknown and I4
			CachedHitCC = null;
			if (!allowDirectionalBonus || weaponRayData.vfxBulletHit != null || !doDamage || (!((Agent)weaponRayData.owner).IsLocallyOwned && (!SNet.IsMaster || !weaponRayData.owner.Owner.IsBot)))
			{
				return;
			}
			s_hitData.Setup(weaponRayData, additionalDis);
			IDamageable damageable = s_hitData.damageable;
			IDamageable val = ((damageable != null) ? damageable.GetBaseDamagable() : damageable);
			if ((val != null && val.GetHealthRel() <= 0f) || (damageSearchID != 0 && val != null && val.TempSearchID == damageSearchID))
			{
				return;
			}
			ItemEquippable wieldedItem = s_hitData.owner.Inventory.WieldedItem;
			CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
			if ((Object)(object)customWeaponComponent == (Object)null)
			{
				Agent val2 = ((damageable != null) ? damageable.GetBaseAgent() : null);
				if ((Object)(object)val2 != (Object)null && (int)val2.Type == 1 && val2.Alive)
				{
					KillTrackerManager.ClearHit(((Il2CppObjectBase)val2).TryCast<EnemyAgent>());
				}
				return;
			}
			if (damageable != null && damageSearchID != 0)
			{
				if (s_lastSearchID != damageSearchID)
				{
					s_lastSearchID = damageSearchID;
					s_origHitDamage = s_hitData.damage;
					s_origHitPrecision = s_hitData.precisionMulti;
				}
				s_hitData.damage = s_origHitDamage;
				s_hitData.precisionMulti = s_origHitPrecision;
			}
			ApplyEWCHit(customWeaponComponent, s_hitData, damageSearchID != 0, ref s_origHitDamage, out allowDirectionalBonus);
		}

		public static void ApplyEWCHit(CustomWeaponComponent cwc, HitData hitData, bool pierce, ref float pierceDamage, out bool doBackstab, bool triggerHit = true)
		{
			ApplyEWCHit(cwc.GetContextController(), cwc.Weapon, hitData, pierce, ref pierceDamage, out doBackstab, triggerHit);
		}

		public static void ApplyEWCHit(ContextController cc, ItemEquippable weapon, HitData hitData, bool pierce, ref float pierceDamage, out bool doBackstab, bool triggerHit = true)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Invalid comparison between Unknown and I4
			//IL_00de: 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)
			doBackstab = true;
			CachedHitCC = cc;
			IDamageable damageable = hitData.damageable;
			if (damageable != null && damageable.GetBaseDamagable().GetHealthRel() > 0f)
			{
				if (triggerHit)
				{
					cc.Invoke(new WeaponPreHitDamageableContext(hitData, DamageType.Bullet));
				}
				WeaponDamageContext weaponDamageContext = new WeaponDamageContext(hitData.damage, hitData.precisionMulti, damageable);
				cc.Invoke(weaponDamageContext);
				hitData.damage = weaponDamageContext.Damage.Value;
				hitData.precisionMulti = weaponDamageContext.Precision.Value;
				CachedBypassTumorCap = weaponDamageContext.BypassTumorCap;
				if (pierce)
				{
					WeaponPierceContext weaponPierceContext = new WeaponPierceContext(pierceDamage, damageable);
					cc.Invoke(weaponPierceContext);
					pierceDamage = weaponPierceContext.Value;
				}
				Agent baseAgent = damageable.GetBaseAgent();
				if ((Object)(object)baseAgent != (Object)null && baseAgent.Alive && (int)baseAgent.Type == 1)
				{
					Dam_EnemyDamageLimb val = ((Il2CppObjectBase)damageable).Cast<Dam_EnemyDamageLimb>();
					float num = val.ApplyDamageFromBehindBonus(1f, hitData.hitPos, ((Vector3)(ref hitData.fireDir)).normalized, 1f);
					float num2 = num.Map(1f, 2f, 1f, cc.Invoke(new WeaponBackstabContext()).Value);
					WeaponHitDamageableContext weaponHitDamageableContext = new WeaponHitDamageableContext(hitData, CachedBypassTumorCap, num2, val, DamageType.Bullet);
					if (triggerHit)
					{
						cc.Invoke(weaponHitDamageableContext);
					}
					KillTrackerManager.RegisterHit(weapon, weaponHitDamageableContext);
					if (num2 > 1f)
					{
						hitData.damage *= num2 / num;
					}
					else
					{
						doBackstab = false;
					}
				}
				else if (triggerHit)
				{
					cc.Invoke(new WeaponHitDamageableContext(hitData, DamageType.Bullet));
				}
			}
			if (triggerHit)
			{
				cc.Invoke(new WeaponHitContext(hitData));
			}
			hitData.Apply();
		}
	}
	[HarmonyPatch]
	internal static class WeaponRayPatches
	{
		public static BulletWeapon? CachedWeapon = null;

		private static HitData s_hitData = new HitData();

		private static CustomWeaponComponent? _cachedCWC = null;

		private static IntPtr _cachedData = IntPtr.Zero;

		[HarmonyTargetMethod]
		private static MethodBase FindWeaponRayFunc(Harmony harmony)
		{
			return AccessTools.Method(typeof(Weapon), "CastWeaponRay", new Type[4]
			{
				typeof(Transform),
				typeof(WeaponHitData).MakeByRefType(),
				typeof(Vector3),
				typeof(int)
			}, (Type[])null);
		}

		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void PreRayCallback(ref WeaponHitData weaponRayData, Vector3 originPos, int altRayCastMask)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if (altRayCastMask != -1 || _cachedData == ((Il2CppObjectBase)weaponRayData).Pointer)
			{
				return;
			}
			_cachedData = ((Il2CppObjectBase)weaponRayData).Pointer;
			if ((Object)(object)CachedWeapon != (Object)null)
			{
				_cachedCWC = ((Component)CachedWeapon).GetComponent<CustomWeaponComponent>();
			}
			else
			{
				PlayerAgent owner = weaponRayData.owner;
				object cachedCWC;
				if (owner == null)
				{
					cachedCWC = null;
				}
				else
				{
					ItemEquippable wieldedItem = owner.Inventory.WieldedItem;
					cachedCWC = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
				}
				_cachedCWC = (CustomWeaponComponent?)cachedCWC;
			}
			if (!((Object)(object)_cachedCWC == (Object)null))
			{
				s_hitData.Setup(weaponRayData);
				_cachedCWC.Invoke(new WeaponPreRayContext(s_hitData, originPos));
				s_hitData.Apply();
			}
		}

		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostRayCallback(ref WeaponHitData weaponRayData, Vector3 originPos, int altRayCastMask, ref bool __result)
		{
			//IL_0029: 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)
			if (!((Object)(object)_cachedCWC == (Object)null))
			{
				s_hitData.Setup(weaponRayData);
				if (!_cachedCWC.Invoke(new WeaponCancelRayContext(s_hitData, originPos)).Result)
				{
					__result = false;
					return;
				}
				__result = _cachedCWC.Invoke(new WeaponPostRayContext(s_hitData, originPos, __result, (IntPtr)0)).Result;
				s_hitData.Apply();
				_cachedCWC = null;
			}
		}
	}
	[HarmonyPatch]
	internal static class WeaponRecoilPatches
	{
		private static BulletWeapon? _cachedWeapon;

		private static CustomWeaponComponent? _cachedComponent;

		[HarmonyPatch(typeof(BulletWeapon), "OnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void UpdateCurrentWeapon(BulletWeapon __instance)
		{
			PlayerAgent owner = ((Item)__instance).Owner;
			if (owner != null && ((Agent)owner).IsLocallyOwned)
			{
				_cachedWeapon = __instance;
				_cachedComponent = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			}
		}

		[HarmonyAfter(new string[] { "Dinorush.ExtraRecoilData" })]
		[HarmonyPatch(typeof(FPS_RecoilSystem), "ApplyRecoil")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostApplyRecoilCallback(FPS_RecoilSystem __instance, bool resetSimilarity, RecoilDataBlock recoilData)
		{
			//IL_0031: 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_0066: 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_0075: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_cachedComponent == (Object)null))
			{
				WeaponRecoilContext weaponRecoilContext = new WeaponRecoilContext();
				_cachedComponent.Invoke(weaponRecoilContext);
				if (weaponRecoilContext.Value != 1f)
				{
					Vector2 val = default(Vector2);
					((Vector2)(ref val))..ctor(__instance.recoilDir.x * (weaponRecoilContext.Value - 1f), __instance.recoilDir.y * (weaponRecoilContext.Value - 1f));
					Vector2 currentRecoilForce = __instance.currentRecoilForce;
					currentRecoilForce.x -= val.x * (1f - recoilData.worldToViewSpaceBlendVertical);
					currentRecoilForce.y -= val.y * (1f - recoilData.worldToViewSpaceBlendHorizontal);
					Vector2 currentRecoilForceVP = __instance.currentRecoilForceVP;
					currentRecoilForceVP.x -= val.x * recoilData.worldToViewSpaceBlendVertical;
					currentRecoilForceVP.y -= val.y * recoilData.worldToViewSpaceBlendHorizontal;
					Vector2 recoilDir = __instance.recoilDir;
					((Vector2)(ref recoilDir)).Set(__instance.recoilDir.x * weaponRecoilContext.Value, __instance.recoilDir.y * weaponRecoilContext.Value);
					__instance.currentRecoilForce = currentRecoilForce;
					__instance.currentRecoilForceVP = currentRecoilForceVP;
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class WeaponSyncPatches
	{
		[HarmonyPatch(typeof(BulletWeaponSynced), "OnGearSpawnComplete")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_SetupSynced(BulletWeaponSynced __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.SetToSync();
			}
		}

		[HarmonyPatch(typeof(ShotgunSynced), "Fire")]
		[HarmonyPatch(typeof(BulletWeaponSynced), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void Pre_FireSynced(BulletWeaponSynced __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponPreFireContextSync>.Instance);
			}
		}

		[HarmonyPatch(typeof(ShotgunSynced), "Fire")]
		[HarmonyPatch(typeof(BulletWeaponSynced), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_FireSynced(BulletWeaponSynced __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.UpdateStoredFireRate();
				component.ModifyFireRateSynced(__instance);
				component.Invoke(StaticContext<WeaponPostFireContextSync>.Instance);
			}
		}
	}
	[HarmonyPatch]
	internal static class PlayerLocalPatches
	{
		[HarmonyPatch(typeof(PUI_LocalPlayerStatus), "UpdateHealth")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void UpdateHealth(PUI_LocalPlayerStatus __instance, float health, bool meleeBuffActive)
		{
			if (__instance.m_lastHealthVal <= 0.14f && health > 0.14f && __instance.m_warningRoutine != null)
			{
				__instance.m_healthWarningLooping = true;
			}
		}
	}
}
namespace EWC.Patches.Native
{
	internal static class EnemyDetectionPatches
	{
		private unsafe delegate void d_DetectOnNoise(IntPtr _this, IntPtr agentTarget, float movementDetectionDistance, float shootDetectionDistance, float delta, out float output, Il2CppMethodInfo* methodInfo);

		private struct CWCHolder
		{
			public CustomWeaponComponent? primary;

			public bool hasPrimary;

			public CustomWeaponComponent? special;

			public bool hasSpecial;

			public readonly bool IsValid
			{
				get
				{
					if ((Object)(object)primary != (Object)null == hasPrimary)
					{
						return (Object)(object)special != (Object)null == hasSpecial;
					}
					return false;
				}
			}
		}

		private static INativeDetour? DetectOnNoiseDetour;

		private static d_DetectOnNoise? orig_DetectOnNoise;

		private static readonly Dictionary<int, CWCHolder> s_cachedCWCs = new Dictionary<int, CWCHolder>();

		internal unsafe static void ApplyNativePatch()
		{
			DetectOnNoiseDetour = INativeDetour.CreateAndApply<d_DetectOnNoise>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<EnemyDetection>("DetectOnNoiseDistance_Conditional_AnimatedWindow", typeof(void).Name, false, new string[5]
			{
				"AgentTarget",
				typeof(float).Name,
				typeof(float).Name,
				typeof(float).Name,
				typeof(float).MakeByRefType().Name
			}), (d_DetectOnNoise)DetectOnNoisePatch, ref orig_DetectOnNoise);
			NativePatchAPI.AddDetectPostfix(Post_DetectAgentNoise);
		}

		private unsafe static void DetectOnNoisePatch(IntPtr _this, IntPtr agentTarget, float movementDetectionDistance, float shootDetectionDistance, float delta, out float output, Il2CppMethodInfo* methodInfo)
		{
			//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)
			//IL_0015: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0044: Expected O, but got Unknown
			output = 0f;
			EnemyDetection val = new EnemyDetection(_this);
			AgentTarget agentTarget2 = new AgentTarget(agentTarget);
			if (NativePatchAPI.RunDetectPrefix(val, agentTarget2, movementDetectionDistance, shootDetectionDistance, delta, ref output))
			{
				orig_DetectOnNoise(_this, agentTarget, movementDetectionDistance, shootDetectionDistance, delta, out output, methodInfo);
			}
			NativePatchAPI.RunDetectPostfix(val, agentTarget2, movementDetectionDistance, shootDetectionDistance, delta, ref output);
		}

		private static void UpdateCache()
		{
			if (s_cachedCWCs.Count == PlayerManager.PlayerAgentsInLevel.Count && !s_cachedCWCs.Values.Any((CWCHolder holder) => !holder.IsValid))
			{
				return;
			}
			s_cachedCWCs.Clear();
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			PlayerBackpack val = default(PlayerBackpack);
			BackpackItem val2 = default(BackpackItem);
			BackpackItem val3 = default(BackpackItem);
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (PlayerBackpackManager.TryGetBackpack(current.Owner, ref val) && val.TryGetBackpackItem((InventorySlot)1, ref val2) && val.TryGetBackpackItem((InventorySlot)2, ref val3))
				{
					Item instance = val2.Instance;
					CustomWeaponComponent customWeaponComponent = ((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null);
					Item instance2 = val3.Instance;
					CustomWeaponComponent customWeaponComponent2 = ((instance2 != null) ? ((Component)instance2).GetComponent<CustomWeaponComponent>() : null);
					s_cachedCWCs.Add(((Agent)current).GlobalID, new CWCHolder
					{
						primary = customWeaponComponent,
						hasPrimary = ((Object)(object)customWeaponComponent != (Object)null),
						special = customWeaponComponent2,
						hasSpecial = ((Object)(object)customWeaponComponent2 != (Object)null)
					});
				}
			}
		}

		private static void Post_DetectAgentNoise(EnemyDetection __instance, AgentTarget agentTarget, float _mv, float _wp, float _delta, ref float output)
		{
			UpdateCache();
			if (s_cachedCWCs.TryGetValue(agentTarget.m_globalID, out var value) && (value.hasPrimary || value.hasSpecial))
			{
				WeaponStealthUpdateContext weaponStealthUpdateContext = new WeaponStealthUpdateContext(__instance.m_ai.m_enemyAgent, __instance.m_noiseDetectionOn, output);
				value.primary?.Invoke(weaponStealthUpdateContext);
				value.special?.Invoke(weaponStealthUpdateContext);
				output = weaponStealthUpdateContext.Output;
			}
		}
	}
}
namespace EWC.Patches.Melee
{
	[HarmonyPatch]
	internal static class MeleePatches
	{
		private static readonly HitData s_hitData = new HitData();

		private static float s_origHitDamage = 0f;

		private static float s_origHitPrecision = 0f;

		public static float CachedCharge { get; private set; } = 0f;


		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "SetupMeleeAnimations")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetupCallback(MeleeWeaponFirstPerson __instance)
		{
			CachedCharge = 0f;
			CustomWeaponManager.Current.AddWeaponListener((ItemEquippable)(object)__instance);
			CustomWeaponData customMeleeData = CustomWeaponManager.Current.GetCustomMeleeData(((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)((ItemEquippable)__instance).MeleeArchetypeData).persistentID);
			if (customMeleeData != null && !((Object)(object)((Component)__instance).gameObject.GetComponent<CustomWeaponComponent>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<CustomWeaponComponent>().Register(customMeleeData);
			}
		}

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "OnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void UpdateCurrentWeapon(MeleeWeaponFirstPerson __instance)
		{
			CachedCharge = 0f;
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponWieldContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "OnUnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ClearCharge(MeleeWeaponFirstPerson __instance)
		{
			CachedCharge = 0f;
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponUnWieldContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "SetNextDamageToDeal")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetDamageCallback(MeleeWeaponFirstPerson __instance, eMeleeWeaponDamage dam, float scale)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			s_origHitDamage = __instance.m_damageToDeal;
			s_origHitPrecision = __instance.m_precisionMultiToDeal;
			CachedCharge = (((int)dam == 2) ? ((float)Math.Cbrt(scale)) : 0f);
		}

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "DoAttackDamage")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void HitCallback(MeleeWeaponFirstPerson __instance, MeleeWeaponDamageData data, bool isPush)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Invalid comparison between Unknown and I4
			if (isPush)
			{
				return;
			}
			s_hitData.Setup(__instance, data);
			IDamageable damageable = s_hitData.damageable;
			IDamageable val = ((damageable != null) ? damageable.GetBaseDamagable() : null);
			if (val != null && val.GetHealthRel() <= 0f)
			{
				return;
			}
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if ((Object)(object)component == (Object)null)
			{
				Agent val2 = ((damageable != null) ? damageable.GetBaseAgent() : null);
				if ((Object)(object)val2 != (Object)null && (int)val2.Type == 1 && val2.Alive)
				{
					KillTrackerManager.ClearHit(((Il2CppObjectBase)val2).TryCast<EnemyAgent>());
				}
				WeaponPatches.CachedHitCC = null;
			}
			else
			{
				s_hitData.damage = s_origHitDamage;
				s_hitData.precisionMulti = s_origHitPrecision;
				WeaponPatches.ApplyEWCHit(component, s_hitData, pierce: false, ref s_origHitDamage, out var _);
			}
		}
	}
	[HarmonyPatch]
	internal static class MWSPatches
	{
		[HarmonyPatch(typeof(MWS_ChargeUp), "Enter")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ChargeCallback(MWS_ChargeUp __instance)
		{
			CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				WeaponFireRateContext weaponFireRateContext = new WeaponFireRateContext(1f);
				component.Invoke(weaponFireRateContext);
				__instance.m_maxDamageTime /= weaponFireRateContext.Value;
			}
		}

		[HarmonyPatch(typeof(MWS_Push), "Enter")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PushCallback(MWS_Push __instance)
		{
			CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				WeaponFireRateContext weaponFireRateContext = new WeaponFireRateContext(1f);
				component.Invoke(weaponFireRateContext);
				Animator weaponAnimator = ((MWS_Base)__instance).m_weapon.WeaponAnimator;
				weaponAnimator.speed *= weaponFireRateContext.Value;
			}
		}

		[HarmonyPatch(typeof(MWS_AttackSwingBase), "Enter")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PreSwingCallback(MWS_AttackSwingBase __instance)
		{
			CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponPreFireContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(MWS_AttackSwingBase), "Exit")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostSwingCallback(MWS_AttackSwingBase __instance)
		{
			CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponPostFireContext>.Instance);
			}
		}
	}
}
namespace EWC.Networking
{
	public abstract class SyncedEvent<T> where T : struct
	{
		public delegate void ReceiveHandler(T packet);

		private bool _isSetup;

		public abstract string GUID { get; }

		public bool IsSetup => _isSetup;

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


		public event ReceiveHandler? OnReceive;

		public event ReceiveHandler? OnReceiveLocal;

		public void Setup()
		{
			if (!_isSetup)
			{
				EventName = "EWC" + GUID;
				NetworkAPI.RegisterEvent<T>(EventName, (Action<ulong, T>)ReceiveClient_Callback);
				_isSetup = true;
			}
		}

		public void Send(T packetData, SNet_Player? target = null, SNet_ChannelType priority = 4)
		{
			//IL_0020: 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)
			if ((Object)(object)target != (Object)null)
			{
				NetworkAPI.InvokeEvent<T>(EventName, packetData, target, priority);
			}
			else
			{
				NetworkAPI.InvokeEvent<T>(EventName, packetData, priority);
			}
			ReceiveLocal_Callback(packetData);
		}

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

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

		protected virtual void ReceiveLocal(T packet)
		{
		}

		protected virtual void Receive(T packet)
		{
		}
	}
	public abstract class SyncedEventMasterOnly<T> : SyncedEvent<T> where T : struct
	{
		public void Send(T packet, SNet_ChannelType priority = 4)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster)
			{
				Send(packet, SNet.Master, priority);
			}
			else
			{
				Receive(packet);
			}
		}
	}
}
namespace EWC.Networking.Structs
{
	public struct LowResColor
	{
		public byte r;

		public byte g;

		public byte b;

		public byte a;

		private static Color s_color = Color.black;

		public static implicit operator Color(LowResColor lowResColor)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			s_color.r = (float)(int)lowResColor.r / 255f;
			s_color.g = (float)(int)lowResColor.g / 255f;
			s_color.b = (float)(int)lowResColor.b / 255f;
			s_color.a = (float)(int)lowResColor.a / 255f;
			return s_color;
		}

		public static implicit operator LowResColor(Color color)
		{
			//IL_000a: 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_0032: 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)
			LowResColor result = default(LowResColor);
			result.r = (byte)(color.r * 255f);
			result.g = (byte)(color.g * 255f);
			result.b = (byte)(color.b * 255f);
			result.a = (byte)(color.a * 255f);
			return result;
		}
	}
}
namespace EWC.JSON
{
	internal static class CustomWeaponTemplate
	{
		internal static CustomWeaponData CreateTemplate()
		{
			return new CustomWeaponData
			{
				ArchetypeID = 0u,
				Name = "Example",
				Properties = new PropertyList(new List<WeaponPropertyBase>
				{
					new ReferenceProperty(),
					new AmmoMod(),
					new AmmoRegen(),
					new DamageMod(),
					new DamageModPerTarget(),
					new DamageOverTime(),
					new Explosive(),
					new FireRateMod(),
					new FireShot(),
					new HealthMod(),
					new RecoilM

plugins/net6/AccurateCrosshair.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using AccurateCrosshair.CrosshairPatches;
using AccurateCrosshair.PluginDependencies;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using ColorCrosshair.API;
using GTFO.API;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
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("AccurateCrosshair")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AccurateCrosshair")]
[assembly: AssemblyTitle("AccurateCrosshair")]
[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 AccurateCrosshair
{
	public static class Configuration
	{
		public static bool followsRecoil = true;

		public static FirstShotType firstShotType = FirstShotType.Inner;

		public static float firstShotMinDelay = 0.15f;

		public static bool popEnabled = false;

		public static float minSize = 10f;

		public static float speedScalar = 1f;

		public static void CreateAndBindAll()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			BindAll(new ConfigFile(Path.Combine(Paths.ConfigPath, "AccurateCrosshair.cfg"), true));
		}

		private static void BindAll(ConfigFile config)
		{
			BindCrosshairPopEnabled(config);
		}

		private static void BindCrosshairPopEnabled(ConfigFile config)
		{
			//IL_0015: 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_0030: Expected O, but got Unknown
			//IL_0030: Expected O, but got Unknown
			//IL_0049: 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_0064: Expected O, but got Unknown
			//IL_0064: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_0098: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00cc: Expected O, but got Unknown
			//IL_00e5: 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_0100: Expected O, but got Unknown
			//IL_0100: Expected O, but got Unknown
			//IL_0119: 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_0134: Expected O, but got Unknown
			//IL_0134: Expected O, but got Unknown
			string text = "General Settings";
			string text2 = "Follow Recoil";
			string text3 = "Enables or disables the crosshair moving to match weapon recoil that is independent of your aim.";
			followsRecoil = config.Bind<bool>(new ConfigDefinition(text, text2), followsRecoil, new ConfigDescription(text3, (AcceptableValueBase)null, Array.Empty<object>())).Value;
			text2 = "First Shot Display Mode";
			text3 = "Determines how the crosshair shows the hidden bonus accuracy after waiting 2 seconds to shoot.\r\nInner: Shows another circle. Match: Reduces crosshair size to match. None: Turns this off.";
			firstShotType = config.Bind<FirstShotType>(new ConfigDefinition(text, text2), firstShotType, new ConfigDescription(text3, (AcceptableValueBase)null, Array.Empty<object>())).Value;
			text2 = "First Shot Min Delay";
			text3 = "If First Shot Display Mode is set to Match, the minimum shot delay non-semi automatic weapons need for the first shot effect to appear.";
			firstShotMinDelay = config.Bind<float>(new ConfigDefinition(text, text2), firstShotMinDelay, new ConfigDescription(text3, (AcceptableValueBase)null, Array.Empty<object>())).Value;
			text2 = "Pop Enabled";
			text3 = "Enables or disables the visual crosshair bloom when shooting.\r\nNote: Pop is not scaled to the accurate size and may be disproportionately large.";
			popEnabled = config.Bind<bool>(new ConfigDefinition(text, text2), popEnabled, new ConfigDescription(text3, (AcceptableValueBase)null, Array.Empty<object>())).Value;
			text2 = "Minimum Size";
			text3 = "The minimum size of the reticle. Does not scale with field of view.\r\nNote: Cannot be smaller than 10.";
			minSize = config.Bind<float>(new ConfigDefinition(text, text2), minSize, new ConfigDescription(text3, (AcceptableValueBase)null, Array.Empty<object>())).Value;
			text2 = "Resize Modifier";
			text3 = "Scalar applied to the speed at which the crosshair resizes to its target spread.\r\nNote: Must be larger than 0. Does not affect the resize speed of pop.";
			speedScalar = config.Bind<float>(new ConfigDefinition(text, text2), speedScalar, new ConfigDescription(text3, (AcceptableValueBase)null, Array.Empty<object>())).Value;
			if (speedScalar <= 0f)
			{
				speedScalar = 1f;
			}
		}
	}
	[BepInPlugin("Dinorush.AccurateCrosshair", "AccurateCrosshair", "1.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class Loader : BasePlugin
	{
		public const string MODNAME = "AccurateCrosshair";

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

		public override void Load()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			((BasePlugin)this).Log.LogMessage((object)"Loading AccurateCrosshair");
			Configuration.CreateAndBindAll();
			Harmony val = new Harmony("AccurateCrosshair");
			val.PatchAll(typeof(SpreadPatches));
			if (!Configuration.popEnabled)
			{
				val.PatchAll(typeof(PopPatches));
			}
			if (Configuration.followsRecoil)
			{
				val.PatchAll(typeof(RecoilPatches));
			}
			if (Configuration.firstShotType != 0)
			{
				val.PatchAll(typeof(FirstShotPatches));
			}
			if (Configuration.firstShotType == FirstShotType.Inner)
			{
				val.PatchAll(typeof(FirstShotGuiPatches));
			}
			AssetAPI.OnStartupAssetsLoaded += AssetAPI_OnStartupAssetsLoaded;
			((BasePlugin)this).Log.LogMessage((object)"Loaded AccurateCrosshair");
		}

		private void AssetAPI_OnStartupAssetsLoaded()
		{
			ColorCrosshairDependency.Init();
		}
	}
}
namespace AccurateCrosshair.PluginDependencies
{
	internal static class ColorCrosshairDependency
	{
		public static bool HasColorCrosshair => ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("Dinorush.ColorCrosshair");

		public static Color DefaultColor => ColorCrosshairAPI.DefaultColor;

		public static Color ChargeColor => ColorCrosshairAPI.ChargeColor;

		public static Color ChargeBlinkColor => ColorCrosshairAPI.ChargeBlinkColor;

		public static Color ChargeWarningColor => ColorCrosshairAPI.ChargeWarningColor;

		public static Color EnemyBlinkColor => ColorCrosshairAPI.EnemyBlinkColor;

		public static void Init()
		{
			if (HasColorCrosshair && Configuration.firstShotType == FirstShotType.Inner)
			{
				UnsafeInit();
			}
		}

		private static void UnsafeInit()
		{
			FirstShotGuiPatches.RefreshCrosshairColor();
			ColorCrosshairAPI.OnReload += ApplyColorChanges;
		}

		private static void ApplyColorChanges()
		{
			FirstShotGuiPatches.RefreshCrosshairColor();
		}
	}
}
namespace AccurateCrosshair.CrosshairPatches
{
	internal sealed class FirstShotGui : GuiLayer
	{
		private CircleCrosshair? smallCrosshair;

		public override void OnLevelCleanup()
		{
			CircleCrosshair? obj = smallCrosshair;
			if (obj != null)
			{
				((GuiLayerComp)obj).SetVisible(false, false);
			}
		}

		public override void Setup(Transform root, string name)
		{
			//IL_0011: 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)
			((GuiLayer)this).Setup(root, name);
			GuiLayerComp val = ((GuiLayer)this).AddComp("Gui/Crosshairs/CanvasCircleCrosshair", (GuiAnchor)3, default(Vector2), (Transform)null);
			smallCrosshair = ((Il2CppObjectBase)val).TryCast<CircleCrosshair>();
			if ((Object)(object)smallCrosshair != (Object)null)
			{
				smallCrosshair.UpdateAlphaMul(CellSettingsManager.SettingsData.HUD.Player_CrosshairOpacity.Value);
				RefreshColor();
				((GuiLayerComp)smallCrosshair).SetVisible(false, false);
			}
		}

		public void Disable()
		{
			CircleCrosshair? obj = smallCrosshair;
			if (obj != null)
			{
				((GuiLayerComp)obj).SetVisible(false, false);
			}
		}

		public void Enable(float size)
		{
			if (!((Object)(object)smallCrosshair == (Object)null) && !(size < 0f) && !(size <= Configuration.minSize))
			{
				float num = Math.Max(size * 0.2f, Configuration.minSize);
				((GuiLayerComp)smallCrosshair).SetVisible(true, false);
				smallCrosshair.SetScale(num / smallCrosshair.m_circleRadius);
			}
		}

		public void RefreshAlpha()
		{
			CircleCrosshair? obj = smallCrosshair;
			if (obj != null)
			{
				obj.UpdateAlphaMul(CellSettingsManager.SettingsData.HUD.Player_CrosshairOpacity.Value);
			}
		}

		public void RefreshColor()
		{
			//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_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)smallCrosshair == (Object)null) && ColorCrosshairDependency.HasColorCrosshair)
			{
				CircleCrosshair? obj = smallCrosshair;
				Color color = (smallCrosshair.m_crosshairColOrg = ColorCrosshairDependency.DefaultColor);
				obj.SetColor(color);
			}
		}
	}
	internal static class FirstShotGuiPatches
	{
		public static FirstShotGui crosshairGui = new FirstShotGui();

		public static void Disable()
		{
			crosshairGui.Disable();
		}

		public static void Enable(float size, bool forceOn = false)
		{
			if (forceOn || ((GuiLayerComp)GuiManager.CrosshairLayer.m_circleCrosshair).GetVisible())
			{
				crosshairGui.Enable(size);
			}
		}

		public static void RefreshCrosshairColor()
		{
			crosshairGui.RefreshColor();
		}

		[HarmonyPatch(typeof(GuiManager), "Setup")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetupSmallCrosshair(GuiManager __instance)
		{
			((GuiLayer)crosshairGui).Setup(__instance.m_root, "SmallCrosshairLayer");
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "OnSetVisible")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void MatchLayerVisibility(CrosshairGuiLayer __instance, bool visible)
		{
			((GuiLayer)crosshairGui).SetVisible(visible);
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "HideCircleCrosshair")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void MatchCrosshairVisibility(CrosshairGuiLayer __instance)
		{
			crosshairGui.Disable();
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "UpdateAlphaFromSettings")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void MatchCrosshairAlpha(CrosshairGuiLayer __instance)
		{
			crosshairGui.RefreshAlpha();
		}
	}
	internal static class FirstShotPatches
	{
		private static Coroutine? firstShotRoutine = null;

		private static float firstShotTime = 0f;

		private static float fireRecoilCooldown = 2f;

		private static float storedCrosshairSize = -1f;

		private static void EnableSmallCrosshair(bool forceGuiOn = false)
		{
			if (Configuration.firstShotType == FirstShotType.Match)
			{
				SpreadPatches.SetCrosshairSize(storedCrosshairSize * 0.2f);
			}
			else if (Configuration.firstShotType == FirstShotType.Inner)
			{
				FirstShotGuiPatches.Enable(storedCrosshairSize, forceGuiOn);
			}
		}

		private static IEnumerator MinimizeAfterDelay()
		{
			while (firstShotTime > Clock.Time)
			{
				yield return (object)new WaitForSeconds(firstShotTime - Clock.Time);
			}
			firstShotRoutine = null;
			if (!(storedCrosshairSize < 0f))
			{
				EnableSmallCrosshair();
			}
		}

		public static void SetStoredCrosshair(BulletWeapon weapon, ref float crosshairSize)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			ArchetypeDataBlock archetypeData = ((ItemEquippable)weapon).ArchetypeData;
			if (Configuration.firstShotType == FirstShotType.Match && (int)archetypeData.FireMode != 0 && archetypeData.ShotDelay < Configuration.firstShotMinDelay)
			{
				return;
			}
			storedCrosshairSize = crosshairSize;
			fireRecoilCooldown = weapon.m_fireRecoilCooldown;
			firstShotTime = weapon.m_lastFireTime + fireRecoilCooldown;
			if (firstShotTime > Clock.Time)
			{
				if (firstShotRoutine == null)
				{
					firstShotRoutine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(MinimizeAfterDelay()), (Action)null);
				}
				return;
			}
			if (Configuration.firstShotType == FirstShotType.Match)
			{
				crosshairSize = Math.Max(crosshairSize * 0.2f, Configuration.minSize);
			}
			EnableSmallCrosshair(forceGuiOn: true);
		}

		public static void ResetStoredCrosshair()
		{
			storedCrosshairSize = -1f;
			FirstShotGuiPatches.Disable();
		}

		[HarmonyPatch(typeof(BulletWeapon), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ResetFirstShotTimer(BulletWeapon __instance)
		{
			firstShotTime = Clock.Time + fireRecoilCooldown;
			SpreadPatches.SetCrosshairSize(storedCrosshairSize);
			FirstShotGuiPatches.Disable();
			if (firstShotRoutine == null)
			{
				firstShotRoutine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(MinimizeAfterDelay()), (Action)null);
			}
		}
	}
	public enum FirstShotType
	{
		None,
		Match,
		Inner
	}
	internal static class PopPatches
	{
		[HarmonyPatch(typeof(CrosshairGuiLayer), "PopCircleCrosshair")]
		[HarmonyPrefix]
		public static bool CancelRecoilPop(CrosshairGuiLayer __instance, float pop, float sizeMax)
		{
			return false;
		}
	}
	internal static class RecoilPatches
	{
		[HarmonyPatch(typeof(CrosshairGuiLayer), "ShowSpreadCircle")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void EnableCrosshairMovement(CrosshairGuiLayer __instance, ref float crosshairSize)
		{
			__instance.m_moveCircleCrosshair = !SpreadPatches.isShotgun;
		}

		[HarmonyPatch(typeof(FPS_RecoilSystem), "FPS_Update")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void TightCrosshairMovement(FPS_RecoilSystem __instance)
		{
			//IL_0011: 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_0025: 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_0040: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			float scale = GuiManager.CrosshairLayer.m_circleCrosshair.GetScale();
			Vector2 val = __instance.CurrentVSPos - new Vector2(0.5f, 0.5f);
			val.y *= 0.78f;
			GuiManager.CrosshairLayer.SetCrosshairPosition(val / scale + new Vector2(0.5f, 0.5f));
		}
	}
	internal static class SpreadPatches
	{
		private const float BASE_CROSSHAIR_SIZE = 20f;

		private const float EXTRA_BUFFER_SIZE = 10f;

		public static bool isShotgun;

		public static void SetCrosshairSize(float crosshairSize)
		{
			if (Configuration.firstShotType == FirstShotType.Match && !(crosshairSize < 0f))
			{
				crosshairSize = Math.Max(Configuration.minSize, crosshairSize);
				CrosshairGuiLayer crosshairLayer = GuiManager.CrosshairLayer;
				float num2 = (GuiManager.CrosshairLayer.m_neutralCircleSize = crosshairSize);
				crosshairLayer.ScaleToSize(num2);
			}
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "ShowSpreadCircle")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void AdjustCrosshairSize(CrosshairGuiLayer __instance, ref float crosshairSize)
		{
			if (Configuration.firstShotType != 0)
			{
				FirstShotPatches.ResetStoredCrosshair();
			}
			BulletWeapon val = ((Il2CppObjectBase)PlayerManager.GetLocalPlayerAgent().Inventory.m_wieldedItem).TryCast<BulletWeapon>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			isShotgun = (Object)(object)((Il2CppObjectBase)val).TryCast<Shotgun>() != (Object)null;
			float num = CellSettingsManager.SettingsData.Video.Fov.Value;
			ArchetypeDataBlock archetypeData = ((ItemEquippable)val).ArchetypeData;
			if (archetypeData != null)
			{
				float num2 = (float)(20.0 / Math.Tan(Math.PI / 180.0 * (double)num / 2.0));
				float num3 = (isShotgun ? ((float)(archetypeData.ShotgunConeSize + archetypeData.ShotgunBulletSpread)) : archetypeData.HipFireSpread);
				float num4 = Math.Max(Configuration.minSize, num3 * num2 + 10f);
				crosshairSize = num4;
				if (!isShotgun && Configuration.firstShotType != 0)
				{
					FirstShotPatches.SetStoredCrosshair(val, ref crosshairSize);
				}
			}
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "Setup")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void AdjustResizeSpeed(CrosshairGuiLayer __instance)
		{
			__instance.m_circleSpeed *= Configuration.speedScalar;
		}
	}
}

plugins/net6/CleanerRundownMenu.dll

Decompiled a week ago
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 BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using GTFO.API.JSON;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("CleanerRundownMenu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CleanerRundownMenu")]
[assembly: AssemblyTitle("CleanerRundownMenu")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CleanerRundownMenu;

[BepInPlugin("com.Untilted.CleanerRundownMenu", "CleanerRundownMenu", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Loader : BasePlugin
{
	public const string MODNAME = "CleanerRundownMenu";

	public const string AUTHOR = "Untilted";

	public const string GUID = "com.Untilted.CleanerRundownMenu";

	public const string VERSION = "1.0.0";

	public static ManualLogSource Logger;

	public override void Load()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		Logger = ((BasePlugin)this).Log;
		((BasePlugin)this).Log.LogMessage((object)"Loading CleanerRundownMenu");
		new Harmony("CleanerRundownMenu").PatchAll(typeof(MenuPatches));
		((BasePlugin)this).Log.LogMessage((object)"Loaded CleanerRundownMenu");
	}
}
public class MenuData : VPersistentData<MenuData>
{
	[JsonIgnore]
	public override string PersistentDataVersion { get; set; } = "1.0.0";


	public bool ShowVanityDrops { get; set; }

	public bool ShowSectorSummary { get; set; }

	public bool ShowIntel { get; set; }

	public MenuData()
	{
		ShowVanityDrops = false;
		ShowSectorSummary = true;
		ShowIntel = true;
	}
}
internal class MenuPatches
{
	[HarmonyPatch(typeof(CM_PageRundown_New), "PlaceRundown")]
	[HarmonyPostfix]
	public static void PlaceRundown()
	{
		//IL_0021: 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_004a: 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_007f: 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_00b4: 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 (!VPersistentData<MenuData>.CurrentData.ShowVanityDrops)
		{
			Transform transform = ((Component)MainMenuGuiLayer.Current.PageRundownNew.m_buttonVanityItemDrops).transform;
			transform.position *= 20f;
			Transform transform2 = ((Component)MainMenuGuiLayer.Current.PageRundownNew.m_vanityItemDropsNext).transform;
			transform2.position *= 20f;
		}
		if (!VPersistentData<MenuData>.CurrentData.ShowSectorSummary)
		{
			Transform transform3 = ((Component)MainMenuGuiLayer.Current.PageRundownNew.m_tierMarkerSectorSummary).transform;
			transform3.position *= 20f;
		}
		if (!VPersistentData<MenuData>.CurrentData.ShowIntel)
		{
			Transform transform4 = ((Component)MainMenuGuiLayer.Current.PageRundownNew.m_rundownIntelButton).transform;
			transform4.position *= 20f;
		}
	}
}
public class VPersistentData<T> where T : VPersistentData<T>, new()
{
	private const string VERSION_REGEX = "\"PersistentDataVersion\": \"(.+?)\"";

	private static T s_CurrentData;

	private static readonly string s_fullPath = GetFullPath();

	public static T CurrentData
	{
		get
		{
			if (s_CurrentData != null)
			{
				return s_CurrentData;
			}
			s_CurrentData = Load();
			return s_CurrentData;
		}
		set
		{
			s_CurrentData = value;
		}
	}

	protected static string persistentPath => Path.Combine("PersistentData", typeof(T).Assembly.GetName().Name, typeof(T).Name + ".json");

	public virtual string PersistentDataVersion { get; set; } = "1.0.0";


	[JsonIgnore]
	public bool LoadingFailed { get; private set; }

	private static string GetFullPath()
	{
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Expected O, but got Unknown
		string TPersistentPath = persistentPath;
		PropertyInfo property = typeof(T).GetProperty("persistentPath", BindingFlags.Static | BindingFlags.NonPublic);
		if (property != null)
		{
			TPersistentPath = (string)property.GetValue(null, null);
		}
		if (Path.IsPathFullyQualified(TPersistentPath))
		{
			return TPersistentPath;
		}
		string fileName = Path.GetFileName(TPersistentPath);
		string text = Directory.GetFiles(Paths.PluginPath, fileName, SearchOption.AllDirectories).FirstOrDefault((string f) => f.EndsWith(TPersistentPath));
		if (string.IsNullOrEmpty(text))
		{
			ManualLogSource logger = Loader.Logger;
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(32, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Couldn't find existing data for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeof(T).Name);
			}
			logger.LogDebug(val);
			return Path.Combine(Paths.PluginPath, TPersistentPath);
		}
		return text;
	}

	public static T Load()
	{
		return Load(s_fullPath);
	}

	public static T Load(string path)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Expected O, but got Unknown
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Expected O, but got Unknown
		ManualLogSource logger = Loader.Logger;
		bool flag = default(bool);
		BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(14, 2, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loading ");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeof(T).Name);
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" from ");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(path);
		}
		logger.LogDebug(val);
		T val2 = new T();
		if (File.Exists(path))
		{
			string text = File.ReadAllText(path);
			string text2 = "1.0.0";
			Match match = Regex.Match(text, "\"PersistentDataVersion\": \"(.+?)\"");
			if (match.Success)
			{
				text2 = match.Groups[1].Value ?? "";
			}
			if (text2 != val2.PersistentDataVersion)
			{
				ManualLogSource logger2 = Loader.Logger;
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(48, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(typeof(T).Name);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" PersistentDataVersion mismatch: expected ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(val2.PersistentDataVersion);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", got ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text2);
				}
				logger2.LogWarning(val3);
				File.WriteAllText(Path.ChangeExtension(path, null) + "-" + text2 + ".json", text);
				val2.Save(path);
				return val2;
			}
			T val4;
			try
			{
				val4 = JsonSerializer.Deserialize<T>(text, (JsonSerializerOptions)null);
			}
			catch (JsonException ex)
			{
				ManualLogSource logger3 = Loader.Logger;
				BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(23, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Failed to deserialize ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(typeof(T).Name);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("\n");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<JsonException>(ex);
				}
				logger3.LogError(val5);
				val2.LoadingFailed = true;
				return val2;
			}
			val2 = val4;
		}
		else
		{
			val2.Save(path);
		}
		return val2;
	}

	public void Save()
	{
		Save(s_fullPath);
	}

	public void Save(string path)
	{
		string contents = JsonSerializer.Serialize((object)(T)this, (JsonSerializerOptions)null);
		string directoryName = Path.GetDirectoryName(path);
		if (!Directory.Exists(directoryName))
		{
			Directory.CreateDirectory(directoryName);
		}
		File.WriteAllText(path, contents);
	}
}

plugins/net6/Inas07.LocalProgression.dll

Decompiled a week 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 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;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using LocalProgression.Component;
using LocalProgression.Data;
using Localization;
using MTFO.API;
using Microsoft.CodeAnalysis;
using SNetwork;
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("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
{
	internal static class Assets
	{
		internal static GameObject NoBoosterIcon { get; private set; }

		internal static void Init()
		{
			NoBoosterIcon = AssetAPI.GetLoadedAsset<GameObject>("Assets/Misc/CM_ExpeditionSectorIcon.prefab");
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.LocalProgression", "LocalProgression", "1.3.6")]
	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;
			AssetAPI.OnAssetBundlesLoaded += Assets.Init;
		}
	}
	internal static class JSON
	{
		private static JsonSerializerOptions _setting;

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

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

		static JSON()
		{
			_setting = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = false,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				IgnoreReadOnlyProperties = true
			};
			_setting.Converters.Add(new JsonStringEnumConverter());
		}
	}
	public class LocalProgressionManager
	{
		public const string CONFIG_FILE_NAME = "ProgressionConfig.json";

		public static readonly LocalProgressionManager Current;

		private CM_PageRundown_New rundownPage;

		public static readonly string DirPath;

		public string LP_CONFIG_DIR => Path.Combine(MTFOPathAPI.CustomPath, "LocalProgressionConfig");

		public string CONFIG_PATH => Path.Combine(LP_CONFIG_DIR, "ProgressionConfig.json");

		public RundownProgressonConfig RundownProgressonConfig { get; private set; } = new RundownProgressonConfig();


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


		internal RundownProgData nativeProgData { get; private set; }

		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)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rundownPage == (Object)null)
			{
				return;
			}
			uint rundownID = CurrentRundownPData.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 {CurrentRundownPData.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))
			{
				return;
			}
			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");
			RundownTierMarker_NoBoosterIcon component = ((Component)rundownPage.m_tierMarkerSectorSummary).GetComponent<RundownTierMarker_NoBoosterIcon>();
			if (!((Object)(object)component != (Object)null) || !TryGetRundownConfig(rundownID, out var rundownConf))
			{
				return;
			}
			int value = rundownConf.ComputeNoBoosterClearPossibleCount();
			if (rundownConf.EnableNoBoosterUsedProgressionForRundown && (rundownConf.AlwaysShowIcon || CurrentRundownPData.NoBoosterAllClearCount > 0))
			{
				if (rundownConf.EnableNoBoosterUsedProgressionForRundown)
				{
					value = nativeProgData.totalMain;
				}
				component.SetVisible(visible: true);
				component.SetSectorIconText($"<color=orange>[{CurrentRundownPData.NoBoosterAllClearCount}/{value}]</color>");
			}
			else
			{
				component.SetVisible(visible: false);
			}
		}

		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 = CurrentRundownPData.LPData.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 (CurrentRundownPData.RundownID == 0)
			{
				LPLogger.Error("ComputeLocalProgressionDataToRundownProgData: rundown_id == 0...");
				return progressionData;
			}
			RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(CurrentRundownPData.RundownID);
			if (block == null)
			{
				LPLogger.Error($"ComputeLocalProgressionDataToRundownProgData: cannot get rundown datablock with rundown_id: {CurrentRundownPData.RundownID}");
				return progressionData;
			}
			progressionData.clearedMain = CurrentRundownPData.MainClearCount;
			progressionData.clearedSecondary = CurrentRundownPData.SecondaryClearCount;
			progressionData.clearedThird = CurrentRundownPData.ThirdClearCount;
			progressionData.clearedAllClear = CurrentRundownPData.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 (CurrentRundownPData.LPData.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(CurrentRundownPData.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 (CurrentRundownPData.MainClearCount >= val.MainSectors && CurrentRundownPData.SecondaryClearCount >= val.SecondarySectors && CurrentRundownPData.ThirdClearCount >= val.ThirdSectors)
			{
				return CurrentRundownPData.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 (CurrentRundownPData.MainClearCount >= customProgressionLock.MainSectors && CurrentRundownPData.SecondaryClearCount >= customProgressionLock.SecondarySectors && CurrentRundownPData.ThirdClearCount >= customProgressionLock.ThirdSectors)
				{
					return CurrentRundownPData.AllClearCount >= customProgressionLock.AllClearedSectors;
				}
				return false;
			}
			case 5:
			{
				ExpeditionIndex unlockedByExpedition = expedition.UnlockedByExpedition;
				string rundownProgressionExpeditionKey = RundownManager.GetRundownProgressionExpeditionKey(unlockedByExpedition.Tier, (int)unlockedByExpedition.Exp);
				return CurrentRundownPData.LPData.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: {CurrentRundownPData.RundownID}");
				expeditions.Clear();
			}
			Dictionary<string, ExpeditionProgressionData> lPData = CurrentRundownPData.LPData;
			Layer val2 = default(Layer);
			Layer val3 = default(Layer);
			Layer val4 = default(Layer);
			foreach (string key in lPData.Keys)
			{
				Expedition val = new Expedition();
				ExpeditionProgressionData expeditionProgressionData = lPData[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;
			}
		}

		private void InitConfig()
		{
			if (!Directory.Exists(LP_CONFIG_DIR))
			{
				Directory.CreateDirectory(LP_CONFIG_DIR);
			}
			if (!File.Exists(CONFIG_PATH))
			{
				StreamWriter streamWriter = File.CreateText(CONFIG_PATH);
				streamWriter.WriteLine(JSON.Serialize(new RundownProgressonConfig()));
				streamWriter.Flush();
				streamWriter.Close();
				RundownProgressonConfig = new RundownProgressonConfig();
			}
			ReloadConfig();
			RundownManager.OnRundownProgressionUpdated += Action.op_Implicit((Action)ReloadConfig);
		}

		private void ReloadConfig()
		{
			try
			{
				RundownProgressonConfig = JSON.Deserialize<RundownProgressonConfig>(File.ReadAllText(CONFIG_PATH));
			}
			catch
			{
				LPLogger.Error("Cannot reload RundownProgressonConfig, probably the file is invalid");
				RundownProgressonConfig = new RundownProgressonConfig();
			}
		}

		public bool TryGetRundownConfig(uint RundownID, out RundownConfig rundownConf)
		{
			rundownConf = RundownProgressonConfig.Configs.Find((RundownConfig rundownConf) => rundownConf.RundownID == RundownID);
			return rundownConf != null;
		}

		public bool TryGetExpeditionConfig(uint RundownID, eRundownTier tier, int expIndex, out ExpeditionProgressionConfig expConf)
		{
			//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)
			expConf = null;
			if (TryGetRundownConfig(RundownID, out var rundownConf))
			{
				expConf = rundownConf.Expeditions.Find((ExpeditionProgressionConfig e) => e.Tier == tier && e.ExpeditionIndex == expIndex);
			}
			return expConf != null;
		}

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

		public void UpdateLPDataToActiveRundown()
		{
			uint num = ActiveRundownID();
			if (num == 0)
			{
				LPLogger.Debug("UpdateLPDataToActiveRundown: cannot find any active rundown!");
				return;
			}
			LPLogger.Warning($"Update LPData to rundown_id: {num}");
			CurrentRundownPData.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 = ReadRundownLPData(((GameDataBlockBase<RundownDataBlock>)(object)block).name);
			CurrentRundownPData.RundownID = num;
			CurrentRundownPData.RundownName = ((GameDataBlockBase<RundownDataBlock>)(object)block).name;
			CurrentRundownPData.LPData = dictionary;
			foreach (ExpeditionProgressionData value in dictionary.Values)
			{
				CurrentRundownPData.MainClearCount += ((value.MainCompletionCount > 0) ? 1 : 0);
				CurrentRundownPData.SecondaryClearCount += ((value.SecondaryCompletionCount > 0) ? 1 : 0);
				CurrentRundownPData.ThirdClearCount += ((value.ThirdCompletionCount > 0) ? 1 : 0);
				CurrentRundownPData.AllClearCount += ((value.AllClearCount > 0) ? 1 : 0);
				CurrentRundownPData.NoBoosterAllClearCount += ((value.NoBoosterAllClearCount > 0) ? 1 : 0);
			}
		}

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

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

		public bool AllSectorCompletedWithoutBoosterAndCheckpoint()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			if (RundownManager.HasSecondaryLayer(RundownManager.ActiveExpedition) && (int)WardenObjectiveManager.CurrentState.second_status != 40)
			{
				return false;
			}
			if (RundownManager.HasThirdLayer(RundownManager.ActiveExpedition) && (int)WardenObjectiveManager.CurrentState.second_status != 40)
			{
				return false;
			}
			bool flag = CheckpointManager.CheckpointUsage == 0;
			if (flag)
			{
				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)
						{
							flag = false;
							break;
						}
					}
				}
			}
			return flag;
		}

		public uint ActiveRundownID()
		{
			uint num = default(uint);
			if (!RundownManager.TryGetIdFromLocalRundownKey(RundownManager.ActiveRundownKey, ref num) || num == 0)
			{
				return 0u;
			}
			return num;
		}

		public string ExpeditionKey(eRundownTier tier, int expIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return RundownManager.GetRundownProgressionExpeditionKey(tier, expIndex);
		}

		public ExpeditionProgressionData GetExpeditionLP(uint RundownID, eRundownTier tier, int expIndex)
		{
			//IL_0007: 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)
			ExpeditionProgressionData result = new ExpeditionProgressionData
			{
				ExpeditionKey = ExpeditionKey(tier, expIndex)
			};
			Dictionary<string, ExpeditionProgressionData> dictionary;
			if (CurrentRundownPData.RundownID != RundownID)
			{
				RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(RundownID);
				if (block == null)
				{
					LPLogger.Error($"Didn't find Rundown Datablock with rundown id {RundownID}");
					return result;
				}
				dictionary = ReadRundownLPData(((GameDataBlockBase<RundownDataBlock>)(object)block).name);
			}
			else
			{
				dictionary = CurrentRundownPData.LPData;
			}
			string key = ExpeditionKey(tier, expIndex);
			if (dictionary.TryGetValue(key, out var value))
			{
				return value;
			}
			return result;
		}

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

		private LocalProgressionManager()
		{
		}

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

		private static string NBSClearDataPath(string rundownName)
		{
			return RundownLPDataPath(rundownName) + " - NBSClear";
		}

		private bool TryReadAggregatedFormatData(string datapath, out Dictionary<string, ExpeditionProgressionData> dataDict)
		{
			dataDict = new Dictionary<string, ExpeditionProgressionData>();
			bool result = true;
			FileStream fileStream = null;
			BinaryReader binaryReader = null;
			try
			{
				fileStream = File.Open(datapath, FileMode.Open);
				binaryReader = new BinaryReader(fileStream, Encoding.UTF8, leaveOpen: false);
				int 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();
					expeditionProgressionData.NoBoosterAllClearCount = binaryReader.ReadInt32();
					dataDict[expeditionProgressionData.ExpeditionKey] = expeditionProgressionData;
				}
			}
			catch (EndOfStreamException)
			{
				dataDict.Clear();
				result = false;
			}
			finally
			{
				binaryReader?.Close();
				fileStream?.Close();
			}
			return result;
		}

		private bool TryReadOldFormatData(string datapath, out Dictionary<string, ExpeditionProgressionData> dataDict)
		{
			dataDict = new Dictionary<string, ExpeditionProgressionData>();
			bool result = true;
			FileStream fileStream = null;
			BinaryReader binaryReader = null;
			if (!File.Exists(datapath))
			{
				return true;
			}
			try
			{
				fileStream = File.Open(datapath, FileMode.Open);
				binaryReader = new BinaryReader(fileStream, Encoding.UTF8, leaveOpen: false);
				int 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();
					dataDict[expeditionProgressionData.ExpeditionKey] = expeditionProgressionData;
				}
			}
			catch (EndOfStreamException)
			{
				dataDict.Clear();
				result = false;
			}
			finally
			{
				binaryReader?.Close();
				fileStream?.Close();
			}
			return result;
		}

		private bool TryReadNBSClearData(string datapath, out Dictionary<string, ExpeditionProgressionData> dataDict)
		{
			dataDict = new Dictionary<string, ExpeditionProgressionData>();
			bool result = true;
			FileStream fileStream = null;
			BinaryReader binaryReader = null;
			if (!File.Exists(datapath))
			{
				return true;
			}
			try
			{
				fileStream = File.Open(datapath, FileMode.Open);
				binaryReader = new BinaryReader(fileStream, Encoding.UTF8, leaveOpen: false);
				int num = binaryReader.ReadInt32();
				for (int i = 0; i < num; i++)
				{
					ExpeditionProgressionData expeditionProgressionData = new ExpeditionProgressionData();
					expeditionProgressionData.ExpeditionKey = binaryReader.ReadString();
					expeditionProgressionData.NoBoosterAllClearCount = binaryReader.ReadInt32();
					dataDict[expeditionProgressionData.ExpeditionKey] = expeditionProgressionData;
				}
			}
			catch (EndOfStreamException)
			{
				dataDict.Clear();
				result = false;
			}
			finally
			{
				binaryReader?.Close();
				fileStream?.Close();
			}
			return result;
		}

		private void WriteOldFormatDataToDisk(string filepath, Dictionary<string, ExpeditionProgressionData> dataDict)
		{
			using FileStream output = File.Open(filepath, FileMode.Create);
			using BinaryWriter binaryWriter = new BinaryWriter(output, Encoding.UTF8, leaveOpen: false);
			binaryWriter.Write(dataDict.Count);
			foreach (string key in dataDict.Keys)
			{
				ExpeditionProgressionData expeditionProgressionData = dataDict[key];
				binaryWriter.Write(key);
				binaryWriter.Write(expeditionProgressionData.MainCompletionCount);
				binaryWriter.Write(expeditionProgressionData.SecondaryCompletionCount);
				binaryWriter.Write(expeditionProgressionData.ThirdCompletionCount);
				binaryWriter.Write(expeditionProgressionData.AllClearCount);
			}
		}

		private void WriteNBSClearDataToDisk(string filepath, Dictionary<string, ExpeditionProgressionData> dataDict)
		{
			using FileStream output = File.Open(filepath, FileMode.Create);
			using BinaryWriter binaryWriter = new BinaryWriter(output, Encoding.UTF8, leaveOpen: false);
			binaryWriter.Write(dataDict.Count);
			foreach (string key in dataDict.Keys)
			{
				ExpeditionProgressionData expeditionProgressionData = dataDict[key];
				binaryWriter.Write(key);
				binaryWriter.Write(expeditionProgressionData.NoBoosterAllClearCount);
			}
		}

		private Dictionary<string, ExpeditionProgressionData> ReadRundownLPData(string rundownName)
		{
			string text = RundownLPDataPath(rundownName);
			string text2 = NBSClearDataPath(rundownName);
			Dictionary<string, ExpeditionProgressionData> dataDict = new Dictionary<string, ExpeditionProgressionData>();
			if (File.Exists(text))
			{
				if (TryReadAggregatedFormatData(text, out dataDict))
				{
					LPLogger.Warning(rundownName + " - aggregated format");
					WriteOldFormatDataToDisk(text, dataDict);
					WriteNBSClearDataToDisk(text2, dataDict);
					LPLogger.Warning("wrote old format and nbs data");
				}
				else if (TryReadOldFormatData(text, out dataDict))
				{
					LPLogger.Warning(rundownName + " - old format");
					if (TryReadNBSClearData(text2, out var dataDict2))
					{
						foreach (string key in dataDict.Keys)
						{
							dataDict[key].NoBoosterAllClearCount = (dataDict2.TryGetValue(key, out var value) ? value.NoBoosterAllClearCount : 0);
						}
					}
				}
				else
				{
					LPLogger.Error("Something went wrong with localprogression data, contact the plugin developer...");
				}
			}
			return dataDict;
		}

		internal RundownProgressionData GetLPDataForCurrentRundown()
		{
			return CurrentRundownPData;
		}

		private void SaveRundownLPDataToDisk()
		{
			string rundownName = CurrentRundownPData.RundownName;
			Dictionary<string, ExpeditionProgressionData> lPData = CurrentRundownPData.LPData;
			string text = RundownLPDataPath(rundownName);
			string filepath = NBSClearDataPath(rundownName);
			LPLogger.Warning($"SaveData: saving {CurrentRundownPData.RundownName} LPData to '{text}'");
			WriteOldFormatDataToDisk(text, lPData);
			WriteNBSClearDataToDisk(filepath, lPData);
		}
	}
	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 static class Patches_CM_ExpeditionWindow
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_ExpeditionWindow), "Setup")]
		private static void Post_Setup(CM_ExpeditionWindow __instance)
		{
			ExpeditionWindow_NoBoosterIcon expeditionWindow_NoBoosterIcon = ((Component)__instance).gameObject.AddComponent<ExpeditionWindow_NoBoosterIcon>();
			expeditionWindow_NoBoosterIcon.m_window = __instance;
			expeditionWindow_NoBoosterIcon.InitialSetup();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_ExpeditionWindow), "SetExpeditionInfo")]
		private static void Post_SetExpeditionInfo(CM_ExpeditionWindow __instance)
		{
			//IL_002e: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			ExpeditionWindow_NoBoosterIcon component = ((Component)__instance).gameObject.GetComponent<ExpeditionWindow_NoBoosterIcon>();
			if (!((Object)(object)component == (Object)null))
			{
				float num = 0f;
				float num2 = 410f;
				((RectTransformComp)__instance.m_sectorIconMain).SetPosition(new Vector2(num, 0f));
				num += num2;
				if (RundownManager.HasSecondaryLayer(__instance.m_data))
				{
					num += num2;
				}
				if (RundownManager.HasThirdLayer(__instance.m_data))
				{
					num += num2;
				}
				ExpeditionProgressionData expeditionLP = LocalProgressionManager.Current.GetExpeditionLP(LocalProgressionManager.Current.ActiveRundownID(), __instance.m_tier, __instance.m_expIndex);
				if (RundownManager.HasAllCompletetionPossibility(__instance.m_data) && expeditionLP.AllClearCount > 0)
				{
					num += num2;
				}
				component.SetIconPosition(new Vector2(num, 0f));
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CM_ExpeditionWindow), "SetVisible")]
		private static bool Pre_SetVisible(CM_ExpeditionWindow __instance, bool visible, bool inMenuBar)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Invalid comparison between Unknown and I4
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Invalid comparison between Unknown and I4
			//IL_00bf: 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_00cd: Invalid comparison between Unknown and I4
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Invalid comparison between Unknown and I4
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			ExpeditionWindow_NoBoosterIcon component = ((Component)__instance).GetComponent<ExpeditionWindow_NoBoosterIcon>();
			if (!visible)
			{
				return true;
			}
			if (__instance.m_data == null)
			{
				return true;
			}
			uint rundownID = LocalProgressionManager.Current.ActiveRundownID();
			ExpeditionProgressionData expeditionLP = LocalProgressionManager.Current.GetExpeditionLP(rundownID, __instance.m_tier, __instance.m_expIndex);
			((Component)__instance).gameObject.SetActive(visible);
			((RectTransformComp)__instance.m_joinWindow).SetVisible(!inMenuBar && !SNet.IsInLobby);
			((RectTransformComp)__instance.m_hostButton).SetVisible(!inMenuBar && !SNet.IsInLobby && (int)__instance.m_status != 0 && (int)__instance.m_status != 5 && (int)__instance.m_status != 1);
			((RectTransformComp)__instance.m_changeExpeditionButton).SetVisible(SNet.IsMaster && !((RectTransformComp)__instance.m_hostButton).IsVisible && !inMenuBar && SNet.IsInLobby && RundownManager.ActiveExpedition != null && (int)__instance.m_status != 0 && (int)__instance.m_status != 5 && (int)__instance.m_status != 1);
			__instance.m_bottomStripes.SetActive(!((RectTransformComp)__instance.m_hostButton).IsVisible && !((RectTransformComp)__instance.m_changeExpeditionButton).IsVisible);
			((Component)__instance.m_title).gameObject.SetActive(false);
			((Component)__instance.m_wardenObjective).gameObject.SetActive(false);
			((Component)__instance.m_wardenIntel).gameObject.SetActive(false);
			((Component)__instance.m_depthTitle).gameObject.SetActive(false);
			((Component)__instance.m_artifactHeatTitle).gameObject.SetActive(false);
			CoroutineManager.BlinkIn(__instance.m_title, 0.3f, (Transform)null);
			CoroutineManager.BlinkIn(__instance.m_wardenObjective, 1.1f, (Transform)null);
			CoroutineManager.BlinkIn(__instance.m_wardenIntel, 2.5f, (Transform)null);
			CoroutineManager.BlinkIn(__instance.m_depthTitle, 3f, (Transform)null);
			CoroutineManager.BlinkIn(__instance.m_artifactHeatTitle, 3.25f, (Transform)null);
			float num = 1.8f;
			float num2 = 0.4f;
			__instance.m_sectorIconMain.Setup((LG_LayerType)0, __instance.m_root, true, expeditionLP.MainCompletionCount > 0, true, 0.5f, 0.8f);
			((RectTransformComp)__instance.m_sectorIconMain).SetVisible(false);
			((RectTransformComp)__instance.m_sectorIconSecond).SetVisible(false);
			((RectTransformComp)__instance.m_sectorIconThird).SetVisible(false);
			((RectTransformComp)__instance.m_sectorIconAllCompleted).SetVisible(false);
			component.SetVisible(visible: false);
			__instance.m_sectorIconMain.StopBlink();
			__instance.m_sectorIconSecond.StopBlink();
			__instance.m_sectorIconThird.StopBlink();
			__instance.m_sectorIconAllCompleted.StopBlink();
			__instance.m_sectorIconMain.BlinkIn(num);
			num += num2;
			if (RundownManager.HasSecondaryLayer(__instance.m_data))
			{
				__instance.m_sectorIconSecond.Setup((LG_LayerType)1, __instance.m_root, true, expeditionLP.SecondaryCompletionCount > 0, true, 0.5f, 0.8f);
				__instance.m_sectorIconSecond.BlinkIn(num);
				num += num2;
			}
			if (RundownManager.HasThirdLayer(__instance.m_data))
			{
				__instance.m_sectorIconThird.Setup((LG_LayerType)2, __instance.m_root, true, expeditionLP.ThirdCompletionCount > 0, true, 0.5f, 0.8f);
				__instance.m_sectorIconThird.BlinkIn(num);
				num += num2;
			}
			if (expeditionLP.AllClearCount > 0)
			{
				__instance.m_sectorIconAllCompleted.BlinkIn(num);
				num += num2;
			}
			bool flag = expeditionLP.NoBoosterAllClearCount > 0;
			if ((LocalProgressionManager.Current.TryGetRundownConfig(rundownID, out var rundownConf) && rundownConf.EnableNoBoosterUsedProgressionForRundown && (rundownConf.AlwaysShowIcon || flag)) || (LocalProgressionManager.Current.TryGetExpeditionConfig(rundownID, __instance.m_tier, __instance.m_expIndex, out var expConf) && expConf.EnableNoBoosterUsedProgression && (expConf.AlwaysShowIcon || flag)))
			{
				component.SetupNoBoosterUsedIcon(flag);
				component.BlinkIn(num);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class Patches_CM_ExpeditionIcon
	{
		private static readonly Color BORDER_COLOR = new Color(0f, 1f, 82f / 85f, 1f);

		private static readonly Color TEXT_COLOR = new Color(0f, 1f, 0.5882353f, 1f);

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_ExpeditionIcon_New), "UpdateBorderColor")]
		private static void Post_UpdateBorderColor(CM_ExpeditionIcon_New __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0033: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)__instance.Status != 5)
			{
				uint rundownID = LocalProgressionManager.Current.ActiveRundownID();
				if (((LocalProgressionManager.Current.TryGetRundownConfig(rundownID, out var rundownConf) && rundownConf.EnableNoBoosterUsedProgressionForRundown) || (LocalProgressionManager.Current.TryGetExpeditionConfig(rundownID, __instance.Tier, __instance.ExpIndex, out var expConf) && expConf.EnableNoBoosterUsedProgression)) && LocalProgressionManager.Current.GetExpeditionLP(rundownID, __instance.Tier, __instance.ExpIndex).NoBoosterAllClearCount > 0)
				{
					__instance.SetBorderColor(BORDER_COLOR);
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class Patch_CM_PageExpeditionSuccess
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageExpeditionSuccess), "Setup")]
		private static void Post_Setup(CM_PageExpeditionSuccess __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<ExpeditionSuccessPage_NoBoosterIcon>() == (Object)null)
			{
				ExpeditionSuccessPage_NoBoosterIcon expeditionSuccessPage_NoBoosterIcon = ((Component)__instance).gameObject.AddComponent<ExpeditionSuccessPage_NoBoosterIcon>();
				expeditionSuccessPage_NoBoosterIcon.m_page = __instance;
				expeditionSuccessPage_NoBoosterIcon.Setup();
			}
		}
	}
	[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 Patches_CM_RundownTierMarker
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_RundownTierMarker), "Setup")]
		private static void Post_Setup(CM_RundownTierMarker __instance)
		{
			RundownTierMarker_NoBoosterIcon rundownTierMarker_NoBoosterIcon = ((Component)__instance).gameObject.AddComponent<RundownTierMarker_NoBoosterIcon>();
			rundownTierMarker_NoBoosterIcon.m_tierMarker = __instance;
			rundownTierMarker_NoBoosterIcon.Setup();
		}
	}
	[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_000c: 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
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			pActiveExpedition activeExpeditionData = RundownManager.GetActiveExpeditionData();
			string text = LocalProgressionManager.Current.ExpeditionKey(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;
			bool clearedWithNoBooster = LocalProgressionManager.Current.AllSectorCompletedWithoutBoosterAndCheckpoint();
			LPLogger.Debug("Level cleared, recording - " + text);
			LocalProgressionManager.Current.RecordExpeditionSuccessForCurrentRundown(text, mainLayerCleared, secondaryLayerCleared, thirdLayerCleared, clearedWithNoBooster);
		}
	}
}
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 int NoBoosterAllClearCount { get; set; }
	}
	public class ExpeditionProgressionConfig
	{
		public eRundownTier Tier { get; set; }

		public int ExpeditionIndex { get; set; }

		public bool EnableNoBoosterUsedProgression { get; set; }

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

	}
	public class RundownConfig
	{
		public uint RundownID { get; set; }

		public bool EnableNoBoosterUsedProgressionForRundown { get; set; }

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


		public List<ExpeditionProgressionConfig> Expeditions { get; set; } = new List<ExpeditionProgressionConfig>
		{
			new ExpeditionProgressionConfig()
		};


		internal int ComputeNoBoosterClearPossibleCount()
		{
			if (EnableNoBoosterUsedProgressionForRundown)
			{
				return int.MaxValue;
			}
			return Expeditions.TakeWhile((ExpeditionProgressionConfig conf) => conf.EnableNoBoosterUsedProgression).Count();
		}
	}
	public class RundownProgressonConfig
	{
		public List<RundownConfig> Configs { get; set; } = new List<RundownConfig>
		{
			new RundownConfig()
		};

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


		public uint RundownID { get; set; }

		public Dictionary<string, ExpeditionProgressionData> LPData { 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 int NoBoosterAllClearCount { get; set; }

		public void Reset()
		{
			RundownName = string.Empty;
			RundownID = 0u;
			LPData.Clear();
			int num2 = (NoBoosterAllClearCount = 0);
			int num4 = (AllClearCount = num2);
			int num6 = (ThirdClearCount = num4);
			int mainClearCount = (SecondaryClearCount = num6);
			MainClearCount = mainClearCount;
		}
	}
}
namespace LocalProgression.Component
{
	public class ExpeditionSuccessPage_NoBoosterIcon : MonoBehaviour
	{
		internal CM_PageExpeditionSuccess m_page;

		private CM_ExpeditionSectorIcon m_completeWithNoBoosterIcon;

		private SpriteRenderer m_icon;

		private SpriteRenderer m_bg;

		private TextMeshPro m_title;

		private TextMeshPro m_rightSideText;

		private NoBoosterIconGOWrapper Wrapper;

		internal void Setup()
		{
			if ((Object)(object)m_page == (Object)null)
			{
				LPLogger.Error("ExpeditionSuccess_NoBooster: Assign the page instance before setup");
			}
			else
			{
				if ((Object)(object)m_completeWithNoBoosterIcon != (Object)null)
				{
					return;
				}
				if ((Object)(object)Assets.NoBoosterIcon == (Object)null)
				{
					AssetAPI.OnAssetBundlesLoaded += delegate
					{
						LoadAsset();
						AssetAPI.OnAssetBundlesLoaded -= LoadAsset;
					};
				}
				else
				{
					LoadAsset();
				}
			}
		}

		private void LoadAsset()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Assets.NoBoosterIcon == (Object)null)
			{
				LPLogger.Error("ExpeditionSuccess_NoBooster.Setup: cannot instantiate NoBooster icon...");
				return;
			}
			m_completeWithNoBoosterIcon = ((Il2CppObjectBase)((GuiLayer)((CM_PageBase)m_page).m_guiLayer).AddRectComp(Assets.NoBoosterIcon, (GuiAnchor)1, new Vector2(1200f, 0f), m_page.m_sectorIconAlign)).Cast<CM_ExpeditionSectorIcon>();
			Wrapper = new NoBoosterIconGOWrapper(((Component)m_completeWithNoBoosterIcon).gameObject);
			m_bg = Wrapper.BGGO.GetComponent<SpriteRenderer>();
			m_icon = Wrapper.IconGO.GetComponent<SpriteRenderer>();
			m_title = Object.Instantiate<TextMeshPro>(m_page.m_sectorIconMain.m_title);
			m_title.transform.SetParent(Wrapper.ObjectiveIcon.transform, false);
			m_rightSideText = Object.Instantiate<TextMeshPro>(m_page.m_sectorIconMain.m_rightSideText);
			m_rightSideText.transform.SetParent(Wrapper.RightSideText.transform, false);
			m_completeWithNoBoosterIcon.m_title = m_title;
			m_completeWithNoBoosterIcon.m_rightSideText = m_rightSideText;
			((RectTransformComp)m_completeWithNoBoosterIcon).SetVisible(false);
		}

		private void OnEnable()
		{
			//IL_003b: 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_00ab: Invalid comparison between Unknown and I4
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Invalid comparison between Unknown and I4
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			((RectTransformComp)m_completeWithNoBoosterIcon).SetVisible(false);
			uint rundownID = LocalProgressionManager.Current.ActiveRundownID();
			pActiveExpedition activeExpeditionData = RundownManager.GetActiveExpeditionData();
			if ((LocalProgressionManager.Current.TryGetRundownConfig(rundownID, out var rundownConf) && rundownConf.EnableNoBoosterUsedProgressionForRundown) || (LocalProgressionManager.Current.TryGetExpeditionConfig(rundownID, activeExpeditionData.tier, activeExpeditionData.expeditionIndex, out var expConf) && expConf.EnableNoBoosterUsedProgression))
			{
				bool boosterUnused = LocalProgressionManager.Current.AllSectorCompletedWithoutBoosterAndCheckpoint();
				int num = 1;
				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);
				float num2 = m_page.m_time_sectorIcon + (float)num * 0.7f;
				SetupNoBoosterUsedIcon(boosterUnused);
				((RectTransformComp)m_completeWithNoBoosterIcon).SetPosition(new Vector2((float)num * 400f, 0f));
				m_completeWithNoBoosterIcon.BlinkIn(num2);
			}
		}

		private void SetupNoBoosterUsedIcon(bool boosterUnused)
		{
			//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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00db: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			CM_ExpeditionSectorIcon completeWithNoBoosterIcon = m_completeWithNoBoosterIcon;
			completeWithNoBoosterIcon.m_isFinishedAll = true;
			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, false, false, 0.5f, 0.7f);
			Color color = m_icon.color;
			Color color2 = m_bg.color;
			m_icon.color = new Color(color.r, color.g, color.b, boosterUnused ? 1f : 0.4f);
			m_bg.color = new Color(color2.r, color2.g, color2.b, boosterUnused ? 1f : 0.3f);
			((TMP_Text)m_title).alpha = (boosterUnused ? 1f : 0.2f);
			completeWithNoBoosterIcon.m_titleVisible = true;
			completeWithNoBoosterIcon.m_isCleared = boosterUnused;
			if (boosterUnused)
			{
				completeWithNoBoosterIcon.m_isFinishedAll = true;
			}
			else
			{
				completeWithNoBoosterIcon.m_isFinishedAll = false;
				completeWithNoBoosterIcon.m_type = (LG_LayerType)0;
			}
			((Component)completeWithNoBoosterIcon.m_rightSideText).gameObject.SetActive(false);
			TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.ExpeditionSuccessPage.AllClearWithNoBoosterUsed");
			if (block != null)
			{
				((TMP_Text)completeWithNoBoosterIcon.m_title).SetText(Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID), true);
			}
			else
			{
				((TMP_Text)completeWithNoBoosterIcon.m_title).SetText("<color=orange>OMNIPOTENT</color>", true);
			}
			((Component)completeWithNoBoosterIcon.m_title).gameObject.SetActive(true);
		}

		private void OnDestroy()
		{
			m_icon = (m_bg = null);
			m_completeWithNoBoosterIcon = null;
			Wrapper.Destory();
		}

		static ExpeditionSuccessPage_NoBoosterIcon()
		{
			ClassInjector.RegisterTypeInIl2Cpp<ExpeditionSuccessPage_NoBoosterIcon>();
		}
	}
	internal class ExpeditionWindow_NoBoosterIcon : MonoBehaviour
	{
		internal CM_ExpeditionWindow m_window;

		private CM_ExpeditionSectorIcon m_completeWithNoBoosterIcon;

		private NoBoosterIconGOWrapper Wrapper;

		private SpriteRenderer m_icon;

		private SpriteRenderer m_bg;

		private TextMeshPro m_title;

		private TextMeshPro m_rightSideText;

		internal void InitialSetup()
		{
			if ((Object)(object)m_window == (Object)null)
			{
				LPLogger.Error("ExpeditionSuccess_NoBooster: Assign the page instance before setup");
			}
			else
			{
				if ((Object)(object)m_completeWithNoBoosterIcon != (Object)null)
				{
					return;
				}
				if ((Object)(object)Assets.NoBoosterIcon == (Object)null)
				{
					AssetAPI.OnAssetBundlesLoaded += delegate
					{
						LoadAsset();
						AssetAPI.OnAssetBundlesLoaded -= LoadAsset;
					};
				}
				else
				{
					LoadAsset();
				}
			}
		}

		private void LoadAsset()
		{
			if ((Object)(object)Assets.NoBoosterIcon == (Object)null)
			{
				LPLogger.Error("ExpeditionSuccess_NoBooster.Setup: cannot instantiate NoBooster icon...");
				return;
			}
			m_completeWithNoBoosterIcon = GOUtil.SpawnChildAndGetComp<CM_ExpeditionSectorIcon>(Assets.NoBoosterIcon, m_window.m_sectorIconAlign);
			Wrapper = new NoBoosterIconGOWrapper(((Component)m_completeWithNoBoosterIcon).gameObject);
			m_bg = Wrapper.BGGO.GetComponent<SpriteRenderer>();
			m_icon = Wrapper.IconGO.GetComponent<SpriteRenderer>();
			m_title = Object.Instantiate<TextMeshPro>(m_window.m_sectorIconMain.m_title);
			m_title.transform.SetParent(Wrapper.ObjectiveIcon.transform, false);
			m_rightSideText = Object.Instantiate<TextMeshPro>(m_window.m_sectorIconMain.m_rightSideText);
			m_rightSideText.transform.SetParent(Wrapper.RightSideText.transform, false);
			m_completeWithNoBoosterIcon.m_title = m_title;
			m_completeWithNoBoosterIcon.m_rightSideText = m_rightSideText;
			((RectTransformComp)m_completeWithNoBoosterIcon).SetAnchor((GuiAnchor)1, true);
			((RectTransformComp)m_completeWithNoBoosterIcon).SetVisible(false);
			m_completeWithNoBoosterIcon.SortAsPopupLayer();
			m_completeWithNoBoosterIcon.m_root = m_window.m_root;
		}

		internal void SetVisible(bool visible)
		{
			((RectTransformComp)m_completeWithNoBoosterIcon).SetVisible(visible);
		}

		internal void SetIconPosition(Vector2 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			((RectTransformComp)m_completeWithNoBoosterIcon).SetPosition(position);
		}

		internal void BlinkIn(float delay)
		{
			m_completeWithNoBoosterIcon.BlinkIn(delay);
		}

		internal void SetupNoBoosterUsedIcon(bool boosterUnused)
		{
			//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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00db: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			CM_ExpeditionSectorIcon completeWithNoBoosterIcon = m_completeWithNoBoosterIcon;
			completeWithNoBoosterIcon.m_isFinishedAll = true;
			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, false, false, 0.5f, 0.7f);
			Color color = m_icon.color;
			Color color2 = m_bg.color;
			m_icon.color = new Color(color.r, color.g, color.b, boosterUnused ? 1f : 0.4f);
			m_bg.color = new Color(color2.r, color2.g, color2.b, boosterUnused ? 1f : 0.3f);
			((TMP_Text)m_title).alpha = (boosterUnused ? 1f : 0.2f);
			completeWithNoBoosterIcon.m_titleVisible = true;
			completeWithNoBoosterIcon.m_isCleared = boosterUnused;
			if (boosterUnused)
			{
				completeWithNoBoosterIcon.m_isFinishedAll = true;
			}
			else
			{
				completeWithNoBoosterIcon.m_isFinishedAll = false;
				completeWithNoBoosterIcon.m_type = (LG_LayerType)0;
			}
			((Component)completeWithNoBoosterIcon.m_rightSideText).gameObject.SetActive(false);
			TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.ExpeditionSuccessPage.AllClearWithNoBoosterUsed");
			if (block != null)
			{
				((TMP_Text)completeWithNoBoosterIcon.m_title).SetText(Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID), true);
			}
			else
			{
				((TMP_Text)completeWithNoBoosterIcon.m_title).SetText("<color=orange>OMNIPOTENT</color>", true);
			}
			((Component)completeWithNoBoosterIcon.m_title).gameObject.SetActive(true);
		}

		private void OnDestroy()
		{
			m_icon = (m_bg = null);
			m_completeWithNoBoosterIcon = null;
			Wrapper.Destory();
		}

		static ExpeditionWindow_NoBoosterIcon()
		{
			ClassInjector.RegisterTypeInIl2Cpp<ExpeditionWindow_NoBoosterIcon>();
		}
	}
	public class NoBoosterIconGOWrapper
	{
		public GameObject GameObject { get; private set; }

		public GameObject ObjectiveIcon
		{
			get
			{
				GameObject gameObject = GameObject;
				if (gameObject == null)
				{
					return null;
				}
				return ((Component)gameObject.transform.GetChild(0)).gameObject;
			}
		}

		public GameObject BGHolder
		{
			get
			{
				GameObject objectiveIcon = ObjectiveIcon;
				if (objectiveIcon == null)
				{
					return null;
				}
				return ((Component)objectiveIcon.transform.GetChild(2)).gameObject;
			}
		}

		public GameObject SkullHolder
		{
			get
			{
				GameObject objectiveIcon = ObjectiveIcon;
				if (objectiveIcon == null)
				{
					return null;
				}
				return ((Component)objectiveIcon.transform.GetChild(3)).gameObject;
			}
		}

		public GameObject BGGO
		{
			get
			{
				GameObject bGHolder = BGHolder;
				if (bGHolder == null)
				{
					return null;
				}
				return ((Component)bGHolder.transform.GetChild(4)).gameObject;
			}
		}

		public GameObject IconGO
		{
			get
			{
				GameObject skullHolder = SkullHolder;
				if (skullHolder == null)
				{
					return null;
				}
				return ((Component)skullHolder.transform.GetChild(4)).gameObject;
			}
		}

		public GameObject TitleGO
		{
			get
			{
				GameObject objectiveIcon = ObjectiveIcon;
				if (objectiveIcon == null)
				{
					return null;
				}
				return ((Component)objectiveIcon.transform.GetChild(1)).gameObject;
			}
		}

		public GameObject RightSideText
		{
			get
			{
				GameObject gameObject = GameObject;
				if (gameObject == null)
				{
					return null;
				}
				return ((Component)gameObject.transform.GetChild(2)).gameObject;
			}
		}

		public NoBoosterIconGOWrapper(GameObject iconGO)
		{
			GameObject = iconGO;
		}

		public void Destory()
		{
			if ((Object)(object)GameObject != (Object)null)
			{
				Object.Destroy((Object)(object)GameObject);
			}
			GameObject = null;
		}
	}
	internal class RundownTierMarker_NoBoosterIcon : MonoBehaviour
	{
		internal CM_RundownTierMarker m_tierMarker;

		private CM_ExpeditionSectorIcon m_completeWithNoBoosterIcon;

		private SpriteRenderer m_icon;

		private SpriteRenderer m_bg;

		private TextMeshPro m_title;

		private TextMeshPro m_rightSideText;

		private NoBoosterIconGOWrapper Wrapper;

		internal void Setup()
		{
			if ((Object)(object)m_tierMarker == (Object)null)
			{
				LPLogger.Error("ExpeditionSuccess_NoBooster: Assign the page instance before setup");
			}
			else
			{
				if ((Object)(object)m_completeWithNoBoosterIcon != (Object)null)
				{
					return;
				}
				if ((Object)(object)Assets.NoBoosterIcon == (Object)null)
				{
					AssetAPI.OnAssetBundlesLoaded += delegate
					{
						LoadAsset();
						AssetAPI.OnAssetBundlesLoaded -= LoadAsset;
					};
				}
				else
				{
					LoadAsset();
				}
			}
		}

		private void LoadAsset()
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_016b: 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)
			if ((Object)(object)Assets.NoBoosterIcon == (Object)null)
			{
				LPLogger.Error("ExpeditionSuccess_NoBooster.Setup: cannot instantiate NoBooster icon...");
				return;
			}
			m_completeWithNoBoosterIcon = GOUtil.SpawnChildAndGetComp<CM_ExpeditionSectorIcon>(Assets.NoBoosterIcon, m_tierMarker.m_sectorIconAlign_main);
			Wrapper = new NoBoosterIconGOWrapper(((Component)m_completeWithNoBoosterIcon).gameObject);
			m_bg = Wrapper.BGGO.GetComponent<SpriteRenderer>();
			m_icon = Wrapper.IconGO.GetComponent<SpriteRenderer>();
			m_title = Object.Instantiate<TextMeshPro>(m_tierMarker.m_sectorIconSummaryMain.m_title);
			m_title.transform.SetParent(Wrapper.ObjectiveIcon.transform, false);
			m_rightSideText = Object.Instantiate<TextMeshPro>(m_tierMarker.m_sectorIconSummaryMain.m_rightSideText);
			m_rightSideText.transform.SetParent(Wrapper.RightSideText.transform, false);
			m_completeWithNoBoosterIcon.m_title = m_title;
			m_completeWithNoBoosterIcon.m_rightSideText = m_rightSideText;
			SetupNoBoosterUsedIcon(boosterUnused: true);
			float num = 0.16f;
			Vector3 localScale = default(Vector3);
			((Vector3)(ref localScale))..ctor(num, num, num);
			_ = num / 0.16f;
			((Component)m_completeWithNoBoosterIcon).transform.localScale = localScale;
			Vector2 val = ((RectTransformComp)m_tierMarker.m_sectorIconSummarySecondary).GetPosition() - ((RectTransformComp)m_tierMarker.m_sectorIconSummaryMain).GetPosition();
			((RectTransformComp)m_completeWithNoBoosterIcon).SetPosition(val * 4f);
			((RectTransformComp)m_completeWithNoBoosterIcon).SetVisible(false);
		}

		internal void SetVisible(bool visible)
		{
			((RectTransformComp)m_completeWithNoBoosterIcon).SetVisible(visible);
		}

		internal void SetSectorIconText(string text)
		{
			((RectTransformComp)m_completeWithNoBoosterIcon).SetVisible(true);
			m_completeWithNoBoosterIcon.SetRightSideText(text);
		}

		private void SetupNoBoosterUsedIcon(bool boosterUnused)
		{
			//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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00db: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			CM_ExpeditionSectorIcon completeWithNoBoosterIcon = m_completeWithNoBoosterIcon;
			completeWithNoBoosterIcon.m_isFinishedAll = true;
			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, false, false, 0.5f, 0.7f);
			Color color = m_icon.color;
			Color color2 = m_bg.color;
			m_icon.color = new Color(color.r, color.g, color.b, boosterUnused ? 1f : 0.4f);
			m_bg.color = new Color(color2.r, color2.g, color2.b, boosterUnused ? 1f : 0.3f);
			((TMP_Text)m_title).alpha = (boosterUnused ? 1f : 0.2f);
			completeWithNoBoosterIcon.m_titleVisible = true;
			completeWithNoBoosterIcon.m_isCleared = boosterUnused;
			if (boosterUnused)
			{
				completeWithNoBoosterIcon.m_isFinishedAll = true;
			}
			else
			{
				completeWithNoBoosterIcon.m_isFinishedAll = false;
				completeWithNoBoosterIcon.m_type = (LG_LayerType)0;
			}
			((Component)completeWithNoBoosterIcon.m_rightSideText).gameObject.SetActive(false);
			TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.ExpeditionSuccessPage.AllClearWithNoBoosterUsed");
			if (block != null)
			{
				((TMP_Text)completeWithNoBoosterIcon.m_title).SetText(Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID), true);
			}
			else
			{
				((TMP_Text)completeWithNoBoosterIcon.m_title).SetText("<color=orange>OMNIPOTENT</color>", true);
			}
			((Component)completeWithNoBoosterIcon.m_title).gameObject.SetActive(true);
		}

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

plugins/net6/Inas07.ThermalSights.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json.Serialization;
using AssetShards;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using ExtraObjectiveSetup.BaseClasses;
using ExtraObjectiveSetup.Expedition.Gears;
using ExtraObjectiveSetup.Utils;
using FirstPersonItem;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using ThermalSights.Definition;
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.ThermalSights")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Inas07.ThermalSights")]
[assembly: AssemblyTitle("Inas07.ThermalSights")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[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 ThermalSights
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Inas.ThermalSights", "ThermalSights", "1.0.0")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string PLUGIN_NAME = "ThermalSights";

		public const string VERSION = "1.0.0";

		private Harmony m_Harmony;

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

		private void SetupManagers()
		{
			AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)delegate
			{
				((GenericDefinitionManager<TSADefinition>)TSAManager.Current).Init();
			});
		}
	}
	public class TSAManager : GenericDefinitionManager<TSADefinition>
	{
		public class PuzzleVisualWrapper
		{
			public GameObject GO { get; set; }

			public Renderer Renderer { get; set; }

			public float Intensity { get; set; }

			public float BehindWallIntensity { get; set; }

			public void SetIntensity(float t)
			{
				if (GO.active)
				{
					if (Intensity > 0f)
					{
						Renderer.material.SetFloat("_Intensity", Intensity * t);
					}
					if (BehindWallIntensity > 0f)
					{
						Renderer.material.SetFloat("_BehindWallIntensity", BehindWallIntensity * t);
					}
				}
			}
		}

		private const bool OUTPUT_THERMAL_SHADER_SETTINGS_ON_WIELD = false;

		public static TSAManager Current { get; }

		protected override string DEFINITION_NAME => "ThermalSight";

		private Dictionary<uint, Renderer[]> InLevelGearThermals { get; } = new Dictionary<uint, Renderer[]>();


		private HashSet<uint> ModifiedInLevelGearThermals { get; } = new HashSet<uint>();


		private HashSet<uint> ThermalOfflineGears { get; } = new HashSet<uint>();


		public uint CurrentGearPID { get; private set; }

		private List<PuzzleVisualWrapper> PuzzleVisuals { get; } = new List<PuzzleVisualWrapper>();


		protected override void FileChanged(LiveEditEventArgs e)
		{
			base.FileChanged(e);
			InitThermalOfflineGears();
			CleanupInLevelGearThermals(keepCurrentGear: true);
			TrySetThermalSightRenderer(CurrentGearPID);
		}

		public override void Init()
		{
			InitThermalOfflineGears();
		}

		private void InitThermalOfflineGears()
		{
			ThermalOfflineGears.Clear();
			foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocks())
			{
				if (((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).name.ToLowerInvariant().EndsWith("_t"))
				{
					ThermalOfflineGears.Add(((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).persistentID);
				}
			}
			EOSLogger.Debug($"Found OfflineGear with thermal sight, count: {ThermalOfflineGears.Count}");
		}

		private bool TryGetInLevelGearThermalRenderersFromItem(ItemEquippable item, uint gearPID, out Renderer[] renderers)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			renderers = null;
			if (item.GearIDRange == null)
			{
				return false;
			}
			if (gearPID == 0)
			{
				gearPID = ExpeditionGearManager.GetOfflineGearPID(item.GearIDRange);
			}
			if (gearPID == 0 || !IsGearWithThermal(gearPID))
			{
				return false;
			}
			bool flag = false;
			if (!InLevelGearThermals.ContainsKey(gearPID))
			{
				flag = true;
			}
			else
			{
				try
				{
					_ = ((Component)InLevelGearThermals[gearPID][0]).gameObject.transform.position;
					flag = false;
				}
				catch
				{
					ModifiedInLevelGearThermals.Remove(gearPID);
					flag = true;
				}
			}
			if (flag)
			{
				renderers = (from x in ((IEnumerable<Renderer>)((Component)item).GetComponentsInChildren<Renderer>(true))?.Where((Renderer x) => (Object)(object)x.sharedMaterial != (Object)null && (Object)(object)x.sharedMaterial.shader != (Object)null)
					where ((Object)x.sharedMaterial.shader).name.ToLower().Contains("Thermal".ToLower())
					select x).ToArray() ?? null;
				if (renderers != null)
				{
					if (renderers.Length != 1)
					{
						EOSLogger.Warning(((Item)item).PublicName + " contains more than 1 thermal renderers!");
					}
					InLevelGearThermals[gearPID] = renderers;
					return true;
				}
				EOSLogger.Debug(((Item)item).PublicName + ": thermal renderer not found");
				return false;
			}
			renderers = InLevelGearThermals[gearPID];
			return true;
		}

		internal bool TrySetThermalSightRenderer(uint gearPID = 0u)
		{
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_0110: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			if (gearPID == 0)
			{
				gearPID = CurrentGearPID;
			}
			if (!IsGearWithThermal(gearPID))
			{
				return false;
			}
			if (ModifiedInLevelGearThermals.Contains(gearPID))
			{
				return true;
			}
			if (base.definitions.TryGetValue(gearPID, out var value) && InLevelGearThermals.TryGetValue(gearPID, out var value2))
			{
				TSShader shader = value.Definition.Shader;
				Renderer[] array = value2;
				foreach (Renderer val in array)
				{
					PropertyInfo[] properties = shader.GetType().GetProperties();
					foreach (PropertyInfo propertyInfo in properties)
					{
						Type type = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
						string text = "_" + propertyInfo.Name;
						if (type == typeof(float))
						{
							val.material.SetFloat(text, (float)propertyInfo.GetValue(shader));
						}
						else if (type == typeof(EOSColor))
						{
							EOSColor val2 = (EOSColor)propertyInfo.GetValue(shader);
							val.material.SetVector(text, Color.op_Implicit(val2.ToUnityColor()));
						}
						else if (type == typeof(bool))
						{
							bool flag = (bool)propertyInfo.GetValue(shader);
							val.material.SetFloat(text, flag ? 1f : 0f);
						}
						else if (type == typeof(Vec4))
						{
							Vec4 val3 = (Vec4)propertyInfo.GetValue(shader);
							val.material.SetVector(text, val3.ToVector4());
						}
					}
				}
				ModifiedInLevelGearThermals.Add(gearPID);
				return true;
			}
			return false;
		}

		internal void OnPlayerItemWielded(FirstPersonItemHolder fpsItemHolder, ItemEquippable item)
		{
			if (item.GearIDRange == null)
			{
				CurrentGearPID = 0u;
				return;
			}
			CurrentGearPID = ExpeditionGearManager.GetOfflineGearPID(item.GearIDRange);
			TryGetInLevelGearThermalRenderersFromItem(item, CurrentGearPID, out var _);
			TrySetThermalSightRenderer(CurrentGearPID);
		}

		public bool IsGearWithThermal(uint gearPID)
		{
			return ThermalOfflineGears.Contains(gearPID);
		}

		private void CleanupInLevelGearThermals(bool keepCurrentGear = false)
		{
			if (!keepCurrentGear || !InLevelGearThermals.ContainsKey(CurrentGearPID))
			{
				InLevelGearThermals.Clear();
			}
			else
			{
				Renderer[] value = InLevelGearThermals[CurrentGearPID];
				InLevelGearThermals.Clear();
				InLevelGearThermals[CurrentGearPID] = value;
			}
			ModifiedInLevelGearThermals.Clear();
		}

		internal void SetCurrentThermalSightSettings(float t)
		{
			if (InLevelGearThermals.TryGetValue(CurrentGearPID, out var value) && base.definitions.TryGetValue(CurrentGearPID, out var value2))
			{
				Renderer[] array = value;
				foreach (Renderer obj in array)
				{
					float zoom = value2.Definition.Shader.Zoom;
					float offAimPixelZoom = value2.Definition.OffAimPixelZoom;
					float num = Mathf.Lerp(zoom, offAimPixelZoom, t);
					obj.material.SetFloat("_Zoom", num);
				}
			}
		}

		private void Clear()
		{
			CurrentGearPID = 0u;
			CleanupInLevelGearThermals();
			CleanupPuzzleVisuals();
		}

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

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

		public void RegisterPuzzleVisual(CP_Bioscan_Core core)
		{
			Il2CppArrayBase<Renderer> componentsInChildren = ((Component)core).gameObject.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren == null)
			{
				return;
			}
			foreach (Renderer item2 in ((IEnumerable<Renderer>)componentsInChildren).Where((Renderer comp) => ((Object)((Component)comp).gameObject).name.Equals("Zone")).ToList())
			{
				GameObject gameObject = ((Component)item2).gameObject;
				float @float = item2.material.GetFloat("_Intensity");
				float float2 = item2.material.GetFloat("_BehindWallIntensity");
				PuzzleVisualWrapper item = new PuzzleVisualWrapper
				{
					GO = gameObject,
					Renderer = item2,
					Intensity = @float,
					BehindWallIntensity = float2
				};
				PuzzleVisuals.Add(item);
			}
		}

		public void RegisterPuzzleVisual(PuzzleVisualWrapper wrapper)
		{
			PuzzleVisuals.Add(wrapper);
		}

		internal void SetPuzzleVisualsIntensity(float t)
		{
			PuzzleVisuals.ForEach(delegate(PuzzleVisualWrapper v)
			{
				v.SetIntensity(t);
			});
		}

		private void CleanupPuzzleVisuals()
		{
			PuzzleVisuals.Clear();
		}
	}
}
namespace ThermalSights.Patches
{
	internal static class CP_Bioscan_Core_Setup
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")]
		private static void Post_CaptureBioscanVisual(CP_Bioscan_Core __instance)
		{
			TSAManager.Current.RegisterPuzzleVisual(__instance);
		}
	}
	[HarmonyPatch]
	internal static class FirstPersonItemHolder_SetWieldedItem
	{
		public static event Action<FirstPersonItemHolder, ItemEquippable> OnItemWielded;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FirstPersonItemHolder), "SetWieldedItem")]
		private static void Post_SetWieldedItem(FirstPersonItemHolder __instance, ItemEquippable item)
		{
			TSAManager.Current.OnPlayerItemWielded(__instance, item);
			TSAManager.Current.SetPuzzleVisualsIntensity(1f);
			TSAManager.Current.SetCurrentThermalSightSettings(1f);
			FirstPersonItemHolder_SetWieldedItem.OnItemWielded?.Invoke(__instance, item);
		}
	}
	[HarmonyPatch]
	internal static class FPIS_Aim_Update
	{
		public static event Action<FPIS_Aim, float> OnAimUpdate;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FPIS_Aim), "Update")]
		private static void Post_Aim_Update(FPIS_Aim __instance)
		{
			if (!((Object)(object)((FPItemState)__instance).Holder.WieldedItem == (Object)null))
			{
				float num = 1f - FirstPersonItemHolder.m_transitionDelta;
				if (!TSAManager.Current.IsGearWithThermal(TSAManager.Current.CurrentGearPID))
				{
					num = Math.Max(0.05f, num);
				}
				else
				{
					TSAManager.Current.SetCurrentThermalSightSettings(num);
				}
				TSAManager.Current.SetPuzzleVisualsIntensity(num);
				FPIS_Aim_Update.OnAimUpdate?.Invoke(__instance, num);
			}
		}
	}
}
namespace ThermalSights.Definition
{
	public class TSADefinition
	{
		public float OffAimPixelZoom { get; set; } = 1f;


		public TSShader Shader { get; set; } = new TSShader();

	}
	public class TSShader
	{
		[JsonPropertyName("DistanceFalloff")]
		[Range(0.0, 1.0)]
		public float HeatFalloff { get; set; } = 0.01f;


		[Range(0.0, 1.0)]
		public float FogFalloff { get; set; } = 0.1f;


		[JsonPropertyName("PixelZoom")]
		[Range(0.0, 1.0)]
		public float Zoom { get; set; } = 0.8f;


		[JsonPropertyName("AspectRatioAdjust")]
		[Range(0.0, 2.0)]
		public float RatioAdjust { get; set; } = 1f;


		[Range(0.0, 1.0)]
		public float DistortionCenter { get; set; } = 0.5f;


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


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


		public float DistortionSignalSpeed { get; set; } = 0.025f;


		[Range(0.0, 1.0)]
		public float DistortionMin { get; set; } = 0.01f;


		[Range(0.0, 1.0)]
		public float DistortionMax { get; set; } = 0.4f;


		[JsonPropertyName("AmbientTemperature")]
		[Range(0.0, 1.0)]
		public float AmbientTemp { get; set; } = 0.15f;


		[JsonPropertyName("BackgroundTemperature")]
		[Range(0.0, 1.0)]
		public float BackgroundTemp { get; set; } = 0.05f;


		[Range(0.0, 10.0)]
		public float AlbedoColorFactor { get; set; } = 0.5f;


		[Range(0.0, 10.0)]
		public float AmbientColorFactor { get; set; } = 5f;


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


		public float BodyOcclusionHeat { get; set; } = 2.5f;


		[Range(0.0, 1.0)]
		public float ScreenIntensity { get; set; } = 0.2f;


		[Range(0.0, 1.0)]
		public float OffAngleFade { get; set; } = 0.95f;


		[Range(0.0, 1.0)]
		public float Noise { get; set; } = 0.1f;


		[JsonPropertyName("MinShadowEnemyDistortion")]
		[Range(0.0, 1.0)]
		public float DistortionMinShadowEnemies { get; set; } = 0.2f;


		[JsonPropertyName("MaxShadowEnemyDistortion")]
		[Range(0.0, 1.0)]
		public float DistortionMaxShadowEnemies { get; set; } = 1f;


		[Range(0.0, 1.0)]
		public float DistortionSignalSpeedShadowEnemies { get; set; } = 1f;


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


		[Range(0.0, 1.0)]
		public float ShadowEnemyHeat { get; set; } = 0.1f;


		public EOSColor ReticuleColorA { get; set; } = new EOSColor
		{
			r = 1f,
			g = 1f,
			b = 1f,
			a = 1f
		};


		public EOSColor ReticuleColorB { get; set; } = new EOSColor
		{
			r = 1f,
			g = 1f,
			b = 1f,
			a = 1f
		};


		public EOSColor ReticuleColorC { get; set; } = new EOSColor
		{
			r = 1f,
			g = 1f,
			b = 1f,
			a = 1f
		};


		[Range(0.0, 20.0)]
		public float SightDirt { get; set; }

		public bool LitGlass { get; set; }

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


		public Vec4 AxisX { get; set; } = new Vec4();


		public Vec4 AxisY { get; set; } = new Vec4();


		public Vec4 AxisZ { get; set; } = new Vec4();


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


		[JsonPropertyName("Distance1")]
		[Range(0.0, 100.0)]
		public float ProjDist1 { get; set; } = 100f;


		[JsonPropertyName("Distance2")]
		[Range(0.0, 100.0)]
		public float ProjDist2 { get; set; } = 66f;


		[JsonPropertyName("Distance3")]
		[Range(0.0, 100.0)]
		public float ProjDist3 { get; set; } = 33f;


		[JsonPropertyName("Size1")]
		[Range(0.0, 3.0)]
		public float ProjSize1 { get; set; } = 1f;


		[JsonPropertyName("Size2")]
		[Range(0.0, 3.0)]
		public float ProjSize2 { get; set; } = 1f;


		[JsonPropertyName("Size3")]
		[Range(0.0, 3.0)]
		public float ProjSize3 { get; set; } = 1f;


		[JsonPropertyName("Zeroing")]
		[Range(-1.0, 1.0)]
		public float ZeroOffset { get; set; }
	}
}

plugins/net6/KillIndicatorFix.dll

Decompiled a week 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 API;
using Agents;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Enemies;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using KillIndicatorFix.BepInEx;
using KillIndicatorFix.Patches;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;
using UnityEngine.Analytics;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("KillIndicatorFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a713a64d1323e013d952ed587cc3e798e9167afe")]
[assembly: AssemblyProduct("KillIndicatorFix")]
[assembly: AssemblyTitle("KillIndicatorFix")]
[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]
	[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;
		}
	}
}
internal static class BitHelper
{
	public const int SizeOfHalf = 2;

	public const int SizeOfVector3 = 12;

	public const int SizeOfQuaternion = 13;

	public const int SizeOfHalfVector3 = 6;

	public const int SizeOfHalfQuaternion = 7;

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static uint RotateLeft(uint value, int offset)
	{
		return (value << offset) | (value >> 32 - offset);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static uint RotateRight(uint value, int offset)
	{
		return (value >> offset) | (value << 32 - offset);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static long ReverseEndianness(long value)
	{
		return (long)ReverseEndianness((ulong)value);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static int ReverseEndianness(int value)
	{
		return (int)ReverseEndianness((uint)value);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static short ReverseEndianness(short value)
	{
		return (short)ReverseEndianness((ushort)value);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static ushort ReverseEndianness(ushort value)
	{
		return (ushort)((value >> 8) + (value << 8));
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static uint ReverseEndianness(uint value)
	{
		return RotateRight(value & 0xFF00FFu, 8) + RotateLeft(value & 0xFF00FF00u, 8);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static ulong ReverseEndianness(ulong value)
	{
		return ((ulong)ReverseEndianness((uint)value) << 32) + ReverseEndianness((uint)(value >> 32));
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private unsafe static void _WriteBytes(byte* source, int size, byte[] destination, ref int index)
	{
		int num = 0;
		while (num < size)
		{
			destination[index++] = source[num++];
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static void WriteBytes(byte value, byte[] destination, ref int index)
	{
		destination[index++] = value;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static void WriteBytes(bool value, byte[] destination, ref int index)
	{
		destination[index++] = (value ? ((byte)1) : ((byte)0));
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static void WriteBytes(ulong value, byte[] destination, ref int index)
	{
		if (!BitConverter.IsLittleEndian)
		{
			value = ReverseEndianness(value);
		}
		_WriteBytes((byte*)(&value), 8, destination, ref index);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static void WriteBytes(uint value, byte[] destination, ref int index)
	{
		if (!BitConverter.IsLittleEndian)
		{
			value = ReverseEndianness(value);
		}
		_WriteBytes((byte*)(&value), 4, destination, ref index);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static void WriteBytes(ushort value, byte[] destination, ref int index)
	{
		if (!BitConverter.IsLittleEndian)
		{
			value = ReverseEndianness(value);
		}
		_WriteBytes((byte*)(&value), 2, destination, ref index);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static void WriteBytes(long value, byte[] destination, ref int index)
	{
		if (!BitConverter.IsLittleEndian)
		{
			value = ReverseEndianness(value);
		}
		_WriteBytes((byte*)(&value), 8, destination, ref index);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static void WriteBytes(int value, byte[] destination, ref int index)
	{
		if (!BitConverter.IsLittleEndian)
		{
			value = ReverseEndianness(value);
		}
		_WriteBytes((byte*)(&value), 4, destination, ref index);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static void WriteBytes(short value, byte[] destination, ref int index)
	{
		if (!BitConverter.IsLittleEndian)
		{
			value = ReverseEndianness(value);
		}
		_WriteBytes((byte*)(&value), 2, destination, ref index);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static void WriteBytes(float value, byte[] destination, ref int index)
	{
		int value2 = *(int*)(&value);
		if (!BitConverter.IsLittleEndian)
		{
			value2 = ReverseEndianness(value2);
		}
		_WriteBytes((byte*)(&value2), 4, destination, ref index);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static void WriteBytes(string value, byte[] destination, ref int index)
	{
		byte[] bytes = Encoding.UTF8.GetBytes(value);
		WriteBytes((ushort)bytes.Length, destination, ref index);
		Array.Copy(bytes, 0, destination, index, bytes.Length);
		index += bytes.Length;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static void WriteBytes(byte[] buffer, byte[] destination, ref int index)
	{
		WriteBytes((ushort)buffer.Length, destination, ref index);
		Array.Copy(buffer, 0, destination, index, buffer.Length);
		index += buffer.Length;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static void WriteHalf(float value, byte[] destination, ref int index)
	{
		WriteBytes(FloatToHalf(value), destination, ref index);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private unsafe static uint AsUInt(float x)
	{
		return *(uint*)(&x);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private unsafe static float AsFloat(uint x)
	{
		return *(float*)(&x);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static float HalfToFloat(ushort x)
	{
		int num = (x & 0x7C00) >> 10;
		int num2 = (x & 0x3FF) << 13;
		int num3 = (int)(AsUInt(num2) >> 23);
		return AsFloat((uint)(((x & 0x8000) << 16) | (Convert.ToInt32(num != 0) * ((num + 112 << 23) | num2)) | ((Convert.ToInt32(num == 0) & Convert.ToInt32(num2 != 0)) * ((num3 - 37 << 23) | ((num2 << 150 - num3) & 0x7FE000)))));
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static ushort FloatToHalf(float x)
	{
		uint num = AsUInt(x) + 4096;
		uint num2 = (num & 0x7F800000) >> 23;
		uint num3 = num & 0x7FFFFFu;
		return (ushort)(((num & 0x80000000u) >> 16) | (Convert.ToInt32(num2 > 112) * (((num2 - 112 << 10) & 0x7C00) | (num3 >> 13))) | ((Convert.ToInt32(num2 < 113) & Convert.ToInt32(num2 > 101)) * ((8384512 + num3 >> (int)(125 - num2)) + 1 >> 1)) | (Convert.ToUInt32(num2 > 143) * 32767));
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static byte ReadByte(byte[] source, ref int index)
	{
		return source[index++];
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static bool ReadBool(byte[] source, ref int index)
	{
		return source[index++] != 0;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static ulong ReadULong(byte[] source, ref int index)
	{
		fixed (byte* ptr = source)
		{
			byte* num = ptr + index;
			index += 8;
			ulong num2 = *(ulong*)num;
			if (!BitConverter.IsLittleEndian)
			{
				num2 = ReverseEndianness(num2);
			}
			return num2;
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static long ReadLong(byte[] source, ref int index)
	{
		fixed (byte* ptr = source)
		{
			byte* num = ptr + index;
			index += 8;
			long num2 = *(long*)num;
			if (!BitConverter.IsLittleEndian)
			{
				num2 = ReverseEndianness(num2);
			}
			return num2;
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static uint ReadUInt(byte[] source, ref int index)
	{
		fixed (byte* ptr = source)
		{
			byte* num = ptr + index;
			index += 4;
			uint num2 = *(uint*)num;
			if (!BitConverter.IsLittleEndian)
			{
				num2 = ReverseEndianness(num2);
			}
			return num2;
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static int ReadInt(byte[] source, ref int index)
	{
		fixed (byte* ptr = source)
		{
			byte* num = ptr + index;
			index += 4;
			int num2 = *(int*)num;
			if (!BitConverter.IsLittleEndian)
			{
				num2 = ReverseEndianness(num2);
			}
			return num2;
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static ushort ReadUShort(byte[] source, ref int index)
	{
		fixed (byte* ptr = source)
		{
			byte* num = ptr + index;
			index += 2;
			ushort num2 = *(ushort*)num;
			if (!BitConverter.IsLittleEndian)
			{
				num2 = ReverseEndianness(num2);
			}
			return num2;
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static short ReadShort(byte[] source, ref int index)
	{
		fixed (byte* ptr = source)
		{
			byte* num = ptr + index;
			index += 2;
			short num2 = *(short*)num;
			if (!BitConverter.IsLittleEndian)
			{
				num2 = ReverseEndianness(num2);
			}
			return num2;
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static float ReadHalf(byte[] source, ref int index)
	{
		return HalfToFloat(ReadUShort(source, ref index));
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public unsafe static float ReadFloat(byte[] source, ref int index)
	{
		fixed (byte* ptr = source)
		{
			byte* ptr2 = ptr + index;
			index += 4;
			if (!BitConverter.IsLittleEndian)
			{
				int num = ReverseEndianness(*(int*)ptr2);
				return *(float*)(&num);
			}
			return *(float*)ptr2;
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static string ReadString(byte[] source, ref int index)
	{
		int num = ReadUShort(source, ref index);
		string @string = Encoding.UTF8.GetString(source, index, num);
		index += num;
		return @string;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public static void WriteBytes(Vector3 value, byte[] destination, ref int index)
	{
		//IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references)
		WriteBytes(value.x, destination, ref index);
		WriteBytes(value.y, destination, ref index);
		WriteBytes(value.z, destination, ref index);
	}

	public static void WriteBytes(Quaternion value, byte[] destination, ref int index)
	{
		//IL_0000: 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_001b: 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_002d: 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: 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_00be: 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_017e: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: 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_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: 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_00cb: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: 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)
		//IL_012b: 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_0145: 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_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: 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_0198: 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)
		float num = value.x;
		byte b = 0;
		if (value.y > num)
		{
			num = value.y;
			b = 1;
		}
		if (value.z > num)
		{
			num = value.z;
			b = 2;
		}
		if (value.w > num)
		{
			num = value.w;
			b = 3;
		}
		WriteBytes(b, destination, ref index);
		switch (b)
		{
		case 0:
			if (value.x >= 0f)
			{
				WriteBytes(value.y, destination, ref index);
				WriteBytes(value.z, destination, ref index);
				WriteBytes(value.w, destination, ref index);
			}
			else
			{
				WriteBytes(0f - value.y, destination, ref index);
				WriteBytes(0f - value.z, destination, ref index);
				WriteBytes(0f - value.w, destination, ref index);
			}
			break;
		case 1:
			if (value.y >= 0f)
			{
				WriteBytes(value.x, destination, ref index);
				WriteBytes(value.z, destination, ref index);
				WriteBytes(value.w, destination, ref index);
			}
			else
			{
				WriteBytes(0f - value.x, destination, ref index);
				WriteBytes(0f - value.z, destination, ref index);
				WriteBytes(0f - value.w, destination, ref index);
			}
			break;
		case 2:
			if (value.z >= 0f)
			{
				WriteBytes(value.x, destination, ref index);
				WriteBytes(value.y, destination, ref index);
				WriteBytes(value.w, destination, ref index);
			}
			else
			{
				WriteBytes(0f - value.x, destination, ref index);
				WriteBytes(0f - value.y, destination, ref index);
				WriteBytes(0f - value.w, destination, ref index);
			}
			break;
		case 3:
			if (value.w >= 0f)
			{
				WriteBytes(value.x, destination, ref index);
				WriteBytes(value.y, destination, ref index);
				WriteBytes(value.z, destination, ref index);
			}
			else
			{
				WriteBytes(0f - value.x, destination, ref index);
				WriteBytes(0f - value.y, destination, ref index);
				WriteBytes(0f - value.z, destination, ref index);
			}
			break;
		}
	}

	public static Vector3 ReadVector3(byte[] source, ref int index)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3(ReadFloat(source, ref index), ReadFloat(source, ref index), ReadFloat(source, ref index));
	}

	public static Quaternion ReadQuaternion(byte[] source, ref int index)
	{
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		byte b = ReadByte(source, ref index);
		float num = 0f;
		float num2 = 0f;
		float num3 = 0f;
		float num4 = 0f;
		switch (b)
		{
		case 0:
			num2 = ReadFloat(source, ref index);
			num3 = ReadFloat(source, ref index);
			num4 = ReadFloat(source, ref index);
			num = Mathf.Sqrt(1f - num2 * num2 - num3 * num3 - num4 * num4);
			break;
		case 1:
			num = ReadFloat(source, ref index);
			num3 = ReadFloat(source, ref index);
			num4 = ReadFloat(source, ref index);
			num2 = Mathf.Sqrt(1f - num * num - num3 * num3 - num4 * num4);
			break;
		case 2:
			num = ReadFloat(source, ref index);
			num2 = ReadFloat(source, ref index);
			num4 = ReadFloat(source, ref index);
			num3 = Mathf.Sqrt(1f - num * num - num2 * num2 - num4 * num4);
			break;
		case 3:
			num = ReadFloat(source, ref index);
			num2 = ReadFloat(source, ref index);
			num3 = ReadFloat(source, ref index);
			num4 = Mathf.Sqrt(1f - num * num - num2 * num2 - num3 * num3);
			break;
		}
		return new Quaternion(num, num2, num3, num4);
	}

	public static void WriteHalf(Vector3 value, byte[] destination, ref int index)
	{
		//IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references)
		WriteHalf(value.x, destination, ref index);
		WriteHalf(value.y, destination, ref index);
		WriteHalf(value.z, destination, ref index);
	}

	public static void WriteHalf(Quaternion value, byte[] destination, ref int index)
	{
		//IL_0000: 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_001b: 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_002d: 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: 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_00be: 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_017e: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: 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_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: 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_00cb: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: 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)
		//IL_012b: 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_0145: 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_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: 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_0198: 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)
		float num = value.x;
		byte b = 0;
		if (value.y > num)
		{
			num = value.y;
			b = 1;
		}
		if (value.z > num)
		{
			num = value.z;
			b = 2;
		}
		if (value.w > num)
		{
			num = value.w;
			b = 3;
		}
		WriteBytes(b, destination, ref index);
		switch (b)
		{
		case 0:
			if (value.x >= 0f)
			{
				WriteHalf(value.y, destination, ref index);
				WriteHalf(value.z, destination, ref index);
				WriteHalf(value.w, destination, ref index);
			}
			else
			{
				WriteHalf(0f - value.y, destination, ref index);
				WriteHalf(0f - value.z, destination, ref index);
				WriteHalf(0f - value.w, destination, ref index);
			}
			break;
		case 1:
			if (value.y >= 0f)
			{
				WriteHalf(value.x, destination, ref index);
				WriteHalf(value.z, destination, ref index);
				WriteHalf(value.w, destination, ref index);
			}
			else
			{
				WriteHalf(0f - value.x, destination, ref index);
				WriteHalf(0f - value.z, destination, ref index);
				WriteHalf(0f - value.w, destination, ref index);
			}
			break;
		case 2:
			if (value.z >= 0f)
			{
				WriteHalf(value.x, destination, ref index);
				WriteHalf(value.y, destination, ref index);
				WriteHalf(value.w, destination, ref index);
			}
			else
			{
				WriteHalf(0f - value.x, destination, ref index);
				WriteHalf(0f - value.y, destination, ref index);
				WriteHalf(0f - value.w, destination, ref index);
			}
			break;
		case 3:
			if (value.w >= 0f)
			{
				WriteHalf(value.x, destination, ref index);
				WriteHalf(value.y, destination, ref index);
				WriteHalf(value.z, destination, ref index);
			}
			else
			{
				WriteHalf(0f - value.x, destination, ref index);
				WriteHalf(0f - value.y, destination, ref index);
				WriteHalf(0f - value.z, destination, ref index);
			}
			break;
		}
	}

	public static Vector3 ReadHalfVector3(byte[] source, ref int index)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3(ReadHalf(source, ref index), ReadHalf(source, ref index), ReadHalf(source, ref index));
	}

	public static Quaternion ReadHalfQuaternion(byte[] source, ref int index)
	{
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		byte b = ReadByte(source, ref index);
		float num = 0f;
		float num2 = 0f;
		float num3 = 0f;
		float num4 = 0f;
		switch (b)
		{
		case 0:
			num2 = ReadHalf(source, ref index);
			num3 = ReadHalf(source, ref index);
			num4 = ReadHalf(source, ref index);
			num = Mathf.Sqrt(1f - num2 * num2 - num3 * num3 - num4 * num4);
			break;
		case 1:
			num = ReadHalf(source, ref index);
			num3 = ReadHalf(source, ref index);
			num4 = ReadHalf(source, ref index);
			num2 = Mathf.Sqrt(1f - num * num - num3 * num3 - num4 * num4);
			break;
		case 2:
			num = ReadHalf(source, ref index);
			num2 = ReadHalf(source, ref index);
			num4 = ReadHalf(source, ref index);
			num3 = Mathf.Sqrt(1f - num * num - num2 * num2 - num4 * num4);
			break;
		case 3:
			num = ReadHalf(source, ref index);
			num2 = ReadHalf(source, ref index);
			num3 = ReadHalf(source, ref index);
			num4 = Mathf.Sqrt(1f - num * num - num2 * num2 - num3 * num3);
			break;
		}
		return new Quaternion(num, num2, num3, num4);
	}
}
namespace API
{
	internal static class APILogger
	{
		private static readonly ManualLogSource logger;

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

		private static string Format(string module, object msg)
		{
			return $"[{module}]: {msg}";
		}

		public static void Info(string module, object data)
		{
			logger.LogMessage((object)Format(module, data));
		}

		public static void Verbose(string module, object data)
		{
		}

		public static void Log(object data)
		{
			logger.LogDebug((object)Format("KillIndicatorFix", data));
		}

		public static void Debug(object data)
		{
			if (ConfigManager.Debug)
			{
				Log(data);
			}
		}

		public static void Warn(object data)
		{
			logger.LogWarning((object)Format("KillIndicatorFix", data));
		}

		public static void Error(object data)
		{
			logger.LogError((object)Format("KillIndicatorFix", data));
		}
	}
}
namespace KillIndicatorFix
{
	internal static class Utils
	{
		public const BindingFlags AnyBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
	}
	public static class Kill
	{
		public static Action<EnemyAgent, ItemEquippable, long>? OnKillIndicator;

		private static void RegisterMethods(Type t)
		{
			foreach (MethodInfo item in from m in t.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
				where m.GetCustomAttribute<OnKillIndicator>() != null
				select m)
			{
				if (item.IsStatic)
				{
					try
					{
						string value = "OnKillIndicator";
						if (item.GetCustomAttribute<OnKillIndicator>() != null)
						{
							value = "OnKillIndicator";
							OnKillIndicator = (Action<EnemyAgent, ItemEquippable, long>)Delegate.Combine(OnKillIndicator, (Action<EnemyAgent, ItemEquippable, long>)item.CreateDelegate(typeof(Action<EnemyAgent, ItemEquippable, long>)));
						}
						APILogger.Debug($"Registered {value}: '{t.FullName}.{item.Name}'");
					}
					catch (Exception value2)
					{
						APILogger.Error($"Failed to register method: {value2}");
					}
				}
				else
				{
					APILogger.Error($"KillIndicatorFix attributes can only be applied to static methods. '{item}' is not static.");
				}
			}
		}

		public static void RegisterAll()
		{
			Type[] types = Assembly.GetCallingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				RegisterMethods(types[i]);
			}
		}

		public static void RegisterAll(Type type)
		{
			Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (Type obj in nestedTypes)
			{
				RegisterMethods(obj);
				RegisterAll(obj);
			}
		}

		internal static void TriggerOnKillIndicator(EnemyAgent enemy, ItemEquippable item, long delay)
		{
			try
			{
				OnKillIndicator?.Invoke(enemy, item, delay);
			}
			catch (Exception value)
			{
				APILogger.Error($"TriggerOnKillIndicator: {value}");
			}
		}

		public static void TagEnemy(EnemyAgent enemy, ItemEquippable? item = null, Vector3? localHitPosition = null)
		{
			//IL_0085: 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)
			//IL_005c: 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)
			int instanceID = ((Object)enemy).GetInstanceID();
			long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds();
			if (!localHitPosition.HasValue)
			{
				localHitPosition = ((!KillIndicatorFix.Patches.Kill.taggedEnemies.ContainsKey(instanceID)) ? new Vector3?(((Agent)enemy).EyePosition - ((Component)enemy).transform.position) : new Vector3?(KillIndicatorFix.Patches.Kill.taggedEnemies[instanceID].localHitPosition));
			}
			if ((Object)(object)item == (Object)null)
			{
				item = PlayerManager.GetLocalPlayerAgent().Inventory.WieldedItem;
			}
			KillIndicatorFix.Patches.Kill.Tag value = new KillIndicatorFix.Patches.Kill.Tag(timestamp, localHitPosition.Value, item);
			if (KillIndicatorFix.Patches.Kill.taggedEnemies.ContainsKey(instanceID))
			{
				KillIndicatorFix.Patches.Kill.taggedEnemies[instanceID] = value;
			}
			else
			{
				KillIndicatorFix.Patches.Kill.taggedEnemies.Add(instanceID, value);
			}
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class OnKillIndicator : Attribute
	{
	}
}
namespace KillIndicatorFix.Patches
{
	[HarmonyPatch(typeof(GameDataInit))]
	internal class GameDataInit_Patches
	{
		[HarmonyPatch("Initialize")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		public static void Initialize_Postfix()
		{
			Analytics.enabled = false;
		}
	}
	[HarmonyPatch]
	internal static class Kill
	{
		public struct Tag
		{
			public long timestamp;

			public Vector3 localHitPosition;

			public ItemEquippable item;

			public Tag(long timestamp, Vector3 localHitPosition, ItemEquippable item)
			{
				//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)
				this.timestamp = timestamp;
				this.localHitPosition = localHitPosition;
				this.item = item;
			}
		}

		public static Dictionary<int, Tag> taggedEnemies = new Dictionary<int, Tag>();

		internal static bool sentryShot = false;

		public static void OnRundownStart()
		{
			APILogger.Debug("OnRundownStart => Reset Trackers and Markers.");
			taggedEnemies.Clear();
		}

		[HarmonyPatch(typeof(EnemyBehaviour), "ChangeState", new Type[] { typeof(EB_States) })]
		[HarmonyPrefix]
		public static void OnDead(EnemyBehaviour __instance, EB_States state)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0111: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			if (SNet.IsMaster || __instance.m_currentStateName == state || (int)state != 19)
			{
				return;
			}
			APILogger.Debug("EnemyAppearance.OnDead");
			try
			{
				EnemyAgent enemyAgent = __instance.m_ai.m_enemyAgent;
				int instanceID = ((Object)enemyAgent).GetInstanceID();
				long num = ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds();
				if (!taggedEnemies.ContainsKey(instanceID))
				{
					return;
				}
				Tag tag = taggedEnemies[instanceID];
				if (tag.timestamp <= num)
				{
					APILogger.Debug($"Received kill update {num - tag.timestamp} milliseconds after tag.");
				}
				else
				{
					APILogger.Debug("Received kill update for enemy that was tagged in the future? Possibly long overflow...");
				}
				if (tag.timestamp <= num && num - tag.timestamp < ConfigManager.TagBufferPeriod)
				{
					if (!enemyAgent.Damage.DeathIndicatorShown)
					{
						APILogger.Debug("Client side marker was not shown, showing server side one.");
						KillIndicatorFix.Kill.TriggerOnKillIndicator(enemyAgent, tag.item, num - tag.timestamp);
						CrosshairGuiLayer crosshairLayer = GuiManager.CrosshairLayer;
						if (crosshairLayer != null)
						{
							crosshairLayer.ShowDeathIndicator(((Component)enemyAgent).transform.position + tag.localHitPosition);
						}
						enemyAgent.Damage.DeathIndicatorShown = true;
					}
					else
					{
						APILogger.Debug("Client side marker was shown, not showing server side one.");
					}
				}
				else
				{
					APILogger.Debug("Client was no longer interested in this enemy, marker will not be shown.");
				}
				taggedEnemies.Remove(instanceID);
			}
			catch
			{
				APILogger.Debug("Something went wrong.");
			}
		}

		[HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "FireBullet")]
		[HarmonyPrefix]
		private static void Prefix_SentryGunFiringBullet(SentryGunInstance_Firing_Bullets __instance, bool doDamage, bool targetIsTagged)
		{
			if (doDamage)
			{
				sentryShot = true;
			}
		}

		[HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "FireBullet")]
		[HarmonyPostfix]
		private static void Postfix_SentryGunFiringBullet()
		{
			sentryShot = false;
		}

		[HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "UpdateFireShotgunSemi")]
		[HarmonyPrefix]
		private static void Prefix_ShotgunSentryFiring(SentryGunInstance_Firing_Bullets __instance, bool isMaster, bool targetIsTagged)
		{
			if (isMaster)
			{
				sentryShot = true;
			}
		}

		[HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "UpdateFireShotgunSemi")]
		[HarmonyPostfix]
		private static void Postfix_ShotgunSentryFiring()
		{
			sentryShot = false;
		}

		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "BulletDamage")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		public static void EnemyLimb_BulletDamage(Dam_EnemyDamageLimb __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, Vector3 normal, bool allowDirectionalBonus, float staggerMulti, float precisionMulti)
		{
			//IL_0039: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster || !sentryShot)
			{
				return;
			}
			PlayerAgent val = ((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>();
			if ((Object)(object)val == (Object)null)
			{
				APILogger.Debug($"Could not find PlayerAgent, damage was done by agent of type: {sourceAgent.m_type}.");
			}
			else if (!val.Owner.IsBot && !sourceAgent.IsLocallyOwned)
			{
				Dam_EnemyDamageBase @base = __instance.m_base;
				EnemyAgent owner = @base.Owner;
				float num = dam;
				if (!@base.IsImortal)
				{
					num = __instance.ApplyWeakspotAndArmorModifiers(dam, precisionMulti);
					num = __instance.ApplyDamageFromBehindBonus(num, position, direction, 1f);
					bool willDie = ((Dam_SyncedDamageBase)@base).WillDamageKill(num);
					Network.SendHitIndicator((Agent)(object)owner, (byte)__instance.m_limbID, val, num > dam, willDie, position, __instance.m_armorDamageMulti < 1f);
				}
				else
				{
					Network.SendHitIndicator((Agent)(object)owner, (byte)__instance.m_limbID, val, num > dam, willDie: false, position, hitArmor: true);
				}
			}
		}

		[HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveBulletDamage")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		public static void Player_BulletDamage(Dam_PlayerDamageBase __instance, pBulletDamageData data)
		{
			//IL_004a: 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)
			Agent val = default(Agent);
			if (!SNet.IsMaster || !((pAgent)(ref data.source)).TryGet(ref val) || !sentryShot)
			{
				return;
			}
			PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>();
			if ((Object)(object)val2 == (Object)null)
			{
				APILogger.Debug($"Could not find PlayerAgent, damage was done by agent of type: {val.m_type}.");
			}
			else if (!val2.Owner.IsBot && !val.IsLocallyOwned)
			{
				PlayerAgent owner = __instance.Owner;
				if ((Object)(object)owner != (Object)(object)val2)
				{
					Network.SendHitIndicator((Agent)(object)owner, 0, val2, hitWeakspot: false, willDie: false, Vector3.zero);
				}
			}
		}

		[HarmonyPatch(typeof(Dam_EnemyDamageBase), "BulletDamage")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		public static void BulletDamage(Dam_EnemyDamageBase __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, bool allowDirectionalBonus, int limbID, float precisionMulti)
		{
			//IL_0031: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (SNet.IsMaster)
			{
				return;
			}
			PlayerAgent val = ((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>();
			if ((Object)(object)val == (Object)null)
			{
				APILogger.Debug($"Could not find PlayerAgent, damage was done by agent of type: {sourceAgent.m_type}.");
			}
			else if (!val.Owner.IsBot)
			{
				EnemyAgent owner = __instance.Owner;
				int instanceID = ((Object)owner).GetInstanceID();
				long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds();
				float num = AgentModifierManager.ApplyModifier((Agent)(object)owner, (AgentModifier)7, Mathf.Clamp(dam, 0f, ((Dam_SyncedDamageBase)__instance).HealthMax));
				((Dam_SyncedDamageBase)__instance).Health = ((Dam_SyncedDamageBase)__instance).Health - num;
				Vector3 localHitPosition = position - ((Component)owner).transform.position;
				Tag value = new Tag(timestamp, localHitPosition, val.Inventory.WieldedItem);
				if (taggedEnemies.ContainsKey(instanceID))
				{
					taggedEnemies[instanceID] = value;
				}
				else
				{
					taggedEnemies.Add(instanceID, value);
				}
				APILogger.Debug($"{num} Bullet Damage done by {val.PlayerName}. IsBot: {val.Owner.IsBot}");
				APILogger.Debug($"Tracked current HP: {((Dam_SyncedDamageBase)__instance).Health}, [{((Object)owner).GetInstanceID()}]");
			}
		}

		[HarmonyPatch(typeof(Dam_EnemyDamageBase), "MeleeDamage")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		public static void MeleeDamage(Dam_EnemyDamageBase __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, int limbID, float staggerMulti, float precisionMulti, float sleeperMulti, bool skipLimbDestruction, DamageNoiseLevel damageNoiseLevel)
		{
			//IL_0031: 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_00b0: Invalid comparison between Unknown and I4
			//IL_00c8: 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_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)
			if (SNet.IsMaster)
			{
				return;
			}
			PlayerAgent val = ((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>();
			if ((Object)(object)val == (Object)null)
			{
				APILogger.Debug($"Could not find PlayerAgent, damage was done by agent of type: {sourceAgent.m_type}.");
			}
			else if (!val.Owner.IsBot)
			{
				EnemyAgent owner = __instance.Owner;
				int instanceID = ((Object)owner).GetInstanceID();
				long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds();
				float num = AgentModifierManager.ApplyModifier((Agent)(object)owner, (AgentModifier)6, Mathf.Clamp(dam, 0f, ((Dam_SyncedDamageBase)__instance).DamageMax));
				if ((int)__instance.Owner.Locomotion.CurrentStateEnum == 14)
				{
					num *= sleeperMulti;
				}
				((Dam_SyncedDamageBase)__instance).Health = ((Dam_SyncedDamageBase)__instance).Health - num;
				Vector3 localHitPosition = position - ((Component)owner).transform.position;
				Tag value = new Tag(timestamp, localHitPosition, val.Inventory.WieldedItem);
				if (taggedEnemies.ContainsKey(instanceID))
				{
					taggedEnemies[instanceID] = value;
				}
				else
				{
					taggedEnemies.Add(instanceID, value);
				}
				APILogger.Debug($"Melee Damage: {num}");
				APILogger.Debug($"Tracked current HP: {((Dam_SyncedDamageBase)__instance).Health}, [{((Object)owner).GetInstanceID()}]");
			}
		}

		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "ShowHitIndicator")]
		[HarmonyPrefix]
		public static void ShowDeathIndicator(Dam_EnemyDamageLimb __instance, bool hitWeakspot, bool willDie, Vector3 position, bool hitArmor)
		{
			EnemyAgent owner = __instance.m_base.Owner;
			((Object)owner).GetInstanceID();
			((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds();
			if (willDie && !__instance.m_base.DeathIndicatorShown)
			{
				PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
				ItemEquippable item = localPlayerAgent.Inventory.WieldedItem;
				BackpackItem val = default(BackpackItem);
				if (sentryShot && PlayerBackpackManager.TryGetItem(localPlayerAgent.Owner, (InventorySlot)3, ref val))
				{
					item = ((Il2CppObjectBase)val.Instance).Cast<ItemEquippable>();
				}
				KillIndicatorFix.Kill.TriggerOnKillIndicator(owner, item, 0L);
			}
		}
	}
	[HarmonyPatch]
	internal static class Network
	{
		private static byte msgtype = 173;

		private static uint magickey = 10992881u;

		private static ushort repKey = 65531;

		public static void SendHitIndicator(Agent target, byte limbID, PlayerAgent player, bool hitWeakspot, bool willDie, Vector3 position, bool hitArmor = false)
		{
			//IL_0025: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			if (SNet.IsMaster && !((Object)(object)player == (Object)(object)PlayerManager.GetLocalPlayerAgent()) && !player.Owner.IsBot)
			{
				SNet_ChannelType val = (SNet_ChannelType)0;
				SNet_SendGroup val2 = default(SNet_SendGroup);
				SNet_SendQuality val3 = default(SNet_SendQuality);
				int num = default(int);
				SNet.GetSendSettings(ref val, ref val2, ref val3, ref num);
				List<SNet_Player> val4 = new List<SNet_Player>(1);
				val4.Add(player.Owner);
				int index = 0;
				byte[] array = new byte[23];
				BitHelper.WriteBytes(repKey, array, ref index);
				BitHelper.WriteBytes(magickey, array, ref index);
				BitHelper.WriteBytes(msgtype, array, ref index);
				BitHelper.WriteBytes(12, array, ref index);
				BitHelper.WriteBytes((ushort)(target.m_replicator.Key + 1), array, ref index);
				BitHelper.WriteBytes(limbID, array, ref index);
				BitHelper.WriteBytes(hitWeakspot, array, ref index);
				BitHelper.WriteBytes(willDie, array, ref index);
				BitHelper.WriteHalf(position, array, ref index);
				BitHelper.WriteBytes(hitArmor, array, ref index);
				SNet.Core.SendBytes(Il2CppStructArray<byte>.op_Implicit(array), val3, num, val4);
				APILogger.Debug("Sent hit marker to " + player.PlayerName);
			}
		}

		[HarmonyPatch(typeof(SNet_Replication), "RecieveBytes")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static bool RecieveBytes_Prefix(Il2CppStructArray<byte> bytes, uint size, ulong messagerID)
		{
			//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_0100: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			if (size < 12)
			{
				return true;
			}
			ushort num = BitConverter.ToUInt16(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 0);
			if (repKey == num)
			{
				if (BitConverter.ToUInt32(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 2) != magickey)
				{
					APILogger.Debug("[Networking] Magic key is incorrect.");
					return true;
				}
				byte b = ((Il2CppArrayBase<byte>)(object)bytes)[6];
				if (b != msgtype)
				{
					APILogger.Debug($"[Networking] msg type is incorrect. {b} {msgtype}");
					return true;
				}
				int num2 = BitConverter.ToInt32(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 7);
				byte[] array = new byte[num2];
				Array.Copy(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 11, array, 0, num2);
				int index = 0;
				ushort keyPlusOne = BitHelper.ReadUShort(array, ref index);
				byte b2 = BitHelper.ReadByte(array, ref index);
				bool flag = BitHelper.ReadBool(array, ref index);
				bool flag2 = BitHelper.ReadBool(array, ref index);
				Vector3 val = BitHelper.ReadHalfVector3(array, ref index);
				bool flag3 = BitHelper.ReadBool(array, ref index);
				pReplicator pRep = default(pReplicator);
				pRep.keyPlusOne = keyPlusOne;
				pAgent val2 = default(pAgent);
				val2.pRep = pRep;
				Agent val3 = default(Agent);
				((pAgent)(ref val2)).TryGet(ref val3);
				EnemyAgent val4 = ((Il2CppObjectBase)val3).TryCast<EnemyAgent>();
				if ((Object)(object)val4 != (Object)null)
				{
					APILogger.Debug("Received hit indicator for enemy.");
					Dam_EnemyDamageLimb obj = ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)val4.Damage.DamageLimbs)[(int)b2];
					Kill.sentryShot = true;
					obj.ShowHitIndicator(flag, flag2, val, flag3);
					Kill.sentryShot = false;
					return false;
				}
				if ((Object)(object)((Il2CppObjectBase)val3).TryCast<PlayerAgent>() != (Object)null)
				{
					APILogger.Debug("Received hit indicator for player.");
					GuiManager.CrosshairLayer.PopFriendlyTarget();
					return false;
				}
				APILogger.Debug("Received hit indicator packet but could not get player / enemy agent. This should not happen.");
				return false;
			}
			return true;
		}
	}
}
namespace KillIndicatorFix.BepInEx
{
	public static class ConfigManager
	{
		private static ConfigEntry<bool> debug;

		private static ConfigEntry<int> tagBufferPeriod;

		public static bool Debug => debug.Value;

		public static int TagBufferPeriod => tagBufferPeriod.Value;

		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)
			ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "KillIndicatorFix.cfg"), true);
			debug = val.Bind<bool>("Debug", "enable", false, "Enables debug messages when true.");
			tagBufferPeriod = val.Bind<int>("Settings", "TagBufferPeriod", 1000, "Indicates a lee-way period in milliseconds where a kill indicator will still be shown for a given enemy long after it has been tagged (shot at).");
		}
	}
	[BepInPlugin("randomuserhi.KillIndicatorFix", "KillIndicatorFix", "0.1.4")]
	internal class Entry : BasePlugin
	{
		private Harmony? harmony;

		public override void Load()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			APILogger.Debug("Loaded KillIndicatorFix 0.1.4");
			harmony = new Harmony("randomuserhi.KillIndicatorFix");
			harmony.PatchAll();
			APILogger.Debug("Debug is " + (ConfigManager.Debug ? "Enabled" : "Disabled"));
			RundownManager.OnExpeditionGameplayStarted += Action.op_Implicit((Action)KillIndicatorFix.Patches.Kill.OnRundownStart);
		}
	}
	public static class Module
	{
		public const string GUID = "randomuserhi.KillIndicatorFix";

		public const string Name = "KillIndicatorFix";

		public const string Version = "0.1.4";
	}
}

plugins/net6/LEGACY.dll

Decompiled a week 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 AssetShards;
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.Infos;
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.DummyVisual;
using LEGACY.LegacyOverride.DummyVisual.VisualGOAnimation;
using LEGACY.LegacyOverride.DummyVisual.VisualGOAnimation.AnimationConfig;
using LEGACY.LegacyOverride.DummyVisual.VisualSequenceType;
using LEGACY.LegacyOverride.ElevatorCargo;
using LEGACY.LegacyOverride.EnemyTagger;
using LEGACY.LegacyOverride.EventScan;
using LEGACY.LegacyOverride.ExpeditionIntelNotification;
using LEGACY.LegacyOverride.ExpeditionSuccessPage;
using LEGACY.LegacyOverride.FogBeacon;
using LEGACY.LegacyOverride.ForceFail;
using LEGACY.LegacyOverride.Music;
using LEGACY.LegacyOverride.ResourceStations;
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 StateMachines;
using TMPro;
using ThermalSights;
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+6516d149c5b3ab9c71a75700061b6ed33372a1ea")]
[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 value = "4.6.1+gitf831086-dirty-main".Remove("x.x.x".Length);
		((TMP_Text)__instance.m_watermarkText).SetText($"<color=red>MODDED</color> <color=orange>{value}</color>\n<color=#00ae9d>LEGACY</color> <color=orange>{"4.3.3"}</color>", true);
	}
}
namespace LEGACY
{
	internal static class Assets
	{
		public static GameObject CircleSensor { get; private set; }

		public static GameObject MovableSensor { get; private set; }

		public static GameObject OBSVisual { get; private set; }

		public static GameObject ObjectiveMarker { get; private set; }

		public static GameObject EventScan { get; private set; }

		internal static GameObject DummyScan { get; private set; }

		internal static GameObject DummySensor { get; private set; }

		internal static GameObject AmmoStation { get; private set; }

		internal static GameObject MediStation { get; private set; }

		internal static GameObject ToolStation { get; private set; }

		public static void Init()
		{
			CircleSensor = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/CircleSensor.prefab");
			MovableSensor = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/MovableSensor.prefab");
			OBSVisual = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/OBSVisual.prefab");
			ObjectiveMarker = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/ObjectiveMarker.prefab");
			EventScan = AssetAPI.GetLoadedAsset<GameObject>("Assets/EventObjects/EventScan.prefab");
			DummyScan = AssetAPI.GetLoadedAsset<GameObject>("Assets/DummyVisual/DummyScan.prefab");
			DummySensor = AssetAPI.GetLoadedAsset<GameObject>("Assets/DummyVisual/DummySensor.prefab");
			AmmoStation = AssetAPI.GetLoadedAsset<GameObject>("Assets/Misc/AmmoStation.prefab");
			MediStation = AssetAPI.GetLoadedAsset<GameObject>("Assets/Misc/MediStation.prefab");
			ToolStation = AssetAPI.GetLoadedAsset<GameObject>("Assets/Misc/ToolStation.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.*/)]
	[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", "4.3.3")]
	public class EntryPoint : BasePlugin
	{
		public const string AUTHOR = "Inas";

		public const string RUNDOWN_NAME = "LEGACY";

		public const string VERSION = "4.3.3";

		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;
			EventAPI.OnManagersSetup += delegate
			{
				AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)MainMenuGuiLayer.Current.PageRundownNew.SetupCustomTutorialButton);
			};
		}
	}
}
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_002f: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock("LAYOUT_O4_1_L1");
			if (block == null || RundownManager.ActiveExpedition.LevelLayoutData != ((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID)
			{
				return;
			}
			eLocalZoneIndex localIndex = __instance.m_zone.LocalIndex;
			if ((int)localIndex != 1)
			{
				if ((int)localIndex == 5)
				{
					__instance.m_zonePlacementWeights.Start = 0f;
					__instance.m_zonePlacementWeights.Middle = 0f;
					__instance.m_zonePlacementWeights.End = 100000f;
				}
			}
			else if ((int)__instance.m_pickupType == 1)
			{
				__instance.m_zonePlacementWeights.Start = 100000f;
				__instance.m_zonePlacementWeights.Middle = 0f;
				__instance.m_zonePlacementWeights.End = 0f;
			}
		}
	}
}
namespace LEGACY.VanillaFix
{
	[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 && !isRecall)
			{
				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;
		}

		private void f1(int k, out string v)
		{
			if (k < 2)
			{
				v = "2";
			}
			v = null;
		}

		private void f2(int k, ref string v)
		{
			if (k < 2)
			{
				v = "2";
			}
		}
	}
}
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>();
				((Il2CppObjectBase)val.PlayerScanner).Cast<CP_PlayerScanner>().ResetScanProgression(0f);
				val.Deactivate();
				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>();
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val2.m_childCores)
			{
				ResetChild(item);
			}
			val2.Deactivate();
		}

		public static void ResetChainedPuzzle(ChainedPuzzleInstance chainedPuzzleInstance)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0090: 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_0098: 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_00a4: 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 (chainedPuzzleInstance.Data.DisableSurvivalWaveOnComplete)
			{
				chainedPuzzleInstance.m_sound = new CellSoundPlayer(chainedPuzzleInstance.m_parent.position);
			}
			foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)chainedPuzzleInstance.m_chainedPuzzleCores)
			{
				ResetChild(item);
			}
			if (SNet.IsMaster)
			{
				pChainedPuzzleState state = chainedPuzzleInstance.m_stateReplicator.State;
				pChainedPuzzleState val = default(pChainedPuzzleState);
				val.status = (eChainedPuzzleStatus)0;
				val.currentSurvivalWave_EventID = state.currentSurvivalWave_EventID;
				val.isSolved = false;
				val.isActive = false;
				pChainedPuzzleState val2 = val;
				chainedPuzzleInstance.m_stateReplicator.InteractWithState(val2, new pChainedPuzzleInteraction
				{
					type = (eChainedPuzzleInteraction)2
				});
			}
		}

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

		public static 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 List<GameObject> arbitraryNavMarkers = new List<GameObject>();

		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 EnableArbitraryMarkerAt(string markerName, Vector3 Position)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//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_006b: Unknown result type (might be due to invalid IL or missing references)
			if (navMarkers.ContainsKey(markerName))
			{
				navMarkers[markerName].SetVisible(true);
			}
			else
			{
				GameObject val = new GameObject(markerName);
				val.transform.SetPositionAndRotation(Position, Quaternion.identity);
				arbitraryNavMarkers.Add(val);
				NavMarker val2 = GuiManager.NavMarkerLayer.PrepareGenericMarker(val);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SetColor(new Color(0.855f, 0.482f, 0.976f));
					val2.SetStyle((eNavMarkerStyle)14);
					val2.SetVisible(true);
					navMarkers[markerName] = val2;
				}
				else
				{
					LegacyLogger.Error("EnableMarkerAt: got null nav marker");
				}
			}
			LegacyLogger.Debug("EnableMarker: marker " + markerName + " enabled");
		}

		internal (GameObject markerVisual, NavMarker navMakrer) GetMarkerVisuals(string markerName)
		{
			if (!markerVisuals.TryGetValue(markerName, out var value) || !navMarkers.TryGetValue(markerName, out var value2))
			{
				return (null, null);
			}
			return (value, value2);
		}

		public void DisableMakrer(string markerName)
		{
			if (navMarkers.ContainsKey(markerName))
			{
				navMarkers[markerName].SetVisible(false);
			}
			if (markerVisuals.ContainsKey(markerName))
			{
				GameObject val = markerVisuals[markerName];
				if (val.active)
				{
					CoroutineManager.BlinkOut(val, 0f);
				}
				LegacyLogger.Debug("DisableMakrer: marker " + markerName + " disabled");
			}
		}

		public void Clear()
		{
			foreach (GameObject value in markerVisuals.Values)
			{
				Object.Destroy((Object)(object)value);
			}
			arbitraryNavMarkers.ForEach((Action<GameObject>)Object.Destroy);
			markerVisuals.Clear();
			navMarkers.Clear();
			arbitraryNavMarkers.Clear();
		}

		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();
			BigPickupFogBeaconSettingManager.Current.Init();
			EnemyTaggerSettingManager.Current.Init();
			ForceFailManager.Current.Init();
			((GenericExpeditionDefinitionManager<ExpeditionIntel>)ExpeditionIntelNotifier.Current).Init();
			((GenericExpeditionDefinitionManager<EventScanDefinition>)EventScanManager.Current).Init();
			((GenericExpeditionDefinitionManager<VisualGroupDefinition>)VisualManager.Current).Init();
			((GenericExpeditionDefinitionManager<MusicOverride>)MusicStateOverrider.Current).Init();
			((ZoneDefinitionManager<LevelSpawnedFogBeaconDefinition>)LevelSpawnedFogBeaconManager.Current).Init();
			((GenericExpeditionDefinitionManager<SuccessPageCustomization>)SuccessPageCustomizationManager.Current).Init();
			((GenericExpeditionDefinitionManager<ResourceStationDefinition>)ResourceStationManager.Current).Init();
		}
	}
}
namespace LEGACY.LegacyOverride.ResourceStations
{
	public sealed class ToolStation : ResourceStation
	{
		public override string ItemKey => $"Tool_Station_{base.SerialNumber}";

		protected override void SetupInteraction()
		{
			base.SetupInteraction();
			TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.InteractionPrompt.ToolStation");
			Interact.InteractionMessage = ((block == null) ? "TOOL STATION" : Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID));
		}

		protected override void Replenish(PlayerAgent player)
		{
			PlayerAmmoStorage ammoStorage = PlayerBackpackManager.GetBackpack(player.Owner).AmmoStorage;
			float num = Math.Max(0f, Math.Min(def.SupplyUplimit.Tool - ammoStorage.ClassAmmo.RelInPack, def.SupplyEfficiency.Tool));
			player.GiveAmmoRel((PlayerAgent)null, 0f, 0f, num);
			player.Sound.Post(EVENTS.AMMOPACK_APPLY, true);
		}

		public static ToolStation Instantiate(ResourceStationDefinition def)
		{
			if (def.StationType != StationType.TOOL)
			{
				LegacyLogger.Error($"Trying to instantiate MediStation with def with 'StationType': {def.StationType}!");
				return null;
			}
			GameObject gO = Object.Instantiate<GameObject>(Assets.ToolStation);
			return new ToolStation(def, gO);
		}

		private ToolStation(ResourceStationDefinition def, GameObject GO)
			: base(def, GO)
		{
		}

		static ToolStation()
		{
		}
	}
	public sealed class MediStation : ResourceStation
	{
		public const float VANILLA_MAX_HEALTH = 25f;

		public override string ItemKey => $"Health_Station_{base.SerialNumber}";

		protected override void SetupInteraction()
		{
			base.SetupInteraction();
			TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.InteractionPrompt.MediStation");
			Interact.InteractionMessage = ((block == null) ? "HEALTH STATION" : Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID));
		}

		protected override void Replenish(PlayerAgent player)
		{
			float health = ((Dam_SyncedDamageBase)player.Damage).Health;
			float num = def.SupplyUplimit.Medi * 25f;
			if (!(health >= num))
			{
				player.GiveHealth((PlayerAgent)null, Math.Min(def.SupplyEfficiency.Medi, (num - health) / 25f));
				player.Sound.Post(EVENTS.MEDPACK_APPLY, true);
			}
		}

		public static MediStation Instantiate(ResourceStationDefinition def)
		{
			if (def.StationType != 0)
			{
				LegacyLogger.Error($"Trying to instantiate MediStation with def with 'StationType': {def.StationType}!");
				return null;
			}
			GameObject gO = Object.Instantiate<GameObject>(Assets.MediStation);
			return new MediStation(def, gO);
		}

		private MediStation(ResourceStationDefinition def, GameObject GO)
			: base(def, GO)
		{
		}

		static MediStation()
		{
		}
	}
	public abstract class ResourceStation
	{
		public const int UNLIMITED_USE_TIME = int.MaxValue;

		private Coroutine m_blinkMarkerCoroutine;

		public virtual GameObject GameObject { get; protected set; }

		public GameObject InteractGO
		{
			get
			{
				GameObject gameObject = GameObject;
				return ((gameObject != null) ? ((Component)gameObject.transform.GetChild(3)).gameObject : null) ?? null;
			}
		}

		public GameObject StationMarkerGO
		{
			get
			{
				GameObject gameObject = GameObject;
				return ((gameObject != null) ? ((Component)gameObject.transform.GetChild(2)).gameObject : null) ?? null;
			}
		}

		public virtual Interact_Timed Interact { get; protected set; }

		public virtual ResourceStationDefinition def { get; protected set; }

		public RSTimer Timer { get; protected set; }

		public StateReplicator<RSStateStruct> StateReplicator { get; protected set; }

		public RSStateStruct State => StateReplicator?.State ?? new RSStateStruct();

		public LG_GenericTerminalItem TerminalItem { get; protected set; }

		public AIG_CourseNode SpawnNode
		{
			get
			{
				return TerminalItem.SpawnNode;
			}
			set
			{
				TerminalItem.SpawnNode = value;
			}
		}

		protected int SerialNumber { get; private set; }

		public virtual string ItemKey => $"Resource_Station_{SerialNumber}";

		public bool Enabled => State.Enabled;

		protected virtual bool InCooldown
		{
			get
			{
				if (State.RemainingUseTime <= 0)
				{
					return State.CurrentCooldownTime > 0f;
				}
				return false;
			}
		}

		public virtual bool HasUnlimitedUseTime => def.AllowedUseTimePerCooldown == int.MaxValue;

		public virtual void Destroy()
		{
			if (m_blinkMarkerCoroutine != null)
			{
				CoroutineManager.StopCoroutine(m_blinkMarkerCoroutine);
				m_blinkMarkerCoroutine = null;
			}
			Object.Destroy((Object)(object)GameObject);
			StateReplicator?.Unload();
			Interact = null;
			def = null;
			StateReplicator = null;
		}

		protected virtual bool CanInteract()
		{
			if (Enabled)
			{
				return !InCooldown;
			}
			return false;
		}

		protected abstract void Replenish(PlayerAgent player);

		protected virtual void SetInteractionText()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			string text = Text.Format(827u, (Object[])(object)new Object[1] { Object.op_Implicit(InputMapper.GetBindingName(((Interact_Base)Interact).InputAction)) });
			TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.OnAdditionalInteractionText.ResourceStation");
			string text2 = ((block == null) ? "TO REPLENISH" : Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID));
			string text3 = (HasUnlimitedUseTime ? string.Empty : $"({State.RemainingUseTime}/{def.AllowedUseTimePerCooldown})");
			GuiManager.InteractionLayer.SetInteractPrompt(Interact.InteractionMessage, text + text2 + text3, (ePUIMessageStyle)0);
		}

		protected virtual void OnTriggerInteraction(PlayerAgent player)
		{
			RSStateStruct state = State;
			int num = (HasUnlimitedUseTime ? int.MaxValue : Math.Max(state.RemainingUseTime - 1, 0));
			int num2 = player.Owner.PlayerSlotIndex();
			if (num2 < 0 || num2 >= ((Il2CppArrayBase<SNet_Slot>)(object)SNet.Slots.PlayerSlots).Count)
			{
				LegacyLogger.Error($"ResourceStation_OnTriggerInteraction: player {player.PlayerName} has invalid slot index: {num2}");
			}
			else
			{
				StateReplicator?.SetState(new RSStateStruct
				{
					LastInteractedPlayer = num2,
					RemainingUseTime = num,
					CurrentCooldownTime = ((num == 0) ? def.CooldownTime : 0f),
					Enabled = true
				});
			}
		}

		protected virtual void OnInteractionSelected(PlayerAgent agent, bool selected)
		{
			if (selected)
			{
				SetInteractionText();
			}
		}

		protected virtual void SetupInteraction()
		{
			Interact.InteractDuration = def.InteractDuration;
			Interact_Timed interact = Interact;
			interact.ExternalPlayerCanInteract += Func<PlayerAgent, bool>.op_Implicit((Func<PlayerAgent, bool>)((PlayerAgent _) => CanInteract()));
			Interact_Timed interact2 = Interact;
			interact2.OnInteractionSelected += Action<PlayerAgent, bool>.op_Implicit((Action<PlayerAgent, bool>)OnInteractionSelected);
			Interact_Timed interact3 = Interact;
			interact3.OnInteractionTriggered += Action<PlayerAgent>.op_Implicit((Action<PlayerAgent>)OnTriggerInteraction);
		}

		protected virtual void SetupTerminalItem()
		{
			//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_0021: Unknown result type (might be due to invalid IL or missing references)
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(((GlobalZoneIndex)def).DimensionIndex, ((GlobalZoneIndex)def).LayerType, ((GlobalZoneIndex)def).LocalIndex, ref val) || (Object)(object)val == (Object)null)
			{
				LegacyLogger.Error("ResourceStation: Cannot find spawn node!");
				return;
			}
			if (def.AreaIndex < 0 || def.AreaIndex >= val.m_areas.Count)
			{
				LegacyLogger.Error("ResourceStation: Cannot find spawn node - Area index is invalid!");
				return;
			}
			TerminalItem.Setup(ItemKey, val.m_areas[def.AreaIndex].m_courseNode);
			if (SpawnNode != null)
			{
				TerminalItem.FloorItemLocation = SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7);
			}
			TerminalItem.FloorItemStatus = (eFloorInventoryObjectStatus)0;
		}

		protected virtual void OnStateChanged(RSStateStruct oldState, RSStateStruct newState, bool isRecall)
		{
			if (isRecall)
			{
				return;
			}
			int lastInteractedPlayer = newState.LastInteractedPlayer;
			if (lastInteractedPlayer < 0 || lastInteractedPlayer >= ((Il2CppArrayBase<SNet_Slot>)(object)SNet.Slots.PlayerSlots).Count)
			{
				return;
			}
			if (((Interact_Base)Interact).IsSelected)
			{
				SetInteractionText();
			}
			if (!SNet.IsMaster)
			{
				return;
			}
			LegacyLogger.Warning($"ResourceStation OnStateChanged: replenish for player {lastInteractedPlayer}, remaining use time: {newState.RemainingUseTime}");
			if (oldState.RemainingUseTime > 0)
			{
				SNet_Player playerInSlot = SNet.Slots.GetPlayerInSlot(lastInteractedPlayer);
				if ((Object)(object)playerInSlot != (Object)null)
				{
					Replenish(((Il2CppObjectBase)playerInSlot.m_playerAgent).Cast<PlayerAgent>());
				}
				else
				{
					LegacyLogger.Error($"playerSlot_{lastInteractedPlayer} has no player agent!");
				}
			}
			if (newState.RemainingUseTime == 0)
			{
				LegacyLogger.Warning("ResourceStation OnStateChanged: cooldown timer starts!");
				OnCoolDownStart();
			}
		}

		protected virtual void OnCoolDownStart()
		{
			Timer.StartTimer(def.CooldownTime);
			if (m_blinkMarkerCoroutine == null)
			{
				m_blinkMarkerCoroutine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(BlinkMarker()), (Action)null);
			}
		}

		protected virtual void OnCoolDownTimerProgress(float progress)
		{
		}

		protected virtual void OnCoolDownEnd()
		{
			LegacyLogger.Warning("ResourceStation OnCoolDownEnd");
			if (m_blinkMarkerCoroutine != null)
			{
				CoroutineManager.StopCoroutine(m_blinkMarkerCoroutine);
				m_blinkMarkerCoroutine = null;
				StationMarkerGO.SetActive(true);
			}
			if (SNet.IsMaster)
			{
				LegacyLogger.Warning("ResourceStation OnCoolDownEnd: master reset state!");
				StateReplicator.SetState(new RSStateStruct
				{
					LastInteractedPlayer = -1,
					RemainingUseTime = def.AllowedUseTimePerCooldown,
					CurrentCooldownTime = 0f,
					Enabled = true
				});
			}
		}

		protected virtual void SetupReplicator()
		{
			if (StateReplicator == null)
			{
				uint num = EOSNetworking.AllotReplicatorID();
				if (num == 0)
				{
					LegacyLogger.Error("ResourceStation: replicatorID depleted, cannot setup replicator!");
					return;
				}
				StateReplicator = StateReplicator<RSStateStruct>.Create(num, new RSStateStruct
				{
					RemainingUseTime = def.AllowedUseTimePerCooldown,
					CurrentCooldownTime = -1f,
					Enabled = true
				}, (LifeTimeType)1, (IStateReplicatorHolder<RSStateStruct>)null);
				StateReplicator.OnStateChanged += OnStateChanged;
			}
		}

		protected virtual void SetupRSTimer()
		{
			if ((Object)(object)Timer == (Object)null)
			{
				Timer = RSTimer.Instantiate(OnCoolDownTimerProgress, OnCoolDownEnd);
			}
		}

		private IEnumerator BlinkMarker()
		{
			while (true)
			{
				StationMarkerGO.SetActive(!StationMarkerGO.active);
				yield return (object)new WaitForSeconds(0.5f);
			}
		}

		protected ResourceStation(ResourceStationDefinition def, GameObject GO)
		{
			//IL_0025: 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)
			this.def = def;
			GameObject = GO;
			GameObject.transform.SetPositionAndRotation(def.Position.ToVector3(), def.Rotation.ToQuaternion());
			Interact = InteractGO.GetComponent<Interact_Timed>();
			SerialNumber = SerialGenerator.GetUniqueSerialNo();
			if ((Object)(object)Interact == (Object)null)
			{
				LegacyLogger.Error("ResourceStation: Interact Comp not found!");
			}
			else
			{
				SetupInteraction();
			}
			TerminalItem = GO.GetComponent<LG_GenericTerminalItem>();
			if ((Object)(object)TerminalItem == (Object)null)
			{
				LegacyLogger.Error("ResourceStation: TerminalItem not found!");
			}
			else
			{
				SetupTerminalItem();
			}
			SetupReplicator();
			SetupRSTimer();
		}

		static ResourceStation()
		{
		}
	}
	public sealed class AmmoStation : ResourceStation
	{
		public override string ItemKey => $"Ammunition_Station_{base.SerialNumber}";

		protected override void SetupInteraction()
		{
			base.SetupInteraction();
			TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.InteractionPrompt.AmmoStation");
			Interact.InteractionMessage = ((block == null) ? "AMMUNITION STATION" : Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID));
		}

		public static AmmoStation Instantiate(ResourceStationDefinition def)
		{
			if (def.StationType != StationType.AMMO)
			{
				LegacyLogger.Error($"Trying to instantiate AmmoStation with def with 'StationType': {def.StationType}!");
				return null;
			}
			GameObject gO = Object.Instantiate<GameObject>(Assets.AmmoStation);
			return new AmmoStation(def, gO);
		}

		protected override void Replenish(PlayerAgent player)
		{
			PlayerAmmoStorage ammoStorage = PlayerBackpackManager.GetBackpack(player.Owner).AmmoStorage;
			float num = Math.Max(0f, Math.Min(def.SupplyUplimit.AmmoStandard - ammoStorage.StandardAmmo.RelInPack, def.SupplyEfficiency.AmmoStandard));
			float num2 = Math.Max(0f, Math.Min(def.SupplyUplimit.AmmoSpecial - ammoStorage.SpecialAmmo.RelInPack, def.SupplyEfficiency.AmmoSpecial));
			player.GiveAmmoRel((PlayerAgent)null, num, num2, 0f);
			player.Sound.Post(EVENTS.AMMOPACK_APPLY, true);
		}

		private AmmoStation(ResourceStationDefinition def, GameObject GO)
			: base(def, GO)
		{
		}

		static AmmoStation()
		{
		}
	}
	public enum StationType
	{
		MEDI,
		AMMO,
		TOOL
	}
	public class SupplyUplimit
	{
		public float Medi { get; set; } = 0.6f;


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


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


		public float Tool { get; set; }
	}
	public class SupplyEfficiency
	{
		public float Medi { get; set; } = 0.2f;


		public float AmmoStandard { get; set; } = 0.15f;


		public float AmmoSpecial { get; set; } = 0.15f;


		public float Tool { get; set; }
	}
	public class ResourceStationDefinition : GlobalZoneIndex
	{
		public int AreaIndex { get; set; }

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


		public StationType StationType { get; set; } = StationType.AMMO;


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


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


		public float InteractDuration { get; set; } = 2.5f;


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


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


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


		public float CooldownTime { get; set; } = 3f;

	}
	public class ResourceStationManager : GenericExpeditionDefinitionManager<ResourceStationDefinition>
	{
		public static ResourceStationManager Current { get; private set; }

		protected override string DEFINITION_NAME => "ResourceStation";

		private Dictionary<string, ResourceStation> Stations { get; } = new Dictionary<string, ResourceStation>();


		private void Build(ResourceStationDefinition def)
		{
			if (Stations.ContainsKey(def.WorldEventObjectFilter))
			{
				LegacyLogger.Error("ResourceStationManager: WorldEventObjectFilter '" + def.WorldEventObjectFilter + "' is already used");
				return;
			}
			ResourceStation resourceStation = null;
			switch (def.StationType)
			{
			case StationType.MEDI:
				resourceStation = MediStation.Instantiate(def);
				break;
			case StationType.AMMO:
				resourceStation = AmmoStation.Instantiate(def);
				break;
			case StationType.TOOL:
				resourceStation = ToolStation.Instantiate(def);
				break;
			default:
				LegacyLogger.Error($"ResourceStation {def.StationType} is unimplemented");
				return;
			}
			if (resourceStation != null)
			{
				Stations[def.WorldEventObjectFilter] = resourceStation;
				LegacyLogger.Debug("ResourceStation '" + def.WorldEventObjectFilter + "' instantiated");
			}
		}

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

		private void Clear()
		{
			foreach (ResourceStation value in Stations.Values)
			{
				value.Destroy();
			}
			Stations.Clear();
		}

		private ResourceStationManager()
		{
			LevelAPI.OnBuildStart += delegate
			{
				Clear();
			};
			LevelAPI.OnLevelCleanup += Clear;
			LevelAPI.OnBuildDone += BuildStations;
		}

		static ResourceStationManager()
		{
			Current = new ResourceStationManager();
		}
	}
	public struct RSStateStruct
	{
		public int LastInteractedPlayer;

		public int RemainingUseTime;

		public float CurrentCooldownTime;

		public bool Enabled;

		public RSStateStruct()
		{
			LastInteractedPlayer = 0;
			RemainingUseTime = 0;
			CurrentCooldownTime = 0f;
			Enabled = false;
		}
	}
	public class RSTimer : MonoBehaviour
	{
		private float startTime;

		private float endTime;

		private bool hasOnGoingTimer;

		private Action<float> OnProgress;

		private Action OnTimerEnd;

		public float RemainingTime
		{
			get
			{
				if (!hasOnGoingTimer)
				{
					return 0f;
				}
				return Math.Max(endTime - Clock.Time, 0f);
			}
		}

		private static List<GameObject> TimerGOs { get; }

		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
			if ((int)GameStateManager.CurrentStateName == 10 && hasOnGoingTimer)
			{
				float time = Clock.Time;
				if (OnProgress != null)
				{
					OnProgress((time - startTime) / (endTime - startTime));
				}
				if (!(time < endTime))
				{
					endTime = 0f;
					hasOnGoingTimer = false;
					OnTimerEnd?.Invoke();
				}
			}
		}

		public void StartTimer(float time)
		{
			if (time <= 0f)
			{
				LegacyLogger.Error("StartTimer: time is not positive!");
				return;
			}
			if (hasOnGoingTimer)
			{
				LegacyLogger.Error("StartTimer: this timer is yet ended!");
				return;
			}
			startTime = Clock.Time;
			endTime = startTime + time;
			hasOnGoingTimer = true;
		}

		private void OnDestroy()
		{
			endTime = 0f;
			hasOnGoingTimer = false;
			OnTimerEnd = null;
		}

		public static RSTimer Instantiate(Action<float> onProgress, Action actionOnEnd)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			GameObject val = new GameObject();
			RSTimer rSTimer = val.AddComponent<RSTimer>();
			rSTimer.OnProgress = onProgress;
			rSTimer.OnTimerEnd = actionOnEnd;
			TimerGOs.Add(val);
			return rSTimer;
		}

		public static void DestroyAll()
		{
			TimerGOs.ForEach((Action<GameObject>)Object.Destroy);
			TimerGOs.Clear();
		}

		private RSTimer()
		{
		}

		static RSTimer()
		{
			TimerGOs = new List<GameObject>();
			ClassInjector.RegisterTypeInIl2Cpp<RSTimer>();
			LevelAPI.OnBuildStart += DestroyAll;
			LevelAPI.OnLevelCleanup += DestroyAll;
		}
	}
}
namespace LEGACY.LegacyOverride.EnemyTargeting
{
	internal class EnemyTargetingPrioritizer : MonoBehaviour
	{
		public const float UPDATE_INTERVAL = 3f;

		private float nextUpdateTime = float.NaN;

		internal EnemyAgent enemy;

		private Dam_EnemyDamageBase damage
		{
			get
			{
				EnemyAgent obj = enemy;
				if (obj == null)
				{
					return null;
				}
				return obj.Damage;
			}
		}

		private AgentTarget target
		{
			get
			{
				EnemyAgent obj = enemy;
				if (obj == null)
				{
					return null;
				}
				return ((AgentAI)obj.AI).Target;
			}
		}

		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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Invalid comparison between Unknown and I4
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if ((int)GameStateManager.CurrentStateName != 10 || !SNet.IsMaster)
			{
				return;
			}
			if (float.IsNaN(nextUpdateTime))
			{
				nextUpdateTime = Clock.Time + 3f;
			}
			else if (!(Clock.Time < nextUpdateTime) && !((Object)(object)enemy == (Object)null))
			{
				nextUpdateTime = Clock.Time + 3f;
				if ((int)((AgentAI)enemy.AI).Mode == 1 && target != null && !(((Il2CppObjectBase)target.m_agent.CourseNode).Pointer == ((Il2CppObjectBase)((Agent)enemy).CourseNode).Pointer) && PlayerManager.PlayerAgentsInLevel.Count > 1 && ((Agent)PlayerManager.PlayerAgentsInLevel[0]).CourseNode.m_dimension.DimensionIndex == ((Agent)enemy).CourseNode.m_dimension.DimensionIndex)
				{
					TryPrioritizeCloserTarget();
				}
			}
		}

		internal void TryPrioritizeCloserTarget()
		{
			_ = target;
			Agent val = null;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (((Agent)current).Alive && ((Il2CppObjectBase)((Agent)current).CourseNode).Pointer == ((Il2CppObjectBase)((Agent)enemy).CourseNode).Pointer)
				{
					val = (Agent)(object)current;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
				while (enumerator.MoveNext())
				{
					PlayerAgent current2 = enumerator.Current;
					if (((Agent)current2).Alive && ((Il2CppObjectBase)((Agent)current2).CourseNode.m_zone).Pointer == ((Il2CppObjectBase)((Agent)enemy).CourseNode.m_zone).Pointer)
					{
						val = (Agent)(object)current2;
						break;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				((AgentAI)enemy.AI).SetTarget(val);
			}
		}

		private void OnDestroy()
		{
			enemy = null;
		}

		static EnemyTargetingPrioritizer()
		{
			ClassInjector.RegisterTypeInIl2Cpp<EnemyTargetingPrioritizer>();
		}
	}
}
namespace LEGACY.LegacyOverride.Patches
{
	[HarmonyPatch]
	internal static class ExpeditionSuccessPage
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageExpeditionSuccess), "OnEnable")]
		private static void Post_CM_PageExpeditionSuccess_OnEnable(CM_PageExpeditionSuccess __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				SuccessPageCustomization currentCustomization = SuccessPageCustomizationManager.Current.CurrentCustomization;
				if (currentCustomization != null)
				{
					((TMP_Text)__instance.m_header).SetText(LocalizedText.op_Implicit(currentCustomization.PageHeader), true);
					__instance.m_overrideSuccessMusic = currentCustomization.OverrideSuccessMusic;
					LegacyLogger.Warning("Post_CM_PageExpeditionSuccess_OnEnable: " + ((Object)currentCustomization.PageHeader).ToString());
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class LevelSpawnFogBeacon_BugFix
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(HeavyFogRepellerGlobalState), "AttemptInteract")]
		private static void Post_HeavyFogRepellerGlobalState_AttemptInteract(HeavyFogRepellerGlobalState __instance)
		{
			LevelSpawnedFogBeaconSettings lSFBDef = LevelSpawnedFogBeaconManager.Current.GetLSFBDef(__instance);
			if (lSFBDef != null)
			{
				__instance.m_repellerSphere.Range = lSFBDef.Range;
			}
		}
	}
	[HarmonyPatch]
	internal class PrioritizeEnemyTargeting
	{
		private static bool s_patch = true;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EnemyCourseNavigation), "UpdateTracking")]
		private static void UpdateTracking(EnemyCourseNavigation __instance)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			if (!s_patch)
			{
				return;
			}
			int count = PlayerManager.PlayerAgentsInLevel.Count;
			if (!SNet.IsMaster || count <= 1)
			{
				return;
			}
			EnemyAgent owner = __instance.m_owner;
			if ((int)((StateMachine<ES_Base>)(object)owner.Locomotion).m_currentState.m_stateEnum == 14 || ((Il2CppObjectBase)__instance.m_targetRef.m_agent.CourseNode).Pointer == ((Il2CppObjectBase)((Agent)owner).CourseNode).Pointer)
			{
				return;
			}
			PlayerAgent val = null;
			int num = Random.RandomRangeInt(0, count);
			for (int i = 0; i < count; i++)
			{
				PlayerAgent val2 = PlayerManager.PlayerAgentsInLevel[num];
				if (((Agent)val2).Alive && ((Il2CppObjectBase)((Agent)val2).CourseNode).Pointer == ((Il2CppObjectBase)((Agent)owner).CourseNode).Pointer)
				{
					val = val2;
					break;
				}
				num = (num + 1) % count;
			}
			if ((Object)(object)val != (Object)null)
			{
				s_patch = false;
				((AgentAI)owner.AI).SetTarget((Agent)(object)val);
				s_patch = true;
			}
		}
	}
	[HarmonyPatch]
	internal class RundownSelectionCustomization
	{
		private static uint r1TitleID;

		private static uint r2TitleID;

		[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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_0146: 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)
			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;
				((TMP_Text)obj.m_rundownText).text = ((r1TitleID != 0) ? Text.Get(r1TitleID) : "<size=50%><color=#00ae9d>[ LEGACY ]</color></size>");
				((TMP_Text)val.m_rundownText).text = ((r2TitleID != 0) ? Text.Get(r2TitleID) : "<size=80%><color=#009ad6>[ L-OMNI ]</color></size>");
				DestroyAltText(obj);
				DestroyAltText(val);
			}
			static void DestroyAltText(CM_RundownSelection s)
			{
				if ((Object)(object)s.m_altText != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)s.m_altText).gameObject);
					s.m_altText = null;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CM_PageRundown_New), "UpdateRundownSelectionButton")]
		private static void Post_UpdateRundownSelectionButton(CM_PageRundown_New __instance)
		{
			InitTitle();
			SetSelectionScale(__instance);
		}

		private static void InitTitle()
		{
			if (r1TitleID == 0)
			{
				TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("LEGACY_Title");
				if (block != null)
				{
					r1TitleID = ((GameDataBlockBase<TextDataBlock>)(object)block).persistentID;
				}
				block = GameDataBlockBase<TextDataBlock>.GetBlock("LEGACY-Omni_Title");
				if (block != null)
				{
					r2TitleID = ((GameDataBlockBase<TextDataBlock>)(object)block).persistentID;
				}
			}
		}

		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 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;
			BigPickupFogBeaconSetting setting = BigPickupFogBeaconSettingManager.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, re

plugins/net6/LGTuner.dll

Decompiled a week ago
using System;
using System.CodeDom.Compiler;
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 Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("LGTuner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+git32ee113-dirty-master.32ee113f774f28578bd63131db5298640efafe36")]
[assembly: AssemblyProduct("LGTuner")]
[assembly: AssemblyTitle("LGTuner")]
[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 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_0156: 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))
					{
						Logger.Info("loysimme dimension ja levellayoutin");
						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_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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected I4, but got Unknown
			//IL_0116: 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)
			Dimension val = default(Dimension);
			if (!Dimension.GetDimension(zone.DimensionIndex, ref val))
			{
				Logger.Info("dimension getter failed");
				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)
			{
				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 config2))
						{
							Logger.Info("found a dimension + levellayout");
							config2.Reset(((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)current.Grid).m_sizeX);
							DimensionLayer[current.DimensionIndex] = config2;
						}
					}
				}
				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.3")]
	[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"), 
			});
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "LGTuner";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

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

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

		public const string GitRevShort = "32ee113-dirty";

		public const string GitRevLong = "32ee113f774f28578bd63131db5298640efafe36-dirty";

		public const string GitBranch = "master";

		public const string GitTag = null;

		public const bool GitIsDirty = true;
	}
}
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_BuildPlugJob), "Build")]
	internal class Inject_BuildPlugJob
	{
		[HarmonyWrapSafe]
		private static bool Prefix(LG_BuildPlugJob __instance)
		{
			//IL_0022: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Invalid comparison between Unknown and I4
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00c8: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected I4, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			LG_Plug plug = __instance.m_plug;
			Logger.Info($"buildplugjob plug in complex {((LG_ZoneExpander)plug).m_subComplex} plug status {((LG_ZoneExpander)plug).ExpanderStatus} plug direction {plug.m_dir} ..");
			if ((int)((LG_ZoneExpander)plug).ExpanderStatus == 1)
			{
				return true;
			}
			if (((LG_ZoneExpander)plug).m_isZoneSource)
			{
				return true;
			}
			if (!BuilderInfo.TryGetConfig(((LG_ZoneExpander)plug).m_linksFrom.m_zone, out var config))
			{
				return true;
			}
			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 true;
			}
			LG_PlugDir dir = plug.m_dir;
			GameObject prefab;
			switch (dir - 2)
			{
			case 0:
				if (TryGetPlugPrefab(overrideData.BackwardPlug, out prefab))
				{
					Logger.Info(" - Prefab Replaced by BackwardPlug setting! " + ((Object)prefab).name);
					val = prefab;
				}
				break;
			case 2:
				if (TryGetPlugPrefab(overrideData.ForwardPlug, out prefab))
				{
					Logger.Info(" - Prefab Replaced by ForwardPlug setting! " + ((Object)prefab).name);
					val = prefab;
				}
				break;
			case 3:
				if (TryGetPlugPrefab(overrideData.LeftPlug, out prefab))
				{
					Logger.Info(" - Prefab Replaced by LeftPlug setting! " + ((Object)prefab).name);
					val = prefab;
				}
				break;
			case 1:
				if (TryGetPlugPrefab(overrideData.RightPlug, out prefab))
				{
					Logger.Info(" - Prefab Replaced by RightPlug setting! " + ((Object)prefab).name);
					val = prefab;
				}
				break;
			}
			if ((Object)(object)val != (Object)null)
			{
				Logger.Info($"we shall replace a cap going {plug.m_dir}");
				Vector3 position = ((Component)plug).transform.position;
				Quaternion rotation = ((Component)plug).transform.rotation;
				GameObject val2 = Object.Instantiate<GameObject>(val, position, rotation);
				val2.transform.SetParent(((Component)plug).transform, true);
				LG_Factory.FindAndBuildSelectorsAndSpawners(val2, RandomExtensions.NextSubSeed(__instance.m_rnd.Random), false);
				__instance.ProcessDivider(plug, val2, false, RandomExtensions.NextSubSeed(__instance.m_rnd.Random));
				((LG_ZoneExpander)plug).m_wasProcessed = true;
			}
			return true;
		}

		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;
		}
	}
	[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;

		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/NoDustParticles.dll

Decompiled a week ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("NoDustParticles")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NoDustParticles")]
[assembly: AssemblyTitle("NoDustParticles")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace NoDustParticles;

internal class DustPatches
{
	[HarmonyPatch(typeof(AmbientParticles), "Update")]
	[HarmonyPrefix]
	private static bool SkipParticles()
	{
		return false;
	}
}
[BepInPlugin("com.Untilted.NoDustParticles", "NoDustParticles", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Loader : BasePlugin
{
	public const string MODNAME = "NoDustParticles";

	public const string AUTHOR = "Untilted";

	public const string GUID = "com.Untilted.NoDustParticles";

	public const string VERSION = "1.0.0";

	public static ManualLogSource Logger;

	public override void Load()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		Logger = ((BasePlugin)this).Log;
		((BasePlugin)this).Log.LogMessage((object)"Loading NoDustParticles");
		new Harmony("NoDustParticles").PatchAll(typeof(DustPatches));
		((BasePlugin)this).Log.LogMessage((object)"Loaded NoDustParticles");
	}
}

plugins/net6/PortalPuzzleChanger.dll

Decompiled a week 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 AssetShards;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using Enemies;
using FX_EffectSystem;
using GTFO.API;
using GTFO.API.Components;
using GTFO.API.JSON.Converters;
using GTFO.API.Wrappers;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using LevelGeneration;
using MTFO.Managers;
using Microsoft.CodeAnalysis;
using Player;
using PortalPuzzleChanger.ConfigFiles;
using PortalPuzzleChanger.GameScripts;
using PortalPuzzleChanger.Plugin;
using SNetwork;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PortalPuzzleChanger")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PortalPuzzleChanger")]
[assembly: AssemblyTitle("PortalPuzzleChanger")]
[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 PortalPuzzleChanger.Plugin
{
	[BepInPlugin("com.Breeze.PortalPuzzleChanger", "PortalPuzzleChanger", "0.0.1")]
	[BepInProcess("GTFO.exe")]
	internal class EntryPoint : BasePlugin
	{
		public static Dictionary<string, Sprite> CachedSprites;

		public static readonly JsonSerializerOptions SerializerOptions = new JsonSerializerOptions
		{
			ReadCommentHandling = JsonCommentHandling.Skip,
			PropertyNameCaseInsensitive = true,
			IncludeFields = true,
			AllowTrailingCommas = true,
			WriteIndented = true
		};

		public static ManualLogSource? LogSource { get; private set; }

		public static Harmony? m_Harmony { get; private set; }

		public override void Load()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			LogSource = ((BasePlugin)this).Log;
			m_Harmony = new Harmony("_PortalPuzzleChanger_");
			m_Harmony.PatchAll();
			SerializerOptions.Converters.Add((JsonConverter)new LocalizedTextConverter());
			SerializerOptions.Converters.Add((JsonConverter)new Vector3Converter());
			SerializerOptions.Converters.Add((JsonConverter)new Vector2Converter());
			SerializerOptions.Converters.Add((JsonConverter)new ColorConverter());
			PortalPuzzleChangerSetup.Load();
			EnemyTagChangerConfigSetup.Load();
			GrenadeLauncherConfigSetup.Load();
			ClassInjector.RegisterTypeInIl2Cpp<GrenadeProjectile>();
			AssetAPI.OnAssetBundlesLoaded += OnAssetsLoaded;
		}

		public void OnAssetsLoaded()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			List<EnemyTagChanger> list = EnemyTagChangerConfigSetup.EnabledConfigs.Values.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (!string.IsNullOrEmpty(list[i].CustomImagePath))
				{
					Texture2D loadedAsset = AssetAPI.GetLoadedAsset<Texture2D>(list[i].CustomImagePath);
					Sprite val = Sprite.Create(loadedAsset, new Rect(0f, 0f, (float)((Texture)loadedAsset).width, (float)((Texture)loadedAsset).height), new Vector2(0.5f, 0.5f), 64f);
					((Object)val).hideFlags = (HideFlags)61;
					((Object)val).name = list[i].CustomImagePath;
					CachedSprites.Add(((Object)val).name, val);
					Debug("Created a sprite from path: " + list[i].CustomImagePath);
				}
			}
		}

		public static void Debug(string message)
		{
			LogSource.LogDebug((object)("[DEBUG] " + message));
		}

		public static void DebugWarning(string message)
		{
			LogSource.LogWarning((object)("[WARNING] " + message));
		}

		public static void DebugError(string message)
		{
			LogSource.LogError((object)("[ERROR] " + message));
		}
	}
	public class PortalPuzzleChangerSetup
	{
		public static Dictionary<uint, List<PortalEntry>> EnabledConfigs = new Dictionary<uint, List<PortalEntry>>();

		private static List<PortalChangerConfig>? Configs;

		public static string Name { get; } = "PortalPuzzleChanger.json";


		public static void Load()
		{
			string path = Path.Combine(ConfigManager.CustomPath, Name);
			if (File.Exists(path))
			{
				Configs = JsonSerializer.Deserialize<List<PortalChangerConfig>>(File.ReadAllText(path), EntryPoint.SerializerOptions);
				EntryPoint.Debug(Name + " has loaded successfully");
			}
			else
			{
				Configs = new List<PortalChangerConfig>
				{
					new PortalChangerConfig()
				};
				string contents = JsonSerializer.Serialize(Configs, EntryPoint.SerializerOptions);
				File.WriteAllText(path, contents);
				EntryPoint.DebugWarning(Name + " did not exist, creating it now");
			}
			EnabledConfigs.Clear();
			int count = Configs.Count;
			for (int i = 0; i < count; i++)
			{
				if (Configs[i].InternalEnabled)
				{
					EnabledConfigs.Add(Configs[i].MainLevelLayoutID, Configs[i].PortalEntries);
				}
			}
		}
	}
	public class EnemyTagChangerConfigSetup
	{
		public static Dictionary<uint, EnemyTagChanger> EnabledConfigs = new Dictionary<uint, EnemyTagChanger>();

		private static List<EnemyTagChanger>? Configs;

		public static string Name { get; } = "EnemyTags.json";


		public static void Load()
		{
			string path = Path.Combine(ConfigManager.CustomPath, Name);
			if (File.Exists(path))
			{
				Configs = JsonSerializer.Deserialize<List<EnemyTagChanger>>(File.ReadAllText(path), EntryPoint.SerializerOptions);
				EntryPoint.Debug(Name + " has loaded successfully");
			}
			else
			{
				Configs = new List<EnemyTagChanger>
				{
					new EnemyTagChanger()
				};
				string contents = JsonSerializer.Serialize(Configs, EntryPoint.SerializerOptions);
				File.WriteAllText(path, contents);
				EntryPoint.DebugWarning(Name + " did not exist, creating it now");
			}
			EnabledConfigs.Clear();
			int count = Configs.Count;
			for (int i = 0; i < count; i++)
			{
				if (Configs[i].internalEnabled)
				{
					EnabledConfigs.Add(Configs[i].EnemyID, Configs[i]);
				}
			}
		}
	}
	public class GrenadeLauncherConfigSetup
	{
		public static Dictionary<uint, GrenadeLauncherConfig> EnabledConfigs = new Dictionary<uint, GrenadeLauncherConfig>();

		private static List<GrenadeLauncherConfig>? Configs;

		public static string Name { get; } = "GrenadeLauncher.json";


		public static void Load()
		{
			string path = Path.Combine(ConfigManager.CustomPath, Name);
			if (File.Exists(path))
			{
				Configs = JsonSerializer.Deserialize<List<GrenadeLauncherConfig>>(File.ReadAllText(path), EntryPoint.SerializerOptions);
				EntryPoint.Debug(Name + " has loaded successfully");
			}
			else
			{
				Configs = new List<GrenadeLauncherConfig>
				{
					new GrenadeLauncherConfig()
				};
				string contents = JsonSerializer.Serialize(Configs, EntryPoint.SerializerOptions);
				File.WriteAllText(path, contents);
				EntryPoint.DebugWarning(Name + " did not exist, creating it now");
			}
			EnabledConfigs.Clear();
			int count = Configs.Count;
			for (int i = 0; i < count; i++)
			{
				if (Configs[i].internalEnabled)
				{
					EnabledConfigs.Add(Configs[i].PersistentID, Configs[i]);
				}
			}
		}
	}
}
namespace PortalPuzzleChanger.Patches
{
	[HarmonyPatch(typeof(LG_DimensionPortal), "Setup")]
	public static class DimensionPortalPatch
	{
		public static void Prefix(LG_DimensionPortal __instance)
		{
			//IL_002e: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			if (!PortalPuzzleChangerSetup.EnabledConfigs.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData))
			{
				return;
			}
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) original = (__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex);
			List<PortalEntry> list = PortalPuzzleChangerSetup.EnabledConfigs[RundownManager.ActiveExpedition.LevelLayoutData];
			foreach (PortalEntry item in list)
			{
				(eDimensionIndex, LG_LayerType, eLocalZoneIndex) comparingTo = (item.DimensionIndex, item.LayerType, item.ZoneIndex);
				if (DoesZoneMatch(original, comparingTo))
				{
					__instance.m_targetDimension = item.TargetDimension;
					__instance.m_targetZone = item.TargetZoneIndex;
					__instance.PortalChainPuzzle = item.PortalChainedPuzzleId;
					EntryPoint.Debug("Changing the ChainedPuzzleID on " + __instance.PublicName);
				}
			}
		}

		public static void Postfix(LG_DimensionPortal __instance)
		{
			//IL_002e: 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_0049: 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_008a: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			if (!PortalPuzzleChangerSetup.EnabledConfigs.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData))
			{
				return;
			}
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) original = (__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex);
			List<PortalEntry> list = PortalPuzzleChangerSetup.EnabledConfigs[RundownManager.ActiveExpedition.LevelLayoutData];
			foreach (PortalEntry item in list)
			{
				(eDimensionIndex, LG_LayerType, eLocalZoneIndex) comparingTo = (item.DimensionIndex, item.LayerType, item.ZoneIndex);
				if (DoesZoneMatch(original, comparingTo) && item.CreateTeamScanAsLast)
				{
					ChainedPuzzleInstance puzzleInstance = ChainedPuzzleManager.CreatePuzzleInstance(4u, __instance.SpawnNode.m_area, __instance.m_portalBioScanPoint.position, __instance.m_portalBioScanPoint);
					puzzleInstance.OnPuzzleSolved = __instance.m_portalChainPuzzleInstance.OnPuzzleSolved;
					__instance.m_portalChainPuzzleInstance.OnPuzzleSolved = Action.op_Implicit((Action)delegate
					{
						puzzleInstance.AttemptInteract((eChainedPuzzleInteraction)0);
					});
					EntryPoint.Debug("Adding team scan on " + __instance.PublicName);
				}
			}
		}

		private static bool DoesZoneMatch((eDimensionIndex, LG_LayerType, eLocalZoneIndex) original, (eDimensionIndex, LG_LayerType, eLocalZoneIndex) comparingTo)
		{
			//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_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_0022: 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)
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) tuple = original;
			(eDimensionIndex, LG_LayerType, eLocalZoneIndex) tuple2 = comparingTo;
			return tuple.Item1 == tuple2.Item1 && tuple.Item2 == tuple2.Item2 && tuple.Item3 == tuple2.Item3;
		}
	}
	[HarmonyPatch(typeof(HackingTool), "Setup")]
	public static class HackingToolTest
	{
		public static void Postfix(HackingTool __instance)
		{
		}
	}
	[HarmonyPatch(typeof(EnemyAgent), "SyncPlaceNavMarkerTag")]
	internal static class EnemyTagPatch
	{
		public static void Postfix(EnemyAgent __instance)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (EnemyTagChangerConfigSetup.EnabledConfigs.ContainsKey(__instance.EnemyDataID))
			{
				EnemyTagChanger enemyTagChanger = EnemyTagChangerConfigSetup.EnabledConfigs[__instance.EnemyDataID];
				NavMarker tagMarker = __instance.m_tagMarker;
				if (!string.IsNullOrEmpty(enemyTagChanger.CustomImagePath))
				{
					SpriteRenderer component = ((Component)tagMarker.m_enemySubObj).GetComponent<SpriteRenderer>();
					component.sprite = EntryPoint.CachedSprites[enemyTagChanger.CustomImagePath];
				}
				tagMarker.SetColor(enemyTagChanger.TagColor);
			}
		}
	}
	[HarmonyPatch(typeof(GrenadeBase), "Awake")]
	internal static class GrenadeBase_Setup
	{
		public static void Postfix(GrenadeBase __instance)
		{
			GrenadeProjectile grenadeProjectile = ((Component)__instance).gameObject.AddComponent<GrenadeProjectile>();
			((Behaviour)grenadeProjectile).enabled = true;
			grenadeProjectile.GrenadeBase = __instance;
		}
	}
	[HarmonyPatch(typeof(GrenadeBase), "GrenadeDelay")]
	internal static class GrenadeBase_GrenadeDelay
	{
		public static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(GrenadeBase), "Start")]
	internal static class GrenadeBase_Start
	{
		public static void Postfix(GrenadeBase __instance)
		{
			((MonoBehaviour)__instance).CancelInvoke("GrenadeDelay");
		}
	}
	[HarmonyPatch(typeof(BulletWeapon), "Fire")]
	internal static class BulletWeapon_Fire
	{
		public static void Prefix(BulletWeapon __instance)
		{
			if (GrenadeLauncherConfigSetup.EnabledConfigs.ContainsKey(((ItemEquippable)__instance).ArchetypeID))
			{
				GrenadeLauncherConfig config = GrenadeLauncherConfigSetup.EnabledConfigs[((ItemEquippable)__instance).ArchetypeID];
				GrenadeLauncherFire.Fire(__instance, config);
			}
		}
	}
	internal static class GrenadeLauncherFire
	{
		public static void Fire(BulletWeapon weapon, GrenadeLauncherConfig config)
		{
			//IL_0003: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_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_0053: 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)
			pItemData val = default(pItemData);
			val.itemID_gearCRC = 136u;
			Vector3 targetLookDir = ((Agent)((Item)weapon).Owner).TargetLookDir;
			Vector3 normalized = ((Vector3)(ref targetLookDir)).normalized;
			ItemReplicationManager.ThrowItem(val, (delItemCallback)null, (ItemMode)3, ((Component)((ItemEquippable)weapon).MuzzleAlign).transform.position, ((Component)((ItemEquippable)weapon).MuzzleAlign).transform.rotation, normalized * config.ShootForce, ((Component)weapon).transform.position, ((Agent)((Item)weapon).Owner).CourseNode, ((Item)weapon).Owner);
			((Weapon)weapon).MaxRayDist = 0f;
		}
	}
}
namespace PortalPuzzleChanger.GameScripts
{
	public class GrenadeProjectile : ConsumableInstance
	{
		public GrenadeBase GrenadeBase;

		private static FX_Pool explosionPool;

		private float damageRadiusHigh;

		private float damageRadiusLow;

		private float damageValueHigh;

		private float damageValueLow;

		private float explosionForce;

		private readonly int explosionTargetMask = LayerManager.MASK_EXPLOSION_TARGETS;

		private readonly int explosionBlockMask = LayerManager.MASK_EXPLOSION_BLOCKERS;

		private bool madeNoise = false;

		private bool collision = false;

		private bool addForce = false;

		private float decayTime;

		private Rigidbody rigidbody;

		private CellSoundPlayer cellSoundPlayer;

		public GrenadeProjectile(IntPtr hdl)
			: base(hdl)
		{
		}

		private void Awake()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			rigidbody = ((Component)this).GetComponent<Rigidbody>();
			cellSoundPlayer = new CellSoundPlayer();
			if (!Object.op_Implicit((Object)(object)explosionPool))
			{
				explosionPool = FX_Manager.GetEffectPool(AssetShardManager.GetLoadedAsset<GameObject>("Assets/AssetPrefabs/FX_Effects/FX_Tripmine.prefab", false));
			}
		}

		private void Start()
		{
			GrenadeLauncherConfig grenadeLauncherConfig = GrenadeLauncherConfigSetup.EnabledConfigs[((Item)GrenadeBase).Owner.Inventory.WieldedItem.ArchetypeID];
			damageRadiusHigh = grenadeLauncherConfig.MaximumDamageRange.Radius;
			damageRadiusLow = grenadeLauncherConfig.MinimumDamageRange.Radius;
			damageValueHigh = grenadeLauncherConfig.MaximumDamageRange.Damage;
			damageValueLow = grenadeLauncherConfig.MinimumDamageRange.Damage;
			explosionForce = grenadeLauncherConfig.ExplosionForce;
		}

		private void FixedUpdate()
		{
			//IL_0017: 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_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_0036: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			if (rigidbody.useGravity)
			{
				Vector3 val = ((Component)this).transform.position + rigidbody.velocity * Time.fixedDeltaTime;
			}
			else if (!madeNoise)
			{
				MakeNoise();
				((Component)this).transform.position = Vector3.down * 100f;
				madeNoise = true;
			}
		}

		private void Update()
		{
			//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)
			if (rigidbody.useGravity)
			{
				cellSoundPlayer.UpdatePosition(((Component)this).transform.position);
				if (collision)
				{
					DetonateSequence();
				}
			}
			else if (Time.time > decayTime)
			{
				((Item)GrenadeBase).ReplicationWrapper.Replicator.Despawn();
			}
		}

		private void OnCollisionEnter()
		{
			if (rigidbody.useGravity)
			{
				DetonateSequence();
			}
		}

		private void DetonateSequence()
		{
			//IL_001f: 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)
			Detonate();
			decayTime = Time.time + 10f;
			rigidbody.velocity = Vector3.zero;
			rigidbody.angularVelocity = Vector3.zero;
			rigidbody.useGravity = false;
		}

		private void Detonate()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			FX_EffectBase val = (FX_EffectBase)(object)explosionPool.AquireEffect();
			val.Play((FX_Trigger)null, ((Component)this).transform.position, Quaternion.LookRotation(Vector3.up));
			if (SNet.IsMaster)
			{
				DamageUtil.DoExplosionDamage(((Component)this).transform.position, damageRadiusHigh, damageValueHigh, explosionTargetMask, explosionBlockMask, addForce, explosionForce);
				DamageUtil.DoExplosionDamage(((Component)this).transform.position, damageRadiusLow, damageValueLow, explosionTargetMask, explosionBlockMask, addForce, explosionForce);
			}
		}

		private void MakeNoise()
		{
			//IL_000d: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00d9: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_011f: Expected O, but got Unknown
			List<string> list = new List<string>();
			Il2CppReferenceArray<Collider> val = Physics.OverlapSphere(((Component)this).transform.position, 50f, LayerManager.MASK_ENEMY_DAMAGABLE);
			foreach (Collider item in (Il2CppArrayBase<Collider>)(object)val)
			{
				Dam_EnemyDamageLimb component = ((Component)item).GetComponent<Dam_EnemyDamageLimb>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				EnemyAgent glueTargetEnemyAgent = component.GlueTargetEnemyAgent;
				if (!((Object)(object)glueTargetEnemyAgent == (Object)null) && !list.Contains(((Object)((Component)glueTargetEnemyAgent).gameObject).name))
				{
					list.Add(((Object)((Component)glueTargetEnemyAgent).gameObject).name);
					if (!Physics.Linecast(((Component)this).transform.position, ((Agent)glueTargetEnemyAgent).EyePosition, LayerManager.MASK_WORLD))
					{
						NM_NoiseData val2 = new NM_NoiseData
						{
							position = ((Agent)glueTargetEnemyAgent).EyePosition,
							node = ((Agent)glueTargetEnemyAgent).CourseNode,
							type = (NM_NoiseType)0,
							radiusMin = 0.01f,
							radiusMax = 100f,
							yScale = 1f,
							noiseMaker = null,
							raycastFirstNode = false,
							includeToNeightbourAreas = false
						};
						NoiseManager.MakeNoise(val2);
					}
				}
			}
			cellSoundPlayer.Post(EVENTS.FRAGGRENADEEXPLODE, true);
		}

		public override void OnDespawn()
		{
			((ItemWrapped)this).OnDespawn();
		}
	}
}
namespace PortalPuzzleChanger.ConfigFiles
{
	public class EnemyTagChanger
	{
		public bool internalEnabled { get; set; }

		public string internalName { get; set; }

		public uint EnemyID { get; set; }

		public Color TagColor { get; set; }

		public string CustomImagePath { get; set; }

		public EnemyTagChanger()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			internalEnabled = false;
			internalName = string.Empty;
			EnemyID = 0u;
			TagColor = Color.red;
			CustomImagePath = string.Empty;
		}
	}
	public class GrenadeLauncherConfig
	{
		public DamageMinMax MaximumDamageRange { get; set; }

		public DamageMinMax MinimumDamageRange { get; set; }

		public float ExplosionForce { get; set; }

		public float ShootForce { get; set; }

		public uint PersistentID { get; set; }

		public string internalName { get; set; }

		public bool internalEnabled { get; set; }

		public GrenadeLauncherConfig()
		{
			MaximumDamageRange = new DamageMinMax();
			MinimumDamageRange = new DamageMinMax();
			ExplosionForce = 1000f;
			PersistentID = 0u;
			internalName = string.Empty;
			internalEnabled = false;
		}
	}
	public class DamageMinMax
	{
		public float Radius { get; set; }

		public float Damage { get; set; }

		public DamageMinMax()
		{
			Radius = 0f;
			Damage = 0f;
		}
	}
	public class PortalChangerConfig
	{
		public uint MainLevelLayoutID { get; set; }

		public bool InternalEnabled { get; set; }

		public string? InternalName { get; set; }

		public List<PortalEntry> PortalEntries { get; set; }

		public PortalChangerConfig()
		{
			PortalEntries = new List<PortalEntry>
			{
				new PortalEntry()
			};
			InternalEnabled = false;
			InternalName = "Test";
			MainLevelLayoutID = 0u;
		}
	}
	public class PortalEntry
	{
		public eLocalZoneIndex ZoneIndex { get; set; }

		public LG_LayerType LayerType { get; set; }

		public eDimensionIndex DimensionIndex { get; set; }

		public eDimensionIndex TargetDimension { get; set; }

		public eLocalZoneIndex TargetZoneIndex { get; set; }

		public uint PortalChainedPuzzleId { get; set; }

		public bool CreateTeamScanAsLast { get; set; }

		public PortalEntry()
		{
			ZoneIndex = (eLocalZoneIndex)0;
			LayerType = (LG_LayerType)0;
			DimensionIndex = (eDimensionIndex)0;
			TargetDimension = (eDimensionIndex)1;
			TargetZoneIndex = (eLocalZoneIndex)0;
			PortalChainedPuzzleId = 4u;
			CreateTeamScanAsLast = false;
		}
	}
}

plugins/net6/ShotgunCenterFire.dll

Decompiled a week ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Gear;
using HarmonyLib;
using Player;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ShotgunCenterFire")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ShotgunCenterFire")]
[assembly: AssemblyTitle("ShotgunCenterFire")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ShotgunCenterFire;

internal class FirePatches
{
	private static Transform muzzleAlign;

	private static PlayerAgent owner;

	[HarmonyPatch(typeof(Shotgun), "Fire")]
	[HarmonyPrefix]
	private static void ShotgunFire(Shotgun __instance)
	{
		muzzleAlign = ((ItemEquippable)__instance).MuzzleAlign;
		owner = ((Item)__instance).Owner;
	}

	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPrefix]
	private static void CastWeaponRay(Transform alignTransform, ref WeaponHitData weaponRayData, ref Vector3 originPos)
	{
		//IL_0025: 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_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)muzzleAlign != (Object)null && (Object)(object)alignTransform == (Object)(object)muzzleAlign)
		{
			originPos = owner.FPSCamera.Position;
			WeaponHitData obj = weaponRayData;
			Vector3 val = owner.FPSCamera.CameraRayPos - originPos;
			obj.fireDir = ((Vector3)(ref val)).normalized;
		}
	}
}
[BepInPlugin("com.Untilted.ShotgunCenterFire", "ShotgunCenterFire", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Loader : BasePlugin
{
	public const string MODNAME = "ShotgunCenterFire";

	public const string AUTHOR = "Untilted";

	public const string GUID = "com.Untilted.ShotgunCenterFire";

	public const string VERSION = "1.0.0";

	public static ManualLogSource Logger;

	public override void Load()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		Logger = ((BasePlugin)this).Log;
		((BasePlugin)this).Log.LogMessage((object)"Loading ShotgunCenterFire");
		new Harmony("ShotgunCenterFire").PatchAll(typeof(FirePatches));
		((BasePlugin)this).Log.LogMessage((object)"Loaded ShotgunCenterFire");
	}
}

plugins/net6/TerminalGames.dll

Decompiled a week 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 BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GTFO.API;
using HarmonyLib;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
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("TerminalGames")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TerminalGames")]
[assembly: AssemblyTitle("TerminalGames")]
[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]
	[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 TerminalGames
{
	public struct CommandDescriptor
	{
		public TERM_Command Type;

		public string Command;

		public string Description;

		public TERM_CommandRule Rule;
	}
	public class Game
	{
		public enum GameType
		{
			Tictactoe,
			Connect4,
			Othello
		}

		public enum GameMode
		{
			Solo,
			Multi,
			Local
		}

		public static ManualLogSource Log;

		public List<int> symbols = new List<int> { 1, 2 };

		private GameType type;

		private GameMode mode;

		private List<List<int>> board = new List<List<int>>();

		private static List<Tuple<int, int>> placed_tokens = new List<Tuple<int, int>>();

		private bool isActive;

		private int currentPlayer = 1;

		public string MakeAIMove()
		{
			if (!isActive)
			{
				return "";
			}
			List<(int, int)> emptySpots = GetEmptySpots();
			int value = ((currentPlayer != 1) ? 1 : 2);
			foreach (var item in emptySpots)
			{
				List<List<int>> list = CopyBoard();
				list[item.Item1][item.Item2] = currentPlayer;
				if (CheckForWin(list))
				{
					MakeMove(item.Item1, item.Item2, currentPlayer);
					return $"{(ushort)(item.Item2.ToString()[0] + 49)}{item.Item1 + 1}";
				}
			}
			foreach (var item2 in emptySpots)
			{
				List<List<int>> list2 = CopyBoard();
				list2[item2.Item1][item2.Item2] = value;
				if (CheckForWin(list2))
				{
					MakeMove(item2.Item1, item2.Item2, currentPlayer);
					return $"{(ushort)(item2.Item2.ToString()[0] + 49)}{item2.Item1 + 1}";
				}
			}
			int index = new Random().Next(emptySpots.Count);
			var (num, column) = emptySpots[index];
			MakeMove(num, column, currentPlayer);
			return $"{(ushort)(column.ToString()[0] + 49)}{num + 1}";
		}

		private List<(int row, int col)> GetEmptySpots()
		{
			List<(int, int)> list = new List<(int, int)>();
			for (int i = 0; i < board.Count; i++)
			{
				for (int j = 0; j < board[i].Count; j++)
				{
					if (IsValidMove(i, j))
					{
						list.Add((i, j));
					}
				}
			}
			return list;
		}

		private List<List<int>> CopyBoard()
		{
			List<List<int>> list = new List<List<int>>();
			foreach (List<int> item2 in board)
			{
				List<int> item = new List<int>(item2);
				list.Add(item);
			}
			return list;
		}

		public bool CheckForWin(List<List<int>>? board_used = null)
		{
			if (board_used == null)
			{
				board_used = board;
			}
			if (type == GameType.Connect4)
			{
				if (!CheckRows(4, board_used) && !CheckColumns(4, board_used))
				{
					return CheckDiagonals(4, board_used);
				}
				return true;
			}
			if (type == GameType.Tictactoe)
			{
				if (!CheckRows(3, board_used) && !CheckColumns(3, board_used))
				{
					return CheckDiagonals(3, board_used);
				}
				return true;
			}
			if (type == GameType.Othello)
			{
				bool flag = true;
				foreach (List<int> item in board)
				{
					foreach (int item2 in item)
					{
						if (item2 == 0)
						{
							flag = false;
						}
					}
				}
				bool flag2 = false;
				for (int i = 0; i < board.Count; i++)
				{
					for (int j = 0; j < board[0].Count; j++)
					{
						if (IsValidMove(i, j))
						{
							flag2 = true;
						}
					}
				}
				int num = CountPieces(1);
				int num2 = CountPieces(2);
				if (flag || !flag2)
				{
					return num != num2;
				}
				return false;
			}
			return false;
		}

		private bool CheckRows(int consecutiveSymbols, List<List<int>> board_used)
		{
			foreach (int symbol in symbols)
			{
				for (int i = 0; i < board_used.Count; i++)
				{
					for (int j = 0; j <= board_used[i].Count - consecutiveSymbols; j++)
					{
						bool flag = true;
						for (int k = 0; k < consecutiveSymbols; k++)
						{
							if (board_used[i][j + k] != symbol)
							{
								flag = false;
								break;
							}
						}
						if (flag)
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		private bool CheckColumns(int consecutiveSymbols, List<List<int>> board_used)
		{
			foreach (int symbol in symbols)
			{
				for (int i = 0; i < board_used[0].Count; i++)
				{
					for (int j = 0; j <= board_used.Count - consecutiveSymbols; j++)
					{
						bool flag = true;
						for (int k = 0; k < consecutiveSymbols; k++)
						{
							if (board_used[j + k][i] != symbol)
							{
								flag = false;
								break;
							}
						}
						if (flag)
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		private bool CheckDiagonals(int consecutiveSymbols, List<List<int>> board_used)
		{
			foreach (int symbol in symbols)
			{
				for (int i = 0; i <= board_used.Count - consecutiveSymbols; i++)
				{
					for (int j = 0; j <= board_used[i].Count - consecutiveSymbols; j++)
					{
						bool flag = true;
						for (int k = 0; k < consecutiveSymbols; k++)
						{
							if (board_used[i + k][j + k] != symbol)
							{
								flag = false;
								break;
							}
						}
						if (flag)
						{
							return true;
						}
					}
				}
				for (int l = 0; l <= board_used.Count - consecutiveSymbols; l++)
				{
					for (int m = consecutiveSymbols - 1; m < board_used[l].Count; m++)
					{
						bool flag2 = true;
						for (int n = 0; n < consecutiveSymbols; n++)
						{
							if (board_used[l + n][m - n] != symbol)
							{
								flag2 = false;
								break;
							}
						}
						if (flag2)
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		public bool CheckForDraw(List<List<int>>? board_used = null)
		{
			if (board_used == null)
			{
				board_used = board;
			}
			if (type == GameType.Othello)
			{
				bool flag = true;
				foreach (List<int> item in board)
				{
					foreach (int item2 in item)
					{
						if (item2 == 0)
						{
							flag = false;
							break;
						}
					}
					if (!flag)
					{
						break;
					}
				}
				bool flag2 = false;
				for (int i = 0; i < board.Count; i++)
				{
					for (int j = 0; j < board[0].Count; j++)
					{
						if (IsValidMove(i, j))
						{
							flag2 = true;
							break;
						}
					}
					if (flag2)
					{
						break;
					}
				}
				int num = CountPieces(1);
				int num2 = CountPieces(2);
				if (flag || !flag2)
				{
					return num == num2;
				}
				return false;
			}
			for (int k = 0; k < board_used.Count; k++)
			{
				for (int l = 0; l < board_used[k].Count; l++)
				{
					if (board_used[k][l] == 0)
					{
						return false;
					}
				}
			}
			return true;
		}

		private int CountPieces(int player)
		{
			int num = 0;
			foreach (List<int> item in board)
			{
				foreach (int item2 in item)
				{
					if (item2 == player)
					{
						num++;
					}
				}
			}
			return num;
		}

		private void InitializeBoard(int rows, int columns)
		{
			board = new List<List<int>>(rows);
			for (int i = 0; i < rows; i++)
			{
				board.Add(new List<int>(columns));
				for (int j = 0; j < columns; j++)
				{
					board[i].Add(0);
				}
			}
		}

		public void StopGame()
		{
			currentPlayer = 1;
			isActive = false;
		}

		public string SetGameType(string input, string input2)
		{
			if (isActive)
			{
				return "A game is already being played.";
			}
			if (Enum.TryParse<GameType>(input, ignoreCase: true, out var result))
			{
				type = result;
				isActive = true;
				switch (type)
				{
				case GameType.Tictactoe:
					InitializeBoard(3, 3);
					break;
				case GameType.Connect4:
					InitializeBoard(6, 7);
					break;
				case GameType.Othello:
					InitializeBoard(8, 8);
					board[3][3] = 1;
					board[4][4] = 1;
					board[3][4] = 2;
					board[4][3] = 2;
					break;
				}
				if (Enum.TryParse<GameMode>(input2, ignoreCase: true, out var result2))
				{
					mode = result2;
				}
				else
				{
					mode = GameMode.Solo;
				}
				return "";
			}
			return "Invalid Game Type input.";
		}

		public static string ConvertCoordinate(string coordinate, out int row, out int column)
		{
			row = -1;
			column = -1;
			if (coordinate.Length < 1 || coordinate.Length > 2)
			{
				return "Invalid coordinate format. Please use a format like 'a2'.";
			}
			char c = coordinate[0];
			if (coordinate.Length == 2)
			{
				if (!int.TryParse(coordinate[1].ToString(), out row))
				{
					return "Invalid row coordinate. Please use a format like 'a2'.";
				}
				row--;
			}
			column = c - 97;
			return "";
		}

		public List<string> MakeMove(string coordinate, int terminalPlayer)
		{
			if (isActive && ConvertCoordinate(coordinate, out var row, out var column) == "")
			{
				return MakeMove(row, column, terminalPlayer);
			}
			return new List<string> { "Invalid move. Please try again." };
		}

		public List<string> MakeMove(int row, int column, int terminalPlayer)
		{
			if (terminalPlayer != currentPlayer)
			{
				return new List<string> { "This not your turn to play." };
			}
			if (type == GameType.Connect4)
			{
				while (row < board.Count - 1 && board[row + 1][column] == 0)
				{
					row++;
				}
			}
			if (IsValidMove(row, column))
			{
				placed_tokens = new List<Tuple<int, int>>
				{
					new Tuple<int, int>(row, column)
				};
				board[row][column] = currentPlayer;
				if (type == GameType.Othello)
				{
					int num = ((currentPlayer != 1) ? 1 : 2);
					for (int i = -1; i <= 1; i++)
					{
						for (int j = -1; j <= 1; j++)
						{
							if (i == 0 && j == 0)
							{
								continue;
							}
							int num2 = row + i;
							int num3 = column + j;
							if (num2 < 0 || num2 >= board.Count || num3 < 0 || num3 >= board[0].Count || board[num2][num3] != num)
							{
								continue;
							}
							List<(int, int)> list = new List<(int, int)>();
							while (num2 >= 0 && num2 < board.Count && num3 >= 0 && num3 < board[0].Count && board[num2][num3] == num)
							{
								list.Add((num2, num3));
								num2 += i;
								num3 += j;
							}
							if (num2 < 0 || num2 >= board.Count || num3 < 0 || num3 >= board[0].Count || board[num2][num3] != currentPlayer)
							{
								continue;
							}
							foreach (var (num4, num5) in list)
							{
								board[num4][num5] = currentPlayer;
								placed_tokens.Add(new Tuple<int, int>(num4, num5));
							}
						}
					}
				}
				if (currentPlayer == 1)
				{
					currentPlayer = 2;
				}
				else
				{
					currentPlayer = 1;
				}
				return DisplayBoard();
			}
			return new List<string> { "Invalid move. Please try again." };
		}

		private bool IsValidMove(int row, int column)
		{
			bool flag = row >= 0 && row < board.Count && column >= 0 && column < board[row].Count && board[row][column] == 0;
			if (type == GameType.Connect4)
			{
				bool flag2 = row == board.Count - 1;
				bool flag3 = row < board.Count - 1 && board[row + 1][column] != 0;
				flag = flag && (flag2 || flag3);
			}
			else if (flag && type == GameType.Othello)
			{
				int num = ((currentPlayer != 1) ? 1 : 2);
				for (int i = -1; i <= 1; i++)
				{
					for (int j = -1; j <= 1; j++)
					{
						if (i == 0 && j == 0)
						{
							continue;
						}
						int num2 = row + i;
						int num3 = column + j;
						if (num2 >= 0 && num2 < board.Count && num3 >= 0 && num3 < board[0].Count && board[num2][num3] == num)
						{
							while (num2 >= 0 && num2 < board.Count && num3 >= 0 && num3 < board[0].Count && board[num2][num3] == num)
							{
								num2 += i;
								num3 += j;
							}
							if (num2 >= 0 && num2 < board.Count && num3 >= 0 && num3 < board[0].Count && board[num2][num3] == currentPlayer)
							{
								return true;
							}
						}
					}
				}
				return false;
			}
			return flag;
		}

		public bool IsGameActive()
		{
			return isActive;
		}

		public GameMode GetGameMode()
		{
			return mode;
		}

		public GameType GetGameType()
		{
			return type;
		}

		public int GetCurrentPlayer()
		{
			return currentPlayer;
		}

		public Game Copy()
		{
			Game game = new Game
			{
				type = type,
				mode = mode,
				isActive = isActive,
				currentPlayer = currentPlayer,
				board = new List<List<int>>(board.Count)
			};
			for (int i = 0; i < board.Count; i++)
			{
				game.board.Add(new List<int>(board[i]));
			}
			return game;
		}

		public List<string> DisplayBoard()
		{
			List<string> list = new List<string>
			{
				"",
				"   " + string.Join(" ", GetColumnLetters(board[0].Count))
			};
			for (int i = 0; i < board.Count; i++)
			{
				list.Add($"{i + 1} |{string.Join(" ", GetRowSymbols(board[i], i))}|");
			}
			list.Add("");
			return list;
		}

		private static string[] GetRowSymbols(List<int> row, int rowIndex)
		{
			string[] array = new string[row.Count];
			for (int i = 0; i < row.Count; i++)
			{
				string text = GetPlayerColor(row[i]);
				for (int j = 0; j < placed_tokens.Count; j++)
				{
					if (placed_tokens[j].Item1 == rowIndex && placed_tokens[j].Item2 == i)
					{
						text = "<color=green>";
						break;
					}
				}
				array[i] = text + GetSymbol(row[i]) + "</color>";
			}
			return array;
		}

		private static char[] GetColumnLetters(int columnCount)
		{
			char[] array = new char[columnCount];
			for (int i = 0; i < columnCount; i++)
			{
				array[i] = (char)(97 + i);
			}
			return array;
		}

		private static string GetSymbol(int player)
		{
			return player switch
			{
				1 => "X", 
				2 => "O", 
				_ => " ", 
			};
		}

		public static string GetPlayerColor(int player)
		{
			return player switch
			{
				1 => "<color=purple>", 
				2 => "<color=yellow>", 
				_ => "", 
			};
		}
	}
	[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")]
	internal class Inject_Terminal_ReceiveCmd
	{
		public static ManualLogSource Log;

		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 Postfix(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);
		}
	}
	internal static class Patch
	{
		public class MonoPatch : MonoBehaviour
		{
			public static ManualLogSource? Log;

			public static List<EnrichedTerminal> enriched_terminals = new List<EnrichedTerminal>();

			public static void Initialize()
			{
				List<LG_Zone> zones = Builder.Current.m_currentFloor.MainDimension.Layers[0].m_zones;
				for (int i = 0; i < zones.Count; i++)
				{
					List<LG_ComputerTerminal> terminalsSpawnedInZone = zones[i].TerminalsSpawnedInZone;
					for (int j = 0; j < terminalsSpawnedInZone.Count; j++)
					{
						LG_ComputerTerminal val = terminalsSpawnedInZone[j];
						EnrichedTerminal enrichedTerminal = new EnrichedTerminal
						{
							ComputerTerminal = val,
							CmdProcessor = val.m_command,
							Interaction = ((Component)val).GetComponentInChildren<Interact_ComputerTerminal>(true)
						};
						enrichedTerminal.SetTerminalListIndex(enriched_terminals.Count);
						enrichedTerminal.Setup();
						enriched_terminals.Add(enrichedTerminal);
					}
				}
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("TerminalGames", "TerminalGames", "1.0.2")]
	public class Plugin : 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
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			_Harmony = new Harmony("TerminalGames");
			_Harmony.PatchAll();
			Patch.MonoPatch.Log = ((BasePlugin)this).Log;
			EnrichedTerminal.Log = ((BasePlugin)this).Log;
			Game.Log = ((BasePlugin)this).Log;
			((BasePlugin)this).AddComponent<Patch.MonoPatch>();
			EventAPI.OnExpeditionStarted += Patch.MonoPatch.Initialize;
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(35, 0, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin TerminalGames is now loaded.");
			}
			log.LogInfo(val);
		}
	}
	public class EnrichedTerminal
	{
		public static ManualLogSource Log;

		private LocalizedText _GCTextHolder;

		private Game current_game = new Game();

		private int player = 1;

		private int TerminalListIndex;

		private int OtherTerminalListIndex = -1;

		public const TERM_Command COMMAND_PLAY = 255;

		public const TERM_Command COMMAND_PLACE = 254;

		public const TERM_Command COMMAND_STOP = 253;

		public const TERM_Command COMMAND_JOIN = 252;

		public LG_ComputerTerminal ComputerTerminal { get; set; }

		public LG_ComputerTerminalCommandInterpreter CmdProcessor { get; set; }

		public Interact_ComputerTerminal Interaction { get; set; }

		public event Action<TERM_Command, string, string, string> OnCmdUsed;

		public void AddCommand(CommandDescriptor descriptor, Action<LG_ComputerTerminalCommandInterpreter, string, string>? onCommandUsed = null)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00a3: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Action<LG_ComputerTerminalCommandInterpreter, string, string> onCommandUsed2 = onCommandUsed;
			if (CmdProcessor.HasRegisteredCommand(descriptor.Type))
			{
				ManualLogSource log = Log;
				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!!");
				}
				log.LogError(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)
				{
					onCommandUsed2?.Invoke(CmdProcessor, param1, param2);
				}
			};
		}

		public void AddPlayCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter>? onCommandUsed = null)
		{
			//IL_002a: 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)
			Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed2 = onCommandUsed;
			string cmd2 = cmd;
			CommandDescriptor commandDescriptor = default(CommandDescriptor);
			commandDescriptor.Type = (TERM_Command)255;
			commandDescriptor.Command = cmd2;
			commandDescriptor.Description = helpText;
			commandDescriptor.Rule = (TERM_CommandRule)0;
			CommandDescriptor descriptor = commandDescriptor;
			AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter, string param1, string param2)
			{
				onCommandUsed2?.Invoke(interpreter);
				interpreter.AddOutput((TerminalLineType)0, $"Desired Action: <color=orange>{cmd2}</color> <color=yellow>{param1}</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
				if (param1 != null && param1.Length > 0)
				{
					string text = current_game.SetGameType(param1, param2);
					if (text.Length > 0)
					{
						interpreter.AddOutput((TerminalLineType)0, "<color=red>" + text + "</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
					}
					else
					{
						interpreter.AddOutput((TerminalLineType)4, "Preparing game..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
						interpreter.AddOutput((TerminalLineType)0, "<color=green>New game created!</color> " + Game.GetPlayerColor(player) + "You</color><color=green> can start playing!</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
						List<string> list = current_game.DisplayBoard();
						list.Add("<color=green>PLACE {coordinates}</color> to place a move.");
						foreach (string item in list)
						{
							interpreter.AddOutput((TerminalLineType)0, item, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
						}
						if (current_game.GetGameMode() == Game.GameMode.Multi)
						{
							OtherTerminalListIndex = -1;
							interpreter.AddOutput((TerminalLineType)0, $"The other player can join the game with <color=green>JOIN Terminal_{ComputerTerminal.m_serialNumber}</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
						}
					}
				}
				else
				{
					interpreter.AddOutput((TerminalLineType)0, "<color=red>You have to specify a game to play.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
				}
			});
		}

		public void AddPlaceCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter>? onCommandUsed = null)
		{
			//IL_002a: 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)
			Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed2 = onCommandUsed;
			string cmd2 = cmd;
			CommandDescriptor commandDescriptor = default(CommandDescriptor);
			commandDescriptor.Type = (TERM_Command)254;
			commandDescriptor.Command = cmd2;
			commandDescriptor.Description = helpText;
			commandDescriptor.Rule = (TERM_CommandRule)0;
			CommandDescriptor descriptor = commandDescriptor;
			AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter, string param1, string param2)
			{
				LG_ComputerTerminalCommandInterpreter interpreter2 = interpreter;
				onCommandUsed2?.Invoke(interpreter2);
				if (!current_game.IsGameActive())
				{
					interpreter2.AddOutput((TerminalLineType)0, "<color=red>There is no active game yet.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
				}
				else if (current_game.GetGameMode() == Game.GameMode.Multi && OtherTerminalListIndex == -1)
				{
					interpreter2.AddOutput((TerminalLineType)0, "<color=red>You have to wait for a player to join the game.</color>", 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
				}
				else
				{
					interpreter2.AddOutput((TerminalLineType)0, $"Desired Action: <color=orange>{cmd2}</color> <color=yellow>{param1}</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
					List<string> list = current_game.MakeMove(param1, player);
					if (list.Count == 1)
					{
						interpreter2.AddOutput((TerminalLineType)0, "<color=red>" + list[0] + "</color>", 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
					}
					else
					{
						if (IsMultiJoined())
						{
							Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].current_game.MakeMove(param1, player);
						}
						foreach (string item in list)
						{
							interpreter2.AddOutput((TerminalLineType)0, item, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
							if (IsMultiJoined())
							{
								Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)0, item, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
							}
						}
						if (current_game.CheckForWin())
						{
							interpreter2.AddOutput((TerminalLineType)0, $"<color=green>Hurray! The {Game.GetPlayerColor(player)}player {player}</color> <color=green>won! </color></color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
							if (IsMultiJoined())
							{
								Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)0, $"<color=green>Hurray! The {Game.GetPlayerColor(player)}player {player}</color> <color=green>won! </color></color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
								StopMultiGame();
							}
							player = 1;
							current_game.StopGame();
						}
						else if (current_game.CheckForDraw())
						{
							interpreter2.AddOutput((TerminalLineType)0, "<color=orange>No one won... Game's over.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
							if (IsMultiJoined())
							{
								Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)0, "<color=orange>No one won... Game's over.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
								StopMultiGame();
							}
							player = 1;
							current_game.StopGame();
						}
						else
						{
							if (current_game.GetGameMode() == Game.GameMode.Local)
							{
								SetEndOfQueue(delegate
								{
									interpreter2.AddOutput((TerminalLineType)5, Game.GetPlayerColor(player) + "Player " + player + "</color>'s turn.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
								});
							}
							else if (IsMultiJoined())
							{
								SetEndOfQueue(delegate
								{
									interpreter2.AddOutput((TerminalLineType)5, Game.GetPlayerColor(current_game.GetCurrentPlayer()) + "Other player</color>'s turn.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
								});
								Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].SetEndOfQueue(delegate
								{
									Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)5, Game.GetPlayerColor(current_game.GetCurrentPlayer()) + "Your turn</color>.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
								});
							}
							if (current_game.GetGameMode() == Game.GameMode.Solo)
							{
								Random random = new Random();
								interpreter2.AddOutput((TerminalLineType)4, Game.GetPlayerColor((player != 1) ? 1 : 2) + "AI</color> is thinking..", (float)(0.4 + random.NextDouble()), (TerminalSoundType)0, (TerminalSoundType)0);
								string text = current_game.MakeAIMove().ToUpper();
								interpreter2.AddOutput((TerminalLineType)0, Game.GetPlayerColor((player != 1) ? 1 : 2) + "AI placed on</color> <color=orange>" + text + "</color>", 0.1f, (TerminalSoundType)0, (TerminalSoundType)0);
								foreach (string item2 in current_game.DisplayBoard())
								{
									interpreter2.AddOutput((TerminalLineType)0, item2, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
								}
								interpreter2.AddOutput((TerminalLineType)0, Game.GetPlayerColor(player) + "Your turn.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
								if (current_game.CheckForWin())
								{
									interpreter2.AddOutput((TerminalLineType)0, "<color=red>The AI won.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
									player = 1;
									current_game.StopGame();
								}
								else if (current_game.CheckForDraw())
								{
									interpreter2.AddOutput((TerminalLineType)0, "<color=orange>No one won... Game's over.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
									player = 1;
									current_game.StopGame();
								}
							}
							if (current_game.GetGameMode() == Game.GameMode.Local)
							{
								if (player == 1)
								{
									player = 2;
								}
								else
								{
									player = 1;
								}
							}
						}
					}
				}
			});
		}

		public void AddStopCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter>? onCommandUsed = null)
		{
			//IL_002a: 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)
			Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed2 = onCommandUsed;
			string cmd2 = cmd;
			CommandDescriptor commandDescriptor = default(CommandDescriptor);
			commandDescriptor.Type = (TERM_Command)253;
			commandDescriptor.Command = cmd2;
			commandDescriptor.Description = helpText;
			commandDescriptor.Rule = (TERM_CommandRule)0;
			CommandDescriptor descriptor = commandDescriptor;
			AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter, string param1, string param2)
			{
				onCommandUsed2?.Invoke(interpreter);
				interpreter.AddOutput((TerminalLineType)0, "Desired Action: <color=orange>" + cmd2 + "</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
				if (current_game.IsGameActive())
				{
					if (IsMultiJoined())
					{
						Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)4, "Stopping game from remote terminal..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
						Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)0, "<color=orange>The game has been stopped.</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
						StopMultiGame();
					}
					interpreter.AddOutput((TerminalLineType)4, "Stopping game..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
					interpreter.AddOutput((TerminalLineType)0, "<color=orange>The game has been stopped.</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
					player = 1;
					current_game.StopGame();
				}
				else
				{
					interpreter.AddOutput((TerminalLineType)0, "<color=red>There is no game currently played.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
				}
			});
		}

		public void AddJoinCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter>? onCommandUsed = null)
		{
			//IL_002a: 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)
			Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed2 = onCommandUsed;
			string cmd2 = cmd;
			CommandDescriptor commandDescriptor = default(CommandDescriptor);
			commandDescriptor.Type = (TERM_Command)252;
			commandDescriptor.Command = cmd2;
			commandDescriptor.Description = helpText;
			commandDescriptor.Rule = (TERM_CommandRule)0;
			CommandDescriptor descriptor = commandDescriptor;
			AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter, string param1, string param2)
			{
				LG_ComputerTerminalCommandInterpreter interpreter2 = interpreter;
				onCommandUsed2?.Invoke(interpreter2);
				interpreter2.AddOutput((TerminalLineType)0, "Desired Action: <color=orange>" + cmd2 + "</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
				if (current_game.IsGameActive())
				{
					interpreter2.AddOutput((TerminalLineType)0, "<color=red>There is already a game currently being played.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
				}
				else
				{
					interpreter2.AddOutput((TerminalLineType)4, "Finding game..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
					if (param1 != null)
					{
						param1 = param1.ToLower();
					}
					if (param1 != null && param1.Length > 0 && param1.Contains("terminal_"))
					{
						param1 = param1.Split("terminal_")[1];
						if (param1 == ComputerTerminal.m_serialNumber.ToString())
						{
							interpreter2.AddOutput((TerminalLineType)0, "<color=red>You cannot play as the other player on the same terminal.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
						}
						else
						{
							OtherTerminalListIndex = -1;
							for (int i = 0; i < Patch.MonoPatch.enriched_terminals.Count; i++)
							{
								EnrichedTerminal enrichedTerminal = Patch.MonoPatch.enriched_terminals[i];
								if (i != TerminalListIndex && enrichedTerminal.ComputerTerminal.m_serialNumber.ToString() == param1)
								{
									if (enrichedTerminal.OtherTerminalListIndex != -1)
									{
										interpreter2.AddOutput((TerminalLineType)0, "<color=red>A player has already joined the game on this terminal.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
									}
									else
									{
										if (enrichedTerminal.current_game.IsGameActive() && enrichedTerminal.current_game.GetGameMode() == Game.GameMode.Multi)
										{
											current_game = enrichedTerminal.current_game.Copy();
											if (enrichedTerminal.player == 1)
											{
												player = 2;
											}
											else
											{
												player = 2;
											}
											OtherTerminalListIndex = i;
											enrichedTerminal.OtherTerminalListIndex = TerminalListIndex;
											enrichedTerminal.CmdProcessor.AddOutput((TerminalLineType)0, $"<color=orange>A player has joined you from </color><color=green>Terminal_{ComputerTerminal.m_serialNumber}</color><color=orange>!</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
											enrichedTerminal.CmdProcessor.AddOutput((TerminalLineType)5, Game.GetPlayerColor(current_game.GetCurrentPlayer()) + "Your turn</color>.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
											break;
										}
										interpreter2.AddOutput((TerminalLineType)0, "<color=red>No multiplayer game found on that terminal.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
									}
									return;
								}
							}
							if (OtherTerminalListIndex == -1)
							{
								interpreter2.AddOutput((TerminalLineType)0, "<color=red>No other terminal found with that ID.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
							}
							else
							{
								interpreter2.AddOutput((TerminalLineType)4, "Fetching board..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
								foreach (string item in current_game.DisplayBoard())
								{
									interpreter2.AddOutput((TerminalLineType)0, item, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
								}
								SetEndOfQueue(delegate
								{
									interpreter2.AddOutput((TerminalLineType)5, Game.GetPlayerColor(current_game.GetCurrentPlayer()) + "Other player</color>'s turn.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
								});
							}
						}
					}
					else
					{
						interpreter2.AddOutput((TerminalLineType)0, "<color=red>Wrong syntax for JOIN command.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
					}
				}
			});
		}

		public void Setup()
		{
			Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced += OnReceiveCommand;
			AddPlayCommand("play", "{<color=orange>TICTACTOE</color>, <color=orange>CONNECT4</color>, <color=orange>OTHELLO</color>}</color> {<color=green>SOLO</color>, <color=green>MULTI</color>, <color=green>LOCAL</color>}");
			AddPlaceCommand("place", "Once a game is started, place on given <color=orange>{coordinates}</color>. <color=blue> Ex: PLACE A2</color>");
			AddStopCommand("stop", "Once a game is started, <color=red>stops</color> the current game");
			AddJoinCommand("join", "Joins the game from its {<color=orange>Terminal ID</color>}. <color=blue> Ex: JOIN Terminal_284</color>");
		}

		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 SetEndOfQueue(Action onEndOfQueue)
		{
			CmdProcessor.OnEndOfQueue = Action.op_Implicit(onEndOfQueue);
		}

		public bool IsMultiJoined()
		{
			if (OtherTerminalListIndex != -1)
			{
				return current_game.GetGameMode() == Game.GameMode.Multi;
			}
			return false;
		}

		public void StopMultiGame()
		{
			Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].current_game.StopGame();
			Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].OtherTerminalListIndex = -1;
			Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].player = 1;
			OtherTerminalListIndex = -1;
		}

		public void SetTerminalListIndex(int index)
		{
			TerminalListIndex = index;
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "TerminalGames";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = null;

		public const string SemVer = "1.0.0";

		public const string GitRevShort = null;

		public const string GitRevLong = null;

		public const string GitBranch = null;

		public const string GitTag = null;

		public const bool GitIsDirty = false;
	}
}

plugins/net6/WardenIntelOhBehave.dll

Decompiled a week ago
using System;
using System.CodeDom.Compiler;
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.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppSystem;
using LevelGeneration;
using Microsoft.CodeAnalysis;
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("WardenIntelOhBehave")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WardenIntelOhBehave")]
[assembly: AssemblyTitle("WardenIntelOhBehave")]
[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]
	[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 WardenIntelOhBehave
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("WardenIntelOhBehave", "WardenIntelOhBehave", "0.0.1")]
	public class Plugin : BasePlugin
	{
		public class WardenIntelOhBehave : MonoBehaviour
		{
			public static ManualLogSource? Log;

			public static void Initialize()
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				if (DropCount > 0)
				{
					GuiManager.PlayerLayer.m_wardenIntel.ResetSubObjectiveMesssagQueue();
					ManualLogSource? log = Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("drop ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(DropCount);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" : wardenintel revival attempted");
					}
					log.LogInfo(val);
				}
				DropCount++;
			}
		}

		public static int DropCount;

		public static bool BehaveRunning;

		public override void Load()
		{
			((BasePlugin)this).AddComponent<WardenIntelOhBehave>();
			WardenIntelOhBehave.Log = ((BasePlugin)this).Log;
			LG_Factory.OnFactoryBuildDone += Action.op_Implicit((Action)WardenIntelOhBehave.Initialize);
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "WardenIntelOhBehave";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = null;

		public const string SemVer = "1.0.0";

		public const string GitRevShort = null;

		public const string GitRevLong = null;

		public const string GitBranch = null;

		public const string GitTag = null;

		public const bool GitIsDirty = false;
	}
}

plugins/x64/Release/netstandard2.1/Oxygen.dll

Decompiled a week 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;
			}
		}
	}
}