Decompiled source of MordasGearhold v1.0.0

plugins/MordasGearhold/MordasGearhold.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MordasGearhold.Core;
using MordasGearhold.Patches;
using MordasGearhold.UI;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("MordasGearhold")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9675028adf3e59aa281d6979d0f4bd3c07ec8ba5")]
[assembly: AssemblyProduct("Morda's Gearhold")]
[assembly: AssemblyTitle("MordasGearhold")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MordasGearhold
{
	[BepInPlugin("com.morda.gearhold", "Morda's Gearhold", "1.0.0")]
	[BepInIncompatibility("shudnal.ExtraSlots")]
	[BepInIncompatibility("Azumatt.AzuExtendedPlayerInventory")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.morda.gearhold";

		public const string ModName = "Morda's Gearhold";

		public const string ModVersion = "1.0.0";

		internal static ConfigEntry<int> ExtraRows;

		internal static ConfigEntry<int> TrinketSlots;

		internal static ConfigEntry<int> UtilitySlots;

		internal static ConfigEntry<KeyboardShortcut> KeySet1;

		internal static ConfigEntry<KeyboardShortcut> KeySet2;

		internal static ConfigEntry<KeyboardShortcut> KeySet3;

		internal static ConfigEntry<KeyboardShortcut> KeyNextSet;

		internal static readonly ConfigEntry<KeyboardShortcut>[] KeyQuickslots = new ConfigEntry<KeyboardShortcut>[8];

		internal static readonly ConfigEntry<KeyboardShortcut>[] KeyAmmo = new ConfigEntry<KeyboardShortcut>[3];

		internal static ConfigEntry<bool> AutoEquip;

		internal static ConfigEntry<bool> AutoShield;

		internal static ConfigEntry<bool> SharedFirstForCrafting;

		internal static ConfigEntry<bool> QuickslotsUseOnTarget;

		internal static ConfigEntry<bool> AutoEat;

		internal static ConfigEntry<bool> AutoEatEarly;

		internal static ConfigEntry<bool> AutoStoreCoins;

		internal static ConfigEntry<bool> ShowPanel;

		internal static ConfigEntry<bool> ShowQuickslotBar;

		internal static ConfigEntry<float> QuickslotBarScale;

		private Harmony _harmony;

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00b4: 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_00fc: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Expected O, but got Unknown
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ExtraRows = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Inventory", "ExtraGridRows", 3, new ConfigDescription("Rows added to the inventory grid on top of vanilla's 4 (and the rows bought from the trader). Reducing it is refused while the rows that would disappear still hold items.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>()));
			TrinketSlots = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Inventory", "TrinketSlots", 1, new ConfigDescription("How many trinket slots the panel has (1 = only the vanilla slot). An item in a slot that is switched off goes back into the inventory grid.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>()));
			UtilitySlots = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Inventory", "UtilitySlots", 1, new ConfigDescription("How many utility slots the panel has (1 = only the vanilla slot). An item in a slot that is switched off goes back into the inventory grid.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>()));
			KeySet1 = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Hotkeys", "Set1", KeyboardShortcut.Empty, "Switch to equipment set 1.");
			KeySet2 = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Hotkeys", "Set2", KeyboardShortcut.Empty, "Switch to equipment set 2.");
			KeySet3 = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Hotkeys", "Set3", KeyboardShortcut.Empty, "Switch to equipment set 3.");
			KeyNextSet = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Hotkeys", "NextSet", KeyboardShortcut.Empty, "Cycle to the next equipment set.");
			KeyCode[] array = new KeyCode[4];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			KeyCode[] array2 = (KeyCode[])(object)array;
			for (int i = 0; i < KeyQuickslots.Length; i++)
			{
				KeyboardShortcut val = (KeyboardShortcut)((i < array2.Length) ? new KeyboardShortcut(array2[i], Array.Empty<KeyCode>()) : KeyboardShortcut.Empty);
				KeyQuickslots[i] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Hotkeys", "Quickslot" + (i + 1), val, "Use the item in Gearhold quickslot " + (i + 1) + " of the active set (eat, drink, equip).");
			}
			for (int j = 0; j < KeyAmmo.Length; j++)
			{
				KeyAmmo[j] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Hotkeys", "Ammo" + (j + 1), new KeyboardShortcut((KeyCode)(49 + j), (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Select the ammo in Gearhold ammo slot " + (j + 1) + " of the active set.");
			}
			AutoEquip = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Behaviour", "AutoEquip", true, "Equip newly picked-up or crafted gear when the matching slot of the active set is empty. Never replaces equipped gear.");
			AutoShield = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Behaviour", "AutoShield", true, "Equip the active set's shield (shield cell) together with a one-handed weapon.");
			SharedFirstForCrafting = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Behaviour", "SharedFirstForCrafting", true, "Crafting and building take resources from the inventory grid before touching the Gearhold slots (e.g. quickslot food).");
			QuickslotsUseOnTarget = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Behaviour", "QuickslotsUseOnTarget", false, "Like the vanilla hotbar: a quickslot key used while looking at an item stand, mannequin, fire, pet, ... hands the item to it. Off (default): quickslot keys only eat, drink or equip and never give an item away.");
			AutoEat = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Behaviour", "AutoEat", false, "Eat food from the active set's quickslots automatically when one of your three food slots is empty.");
			AutoEatEarly = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Behaviour", "AutoEatEarly", false, "With AutoEat: also eat as soon as the game lets you eat a food again (at half its time), so no food slot runs empty.");
			AutoStoreCoins = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Behaviour", "AutoStoreCoins", true, "Move the coins you carry into the coin slot (top right of the panel) on their own. Coins there weigh nothing.");
			ShowPanel = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - UI", "ShowPanel", true, "Show the Gearhold panel in the middle of the inventory screen.");
			ShowQuickslotBar = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - UI", "ShowQuickslotBar", true, "Show the occupied quickslots of the active set with their hotkeys at the bottom centre of the screen.");
			QuickslotBarScale = ((BaseUnityPlugin)this).Config.Bind<float>("4 - UI", "QuickslotBarScale", 0.75f, new ConfigDescription("Size of the quickslot bar on the HUD (1 = size of the vanilla hotbar).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.4f, 1.2f), Array.Empty<object>()));
			ExtraRows.SettingChanged += delegate
			{
				Topology.Apply(Player.m_localPlayer);
			};
			_harmony = new Harmony("com.morda.gearhold");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Morda's Gearhold v1.0.0 loaded.");
		}

		private void Update()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			if (KeyRebinder.Tick())
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !GearholdState.IsReady(localPlayer))
			{
				return;
			}
			Equipment.LateShieldCheck(localPlayer);
			Trinkets.Tick(localPlayer);
			Coins.Tick(localPlayer);
			MordasGearhold.Patches.AutoEat.Tick(localPlayer);
			Transmog.Tick(localPlayer);
			if (InputBlocked())
			{
				return;
			}
			for (int i = 0; i < KeyAmmo.Length; i++)
			{
				if (Pressed(KeyAmmo[i].Value))
				{
					Equipment.SelectAmmo(localPlayer, i);
					return;
				}
			}
			if (Pressed(KeySet1.Value))
			{
				SetSwitcher.TrySwitch(localPlayer, 0);
				return;
			}
			if (Pressed(KeySet2.Value))
			{
				SetSwitcher.TrySwitch(localPlayer, 1);
				return;
			}
			if (Pressed(KeySet3.Value))
			{
				SetSwitcher.TrySwitch(localPlayer, 2);
				return;
			}
			if (Pressed(KeyNextSet.Value))
			{
				SetSwitcher.TrySwitch(localPlayer, (GearholdState.ActiveSet(localPlayer) + 1) % 3);
				return;
			}
			for (int j = 0; j < KeyQuickslots.Length; j++)
			{
				if (Pressed(KeyQuickslots[j].Value))
				{
					UseQuickslot(localPlayer, j);
					break;
				}
			}
		}

		internal static void UseQuickslot(Player player, int index)
		{
			ItemData val = Equipment.ItemIn(player, Topology.QuickSlot(index));
			if (val != null && !((Character)player).IsDead() && !((Character)player).InCutscene() && !((Character)player).IsTeleporting())
			{
				((Humanoid)player).UseItem((Inventory)null, val, !QuickslotsUseOnTarget.Value);
			}
		}

		internal static string KeyLabel(int quickslot)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return FormatKey(KeyQuickslots[quickslot].Value);
		}

		internal static string AmmoKeyLabel(int ammoSlot)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return FormatKey(KeyAmmo[ammoSlot].Value);
		}

		internal static string FormatKey(KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0)
			{
				return "";
			}
			string text = "";
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				text = text + KeyName(modifier) + "+";
			}
			return text + KeyName(((KeyboardShortcut)(ref shortcut)).MainKey);
		}

		private unsafe static string KeyName(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected I4, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected I4, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected I4, but got Unknown
			if ((int)key >= 48 && (int)key <= 57)
			{
				return (key - 48).ToString();
			}
			if ((int)key >= 256 && (int)key <= 265)
			{
				return "Num" + (key - 256);
			}
			switch (key - 303)
			{
			case 4:
			case 5:
				return "Alt";
			case 0:
			case 1:
				return "Shift";
			case 2:
			case 3:
				return "Ctrl";
			default:
				return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
			}
		}

		internal static bool ModifiedHotkeyHeld(KeyCode mainKey)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			foreach (ConfigEntry<KeyboardShortcut> item in AllHotkeys())
			{
				KeyboardShortcut value = item.Value;
				if (((KeyboardShortcut)(ref value)).MainKey != mainKey)
				{
					continue;
				}
				bool flag = false;
				bool flag2 = true;
				foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
				{
					flag = true;
					flag2 &= ZInput.GetKey(modifier, false);
				}
				if (flag && flag2)
				{
					return true;
				}
			}
			return false;
		}

		internal static IEnumerable<ConfigEntry<KeyboardShortcut>> AllHotkeys()
		{
			ConfigEntry<KeyboardShortcut>[] keyQuickslots = KeyQuickslots;
			for (int i = 0; i < keyQuickslots.Length; i++)
			{
				yield return keyQuickslots[i];
			}
			keyQuickslots = KeyAmmo;
			for (int i = 0; i < keyQuickslots.Length; i++)
			{
				yield return keyQuickslots[i];
			}
			yield return KeySet1;
			yield return KeySet2;
			yield return KeySet3;
			yield return KeyNextSet;
		}

		private void LateUpdate()
		{
			GearholdPanel.Tick();
			GearholdHud.Tick();
		}

		private static bool InputBlocked()
		{
			if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !Minimap.IsOpen())
			{
				return StoreGui.IsVisible();
			}
			return true;
		}

		private static bool Pressed(KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey, false))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if (!ZInput.GetKey(modifier, false))
				{
					return false;
				}
			}
			return true;
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace MordasGearhold.UI
{
	internal static class CharacterPreview
	{
		private const int TextureWidth = 512;

		private const int TextureHeight = 768;

		private const float MinDistance = 1.6f;

		private const float MaxDistance = 4.5f;

		private static Camera s_camera;

		private static RenderTexture s_texture;

		private static int s_layer = -1;

		private static float s_yaw;

		private static float s_distance = 3.4f;

		private static readonly List<Renderer> s_renderers = new List<Renderer>();

		private static readonly List<int> s_layers = new List<int>();

		private static float s_nextScan;

		internal static RawImage CreateView(Transform parent, float x, float y, float width, float height)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			EnsureTexture();
			RectTransform val = UiKit.Rect("CharacterPreview", parent);
			UiKit.Place(val, x, y, width, height);
			RawImage obj = ((Component)val).gameObject.AddComponent<RawImage>();
			obj.texture = (Texture)(object)s_texture;
			((Graphic)obj).raycastTarget = true;
			float num = 2f / 3f;
			if (width / height > num)
			{
				val.sizeDelta = new Vector2(height * num, height);
			}
			else
			{
				val.sizeDelta = new Vector2(width, width / num);
			}
			((Component)val).gameObject.AddComponent<PreviewControls>();
			return obj;
		}

		internal static void Begin()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			EnsureTexture();
			if (s_layer < 0)
			{
				s_layer = FindFreeLayer();
			}
			if ((Object)(object)s_camera == (Object)null)
			{
				GameObject val = new GameObject("MordasGearholdPreviewCamera");
				Object.DontDestroyOnLoad((Object)val);
				s_camera = val.AddComponent<Camera>();
				s_camera.clearFlags = (CameraClearFlags)2;
				s_camera.backgroundColor = new Color(0f, 0f, 0f, 0f);
				s_camera.fieldOfView = 34f;
				s_camera.nearClipPlane = 0.1f;
				s_camera.farClipPlane = 12f;
				s_camera.depth = -50f;
				s_camera.allowHDR = false;
				s_camera.targetTexture = s_texture;
				s_camera.cullingMask = 1 << s_layer;
				Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnPreCull));
				Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnPostRender));
			}
			s_nextScan = 0f;
			((Behaviour)s_camera).enabled = true;
			Tick();
		}

		internal static void End()
		{
			if ((Object)(object)s_camera != (Object)null)
			{
				((Behaviour)s_camera).enabled = false;
			}
		}

		internal static void Rotate(float degrees)
		{
			s_yaw += degrees;
		}

		internal static void Zoom(float delta)
		{
			s_distance = Mathf.Clamp(s_distance - delta * 0.4f, 1.6f, 4.5f);
		}

		internal static void Tick()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)s_camera == (Object)null || !((Behaviour)s_camera).enabled)
			{
				return;
			}
			if ((Object)(object)localPlayer == (Object)null)
			{
				End();
				return;
			}
			Transform transform = ((Component)localPlayer).transform;
			Vector3 val = transform.position + Vector3.up * 1f;
			Vector3 val2 = Quaternion.Euler(0f, s_yaw, 0f) * transform.forward;
			((Component)s_camera).transform.position = val + val2 * s_distance + Vector3.up * 0.25f;
			((Component)s_camera).transform.LookAt(val);
			if (Time.unscaledTime >= s_nextScan)
			{
				s_nextScan = Time.unscaledTime + 0.5f;
				s_renderers.Clear();
				((Component)localPlayer).GetComponentsInChildren<Renderer>(false, s_renderers);
			}
		}

		private static void OnPreCull(Camera camera)
		{
			if ((Object)(object)camera != (Object)(object)s_camera || s_layer < 0)
			{
				return;
			}
			s_layers.Clear();
			foreach (Renderer s_renderer in s_renderers)
			{
				if ((Object)(object)s_renderer == (Object)null)
				{
					s_layers.Add(-1);
					continue;
				}
				s_layers.Add(((Component)s_renderer).gameObject.layer);
				((Component)s_renderer).gameObject.layer = s_layer;
			}
		}

		private static void OnPostRender(Camera camera)
		{
			if ((Object)(object)camera != (Object)(object)s_camera)
			{
				return;
			}
			for (int i = 0; i < s_renderers.Count && i < s_layers.Count; i++)
			{
				if ((Object)(object)s_renderers[i] != (Object)null && s_layers[i] >= 0)
				{
					((Component)s_renderers[i]).gameObject.layer = s_layers[i];
				}
			}
			s_layers.Clear();
		}

		private static int FindFreeLayer()
		{
			for (int num = 31; num >= 8; num--)
			{
				if (string.IsNullOrEmpty(LayerMask.LayerToName(num)))
				{
					return num;
				}
			}
			Plugin.Log.LogWarning((object)"Gearhold preview: no free layer found, the preview may show the surroundings.");
			return 31;
		}

		private static void EnsureTexture()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if ((Object)(object)s_texture == (Object)null)
			{
				s_texture = new RenderTexture(512, 768, 24, (RenderTextureFormat)0)
				{
					name = "MordasGearholdPreview",
					antiAliasing = 2
				};
			}
		}
	}
	internal sealed class PreviewControls : MonoBehaviour, IDragHandler, IEventSystemHandler, IScrollHandler
	{
		public void OnDrag(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			CharacterPreview.Rotate(eventData.delta.x * 0.6f);
		}

		public void OnScroll(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			CharacterPreview.Zoom(eventData.scrollDelta.y);
		}
	}
	internal sealed class ClickSink : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
	{
		public void OnPointerClick(PointerEventData eventData)
		{
		}
	}
	internal static class CharacterSheet
	{
		private const string Head = "#ffc96e";

		private const string Muted = "#9a907e";

		private const string Good = "#8fd16a";

		private const string Bad = "#e06a5a";

		private static readonly (DamageType type, string name)[] s_damageTypes = new(DamageType, string)[8]
		{
			((DamageType)1, "Blunt"),
			((DamageType)2, "Slash"),
			((DamageType)4, "Pierce"),
			((DamageType)32, "Fire"),
			((DamageType)64, "Frost"),
			((DamageType)128, "Lightning"),
			((DamageType)256, "Poison"),
			((DamageType)512, "Spirit")
		};

		private static readonly StringBuilder s_sb = new StringBuilder(1024);

		private static readonly string[] s_damageNames = new string[10] { "Blunt", "Slash", "Pierce", "Chop", "Pickaxe", "Fire", "Frost", "Lightning", "Poison", "Spirit" };

		private static readonly Regex s_tags = new Regex("<.*?>");

		internal static string Build(Player player)
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = s_sb.Clear();
			Inventory inventory = ((Humanoid)player).GetInventory();
			Row(stringBuilder, "Armor", ((Character)player).GetBodyArmor().ToString("0"));
			Row(stringBuilder, "Weight", inventory.GetTotalWeight().ToString("0") + " / " + player.GetMaxCarryWeight().ToString("0"));
			Percent(stringBuilder, "Movement", ((Character)player).GetEquipmentMovementModifier(), higherIsBetter: true);
			Percent(stringBuilder, "Heat resist.", ((Character)player).GetEquipmentHeatResistanceModifier(), higherIsBetter: true);
			Percent(stringBuilder, "Run stamina", ((Character)player).GetEquipmentRunStaminaModifier(), higherIsBetter: false);
			Percent(stringBuilder, "Attack stamina", ((Character)player).GetEquipmentAttackStaminaModifier(), higherIsBetter: false);
			Percent(stringBuilder, "Block stamina", ((Character)player).GetEquipmentBlockStaminaModifier(), higherIsBetter: false);
			Percent(stringBuilder, "Dodge stamina", ((Character)player).GetEquipmentDodgeStaminaModifier(), higherIsBetter: false);
			Percent(stringBuilder, "Jump stamina", ((Character)player).GetEquipmentJumpStaminaModifier(), higherIsBetter: false);
			Percent(stringBuilder, "Swim stamina", ((Character)player).GetEquipmentSwimStaminaModifier(), higherIsBetter: false);
			Percent(stringBuilder, "Sneak stamina", ((Character)player).GetEquipmentSneakStaminaModifier(), higherIsBetter: false);
			AppendWeapon(stringBuilder, player);
			AppendShield(stringBuilder, player);
			AppendTrinkets(stringBuilder, player);
			AppendUtilities(stringBuilder, player);
			DamageModifiers damageModifiers = ((Character)player).GetDamageModifiers((WeakSpot)null);
			bool flag = false;
			(DamageType, string)[] array = s_damageTypes;
			for (int i = 0; i < array.Length; i++)
			{
				(DamageType, string) tuple = array[i];
				DamageType item = tuple.Item1;
				string item2 = tuple.Item2;
				DamageModifier modifier = ((DamageModifiers)(ref damageModifiers)).GetModifier(item);
				if ((int)modifier != 0)
				{
					if (!flag)
					{
						stringBuilder.Append("\n<color=").Append("#ffc96e").Append(">RESISTANCES</color>\n");
						flag = true;
					}
					Row(stringBuilder, item2, Describe(modifier));
				}
			}
			return stringBuilder.ToString();
		}

		private static void AppendWeapon(StringBuilder sb, Player player)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			ItemData val = Access.LeftItem.Invoke((Humanoid)(object)player);
			ItemData val2 = Access.RightItem.Invoke((Humanoid)(object)player);
			if (val2 == null && val != null && (int)val.m_shared.m_itemType != 5 && (int)val.m_shared.m_itemType != 15)
			{
				val2 = val;
			}
			if (val2 == null)
			{
				return;
			}
			Header(sb, "WEAPON");
			DamageTypes damage = val2.GetDamage();
			float[] array = new float[10] { damage.m_blunt, damage.m_slash, damage.m_pierce, damage.m_chop, damage.m_pickaxe, damage.m_fire, damage.m_frost, damage.m_lightning, damage.m_poison, damage.m_spirit };
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] > 0f)
				{
					Row(sb, s_damageNames[i], array[i].ToString("0"));
				}
			}
			Attack attack = val2.m_shared.m_attack;
			if (attack != null && attack.m_attackStamina > 0f)
			{
				Row(sb, "Stamina use", attack.m_attackStamina.ToString("0"));
			}
			if (attack != null && attack.m_attackEitr > 0f)
			{
				Row(sb, "Eitr use", attack.m_attackEitr.ToString("0"));
			}
			AppendBlock(sb, val2);
			if (val2.m_shared.m_attackForce > 0f)
			{
				Row(sb, "Knockback", val2.m_shared.m_attackForce.ToString("0"));
			}
			if (val2.m_shared.m_backstabBonus > 1f)
			{
				Row(sb, "Backstab", val2.m_shared.m_backstabBonus.ToString("0.#") + "x");
			}
			if (val2.m_shared.m_useDurability)
			{
				Row(sb, "Durability", val2.m_durability.ToString("0") + " / " + val2.GetMaxDurability().ToString("0"));
			}
		}

		private static void AppendShield(StringBuilder sb, Player player)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			ItemData val = Access.LeftItem.Invoke((Humanoid)(object)player);
			if (val != null && (int)val.m_shared.m_itemType == 5)
			{
				Header(sb, "SHIELD");
				AppendBlock(sb, val);
			}
		}

		private static void AppendTrinkets(StringBuilder sb, Player player)
		{
			List<ItemData> list = new List<ItemData>(3);
			ItemData val = Access.TrinketItem.Invoke((Humanoid)(object)player);
			if (val != null)
			{
				list.Add(val);
			}
			list.AddRange(Trinkets.ActiveExtras(player).FindAll((ItemData i) => (int)i.m_shared.m_itemType == 24));
			if (list.Count == 0)
			{
				return;
			}
			Header(sb, "TRINKETS");
			float num = 0f;
			foreach (ItemData item in list)
			{
				num += item.m_shared.m_maxAdrenaline;
			}
			if (num != 0f)
			{
				Row(sb, "Max adrenaline", "<color=#8fd16a>" + num.ToString("+0;-0") + "</color>");
			}
			foreach (ItemData item2 in list)
			{
				Effect(sb, item2.m_shared.m_fullAdrenalineSE, "at full adrenaline");
				Effect(sb, item2.m_shared.m_equipStatusEffect, "while worn");
			}
		}

		private static void AppendUtilities(StringBuilder sb, Player player)
		{
			List<ItemData> list = new List<ItemData>(3);
			ItemData val = Access.UtilityItem.Invoke((Humanoid)(object)player);
			if (val != null)
			{
				list.Add(val);
			}
			list.AddRange(Trinkets.ActiveExtras(player).FindAll((ItemData i) => (int)i.m_shared.m_itemType == 18));
			if (!list.Exists((ItemData i) => (Object)(object)i.m_shared.m_equipStatusEffect != (Object)null))
			{
				return;
			}
			Header(sb, "UTILITY");
			foreach (ItemData item in list)
			{
				Effect(sb, item.m_shared.m_equipStatusEffect, "while worn");
			}
		}

		private static void Effect(StringBuilder sb, StatusEffect effect, string when)
		{
			if ((Object)(object)effect == (Object)null)
			{
				return;
			}
			sb.Append("<color=").Append("#ffc96e").Append('>')
				.Append(Clip(Localization.instance.Localize(effect.m_name), 22))
				.Append("</color> <color=")
				.Append("#9a907e")
				.Append('>')
				.Append(when)
				.Append("</color>\n");
			string text = Localization.instance.Localize(effect.GetTooltipString() ?? "");
			int num = 0;
			string[] array = text.Split(new char[1] { '\n' });
			foreach (string input in array)
			{
				string text2 = s_tags.Replace(input, "").Trim();
				if (text2.Length != 0)
				{
					if (++num > 4)
					{
						break;
					}
					sb.Append("  ").Append(Clip(text2, 34)).Append('\n');
				}
			}
		}

		private static string Clip(string text, int max)
		{
			if (text.Length > max)
			{
				return text.Substring(0, max - 1) + "…";
			}
			return text;
		}

		private static void Header(StringBuilder sb, string title)
		{
			sb.Append("\n<color=").Append("#ffc96e").Append('>')
				.Append(title)
				.Append("</color>\n");
		}

		private static void AppendBlock(StringBuilder sb, ItemData item)
		{
			float baseBlockPower = item.GetBaseBlockPower(item.m_quality);
			if (baseBlockPower > 0f)
			{
				Row(sb, "Block armor", baseBlockPower.ToString("0"));
				Row(sb, "Block force", item.GetDeflectionForce(item.m_quality).ToString("0"));
			}
			if (item.m_shared.m_timedBlockBonus > 1f)
			{
				Row(sb, "Parry bonus", item.m_shared.m_timedBlockBonus.ToString("0.#") + "x");
			}
		}

		private static void Row(StringBuilder sb, string label, string value)
		{
			sb.Append(label).Append("<pos=58%>").Append(value)
				.Append('\n');
		}

		private static void Percent(StringBuilder sb, string label, float value, bool higherIsBetter)
		{
			if (!(value > -0.0005f) || !(value < 0.0005f))
			{
				bool flag = (higherIsBetter ? (value > 0f) : (value < 0f));
				Row(sb, label, "<color=" + (flag ? "#8fd16a" : "#e06a5a") + ">" + (value * 100f).ToString("+0;-0") + "%</color>");
			}
		}

		private static string Describe(DamageModifier modifier)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected I4, but got Unknown
			return (modifier - 1) switch
			{
				2 => "<color=#8fd16a>Immune</color>", 
				3 => "<color=#8fd16a>Ignored</color>", 
				4 => "<color=#8fd16a>Very resistant</color>", 
				0 => "<color=#8fd16a>Resistant</color>", 
				6 => "<color=#8fd16a>Slightly resistant</color>", 
				7 => "<color=#e06a5a>Slightly weak</color>", 
				1 => "<color=#e06a5a>Weak</color>", 
				5 => "<color=#e06a5a>Very weak</color>", 
				_ => "<color=#9a907e>Normal</color>", 
			};
		}
	}
	internal static class GearholdHud
	{
		internal static void Tick()
		{
			Hud instance = Hud.instance;
			if ((Object)(object)instance != (Object)null)
			{
				QuickslotBar.Tick(instance, Player.m_localPlayer);
			}
		}
	}
	internal static class GearholdPanel
	{
		private sealed class Slot
		{
			public GearSlot Kind;

			public InventoryElement Element;

			public TMP_Text Binding;

			public TMP_Text KeyButton;

			public TMP_Text Caption;

			public ItemData Item;

			public string Label;
		}

		private const float DesignWidth = 460f;

		private const float DesignHeight = 930f;

		private const float SlotTop = 178f;

		private const float SlotStep = 88f;

		private const float CompactHeight = 140f;

		private const float SlotSize = 64f;

		private const float QuickSize = 46f;

		private static InventoryGui s_gui;

		private static RectTransform s_root;

		private static RectTransform s_body;

		private static readonly List<Slot> s_slots = new List<Slot>();

		private static readonly Button[] s_tabs = (Button[])(object)new Button[3];

		private static TMP_Text s_stats;

		private static TMP_Text s_footer;

		private static bool s_failed;

		private static readonly Vector3[] s_corners = (Vector3[])(object)new Vector3[4];

		private static float s_nextSheet;

		private static Sprite s_coinIcon;

		internal static void Tick()
		{
			SkinMenu.Tick();
			InventoryGui instance = InventoryGui.instance;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)instance == (Object)null || s_failed)
			{
				return;
			}
			if ((Object)(object)s_gui != (Object)(object)instance || (Object)(object)s_root == (Object)null)
			{
				try
				{
					Build(instance);
				}
				catch (Exception ex)
				{
					s_failed = true;
					if ((Object)(object)s_root != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)s_root).gameObject);
						s_root = null;
					}
					Plugin.Log.LogError((object)("Gearhold panel could not be built, panel disabled: " + ex));
					return;
				}
			}
			bool flag = Plugin.ShowPanel.Value && InventoryGui.IsVisible() && (Object)(object)localPlayer != (Object)null && GearholdState.IsReady(localPlayer);
			if (((Component)s_root).gameObject.activeSelf != flag)
			{
				((Component)s_root).gameObject.SetActive(flag);
			}
			if (!flag)
			{
				return;
			}
			try
			{
				Layout(instance);
				Refresh(localPlayer);
			}
			catch (Exception ex2)
			{
				s_failed = true;
				((Component)s_root).gameObject.SetActive(false);
				Plugin.Log.LogError((object)("Gearhold panel failed, panel disabled until restart: " + ex2));
			}
		}

		private static void Build(InventoryGui gui)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Expected O, but got Unknown
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Expected O, but got Unknown
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Expected O, but got Unknown
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cf: Expected O, but got Unknown
			//IL_0659: Unknown result type (might be due to invalid IL or missing references)
			//IL_06de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0638: Unknown result type (might be due to invalid IL or missing references)
			//IL_0797: Unknown result type (might be due to invalid IL or missing references)
			s_gui = gui;
			s_slots.Clear();
			RectTransform parent = (RectTransform)((Transform)gui.m_player).parent;
			s_root = UiKit.Rect("MordasGearholdPanel", (Transform)(object)parent);
			RectTransform obj = s_root;
			RectTransform obj2 = s_root;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			obj2.anchorMax = val;
			obj.anchorMin = val;
			s_root.pivot = new Vector2(0.5f, 1f);
			s_root.sizeDelta = new Vector2(460f, 930f);
			Image val2 = UiKit.Named(gui.m_crafting, "Darken");
			if ((Object)(object)val2 != (Object)null)
			{
				UiKit.Fill((Transform)(object)s_root, "Darken", val2, 40f);
			}
			Image val3 = UiKit.Named(gui.m_crafting, "Bkg") ?? UiKit.FindBackground(gui.m_crafting);
			Image val4 = UiKit.Fill((Transform)(object)s_root, "Board", val3, 0f);
			((Graphic)val4).raycastTarget = true;
			if ((Object)(object)val3 == (Object)null)
			{
				((Graphic)val4).color = UiKit.PanelFallback;
			}
			Plugin.Log.LogInfo((object)("Gearhold panel background: " + (((Object)(object)val3 != (Object)null) ? (((Object)val3).name + " / " + ((Object)val3.sprite).name) : "none found, plain fallback")));
			Image template = UiKit.Named(gui.m_crafting, "BraidLineHorisontalMedium");
			Image val5 = UiKit.Named(gui.m_crafting, "Decription");
			TMP_Text craftingStationName = gui.m_craftingStationName;
			TMP_Text val6 = (((Object)(object)gui.m_recipeDecription != (Object)null) ? gui.m_recipeDecription : craftingStationName);
			UiKit.Place(UiKit.Text((Transform)(object)s_root, craftingStationName, "MORDA'S GEARHOLD", 34f, UiKit.Gold, (TextAlignmentOptions)514).rectTransform, 230f, 34f, 420f, 44f);
			UiKit.Place(UiKit.Text((Transform)(object)s_root, val6, "INVENTORY · LOADOUTS · QUICKSLOTS", 14f, UiKit.Dim, (TextAlignmentOptions)514).rectTransform, 230f, 64f, 420f, 20f);
			for (int i = 0; i < 3; i++)
			{
				int index = i;
				Button component = Object.Instantiate<GameObject>(((Component)gui.m_tabCraft).gameObject, (Transform)(object)s_root).GetComponent<Button>();
				((Object)((Component)component).gameObject).name = "SetTab" + (i + 1);
				((Component)component).gameObject.SetActive(true);
				component.onClick = new ButtonClickedEvent();
				((UnityEvent)component.onClick).AddListener((UnityAction)delegate
				{
					SetSwitcher.TrySwitch(Player.m_localPlayer, index);
				});
				TMP_Text componentInChildren = ((Component)component).GetComponentInChildren<TMP_Text>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.text = "SET " + (i + 1);
				}
				UiKit.Place((RectTransform)((Component)component).transform, 90f + (float)i * 140f, 102f, 128f, 34f);
				s_tabs[i] = component;
			}
			s_body = UiKit.Rect("Body", (Transform)(object)s_root);
			s_body.anchorMin = new Vector2(0f, 0f);
			s_body.anchorMax = new Vector2(1f, 1f);
			val = (s_body.offsetMin = (s_body.offsetMax = Vector2.zero));
			UiKit.Divider((Transform)(object)s_body, template, 230f, 132f, 420f);
			AddSlot(gui, GearSlot.Helmet, "Head", 58f, Row(0));
			AddSlot(gui, GearSlot.Chest, "Chest", 58f, Row(1));
			AddSlot(gui, GearSlot.Legs, "Legs", 58f, Row(2));
			AddSlot(gui, GearSlot.Shoulder, "Cape", 58f, Row(3));
			AddSlot(gui, GearSlot.Utility, "Utility 1", 58f, Row(4));
			AddSlot(gui, GearSlot.Utility2, "Utility 2", 58f, Row(5));
			AddSlot(gui, GearSlot.Utility3, "Utility 3", 58f, Row(6));
			AddSlot(gui, GearSlot.Shield, "Shield", 402f, Row(0));
			AddSlot(gui, GearSlot.Trinket, "Trinket 1", 402f, Row(4));
			AddSlot(gui, GearSlot.Trinket2, "Trinket 2", 402f, Row(5));
			AddSlot(gui, GearSlot.Trinket3, "Trinket 3", 402f, Row(6));
			AddSlot(gui, GearSlot.Coins, null, 416f, 46f, 52f);
			for (int num = 0; num < 3; num++)
			{
				Slot slot = AddSlot(gui, Topology.AmmoSlot(num), "Ammo " + (num + 1), 402f, Row(1 + num));
				int number = num;
				RectTransform obj3 = UiKit.Rect("KeyClickArea", slot.Caption.transform);
				obj3.anchorMin = Vector2.zero;
				obj3.anchorMax = Vector2.one;
				val = (obj3.offsetMin = (obj3.offsetMax = Vector2.zero));
				((Graphic)((Component)obj3).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.001f);
				Button obj4 = ((Component)obj3).gameObject.AddComponent<Button>();
				((Selectable)obj4).transition = (Transition)0;
				((UnityEvent)obj4.onClick).AddListener((UnityAction)delegate
				{
					KeyRebinder.Begin(Plugin.KeyAmmo[number]);
				});
			}
			float num2 = 146f;
			float num3 = Row(6) + 42f;
			if ((Object)(object)val5 != (Object)null)
			{
				RectTransform obj5 = UiKit.Rect("SheetBox", (Transform)(object)s_body);
				UiKit.Place(obj5, 230f, (num2 + num3) / 2f, 248f, num3 - num2);
				Image obj6 = ((Component)obj5).gameObject.AddComponent<Image>();
				UiKit.CopyLook(obj6, val5, Color.clear);
				((Graphic)obj6).raycastTarget = false;
			}
			UiKit.Place(UiKit.Text((Transform)(object)s_body, craftingStationName, "YOUR VIKING", 22f, UiKit.Gold, (TextAlignmentOptions)514).rectTransform, 230f, 160f, 230f, 28f);
			s_stats = BuildScrollingSheet(gui, val6, 230f, 180f, 232f, num3 - 8f);
			float num4 = num3 + 30f;
			UiKit.Divider((Transform)(object)s_body, template, 230f, num4, 420f);
			UiKit.Place(UiKit.Text((Transform)(object)s_body, craftingStationName, "QUICKSLOTS · ACTIVE SET", 16f, UiKit.Gold, (TextAlignmentOptions)513).rectTransform, 230f, num4 + 18f, 410f, 22f);
			for (int num5 = 0; num5 < 8; num5++)
			{
				float x = 230f + ((float)num5 - 3.5f) * 52f;
				Slot slot2 = AddSlot(gui, Topology.QuickSlot(num5), null, x, num4 + 58f, 46f);
				slot2.Label = "Quickslot " + (num5 + 1);
				slot2.KeyButton = AddKeyButton(gui, num5, x, num4 + 96f);
			}
			s_footer = UiKit.Text((Transform)(object)s_body, val6, "", 12f, UiKit.Dim, (TextAlignmentOptions)514);
			UiKit.Place(s_footer.rectTransform, 230f, num4 + 124f, 430f, 18f);
			((Component)s_root).gameObject.SetActive(false);
			static float Row(int num6)
			{
				return 178f + (float)num6 * 88f;
			}
		}

		private static TMP_Text BuildScrollingSheet(InventoryGui gui, TMP_Text font, float x, float top, float width, float bottom)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Expected O, but got Unknown
			RectTransform val = UiKit.Rect("SheetView", (Transform)(object)s_body);
			UiKit.Place(val, x, (top + bottom) / 2f, width, bottom - top);
			((Component)val).gameObject.AddComponent<RectMask2D>();
			((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.001f);
			TMP_Text obj = UiKit.Text((Transform)(object)val, font, "", 13.5f, UiKit.Parchment, (TextAlignmentOptions)257);
			obj.textWrappingMode = (TextWrappingModes)0;
			obj.lineSpacing = -8f;
			RectTransform rectTransform = obj.rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.anchoredPosition = Vector2.zero;
			rectTransform.sizeDelta = new Vector2(-14f, 0f);
			((Component)obj).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			ScrollRect val2 = ((Component)val).gameObject.AddComponent<ScrollRect>();
			val2.viewport = val;
			val2.content = rectTransform;
			val2.horizontal = false;
			val2.vertical = true;
			val2.movementType = (MovementType)2;
			val2.inertia = false;
			val2.scrollSensitivity = 25f;
			if ((Object)(object)gui.m_recipeListScroll != (Object)null)
			{
				Scrollbar component = Object.Instantiate<GameObject>(((Component)gui.m_recipeListScroll).gameObject, (Transform)(object)s_body).GetComponent<Scrollbar>();
				component.onValueChanged = new ScrollEvent();
				UiKit.Place((RectTransform)((Component)component).transform, x + width / 2f - 5f, (top + bottom) / 2f, 10f, bottom - top);
				component.direction = (Direction)2;
				val2.verticalScrollbar = component;
				val2.verticalScrollbarVisibility = (ScrollbarVisibility)1;
			}
			return obj;
		}

		private static TMP_Text AddKeyButton(InventoryGui gui, int quickslot, float x, float y)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			Button component = Object.Instantiate<GameObject>(((Component)gui.m_tabCraft).gameObject, (Transform)(object)s_body).GetComponent<Button>();
			((Object)((Component)component).gameObject).name = "QuickslotKey" + (quickslot + 1);
			((Component)component).gameObject.SetActive(true);
			((Selectable)component).interactable = true;
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				KeyRebinder.Begin(Plugin.KeyQuickslots[quickslot]);
			});
			UiKit.Place((RectTransform)((Component)component).transform, x, y, 48f, 24f);
			TMP_Text componentInChildren = ((Component)component).GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.enableAutoSizing = false;
				componentInChildren.fontSize = 13f;
				componentInChildren.textWrappingMode = (TextWrappingModes)0;
				componentInChildren.overflowMode = (TextOverflowModes)1;
			}
			UITooltip val = ((Component)component).GetComponent<UITooltip>();
			if ((Object)(object)val == (Object)null)
			{
				GameObject val2 = gui.m_playerGrid.m_elementPrefab.GetComponent<InventoryElement>()?.m_tooltip?.m_tooltipPrefab;
				if ((Object)(object)val2 == (Object)null)
				{
					return componentInChildren;
				}
				val = ((Component)component).gameObject.AddComponent<UITooltip>();
				val.m_tooltipPrefab = val2;
			}
			val.m_topic = "Quickslot " + (quickslot + 1);
			val.m_text = "Click, then press the new key (Shift / Ctrl / Alt allowed).\nEsc cancels · Delete clears.";
			return componentInChildren;
		}

		private static Slot AddSlot(InventoryGui gui, GearSlot kind, string label, float x, float y, float size = 64f)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(gui.m_playerGrid.m_elementPrefab, (Transform)(object)s_body);
			((Object)val).name = "Slot" + kind;
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = (Vector2)((val2.sizeDelta.x > 1f) ? val2.sizeDelta : new Vector2(size, size));
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(0f, 1f);
			val2.anchorMax = val4;
			val2.anchorMin = val4;
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.anchoredPosition = new Vector2(x, 0f - y);
			((Transform)val2).localScale = Vector3.one * (size / val3.x);
			Slot slot = new Slot
			{
				Kind = kind,
				Element = val.GetComponent<InventoryElement>(),
				Label = label
			};
			UIInputHandler componentInChildren = val.GetComponentInChildren<UIInputHandler>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.m_onLeftClick = delegate
				{
					OnLeftClick(slot);
				};
				componentInChildren.m_onRightDown = delegate
				{
					OnRightClick(slot);
				};
				componentInChildren.m_onPointerEnter = delegate
				{
					OnHover(slot);
				};
			}
			Slot slot2 = slot;
			Transform obj = val.transform.Find("binding");
			slot2.Binding = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null);
			if ((Object)(object)slot.Binding != (Object)null)
			{
				((Behaviour)slot.Binding).enabled = false;
			}
			if (label != null)
			{
				TMP_Text val5 = UiKit.Text((Transform)(object)s_body, gui.m_recipeDecription, label, 13f, UiKit.Dim, (TextAlignmentOptions)514);
				UiKit.Place(val5.rectTransform, x, y + size / 2f + 11f, 110f, 18f);
				slot.Caption = val5;
			}
			s_slots.Add(slot);
			return slot;
		}

		private static void Layout(InventoryGui gui)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Transform)s_root).parent;
			gui.m_player.GetWorldCorners(s_corners);
			float x = ((Transform)val).InverseTransformPoint(s_corners[2]).x;
			float y = ((Transform)val).InverseTransformPoint(s_corners[1]).y;
			Rect rect = val.rect;
			float num = ((Rect)(ref rect)).xMax - 20f;
			if ((Object)(object)gui.m_crafting != (Object)null && ((Component)gui.m_crafting).gameObject.activeInHierarchy)
			{
				gui.m_crafting.GetWorldCorners(s_corners);
				num = ((Transform)val).InverseTransformPoint(s_corners[0]).x;
			}
			float num2 = num - x - 24f;
			rect = val.rect;
			float num3 = y - (((Rect)(ref rect)).yMin + 70f);
			bool flag = gui.IsContainerOpen() && Overlaps(gui.m_container, val, x, num, y, 930f);
			float num4 = (flag ? 140f : 930f);
			float num5 = Mathf.Clamp(Mathf.Min(num2 / 460f, num3 / num4), 0.45f, 1f);
			((Component)s_body).gameObject.SetActive(!flag);
			s_root.sizeDelta = new Vector2(460f, num4);
			((Transform)s_root).localScale = Vector3.one * num5;
			((Transform)s_root).localPosition = new Vector3((x + num) / 2f, y, 0f);
		}

		private static bool Overlaps(RectTransform other, RectTransform parent, float left, float right, float top, float height)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)other == (Object)null || !((Component)other).gameObject.activeInHierarchy)
			{
				return false;
			}
			other.GetWorldCorners(s_corners);
			Vector3 val = ((Transform)parent).InverseTransformPoint(s_corners[0]);
			Vector3 val2 = ((Transform)parent).InverseTransformPoint(s_corners[2]);
			if (val2.x > left && val.x < right && val2.y > top - height)
			{
				return val.y < top;
			}
			return false;
		}

		private static void Refresh(Player player)
		{
			int num = GearholdState.ActiveSet(player);
			for (int i = 0; i < s_tabs.Length; i++)
			{
				((Selectable)s_tabs[i]).interactable = i != num;
			}
			ItemData drag = Access.DragItem.Invoke(s_gui);
			foreach (Slot s_slot in s_slots)
			{
				bool flag = Topology.IsEnabled(s_slot.Kind);
				if (((Component)s_slot.Element).gameObject.activeSelf != flag)
				{
					((Component)s_slot.Element).gameObject.SetActive(flag);
					if ((Object)(object)s_slot.Caption != (Object)null)
					{
						((Component)s_slot.Caption).gameObject.SetActive(flag);
					}
				}
				if (!flag)
				{
					continue;
				}
				s_slot.Item = Equipment.ItemIn(player, s_slot.Kind);
				Draw(player, s_slot, drag);
				if ((Object)(object)s_slot.KeyButton != (Object)null)
				{
					int num2 = (int)(s_slot.Kind - 16);
					string text = Plugin.KeyLabel(num2);
					s_slot.KeyButton.text = (KeyRebinder.IsWaitingFor(Plugin.KeyQuickslots[num2]) ? "<color=#ffc96e>...</color>" : ((text.Length > 0) ? text : "–"));
				}
				if ((Object)(object)s_slot.Caption != (Object)null && Topology.IsAmmoSlot(s_slot.Kind))
				{
					int num3 = (int)(s_slot.Kind - 9);
					string text2 = Plugin.AmmoKeyLabel(num3);
					if (KeyRebinder.IsWaitingFor(Plugin.KeyAmmo[num3]))
					{
						s_slot.Caption.text = $"Ammo {num3 + 1} · <color=#ffc96e>press key</color>";
					}
					else
					{
						s_slot.Caption.text = ((text2.Length > 0) ? $"Ammo {num3 + 1} · {text2}" : $"Ammo {num3 + 1} · <color=#e0a040>set key</color>");
					}
				}
			}
			if (Time.unscaledTime >= s_nextSheet)
			{
				s_nextSheet = Time.unscaledTime + 0.25f;
				s_stats.text = CharacterSheet.Build(player);
				SetPackage package;
				string error;
				int num4 = (GearholdState.TryReadSet(player, num, out package, out error) ? package.Records.Count : 0);
				s_footer.text = ((num4 > 0) ? $"<color=#e0a040>{num4} items of this set wait for their mod to return</color>" : "Only the Gearhold slots change with the set · the inventory is shared");
			}
		}

		private static void Draw(Player player, Slot slot, ItemData drag)
		{
			//IL_0169: 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_0200: Unknown result type (might be due to invalid IL or missing references)
			InventoryElement element = slot.Element;
			ItemData item = slot.Item;
			if ((Object)(object)element.m_selected != (Object)null)
			{
				element.m_selected.SetActive(false);
			}
			if ((Object)(object)element.m_queued != (Object)null)
			{
				((Behaviour)element.m_queued).enabled = item != null && player.IsEquipActionQueued(item);
			}
			if ((Object)(object)element.m_noteleport != (Object)null)
			{
				((Behaviour)element.m_noteleport).enabled = false;
			}
			if ((Object)(object)element.m_food != (Object)null)
			{
				((Behaviour)element.m_food).enabled = false;
			}
			if ((Object)(object)element.m_dropFocus != (Object)null)
			{
				((Behaviour)element.m_dropFocus).enabled = drag != null && Accepts(slot.Kind, drag);
			}
			Transmog.Piece? piece = Transmog.PieceFor(slot.Kind);
			string look = null;
			if (piece.HasValue)
			{
				look = Transmog.GetLook(player, piece.Value) ?? (Dye.Get(player, piece.Value).IsNeutral ? null : "dye");
			}
			else if (item != null && Transmog.IsWeapon(item))
			{
				look = Transmog.ItemMarker(item);
			}
			LookBadge.Show(((Component)element).transform, look);
			if (item == null)
			{
				Sprite val = ((slot.Kind == GearSlot.Coins) ? CoinIcon() : null);
				((Behaviour)element.m_icon).enabled = (Object)(object)val != (Object)null;
				element.m_icon.sprite = val;
				((Graphic)element.m_icon).color = new Color(1f, 1f, 1f, 0.25f);
				((Behaviour)element.m_equiped).enabled = false;
				((Behaviour)element.m_amount).enabled = false;
				if ((Object)(object)element.m_quality != (Object)null)
				{
					((Behaviour)element.m_quality).enabled = false;
				}
				((Component)element.m_durability).gameObject.SetActive(false);
				return;
			}
			((Behaviour)element.m_icon).enabled = true;
			element.m_icon.sprite = item.GetIcon();
			bool flag = item == drag || (Topology.IsArmorSlot(slot.Kind) && !item.m_equipped);
			((Graphic)element.m_icon).color = (flag ? Color.grey : Color.white);
			((Behaviour)element.m_equiped).enabled = item.m_equipped;
			bool flag2 = item.m_shared.m_maxStackSize > 1;
			((Behaviour)element.m_amount).enabled = flag2;
			if (flag2)
			{
				element.m_amount.text = item.m_stack + "/" + item.m_shared.m_maxStackSize;
			}
			if ((Object)(object)element.m_quality != (Object)null)
			{
				((Behaviour)element.m_quality).enabled = item.m_shared.m_maxQuality > 1;
				element.m_quality.text = item.m_quality.ToString();
			}
			bool flag3 = item.m_shared.m_useDurability && item.m_durability < item.GetMaxDurability();
			((Component)element.m_durability).gameObject.SetActive(flag3);
			if (flag3)
			{
				element.m_durability.SetValue((item.m_durability <= 0f) ? 1f : item.GetDurabilityPercentage());
			}
		}

		private static Sprite CoinIcon()
		{
			if ((Object)(object)s_coinIcon == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Coins");
				ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				s_coinIcon = (((Object)(object)val != (Object)null) ? val.m_itemData.GetIcon() : null);
			}
			return s_coinIcon;
		}

		private static bool Accepts(GearSlot slot, ItemData item)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			if (slot >= GearSlot.Quick1)
			{
				return true;
			}
			if (slot == GearSlot.Coins)
			{
				return Topology.IsCoins(item);
			}
			if (Topology.IsTrinketSlot(slot))
			{
				return (int)item.m_shared.m_itemType == 24;
			}
			if (Topology.IsUtilitySlot(slot))
			{
				return (int)item.m_shared.m_itemType == 18;
			}
			if (Topology.IsAmmoSlot(slot))
			{
				return (int)item.m_shared.m_itemType == 9;
			}
			return Topology.SlotFor(item) == slot;
		}

		private static void OnLeftClick(Slot slot)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)s_gui == (Object)null)
			{
				return;
			}
			ItemData val = Access.DragItem.Invoke(s_gui);
			if (val == null)
			{
				if (slot.Item != null)
				{
					if (slot.Kind >= GearSlot.Quick1 || slot.Kind == GearSlot.Coins)
					{
						Access.StartDrag(s_gui, slot.Item, ((Humanoid)localPlayer).GetInventory());
					}
					else
					{
						Equipment.TakeOut(localPlayer, slot.Item);
					}
				}
			}
			else if (!((Humanoid)localPlayer).GetInventory().ContainsItem(val))
			{
				((Character)localPlayer).Message((MessageType)2, "Take the item into your inventory first", 0, (Sprite)null, false);
			}
			else if (!Accepts(slot.Kind, val))
			{
				((Character)localPlayer).Message((MessageType)2, "This item does not fit into " + (slot.Label ?? "this slot"), 0, (Sprite)null, false);
			}
			else
			{
				Access.ClearDrag(s_gui);
				PutIntoSlot(localPlayer, slot.Kind, val);
			}
		}

		private static void PutIntoSlot(Player player, GearSlot kind, ItemData item)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Invalid comparison between Unknown and I4
			bool flag = Equipment.ItemIn(player, kind)?.m_equipped ?? false;
			Equipment.MoveToCell(player, item, Topology.Cell(player, kind));
			if (kind < GearSlot.Quick1 && kind != GearSlot.Coins && !Topology.IsExtraSlot(kind) && !item.m_equipped)
			{
				ItemData val = Access.RightItem.Invoke((Humanoid)(object)player);
				bool flag2;
				switch (kind)
				{
				case GearSlot.Shield:
					flag2 = flag || (Access.LeftItem.Invoke((Humanoid)(object)player) == null && val != null && ((int)val.m_shared.m_itemType == 3 || (int)val.m_shared.m_itemType == 15));
					break;
				case GearSlot.Ammo:
				case GearSlot.Ammo2:
				case GearSlot.Ammo3:
					flag2 = flag || Access.AmmoItem.Invoke((Humanoid)(object)player) == null;
					break;
				default:
					flag2 = true;
					break;
				}
				if (flag2)
				{
					((Humanoid)player).EquipItem(item, true);
				}
			}
		}

		private static void OnRightClick(Slot slot)
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				ItemData val = ((slot.Item != null && ((Humanoid)localPlayer).GetInventory().ContainsItem(slot.Item)) ? slot.Item : null);
				Transmog.Piece? piece = Transmog.PieceFor(slot.Kind);
				if (piece.HasValue)
				{
					SkinMenu.OpenForPiece(localPlayer, piece.Value);
				}
				else if (val != null && Transmog.IsWeapon(val))
				{
					SkinMenu.OpenForWeapon(localPlayer, val);
				}
				else if (val != null)
				{
					((Humanoid)localPlayer).UseItem((Inventory)null, val, true);
				}
			}
		}

		private static void OnHover(Slot slot)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			UITooltip tooltip = slot.Element.m_tooltip;
			if (!((Object)(object)tooltip == (Object)null))
			{
				if (slot.Item != null)
				{
					tooltip.Set(slot.Item.m_shared.m_name, slot.Item.GetTooltip(-1), s_gui.m_playerGrid.m_tooltipAnchor, default(Vector2));
				}
				else
				{
					tooltip.Set("", "", (RectTransform)null, default(Vector2));
				}
			}
		}
	}
	internal static class KeyRebinder
	{
		private static readonly KeyCode[] s_modifiers;

		private static readonly KeyCode[] s_candidates;

		private static readonly Dictionary<KeyCode, string> s_vanilla;

		private static ConfigEntry<KeyboardShortcut> s_target;

		private static int s_startFrame;

		internal static bool Active => s_target != null;

		internal static bool IsWaitingFor(ConfigEntry<KeyboardShortcut> entry)
		{
			if (s_target != null)
			{
				return s_target == entry;
			}
			return false;
		}

		internal static void Begin(ConfigEntry<KeyboardShortcut> entry)
		{
			s_target = ((s_target == entry) ? null : entry);
			s_startFrame = Time.frameCount;
		}

		internal static bool Tick()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (s_target == null)
			{
				return false;
			}
			if (!InventoryGui.IsVisible() || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				s_target = null;
				return false;
			}
			if (Time.frameCount == s_startFrame)
			{
				return true;
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				s_target = null;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)127) || Input.GetKeyDown((KeyCode)8))
			{
				Assign(KeyboardShortcut.Empty);
				return true;
			}
			KeyCode[] array = s_candidates;
			foreach (KeyCode val in array)
			{
				if (Input.GetKeyDown(val))
				{
					KeyCode[] array2 = ((IEnumerable<KeyCode>)s_modifiers).Where((Func<KeyCode, bool>)Input.GetKey).ToArray();
					Assign(new KeyboardShortcut(val, array2));
					return true;
				}
			}
			return true;
		}

		private static void Assign(KeyboardShortcut shortcut)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<KeyboardShortcut> val = s_target;
			s_target = null;
			Player localPlayer = Player.m_localPlayer;
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0)
			{
				foreach (ConfigEntry<KeyboardShortcut> item in AllHotkeys())
				{
					if (item != val && Same(item.Value, shortcut))
					{
						item.Value = KeyboardShortcut.Empty;
						if (localPlayer != null)
						{
							((Character)localPlayer).Message((MessageType)2, Plugin.FormatKey(shortcut) + " was removed from " + ((ConfigEntryBase)item).Definition.Key, 0, (Sprite)null, false);
						}
					}
				}
				if (((KeyboardShortcut)(ref shortcut)).Modifiers.Count() == 0 && s_vanilla.TryGetValue(((KeyboardShortcut)(ref shortcut)).MainKey, out var value) && localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "Note: " + Plugin.FormatKey(shortcut) + " is also vanilla \"" + value + "\"", 0, (Sprite)null, false);
				}
			}
			val.Value = shortcut;
		}

		private static IEnumerable<ConfigEntry<KeyboardShortcut>> AllHotkeys()
		{
			return Plugin.AllHotkeys();
		}

		private static bool Same(KeyboardShortcut a, KeyboardShortcut b)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (((KeyboardShortcut)(ref a)).MainKey == ((KeyboardShortcut)(ref b)).MainKey)
			{
				return ((KeyboardShortcut)(ref a)).Modifiers.OrderBy((KeyCode k) => k).SequenceEqual(((KeyboardShortcut)(ref b)).Modifiers.OrderBy((KeyCode k) => k));
			}
			return false;
		}

		static KeyRebinder()
		{
			KeyCode[] array = new KeyCode[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			s_modifiers = (KeyCode[])(object)array;
			s_candidates = ((KeyCode[])Enum.GetValues(typeof(KeyCode))).Where((KeyCode k) => (int)k != 0 && (int)k < 323 && !s_modifiers.Contains(k)).Distinct().ToArray();
			s_vanilla = new Dictionary<KeyCode, string>
			{
				{
					(KeyCode)101,
					"Use"
				},
				{
					(KeyCode)114,
					"Hide weapons"
				},
				{
					(KeyCode)32,
					"Jump"
				},
				{
					(KeyCode)99,
					"Walk"
				},
				{
					(KeyCode)113,
					"Auto-run"
				},
				{
					(KeyCode)120,
					"Sit"
				},
				{
					(KeyCode)102,
					"Forsaken power"
				},
				{
					(KeyCode)9,
					"Inventory"
				},
				{
					(KeyCode)109,
					"Map"
				},
				{
					(KeyCode)118,
					"Auto-pickup"
				},
				{
					(KeyCode)103,
					"Radial menu"
				},
				{
					(KeyCode)116,
					"Emotes"
				},
				{
					(KeyCode)13,
					"Chat"
				},
				{
					(KeyCode)286,
					"Console"
				},
				{
					(KeyCode)119,
					"Forward"
				},
				{
					(KeyCode)97,
					"Left"
				},
				{
					(KeyCode)115,
					"Backward"
				},
				{
					(KeyCode)100,
					"Right"
				},
				{
					(KeyCode)44,
					"Map zoom"
				},
				{
					(KeyCode)46,
					"Map zoom"
				},
				{
					(KeyCode)49,
					"Hotbar 1"
				},
				{
					(KeyCode)50,
					"Hotbar 2"
				},
				{
					(KeyCode)51,
					"Hotbar 3"
				},
				{
					(KeyCode)52,
					"Hotbar 4"
				},
				{
					(KeyCode)53,
					"Hotbar 5"
				},
				{
					(KeyCode)54,
					"Hotbar 6"
				},
				{
					(KeyCode)55,
					"Hotbar 7"
				},
				{
					(KeyCode)56,
					"Hotbar 8"
				}
			};
		}
	}
	internal static class LookBadge
	{
		private const string Name = "MGH_LookSparkle";

		private static readonly Color Glow = new Color(1f, 0.93f, 0.66f, 1f);

		private static readonly Color Core = new Color(1f, 1f, 0.92f, 1f);

		internal static void Show(Transform element, string look)
		{
			Transform val = element.Find("MGH_LookSparkle");
			if (look == null)
			{
				if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf)
				{
					((Component)val).gameObject.SetActive(false);
				}
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Build(element);
			}
			if (!((Component)val).gameObject.activeSelf)
			{
				((Component)val).gameObject.SetActive(true);
			}
		}

		private static Transform Build(Transform element)
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = ((RectTransform)element).rect;
			float num = Mathf.Max(10f, ((Rect)(ref rect)).width * 0.26f);
			RectTransform val = UiKit.Rect("MGH_LookSparkle", element);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 1f);
			val.anchorMax = val2;
			val.anchorMin = val2;
			val.pivot = new Vector2(0.5f, 0.5f);
			val.sizeDelta = new Vector2(num, num);
			val.anchoredPosition = new Vector2(num * 0.62f, (0f - num) * 0.62f);
			Ray(val, num, vertical: true);
			Ray(val, num, vertical: false);
			RectTransform obj = UiKit.Rect("Core", (Transform)(object)val);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			obj.anchorMax = val2;
			obj.anchorMin = val2;
			obj.pivot = new Vector2(0.5f, 0.5f);
			obj.sizeDelta = new Vector2(num * 0.2f, num * 0.2f);
			((Transform)obj).localRotation = Quaternion.Euler(0f, 0f, 45f);
			Image obj2 = ((Component)obj).gameObject.AddComponent<Image>();
			((Graphic)obj2).color = Core;
			((Graphic)obj2).raycastTarget = false;
			((Transform)val).SetAsLastSibling();
			return (Transform)(object)val;
		}

		private static void Ray(RectTransform root, float size, bool vertical)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			RectTransform val = UiKit.Rect(vertical ? "RayV" : "RayH", (Transform)(object)root);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			val.anchorMax = val2;
			val.anchorMin = val2;
			val.pivot = new Vector2(0.5f, 0.5f);
			val.sizeDelta = new Vector2(size, size);
			((Transform)val).localScale = (vertical ? new Vector3(0.28f, 1f, 1f) : new Vector3(1f, 0.28f, 1f));
			RectTransform obj = UiKit.Rect("Shape", (Transform)(object)val);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			obj.anchorMax = val2;
			obj.anchorMin = val2;
			obj.pivot = new Vector2(0.5f, 0.5f);
			obj.sizeDelta = new Vector2(size * 0.7071f, size * 0.7071f);
			((Transform)obj).localRotation = Quaternion.Euler(0f, 0f, 45f);
			Image obj2 = ((Component)obj).gameObject.AddComponent<Image>();
			((Graphic)obj2).color = Glow;
			((Graphic)obj2).raycastTarget = false;
			Shadow obj3 = ((Component)obj).gameObject.AddComponent<Shadow>();
			obj3.effectColor = new Color(0f, 0f, 0f, 0.7f);
			obj3.effectDistance = new Vector2(0.8f, -0.8f);
		}
	}
	internal static class QuickslotBar
	{
		private sealed class Element
		{
			public GameObject Go;

			public Image Icon;

			public TMP_Text Amount;

			public TMP_Text Key;

			public GuiBar Durability;

			public GameObject Equipped;
		}

		private const float KeyHeight = 20f;

		private static Hud s_hud;

		private static RectTransform s_root;

		private static readonly Element[] s_elements = new Element[8];

		private static float s_spacing = 70f;

		private static bool s_failed;

		internal static void Tick(Hud hud, Player player)
		{
			if (s_failed)
			{
				return;
			}
			try
			{
				if ((Object)(object)s_hud != (Object)(object)hud || (Object)(object)s_root == (Object)null)
				{
					Build(hud);
				}
				if (!((Object)(object)s_root == (Object)null))
				{
					bool flag = Plugin.ShowQuickslotBar.Value && (Object)(object)player != (Object)null && GearholdState.IsReady(player) && hud.m_rootObject.activeInHierarchy && !InventoryGui.IsVisible();
					if (flag)
					{
						flag = Refresh(player) > 0;
					}
					if (((Component)s_root).gameObject.activeSelf != flag)
					{
						((Component)s_root).gameObject.SetActive(flag);
					}
				}
			}
			catch (Exception ex)
			{
				s_failed = true;
				if ((Object)(object)s_root != (Object)null)
				{
					((Component)s_root).gameObject.SetActive(false);
				}
				Plugin.Log.LogError((object)("Gearhold quickslot bar failed, bar disabled until restart: " + ex));
			}
		}

		private static void Build(Hud hud)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_01bb: 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_01f8: Unknown result type (might be due to invalid IL or missing references)
			s_hud = hud;
			HotkeyBar componentInChildren = ((Component)hud).GetComponentInChildren<HotkeyBar>(true);
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.m_elementPrefab == (Object)null)
			{
				return;
			}
			s_spacing = componentInChildren.m_elementSpace;
			s_root = UiKit.Rect("MordasGearholdQuickslots", hud.m_rootObject.transform);
			RectTransform obj = s_root;
			RectTransform obj2 = s_root;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0f);
			obj2.anchorMax = val;
			obj.anchorMin = val;
			s_root.pivot = new Vector2(0.5f, 0f);
			s_root.sizeDelta = new Vector2(s_spacing * 8f, s_spacing + 20f);
			s_root.anchoredPosition = new Vector2(0f, 100f);
			for (int i = 0; i < s_elements.Length; i++)
			{
				GameObject val2 = Object.Instantiate<GameObject>(componentInChildren.m_elementPrefab, (Transform)(object)s_root);
				((Object)val2).name = "Quickslot" + (i + 1);
				Transform transform = val2.transform;
				Transform obj3 = transform.Find("binding");
				TMP_Text val3 = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null);
				if ((Object)(object)val3 != (Object)null)
				{
					((Behaviour)val3).enabled = false;
				}
				TMP_Text val4 = UiKit.Text(transform, val3, "", 16f, UiKit.Gold, (TextAlignmentOptions)1026);
				RectTransform rectTransform = val4.rectTransform;
				rectTransform.anchorMin = new Vector2(0.5f, 1f);
				rectTransform.anchorMax = new Vector2(0.5f, 1f);
				rectTransform.pivot = new Vector2(0.5f, 0f);
				rectTransform.sizeDelta = new Vector2(s_spacing + 10f, 20f);
				rectTransform.anchoredPosition = new Vector2(0f, 1f);
				val4.enableAutoSizing = true;
				val4.fontSizeMin = 10f;
				val4.fontSizeMax = 16f;
				val4.outlineWidth = 0.2f;
				val4.outlineColor = Color32.op_Implicit(Color.black);
				Element[] array = s_elements;
				int num = i;
				Element obj4 = new Element
				{
					Go = val2
				};
				Transform obj5 = transform.Find("icon");
				obj4.Icon = ((obj5 != null) ? ((Component)obj5).GetComponent<Image>() : null);
				Transform obj6 = transform.Find("amount");
				obj4.Amount = ((obj6 != null) ? ((Component)obj6).GetComponent<TMP_Text>() : null);
				obj4.Key = val4;
				Transform obj7 = transform.Find("durability");
				obj4.Durability = ((obj7 != null) ? ((Component)obj7).GetComponent<GuiBar>() : null);
				Transform obj8 = transform.Find("equiped");
				obj4.Equipped = ((obj8 != null) ? ((Component)obj8).gameObject : null);
				array[num] = obj4;
				Transform obj9 = transform.Find("queued");
				if (obj9 != null)
				{
					((Component)obj9).gameObject.SetActive(false);
				}
				Transform obj10 = transform.Find("selected");
				if (obj10 != null)
				{
					((Component)obj10).gameObject.SetActive(false);
				}
				val2.SetActive(false);
			}
			((Component)s_root).gameObject.SetActive(false);
		}

		private static int Refresh(Player player)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00e3: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			((Transform)s_root).localScale = Vector3.one * Plugin.QuickslotBarScale.Value;
			int num = 0;
			for (int i = 0; i < s_elements.Length; i++)
			{
				if (Equipment.ItemIn(player, Topology.QuickSlot(i)) != null)
				{
					num++;
				}
			}
			if (num == 0)
			{
				return 0;
			}
			float num2 = (float)(-(num - 1)) * s_spacing / 2f;
			Vector2 val3 = default(Vector2);
			for (int j = 0; j < s_elements.Length; j++)
			{
				Element element = s_elements[j];
				ItemData val = Equipment.ItemIn(player, Topology.QuickSlot(j));
				if (val == null)
				{
					if (element.Go.activeSelf)
					{
						element.Go.SetActive(false);
					}
					continue;
				}
				if (!element.Go.activeSelf)
				{
					element.Go.SetActive(true);
				}
				RectTransform val2 = (RectTransform)element.Go.transform;
				((Vector2)(ref val3))..ctor(0.5f, 0.5f);
				val2.anchorMax = val3;
				val2.anchorMin = val3;
				Vector2 val4 = new Vector2(num2, 0f);
				Rect rect = val2.rect;
				val2.anchoredPosition = val4 - ((Rect)(ref rect)).center;
				num2 += s_spacing;
				if ((Object)(object)element.Icon != (Object)null)
				{
					((Component)element.Icon).gameObject.SetActive(true);
					element.Icon.sprite = val.GetIcon();
				}
				element.Key.text = Plugin.KeyLabel(j);
				if ((Object)(object)element.Amount != (Object)null)
				{
					bool flag = val.m_shared.m_maxStackSize > 1;
					((Component)element.Amount).gameObject.SetActive(flag);
					if (flag)
					{
						element.Amount.text = val.m_stack.ToString();
					}
				}
				if ((Object)(object)element.Equipped != (Object)null)
				{
					element.Equipped.SetActive(val.m_equipped);
				}
				if ((Object)(object)element.Durability != (Object)null)
				{
					bool flag2 = val.m_shared.m_useDurability && val.m_durability < val.GetMaxDurability();
					((Component)element.Durability).gameObject.SetActive(flag2);
					if (flag2)
					{
						element.Durability.SetValue((val.m_durability <= 0f) ? 1f : val.GetDurabilityPercentage());
					}
				}
			}
			return num;
		}
	}
	internal static class SkinMenu
	{
		private const int Columns = 7;

		private const float Cell = 64f;

		private const float Pad = 20f;

		private const float PreviewWidth = 360f;

		private const float ColorRow = 34f;

		private const float ColorHeader = 30f;

		private const float SwatchRow = 44f;

		private const float MinHeight = 640f;

		private static readonly Transmog.Piece[] s_pieces = new Transmog.Piece[5]
		{
			Transmog.Piece.Helmet,
			Transmog.Piece.Chest,
			Transmog.Piece.Legs,
			Transmog.Piece.Shoulder,
			Transmog.Piece.Shield
		};

		private static InventoryGui s_gui;

		private static RectTransform s_blocker;

		private static RectTransform s_menu;

		private static RectTransform s_content;

		private static Action s_revert;

		private static readonly (string name, float hue)[] s_hues = new(string, float)[8]
		{
			("Red", 0f),
			("Orange", 0.08f),
			("Yellow", 0.15f),
			("Green", 0.33f),
			("Teal", 0.48f),
			("Blue", 0.6f),
			("Purple", 0.76f),
			("Pink", 0.89f)
		};

		internal static bool IsOpen
		{
			get
			{
				if ((Object)(object)s_blocker != (Object)null)
				{
					return ((Component)s_blocker).gameObject.activeSelf;
				}
				return false;
			}
		}

		internal static void OpenForPiece(Player player, Transmog.Piece piece)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen)
			{
				int set = GearholdState.ActiveSet(player);
				string looks0 = Transmog.ReadSetLooks(player, set);
				string dyes0 = Dye.ReadSet(player, set);
				s_revert = delegate
				{
					Transmog.WriteSetLooks(player, set, looks0);
					Dye.WriteSet(player, set, dyes0);
				};
			}
			string look = Transmog.GetLook(player, piece);
			List<GameObject> list = Transmog.LooksFor(player, Transmog.TypeOf(piece), null);
			int num = 0;
			Transmog.Piece[] array = s_pieces;
			foreach (Transmog.Piece piece2 in array)
			{
				num = Mathf.Max(num, (piece2 == piece) ? list.Count : Transmog.LooksFor(player, Transmog.TypeOf(piece2), null).Count);
			}
			Open("LOOKS & COLORS", look, list, num, delegate(string look2)
			{
				Transmog.SetLook(player, piece, look2);
				OpenForPiece(player, piece);
			}, player, piece);
		}

		internal static void OpenForWeapon(Player player, ItemData weapon)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen)
			{
				string look0 = Transmog.GetItemLook(weapon);
				GlowValue glow0 = Glow.Get(weapon);
				s_revert = delegate
				{
					Transmog.SetItemLook(player, weapon, look0);
					Glow.Set(player, weapon, glow0);
				};
			}
			string itemLook = Transmog.GetItemLook(weapon);
			List<GameObject> list = Transmog.LooksFor(player, weapon.m_shared.m_itemType, weapon.m_shared.m_skillType);
			string title = Localization.instance.Localize(weapon.m_shared.m_name).ToUpperInvariant() + " LOOK";
			int count = list.Count;
			Action<string> choose = delegate(string look1)
			{
				Transmog.SetItemLook(player, weapon, look1);
				OpenForWeapon(player, weapon);
			};
			Player glowPlayer = player;
			ItemData glowWeapon = (Glow.CanGlow(weapon) ? weapon : null);
			Open(title, itemLook, list, count, choose, null, null, glowPlayer, glowWeapon);
		}

		internal static void Close(bool save = false)
		{
			Action action = s_revert;
			s_revert = null;
			if ((Object)(object)s_blocker != (Object)null)
			{
				((Component)s_blocker).gameObject.SetActive(false);
			}
			CharacterPreview.End();
			if (!save && action != null && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				try
				{
					action();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Gearhold look menu: could not undo the unsaved changes: " + ex.Message));
				}
			}
		}

		internal static void Tick()
		{
			if (IsOpen && !InventoryGui.IsVisible())
			{
				Close();
			}
			if (IsOpen)
			{
				CharacterPreview.Tick();
			}
		}

		private static void Open(string title, string current, List<GameObject> looks, int maxLooks, Action<string> choose, Player dyePlayer = null, Transmog.Piece? dyePiece = null, Player glowPlayer = null, ItemData glowWeapon = null)
		{
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)s_gui != (Object)(object)instance || (Object)(object)s_blocker == (Object)null)
			{
				Build(instance);
			}
			for (int num = ((Transform)s_content).childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)((Transform)s_content).GetChild(num)).gameObject);
			}
			bool flag = (Object)(object)dyePlayer != (Object)null && dyePiece.HasValue;
			int num2 = looks.Count + 1;
			int num3 = Mathf.Max(1, Mathf.CeilToInt((float)(maxLooks + 1) / 7f));
			float num4 = 380f;
			float num5 = 488f;
			float num6 = num5 - 40f;
			float x = num4 + num5 / 2f;
			float num7 = num4 + num5;
			float num8 = 70f;
			float num9 = (flag ? (num8 + 40f) : 70f);
			float num10 = num9 + 24f;
			float num11 = num10 + (float)num3 * 64f + 20f;
			if (flag)
			{
				num11 += 226f;
			}
			bool flag2 = (Object)(object)glowPlayer != (Object)null && glowWeapon != null;
			if (flag2)
			{
				num11 += 124f;
			}
			num11 = Mathf.Max(num11, 640f);
			s_menu.sizeDelta = new Vector2(num7, num11);
			AddButton(instance, "< BACK", 70f, 34f, 100f, selected: false, delegate
			{
				Close();
			});
			UiKit.Place(UiKit.Text((Transform)(object)s_content, instance.m_craftingStationName, title, 22f, UiKit.Gold, (TextAlignmentOptions)514).rectTransform, num7 / 2f, 34f, num7 - 300f, 30f);
			float num12 = 60f;
			float num13 = num11 - 20f - 48f;
			float x2 = 190f;
			CharacterPreview.CreateView((Transform)(object)s_content, x2, (num12 + num13) / 2f, 340f, num13 - num12);
			AddButton(instance, "SAVE", x2, num11 - 20f - 18f, 200f, selected: false, delegate
			{
				Close(save: true);
			});
			if (flag)
			{
				float num14 = num6 / (float)s_pieces.Length;
				for (int num15 = 0; num15 < s_pieces.Length; num15++)
				{
					Transmog.Piece piece = s_pieces[num15];
					AddButton(instance, PieceLabel(piece), num4 + 20f + num14 / 2f + (float)num15 * num14, num8, num14 - 6f, piece == dyePiece.Value, delegate
					{
						OpenForPiece(dyePlayer, piece);
					});
				}
			}
			AddButton(instance, "OWN LOOK", x, num9, num6, current == null, delegate
			{
				choose(null);
			});
			for (int num16 = 0; num16 < num2; num16++)
			{
				float x3 = num4 + 20f + 32f + (float)(num16 % 7) * 64f;
				float y = num10 + 32f + (float)(num16 / 7) * 64f;
				if (num16 == 0)
				{
					AddCell(instance, null, "Hide", x3, y, current == "-", delegate
					{
						choose("-");
					});
					continue;
				}
				GameObject prefab = looks[num16 - 1];
				ItemData itemData = prefab.GetComponent<ItemDrop>().m_itemData;
				AddCell(instance, itemData.GetIcon(), itemData.m_shared.m_name, x3, y, ((Object)prefab).name == current, delegate
				{
					choose(((Object)prefab).name);
				});
			}
			if (flag)
			{
				AddColorSection(instance, dyePlayer, dyePiece.Value, num4, num5, num10 + (float)num3 * 64f + 10f);
			}
			if (flag2)
			{
				AddGlowSection(instance, glowPlayer, glowWeapon, num4, num5, num10 + (float)num3 * 64f + 10f);
			}
			Rect rect = s_blocker.rect;
			float num17 = Mathf.Min(new float[3]
			{
				1f,
				(((Rect)(ref rect)).width - 40f) / num7,
				(((Rect)(ref rect)).height - 40f) / num11
			});
			((Transform)s_menu).localScale = Vector3.one * Mathf.Max(0.4f, num17);
			s_menu.anchoredPosition = Vector2.zero;
			((Transform)s_blocker).SetAsLastSibling();
			((Component)s_blocker).gameObject.SetActive(true);
			CharacterPreview.Begin();
		}

		private static string PieceLabel(Transmog.Piece piece)
		{
			return piece switch
			{
				Transmog.Piece.Helmet => "HEAD", 
				Transmog.Piece.Shoulder => "CAPE", 
				_ => piece.ToString().ToUpperInvariant(), 
			};
		}

		private static void AddColorSection(InventoryGui gui, Player player, Transmog.Piece piece, float ox, float columnWidth, float top)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			float x = ox + columnWidth / 2f;
			float num = columnWidth - 40f;
			Image template = UiKit.Named(gui.m_crafting, "BraidLineHorisontalMedium");
			UiKit.Divider((Transform)(object)s_content, template, x, top, num);
			UiKit.Place(UiKit.Text((Transform)(object)s_content, gui.m_craftingStationName, "COLOR", 18f, UiKit.Gold, (TextAlignmentOptions)514).rectTransform, x, top + 18f, num, 24f);
			TMP_Text[] values = (TMP_Text[])(object)new TMP_Text[3];
			int num2 = s_hues.Length + 3;
			float num3 = num / (float)num2;
			float size = Mathf.Min(num3 - 6f, 34f);
			float y = top + 30f + 22f;
			for (int i = 0; i < num2; i++)
			{
				float x2 = ox + 20f + num3 / 2f + (float)i * num3;
				if (i < s_hues.Length)
				{
					float hue = s_hues[i].hue;
					AddSwatch(x2, y, size, Color.HSVToRGB(hue, 0.75f, 0.85f), s_hues[i].name, delegate
					{
						SetDye(TowardsHue(player, piece, hue));
					});
				}
				else if (i == s_hues.Length)
				{
					AddSwatch(x2, y, size, new Color(0.08f, 0.08f, 0.08f), "Black", delegate
					{
						SetDye(new DyeValue
						{
							Saturation = -60,
							Brightness = -70
						});
					});
				}
				else if (i == s_hues.Length + 1)
				{
					AddSwatch(x2, y, size, new Color(0.92f, 0.92f, 0.9f), "White", delegate
					{
						SetDye(new DyeValue
						{
							Saturation = -95,
							Brightness = 60
						});
					});
				}
				else
				{
					AddSwatch(x2, y, size, new Color(0.5f, 0.5f, 0.5f), "Grey", delegate
					{
						SetDye(new DyeValue
						{
							Saturation = -100
						});
					});
				}
			}
			string[] array = new string[3] { "Color", "Intensity", "Brightness" };
			int[] steps = new int[3] { 15, 10, 10 };
			float num4 = top + 30f + 44f;
			for (int num5 = 0; num5 < 3; num5++)
			{
				int channel = num5;
				float y2 = num4 + 17f + (float)num5 * 34f;
				UiKit.Place(UiKit.Text((Transform)(object)s_content, gui.m_recipeDecription, array[num5], 16f, UiKit.Parchment, (TextAlignmentOptions)513).rectTransform, ox + 20f + 60f, y2, 120f, 24f);
				AddButton(gui, "-", ox + columnWidth - 20f - 150f, y2, 40f, selected: false, delegate
				{
					DyeValue d = Dye.Get(player, piece);
					Nudge(ref d, channel, -steps[channel]);
					SetDye(d);
				});
				values[num5] = UiKit.Text((Transform)(object)s_content, gui.m_recipeDecription, "", 16f, UiKit.Gold, (TextAlignmentOptions)514);
				UiKit.Place(values[num5].rectTransform, ox + columnWidth - 20f - 90f, y2, 70f, 24f);
				AddButton(gui, "+", ox + columnWidth - 20f - 30f, y2, 40f, selected: false, delegate
				{
					DyeValue d = Dye.Get(player, piece);
					Nudge(ref d, channel, steps[channel]);
					SetDye(d);
				});
			}
			float y3 = num4 + 102f + 20f;
			AddButton(gui, "RESET", ox + columnWidth - 20f - 60f, y3, 120f, selected: false, delegate
			{
				SetDye(default(DyeValue));
			});
			Refresh();
			void Refresh()
			{
				DyeValue dyeValue = Dye.Get(player, piec