Decompiled source of ArmorSlots v0.1.1

plugins/ArmorSlots.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("ArmorSlots")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ArmorSlots")]
[assembly: AssemblyTitle("ArmorSlots")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace ArmorSlots
{
	internal static class ArmorRow
	{
		public static readonly string[] SlotNames = new string[6] { "Head", "Chest", "Legs", "Cape", "Utility", "Trinket" };

		public const int SlotCount = 6;

		private static readonly List<ItemData> Temp = new List<ItemData>();

		public static bool IsPlayerInventory(Inventory inv)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && inv != null)
			{
				return ((Humanoid)localPlayer).m_inventory == inv;
			}
			return false;
		}

		public static int SlotOf(ItemData item)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			if (item == null)
			{
				return -1;
			}
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType <= 11)
			{
				if ((int)itemType == 6)
				{
					return 0;
				}
				if ((int)itemType == 7)
				{
					return 1;
				}
				if ((int)itemType == 11)
				{
					return 2;
				}
			}
			else
			{
				if ((int)itemType == 17)
				{
					return 3;
				}
				if ((int)itemType == 18)
				{
					if (!ModConfig.IncludeUtility.Value)
					{
						return -1;
					}
					return 4;
				}
				if ((int)itemType == 24)
				{
					if (!ModConfig.IncludeTrinket.Value)
					{
						return -1;
					}
					return 5;
				}
			}
			return -1;
		}

		public static bool SlotEnabled(int slot)
		{
			if (slot >= 4 && (slot != 4 || !ModConfig.IncludeUtility.Value))
			{
				if (slot == 5)
				{
					return ModConfig.IncludeTrinket.Value;
				}
				return false;
			}
			return true;
		}

		public static ItemData Equipped(Player p, int slot)
		{
			return (ItemData)(slot switch
			{
				0 => ((Humanoid)p).m_helmetItem, 
				1 => ((Humanoid)p).m_chestItem, 
				2 => ((Humanoid)p).m_legItem, 
				3 => ((Humanoid)p).m_shoulderItem, 
				4 => ((Humanoid)p).m_utilityItem, 
				5 => ((Humanoid)p).m_trinketItem, 
				_ => null, 
			});
		}

		public static ItemData InSlot(Player p, int slot)
		{
			Inventory inventory = ((Humanoid)p).GetInventory();
			return inventory.GetItemAt(slot, inventory.GetHeight());
		}

		public static int OutOfGridCount(Inventory inv)
		{
			int height = inv.GetHeight();
			int num = 0;
			foreach (ItemData item in inv.m_inventory)
			{
				if (item.m_gridPos.y >= height)
				{
					num++;
				}
			}
			return num;
		}

		public static void ReconcileLocal()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead())
			{
				if (ModConfig.Enabled.Value)
				{
					Reconcile(localPlayer);
				}
				else
				{
					ReleaseAll(localPlayer);
				}
			}
		}

		public static bool Reconcile(Player p)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = ((Humanoid)p).GetInventory();
			int height = inventory.GetHeight();
			bool flag = false;
			Temp.Clear();
			Temp.AddRange(inventory.m_inventory);
			foreach (ItemData item in Temp)
			{
				if (item.m_gridPos.y < height)
				{
					continue;
				}
				int num = SlotOf(item);
				if (num < 0 || Equipped(p, num) != item)
				{
					Vector2i val = inventory.FindEmptySlot(false);
					if (val.x >= 0)
					{
						item.m_gridPos = val;
						flag = true;
					}
				}
			}
			Vector2i val3 = default(Vector2i);
			for (int i = 0; i < 6; i++)
			{
				if (!SlotEnabled(i))
				{
					continue;
				}
				ItemData val2 = Equipped(p, i);
				if (val2 == null || !inventory.ContainsItem(val2))
				{
					continue;
				}
				((Vector2i)(ref val3))..ctor(i, height);
				if (!(val2.m_gridPos == val3))
				{
					ItemData itemAt = inventory.GetItemAt(val3.x, val3.y);
					if (itemAt != null && itemAt != val2)
					{
						itemAt.m_gridPos = val2.m_gridPos;
					}
					val2.m_gridPos = val3;
					flag = true;
				}
			}
			if (flag)
			{
				inventory.Changed(false, false);
			}
			Temp.Clear();
			return flag;
		}

		public static void ReleaseAll(Player p)
		{
			if (!((Object)(object)p == (Object)null))
			{
				Inventory inventory = ((Humanoid)p).GetInventory();
				if (MoveIntoGrid(inventory, null))
				{
					inventory.Changed(false, false);
				}
			}
		}

		public static bool MoveIntoGrid(Inventory inv, List<KeyValuePair<ItemData, Vector2i>> undo)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			int height = inv.GetHeight();
			bool result = false;
			Temp.Clear();
			Temp.AddRange(inv.m_inventory);
			foreach (ItemData item in Temp)
			{
				if (item.m_gridPos.y >= height)
				{
					Vector2i val = inv.FindEmptySlot(false);
					if (val.x < 0)
					{
						break;
					}
					undo?.Add(new KeyValuePair<ItemData, Vector2i>(item, item.m_gridPos));
					item.m_gridPos = val;
					result = true;
				}
			}
			Temp.Clear();
			return result;
		}
	}
	internal static class EquipmentPanel
	{
		private sealed class Slot
		{
			public int Index;

			public InventoryElement Element;

			public TMP_Text Placeholder;

			public ItemData Shown;

			public bool ShownEquipped;

			public bool TooltipSet;
		}

		private const float Pad = 14f;

		private const float TitleHeight = 30f;

		private const float Gap = 8f;

		private static RectTransform _root;

		private static InventoryGui _gui;

		private static readonly Slot[] Slots = new Slot[6];

		private static int _layoutKey = -1;

		private static bool _failed;

		private static bool _dumped;

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

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

		private static readonly PanelPlacement[] AutoOrder = new PanelPlacement[3]
		{
			PanelPlacement.Right,
			PanelPlacement.Left,
			PanelPlacement.Below
		};

		public static void Refresh(InventoryGui gui)
		{
			if (_failed)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			bool flag = ModConfig.Enabled.Value && (Object)(object)localPlayer != (Object)null && InventoryGui.IsVisible() && (Object)(object)gui.m_player != (Object)null && ((Component)gui.m_player).gameObject.activeInHierarchy;
			if ((Object)(object)_root == (Object)null || (Object)(object)_gui != (Object)(object)gui)
			{
				if (!flag)
				{
					return;
				}
				Build(gui);
			}
			if (((Component)_root).gameObject.activeSelf != flag)
			{
				((Component)_root).gameObject.SetActive(flag);
			}
			if (!flag)
			{
				return;
			}
			Layout(gui);
			Slot[] slots = Slots;
			foreach (Slot slot in slots)
			{
				if (((Component)slot.Element).gameObject.activeSelf)
				{
					UpdateSlot(gui, localPlayer, slot);
				}
			}
		}

		public static void Destroy()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_root).gameObject);
			}
			_root = null;
			_gui = null;
			_layoutKey = -1;
		}

		public static void Fail(Exception e)
		{
			_failed = true;
			Plugin.Log.LogError((object)("Equipment panel failed and was turned off for this session (armor still works): " + e));
			Destroy();
		}

		private static void Build(InventoryGui gui)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: 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_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			Destroy();
			_gui = gui;
			InventoryGrid playerGrid = gui.m_playerGrid;
			GameObject val = new GameObject("ArmorSlotsPanel", new Type[1] { typeof(RectTransform) })
			{
				layer = ((Component)gui.m_player).gameObject.layer
			};
			_root = (RectTransform)val.transform;
			((Transform)_root).SetParent((Transform)(object)gui.m_player, false);
			Image val2 = val.AddComponent<Image>();
			Image val3 = FindBackground(gui.m_player);
			if ((Object)(object)val3 != (Object)null)
			{
				val2.sprite = val3.sprite;
				val2.type = val3.type;
				((Graphic)val2).color = ((Graphic)val3).color;
				((Graphic)val2).material = ((Graphic)val3).material;
				val2.pixelsPerUnitMultiplier = val3.pixelsPerUnitMultiplier;
			}
			else
			{
				((Graphic)val2).color = new Color(0.1f, 0.07f, 0.05f, 0.88f);
			}
			TMP_FontAsset font = FindFont(playerGrid);
			TMP_Text val4 = NewText("Title", (Transform)(object)_root, font, 20f, (TextAlignmentOptions)514, new Color(0.96f, 0.89f, 0.72f));
			val4.text = ((Localization.instance != null) ? Localization.instance.Localize("$inventory_equipment") : "Equipment");
			if (val4.text.StartsWith("["))
			{
				val4.text = "Equipment";
			}
			RectTransform rectTransform = val4.rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.anchoredPosition = new Vector2(0f, -8f);
			rectTransform.sizeDelta = new Vector2(0f, 30f);
			for (int i = 0; i < Slots.Length; i++)
			{
				GameObject val5 = Object.Instantiate<GameObject>(playerGrid.m_elementPrefab, (Transform)(object)_root);
				((Object)val5).name = "Slot_" + ArmorRow.SlotNames[i];
				InventoryElement component = val5.GetComponent<InventoryElement>();
				Transform val6 = val5.transform.Find("binding");
				if ((Object)(object)val6 != (Object)null)
				{
					((Component)val6).gameObject.SetActive(false);
				}
				Hide((Behaviour)(object)component.m_amount);
				Hide((Behaviour)(object)component.m_equiped);
				Hide((Behaviour)(object)component.m_queued);
				Hide((Behaviour)(object)component.m_noteleport);
				Hide((Behaviour)(object)component.m_food);
				Hide((Behaviour)(object)component.m_dropFocus);
				if ((Object)(object)component.m_selected != (Object)null)
				{
					component.m_selected.SetActive(false);
				}
				((Component)component.m_durability).gameObject.SetActive(false);
				((Behaviour)component.m_icon).enabled = false;
				TMP_Text val7 = NewText("Placeholder", val5.transform, font, 13f, (TextAlignmentOptions)514, new Color(0.76f, 0.67f, 0.52f, 0.55f));
				RectTransform rectTransform2 = val7.rectTransform;
				rectTransform2.anchorMin = Vector2.zero;
				rectTransform2.anchorMax = Vector2.one;
				rectTransform2.offsetMin = Vector2.zero;
				rectTransform2.offsetMax = Vector2.zero;
				val7.text = ArmorRow.SlotNames[i];
				int index = i;
				UIInputHandler componentInChildren = val5.GetComponentInChildren<UIInputHandler>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.m_onLeftClick = delegate
					{
						OnClick(index);
					};
					componentInChildren.m_onRightDown = delegate
					{
						OnClick(index);
					};
					componentInChildren.m_onLeftDown = null;
					componentInChildren.m_onLeftUp = null;
				}
				UIDragHandler componentInChildren2 = val5.GetComponentInChildren<UIDragHandler>();
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					((Behaviour)componentInChildren2).enabled = false;
				}
				Slots[i] = new Slot
				{
					Index = i,
					Element = component,
					Placeholder = val7
				};
			}
			if (!_dumped)
			{
				_dumped = true;
				ManualLogSource log = Plugin.Log;
				object[] obj = new object[4]
				{
					((Object)gui.m_player).name,
					null,
					null,
					null
				};
				Rect rect = gui.m_player.rect;
				obj[1] = ((Rect)(ref rect)).size;
				obj[2] = SlotSize(playerGrid);
				obj[3] = playerGrid.m_elementSpace;
				log.LogInfo((object)string.Format("Equipment panel attached to '{0}' (size {1}), slot prefab size {2}, spacing {3}.", obj));
			}
		}

		private static void Layout(InventoryGui gui)
		{
			int num = Mathf.Max(1, ModConfig.Columns.Value);
			int num2 = num | (ModConfig.IncludeUtility.Value ? 32 : 0) | (ModConfig.IncludeTrinket.Value ? 64 : 0);
			if (num2 != _layoutKey)
			{
				_layoutKey = num2;
				LayoutSlots(gui, num);
			}
			Place(gui.m_player);
		}

		private static void LayoutSlots(InventoryGui gui, int columns)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_00db: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			InventoryGrid playerGrid = gui.m_playerGrid;
			Vector2 val = SlotSize(playerGrid);
			float num = Mathf.Max(playerGrid.m_elementSpace, val.x + 4f);
			int num2 = 0;
			for (int i = 0; i < Slots.Length; i++)
			{
				if (ArmorRow.SlotEnabled(i))
				{
					num2++;
				}
			}
			columns = Mathf.Min(columns, Mathf.Max(1, num2));
			int num3 = (num2 + columns - 1) / columns;
			int num4 = 0;
			Slot[] slots = Slots;
			Vector2 val3 = default(Vector2);
			Vector2 val4 = default(Vector2);
			foreach (Slot slot in slots)
			{
				bool flag = ArmorRow.SlotEnabled(slot.Index);
				((Component)slot.Element).gameObject.SetActive(flag);
				if (flag)
				{
					int num5 = num4 % columns;
					int num6 = num4 / columns;
					num4++;
					RectTransform val2 = (RectTransform)((Component)slot.Element).transform;
					((Vector2)(ref val3))..ctor(0f, 1f);
					val2.anchorMax = val3;
					val2.anchorMin = val3;
					((Vector2)(ref val4))..ctor(14f + (float)num5 * num + val.x * 0.5f, 0f - (44f + (float)num6 * num + val.y * 0.5f));
					val2.anchoredPosition = val4 + Vector2.Scale(val2.pivot - new Vector2(0.5f, 0.5f), val);
				}
			}
			float num7 = 28f + (float)(columns - 1) * num + val.x;
			float num8 = 44f + (float)(num3 - 1) * num + val.y + 14f;
			RectTransform root = _root;
			RectTransform root2 = _root;
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			root2.anchorMax = val3;
			root.anchorMin = val3;
			_root.sizeDelta = new Vector2(num7, num8);
		}

		private static void Place(RectTransform inventory)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_010c: 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_0147: 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_006f: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = inventory.rect;
			foreach (Transform item in (Transform)inventory)
			{
				Transform val = item;
				if ((Object)(object)val == (Object)(object)_root || !((Component)val).gameObject.activeInHierarchy)
				{
					continue;
				}
				RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
				if (val2 != null)
				{
					val2.GetWorldCorners(Corners);
					Vector3[] corners = Corners;
					foreach (Vector3 val3 in corners)
					{
						Vector2 val4 = Vector2.op_Implicit(((Transform)inventory).InverseTransformPoint(val3));
						((Rect)(ref rect)).xMin = Mathf.Min(((Rect)(ref rect)).xMin, val4.x);
						((Rect)(ref rect)).xMax = Mathf.Max(((Rect)(ref rect)).xMax, val4.x);
						((Rect)(ref rect)).yMin = Mathf.Min(((Rect)(ref rect)).yMin, val4.y);
					}
				}
			}
			PanelPlacement value = ModConfig.Placement.Value;
			if (value != PanelPlacement.Auto)
			{
				Apply(inventory, rect, value);
				return;
			}
			PanelPlacement[] autoOrder = AutoOrder;
			foreach (PanelPlacement panelPlacement in autoOrder)
			{
				Apply(inventory, rect, panelPlacement);
				if (OnScreen())
				{
					return;
				}
			}
			Apply(inventory, rect, PanelPlacement.Below);
		}

		private static void Apply(RectTransform inventory, Rect content, PanelPlacement where)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = inventory.rect;
			Vector2 pivot = default(Vector2);
			Vector2 val = default(Vector2);
			switch (where)
			{
			case PanelPlacement.Left:
				((Vector2)(ref pivot))..ctor(1f, 1f);
				((Vector2)(ref val))..ctor(((Rect)(ref content)).xMin - 8f, ((Rect)(ref rect)).yMax);
				break;
			case PanelPlacement.Below:
				((Vector2)(ref pivot))..ctor(0f, 1f);
				((Vector2)(ref val))..ctor(((Rect)(ref rect)).xMin, ((Rect)(ref content)).yMin - 8f);
				break;
			default:
				((Vector2)(ref pivot))..ctor(0f, 1f);
				((Vector2)(ref val))..ctor(((Rect)(ref content)).xMax + 8f, ((Rect)(ref rect)).yMax);
				break;
			}
			_root.pivot = pivot;
			_root.anchoredPosition = val - ((Rect)(ref rect)).center + ModConfig.Offset.Value;
		}

		private static bool OnScreen()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Canvas componentInParent = ((Component)_root).GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return true;
			}
			((RectTransform)((Component)componentInParent.rootCanvas).transform).GetWorldCorners(CanvasCorners);
			_root.GetWorldCorners(Corners);
			if (Corners[0].x >= CanvasCorners[0].x - 1f && Corners[0].y >= CanvasCorners[0].y - 1f && Corners[2].x <= CanvasCorners[2].x + 1f)
			{
				return Corners[2].y <= CanvasCorners[2].y + 1f;
			}
			return false;
		}

		private static void UpdateSlot(InventoryGui gui, Player player, Slot slot)
		{
			//IL_00a2: 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_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			ItemData val = ArmorRow.InSlot(player, slot.Index);
			InventoryElement element = slot.Element;
			bool flag = val != null && ArmorRow.Equipped(player, slot.Index) == val;
			((Behaviour)element.m_icon).enabled = val != null;
			((Behaviour)slot.Placeholder).enabled = val == null;
			((Behaviour)element.m_quality).enabled = val != null && val.m_shared.m_maxQuality > 1;
			if (val != null)
			{
				element.m_icon.sprite = val.GetIcon();
				((Graphic)element.m_icon).color = (Color)(flag ? Color.white : new Color(1f, 1f, 1f, 0.45f));
				if (((Behaviour)element.m_quality).enabled)
				{
					element.m_quality.text = val.m_quality.ToString();
				}
				bool flag2 = val.m_shared.m_useDurability && val.m_durability < val.GetMaxDurability();
				((Component)element.m_durability).gameObject.SetActive(flag2);
				if (flag2)
				{
					if (val.m_durability <= 0f)
					{
						element.m_durability.SetValue(1f);
						element.m_durability.SetColor((Color)((Mathf.Sin(Time.time * 10f) > 0f) ? Color.red : new Color(0f, 0f, 0f, 0f)));
					}
					else
					{
						element.m_durability.SetValue(val.GetDurabilityPercentage());
						element.m_durability.ResetColor();
					}
				}
			}
			else
			{
				((Component)element.m_durability).gameObject.SetActive(false);
			}
			if (slot.TooltipSet && val == slot.Shown && flag == slot.ShownEquipped)
			{
				return;
			}
			slot.TooltipSet = true;
			slot.Shown = val;
			slot.ShownEquipped = flag;
			if (!((Object)(object)element.m_tooltip == (Object)null))
			{
				if (val != null)
				{
					gui.m_playerGrid.CreateItemTooltip(val, element.m_tooltip);
				}
				else
				{
					element.m_tooltip.Set(ArmorRow.SlotNames[slot.Index], "Equip a matching item, or pick one up and click here.", gui.m_playerGrid.m_tooltipAnchor, default(Vector2));
				}
			}
		}

		private static void OnClick(int index)
		{
			Player localPlayer = Player.m_localPlayer;
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null)
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			ItemData dragItem = instance.m_dragItem;
			if (dragItem != null)
			{
				if (instance.m_dragInventory != inventory)
				{
					Message("Move it into your inventory first");
					return;
				}
				if (ArmorRow.SlotOf(dragItem) != index)
				{
					Message("That doesn't go in the " + ArmorRow.SlotNames[index] + " slot");
					return;
				}
				instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
				if (!((Humanoid)localPlayer).IsItemEquiped(dragItem))
				{
					((Humanoid)localPlayer).UseItem(inventory, dragItem, true);
				}
				return;
			}
			ItemData val = ArmorRow.InSlot(localPlayer, index);
			if (val != null)
			{
				if (((Humanoid)localPlayer).IsItemEquiped(val))
				{
					((Humanoid)localPlayer).UseItem(inventory, val, true);
				}
				else
				{
					ArmorRow.ReconcileLocal();
				}
				if (ArmorRow.InSlot(localPlayer, index) == val && !((Humanoid)localPlayer).IsItemEquiped(val) && !inventory.HaveEmptySlot())
				{
					Message("$inventory_full");
				}
			}
		}

		private static void Message(string text)
		{
			MessageHud instance = MessageHud.instance;
			if (instance != null)
			{
				instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, true);
			}
		}

		private static Vector2 SlotSize(InventoryGrid grid)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = grid.m_elementPrefab.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			Vector2 val2 = (((Object)(object)val != (Object)null) ? val.sizeDelta : Vector2.zero);
			if (!(val2.x > 1f) || !(val2.y > 1f))
			{
				return new Vector2(64f, 64f);
			}
			return val2;
		}

		private static Image FindBackground(RectTransform player)
		{
			Image component = ((Component)player).GetComponent<Image>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null)
			{
				return component;
			}
			Image[] componentsInChildren = ((Component)player).GetComponentsInChildren<Image>(true);
			foreach (Image val in componentsInChildren)
			{
				string text = ((Object)val).name.ToLowerInvariant();
				if ((Object)(object)val.sprite != (Object)null && (text.Contains("bkg") || text.Contains("background") || text == "bg"))
				{
					return val;
				}
			}
			return null;
		}

		private static TMP_FontAsset FindFont(InventoryGrid grid)
		{
			TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			foreach (TMP_FontAsset val in array)
			{
				if (((Object)val).name.ToLowerInvariant().Contains("norse"))
				{
					return val;
				}
			}
			TMP_Text componentInChildren = grid.m_elementPrefab.GetComponentInChildren<TMP_Text>(true);
			if (!((Object)(object)componentInChildren != (Object)null))
			{
				return null;
			}
			return componentInChildren.font;
		}

		private static TMP_Text NewText(string name, Transform parent, TMP_FontAsset font, float size, TextAlignmentOptions align, Color color)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) })
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)font != (Object)null)
			{
				((TMP_Text)val2).font = font;
			}
			((TMP_Text)val2).fontSize = size;
			((TMP_Text)val2).alignment = align;
			((Graphic)val2).color = color;
			((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0;
			((Graphic)val2).raycastTarget = false;
			return (TMP_Text)(object)val2;
		}

		private static void Hide(Behaviour b)
		{
			if ((Object)(object)b != (Object)null)
			{
				b.enabled = false;
			}
		}
	}
	internal enum PanelPlacement
	{
		Auto,
		Right,
		Left,
		Below
	}
	internal static class ModConfig
	{
		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<bool> IncludeUtility;

		public static ConfigEntry<bool> IncludeTrinket;

		public static ConfigEntry<PanelPlacement> Placement;

		public static ConfigEntry<Vector2> Offset;

		public static ConfigEntry<int> Columns;

		public static void Bind(ConfigFile cfg)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			Enabled = cfg.Bind<bool>("1 - General", "Enabled", true, "Keep equipped armor in its own Equipment panel instead of the inventory grid. Off = everything goes back to the grid.");
			IncludeUtility = cfg.Bind<bool>("1 - General", "IncludeUtility", true, "Give the utility item (belts, Megingjord, etc.) a slot.");
			IncludeTrinket = cfg.Bind<bool>("1 - General", "IncludeTrinket", true, "Give the trinket a slot.");
			Placement = cfg.Bind<PanelPlacement>("2 - Panel", "Placement", PanelPlacement.Auto, "Where the Equipment panel goes. Auto tries right of the inventory, then left, then below, and uses the first spot that is fully on screen.");
			Offset = cfg.Bind<Vector2>("2 - Panel", "Offset", new Vector2(0f, 0f), "Extra nudge for the panel in pixels (x right, y up).");
			Columns = cfg.Bind<int>("2 - Panel", "Columns", 2, new ConfigDescription("Slots per row in the panel.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6), Array.Empty<object>()));
		}
	}
	[HarmonyPatch(typeof(Humanoid))]
	internal static class EquipPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("EquipItem")]
		private static void EquipPostfix(Humanoid __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				Safe(ArmorRow.ReconcileLocal);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("UnequipItem")]
		private static void UnequipPostfix(Humanoid __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				Safe(ArmorRow.ReconcileLocal);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("DropInvalidItems")]
		private static void DropInvalidPrefix(Humanoid __instance, out List<ItemData> __state)
		{
			__state = null;
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			Inventory inventory = __instance.GetInventory();
			int height = inventory.GetHeight();
			__state = new List<ItemData>();
			foreach (ItemData item in inventory.m_inventory)
			{
				int num = ArmorRow.SlotOf(item);
				if (item.m_gridPos.y >= height && num >= 0 && item.m_gridPos.x == num)
				{
					__state.Add(item);
				}
			}
			foreach (ItemData item2 in __state)
			{
				inventory.m_inventory.Remove(item2);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("DropInvalidItems")]
		private static void DropInvalidPostfix(Humanoid __instance, List<ItemData> __state)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (__state == null || __state.Count == 0)
			{
				return;
			}
			Inventory inventory = __instance.GetInventory();
			int height = inventory.GetHeight();
			foreach (ItemData item in __state)
			{
				item.m_gridPos = new Vector2i(item.m_gridPos.x, height);
				inventory.m_inventory.Add(item);
			}
			inventory.Changed(false, false);
			Safe(ArmorRow.ReconcileLocal);
		}

		internal static void Safe(Action a)
		{
			try
			{
				a();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)ex);
			}
		}
	}
	[HarmonyPatch(typeof(Inventory))]
	internal static class SpacePatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetEmptySlots")]
		private static void EmptySlots(Inventory __instance, ref int __result)
		{
			if (ArmorRow.IsPlayerInventory(__instance))
			{
				__result += ArmorRow.OutOfGridCount(__instance);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("HaveEmptySlot")]
		private static void HaveEmpty(Inventory __instance, ref bool __result)
		{
			if (!__result && ArmorRow.IsPlayerInventory(__instance))
			{
				int num = __instance.m_inventory.Count - ArmorRow.OutOfGridCount(__instance);
				__result = num < __instance.GetWidth() * __instance.GetHeight();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("CanAddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int)
		})]
		private static void CanAdd(Inventory __instance, ItemData item, int stack, ref bool __result)
		{
			if (__result || !ArmorRow.IsPlayerInventory(__instance))
			{
				return;
			}
			int num = ArmorRow.OutOfGridCount(__instance);
			if (num != 0)
			{
				if (stack <= 0)
				{
					stack = item.m_stack;
				}
				int num2 = __instance.GetWidth() * __instance.GetHeight() - (__instance.m_inventory.Count - num);
				__result = __instance.FindFreeStackSpace(item.m_shared.m_name, (float)item.m_worldLevel) + num2 * item.m_shared.m_maxStackSize >= stack;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("Save")]
		private static void SavePrefix(Inventory __instance, out List<KeyValuePair<ItemData, Vector2i>> __state)
		{
			__state = null;
			if (ArmorRow.IsPlayerInventory(__instance))
			{
				__state = new List<KeyValuePair<ItemData, Vector2i>>();
				ArmorRow.MoveIntoGrid(__instance, __state);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Save")]
		private static void SavePostfix(List<KeyValuePair<ItemData, Vector2i>> __state)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (__state == null)
			{
				return;
			}
			foreach (KeyValuePair<ItemData, Vector2i> item in __state)
			{
				item.Key.m_gridPos = item.Value;
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui))]
	internal static class GuiPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Show")]
		private static void ShowPostfix()
		{
			EquipPatches.Safe(ArmorRow.ReconcileLocal);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void UpdatePostfix(InventoryGui __instance)
		{
			try
			{
				EquipmentPanel.Refresh(__instance);
			}
			catch (Exception e)
			{
				EquipmentPanel.Fail(e);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnDestroy")]
		private static void DestroyPostfix()
		{
			EquipmentPanel.Destroy();
		}
	}
	[BepInPlugin("com.armorslots.valheim", "Armor Slots", "0.1.1")]
	[BepInProcess("valheim.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.armorslots.valheim";

		public const string ModName = "Armor Slots";

		public const string ModVersion = "0.1.1";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private float _reconcileTimer;

		private void Awake()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			ModConfig.Enabled.SettingChanged += delegate
			{
				ArmorRow.ReconcileLocal();
			};
			ModConfig.IncludeUtility.SettingChanged += delegate
			{
				ArmorRow.ReconcileLocal();
			};
			ModConfig.IncludeTrinket.SettingChanged += delegate
			{
				ArmorRow.ReconcileLocal();
			};
			_harmony = new Harmony("com.armorslots.valheim");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"Armor Slots 0.1.1 loaded (client-side only).");
		}

		private void Update()
		{
			_reconcileTimer -= Time.unscaledDeltaTime;
			if (!(_reconcileTimer > 0f))
			{
				_reconcileTimer = 1f;
				ArmorRow.ReconcileLocal();
			}
		}

		private void OnDestroy()
		{
			ArmorRow.ReleaseAll(Player.m_localPlayer);
			EquipmentPanel.Destroy();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}