Decompiled source of ModernStatsHUD v1.0.0

ModernStatsHUD.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using ModernStatsHUD.Configuration;
using ModernStatsHUD.Integrations;
using ModernStatsHUD.Stats;
using ModernStatsHUD.UI;
using Photon.Pun;
using TMPro;
using UnboundLib;
using UnboundLib.Utils.UI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ModernStatsHUD
{
	[BepInPlugin("com.naccel.rounds.modernstatshud", "ModernStatsHUD", "1.0.0")]
	[BepInProcess("Rounds.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ModernStatsHUDPlugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__20_0;

			internal void <Awake>b__20_0()
			{
			}
		}

		public const string ModId = "com.naccel.rounds.modernstatshud";

		public const string ModName = "ModernStatsHUD";

		public const string ModVersion = "1.0.0";

		private ModernHudView _hudView;

		private ModernTabOverlay _tabOverlay;

		private float _pollTimer;

		private static readonly Type _epStateType = Type.GetType("EveryonePicks.State, EveryonePicks");

		private static readonly FieldInfo _epPhaseActiveField = _epStateType?.GetField("phaseActive", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _epLocalPickActiveField = _epStateType?.GetField("localPickActive", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _epCurrentSessionPlayerField = _epStateType?.GetField("currentSessionPlayer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _epLocalCardsField = _epStateType?.GetField("localCards", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly Type _botPickerType = Type.GetType("RoundsWithBots.Handlers.BotCardPickerHandler, RoundsWithBots");

		private static readonly PropertyInfo _botPickerInstanceProp = _botPickerType?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);

		private static readonly FieldInfo _botPickerAIPickingField = _botPickerType?.GetField("pickerAIPicking", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly Type _botsManagerType = Type.GetType("RoundsWithBots.Handlers.BotsManager, RoundsWithBots");

		private static readonly PropertyInfo _botsManagerInstanceProp = _botsManagerType?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);

		private static readonly PropertyInfo _botsManagerBotListProp = _botsManagerType?.GetProperty("BotList", BindingFlags.Instance | BindingFlags.Public);

		private static readonly FieldInfo _spawnedCardsField = typeof(CardChoice).GetField("spawnedCards", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _currentlySelectedField = typeof(CardChoice).GetField("currentlySelectedCard", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly PropertyInfo _currentlySelectedProp = typeof(CardChoice).GetProperty("currentlySelectedCard", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _isHoveredField = typeof(CardVisuals).GetField("isHovered", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _isSelectedField = typeof(CardVisuals).GetField("isSelected", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _pickerTypeField = typeof(CardChoice).GetField("pickerType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		public static ModernStatsHUDPlugin Instance { get; private set; }

		public static ManualLogSource Logger { get; private set; }

		public static bool MatchActive
		{
			get
			{
				if ((Object)(object)GameManager.instance != (Object)null && GameManager.instance.isPlaying)
				{
					return true;
				}
				if ((Object)(object)PlayerManager.instance != (Object)null && PlayerManager.instance.players != null && PlayerManager.instance.players.Count > 0)
				{
					return true;
				}
				return false;
			}
		}

		public static bool InBattlePhase
		{
			get
			{
				if ((Object)(object)GameManager.instance != (Object)null)
				{
					return GameManager.instance.battleOngoing;
				}
				return false;
			}
		}

		public static bool InPickPhase
		{
			get
			{
				if ((Object)(object)CardChoice.instance != (Object)null && CardChoice.instance.IsPicking)
				{
					return true;
				}
				if (_epPhaseActiveField != null)
				{
					try
					{
						if ((bool)_epPhaseActiveField.GetValue(null))
						{
							return true;
						}
					}
					catch
					{
					}
				}
				return false;
			}
		}

		private void Awake()
		{
			//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_0050: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"[ModernStatsHUD] Initializing v1.0.0...");
			new ModConfig(((BaseUnityPlugin)this).Config);
			try
			{
				object obj = <>c.<>9__20_0;
				if (obj == null)
				{
					UnityAction val = delegate
					{
					};
					<>c.<>9__20_0 = val;
					obj = (object)val;
				}
				Unbound.RegisterMenu("Modern Stats HUD", (UnityAction)obj, (Action<GameObject>)ModernMenuBuilder.BuildMenu, (GameObject)null, true);
				Logger.LogInfo((object)"[ModernStatsHUD] Registered menu in UnboundLib Mods tab.");
			}
			catch (Exception arg)
			{
				Logger.LogError((object)string.Format("[{0}] Failed to register Unbound menu: {1}", "ModernStatsHUD", arg));
			}
			Logger.LogInfo((object)"[ModernStatsHUD] ModernStatsHUD loaded successfully (UI lazy-loaded on match/menu start)!");
		}

		private void Start()
		{
			EnsureInitialized();
		}

		public void EnsureInitialized()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			if ((Object)(object)_hudView != (Object)null)
			{
				return;
			}
			try
			{
				GameObject val = new GameObject("ModernStatsHUD_Controller");
				Object.DontDestroyOnLoad((Object)(object)val);
				_hudView = val.AddComponent<ModernHudView>();
				_tabOverlay = val.AddComponent<ModernTabOverlay>();
				ManualLogSource logger = Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"[ModernStatsHUD] HUD components successfully initialized.");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger2 = Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)string.Format("[{0}] Error initializing HUD components: {1}", "ModernStatsHUD", arg));
				}
			}
		}

		private void Update()
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			ModConfig instance = ModConfig.Instance;
			if (instance == null)
			{
				return;
			}
			bool flag = (Object)(object)PlayerManager.instance != (Object)null && PlayerManager.instance.players != null && PlayerManager.instance.players.Count > 0;
			if (!MatchActive && !flag)
			{
				if ((Object)(object)_hudView != (Object)null && (Object)(object)_hudView.Canvas != (Object)null && ((Component)_hudView.Canvas).gameObject.activeSelf)
				{
					_hudView.SetVisible(visible: false);
				}
				if ((Object)(object)_tabOverlay != (Object)null && _tabOverlay.IsOpen)
				{
					_tabOverlay.SetOpen(open: false);
				}
				return;
			}
			EnsureInitialized();
			if (Input.GetKeyDown(instance.ToggleKey.Value))
			{
				instance.EnableHUD.Value = !instance.EnableHUD.Value;
				ModConfig.TriggerChanged();
			}
			_pollTimer += Time.deltaTime;
			if (_pollTimer >= 0.05f)
			{
				_pollTimer = 0f;
				UpdateHUD();
			}
		}

		private void UpdateHUD()
		{
			if ((Object)(object)_hudView == (Object)null)
			{
				return;
			}
			ModConfig instance = ModConfig.Instance;
			Player localPlayer = GetLocalPlayer();
			if ((Object)(object)localPlayer == (Object)null)
			{
				_hudView.SetVisible(visible: false);
				return;
			}
			bool inPickPhase = InPickPhase;
			bool inBattlePhase = InBattlePhase;
			Player player = localPlayer;
			if (inPickPhase && !inBattlePhase && instance != null && instance.ShowActivePickerInDraft.Value)
			{
				Player currentPicker = GetCurrentPicker();
				if ((Object)(object)currentPicker != (Object)null)
				{
					player = currentPicker;
				}
			}
			CardInfo val = null;
			if (!inBattlePhase && IsPlayerPicking(player))
			{
				val = GetCurrentlyHoveredCard();
			}
			_hudView.SetHoveredCard(player, val);
			_hudView.UpdateStatsDisplay(player, (Object)(object)val != (Object)null || inPickPhase, inBattlePhase);
		}

		public static PickerType GetCardChoicePickerType(CardChoice choice)
		{
			//IL_002e: 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_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)
			if ((Object)(object)choice == (Object)null || _pickerTypeField == null)
			{
				return (PickerType)1;
			}
			try
			{
				return (PickerType)_pickerTypeField.GetValue(choice);
			}
			catch
			{
				return (PickerType)1;
			}
		}

		public static bool IsBot(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			try
			{
				if (_botsManagerInstanceProp != null && _botsManagerBotListProp != null)
				{
					object value = _botsManagerInstanceProp.GetValue(null);
					if (value != null && _botsManagerBotListProp.GetValue(value) is IEnumerable enumerable)
					{
						foreach (object item in enumerable)
						{
							Player val = (Player)((item is Player) ? item : null);
							if (val != null && (Object)(object)val == (Object)(object)player)
							{
								return true;
							}
						}
					}
				}
				if ((Object)(object)((Component)player).GetComponent("PlayerAIBase") != (Object)null || (Object)(object)((Component)player).GetComponent("PlayerAIPhilip") != (Object)null || (Object)(object)((Component)player).GetComponent("AIAttackModule") != (Object)null || (Object)(object)((Component)player).GetComponent("AIModuleBase") != (Object)null)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		public static bool IsBotPicking()
		{
			try
			{
				if (_botPickerInstanceProp != null && _botPickerAIPickingField != null)
				{
					object value = _botPickerInstanceProp.GetValue(null);
					if (value != null)
					{
						return (bool)_botPickerAIPickingField.GetValue(value);
					}
				}
			}
			catch
			{
			}
			return false;
		}

		public static Player FindPlayerById(int id)
		{
			try
			{
				if ((Object)(object)PlayerManager.instance != (Object)null && PlayerManager.instance.players != null)
				{
					foreach (Player player in PlayerManager.instance.players)
					{
						if ((Object)(object)player != (Object)null && player.playerID == id)
						{
							return player;
						}
					}
				}
			}
			catch
			{
			}
			return null;
		}

		public static Player GetCurrentPicker()
		{
			//IL_00c4: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Invalid comparison between Unknown and I4
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Invalid comparison between Unknown and I4
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (_epPhaseActiveField != null)
				{
					bool flag = false;
					try
					{
						flag = (bool)_epPhaseActiveField.GetValue(null);
					}
					catch
					{
					}
					if (flag)
					{
						bool flag2 = false;
						int num = -1;
						try
						{
							flag2 = _epLocalPickActiveField != null && (bool)_epLocalPickActiveField.GetValue(null);
							num = ((_epCurrentSessionPlayerField != null) ? ((int)_epCurrentSessionPlayerField.GetValue(null)) : (-1));
						}
						catch
						{
						}
						if (flag2 && num >= 0)
						{
							Player val = FindPlayerById(num);
							if ((Object)(object)val != (Object)null)
							{
								return val;
							}
						}
						return GetLocalPlayer();
					}
				}
				if (IsBotPicking())
				{
					CardChoice instance = CardChoice.instance;
					if ((Object)(object)instance != (Object)null)
					{
						PickerType cardChoicePickerType = GetCardChoicePickerType(instance);
						if ((int)cardChoicePickerType == 1)
						{
							Player val2 = FindPlayerById(instance.pickrID);
							if ((Object)(object)val2 != (Object)null)
							{
								return val2;
							}
						}
						else if ((int)cardChoicePickerType == 0)
						{
							PlayerManager instance2 = PlayerManager.instance;
							Player[] array = ((instance2 != null) ? instance2.GetPlayersInTeam(instance.pickrID) : null);
							if (array != null && array.Length != 0)
							{
								Player[] array2 = array;
								foreach (Player val3 in array2)
								{
									if ((Object)(object)val3 != (Object)null && IsBot(val3))
									{
										return val3;
									}
								}
								return array[0];
							}
						}
					}
				}
				CardChoice instance3 = CardChoice.instance;
				if ((Object)(object)instance3 != (Object)null && instance3.IsPicking)
				{
					PickerType cardChoicePickerType2 = GetCardChoicePickerType(instance3);
					if ((int)cardChoicePickerType2 == 1)
					{
						Player val4 = FindPlayerById(instance3.pickrID);
						if ((Object)(object)val4 != (Object)null)
						{
							return val4;
						}
					}
					else if ((int)cardChoicePickerType2 == 0)
					{
						PlayerManager instance4 = PlayerManager.instance;
						Player[] array3 = ((instance4 != null) ? instance4.GetPlayersInTeam(instance3.pickrID) : null);
						if (array3 != null && array3.Length != 0)
						{
							Player localPlayer = GetLocalPlayer();
							if ((Object)(object)localPlayer != (Object)null && localPlayer.teamID == instance3.pickrID)
							{
								return localPlayer;
							}
							return array3[0];
						}
					}
				}
				return GetLocalPlayer();
			}
			catch
			{
				return GetLocalPlayer();
			}
		}

		public static bool IsPlayerPicking(Player player)
		{
			//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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Invalid comparison between Unknown and I4
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Invalid comparison between Unknown and I4
			//IL_0139: 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)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			try
			{
				if (_epPhaseActiveField != null)
				{
					bool flag = false;
					try
					{
						flag = (bool)_epPhaseActiveField.GetValue(null);
					}
					catch
					{
					}
					if (flag)
					{
						bool flag2 = false;
						int num = -1;
						try
						{
							flag2 = _epLocalPickActiveField != null && (bool)_epLocalPickActiveField.GetValue(null);
							num = ((_epCurrentSessionPlayerField != null) ? ((int)_epCurrentSessionPlayerField.GetValue(null)) : (-1));
						}
						catch
						{
						}
						return flag2 && num == player.playerID;
					}
				}
				if (IsBotPicking())
				{
					if (!IsBot(player))
					{
						return false;
					}
					CardChoice instance = CardChoice.instance;
					if ((Object)(object)instance != (Object)null)
					{
						PickerType cardChoicePickerType = GetCardChoicePickerType(instance);
						if ((int)cardChoicePickerType == 1)
						{
							return instance.pickrID == player.playerID;
						}
						if ((int)cardChoicePickerType == 0)
						{
							return instance.pickrID == player.teamID;
						}
					}
					return true;
				}
				CardChoice instance2 = CardChoice.instance;
				if ((Object)(object)instance2 != (Object)null && instance2.IsPicking)
				{
					PickerType cardChoicePickerType2 = GetCardChoicePickerType(instance2);
					if ((int)cardChoicePickerType2 == 1)
					{
						return instance2.pickrID == player.playerID;
					}
					if ((int)cardChoicePickerType2 == 0)
					{
						return instance2.pickrID == player.teamID;
					}
				}
				if ((Object)(object)PlayerManager.instance != (Object)null && PlayerManager.instance.players != null && PlayerManager.instance.players.Count == 1)
				{
					return true;
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		public static Player GetLocalPlayer()
		{
			try
			{
				if ((Object)(object)PlayerManager.instance == (Object)null || PlayerManager.instance.players == null || PlayerManager.instance.players.Count == 0)
				{
					return null;
				}
				foreach (Player player in PlayerManager.instance.players)
				{
					if ((Object)(object)player != (Object)null && !IsBot(player) && (Object)(object)player.data != (Object)null && (Object)(object)player.data.view != (Object)null && player.data.view.IsMine)
					{
						return player;
					}
				}
				foreach (Player player2 in PlayerManager.instance.players)
				{
					if ((Object)(object)player2 != (Object)null && !IsBot(player2))
					{
						return player2;
					}
				}
				return PlayerManager.instance.players[0];
			}
			catch
			{
				return null;
			}
		}

		public static CardInfo GetCurrentlyHoveredCard()
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (_epLocalCardsField != null)
				{
					try
					{
						if (_epLocalCardsField.GetValue(null) is IEnumerable enumerable)
						{
							CardInfo val = null;
							float num = 1.04f;
							foreach (object item in enumerable)
							{
								GameObject val2 = (GameObject)((item is GameObject) ? item : null);
								if (val2 == null || !((Object)(object)val2 != (Object)null))
								{
									continue;
								}
								CardVisuals componentInChildren = val2.GetComponentInChildren<CardVisuals>(true);
								if ((Object)(object)componentInChildren != (Object)null && (ReadFlag(componentInChildren, _isSelectedField) || ReadFlag(componentInChildren, _isHoveredField)))
								{
									CardInfo val3 = val2.GetComponent<CardInfo>() ?? val2.GetComponentInChildren<CardInfo>();
									if ((Object)(object)val3 != (Object)null)
									{
										return val3;
									}
								}
								float x = val2.transform.localScale.x;
								if (x > num)
								{
									num = x;
									CardInfo val4 = val2.GetComponent<CardInfo>() ?? val2.GetComponentInChildren<CardInfo>();
									if ((Object)(object)val4 != (Object)null)
									{
										val = val4;
									}
								}
							}
							if ((Object)(object)val != (Object)null)
							{
								return val;
							}
						}
					}
					catch
					{
					}
				}
				CardChoice instance = CardChoice.instance;
				if ((Object)(object)instance != (Object)null)
				{
					object obj2 = _currentlySelectedField?.GetValue(instance) ?? _currentlySelectedProp?.GetValue(instance);
					if (obj2 != null)
					{
						GameObject val5 = (GameObject)((obj2 is GameObject) ? obj2 : null);
						if (val5 != null && (Object)(object)val5 != (Object)null)
						{
							CardInfo val6 = val5.GetComponent<CardInfo>() ?? val5.GetComponentInChildren<CardInfo>();
							if ((Object)(object)val6 != (Object)null)
							{
								return val6;
							}
						}
						else
						{
							CardInfo val7 = (CardInfo)((obj2 is CardInfo) ? obj2 : null);
							if (val7 != null && (Object)(object)val7 != (Object)null)
							{
								return val7;
							}
							if (obj2 is int num2 && num2 >= 0 && _spawnedCardsField != null && _spawnedCardsField.GetValue(instance) is List<GameObject> list && num2 < list.Count)
							{
								GameObject val8 = list[num2];
								if ((Object)(object)val8 != (Object)null)
								{
									CardInfo val9 = val8.GetComponent<CardInfo>() ?? val8.GetComponentInChildren<CardInfo>();
									if ((Object)(object)val9 != (Object)null)
									{
										return val9;
									}
								}
							}
						}
					}
				}
				if ((Object)(object)instance != (Object)null && _spawnedCardsField != null && _spawnedCardsField.GetValue(instance) is IEnumerable enumerable2)
				{
					CardInfo val10 = null;
					float num3 = 1.04f;
					foreach (object item2 in enumerable2)
					{
						GameObject val11 = (GameObject)((item2 is GameObject) ? item2 : null);
						if (val11 == null || !((Object)(object)val11 != (Object)null))
						{
							continue;
						}
						CardVisuals componentInChildren2 = val11.GetComponentInChildren<CardVisuals>(true);
						if ((Object)(object)componentInChildren2 != (Object)null && (ReadFlag(componentInChildren2, _isSelectedField) || ReadFlag(componentInChildren2, _isHoveredField)))
						{
							CardInfo val12 = val11.GetComponent<CardInfo>() ?? val11.GetComponentInChildren<CardInfo>();
							if ((Object)(object)val12 != (Object)null)
							{
								return val12;
							}
						}
						float x2 = val11.transform.localScale.x;
						if (x2 > num3)
						{
							num3 = x2;
							CardInfo val13 = val11.GetComponent<CardInfo>() ?? val11.GetComponentInChildren<CardInfo>();
							if ((Object)(object)val13 != (Object)null)
							{
								val10 = val13;
							}
						}
					}
					if ((Object)(object)val10 != (Object)null)
					{
						return val10;
					}
				}
				CardVisuals[] array = Object.FindObjectsOfType<CardVisuals>();
				if (array != null && array.Length != 0)
				{
					CardInfo val14 = null;
					float num4 = 1.04f;
					CardVisuals[] array2 = array;
					foreach (CardVisuals val15 in array2)
					{
						if ((Object)(object)val15 == (Object)null || !((Component)val15).gameObject.activeInHierarchy)
						{
							continue;
						}
						if (ReadFlag(val15, _isSelectedField) || ReadFlag(val15, _isHoveredField))
						{
							CardInfo val16 = ((Component)val15).GetComponentInParent<CardInfo>() ?? ((Component)val15).GetComponent<CardInfo>();
							if ((Object)(object)val16 != (Object)null)
							{
								return val16;
							}
						}
						float x3 = ((Component)val15).transform.localScale.x;
						if (x3 > num4)
						{
							num4 = x3;
							CardInfo val17 = ((Component)val15).GetComponentInParent<CardInfo>() ?? ((Component)val15).GetComponent<CardInfo>();
							if ((Object)(object)val17 != (Object)null)
							{
								val14 = val17;
							}
						}
					}
					if ((Object)(object)val14 != (Object)null)
					{
						return val14;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static bool ReadFlag(CardVisuals visuals, FieldInfo field)
		{
			if ((Object)(object)visuals == (Object)null || field == null)
			{
				return false;
			}
			try
			{
				return (bool)field.GetValue(visuals);
			}
			catch
			{
				return false;
			}
		}
	}
}
namespace ModernStatsHUD.UI
{
	public class ModernHudView : MonoBehaviour
	{
		private static ModernHudView _instance;

		private Canvas _canvas;

		private CanvasScaler _scaler;

		private GameObject _hudRoot;

		private RectTransform _rootRect;

		private Image _bgImage;

		private Image _accentBar;

		private TextMeshProUGUI _headerText;

		private TextMeshProUGUI _bodyText;

		private CardInfo _hoveredCard;

		private Dictionary<string, float> _currentDeltas = new Dictionary<string, float>();

		public static ModernHudView Instance => _instance;

		public Canvas Canvas => _canvas;

		private void Awake()
		{
			_instance = this;
			BuildUI();
			ModConfig.OnConfigChanged += OnConfigChanged;
		}

		private void OnDestroy()
		{
			ModConfig.OnConfigChanged -= OnConfigChanged;
			if ((Object)(object)_hudRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_hudRoot);
			}
		}

		private void BuildUI()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_00a7: 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_00fd: Expected O, but got Unknown
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Expected O, but got Unknown
			//IL_01b1: 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_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Expected O, but got Unknown
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Expected O, but got Unknown
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ModernStatsHUD_Canvas", new Type[4]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster)
			});
			Object.DontDestroyOnLoad((Object)(object)val);
			_canvas = val.GetComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 300;
			_canvas.pixelPerfect = false;
			_scaler = val.GetComponent<CanvasScaler>();
			_scaler.uiScaleMode = (ScaleMode)1;
			_scaler.referenceResolution = new Vector2(1920f, 1080f);
			_scaler.screenMatchMode = (ScreenMatchMode)0;
			_scaler.matchWidthOrHeight = 1f;
			_hudRoot = new GameObject("ModernStatsHUD_Panel", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			_hudRoot.transform.SetParent(val.transform, false);
			_rootRect = _hudRoot.GetComponent<RectTransform>();
			_bgImage = _hudRoot.GetComponent<Image>();
			_bgImage.sprite = UIHelpers.GetRoundedSprite();
			_bgImage.type = (Type)1;
			((Graphic)_bgImage).raycastTarget = false;
			GameObject val2 = new GameObject("AccentGlow", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val2.transform.SetParent(_hudRoot.transform, false);
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.anchoredPosition = new Vector2(0f, 0f);
			component.sizeDelta = new Vector2(-16f, 3.5f);
			_accentBar = val2.GetComponent<Image>();
			((Graphic)_accentBar).raycastTarget = false;
			GameObject val3 = new GameObject("HeaderLabel", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val3.transform.SetParent(_hudRoot.transform, false);
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(0f, 1f);
			component2.anchoredPosition = new Vector2(14f, -10f);
			component2.sizeDelta = new Vector2(-28f, 28f);
			_headerText = val3.GetComponent<TextMeshProUGUI>();
			TMP_FontAsset defaultTMPFont = UIHelpers.GetDefaultTMPFont();
			if ((Object)(object)defaultTMPFont != (Object)null)
			{
				((TMP_Text)_headerText).font = defaultTMPFont;
			}
			((TMP_Text)_headerText).fontSize = 16f;
			((TMP_Text)_headerText).richText = true;
			((TMP_Text)_headerText).alignment = (TextAlignmentOptions)513;
			((Graphic)_headerText).raycastTarget = false;
			GameObject val4 = new GameObject("BodyLabel", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val4.transform.SetParent(_hudRoot.transform, false);
			RectTransform component3 = val4.GetComponent<RectTransform>();
			component3.anchorMin = Vector2.zero;
			component3.anchorMax = Vector2.one;
			component3.offsetMin = new Vector2(14f, 10f);
			component3.offsetMax = new Vector2(-14f, -40f);
			_bodyText = val4.GetComponent<TextMeshProUGUI>();
			if ((Object)(object)defaultTMPFont != (Object)null)
			{
				((TMP_Text)_bodyText).font = defaultTMPFont;
			}
			((TMP_Text)_bodyText).richText = true;
			((TMP_Text)_bodyText).alignment = (TextAlignmentOptions)257;
			((Graphic)_bodyText).raycastTarget = false;
			((TMP_Text)_bodyText).enableWordWrapping = false;
			((TMP_Text)_bodyText).overflowMode = (TextOverflowModes)0;
			ApplyConfiguration();
		}

		public void ApplyConfiguration()
		{
			//IL_0069: 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_009d: 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_00ce: 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_0102: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: 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)
			ModConfig instance = ModConfig.Instance;
			if (instance != null && !((Object)(object)_rootRect == (Object)null))
			{
				float value = instance.OffsetX.Value;
				float value2 = instance.OffsetY.Value;
				switch (instance.Position.Value)
				{
				case ScreenPosition.BottomLeft:
					_rootRect.anchorMin = new Vector2(0f, 0f);
					_rootRect.anchorMax = new Vector2(0f, 0f);
					_rootRect.pivot = new Vector2(0f, 0f);
					_rootRect.anchoredPosition = new Vector2(value, value2);
					break;
				case ScreenPosition.TopLeft:
					_rootRect.anchorMin = new Vector2(0f, 1f);
					_rootRect.anchorMax = new Vector2(0f, 1f);
					_rootRect.pivot = new Vector2(0f, 1f);
					_rootRect.anchoredPosition = new Vector2(value, 0f - value2);
					break;
				case ScreenPosition.BottomRight:
					_rootRect.anchorMin = new Vector2(1f, 0f);
					_rootRect.anchorMax = new Vector2(1f, 0f);
					_rootRect.pivot = new Vector2(1f, 0f);
					_rootRect.anchoredPosition = new Vector2(0f - value, value2);
					break;
				case ScreenPosition.TopRight:
					_rootRect.anchorMin = new Vector2(1f, 1f);
					_rootRect.anchorMax = new Vector2(1f, 1f);
					_rootRect.pivot = new Vector2(1f, 1f);
					_rootRect.anchoredPosition = new Vector2(0f - value, 0f - value2);
					break;
				}
				float num = Mathf.Clamp(instance.Scale.Value, 0.5f, 2f);
				((Transform)_rootRect).localScale = new Vector3(num, num, 1f);
				float num2 = Mathf.Clamp(instance.Width.Value, 240f, 520f);
				_rootRect.sizeDelta = new Vector2(num2, _rootRect.sizeDelta.y);
				((TMP_Text)_bodyText).fontSize = Mathf.Clamp(instance.FontSize.Value, 11f, 24f);
				float num3 = Mathf.Clamp01(instance.Opacity.Value);
				((Graphic)_bgImage).color = new Color(0.04f, 0.06f, 0.09f, num3);
				Color accentColor = instance.GetAccentColor();
				((Graphic)_accentBar).color = accentColor;
				((Component)_accentBar).gameObject.SetActive(instance.ShowAccentGlow.Value);
			}
		}

		private void OnConfigChanged()
		{
			ApplyConfiguration();
		}

		public void SetHoveredCard(Player player, CardInfo card)
		{
			if ((Object)(object)card == (Object)null || (Object)(object)player == (Object)null)
			{
				if ((Object)(object)_hoveredCard != (Object)null || _currentDeltas.Count > 0)
				{
					_hoveredCard = null;
					_currentDeltas.Clear();
				}
			}
			else if (!((Object)(object)_hoveredCard == (Object)(object)card))
			{
				_hoveredCard = card;
				ModConfig instance = ModConfig.Instance;
				if (instance != null && instance.ShowPickPreview.Value)
				{
					_currentDeltas = CardPreviewCalculator.CalculateDeltas(player, card);
				}
				else
				{
					_currentDeltas.Clear();
				}
			}
		}

		public void SetVisible(bool visible)
		{
			if ((Object)(object)_hudRoot != (Object)null && _hudRoot.activeSelf != visible)
			{
				_hudRoot.SetActive(visible);
			}
		}

		public void UpdateStatsDisplay(Player player, bool inPickPhase, bool inBattlePhase)
		{
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Invalid comparison between Unknown and I4
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Invalid comparison between Unknown and I4
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
			ModConfig instance = ModConfig.Instance;
			if (instance == null || (Object)(object)_hudRoot == (Object)null)
			{
				return;
			}
			if (!instance.EnableHUD.Value || (inBattlePhase && instance.HideInBattle.Value) || (inPickPhase && instance.HideInPickPhase.Value))
			{
				SetVisible(visible: false);
				return;
			}
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null)
			{
				SetVisible(visible: false);
				return;
			}
			SetVisible(visible: true);
			string text = UIHelpers.ColorToHex(instance.GetAccentColor());
			string arg = "#38BDF8";
			try
			{
				PlayerSkin playerSkinColors = PlayerSkinBank.GetPlayerSkinColors(player.playerID);
				if ((Object)(object)playerSkinColors != (Object)null && playerSkinColors.color.a > 0.1f)
				{
					arg = UIHelpers.ColorToHex(playerSkinColors.color);
				}
			}
			catch
			{
			}
			string text2 = "PLAYER";
			bool flag = (Object)(object)player == (Object)(object)ModernStatsHUDPlugin.GetLocalPlayer();
			bool flag2 = ModernStatsHUDPlugin.IsBot(player);
			try
			{
				PhotonView view = player.data.view;
				text2 = ((!((Object)(object)view != (Object)null) || view.Owner == null || string.IsNullOrEmpty(view.Owner.NickName)) ? $"PLAYER {player.playerID + 1}" : view.Owner.NickName);
			}
			catch
			{
			}
			if (flag2)
			{
				text2 += " [BOT]";
			}
			else if (flag)
			{
				text2 += " (YOU)";
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append($"<b><color={arg}>[P{player.playerID + 1}]</color> {text2}</b>");
			if ((Object)(object)_hoveredCard != (Object)null)
			{
				string text3 = "#FFFFFF";
				Rarity rarity = _hoveredCard.rarity;
				if ((int)rarity != 1)
				{
					if ((int)rarity == 2)
					{
						text3 = "#F59E0B";
					}
				}
				else
				{
					text3 = "#38BDF8";
				}
				stringBuilder.Append("  <color=" + text3 + ">> <b>" + _hoveredCard.cardName.ToUpper() + "</b></color>");
			}
			else if (inPickPhase)
			{
				stringBuilder.Append("  <color=#94A3B8>[ DRAFTING ]</color>");
			}
			((TMP_Text)_headerText).text = stringBuilder.ToString();
			List<StatEntry> list = PlayerStatsReader.ReadAllStats(player);
			if ((Object)(object)_hoveredCard != (Object)null && _currentDeltas.Count > 0)
			{
				foreach (KeyValuePair<string, float> currentDelta in _currentDeltas)
				{
					bool flag3 = false;
					for (int i = 0; i < list.Count; i++)
					{
						if (list[i].Key == currentDelta.Key)
						{
							flag3 = true;
							break;
						}
					}
					if (!flag3)
					{
						list.Add(CreateStatEntryForPreview(currentDelta.Key, currentDelta.Value));
					}
				}
			}
			StringBuilder stringBuilder2 = new StringBuilder();
			bool value = instance.OnlyShowChangedStats.Value;
			bool value2 = instance.ShowModdedStats.Value;
			bool value3 = instance.ShowCategoryHeaders.Value;
			StatCategory? statCategory = null;
			int num = 0;
			foreach (StatEntry item in list)
			{
				if ((item.IsModded && !value2) || (value && !item.IsModified && !item.IsModded && !_currentDeltas.ContainsKey(item.Key)))
				{
					continue;
				}
				if (value3 && statCategory != item.Category)
				{
					statCategory = item.Category;
					num = 0;
					string text4 = item.Category switch
					{
						StatCategory.Vitality => "VITALITY & DEFENSE", 
						StatCategory.Weapon => "WEAPON & COMBAT", 
						StatCategory.Mobility => "MOBILITY", 
						StatCategory.Modded => "MODDED & BUFFS", 
						_ => item.Category.ToString().ToUpper(), 
					};
					if (stringBuilder2.Length > 0)
					{
						stringBuilder2.AppendLine();
					}
					stringBuilder2.AppendLine("<color=" + text + "><b><size=85%>-- " + text4 + " --</size></b></color>");
				}
				string text5 = "";
				if (_currentDeltas.TryGetValue(item.Key, out var value4))
				{
					text5 = CardPreviewCalculator.FormatDeltaBadge(item.Key, value4, item.LowerIsBetter);
				}
				string text6 = item.Category switch
				{
					StatCategory.Vitality => "#38BDF8", 
					StatCategory.Weapon => "#F59E0B", 
					StatCategory.Mobility => "#10B981", 
					StatCategory.Modded => "#C084FC", 
					_ => "#94A3B8", 
				};
				stringBuilder2.AppendLine("<color=" + text6 + "><b>" + item.Label + "</b></color><pos=54%><color=#F8FAFC><b>" + item.ValueString + "</b></color>" + text5 + "</pos>");
				num++;
			}
			if (stringBuilder2.Length == 0)
			{
				stringBuilder2.AppendLine("<color=#64748B><i>No active stat modifications</i></color>");
			}
			((TMP_Text)_bodyText).text = stringBuilder2.ToString();
			((TMP_Text)_bodyText).ForceMeshUpdate();
			float num2 = ((TMP_Text)_bodyText).preferredHeight + 52f;
			float num3 = ((Screen.height > 0) ? ((float)Screen.height * 0.95f) : 1000f);
			float num4 = Mathf.Clamp(num2, 80f, Mathf.Max(950f, num3));
			_rootRect.sizeDelta = new Vector2(instance.Width.Value, num4);
			((TMP_Text)_bodyText).ForceMeshUpdate();
		}

		public static StatEntry CreateStatEntryForPreview(string key, float delta)
		{
			if (key.StartsWith("Custom_"))
			{
				string customStatLabel = CardPreviewCalculator.GetCustomStatLabel(key);
				return new StatEntry(StatCategory.Modded, key, customStatLabel, "[MOD]", "0", 0f, 0f, lowerIsBetter: false, isModded: true);
			}
			return key switch
			{
				"BulletPortal" => new StatEntry(StatCategory.Modded, "BulletPortal", "Portals", "", "0", 0f, 0f, lowerIsBetter: false, isModded: true), 
				"ProjectileSize" => new StatEntry(StatCategory.Modded, "ProjectileSize", "Proj Size", "", "1.00x", 0f, 0f, lowerIsBetter: false, isModded: true), 
				"GunCharge" => new StatEntry(StatCategory.Modded, "GunCharge", "Charge Dmg", "", "1.0x", 1f, 1f, lowerIsBetter: false, isModded: true), 
				"EvenSpread" => new StatEntry(StatCategory.Modded, "EvenSpread", "Even Spread", "", "0.0 deg", 0f, 0f, lowerIsBetter: false, isModded: true), 
				"BlockForce" => new StatEntry(StatCategory.Modded, "BlockForce", "Block Force", "", "0.0", 0f, 0f, lowerIsBetter: false, isModded: true), 
				"Unblockable" => new StatEntry(StatCategory.Modded, "Unblockable", "Unblockable", "", "OFF", 0f, 0f, lowerIsBetter: false, isModded: true), 
				"IgnoreWalls" => new StatEntry(StatCategory.Modded, "IgnoreWalls", "Wall Pierce", "", "OFF", 0f, 0f, lowerIsBetter: false, isModded: true), 
				"Respawns" => new StatEntry(StatCategory.Vitality, "Respawns", "Respawns", "", "0", 0f, 0f), 
				"Bursts" => new StatEntry(StatCategory.Weapon, "Bursts", "Bursts", "", "0", 0f, 0f), 
				"Bounces" => new StatEntry(StatCategory.Weapon, "Bounces", "Bounces", "", "0", 0f, 0f), 
				"Knockback" => new StatEntry(StatCategory.Weapon, "Knockback", "Knockback", "", "1.00x", 1f, 1f), 
				"Slow" => new StatEntry(StatCategory.Weapon, "Slow", "Target Slow", "", "0%", 0f, 0f), 
				_ => new StatEntry(StatCategory.Modded, key, key, "", "0", 0f, 0f, lowerIsBetter: false, isModded: true), 
			};
		}
	}
	public static class ModernMenuBuilder
	{
		public static void BuildMenu(GameObject menu)
		{
			//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_01a9: 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_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_054f: Unknown result type (might be due to invalid IL or missing references)
			//IL_079f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0826: Unknown result type (might be due to invalid IL or missing references)
			ModernStatsHUDPlugin.Instance?.EnsureInitialized();
			ModConfig cfg = ModConfig.Instance;
			TextMeshProUGUI statusCardText = default(TextMeshProUGUI);
			Dictionary<ScreenPosition, TextMeshProUGUI> posButtons;
			Dictionary<AccentColorPreset, TextMeshProUGUI> themeButtons;
			if (cfg != null && !((Object)(object)menu == (Object)null))
			{
				AddHeader("MODERN STATS HUD", 46, new Color(0f, 0.9f, 1f), menu);
				AddSubtitle("Real-time player stats, modded attribute tracking & draft previews.", menu);
				MenuHandler.CreateText(GetStatusCard(cfg), menu, ref statusCardText, 20, false, (Color?)new Color(0.95f, 0.95f, 1f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)(TextAlignmentOptions)514);
				AddSpacer(menu);
				AddSectionTitle("HUD POSITION ON SCREEN", menu);
				posButtons = new Dictionary<ScreenPosition, TextMeshProUGUI>();
				GameObject val = AddButton("Bottom-Left", menu, delegate
				{
					cfg.SetPositionPreset(ScreenPosition.BottomLeft);
					UpdatePosButtons();
				});
				posButtons[ScreenPosition.BottomLeft] = val.GetComponentInChildren<TextMeshProUGUI>();
				GameObject val2 = AddButton("Top-Left", menu, delegate
				{
					cfg.SetPositionPreset(ScreenPosition.TopLeft);
					UpdatePosButtons();
				});
				posButtons[ScreenPosition.TopLeft] = val2.GetComponentInChildren<TextMeshProUGUI>();
				GameObject val3 = AddButton("Bottom-Right", menu, delegate
				{
					cfg.SetPositionPreset(ScreenPosition.BottomRight);
					UpdatePosButtons();
				});
				posButtons[ScreenPosition.BottomRight] = val3.GetComponentInChildren<TextMeshProUGUI>();
				GameObject val4 = AddButton("Top-Right", menu, delegate
				{
					cfg.SetPositionPreset(ScreenPosition.TopRight);
					UpdatePosButtons();
				});
				posButtons[ScreenPosition.TopRight] = val4.GetComponentInChildren<TextMeshProUGUI>();
				UpdatePosButtons();
				AddSpacer(menu);
				TextMeshProUGUI posXLabel = default(TextMeshProUGUI);
				MenuHandler.CreateText($"Horizontal Offset (X): {cfg.OffsetX.Value:F0} px", menu, ref posXLabel, 20, false, (Color?)new Color(0.7f, 0.8f, 0.9f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				AddSlider(0f, 600f, cfg.OffsetX.Value, whole: true, menu, delegate(float num)
				{
					cfg.OffsetX.Value = num;
					((TMP_Text)posXLabel).text = $"Horizontal Offset (X): {num:F0} px";
					ModConfig.TriggerChanged();
					RefreshStatus();
				});
				TextMeshProUGUI posYLabel = default(TextMeshProUGUI);
				MenuHandler.CreateText($"Vertical Offset (Y): {cfg.OffsetY.Value:F0} px", menu, ref posYLabel, 20, false, (Color?)new Color(0.7f, 0.8f, 0.9f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				AddSlider(0f, 600f, cfg.OffsetY.Value, whole: true, menu, delegate(float num)
				{
					cfg.OffsetY.Value = num;
					((TMP_Text)posYLabel).text = $"Vertical Offset (Y): {num:F0} px";
					ModConfig.TriggerChanged();
					RefreshStatus();
				});
				AddSpacer(menu);
				AddSectionTitle("HUD SIZING & DIMENSIONS", menu);
				TextMeshProUGUI scaleLabel = default(TextMeshProUGUI);
				MenuHandler.CreateText($"Overall Scale: {cfg.Scale.Value * 100f:F0}%", menu, ref scaleLabel, 20, false, (Color?)new Color(0.7f, 0.8f, 0.9f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				AddSlider(0.5f, 2f, cfg.Scale.Value, whole: false, menu, delegate(float num)
				{
					cfg.Scale.Value = num;
					((TMP_Text)scaleLabel).text = $"Overall Scale: {num * 100f:F0}%";
					ModConfig.TriggerChanged();
					RefreshStatus();
				});
				TextMeshProUGUI widthLabel = default(TextMeshProUGUI);
				MenuHandler.CreateText($"Panel Width: {cfg.Width.Value:F0} px", menu, ref widthLabel, 20, false, (Color?)new Color(0.7f, 0.8f, 0.9f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				AddSlider(240f, 520f, cfg.Width.Value, whole: true, menu, delegate(float num)
				{
					cfg.Width.Value = num;
					((TMP_Text)widthLabel).text = $"Panel Width: {num:F0} px";
					ModConfig.TriggerChanged();
					RefreshStatus();
				});
				TextMeshProUGUI fontLabel = default(TextMeshProUGUI);
				MenuHandler.CreateText($"Font Size: {cfg.FontSize.Value:F0} pt", menu, ref fontLabel, 20, false, (Color?)new Color(0.7f, 0.8f, 0.9f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				AddSlider(11f, 24f, cfg.FontSize.Value, whole: true, menu, delegate(float num)
				{
					cfg.FontSize.Value = num;
					((TMP_Text)fontLabel).text = $"Font Size: {num:F0} pt";
					ModConfig.TriggerChanged();
					RefreshStatus();
				});
				AddSpacer(menu);
				AddSectionTitle("THEME & ACCENT COLORS", menu);
				themeButtons = new Dictionary<AccentColorPreset, TextMeshProUGUI>();
				GameObject val5 = AddButton("Neon Cyan", menu, delegate
				{
					cfg.SetAccentPreset(AccentColorPreset.Cyan);
					UpdateThemeButtons();
				});
				themeButtons[AccentColorPreset.Cyan] = val5.GetComponentInChildren<TextMeshProUGUI>();
				GameObject val6 = AddButton("Neon Violet", menu, delegate
				{
					cfg.SetAccentPreset(AccentColorPreset.Violet);
					UpdateThemeButtons();
				});
				themeButtons[AccentColorPreset.Violet] = val6.GetComponentInChildren<TextMeshProUGUI>();
				GameObject val7 = AddButton("Emerald Green", menu, delegate
				{
					cfg.SetAccentPreset(AccentColorPreset.Emerald);
					UpdateThemeButtons();
				});
				themeButtons[AccentColorPreset.Emerald] = val7.GetComponentInChildren<TextMeshProUGUI>();
				GameObject val8 = AddButton("Amber Gold", menu, delegate
				{
					cfg.SetAccentPreset(AccentColorPreset.Gold);
					UpdateThemeButtons();
				});
				themeButtons[AccentColorPreset.Gold] = val8.GetComponentInChildren<TextMeshProUGUI>();
				GameObject val9 = AddButton("Ruby Crimson", menu, delegate
				{
					cfg.SetAccentPreset(AccentColorPreset.Ruby);
					UpdateThemeButtons();
				});
				themeButtons[AccentColorPreset.Ruby] = val9.GetComponentInChildren<TextMeshProUGUI>();
				UpdateThemeButtons();
				AddSpacer(menu);
				TextMeshProUGUI opacityLabel = default(TextMeshProUGUI);
				MenuHandler.CreateText($"Background Opacity: {cfg.Opacity.Value * 100f:F0}%", menu, ref opacityLabel, 20, false, (Color?)new Color(0.7f, 0.8f, 0.9f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				AddSlider(0.1f, 1f, cfg.Opacity.Value, whole: false, menu, delegate(float num)
				{
					cfg.Opacity.Value = num;
					((TMP_Text)opacityLabel).text = $"Background Opacity: {num * 100f:F0}%";
					ModConfig.TriggerChanged();
					RefreshStatus();
				});
				AddToggle("Show Accent Glow Bar at Top", cfg.ShowAccentGlow.Value, menu, delegate(bool value)
				{
					cfg.ShowAccentGlow.Value = value;
					ModConfig.TriggerChanged();
				});
				AddToggle("Show Category Dividers (Vitality, Weapon, etc.)", cfg.ShowCategoryHeaders.Value, menu, delegate(bool value)
				{
					cfg.ShowCategoryHeaders.Value = value;
					ModConfig.TriggerChanged();
				});
				AddSpacer(menu);
				AddSectionTitle("DISPLAY BEHAVIOR & PREVIEWS", menu);
				AddToggle("Enable Stats HUD", cfg.EnableHUD.Value, menu, delegate(bool value)
				{
					cfg.EnableHUD.Value = value;
					ModConfig.TriggerChanged();
					RefreshStatus();
				});
				AddToggle("Only Show Modified / Changed Stats", cfg.OnlyShowChangedStats.Value, menu, delegate(bool value)
				{
					cfg.OnlyShowChangedStats.Value = value;
					ModConfig.TriggerChanged();
				});
				AddToggle("Show Modded Parameters (when acquired)", cfg.ShowModdedStats.Value, menu, delegate(bool value)
				{
					cfg.ShowModdedStats.Value = value;
					ModConfig.TriggerChanged();
				});
				AddToggle("Show Card Pick Hover Deltas (+X / -X)", cfg.ShowPickPreview.Value, menu, delegate(bool value)
				{
					cfg.ShowPickPreview.Value = value;
					ModConfig.TriggerChanged();
				});
				AddToggle("Show Active Picker in Draft (stats & preview)", cfg.ShowActivePickerInDraft.Value, menu, delegate(bool value)
				{
					cfg.ShowActivePickerInDraft.Value = value;
					ModConfig.TriggerChanged();
				});
				AddToggle("Hide HUD During Battle Phase", cfg.HideInBattle.Value, menu, delegate(bool value)
				{
					cfg.HideInBattle.Value = value;
					ModConfig.TriggerChanged();
				});
				AddToggle("Hide HUD During Card Draft Phase", cfg.HideInPickPhase.Value, menu, delegate(bool value)
				{
					cfg.HideInPickPhase.Value = value;
					ModConfig.TriggerChanged();
				});
				AddSpacer(menu);
				AddSectionTitle("TAB OVERLAY (OTHER PLAYERS SCOREBOARD)", menu);
				AddToggle("Enable Tab Overlay Scoreboard", cfg.EnableTabOverlay.Value, menu, delegate(bool value)
				{
					cfg.EnableTabOverlay.Value = value;
					ModConfig.TriggerChanged();
				});
				AddToggle("Hold Mode (Hold Tab instead of Toggle)", cfg.TabOverlayHoldMode.Value, menu, delegate(bool value)
				{
					cfg.TabOverlayHoldMode.Value = value;
					ModConfig.TriggerChanged();
				});
				TextMeshProUGUI tabWidthLabel = default(TextMeshProUGUI);
				MenuHandler.CreateText($"Tab Overlay Width: {cfg.TabPanelWidth.Value:F0} px", menu, ref tabWidthLabel, 20, false, (Color?)new Color(0.7f, 0.8f, 0.9f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				AddSlider(520f, 1100f, cfg.TabPanelWidth.Value, whole: true, menu, delegate(float num)
				{
					cfg.TabPanelWidth.Value = num;
					((TMP_Text)tabWidthLabel).text = $"Tab Overlay Width: {num:F0} px";
					ModConfig.TriggerChanged();
				});
				TextMeshProUGUI tabOpacityLabel = default(TextMeshProUGUI);
				MenuHandler.CreateText($"Tab Overlay Opacity: {cfg.TabPanelOpacity.Value * 100f:F0}%", menu, ref tabOpacityLabel, 20, false, (Color?)new Color(0.7f, 0.8f, 0.9f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				AddSlider(0.3f, 1f, cfg.TabPanelOpacity.Value, whole: false, menu, delegate(float num)
				{
					cfg.TabPanelOpacity.Value = num;
					((TMP_Text)tabOpacityLabel).text = $"Tab Overlay Opacity: {num * 100f:F0}%";
					ModConfig.TriggerChanged();
				});
				AddSpacer(menu);
				AddSectionTitle("ACTIONS", menu);
				AddButton("Reset All Settings to Default", menu, delegate
				{
					cfg.ResetToDefaults();
					UpdatePosButtons();
					UpdateThemeButtons();
					RefreshStatus();
				});
			}
			void RefreshStatus()
			{
				if ((Object)(object)statusCardText != (Object)null)
				{
					((TMP_Text)statusCardText).text = GetStatusCard(cfg);
				}
			}
			void UpdatePosButtons()
			{
				foreach (KeyValuePair<ScreenPosition, TextMeshProUGUI> item in posButtons)
				{
					if (!((Object)(object)item.Value == (Object)null))
					{
						bool flag = cfg.Position.Value == item.Key;
						string text = item.Key switch
						{
							ScreenPosition.BottomLeft => "Bottom-Left (Default)", 
							ScreenPosition.TopLeft => "Top-Left", 
							ScreenPosition.BottomRight => "Bottom-Right", 
							ScreenPosition.TopRight => "Top-Right", 
							_ => item.Key.ToString(), 
						};
						((TMP_Text)item.Value).text = (flag ? ("<color=#00E5FF><b>[ACTIVE]  " + text + "</b></color>") : ("<color=#94A3B8>[      ]  " + text + "</color>"));
					}
				}
				RefreshStatus();
			}
			void UpdateThemeButtons()
			{
				foreach (KeyValuePair<AccentColorPreset, TextMeshProUGUI> item2 in themeButtons)
				{
					if (!((Object)(object)item2.Value == (Object)null))
					{
						bool flag = cfg.AccentPreset.Value == item2.Key;
						string text = item2.Key switch
						{
							AccentColorPreset.Cyan => "Neon Cyan (Default)", 
							AccentColorPreset.Violet => "Neon Violet", 
							AccentColorPreset.Emerald => "Emerald Green", 
							AccentColorPreset.Gold => "Amber Gold", 
							AccentColorPreset.Ruby => "Ruby Crimson", 
							_ => item2.Key.ToString(), 
						};
						string text2 = item2.Key switch
						{
							AccentColorPreset.Cyan => "#00E5FF", 
							AccentColorPreset.Violet => "#A855F7", 
							AccentColorPreset.Emerald => "#10B981", 
							AccentColorPreset.Gold => "#F59E0B", 
							AccentColorPreset.Ruby => "#F43F5E", 
							_ => "#FFFFFF", 
						};
						((TMP_Text)item2.Value).text = (flag ? ("<color=" + text2 + "><b>[ACTIVE]  Theme: " + text + "</b></color>") : ("<color=#94A3B8>[      ]  Theme: " + text + "</color>"));
					}
				}
				RefreshStatus();
			}
		}

		private static string GetStatusCard(ModConfig cfg)
		{
			//IL_0001: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			string text = UIHelpers.ColorToHex(cfg.GetAccentColor());
			string arg = (cfg.EnableHUD.Value ? "<color=#10B981>ENABLED</color>" : "<color=#EF4444>DISABLED</color>");
			string text2 = cfg.Position.Value.ToString().ToUpper();
			string text3 = cfg.AccentPreset.Value.ToString().ToUpper();
			return "<color=#64748B>====================================================</color>\n" + $"HUD: {arg}  |  Toggle Key: <b>[{cfg.ToggleKey.Value}]</b>  |  Tab Overlay: <b>[{cfg.TabOverlayKey.Value}]</b>\n" + $"Position: <color={text}><b>{text2}</b></color> (X:{cfg.OffsetX.Value:F0}, Y:{cfg.OffsetY.Value:F0})  |  Theme: <color={text}><b>{text3}</b></color>\n" + "<color=#64748B>====================================================</color>";
		}

		private static void AddHeader(string text, int size, Color color, GameObject parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = default(TextMeshProUGUI);
			MenuHandler.CreateText(text, parent, ref val, size, true, (Color?)color, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)(TextAlignmentOptions)514);
		}

		private static void AddSubtitle(string text, GameObject parent)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = default(TextMeshProUGUI);
			MenuHandler.CreateText(text, parent, ref val, 20, false, (Color?)new Color(0.6f, 0.65f, 0.72f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)(TextAlignmentOptions)514);
		}

		private static void AddSpacer(GameObject parent)
		{
			TextMeshProUGUI val = default(TextMeshProUGUI);
			MenuHandler.CreateText(" ", parent, ref val, 12, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}

		private static void AddSectionTitle(string text, GameObject parent)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = default(TextMeshProUGUI);
			MenuHandler.CreateText("--- " + text + " ---", parent, ref val, 24, true, (Color?)new Color(0.9f, 0.95f, 1f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)(TextAlignmentOptions)513);
		}

		private static void AddToggle(string text, bool value, GameObject parent, Action<bool> onChange)
		{
			MenuHandler.CreateToggle(value, text, parent, (UnityAction<bool>)onChange.Invoke, 22, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}

		private static void AddSlider(float min, float max, float current, bool whole, GameObject parent, Action<float> onChange)
		{
			Slider val = default(Slider);
			MenuHandler.CreateSlider("", parent, 20, min, max, current, (UnityAction<float>)onChange.Invoke, ref val, whole, (Color?)null, (Direction)0, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}

		private static GameObject AddButton(string text, GameObject parent, Action onClick)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			return MenuHandler.CreateButton(text, parent, new UnityAction(onClick.Invoke), 22, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}
	}
	public class ModernTabOverlay : MonoBehaviour
	{
		private class PlayerCardUI
		{
			public GameObject Root;

			public RectTransform Rect;

			public Image Background;

			public Image AccentBar;

			public TextMeshProUGUI HeaderText;

			public TextMeshProUGUI StatsText;
		}

		private static ModernTabOverlay _instance;

		private GameObject _overlayRoot;

		private RectTransform _rootRect;

		private Image _bgImage;

		private TextMeshProUGUI _titleText;

		private TextMeshProUGUI _subtitleText;

		private GameObject _cardsContainer;

		private HorizontalLayoutGroup _horizontalLayout;

		private readonly List<PlayerCardUI> _playerCards = new List<PlayerCardUI>();

		private float _refreshTimer;

		public static ModernTabOverlay Instance => _instance;

		public bool IsOpen { get; private set; }

		private void Awake()
		{
			_instance = this;
			BuildUI();
			ModConfig.OnConfigChanged += OnConfigChanged;
		}

		private void OnDestroy()
		{
			ModConfig.OnConfigChanged -= OnConfigChanged;
			if ((Object)(object)_overlayRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_overlayRoot);
			}
		}

		private void BuildUI()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_007a: 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_009a: 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_00df: 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_0126: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Expected O, but got Unknown
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			Canvas val = ModernHudView.Instance?.Canvas;
			if (!((Object)(object)val == (Object)null))
			{
				_overlayRoot = new GameObject("ModernTabOverlay_Root", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				_overlayRoot.transform.SetParent(((Component)val).transform, false);
				_rootRect = _overlayRoot.GetComponent<RectTransform>();
				_rootRect.anchorMin = Vector2.zero;
				_rootRect.anchorMax = Vector2.one;
				_rootRect.offsetMin = Vector2.zero;
				_rootRect.offsetMax = Vector2.zero;
				_bgImage = _overlayRoot.GetComponent<Image>();
				((Graphic)_bgImage).color = new Color(0.02f, 0.03f, 0.05f, 0.85f);
				((Graphic)_bgImage).raycastTarget = false;
				TMP_FontAsset defaultTMPFont = UIHelpers.GetDefaultTMPFont();
				GameObject val2 = new GameObject("TabTitle", new Type[2]
				{
					typeof(RectTransform),
					typeof(TextMeshProUGUI)
				});
				val2.transform.SetParent(_overlayRoot.transform, false);
				RectTransform component = val2.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0f, 1f);
				component.anchorMax = new Vector2(1f, 1f);
				component.pivot = new Vector2(0.5f, 1f);
				component.anchoredPosition = new Vector2(0f, -25f);
				component.sizeDelta = new Vector2(0f, 36f);
				_titleText = val2.GetComponent<TextMeshProUGUI>();
				if ((Object)(object)defaultTMPFont != (Object)null)
				{
					((TMP_Text)_titleText).font = defaultTMPFont;
				}
				((TMP_Text)_titleText).fontSize = 26f;
				((TMP_Text)_titleText).alignment = (TextAlignmentOptions)514;
				((TMP_Text)_titleText).richText = true;
				((Graphic)_titleText).raycastTarget = false;
				GameObject val3 = new GameObject("TabSubtitle", new Type[2]
				{
					typeof(RectTransform),
					typeof(TextMeshProUGUI)
				});
				val3.transform.SetParent(_overlayRoot.transform, false);
				RectTransform component2 = val3.GetComponent<RectTransform>();
				component2.anchorMin = new Vector2(0f, 1f);
				component2.anchorMax = new Vector2(1f, 1f);
				component2.pivot = new Vector2(0.5f, 1f);
				component2.anchoredPosition = new Vector2(0f, -65f);
				component2.sizeDelta = new Vector2(0f, 22f);
				_subtitleText = val3.GetComponent<TextMeshProUGUI>();
				if ((Object)(object)defaultTMPFont != (Object)null)
				{
					((TMP_Text)_subtitleText).font = defaultTMPFont;
				}
				((TMP_Text)_subtitleText).fontSize = 13f;
				((Graphic)_subtitleText).color = new Color(0.6f, 0.65f, 0.72f);
				((TMP_Text)_subtitleText).alignment = (TextAlignmentOptions)514;
				((TMP_Text)_subtitleText).richText = true;
				((Graphic)_subtitleText).raycastTarget = false;
				_cardsContainer = new GameObject("CardsContainer", new Type[2]
				{
					typeof(RectTransform),
					typeof(HorizontalLayoutGroup)
				});
				_cardsContainer.transform.SetParent(_overlayRoot.transform, false);
				RectTransform component3 = _cardsContainer.GetComponent<RectTransform>();
				component3.anchorMin = new Vector2(0.5f, 0.5f);
				component3.anchorMax = new Vector2(0.5f, 0.5f);
				component3.pivot = new Vector2(0.5f, 0.5f);
				component3.anchoredPosition = new Vector2(0f, -20f);
				component3.sizeDelta = new Vector2(1800f, 700f);
				_horizontalLayout = _cardsContainer.GetComponent<HorizontalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)_horizontalLayout).spacing = 16f;
				((LayoutGroup)_horizontalLayout).childAlignment = (TextAnchor)4;
				((HorizontalOrVerticalLayoutGroup)_horizontalLayout).childControlWidth = false;
				((HorizontalOrVerticalLayoutGroup)_horizontalLayout).childControlHeight = false;
				((HorizontalOrVerticalLayoutGroup)_horizontalLayout).childForceExpandWidth = false;
				((HorizontalOrVerticalLayoutGroup)_horizontalLayout).childForceExpandHeight = false;
				ApplyConfiguration();
				SetOpen(open: false);
			}
		}

		private PlayerCardUI CreatePlayerCard(int index)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0065: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			TMP_FontAsset defaultTMPFont = UIHelpers.GetDefaultTMPFont();
			GameObject val = new GameObject($"PlayerCard_{index}", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(_cardsContainer.transform, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(290f, 620f);
			Image component2 = val.GetComponent<Image>();
			component2.sprite = UIHelpers.GetRoundedSprite();
			component2.type = (Type)1;
			((Graphic)component2).color = new Color(0.04f, 0.06f, 0.09f, 0.94f);
			((Graphic)component2).raycastTarget = false;
			GameObject val2 = new GameObject("CardAccent", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val2.transform.SetParent(val.transform, false);
			RectTransform component3 = val2.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 1f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.pivot = new Vector2(0.5f, 1f);
			component3.anchoredPosition = new Vector2(0f, 0f);
			component3.sizeDelta = new Vector2(-12f, 3f);
			Image component4 = val2.GetComponent<Image>();
			((Graphic)component4).raycastTarget = false;
			GameObject val3 = new GameObject("CardHeader", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val3.transform.SetParent(val.transform, false);
			RectTransform component5 = val3.GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(0f, 1f);
			component5.anchorMax = new Vector2(1f, 1f);
			component5.pivot = new Vector2(0f, 1f);
			component5.anchoredPosition = new Vector2(14f, -10f);
			component5.sizeDelta = new Vector2(-28f, 42f);
			TextMeshProUGUI component6 = val3.GetComponent<TextMeshProUGUI>();
			if ((Object)(object)defaultTMPFont != (Object)null)
			{
				((TMP_Text)component6).font = defaultTMPFont;
			}
			((TMP_Text)component6).fontSize = 16f;
			((TMP_Text)component6).richText = true;
			((Graphic)component6).raycastTarget = false;
			GameObject val4 = new GameObject("CardStats", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val4.transform.SetParent(val.transform, false);
			RectTransform component7 = val4.GetComponent<RectTransform>();
			component7.anchorMin = Vector2.zero;
			component7.anchorMax = Vector2.one;
			component7.offsetMin = new Vector2(14f, 12f);
			component7.offsetMax = new Vector2(-14f, -56f);
			TextMeshProUGUI component8 = val4.GetComponent<TextMeshProUGUI>();
			if ((Object)(object)defaultTMPFont != (Object)null)
			{
				((TMP_Text)component8).font = defaultTMPFont;
			}
			((TMP_Text)component8).fontSize = 13.5f;
			((TMP_Text)component8).richText = true;
			((TMP_Text)component8).alignment = (TextAlignmentOptions)257;
			((Graphic)component8).raycastTarget = false;
			PlayerCardUI playerCardUI = new PlayerCardUI
			{
				Root = val,
				Rect = component,
				Background = component2,
				AccentBar = component4,
				HeaderText = component6,
				StatsText = component8
			};
			_playerCards.Add(playerCardUI);
			return playerCardUI;
		}

		public void ApplyConfiguration()
		{
			//IL_000b: 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)
			ModConfig instance = ModConfig.Instance;
			if (instance != null)
			{
				string text = UIHelpers.ColorToHex(instance.GetAccentColor());
				if ((Object)(object)_titleText != (Object)null)
				{
					((TMP_Text)_titleText).text = "<color=" + text + "><b>PLAYERS MATCH SCOREBOARD</b></color>";
				}
				if ((Object)(object)_subtitleText != (Object)null)
				{
					((TMP_Text)_subtitleText).text = $"Press <b>[{instance.TabOverlayKey.Value}]</b> or <b>[ESC]</b> to close  |  Live match comparison";
				}
			}
		}

		private void OnConfigChanged()
		{
			ApplyConfiguration();
		}

		public void Toggle()
		{
			SetOpen(!IsOpen);
		}

		public void SetOpen(bool open)
		{
			IsOpen = open;
			if ((Object)(object)_overlayRoot != (Object)null)
			{
				_overlayRoot.SetActive(open);
			}
			if (open)
			{
				Refresh();
			}
		}

		private void Update()
		{
			//IL_005c: 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)
			ModConfig instance = ModConfig.Instance;
			if (instance == null || !instance.EnableTabOverlay.Value)
			{
				if (IsOpen)
				{
					SetOpen(open: false);
				}
				return;
			}
			if (instance.TabOverlayHoldMode.Value)
			{
				bool key = Input.GetKey(instance.TabOverlayKey.Value);
				if (key != IsOpen)
				{
					SetOpen(key);
				}
			}
			else if (Input.GetKeyDown(instance.TabOverlayKey.Value))
			{
				Toggle();
			}
			if (IsOpen && Input.GetKeyDown((KeyCode)27))
			{
				SetOpen(open: false);
			}
			else if (IsOpen)
			{
				_refreshTimer += Time.unscaledDeltaTime;
				if (_refreshTimer >= 0.15f)
				{
					_refreshTimer = 0f;
					Refresh();
				}
			}
		}

		public void Refresh()
		{
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: 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)
			ModConfig instance = ModConfig.Instance;
			if (instance == null || (Object)(object)_cardsContainer == (Object)null)
			{
				return;
			}
			List<Player> list = new List<Player>();
			if ((Object)(object)PlayerManager.instance != (Object)null && PlayerManager.instance.players != null)
			{
				foreach (Player player in PlayerManager.instance.players)
				{
					if ((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null)
					{
						list.Add(player);
					}
				}
			}
			if (list.Count == 0)
			{
				foreach (PlayerCardUI playerCard in _playerCards)
				{
					playerCard.Root.SetActive(false);
				}
				return;
			}
			Player localPlayer = ModernStatsHUDPlugin.GetLocalPlayer();
			string text = UIHelpers.ColorToHex(instance.GetAccentColor());
			int count = list.Count;
			float num = count switch
			{
				1 => 340f, 
				2 => 320f, 
				3 => 300f, 
				4 => 275f, 
				_ => Mathf.Clamp((1700f - (float)count * 16f) / (float)count, 200f, 260f), 
			};
			float num2 = 620f;
			Color color = default(Color);
			for (int i = 0; i < count; i++)
			{
				Player val = list[i];
				PlayerCardUI playerCardUI = ((i < _playerCards.Count) ? _playerCards[i] : CreatePlayerCard(i));
				playerCardUI.Root.SetActive(true);
				playerCardUI.Rect.sizeDelta = new Vector2(num, num2);
				((Color)(ref color))..ctor(0.22f, 0.74f, 0.97f);
				try
				{
					PlayerSkin playerSkinColors = PlayerSkinBank.GetPlayerSkinColors(val.playerID);
					if ((Object)(object)playerSkinColors != (Object)null && playerSkinColors.color.a > 0.1f)
					{
						color = playerSkinColors.color;
					}
				}
				catch
				{
				}
				string text2 = UIHelpers.ColorToHex(color);
				((Graphic)playerCardUI.AccentBar).color = color;
				string text3 = $"PLAYER {val.playerID + 1}";
				try
				{
					if ((Object)(object)val.data.view != (Object)null && val.data.view.Owner != null && !string.IsNullOrEmpty(val.data.view.Owner.NickName))
					{
						text3 = val.data.view.Owner.NickName;
					}
				}
				catch
				{
				}
				string text4 = (((Object)(object)localPlayer != (Object)null && val.playerID == localPlayer.playerID) ? " <color=#38BDF8>(YOU)</color>" : "");
				int num3 = ((val.data.currentCards != null) ? val.data.currentCards.Count : 0);
				((TMP_Text)playerCardUI.HeaderText).text = $"<b><color={text2}>[P{val.playerID + 1}]</color> {text3}{text4}</b>\n<size=80%><color=#94A3B8>Cards: {num3}</color></size>";
				List<StatEntry> list2 = PlayerStatsReader.ReadAllStats(val);
				StringBuilder stringBuilder = new StringBuilder();
				bool value = instance.ShowModdedStats.Value;
				StatCategory? statCategory = null;
				foreach (StatEntry item in list2)
				{
					if (item.IsModded && !value)
					{
						continue;
					}
					if (statCategory != item.Category)
					{
						statCategory = item.Category;
						string text5 = item.Category switch
						{
							StatCategory.Vitality => "VITALITY", 
							StatCategory.Weapon => "WEAPON", 
							StatCategory.Mobility => "MOBILITY", 
							StatCategory.Modded => "MODDED", 
							_ => item.Category.ToString().ToUpper(), 
						};
						if (stringBuilder.Length > 0)
						{
							stringBuilder.AppendLine();
						}
						stringBuilder.AppendLine("<color=" + text + "><b><size=85%>-- " + text5 + " --</size></b></color>");
					}
					string text6 = item.Category switch
					{
						StatCategory.Vitality => "#38BDF8", 
						StatCategory.Weapon => "#F59E0B", 
						StatCategory.Mobility => "#10B981", 
						StatCategory.Modded => "#C084FC", 
						_ => "#94A3B8", 
					};
					stringBuilder.AppendLine("<color=" + text6 + "><b>" + item.Label + "</b></color><pos=54%><color=#F8FAFC><b>" + item.ValueString + "</b></color></pos>");
				}
				if (stringBuilder.Length == 0)
				{
					stringBuilder.AppendLine("<color=#64748B><i>No active stats</i></color>");
				}
				((TMP_Text)playerCardUI.StatsText).text = stringBuilder.ToString();
			}
			for (int j = count; j < _playerCards.Count; j++)
			{
				_playerCards[j].Root.SetActive(false);
			}
		}
	}
	public static class UIHelpers
	{
		private static Sprite _roundedSprite;

		private static TMP_FontAsset _cachedFont;

		public static Sprite GetRoundedSprite()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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)
			//IL_00e3: 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)
			if ((Object)(object)_roundedSprite != (Object)null)
			{
				return _roundedSprite;
			}
			int num = 32;
			int num2 = 8;
			int num3 = 8;
			Texture2D val = new Texture2D(num, num, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Color[] array = (Color[])(object)new Color[num * num];
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num4 = 1f;
					float num5 = ((j < num2) ? (num2 - j) : ((j >= num - num2) ? (j - (num - num2 - 1)) : 0));
					float num6 = ((i < num2) ? (num2 - i) : ((i >= num - num2) ? (i - (num - num2 - 1)) : 0));
					if (num5 > 0f && num6 > 0f)
					{
						float num7 = Mathf.Sqrt(num5 * num5 + num6 * num6);
						num4 = Mathf.Clamp01((float)num2 - num7 + 0.5f);
					}
					array[i * num + j] = new Color(1f, 1f, 1f, num4);
				}
			}
			val.SetPixels(array);
			val.Apply(false, true);
			_roundedSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4((float)num3, (float)num3, (float)num3, (float)num3));
			return _roundedSprite;
		}

		public static TMP_FontAsset GetDefaultTMPFont()
		{
			if ((Object)(object)_cachedFont != (Object)null)
			{
				return _cachedFont;
			}
			try
			{
				if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null)
				{
					_cachedFont = TMP_Settings.defaultFontAsset;
					return _cachedFont;
				}
			}
			catch
			{
			}
			try
			{
				TextMeshProUGUI val = Object.FindObjectOfType<TextMeshProUGUI>();
				if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null)
				{
					_cachedFont = ((TMP_Text)val).font;
					return _cachedFont;
				}
			}
			catch
			{
			}
			try
			{
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				if (array != null && array.Length != 0)
				{
					TMP_FontAsset[] array2 = array;
					foreach (TMP_FontAsset val2 in array2)
					{
						if ((Object)(object)val2 != (Object)null && ((Object)val2).name != null && ((Object)val2).name.IndexOf("Liberation", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							_cachedFont = val2;
							return _cachedFont;
						}
					}
					_cachedFont = array[0];
					return _cachedFont;
				}
			}
			catch
			{
			}
			return null;
		}

		public static string ColorToHex(Color color)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Color32 val = Color32.op_Implicit(color);
			return $"#{val.r:X2}{val.g:X2}{val.b:X2}";
		}
	}
}
namespace ModernStatsHUD.Stats
{
	internal sealed class ComponentFieldSnapshot
	{
		private static readonly Dictionary<Type, FieldInfo[]> FieldCache = new Dictionary<Type, FieldInfo[]>();

		private readonly Component _target;

		private readonly FieldInfo[] _fields;

		private readonly object[] _values;

		private readonly bool[] _captured;

		public ComponentFieldSnapshot(Component target)
		{
			_target = target;
			if ((Object)(object)target == (Object)null)
			{
				return;
			}
			_fields = FieldsFor(((object)target).GetType());
			_values = new object[_fields.Length];
			_captured = new bool[_fields.Length];
			for (int i = 0; i < _fields.Length; i++)
			{
				try
				{
					_values[i] = _fields[i].GetValue(target);
					_captured[i] = true;
				}
				catch
				{
				}
			}
		}

		public void Restore()
		{
			if ((Object)(object)_target == (Object)null)
			{
				return;
			}
			for (int i = 0; i < _fields.Length; i++)
			{
				if (_captured[i])
				{
					try
					{
						_fields[i].SetValue(_target, _values[i]);
					}
					catch
					{
					}
				}
			}
		}

		private static FieldInfo[] FieldsFor(Type type)
		{
			if (FieldCache.TryGetValue(type, out var value))
			{
				return value;
			}
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
			List<FieldInfo> list = new List<FieldInfo>();
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				if (!fieldInfo.IsInitOnly && !fieldInfo.IsLiteral)
				{
					list.Add(fieldInfo);
				}
			}
			FieldInfo[] array2 = list.ToArray();
			FieldCache[type] = array2;
			return array2;
		}
	}
	internal sealed class PlayerStatRawBackup
	{
		private ComponentFieldSnapshot _gun;

		private ComponentFieldSnapshot _ammo;

		private ComponentFieldSnapshot _block;

		private float _health;

		private float _maxHealth;

		private int _jumps;

		private float _movementSpeed;

		private float _jump;

		private float _sizeMultiplier;

		private float _lifeSteal;

		private int _respawns;

		private float _regeneration;

		private GameObject _projectileToSpawn;

		public static PlayerStatRawBackup Capture(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null)
			{
				return null;
			}
			CharacterData data = player.data;
			Gun val = (((Object)(object)data.weaponHandler != (Object)null) ? data.weaponHandler.gun : null);
			GunAmmo val2 = PlayerStatsReader.ResolveAmmo(val, player);
			return new PlayerStatRawBackup
			{
				_gun = (((Object)(object)val != (Object)null) ? new ComponentFieldSnapshot((Component)(object)val) : null),
				_ammo = (((Object)(object)val2 != (Object)null) ? new ComponentFieldSnapshot((Component)(object)val2) : null),
				_block = (((Object)(object)data.block != (Object)null) ? new ComponentFieldSnapshot((Component)(object)data.block) : null),
				_health = data.health,
				_maxHealth = data.maxHealth,
				_jumps = data.jumps,
				_movementSpeed = (((Object)(object)data.stats != (Object)null) ? data.stats.movementSpeed : 1f),
				_jump = (((Object)(object)data.stats != (Object)null) ? data.stats.jump : 1f),
				_sizeMultiplier = (((Object)(object)data.stats != (Object)null) ? data.stats.sizeMultiplier : 1f),
				_lifeSteal = (((Object)(object)data.stats != (Object)null) ? data.stats.lifeSteal : 0f),
				_respawns = (((Object)(object)data.stats != (Object)null) ? data.stats.respawns : 0),
				_regeneration = (((Object)(object)data.healthHandler != (Object)null) ? data.healthHandler.regeneration : (((Object)(object)data.stats != (Object)null) ? data.stats.regen : 0f)),
				_projectileToSpawn = (((Object)(object)val != (Object)null && val.projectiles != null && val.projectiles.Length != 0 && val.projectiles[0] != null) ? val.projectiles[0].objectToSpawn : null)
			};
		}

		public void Apply(Player player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player.data == (Object)null))
			{
				CharacterData data = player.data;
				Gun val = (((Object)(object)data.weaponHandler != (Object)null) ? data.weaponHandler.gun : null);
				_gun?.Restore();
				_ammo?.Restore();
				_block?.Restore();
				if ((Object)(object)val != (Object)null && val.projectiles != null && val.projectiles.Length != 0 && val.projectiles[0] != null)
				{
					val.projectiles[0].objectToSpawn = _projectileToSpawn;
				}
				data.health = _health;
				data.maxHealth = _maxHealth;
				data.jumps = _jumps;
				if ((Object)(object)data.stats != (Object)null)
				{
					data.stats.movementSpeed = _movementSpeed;
					data.stats.jump = _jump;
					data.stats.sizeMultiplier = _sizeMultiplier;
					data.stats.lifeSteal = _lifeSteal;
					data.stats.respawns = _respawns;
				}
				if ((Object)(object)data.healthHandler != (Object)null)
				{
					data.healthHandler.regeneration = _regeneration;
				}
			}
		}
	}
	public static class CardPreviewCalculator
	{
		private static readonly FieldInfo _applyGunField = typeof(ApplyCardStats).GetField("myGunStats", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo _applyStatsField = typeof(ApplyCardStats).GetField("myPlayerStats", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo _applyBlockField = typeof(ApplyCardStats).GetField("myBlock", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly Dictionary<string, string> _customPreviewBadges = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, string> _customPreviewLabels = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		private static readonly object _syncLock = new object();

		public static string GetCustomStatLabel(string key)
		{
			lock (_syncLock)
			{
				if (_customPreviewLabels.TryGetValue(key, out var value))
				{
					return value;
				}
			}
			if (key.StartsWith("Custom_"))
			{
				return key.Substring(7);
			}
			return key;
		}

		public static Gun ResolveCardGun(CardInfo card)
		{
			if ((Object)(object)card == (Object)null)
			{
				return null;
			}
			Gun val = ((Component)card).GetComponent<Gun>() ?? ((Component)card).GetComponentInChildren<Gun>(true);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			if ((Object)(object)card.sourceCard != (Object)null && (Object)(object)card.sourceCard != (Object)(object)card)
			{
				val = ((Component)card.sourceCard).GetComponent<Gun>() ?? ((Component)card.sourceCard).GetComponentInChildren<Gun>(true);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			try
			{
				CardChoice instance = CardChoice.instance;
				if ((Object)(object)instance != (Object)null)
				{
					CardInfo sourceCard = instance.GetSourceCard(card);
					if ((Object)(object)sourceCard != (Object)null && (Object)(object)sourceCard != (Object)(object)card && (Object)(object)sourceCard != (Object)(object)card.sourceCard)
					{
						val = ((Component)sourceCard).GetComponent<Gun>() ?? ((Component)sourceCard).GetComponentInChildren<Gun>(true);
						if ((Object)(object)val != (Object)null)
						{
							return val;
						}
					}
				}
			}
			catch
			{
			}
			ApplyCardStats val2 = ((Component)card).GetComponent<ApplyCardStats>() ?? ((Component)card).GetComponentInChildren<ApplyCardStats>(true);
			if ((Object)(object)val2 != (Object)null)
			{
				if (_applyGunField != null)
				{
					try
					{
						object? value = _applyGunField.GetValue(val2);
						val = (Gun)((value is Gun) ? value : null);
					}
					catch
					{
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)val2).GetComponent<Gun>() ?? ((Component)val2).GetComponentInChildren<Gun>(true);
				}
			}
			return val;
		}

		public static CharacterStatModifiers ResolveCardStats(CardInfo card)
		{
			if ((Object)(object)card == (Object)null)
			{
				return null;
			}
			CharacterStatModifiers val = ((Component)card).GetComponent<CharacterStatModifiers>() ?? ((Component)card).GetComponentInChildren<CharacterStatModifiers>(true);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			if ((Object)(object)card.sourceCard != (Object)null && (Object)(object)card.sourceCard != (Object)(object)card)
			{
				val = ((Component)card.sourceCard).GetComponent<CharacterStatModifiers>() ?? ((Component)card.sourceCard).GetComponentInChildren<CharacterStatModifiers>(true);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			try
			{
				CardChoice instance = CardChoice.instance;
				if ((Object)(object)instance != (Object)null)
				{
					CardInfo sourceCard = instance.GetSourceCard(card);
					if ((Object)(object)sourceCard != (Object)null && (Object)(object)sourceCard != (Object)(object)card && (Object)(object)sourceCard != (Object)(object)card.sourceCard)
					{
						val = ((Component)sourceCard).GetComponent<CharacterStatModifiers>() ?? ((Component)sourceCard).GetComponentInChildren<CharacterStatModifiers>(true);
						if ((Object)(object)val != (Object)null)
						{
							return val;
						}
					}
				}
			}
			catch
			{
			}
			ApplyCardStats val2 = ((Component)card).GetComponent<ApplyCardStats>() ?? ((Component)card).GetComponentInChildren<ApplyCardStats>(true);
			if ((Object)(object)val2 != (Object)null)
			{
				if (_applyStatsField != null)
				{
					try
					{
						object? value = _applyStatsField.GetValue(val2);
						val = (CharacterStatModifiers)((value is CharacterStatModifiers) ? value : null);
					}
					catch
					{
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)val2).GetComponent<CharacterStatModifiers>() ?? ((Component)val2).GetComponentInChildren<CharacterStatModifiers>(true);
				}
			}
			return val;
		}

		public static Block ResolveCardBlock(CardInfo card)
		{
			if ((Object)(object)card == (Object)null)
			{
				return null;
			}
			Block val = ((Component)card).GetComponent<Block>() ?? ((Component)card).GetComponentInChildren<Block>(true);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			if ((Object)(object)card.sourceCard != (Object)null && (Object)(object)card.sourceCard != (Object)(object)card)
			{
				val = ((Component)card.sourceCard).GetComponent<Block>() ?? ((Component)card.sourceCard).GetComponentInChildren<Block>(true);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			try
			{
				CardChoice instance = CardChoice.instance;
				if ((Object)(object)instance != (Object)null)
				{
					CardInfo sourceCard = instance.GetSourceCard(card);
					if ((Object)(object)sourceCard != (Object)null && (Object)(object)sourceCard != (Object)(object)card && (Object)(object)sourceCard != (Object)(object)card.sourceCard)
					{
						val = ((Component)sourceCard).GetComponent<Block>() ?? ((Component)sourceCard).GetComponentInChildren<Block>(true);
						if ((Object)(object)val != (Object)null)
						{
							return val;
						}
					}
				}
			}
			catch
			{
			}
			ApplyCardStats val2 = ((Component)card).GetComponent<ApplyCardStats>() ?? ((Component)card).GetComponentInChildren<ApplyCardStats>(true);
			if ((Object)(object)val2 != (Object)null)
			{
				if (_applyBlockField != null)
				{
					try
					{
						object? value = _applyBlockField.GetValue(val2);
						val = (Block)((value is Block) ? value : null);
					}
					catch
					{
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)val2).GetComponent<Block>() ?? ((Component)val2).GetComponentInChildren<Block>(true);
				}
			}
			return val;
		}

		public static Dictionary<string, float> CalculateDeltas(Player player, CardInfo card)
		{
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || (Object)(object)card == (Object)null)
			{
				return dictionary;
			}
			lock (_syncLock)
			{
				_customPreviewBadges.Clear();
				_customPreviewLabels.Clear();
			}
			try
			{
				CharacterData data = player.data;
				Gun val = (((Object)(object)data.weaponHandler != (Object)null) ? data.weaponHandler.gun : null);
				GunAmmo val2 = PlayerStatsReader.ResolveAmmo(val, player);
				Block block = data.block;
				CharacterStatModifiers stats = data.stats;
				HealthHandler healthHandler = data.healthHandler;
				float num = ((data.maxHealth > 0f) ? data.maxHealth : 100f);
				float num2 = (((Object)(object)healthHandler != (Object)null) ? healthHandler.regeneration : (((Object)(object)stats != (Object)null) ? stats.regen : 0f));
				float num3 = (((Object)(object)block != (Object)null) ? block.Cooldown() : 4f);
				int num4 = ((!((Object)(object)block != (Object)null)) ? 1 : (1 + block.additionalBlocks));
				float num5 = (((Object)(object)stats != (Object)null) ? stats.lifeSteal : 0f);
				int num6 = (((Object)(object)stats != (Object)null) ? stats.respawns : 0);
				float num7 = PlayerStatsReader.ComputeDamage(val);
				float num8 = (((Object)(object)val != (Object)null) ? (val.attackSpeed * val.attackSpeedMultiplier) : 0.3f);
				int num9 = (((Object)(object)val2 != (Object)null) ? val2.maxAmmo : 3);
				float num10 = (((Object)(object)val2 != (Object)null) ? ((val2.reloadTime + val2.reloadTimeAdd) * val2.reloadTimeMultiplier) : 1.5f);
				int num11 = ((!((Object)(object)val != (Object)null)) ? 1 : val.numberOfProjectiles);
				int num12 = (((Object)(object)val != (Object)null) ? (val.reflects + val.smartBounce + val.randomBounces) : 0);
				int num13 = (((Object)(object)val != (Object)null) ? val.bursts : 0);
				float num14 = (((Object)(object)val != (Object)null) ? (val.projectileSpeed * val.projectielSimulatonSpeed) : 1f);
				float num15 = (((Object)(object)val != (Object)null) ? val.destroyBulletAfter : 2f);
				float num16 = (((Object)(object)val != (Object)null) ? val.knockback : 1f);
				float num17 = (((Object)(object)val != (Object)null) ? val.slow : 0f);
				float num18 = (((Object)(object)stats != (Object)null) ? stats.movementSpeed : 1f);
				float num19 = (((Object)(object)stats != (Object)null) ? stats.jump : 1f);
				int jumps = data.jumps;
				float num20 = (((Object)(object)stats != (Object)null) ? stats.sizeMultiplier : 1f);
				PlayerStatRawBackup playerStatRawBackup = PlayerStatRawBackup.Capture(player);
				Gun val3 = ResolveCardGun(card);
				CharacterStatModifiers val4 = ResolveCardStats(card);
				Block val5 = ResolveCardBlock(card);
				if ((Object)(object)val3 != (Object)null && (Object)(object)val != (Object)null)
				{
					ApplyCardStats.CopyGunStats(val3, val);
					if ((Object)(object)val2 != (Object)null)
					{
						val2.maxAmmo += val3.ammo;
						val2.maxAmmo = Mathf.Clamp(val2.maxAmmo, 1, 90);
						if (val3.reloadTime != 0f)
						{
							val2.reloadTimeMultiplier *= val3.reloadTime;
						}
						val2.reloadTimeAdd += val3.reloadTimeAdd;
					}
					if (val3.projectiles != null && val3.projectiles.Length != 0 && val.projectiles != null && val.projectiles.Length != 0)
					{
						val.projectiles[0].objectToSpawn = val3.projectiles[0].objectToSpawn;
					}
				}
				if ((Object)(object)val4 != (Object)null && (Object)(object)stats != (Object)null)
				{
					if (val4.sizeMultiplier != 0f)
					{
						stats.sizeMultiplier *= val4.sizeMultiplier;
					}
					if (val4.health != 0f)
					{
						data.maxHealth *= val4.health;
						data.health *= val4.health;
					}
					if (val4.movementSpeed != 0f)
					{
						stats.movementSpeed *= val4.movementSpeed;
					}
					if (val4.jump != 0f)
					{
						stats.jump *= val4.jump;
					}
					data.jumps += val4.numberOfJumps;
					stats.lifeSteal += val4.lifeSteal;
					stats.respawns += val4.respawns;
					if ((Object)(object)healthHandler != (Object)null)
					{
						healthHandler.regeneration += val4.regen;
					}
				}
				if ((Object)(object)val5 != (Object)null && (Object)(object)block != (Object)null)
				{
					block.additionalBlocks += val5.additionalBlocks;
					block.cdAdd += val5.cdAdd;
					if (val5.cdMultiplier != 0f)
					{
						block.cdMultiplier *= val5.cdMultiplier;
					}
					block.forceToAdd += val5.forceToAdd;
					block.forceToAddUp += val5.forceToAddUp;
				}
				float maxHealth = data.maxHealth;
				float num21 = (((Object)(object)healthHandler != (Object)null) ? healthHandler.regeneration : (((Object)(object)stats != (Object)null) ? stats.regen : 0f));
				float num22 = (((Object)(object)block != (Object)null) ? block.Cooldown() : 4f);
				int num23 = ((!((Object)(object)block != (Object)null)) ? 1 : (1 + block.additionalBlocks));
				float num24 = (((Object)(object)stats != (Object)null) ? stats.lifeSteal : 0f);
				int num25 = (((Object)(object)stats != (Object)null) ? stats.respawns : 0);
				float num26 = PlayerStatsReader.ComputeDamage(val);
				float num27 = (((Object)(object)val != (Object)null) ? (val.attackSpeed * val.attackSpeedMultiplier) : 0.3f);
				int num28 = (((Object)(object)val2 != (Object)null) ? val2.maxAmmo : 3);
				float num29 = (((Object)(object)val2 != (Object)null) ? ((val2.reloadTime + val2.reloadTimeAdd) * val2.reloadTimeMultiplier) : 1.5f);
				int num30 = ((!((Object)(object)val != (Object)null)) ? 1 : val.numberOfProjectiles);
				int num31 = (((Object)(object)val != (Object)null) ? (val.reflects + val.smartBounce + val.randomBounces) : 0);
				int num32 = (((Object)(object)val != (Object)null) ? val.bursts : 0);
				float num33 = (((Object)(object)val != (Object)null) ? (val.projectileSpeed * val.projectielSimulatonSpeed) : 1f);
				float num34 = (((Object)(object)val != (Object)null) ? val.destroyBulletAfter : 2f);
				float num35 = (((Object)(object)val != (Object)null) ? val.knockback : 1f);
				float num36 = (((Object)(object)val != (Object)null) ? val.slow : 0f);
				float num37 = (((Object)(object)stats != (Object)null) ? stats.movementSpeed : 1f);
				float num38 = (((Object)(object)stats != (Object)null) ? stats.jump : 1f);
				int jumps2 = data.jumps;
				float num39 = (((Object)(object)stats != (Object)null) ? stats.sizeMultiplier : 1f);
				playerStatRawBackup?.Apply(player);
				float value = maxHealth - num;
				if (Math.Abs(value) > 0.1f)
				{
					dictionary["Health"] = value;
				}
				float value2 = num21 - num2;
				if (Math.Abs(value2) > 0.01f)
				{
					dictionary["Regen"] = value2;
				}
				float value3 = num22 - num3;
				if (Math.Abs(value3) > 0.005f)
				{
					dictionary["BlockCD"] = value3;
				}
				int num40 = num23 - num4;
				if (num40 != 0)
				{
					dictionary["BlockCount"] = num40;
				}
				float value4 = num24 - num5;
				if (Math.Abs(value4) > 0.005f)
				{
					dictionary["LifeSteal"] = value4;
				}
				int num41 = num25 - num6;
				if