Decompiled source of Armory v2.0.0

BepInEx/plugins/Armory.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
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.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Armory")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+9e03c2a9c664de7a4ae6d89632d09fa087a2d9d7")]
[assembly: AssemblyProduct("Armory")]
[assembly: AssemblyTitle("Armory")]
[assembly: AssemblyVersion("2.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Armory
{
	[BepInPlugin("GBahns.Armory", "Armory", "2.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ArmoryMod : BaseUnityPlugin
	{
		public const string ModGuid = "GBahns.Armory";

		private readonly Harmony _harmony = new Harmony("GBahns.Armory");

		public static ArmoryMod Instance;

		public static ConfigEntry<bool> ModEnabled;

		private bool _initialized;

		public static ConfigEntry<bool> PauseGameWhileOpen;

		public static ConfigEntry<bool> ShowSummaryText;

		public static ConfigEntry<bool> ShowIcons;

		public static ConfigEntry<bool> ShowRowButtons;

		public static ConfigEntry<float> PanelPosX;

		public static ConfigEntry<float> PanelPosY;

		public static ConfigEntry<float> PanelWidth;

		public static ConfigEntry<float> PanelHeight;

		private void Awake()
		{
			Instance = this;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Mod Enabled", true, "Master toggle for the entire mod. Set to false to disable the Armory Rack piece, the UI, and all Harmony patches without removing the DLL. Useful for quickly isolating mod conflicts.  Requires a game restart to take effect.");
			PauseGameWhileOpen = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Pause Game While Armory Open", false, "Pause the game while the Armory Rack panel is open, the way the ESC menu does. This works by itself when playing solo or hosting alone; on a dedicated server it takes the Pause My Server mod, and without it the request is simply refused rather than stopping your own clock while the server runs on.");
			PauseGameWhileOpen.SettingChanged += delegate
			{
				ArmoryPause.Refresh();
			};
			ShowSummaryText = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Show Summary Text", true, "Show the textual list of items below each loadout's name (Helm:..., Chest:..., etc).");
			ShowIcons = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Show Icons", true, "Show the row of item icons at the bottom of each loadout row.");
			ShowRowButtons = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Show Row Buttons", false, "Show Save, Load, +, Cmp and x on every loadout row. Off puts them in a menu behind one button per row, which takes less room and lets the panel be narrower.");
			PanelPosX = ((BaseUnityPlugin)this).Config.Bind<float>("Window", "Panel Position X", 380f, "Saved horizontal panel position (auto-updated when you close the rack).");
			PanelPosY = ((BaseUnityPlugin)this).Config.Bind<float>("Window", "Panel Position Y", 0f, "Saved vertical panel position (auto-updated when you close the rack).");
			PanelWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Window", "Panel Width", 760f, "Saved panel width (auto-updated when you drag the grip in the panel's bottom-right corner). A loadout's icon groups sit on one line when they fit the width, and wrap onto more lines only when they don't.");
			PanelHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Window", "Panel Height", 0f, "Saved panel height (auto-updated when you drag the grip). 0 means fit the panel to its loadouts, up to most of the screen; the list scrolls past that.");
			if (!ModEnabled.Value)
			{
				Logger.LogInfo((object)"[Armory] Mod Enabled = false in config — skipping piece registration and Harmony patches.");
				return;
			}
			_initialized = true;
			_harmony.PatchAll();
			try
			{
				CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
				string text = "English";
				localization.AddTranslation(ref text, new Dictionary<string, string>
				{
					["armory_rack_name"] = "Armory Rack",
					["armory_rack_desc"] = "A masterwork rack for storing and instantly recalling named equipment sets.",
					["armory_rename_topic"] = "Armory Name"
				});
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Armory] Localization registration skipped: " + ex.Message));
			}
			PrefabManager.OnVanillaPrefabsAvailable += ArmoryPieces.CreatePiece;
			PieceManager.OnPiecesRegistered += ArmoryPieces.ConfigureAndRegister;
		}

		private void Update()
		{
			if (_initialized)
			{
				ArmoryUI.Tick();
				ArmoryPause.Refresh();
			}
		}

		private void OnDestroy()
		{
			if (_initialized)
			{
				ArmoryPause.Release();
				_harmony.UnpatchSelf();
			}
		}
	}
	[HarmonyPatch(typeof(Player), "TakeInput")]
	internal static class Player_TakeInput_Patch
	{
		private static bool Prefix()
		{
			return !ArmoryUI.IsOpen;
		}
	}
	[HarmonyPatch(typeof(Player), "SetMouseLook")]
	internal static class Player_SetMouseLook_Patch
	{
		private static bool Prefix()
		{
			return !ArmoryUI.IsOpen;
		}
	}
	[HarmonyPatch(typeof(Chat), "HasFocus")]
	internal static class Chat_HasFocus_Patch
	{
		private static void Postfix(ref bool __result)
		{
			if (ArmoryUI.IsEditing)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Show")]
	internal static class ArmoryOpenPatch
	{
		private static void Postfix(Container container)
		{
			if (!((Object)(object)container == (Object)null))
			{
				ArmoryRack component = ((Component)container).GetComponent<ArmoryRack>();
				if (!((Object)(object)component == (Object)null))
				{
					ArmoryUI.Open(component);
				}
			}
		}
	}
	internal static class ArmoryPause
	{
		private static bool _holding;

		internal static bool Holding => _holding;

		internal static void Refresh()
		{
			bool flag = ArmoryMod.PauseGameWhileOpen != null && ArmoryMod.PauseGameWhileOpen.Value && ArmoryUI.IsOpen && (Object)(object)Player.m_localPlayer != (Object)null;
			if (flag == _holding)
			{
				if (flag && !Game.IsPaused())
				{
					Game.Pause();
				}
				return;
			}
			_holding = flag;
			if (flag)
			{
				Game.Pause();
			}
			else
			{
				Game.Unpause();
			}
			ArmoryUI.SetInventoryGuiUnscaled(flag);
			Logger.LogInfo((object)(flag ? $"[Armory] Pause: requested, granted={Game.IsPaused()}" : "[Armory] Pause: released"));
		}

		internal static void Release()
		{
			if (_holding)
			{
				_holding = false;
				Game.Unpause();
				ArmoryUI.SetInventoryGuiUnscaled(unscaled: false);
			}
		}
	}
	internal static class ArmoryPieces
	{
		private const string PieceName = "armory_rack";

		private const string BasePrefab = "piece_chest_blackmetal";

		private const string PieceTable = "_HammerPieceTable";

		private const string Category = "Furniture";

		private static GameObject _clone;

		private static bool _clonesCreated;

		private static bool _piecesConfigured;

		private static readonly FieldInfo _namedPrefabsField = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs");

		private static Dictionary<int, GameObject> GetNamedPrefabs()
		{
			if (!((Object)(object)ZNetScene.instance != (Object)null))
			{
				return null;
			}
			return _namedPrefabsField?.GetValue(ZNetScene.instance) as Dictionary<int, GameObject>;
		}

		internal static void CreatePiece()
		{
			if (_clonesCreated)
			{
				return;
			}
			_clonesCreated = true;
			GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_blackmetal");
			if ((Object)(object)prefab == (Object)null)
			{
				Logger.LogError((object)"[Armory] Base prefab 'piece_chest_wood' not found.");
				return;
			}
			_clone = PrefabManager.Instance.CreateClonedPrefab("armory_rack", prefab);
			Dictionary<int, GameObject> namedPrefabs = GetNamedPrefabs();
			if (namedPrefabs != null)
			{
				namedPrefabs[StringExtensionMethods.GetStableHashCode(((Object)_clone).name)] = _clone;
			}
			Container component = _clone.GetComponent<Container>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			_clone.AddComponent<ArmoryRack>();
			BuildArmoireMesh(_clone);
			Piece obj = _clone.GetComponent<Piece>() ?? _clone.AddComponent<Piece>();
			obj.m_name = "$armory_rack_name";
			obj.m_description = "$armory_rack_desc";
			obj.m_groundOnly = false;
			obj.m_groundPiece = false;
			obj.m_resources = (Requirement[])(object)new Requirement[0];
			Logger.LogInfo((object)"[Armory] Phase 1 — cloned armory_rack");
		}

		private static void BuildArmoireMesh(GameObject parent)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = parent.GetComponentsInChildren<Renderer>();
			Renderer[] array = componentsInChildren;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].enabled = false;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab("wood_floor_1x1");
			if ((Object)(object)prefab == (Object)null)
			{
				Logger.LogWarning((object)"[Armory] wood_floor_1x1 unavailable — reverting to chest visual.");
				array = componentsInChildren;
				for (int i = 0; i < array.Length; i++)
				{
					array[i].enabled = true;
				}
				return;
			}
			GameObject val = null;
			string text = null;
			string[] array2 = new string[4] { "wood_shutter", "wood_shutter_closed", "wood_window_shutter", "wood_window" };
			foreach (string text2 in array2)
			{
				val = PrefabManager.Instance.GetPrefab(text2);
				if ((Object)(object)val != (Object)null)
				{
					text = text2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				val = prefab;
				text = "wood_floor_1x1 (shutter unavailable)";
			}
			Logger.LogInfo((object)("[Armory] BuildArmoireMesh: door prefab = '" + text + "'."));
			for (int j = 0; j < 2; j++)
			{
				for (int k = 0; k < 3; k++)
				{
					AddPanel(parent, prefab, new Vector3(-0.5f + (float)j, 0.5f + (float)k, -0.5f), Quaternion.Euler(-90f, 0f, 0f));
				}
			}
			for (int l = 0; l < 3; l++)
			{
				AddPanel(parent, prefab, new Vector3(-1f, 0.5f + (float)l, 0f), Quaternion.Euler(0f, 0f, -90f));
			}
			for (int m = 0; m < 3; m++)
			{
				AddPanel(parent, prefab, new Vector3(1f, 0.5f + (float)m, 0f), Quaternion.Euler(0f, 0f, 90f));
			}
			for (int n = 0; n < 2; n++)
			{
				AddPanel(parent, prefab, new Vector3(-0.5f + (float)n, 3f, 0f), Quaternion.identity);
			}
			for (int num = 0; num < 2; num++)
			{
				AddPanel(parent, prefab, new Vector3(-0.5f + (float)num, 0f, 0f), Quaternion.Euler(180f, 0f, 0f));
			}
			BuildDoor(parent, val, "ArmoryDoorLeft", new Vector3(-1f, 0f, 0.5f), 0f, flipped: true);
			BuildDoor(parent, val, "ArmoryDoorRight", new Vector3(1f, 0f, 0.5f), 0f, flipped: false);
			BoxCollider obj = parent.AddComponent<BoxCollider>();
			obj.center = new Vector3(0f, 1.5f, 0f);
			obj.size = new Vector3(2f, 3f, 1f);
			ApplyTint(parent.transform, new Color(0.5f, 0.5f, 0.5f));
			Transform val2 = parent.transform.Find("ArmoryDoorLeft");
			Transform val3 = parent.transform.Find("ArmoryDoorRight");
			if ((Object)(object)val2 != (Object)null)
			{
				ApplyTint(val2, new Color(0.75f, 0.75f, 0.75f));
			}
			if ((Object)(object)val3 != (Object)null)
			{
				ApplyTint(val3, new Color(0.75f, 0.75f, 0.75f));
			}
			Logger.LogInfo((object)"[Armory] BuildArmoireMesh: composed 16 wood panels + 2 doors (panels 50%, shutters 75%).");
		}

		private static void ApplyTint(Transform root, Color tint)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if (!val.enabled)
				{
					continue;
				}
				Material[] materials = val.materials;
				foreach (Material val2 in materials)
				{
					if (val2.HasProperty("_Color"))
					{
						val2.color = tint;
					}
				}
			}
		}

		private static void BuildDoor(GameObject parent, GameObject panelSrc, string hingeName, Vector3 hingeLocalPos, float panelOffsetX, bool flipped)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(hingeName);
			val.transform.SetParent(parent.transform, false);
			val.transform.localPosition = hingeLocalPos;
			val.transform.localRotation = Quaternion.identity;
			Vector3 localScale = (Vector3)(flipped ? new Vector3(-1f, 1f, 1f) : Vector3.one);
			for (int i = 0; i < 3; i++)
			{
				GameObject obj = Object.Instantiate<GameObject>(panelSrc, val.transform);
				obj.transform.localPosition = new Vector3(panelOffsetX, 0.5f + (float)i, 0f);
				obj.transform.localRotation = Quaternion.identity;
				obj.transform.localScale = localScale;
				((Object)obj).name = ((Object)panelSrc).name + "_panel";
				StripChildComponents(obj);
			}
		}

		private static void StripChildComponents(GameObject visual)
		{
			Door[] componentsInChildren = visual.GetComponentsInChildren<Door>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Piece[] componentsInChildren2 = visual.GetComponentsInChildren<Piece>();
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			WearNTear[] componentsInChildren3 = visual.GetComponentsInChildren<WearNTear>();
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			ZNetView[] componentsInChildren4 = visual.GetComponentsInChildren<ZNetView>();
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren4[i]);
			}
			ZSyncTransform[] componentsInChildren5 = visual.GetComponentsInChildren<ZSyncTransform>();
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren5[i]);
			}
			Collider[] componentsInChildren6 = visual.GetComponentsInChildren<Collider>();
			for (int i = 0; i < componentsInChildren6.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren6[i]);
			}
			SnapToGround[] componentsInChildren7 = visual.GetComponentsInChildren<SnapToGround>();
			for (int i = 0; i < componentsInChildren7.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren7[i]);
			}
		}

		private static void AddPanel(GameObject parent, GameObject source, Vector3 localPos, Quaternion localRot)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(source, parent.transform);
			obj.transform.localPosition = localPos;
			obj.transform.localRotation = localRot;
			((Object)obj).name = ((Object)source).name + "_panel";
			StripChildComponents(obj);
		}

		internal static void ConfigureAndRegister()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Expected O, but got Unknown
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Expected O, but got Unknown
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			if (_piecesConfigured)
			{
				return;
			}
			_piecesConfigured = true;
			if ((Object)(object)_clone == (Object)null)
			{
				Logger.LogError((object)"[Armory] Phase 2: no clone from Phase 1 — Armory Rack unavailable.");
				return;
			}
			Piece component = _clone.GetComponent<Piece>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_blackmetal");
			WearNTear val = ((prefab != null) ? prefab.GetComponent<WearNTear>() : null);
			WearNTear val2 = _clone.GetComponent<WearNTear>() ?? _clone.AddComponent<WearNTear>();
			val2.m_health = 500f;
			val2.m_materialType = (MaterialType)0;
			if ((Object)(object)val != (Object)null)
			{
				val2.m_destroyedEffect = val.m_destroyedEffect;
				val2.m_hitEffect = val.m_hitEffect;
			}
			List<Requirement> requirements = new List<Requirement>();
			AddReq("FineWood", 8);
			AddReq("RoundLog", 4);
			AddReq("BronzeNails", 4);
			AddReq("Bronze", 2);
			AddReq("DeerHide", 2);
			component.m_resources = requirements.ToArray();
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("piece_workbench");
			component.m_craftingStation = ((prefab2 != null) ? prefab2.GetComponent<CraftingStation>() : null);
			object obj = LoadEmbeddedIcon("armory.png");
			if (obj == null)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("ArmorLeatherChest");
				if (itemPrefab == null)
				{
					obj = null;
				}
				else
				{
					ItemDrop component2 = itemPrefab.GetComponent<ItemDrop>();
					if (component2 == null)
					{
						obj = null;
					}
					else
					{
						ItemData itemData = component2.m_itemData;
						if (itemData == null)
						{
							obj = null;
						}
						else
						{
							SharedData shared = itemData.m_shared;
							if (shared == null)
							{
								obj = null;
							}
							else
							{
								Sprite[] icons = shared.m_icons;
								obj = ((icons != null) ? icons[0] : null);
							}
						}
					}
				}
			}
			component.m_icon = (Sprite)obj;
			GameObject prefab3 = PrefabManager.Instance.GetPrefab("piece_chest_blackmetal");
			Piece val3 = ((prefab3 != null) ? prefab3.GetComponent<Piece>() : null);
			if ((Object)(object)val3 != (Object)null)
			{
				component.m_placeEffect = val3.m_placeEffect;
			}
			if ((Object)(object)_clone.GetComponent<Container>() == (Object)null)
			{
				Container val4 = _clone.AddComponent<Container>();
				GameObject prefab4 = PrefabManager.Instance.GetPrefab("piece_chest_blackmetal");
				Container val5 = ((prefab4 != null) ? prefab4.GetComponent<Container>() : null);
				if ((Object)(object)val5 != (Object)null)
				{
					val4.m_bkg = val5.m_bkg;
					val4.m_destroyedLootPrefab = val5.m_destroyedLootPrefab;
					val4.m_privacy = val5.m_privacy;
					val4.m_checkGuardStone = val5.m_checkGuardStone;
				}
				val4.m_name = "$armory_rack_name";
				val4.m_width = 8;
				val4.m_height = 4;
				Logger.LogInfo((object)string.Format("[Armory] Container access copied from {0}: privacy={1}, checkGuardStone={2}", "piece_chest_blackmetal", val4.m_privacy, val4.m_checkGuardStone));
			}
			PieceConfig val6 = new PieceConfig
			{
				Name = "Armory Rack",
				PieceTable = "_HammerPieceTable",
				Category = "Furniture"
			};
			PieceManager.Instance.AddPiece(new CustomPiece(_clone, false, val6));
			Logger.LogInfo((object)"[Armory] Phase 2 — registered armory_rack");
			EnsureInPieceTable();
			EnsureInNamedPrefabs();
			void AddReq(string prefabName, int amount)
			{
				//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_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Expected O, but got Unknown
				GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(prefabName);
				ItemDrop val7 = ((itemPrefab2 != null) ? itemPrefab2.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val7 != (Object)null)
				{
					requirements.Add(new Requirement
					{
						m_resItem = val7,
						m_amount = amount,
						m_recover = true
					});
				}
				else
				{
					Logger.LogWarning((object)("[Armory] Recipe ingredient '" + prefabName + "' not found in ObjectDB — skipped."));
				}
			}
		}

		private static void EnsureInPieceTable()
		{
			if (!((Object)(object)_clone == (Object)null))
			{
				ObjectDB instance = ObjectDB.instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject itemPrefab = instance.GetItemPrefab("Hammer");
					obj = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces);
				}
				PieceTable val = (PieceTable)obj;
				if ((Object)(object)val == (Object)null)
				{
					Logger.LogInfo((object)"[Armory] EnsureInPieceTable: Hammer not accessible yet.");
					return;
				}
				if (val.m_pieces.Contains(_clone))
				{
					Logger.LogInfo((object)"[Armory] EnsureInPieceTable: armory_rack already present.");
					return;
				}
				val.m_pieces.Add(_clone);
				Logger.LogInfo((object)"[Armory] EnsureInPieceTable: inserted armory_rack.");
			}
		}

		private static Sprite LoadEmbeddedIcon(string fileName)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_009d: 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)
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string text = Array.Find(executingAssembly.GetManifestResourceNames(), (string n) => n.EndsWith(fileName));
				if (text == null)
				{
					return null;
				}
				using Stream stream = executingAssembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					return null;
				}
				byte[] array = new byte[stream.Length];
				stream.Read(array, 0, array.Length);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!UnityLoadImage(val, array))
				{
					return null;
				}
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), (float)((Texture)val).width);
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Armory] Failed to load embedded icon '" + fileName + "': " + ex.Message));
				return null;
			}
		}

		private static bool UnityLoadImage(Texture2D tex, byte[] bytes)
		{
			try
			{
				MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[2]
				{
					typeof(Texture2D),
					typeof(byte[])
				});
				return methodInfo != null && (bool)methodInfo.Invoke(null, new object[2] { tex, bytes });
			}
			catch
			{
				return false;
			}
		}

		private static void EnsureInNamedPrefabs()
		{
			if ((Object)(object)_clone == (Object)null)
			{
				return;
			}
			Dictionary<int, GameObject> namedPrefabs = GetNamedPrefabs();
			if (namedPrefabs != null)
			{
				int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)_clone).name);
				if (!namedPrefabs.ContainsKey(stableHashCode))
				{
					namedPrefabs[stableHashCode] = _clone;
					Logger.LogInfo((object)"[Armory] EnsureInNamedPrefabs: added armory_rack.");
				}
			}
		}
	}
	public class ArmoryRack : MonoBehaviour, Hoverable, TextReceiver
	{
		private ZNetView m_nview;

		private Transform _leftHinge;

		private Transform _rightHinge;

		private float _doorAngle01;

		private const float DoorOpenRate = 4f;

		private const float DoorOpenDegrees = 95f;

		private const string NameKey = "armory_name";

		public const string DefaultName = "Armory";

		private static readonly FieldInfo _inventoryName = AccessTools.Field(typeof(Inventory), "m_name");

		private const string PrivateKey = "armory_private";

		public string RackName
		{
			get
			{
				if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
				{
					return "Armory";
				}
				string text = m_nview.GetZDO().GetString("armory_name", "");
				if (!string.IsNullOrEmpty(text))
				{
					return text;
				}
				return "Armory";
			}
		}

		public bool IsPrivate
		{
			get
			{
				if ((Object)(object)m_nview != (Object)null && m_nview.IsValid())
				{
					return m_nview.GetZDO().GetBool("armory_private", false);
				}
				return false;
			}
		}

		public long CreatorId
		{
			get
			{
				Piece component = ((Component)this).GetComponent<Piece>();
				if (!((Object)(object)component == (Object)null))
				{
					return component.GetCreator();
				}
				return 0L;
			}
		}

		public static long LocalPlayerId
		{
			get
			{
				if (!((Object)(object)Game.instance == (Object)null))
				{
					return Game.instance.GetPlayerProfile().GetPlayerID();
				}
				return 0L;
			}
		}

		public bool IsBuilder
		{
			get
			{
				long creatorId = CreatorId;
				if (creatorId != 0L)
				{
					return creatorId == LocalPlayerId;
				}
				return false;
			}
		}

		public bool CanChangePrivacy
		{
			get
			{
				if (CreatorId != 0L)
				{
					return IsBuilder;
				}
				return false;
			}
		}

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)m_nview != (Object)null)
			{
				m_nview.Register<string>("ArmoryRPC_SetData", (Action<long, string>)RPC_SetData);
				m_nview.Register<bool>("ArmoryRPC_SetPrivate", (Action<long, bool>)RPC_SetPrivate);
				m_nview.Register<string>("ArmoryRPC_SetName", (Action<long, string>)RPC_SetName);
			}
			_leftHinge = ((Component)this).transform.Find("ArmoryDoorLeft");
			_rightHinge = ((Component)this).transform.Find("ArmoryDoorRight");
		}

		public Container GetStorage()
		{
			return ((Component)this).GetComponent<Container>();
		}

		public Inventory GetStorageInventory()
		{
			Container storage = GetStorage();
			if (storage == null)
			{
				return null;
			}
			return storage.GetInventory();
		}

		private void Update()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			ApplyPrivacy();
			ApplyName();
			if (!((Object)(object)_leftHinge == (Object)null) && !((Object)(object)_rightHinge == (Object)null))
			{
				float num = ((ArmoryUI.IsOpen && (Object)(object)ArmoryUI.CurrentRack == (Object)(object)this) ? 1f : 0f);
				_doorAngle01 = Mathf.MoveTowards(_doorAngle01, num, 4f * Time.deltaTime);
				float num2 = _doorAngle01 * 95f;
				_leftHinge.localRotation = Quaternion.Euler(0f, 0f - num2, 0f);
				_rightHinge.localRotation = Quaternion.Euler(0f, num2, 0f);
			}
		}

		public string GetText()
		{
			if (!((Object)(object)m_nview != (Object)null) || !m_nview.IsValid())
			{
				return "";
			}
			return m_nview.GetZDO().GetString("armory_name", "");
		}

		public void SetText(string text)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				string text2 = (text ?? "").Trim();
				if (m_nview.IsOwner())
				{
					m_nview.GetZDO().Set("armory_name", text2);
				}
				else
				{
					m_nview.InvokeRPC("ArmoryRPC_SetName", new object[1] { text2 });
				}
				ApplyName();
				Logger.LogInfo((object)$"[Armory] Renamed to '{text2}' — isOwner={m_nview.IsOwner()}");
			}
		}

		private void RPC_SetName(long sender, string text)
		{
			if (m_nview.IsOwner())
			{
				m_nview.GetZDO().Set("armory_name", text ?? "");
			}
		}

		private void ApplyName()
		{
			Container storage = GetStorage();
			if (!((Object)(object)storage == (Object)null))
			{
				string rackName = RackName;
				if (storage.m_name != rackName)
				{
					storage.m_name = rackName;
				}
				Inventory inventory = storage.GetInventory();
				if (inventory != null && _inventoryName != null && (inventory.GetName() ?? "") != rackName)
				{
					_inventoryName.SetValue(inventory, rackName);
				}
			}
		}

		public void SetPrivate(bool value)
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				Logger.LogWarning((object)"[Armory] SetPrivate: ZNetView not valid, ignoring");
				return;
			}
			if (value && !CanChangePrivacy)
			{
				Logger.LogWarning((object)$"[Armory] SetPrivate refused: creator={CreatorId}, me={LocalPlayerId}");
				return;
			}
			if (m_nview.IsOwner())
			{
				m_nview.GetZDO().Set("armory_private", value);
			}
			else
			{
				m_nview.InvokeRPC("ArmoryRPC_SetPrivate", new object[1] { value });
			}
			ApplyPrivacy();
			Logger.LogInfo((object)$"[Armory] SetPrivate({value}) — isOwner={m_nview.IsOwner()}");
		}

		private void RPC_SetPrivate(long sender, bool value)
		{
			if (m_nview.IsOwner())
			{
				m_nview.GetZDO().Set("armory_private", value);
			}
		}

		private void ApplyPrivacy()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Container storage = GetStorage();
			if (!((Object)(object)storage == (Object)null))
			{
				PrivacySetting val = (PrivacySetting)((!IsPrivate) ? 2 : 0);
				if (storage.m_privacy != val)
				{
					storage.m_privacy = val;
				}
			}
		}

		public string GetHoverName()
		{
			return RackName;
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public string GetHoverText()
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				return string.Empty;
			}
			return LocalizeText(RackName + "\n[<color=yellow><b>$KEY_Use</b></color>] Manage Loadouts\n[<color=yellow><b>$KEY_AltPlace</b> + <b>$KEY_Use</b></color>] Rename\n" + (IsPrivate ? "<color=#ffb14e>Personal</color> <color=#aaaaaa>— only you can open it</color>" : "<color=#aaaaaa>Shared — anyone can open it</color>"));
		}

		private static string LocalizeText(string text)
		{
			try
			{
				Type type = AccessTools.TypeByName("Localization");
				if (type == null)
				{
					return text;
				}
				object obj = AccessTools.Property(type, "instance")?.GetValue(null) ?? AccessTools.Field(type, "instance")?.GetValue(null);
				if (obj == null)
				{
					return text;
				}
				return (AccessTools.Method(type, "Localize", new Type[1] { typeof(string) }, (Type[])null)?.Invoke(obj, new object[1] { text }) as string) ?? text;
			}
			catch
			{
				return text;
			}
		}

		public ArmoryData GetData()
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				Logger.LogWarning((object)"[Armory] GetData: ZNetView not valid, returning empty data");
				return new ArmoryData();
			}
			string text = m_nview.GetZDO().GetString("armory_data", "");
			Logger.LogInfo((object)$"[Armory] GetData: read {text.Length} bytes from ZDO");
			if (string.IsNullOrEmpty(text))
			{
				return new ArmoryData();
			}
			try
			{
				ArmoryData armoryData = ArmorySerializer.Deserialize(text);
				Logger.LogInfo((object)$"[Armory] GetData: parsed {armoryData.Slots.Count} slot(s)");
				return armoryData;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("[Armory] GetData parse error: " + ex.Message));
				return new ArmoryData();
			}
		}

		public void SaveData(ArmoryData data)
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				Logger.LogWarning((object)"[Armory] SaveData: ZNetView not valid, dropping save");
				return;
			}
			string text = ArmorySerializer.Serialize(data);
			if (m_nview.IsOwner())
			{
				m_nview.GetZDO().Set("armory_data", text);
				Logger.LogInfo((object)$"[Armory] SaveData: direct write ({text.Length} bytes) — isOwner=true");
			}
			else
			{
				m_nview.InvokeRPC("ArmoryRPC_SetData", new object[1] { text });
				Logger.LogInfo((object)$"[Armory] SaveData: RPC to owner ({text.Length} bytes) — isOwner=false");
			}
		}

		private void RPC_SetData(long sender, string json)
		{
			if (m_nview.IsOwner())
			{
				m_nview.GetZDO().Set("armory_data", json);
				Logger.LogInfo((object)$"[Armory] RPC_SetData: applied {json.Length} bytes");
			}
		}
	}
	[HarmonyPatch(typeof(Container), "Interact")]
	internal static class ArmoryRenamePatch
	{
		private static bool Prefix(Container __instance, Humanoid character, bool hold, bool alt, ref bool __result)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!alt || hold)
			{
				return true;
			}
			ArmoryRack component = ((Component)__instance).GetComponent<ArmoryRack>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false))
			{
				((Character)character).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null, false);
				__result = true;
				return false;
			}
			if (component.IsPrivate && !component.IsBuilder)
			{
				((Character)character).Message((MessageType)2, "$msg_cantopen", 0, (Sprite)null, false);
				__result = true;
				return false;
			}
			TextInput.instance.RequestText((TextReceiver)(object)component, "$armory_rename_topic", 32);
			__result = true;
			return false;
		}
	}
	internal static class ArmoryUI
	{
		private class SlotRowRefs
		{
			public GameObject Root;

			public GameObject NameLabelGo;

			public Text NameLabel;

			public GameObject NameInputGo;

			public InputField NameInput;

			public Button LoadButton;

			public Text LoadButtonLabel;

			public Color LoadButtonDefaultColor;

			public Button CompareButton;

			public Button SlotsButton;

			public Text SlotsButtonLabel;

			public Button MenuButton;

			public Button ClearButton;

			public Text Summary;

			public GameObject IconsContainer;

			public readonly List<IconCell> IconCells = new List<IconCell>();
		}

		private class IconCell
		{
			public Image Bg;

			public SavedItem Item;

			public bool Included;
		}

		private sealed class DragHandle : MonoBehaviour, IDragHandler, IEventSystemHandler, IEndDragHandler
		{
			public Action<Vector2> OnDrag;

			public Action OnEnd;

			void IDragHandler.OnDrag(PointerEventData e)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				OnDrag?.Invoke(e.delta);
			}

			void IEndDragHandler.OnEndDrag(PointerEventData e)
			{
				OnEnd?.Invoke();
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__Close;

			public static UnityAction <1>__OnPrivacyClicked;

			public static Func<string> <2>__PrivacyTooltip;

			public static UnityAction <3>__OnAddSlotClicked;

			public static Action<Vector2> <4>__OnResizeDrag;

			public static Action <5>__OnResizeEnd;

			public static UnityAction <6>__CloseConfirmModal;

			public static UnityAction <7>__ToggleCompareOff;
		}

		private static ArmoryRack _rack;

		private static ArmoryData _data;

		private static bool _isOpen;

		private static Vector2? _savedMainPos;

		private static Vector2? _savedComparePos;

		private static Animator _invAnimator;

		private static AnimatorUpdateMode _invAnimatorMode;

		private static float _lastIconRefresh;

		private const int DefaultSlotCount = 5;

		private const int MaxSlotCount = 10;

		private const float MaxInteractDistance = 5f;

		private static int _editingSlot = -1;

		private static int _compareSlot = -1;

		private static GameObject _mainPanel;

		private static GameObject _comparePanel;

		private static GameObject _confirmModal;

		private static RectTransform _slotsContent;

		private static readonly List<SlotRowRefs> _rows = new List<SlotRowRefs>();

		private static readonly HashSet<LoadoutSlot> _expanded = new HashSet<LoadoutSlot>();

		private const string SaveIcon = "↓";

		private const string LoadIcon = "↑";

		private const float TitleAreaPx = 70f;

		private const float FooterAreaPx = 70f;

		private const float TopRowPx = 48f;

		private const float SummaryRowPx = 22f;

		private const float IconHeaderPx = 16f;

		private const float IconLinePx = 70f;

		private const float IconLineGapPx = 2f;

		private const float RowPaddingPx = 8f;

		private const float RowSpacingPx = 2f;

		private const float ScrollListPadPx = 8f;

		private const float ScrollListGapPx = 4f;

		private static bool? _lastShowSummary;

		private static bool? _lastShowIcons;

		private static bool? _lastShowButtons;

		private static RectTransform _scrollRT;

		private static ScrollRect _scrollRect;

		private static RectTransform _scrollViewRT;

		private static RectTransform _viewportRT;

		private static RectTransform _vScrollbarRT;

		private static RectTransform _vSlidingAreaRT;

		private const float ScrollHandlePx = 10f;

		private const float ScrollBorderPx = 4f;

		private static Button _privacyButton;

		private static Text _privacyLabel;

		private const float IconSize = 48f;

		private const float CellSpacingPx = 3f;

		private const float GroupSpacingPx = 10f;

		private static GameObject _toastGo;

		private static Text _toastText;

		private static float _toastUntil;

		private const float ToastSeconds = 2.5f;

		private const float MinPanelHeight = 320f;

		private static float _lastReflow;

		private static Sprite _gripSprite;

		private static GameObject _menuGo;

		private static RectTransform _menuRT;

		private static int _menuSlot = -1;

		private static Sprite _menuSprite;

		private static GameObject _tooltipGo;

		private static Text _tooltipText;

		private static RectTransform _tooltipRT;

		public static bool IsOpen => _isOpen;

		public static ArmoryRack CurrentRack => _rack;

		public static bool IsEditing
		{
			get
			{
				if (_isOpen)
				{
					return _editingSlot >= 0;
				}
				return false;
			}
		}

		private static bool ShowRowButtons => ArmoryMod.ShowRowButtons?.Value ?? false;

		private static float MinPanelWidth
		{
			get
			{
				if (!ShowRowButtons)
				{
					return 440f;
				}
				return 520f;
			}
		}

		private static float PanelWidth => Mathf.Clamp(ArmoryMod.PanelWidth?.Value ?? 760f, MinPanelWidth, Mathf.Max(MinPanelWidth, (float)Screen.width));

		private static float IconStripAvailableWidth => PanelWidth - 104f;

		public static void Open(ArmoryRack rack)
		{
			if (_isOpen)
			{
				CloseInternal(hideInventory: false);
			}
			_rack = rack;
			_data = rack.GetData();
			if (!_data.Saved)
			{
				LoadoutManager.EnsureSlots(_data, 5);
			}
			Logger.LogInfo((object)$"[Armory] Open: rack instance {((Object)rack).GetInstanceID()}, slots loaded={_data.Slots.Count}");
			for (int i = 0; i < _data.Slots.Count; i++)
			{
				Logger.LogInfo((object)$"[Armory]   slot {i}: name='{_data.Slots[i].Name}' empty={_data.Slots[i].IsEmpty()}");
			}
			_editingSlot = -1;
			_compareSlot = -1;
			_isOpen = true;
			BuildUI();
			LoadoutManager.MigrateOutOfBoundsItems(rack.GetStorageInventory());
		}

		public static void Close()
		{
			CloseInternal(hideInventory: true);
		}

		private static void CloseInternal(bool hideInventory)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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)
			CloseRowMenu();
			_isOpen = false;
			_editingSlot = -1;
			_compareSlot = -1;
			if ((Object)(object)_mainPanel != (Object)null)
			{
				RectTransform component = _mainPanel.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					_savedMainPos = component.anchoredPosition;
					if (ArmoryMod.PanelPosX != null)
					{
						ArmoryMod.PanelPosX.Value = component.anchoredPosition.x;
					}
					if (ArmoryMod.PanelPosY != null)
					{
						ArmoryMod.PanelPosY.Value = component.anchoredPosition.y;
					}
				}
				Object.Destroy((Object)(object)_mainPanel);
				_mainPanel = null;
			}
			if ((Object)(object)_tooltipGo != (Object)null)
			{
				Object.Destroy((Object)(object)_tooltipGo);
				_tooltipGo = null;
				_tooltipText = null;
				_tooltipRT = null;
			}
			CloseConfirmModal();
			if ((Object)(object)_comparePanel != (Object)null)
			{
				RectTransform component2 = _comparePanel.GetComponent<RectTransform>();
				if ((Object)(object)component2 != (Object)null)
				{
					_savedComparePos = component2.anchoredPosition;
				}
				Object.Destroy((Object)(object)_comparePanel);
				_comparePanel = null;
			}
			_slotsContent = null;
			_privacyButton = null;
			_privacyLabel = null;
			_rows.Clear();
			_lastShowSummary = null;
			_lastShowIcons = null;
			_rack = null;
			if (hideInventory && (Object)(object)InventoryGui.instance != (Object)null)
			{
				InventoryGui.instance.Hide();
			}
			ArmoryPause.Release();
		}

		internal static void SetInventoryGuiUnscaled(bool unscaled)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (unscaled)
			{
				_invAnimator = (((Object)(object)InventoryGui.instance != (Object)null) ? ((Component)InventoryGui.instance).GetComponent<Animator>() : null);
				if ((Object)(object)_invAnimator == (Object)null)
				{
					Logger.LogWarning((object)"[Armory] No Animator on InventoryGui — the inventory panels may sit in the wrong place while paused.");
					return;
				}
				_invAnimatorMode = _invAnimator.updateMode;
				_invAnimator.updateMode = (AnimatorUpdateMode)2;
			}
			else if ((Object)(object)_invAnimator != (Object)null)
			{
				_invAnimator.updateMode = _invAnimatorMode;
				_invAnimator = null;
			}
		}

		public static void Tick()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			TickToast();
			if (!_isOpen)
			{
				return;
			}
			TickWheel();
			if ((Object)(object)_menuGo != (Object)null)
			{
				if (Input.GetKeyDown((KeyCode)27))
				{
					CloseRowMenu();
					return;
				}
				if ((Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) && !RectTransformUtility.RectangleContainsScreenPoint(_menuRT, Vector2.op_Implicit(Input.mousePosition), MenuCamera()))
				{
					CloseRowMenu();
				}
			}
			if ((Object)(object)_confirmModal != (Object)null && Input.GetKeyDown((KeyCode)27))
			{
				CloseConfirmModal();
				return;
			}
			if ((Object)(object)InventoryGui.instance == (Object)null || !InventoryGui.IsVisible())
			{
				Close();
				return;
			}
			if (_editingSlot >= 0 && (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271)))
			{
				CommitPendingEdit();
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)_rack == (Object)null)
			{
				Close();
				return;
			}
			if (Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_rack).transform.position) > 5f)
			{
				((Character)localPlayer).Message((MessageType)2, "Moved too far from the Armory Rack.", 0, (Sprite)null, false);
				Close();
				return;
			}
			bool flag = ArmoryMod.ShowSummaryText?.Value ?? true;
			bool flag2 = ArmoryMod.ShowIcons?.Value ?? true;
			if (_lastShowSummary != flag || _lastShowIcons != flag2)
			{
				_lastShowSummary = flag;
				_lastShowIcons = flag2;
				ResizeMainPanel();
			}
			if (_lastShowButtons != ShowRowButtons)
			{
				_lastShowButtons = ShowRowButtons;
				RebuildSlotRows();
			}
			for (int i = 0; i < _rows.Count && i < _data.Slots.Count; i++)
			{
				SlotRowRefs slotRowRefs = _rows[i];
				LoadoutSlot slot = _data.Slots[i];
				UpdateRowEmptyState(slotRowRefs, slot);
				if ((Object)(object)slotRowRefs.Summary != (Object)null)
				{
					slotRowRefs.Summary.text = BuildSummary(slot);
					if (((Component)slotRowRefs.Summary).gameObject.activeSelf != flag)
					{
						((Component)slotRowRefs.Summary).gameObject.SetActive(flag);
					}
				}
				if ((Object)(object)slotRowRefs.IconsContainer != (Object)null && slotRowRefs.IconsContainer.activeSelf != flag2)
				{
					slotRowRefs.IconsContainer.SetActive(flag2);
				}
			}
			if (flag2 && Time.unscaledTime - _lastIconRefresh > 0.5f)
			{
				_lastIconRefresh = Time.unscaledTime;
				for (int j = 0; j < _rows.Count && j < _data.Slots.Count; j++)
				{
					RefreshIconColors(_rows[j]);
				}
			}
		}

		private static void BuildUI()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			if (GUIManager.Instance != null && !((Object)(object)GUIManager.CustomGUIFront == (Object)null))
			{
				Transform transform = GUIManager.CustomGUIFront.transform;
				_lastShowButtons = ShowRowButtons;
				Vector2 val = (Vector2)(((??)_savedMainPos) ?? new Vector2(ArmoryMod.PanelPosX?.Value ?? 380f, ArmoryMod.PanelPosY?.Value ?? 0f));
				_mainPanel = GUIManager.Instance.CreateWoodpanel(transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), val, PanelWidth, PanelHeightOrAuto(), true);
				BuildMainPanel(_mainPanel.transform);
			}
		}

		private static void BuildMainPanel(Transform panel)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_00b7: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: 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_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Expected O, but got Unknown
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Expected O, but got Unknown
			Text component = GUIManager.Instance.CreateText(((Object)(object)_rack != (Object)null) ? _rack.RackName : "Armory", panel, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -32f), GUIManager.Instance.AveriaSerifBold, 24, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false).GetComponent<Text>();
			if ((Object)(object)component != (Object)null)
			{
				component.alignment = (TextAnchor)4;
			}
			ButtonClickedEvent onClick = GUIManager.Instance.CreateButton("x", panel, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-32f, -32f), 36f, 36f).GetComponent<Button>().onClick;
			object obj = <>O.<0>__Close;
			if (obj == null)
			{
				UnityAction val = Close;
				<>O.<0>__Close = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			GameObject obj2 = GUIManager.Instance.CreateButton("Shared", panel, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(66f, -32f), 100f, 36f);
			_privacyButton = obj2.GetComponent<Button>();
			_privacyLabel = obj2.GetComponentInChildren<Text>();
			ButtonClickedEvent onClick2 = _privacyButton.onClick;
			object obj3 = <>O.<1>__OnPrivacyClicked;
			if (obj3 == null)
			{
				UnityAction val2 = OnPrivacyClicked;
				<>O.<1>__OnPrivacyClicked = val2;
				obj3 = (object)val2;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj3);
			AttachTooltip(obj2, PrivacyTooltip);
			RefreshPrivacyButton();
			GUIManager instance = GUIManager.Instance;
			ColorBlock val3 = default(ColorBlock);
			((ColorBlock)(ref val3)).normalColor = new Color(0.5f, 0.4f, 0.2f, 0.8f);
			((ColorBlock)(ref val3)).highlightedColor = new Color(0.7f, 0.55f, 0.25f, 0.9f);
			((ColorBlock)(ref val3)).pressedColor = new Color(0.4f, 0.3f, 0.15f, 1f);
			((ColorBlock)(ref val3)).selectedColor = new Color(0.6f, 0.5f, 0.2f, 0.9f);
			((ColorBlock)(ref val3)).disabledColor = new Color(0.3f, 0.25f, 0.15f, 0.5f);
			((ColorBlock)(ref val3)).colorMultiplier = 1f;
			((ColorBlock)(ref val3)).fadeDuration = 0.1f;
			GameObject val4 = instance.CreateScrollView(panel, false, true, 10f, 4f, val3, new Color(0.04f, 0.04f, 0.04f, 0.6f), PanelWidth - 60f, PanelHeightOrAuto() - 70f - 70f);
			RectTransform component2 = val4.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.5f, 0.5f);
			component2.anchorMax = new Vector2(0.5f, 0.5f);
			component2.anchoredPosition = new Vector2(0f, 10f);
			_scrollRT = component2;
			Transform obj4 = ((Transform)component2).Find("Scroll View");
			_scrollViewRT = (RectTransform)(object)((obj4 is RectTransform) ? obj4 : null);
			RectTransform scrollViewRT = _scrollViewRT;
			Transform obj5 = ((scrollViewRT != null) ? ((Transform)scrollViewRT).Find("Viewport") : null);
			_viewportRT = (RectTransform)(object)((obj5 is RectTransform) ? obj5 : null);
			RectTransform scrollViewRT2 = _scrollViewRT;
			Transform obj6 = ((scrollViewRT2 != null) ? ((Transform)scrollViewRT2).Find("Scrollbar Vertical") : null);
			_vScrollbarRT = (RectTransform)(object)((obj6 is RectTransform) ? obj6 : null);
			RectTransform vScrollbarRT = _vScrollbarRT;
			Transform obj7 = ((vScrollbarRT != null) ? ((Transform)vScrollbarRT).Find("Sliding Area") : null);
			_vSlidingAreaRT = (RectTransform)(object)((obj7 is RectTransform) ? obj7 : null);
			ScrollRect componentInChildren = val4.GetComponentInChildren<ScrollRect>();
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.content == (Object)null)
			{
				Logger.LogError((object)"[Armory] CreateScrollView did not yield a ScrollRect with content.");
				return;
			}
			ScrollRect[] componentsInChildren = val4.GetComponentsInChildren<ScrollRect>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].scrollSensitivity = 0f;
			}
			_scrollRect = componentInChildren;
			RectTransform content = componentInChildren.content;
			LayoutGroup[] components = ((Component)content).GetComponents<LayoutGroup>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components[i]);
			}
			VerticalLayoutGroup obj8 = ((Component)content).gameObject.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj8).spacing = 4f;
			((LayoutGroup)obj8).padding = new RectOffset(4, 4, 4, 4);
			((HorizontalOrVerticalLayoutGroup)obj8).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj8).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj8).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj8).childControlHeight = true;
			if ((Object)(object)((Component)content).GetComponent<ContentSizeFitter>() == (Object)null)
			{
				((Component)content).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			}
			_slotsContent = content;
			ButtonClickedEvent onClick3 = GUIManager.Instance.CreateButton("+ Add Slot", panel, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 36f), 180f, 40f).GetComponent<Button>().onClick;
			object obj9 = <>O.<3>__OnAddSlotClicked;
			if (obj9 == null)
			{
				UnityAction val5 = OnAddSlotClicked;
				<>O.<3>__OnAddSlotClicked = val5;
				obj9 = (object)val5;
			}
			((UnityEvent)onClick3).AddListener((UnityAction)obj9);
			BuildResizeGrip(panel);
			RebuildSlotRows();
		}

		private static string PrivacyTooltip()
		{
			if ((Object)(object)_rack == (Object)null)
			{
				return string.Empty;
			}
			if (_rack.CreatorId == 0L)
			{
				return "Valheim has no record of who built this rack, and its personal setting is enforced by comparing against the builder — so it cannot be made personal without locking everyone out. Build a new rack to use this.";
			}
			if (!_rack.IsBuilder)
			{
				return "Only the player who built this rack can change this.";
			}
			if (!_rack.IsPrivate)
			{
				return "Anyone can open this rack. Click to make it yours alone.";
			}
			return "Only you can open this rack. Click to share it with everyone.";
		}

		private static void OnPrivacyClicked()
		{
			if (!((Object)(object)_rack == (Object)null))
			{
				Logger.LogInfo((object)($"[Armory] Privacy click: creator={_rack.CreatorId}, me={ArmoryRack.LocalPlayerId}, " + $"isBuilder={_rack.IsBuilder}, canChange={_rack.CanChangePrivacy}, isPrivate={_rack.IsPrivate}"));
				if (_rack.CanChangePrivacy)
				{
					_rack.SetPrivate(!_rack.IsPrivate);
					RefreshPrivacyButton();
				}
			}
		}

		private static void RefreshPrivacyButton()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_privacyButton == (Object)null) && !((Object)(object)_rack == (Object)null))
			{
				Logger.LogInfo((object)$"[Armory] Privacy state: private={_rack.IsPrivate}, creator={_rack.CreatorId}, me={ArmoryRack.LocalPlayerId}, canChange={_rack.CanChangePrivacy}");
				bool isPrivate = _rack.IsPrivate;
				bool canChangePrivacy = _rack.CanChangePrivacy;
				if ((Object)(object)_privacyLabel != (Object)null)
				{
					_privacyLabel.text = (isPrivate ? "Personal" : "Shared");
					((Graphic)_privacyLabel).color = (isPrivate ? GUIManager.Instance.ValheimOrange : Color.white);
				}
				((Selectable)_privacyButton).interactable = canChangePrivacy;
			}
		}

		private static void RebuildSlotRows()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_slotsContent == (Object)null)
			{
				return;
			}
			foreach (Transform item in (Transform)_slotsContent)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			_rows.Clear();
			for (int i = 0; i < _data.Slots.Count; i++)
			{
				_rows.Add(BuildSlotRow(i));
			}
		}

		private static SlotRowRefs BuildSlotRow(int index)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00e2: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_0191: 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)
			//IL_0202: Expected O, but got Unknown
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0525: Unknown result type (might be due to invalid IL or missing references)
			//IL_052f: Expected O, but got Unknown
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Expected O, but got Unknown
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Expected O, but got Unknown
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0578: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_059f: Expected O, but got Unknown
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0609: Unknown result type (might be due to invalid IL or missing references)
			//IL_061e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_0652: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Expected O, but got Unknown
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Expected O, but got Unknown
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Expected O, but got Unknown
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			LoadoutSlot loadoutSlot = _data.Slots[index];
			SlotRowRefs slotRowRefs = new SlotRowRefs();
			GameObject val = new GameObject($"SlotRow_{index}", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)_slotsContent, false);
			VerticalLayoutGroup obj = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 2f;
			((LayoutGroup)obj).padding = new RectOffset(6, 6, 4, 4);
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((Graphic)val.AddComponent<Image>()).color = ((index % 2 == 0) ? new Color(0.2f, 0.15f, 0.08f, 0.55f) : new Color(0.13f, 0.1f, 0.06f, 0.55f));
			val.AddComponent<LayoutElement>().minHeight = 60f;
			GameObject val2 = new GameObject("Top", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(val.transform, false);
			HorizontalLayoutGroup obj2 = val2.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((LayoutGroup)obj2).childAlignment = (TextAnchor)3;
			val2.AddComponent<LayoutElement>().preferredHeight = 48f;
			(GameObject, Text) tuple = AddText(val2.transform, loadoutSlot.Name, 16, 200f, 44f, GUIManager.Instance.ValheimOrange, leftAlign: true, richText: true);
			slotRowRefs.NameLabel = tuple.Item2;
			(slotRowRefs.NameLabelGo, _) = tuple;
			if ((Object)(object)slotRowRefs.NameLabel != (Object)null)
			{
				((Graphic)slotRowRefs.NameLabel).raycastTarget = true;
			}
			Button obj3 = tuple.Item1.AddComponent<Button>();
			int capturedNameIdx = index;
			((UnityEvent)obj3.onClick).AddListener((UnityAction)delegate
			{
				OnNameClicked(capturedNameIdx);
			});
			ColorBlock colors = ((Selectable)obj3).colors;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.95f, 0.75f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(1f, 0.85f, 0.55f, 1f);
			((Selectable)obj3).colors = colors;
			GameObject val3 = GUIManager.Instance.CreateInputField(val2.transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), Vector2.zero, (ContentType)0, "", 14, 200f, 44f);
			slotRowRefs.NameInput = val3.GetComponent<InputField>();
			slotRowRefs.NameInputGo = val3;
			LayoutElement obj4 = val3.GetComponent<LayoutElement>() ?? val3.AddComponent<LayoutElement>();
			obj4.preferredWidth = 200f;
			obj4.preferredHeight = 44f;
			val3.SetActive(false);
			GameObject val4 = new GameObject("Spacer", new Type[1] { typeof(RectTransform) });
			val4.transform.SetParent(val2.transform, false);
			LayoutElement obj5 = val4.AddComponent<LayoutElement>();
			obj5.flexibleWidth = 1f;
			obj5.minWidth = 0f;
			if (ShowRowButtons)
			{
				AttachTooltip(AddRowButton(val2.transform, "↓", 44f, (UnityAction)delegate
				{
					OnSaveClicked(index);
				}), "Save");
				GameObject val5 = AddRowButton(val2.transform, "↑", 44f, (UnityAction)delegate
				{
					OnLoadClicked(index);
				});
				AttachTooltip(val5, "Load");
				slotRowRefs.LoadButton = val5.GetComponent<Button>();
				slotRowRefs.LoadButtonLabel = val5.GetComponentInChildren<Text>();
				slotRowRefs.LoadButtonDefaultColor = (((Object)(object)slotRowRefs.LoadButtonLabel != (Object)null) ? ((Graphic)slotRowRefs.LoadButtonLabel).color : Color.white);
				GameObject val6 = AddRowButton(val2.transform, "+", 44f, (UnityAction)delegate
				{
					OnSlotsToggled(index);
				});
				AttachTooltip(val6, () => SlotsTooltip(index));
				slotRowRefs.SlotsButton = val6.GetComponent<Button>();
				slotRowRefs.SlotsButtonLabel = val6.GetComponentInChildren<Text>();
				GameObject val7 = AddRowButton(val2.transform, "Cmp", 75f, (UnityAction)delegate
				{
					OnCompareClicked(index);
				});
				slotRowRefs.CompareButton = val7.GetComponent<Button>();
				GameObject val8 = AddRowButton(val2.transform, "x", 50f, (UnityAction)delegate
				{
					OnClearClicked(index);
				});
				slotRowRefs.ClearButton = val8.GetComponent<Button>();
				Text componentInChildren = val8.GetComponentInChildren<Text>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((Graphic)componentInChildren).color = new Color(0.95f, 0.35f, 0.35f);
				}
				ColorBlock colors2 = ((Selectable)slotRowRefs.ClearButton).colors;
				((ColorBlock)(ref colors2)).highlightedColor = new Color(0.85f, 0.2f, 0.2f, 1f);
				((ColorBlock)(ref colors2)).pressedColor = new Color(0.65f, 0.12f, 0.12f, 1f);
				((Selectable)slotRowRefs.ClearButton).colors = colors2;
			}
			else
			{
				GameObject val9 = AddRowButton(val2.transform, "Equip", 76f, (UnityAction)delegate
				{
					OnLoadClicked(index);
				});
				AttachTooltip(val9, "Load this loadout");
				slotRowRefs.LoadButton = val9.GetComponent<Button>();
				slotRowRefs.LoadButtonLabel = val9.GetComponentInChildren<Text>();
				slotRowRefs.LoadButtonDefaultColor = (((Object)(object)slotRowRefs.LoadButtonLabel != (Object)null) ? ((Graphic)slotRowRefs.LoadButtonLabel).color : Color.white);
				GameObject val10 = AddRowButton(val2.transform, "", 44f, (UnityAction)delegate
				{
					OnMenuClicked(index);
				});
				AttachTooltip(val10, "Save, Compare, Delete, show all cells");
				GameObject val11 = new GameObject("Bars", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(Image)
				});
				val11.transform.SetParent(val10.transform, false);
				RectTransform component = val11.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = new Vector2(11f, 11f);
				component.offsetMax = new Vector2(-11f, -11f);
				Image component2 = val11.GetComponent<Image>();
				component2.sprite = MenuSprite();
				((Graphic)component2).color = GUIManager.Instance.ValheimOrange;
				((Graphic)component2).raycastTarget = false;
				slotRowRefs.MenuButton = val10.GetComponent<Button>();
			}
			(GameObject, Text) tuple3 = AddText(val.transform, BuildSummary(loadoutSlot), 12, 480f, 22f, new Color(0.78f, 0.72f, 0.58f), leftAlign: true, richText: true);
			slotRowRefs.Summary = tuple3.Item2;
			SetHeight(tuple3.Item1, 22f);
			if ((Object)(object)slotRowRefs.Summary != (Object)null)
			{
				slotRowRefs.Summary.horizontalOverflow = (HorizontalWrapMode)0;
				slotRowRefs.Summary.verticalOverflow = (VerticalWrapMode)0;
			}
			slotRowRefs.IconsContainer = BuildIconsStrip();
			slotRowRefs.IconsContainer.transform.SetParent(val.transform, false);
			PopulateIcons(slotRowRefs, loadoutSlot, index);
			slotRowRefs.Root = val;
			UpdateRowEditState(slotRowRefs, index);
			UpdateRowEmptyState(slotRowRefs, _data.Slots[index]);
			return slotRowRefs;
		}

		private static float GroupWidth(int cells)
		{
			cells = Mathf.Max(1, cells);
			return (float)cells * 48f + (float)(cells - 1) * 3f;
		}

		private static List<LoadoutCategories.Entry> VisibleEntries(LoadoutSlot slot, List<LoadoutCategories.Entry> entries)
		{
			bool expanded = _expanded.Contains(slot);
			return entries.Where((LoadoutCategories.Entry e) => (e.Item != null || e.Worn) && (expanded || e.Included)).ToList();
		}

		private static List<List<LoadoutCategory>> PlanIconLines(LoadoutSlot slot)
		{
			List<List<LoadoutCategory>> list = new List<List<LoadoutCategory>>();
			if (slot == null)
			{
				list.Add(new List<LoadoutCategory>
				{
					LoadoutCategory.Armor,
					LoadoutCategory.Cape
				});
				return list;
			}
			List<LoadoutCategories.Entry> source = VisibleEntries(slot, LoadoutCategories.Entries(slot));
			List<LoadoutCategory> list2 = new List<LoadoutCategory>();
			float num = 0f;
			float iconStripAvailableWidth = IconStripAvailableWidth;
			LoadoutCategory[] order = LoadoutCategories.Order;
			foreach (LoadoutCategory cat in order)
			{
				int num2 = source.Count((LoadoutCategories.Entry e) => e.Category == cat);
				if (num2 != 0)
				{
					float num3 = GroupWidth(num2);
					if (list2.Count > 0 && num + 10f + num3 > iconStripAvailableWidth)
					{
						list.Add(list2);
						list2 = new List<LoadoutCategory>();
						num = 0f;
					}
					num += ((list2.Count > 0) ? 10f : 0f) + num3;
					list2.Add(cat);
				}
			}
			if (list2.Count > 0)
			{
				list.Add(list2);
			}
			if (list.Count == 0)
			{
				list.Add(new List<LoadoutCategory>());
			}
			return list;
		}

		private static GameObject BuildIconsStrip()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			GameObject val = new GameObject("Icons", new Type[1] { typeof(RectTransform) });
			VerticalLayoutGroup obj = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 2f;
			((LayoutGroup)obj).padding = new RectOffset(0, 0, 0, 0);
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((LayoutGroup)obj).childAlignment = (TextAnchor)0;
			val.AddComponent<LayoutElement>().preferredHeight = 70f;
			return val;
		}

		private static float IconStripHeight(LoadoutSlot slot)
		{
			int count = PlanIconLines(slot).Count;
			return (float)count * 70f + (float)(count - 1) * 2f;
		}

		private static void PopulateIcons(SlotRowRefs refs, LoadoutSlot slot, int index)
		{
			if ((Object)(object)refs?.IconsContainer == (Object)null)
			{
				return;
			}
			refs.IconCells.Clear();
			Transform transform = refs.IconsContainer.transform;
			Player localPlayer = Player.m_localPlayer;
			Inventory playerInv = ((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null);
			Inventory rackInv = _rack?.GetStorageInventory();
			List<LoadoutCategories.Entry> visible = VisibleEntries(slot, LoadoutCategories.Entries(slot));
			LayoutElement component = refs.IconsContainer.GetComponent<LayoutElement>();
			if ((Object)(object)component != (Object)null)
			{
				component.preferredHeight = IconStripHeight(slot);
			}
			foreach (List<LoadoutCategory> item in PlanIconLines(slot))
			{
				AddIconLine(transform, item, visible, slot, index, refs, playerInv, rackInv);
			}
		}

		private static void AddIconLine(Transform parent, List<LoadoutCategory> categories, List<LoadoutCategories.Entry> visible, LoadoutSlot slot, int index, SlotRowRefs refs, Inventory playerInv, Inventory rackInv)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("IconLine", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 10f;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((LayoutGroup)obj).padding = new RectOffset(4, 4, 2, 2);
			((LayoutGroup)obj).childAlignment = (TextAnchor)6;
			val.AddComponent<LayoutElement>().preferredHeight = 70f;
			if (categories.Count == 0)
			{
				(GameObject, Text) tuple = AddText(val.transform, "nothing in this loadout — press + to add cells", 12, 0f, 48f, new Color(0.45f, 0.42f, 0.38f), leftAlign: true);
				(tuple.Item1.GetComponent<LayoutElement>() ?? tuple.Item1.AddComponent<LayoutElement>()).preferredHeight = 48f;
				return;
			}
			foreach (LoadoutCategory cat in categories)
			{
				AddIconGroup(val.transform, cat, visible.Where((LoadoutCategories.Entry e) => e.Category == cat).ToList(), slot, index, refs, playerInv, rackInv);
			}
		}

		private static void AddIconGroup(Transform parent, LoadoutCategory cat, List<LoadoutCategories.Entry> members, LoadoutSlot slot, int index, SlotRowRefs refs, Inventory playerInv, Inventory rackInv)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Expected O, but got Unknown
			(int total, int included) tuple = LoadoutCategories.CategoryState(slot, cat);
			int item = tuple.total;
			int item2 = tuple.included;
			GameObject val = new GameObject($"Group_{cat}", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			VerticalLayoutGroup obj = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 2f;
			((LayoutGroup)obj).padding = new RectOffset(0, 0, 0, 0);
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((LayoutGroup)obj).childAlignment = (TextAnchor)0;
			Color color = (Color)((item2 == item) ? GUIManager.Instance.ValheimOrange : ((item2 == 0) ? new Color(0.45f, 0.42f, 0.38f) : new Color(0.8f, 0.62f, 0.35f)));
			(GameObject, Text) tuple2 = AddText(val.transform, LoadoutCategories.Label(cat), 11, 0f, 16f, color, leftAlign: true);
			LayoutElement obj2 = tuple2.Item1.GetComponent<LayoutElement>() ?? tuple2.Item1.AddComponent<LayoutElement>();
			obj2.preferredHeight = 16f;
			obj2.minWidth = 48f;
			if ((Object)(object)tuple2.Item2 != (Object)null)
			{
				((Graphic)tuple2.Item2).raycastTarget = true;
			}
			Button obj3 = tuple2.Item1.AddComponent<Button>();
			((UnityEvent)obj3.onClick).AddListener((UnityAction)delegate
			{
				OnCategoryToggled(index, cat);
			});
			ColorBlock colors = ((Selectable)obj3).colors;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.95f, 0.75f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(1f, 0.85f, 0.55f, 1f);
			((Selectable)obj3).colors = colors;
			AttachTooltip(tuple2.Item1, () => CategoryTooltip(index, cat));
			GameObject val2 = new GameObject("Cells", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(val.transform, false);
			HorizontalLayoutGroup obj4 = val2.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj4).spacing = 3f;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true;
			((LayoutGroup)obj4).childAlignment = (TextAnchor)3;
			val2.AddComponent<LayoutElement>().preferredHeight = 48f;
			foreach (LoadoutCategories.Entry member in members)
			{
				AddIcon(val2.transform, member, index, refs, playerInv, rackInv);
			}
		}

		private static string CategoryTooltip(int index, LoadoutCategory cat)
		{
			if (index < 0 || index >= _data.Slots.Count)
			{
				return string.Empty;
			}
			(int total, int included) tuple = LoadoutCategories.CategoryState(_data.Slots[index], cat);
			int item = tuple.total;
			int item2 = tuple.included;
			string text = LoadoutCategories.Label(cat);
			if (item2 == item)
			{
				return text + ": all in this loadout.\nClick to leave the whole group out.";
			}
			if (item2 == 0)
			{
				return text + ": none in this loadout.\nClick to add the whole group.";
			}
			return $"{text}: {item2} of {item} in this loadout.\nClick to add the rest.";
		}

		private static void AddIcon(Transform parent, LoadoutCategories.Entry entry, int index, SlotRowRefs refs, Inventory playerInv, Inventory rackInv)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			SavedItem item = entry.Item;
			bool included = entry.Included;
			GameObject val = new GameObject(item?.SharedName ?? "EmptySlot", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.preferredWidth = 48f;
			obj.preferredHeight = 48f;
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).raycastTarget = true;
			IconCell iconCell = new IconCell
			{
				Bg = val2,
				Item = item,
				Included = included
			};
			refs.IconCells.Add(iconCell);
			ApplyIconColor(iconCell, playerInv, rackInv);
			Button obj2 = val.AddComponent<Button>();
			((Selectable)obj2).targetGraphic = (Graphic)(object)val2;
			ColorBlock colors = ((Selectable)obj2).colors;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1.4f, 1.3f, 1.1f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(1.6f, 1.4f, 1f, 1f);
			((Selectable)obj2).colors = colors;
			LoadoutCategories.Entry captured = entry;
			((UnityEvent)obj2.onClick).AddListener((UnityAction)delegate
			{
				OnCellToggled(index, captured);
			});
			string text = (included ? "in this loadout — click to leave it out" : "not in this loadout — click to add it");
			if (item == null)
			{
				AttachTooltip(val, included ? (entry.Label + ": nothing — Load takes off whatever is worn here.\nClick to leave the slot alone.") : (entry.Label + ": nothing — " + text + "."));
				return;
			}
			GameObject val3 = new GameObject("Icon", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(val.transform, false);
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = new Vector2(2f, 2f);
			component.offsetMax = new Vector2(-2f, -2f);
			Image val4 = val3.AddComponent<Image>();
			((Graphic)val4).raycastTarget = false;
			Sprite icon = LoadoutManager.GetIcon(item);
			if ((Object)(object)icon != (Object)null)
			{
				val4.sprite = icon;
				val4.preserveAspect = true;
				((Graphic)val4).color = (Color)(included ? Color.white : new Color(1f, 1f, 1f, 0.35f));
			}
			else
			{
				((Graphic)val4).color = new Color(0.5f, 0.4f, 0.3f, included ? 0.7f : 0.25f);
			}
			AttachTooltip(val, entry.Describe() + "\n" + text);
		}

		private static void ApplyIconColor(IconCell cell, Inventory playerInv, Inventory rackInv)
		{
			//IL_004e: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)cell?.Bg == (Object)null))
			{
				float num = (cell.Included ? 1f : 0.4f);
				if (cell.Item == null)
				{
					((Graphic)cell.Bg).color = new Color(0.1f, 0.1f, 0.1f, 0.35f * num);
					return;
				}
				bool flag = LoadoutManager.IsItemAvailable(cell.Item, playerInv, rackInv);
				((Graphic)cell.Bg).color = (flag ? new Color(0.15f, 0.12f, 0.08f, 0.8f * num) : new Color(0.55f, 0.15f, 0.15f, 0.9f * num));
			}
		}

		private static void RefreshIconColors(SlotRowRefs refs)
		{
			if (refs == null || refs.IconCells.Count == 0)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			Inventory playerInv = ((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null);
			Inventory rackInv = _rack?.GetStorageInventory();
			foreach (IconCell iconCell in refs.IconCells)
			{
				ApplyIconColor(iconCell, playerInv, rackInv);
			}
		}

		private static void Notify(string text)
		{
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: 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_006d: Expected O, but got Unknown
			//IL_00a0: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			Logger.LogInfo((object)("[Armory] " + text));
			GameObject customGUIFront = GUIManager.CustomGUIFront;
			if (!_isOpen || (Object)(object)customGUIFront == (Object)null)
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false);
				}
				return;
			}
			if ((Object)(object)_toastGo == (Object)null)
			{
				_toastGo = new GameObject("ArmoryToast", new Type[1] { typeof(RectTransform) });
				_toastGo.transform.SetParent(customGUIFront.transform, false);
				RectTransform component = _toastGo.GetComponent<RectTransform>();
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0.5f, 0.5f);
				component.anchorMax = val;
				component.anchorMin = val;
				component.pivot = new Vector2(0.5f, 0.5f);
				component.anchoredPosition = new Vector2(0f, 220f);
				component.sizeDelta = new Vector2(900f, 44f);
				_toastText = _toastGo.AddComponent<Text>();
				_toastText.fontSize = 26;
				_toastText.alignment = (TextAnchor)4;
				((Graphic)_toastText).raycastTarget = false;
				_toastText.horizontalOverflow = (HorizontalWrapMode)1;
				try
				{
					GUIManager.Instance.ApplyTextStyle(_toastText, GUIManager.Instance.ValheimOrange, 16, true);
				}
				catch
				{
				}
				_toastText.fontSize = 26;
				Outline obj2 = _toastGo.GetComponent<Outline>() ?? _toastGo.AddComponent<Outline>();
				((Shadow)obj2).effectColor = Color.black;
				((Shadow)obj2).effectDistance = new Vector2(1.5f, -1.5f);
			}
			_toastText.text = text;
			((Graphic)_toastText).color = GUIManager.Instance.ValheimOrange;
			_toastGo.transform.SetAsLastSibling();
			_toastGo.SetActive(true);
			_toastUntil = Time.unscaledTime + 2.5f;
		}

		private static void TickToast()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_toastGo == (Object)null) && _toastGo.activeSelf)
			{
				float num = _toastUntil - Time.unscaledTime;
				if (num <= 0f)
				{
					_toastGo.SetActive(false);
					return;
				}
				Color color = ((Graphic)_toastText).color;
				color.a = Mathf.Clamp01(num / 0.6f);
				((Graphic)_toastText).color = color;
			}
		}

		private static float PanelHeightOrAuto()
		{
			float num = ArmoryMod.PanelHeight?.Value ?? 0f;
			if (!(num > 0f))
			{
				return ComputePanelHeight();
			}
			return Mathf.Clamp(num, 320f, (float)Screen.height * 0.95f);
		}

		private static Sprite GripSprite()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_gripSprite != (Object)null)
			{
				return _gripSprite;
			}
			Texture2D val = new Texture2D(24, 24, (TextureFormat)4, false);
			Color32[] array = (Color32[])(object)new Color32[576];
			for (int i = 0; i < 24; i++)
			{
				for (int j = 0; j < 24; j++)
				{
					int num = j + (23 - i);
					bool flag = num >= 21 && (num - 21) % 6 < 2;
					array[i * 24 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(flag ? 255u : 0u));
				}
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Object)val).hideFlags = (HideFlags)61;
			_gripSprite = Sprite.Create(val, new Rect(0f, 0f, 24f, 24f), new Vector2(0.5f, 0.5f), 100f);
			((Object)_gripSprite).hideFlags = (HideFlags)61;
			return _gripSprite;
		}

		private static void BuildResizeGrip(Transform panel)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Grip", new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image),
				typeof(DragHandle)
			});
			val.transform.SetParent(panel, false);
			RectTransform component = val.GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(1f, 0f);
			component.anchorMax = val2;
			component.anchorMin = val2;
			component.pivot = new Vector2(1f, 0f);
			component.anchoredPosition = new Vector2(-5f, 5f);
			component.sizeDelta = new Vector2(18f, 18f);
			Image component2 = val.GetComponent<Image>();
			component2.sprite = GripSprite();
			((Graphic)component2).color = new Color(1f, 0.85f, 0.45f, 0.75f);
			((Graphic)component2).raycastTarget = true;
			DragHandle component3 = val.GetComponent<DragHandle>();
			component3.OnDrag = OnResizeDrag;
			component3.OnEnd = OnResizeEnd;
		}

		private static void OnResizeDrag(Vector2 screenDelta)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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)
			if ((Object)(object)_mainPanel == (Object)null)
			{
				return;
			}
			RectTransform component = _mainPanel.GetComponent<RectTransform>();
			GameObject customGUIFront = GUIManager.CustomGUIFront;
			Canvas val = ((customGUIFront != null) ? customGUIFront.GetComponent<Canvas>() : null);
			float num = (((Object)(object)val != (Object)null && val.scaleFactor > 0f) ? val.scaleFactor : 1f);
			float x = component.sizeDelta.x;
			float y = component.sizeDelta.y;
			float num2 = Mathf.Clamp(x + screenDelta.x / num, MinPanelWidth, Mathf.Max(MinPanelWidth, (float)Screen.width / num));
			float num3 = Mathf.Clamp(y - screenDelta.y / num, 320f, Mathf.Max(320f, (float)Screen.height / num));
			if (!Mathf.Approximately(num2, x) || !Mathf.Approximately(num3, y))
			{
				component.sizeDelta = new Vector2(num2, num3);
				component.anchoredPosition += new Vector2((num2 - x) / 2f, (0f - (num3 - y)) / 2f);
				ApplyScrollViewSize(num2 - 60f, num3 - 70f - 70f);
				if (ArmoryMod.PanelWidth != null)
				{
					ArmoryMod.PanelWidth.Value = num2;
				}
				if (ArmoryMod.PanelHeight != null)
				{
					ArmoryMod.PanelHeight.Value = num3;
				}
				if (!Mathf.Approximately(num2, x) && Time.unscaledTime - _lastReflow > 0.08f)
				{
					_lastReflow = Time.unscaledTime;
					RebuildSlotRows();
				}
			}
		}

		private static void OnResizeEnd()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_mainPanel == (Object)null))
			{
				RectTransform component = _mainPanel.GetComponent<RectTransform>();
				_savedMainPos = component.anchoredPosition;
				if (ArmoryMod.PanelPosX != null)
				{
					ArmoryMod.PanelPosX.Value = component.anchoredPosition.x;
				}
				if (ArmoryMod.PanelPosY != null)
				{
					ArmoryMod.PanelPosY.Value = component.anchoredPosition.y;
				}
				Logger.LogInfo((object)$"[Armory] Panel resized to {component.sizeDelta.x:0} x {component.sizeDelta.y:0}");
				RebuildSlotRows();
			}
		}

		private static Camera MenuCamera()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			GameObject customGUIFront = GUIManager.CustomGUIFront;
			object obj;
			if (customGUIFront == null)
			{
				obj = null;
			}
			else
			{
				Canvas componentInParent = customGUIFront.GetComponentInParent<Canvas>();
				obj = ((componentInParent != null) ? componentInParent.rootCanvas : null);
			}
			Canvas val = (Canvas)obj;
			if (!((Object)(object)val != (Object)null) || (int)val.renderMode == 0)
			{
				return null;
			}
			return val.worldCamera;
		}

		private static Sprite MenuSprite()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_00e3: 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_008d: 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)
			if ((Object)(object)_menuSprite != (Object)null)
			{
				return _menuSprite;
			}
			Texture2D val = new Texture2D(24, 24, (TextureFormat)4, false);
			Color32[] array = (Color32[])(object)new Color32[576];
			for (int i = 0; i < 24; i++)
			{
				for (int j = 0; j < 24; j++)
				{
					bool flag = ((i >= 4 && i <= 6) || (i >= 10 && i <= 12) || (i >= 16 && i <= 18)) && j >= 2 && j <= 21;
					array[i * 24 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(flag ? 255u : 0u));
				}
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Object)val).hideFlags = (HideFlags)61;
			_menuSprite = Sprite.Create(val, new Rect(0f, 0f, 24f, 24f), new Vector2(0.5f, 0.5f), 100f);
			((Object)_menuSprite).hideFlags = (HideFlags)61;
			return _menuSprite;
		}

		private static void OnMenuClicked(int index)
		{
			Logger.LogInfo((object)$"[Armory] Click: menu slot {index}");
			CommitPendingEdit();
			if ((Object)(object)_menuGo != (Object)null && _menuSlot == index)
			{
				CloseRowMenu();
			}
			else if (index >= 0 && index < _rows.Count && !((Object)(object)_rows[index].MenuButton == (Object)null))
			{
				OpenRowMenu(index, ((Component)_rows[index].MenuButton).GetComponent<RectTransform>());
			}
		}

		private static void OpenRowMenu(int index, RectTransform anchor)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00eb: 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_0117: 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_0149: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			CloseRowMenu();
			GameObject customGUIFront = GUIManager.CustomGUIFront;
			if (!((Object)(object)customGUIFront == (Object)null) && index >= 0 && index < _data.Slots.Count)
			{
				LoadoutSlot loadoutSlot = _data.Slots[index];
				bool enabled = !loadoutSlot.IsEmpty();
				bool flag = _expanded.Contains(loadoutSlot);
				_menuGo = new GameObject("ArmoryRowMenu", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(Image)
				});
				_menuGo.transform.SetParent(customGUIFront.transform, false);
				_menuRT = _menuGo.GetComponent<RectTransform>();
				RectTransform menuRT = _menuRT;
				RectTransform menuRT2 = _menuRT;
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0.5f, 0.5f);
				menuRT2.anchorMax = val;
				menuRT.anchorMin = val;
				((Graphic)_menuGo.GetComponent<Image>()).color = new Color(0.07f, 0.055f, 0.04f, 0.97f);
				VerticalLayoutGroup val2 = _menuGo.AddComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)val2).spacing = 2f;
				((LayoutGroup)val2).padding = new RectOffset(6, 6, 6, 6);
				((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
				((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
				((HorizontalOrVerticalLayout