Decompiled source of EquipmentSlotsModByBazilDeLyaguh v1.0.4

BepInEx/plugins/ValheimEquipmentSlotsMod.dll

Decompiled 6 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ValheimEquipmentSlotsMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValheimEquipmentSlotsMod")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("95c1d4ad-c4a7-4f4c-9af9-0c65e52c044c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MyBepInExPlugin;

[BepInPlugin("com.example.GUID", "EquipmentSlotsModByBazilDeLyaguh", "1.0.3")]
public class Main : BaseUnityPlugin
{
	private const string pluginGUID = "com.example.GUID";

	private const string pluginName = "EquipmentSlotsModByBazilDeLyaguh";

	private const string pluginVersion = "1.0.3";

	private readonly Harmony HarmonyInstance = new Harmony("com.example.GUID");

	public static ManualLogSource logger = Logger.CreateLogSource("EquipmentSlotsModByBazilDeLyaguh");

	public void Awake()
	{
		Assembly executingAssembly = Assembly.GetExecutingAssembly();
		HarmonyInstance.PatchAll(executingAssembly);
	}
}
[HarmonyPatch(typeof(InventoryGui))]
public static class InventoryGuiPatches
{
	private static List<GameObject> equipmentSlotObjects = new List<GameObject>();

	private static GameObject equipmentPanel;

	private static InventoryGrid playerGrid;

	private static FieldInfo m_helmetItemField;

	private static FieldInfo m_chestItemField;

	private static FieldInfo m_legItemField;

	private static FieldInfo m_shoulderItemField;

	private static FieldInfo m_utilityItemField;

	private static FieldInfo m_TrinketItemField;

	private static readonly ItemType[] slotTypes;

	[HarmonyPatch("UpdateInventory")]
	[HarmonyPostfix]
	public static void UpdateInventory_Postfix(InventoryGui __instance, InventoryGrid ___m_playerGrid)
	{
		if ((Object)(object)___m_playerGrid != (Object)null)
		{
			playerGrid = ___m_playerGrid;
		}
		if ((Object)(object)equipmentPanel != (Object)null && equipmentSlotObjects.Count == 0)
		{
			CreateEquipmentSlots();
		}
		UpdateEquippedIcons();
	}

	[HarmonyPatch("Show")]
	[HarmonyPostfix]
	public static void Show_Postfix(InventoryGui __instance)
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			CacheFields();
			CreateEquipmentPanel(__instance);
		}
	}

	[HarmonyPatch("Hide")]
	[HarmonyPostfix]
	public static void Hide_Postfix()
	{
		if ((Object)(object)equipmentPanel != (Object)null)
		{
			Object.Destroy((Object)(object)equipmentPanel);
			equipmentPanel = null;
		}
		equipmentSlotObjects.Clear();
	}

	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	[HarmonyPrefix]
	public static void EquipItem_Prefix(Humanoid __instance, ItemData item)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		if (!(__instance is Player) || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
		{
			return;
		}
		int num = Array.IndexOf(slotTypes, item.m_shared.m_itemType);
		if (num >= 0)
		{
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			FieldInfo[] array = new FieldInfo[6] { m_helmetItemField, m_TrinketItemField, m_chestItemField, m_legItemField, m_shoulderItemField, m_utilityItemField };
			object? obj = array[num]?.GetValue(__instance);
			ItemData val = (ItemData)((obj is ItemData) ? obj : null);
			if (val != null && val != item)
			{
				__instance.UnequipItem(val, false);
				array[num]?.SetValue(__instance, null);
				inventory.AddItem(val);
			}
		}
	}

	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	[HarmonyPostfix]
	public static void EquipItem_Postfix(Humanoid __instance, ItemData item)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if (__instance is Player && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			int num = Array.IndexOf(slotTypes, item.m_shared.m_itemType);
			if (num >= 0)
			{
				Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
				inventory.RemoveItem(item, item.m_stack);
				typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(inventory, new object[0]);
			}
		}
	}

	[HarmonyPatch(typeof(PlayerProfile), "SavePlayerData")]
	[HarmonyPrefix]
	public static void SavePlayerData_Prefix(PlayerProfile __instance, Player player)
	{
		FieldInfo[] array = new FieldInfo[6] { m_helmetItemField, m_TrinketItemField, m_chestItemField, m_legItemField, m_shoulderItemField, m_utilityItemField };
		Inventory inventory = ((Humanoid)player).GetInventory();
		FieldInfo[] array2 = array;
		for (int i = 0; i < array2.Length; i++)
		{
			object? obj = array2[i]?.GetValue(player);
			ItemData val = (ItemData)((obj is ItemData) ? obj : null);
			if (val != null && !inventory.ContainsItem(val))
			{
				inventory.AddItem(val);
			}
		}
	}

	[HarmonyPatch(typeof(PlayerProfile), "SavePlayerData")]
	[HarmonyPostfix]
	public static void SavePlayerData_Postfix(PlayerProfile __instance, Player player)
	{
		FieldInfo[] array = new FieldInfo[6] { m_helmetItemField, m_TrinketItemField, m_chestItemField, m_legItemField, m_shoulderItemField, m_utilityItemField };
		Inventory inventory = ((Humanoid)player).GetInventory();
		FieldInfo[] array2 = array;
		for (int i = 0; i < array2.Length; i++)
		{
			object? obj = array2[i]?.GetValue(player);
			ItemData val = (ItemData)((obj is ItemData) ? obj : null);
			if (val != null && inventory.ContainsItem(val))
			{
				inventory.RemoveItem(val, val.m_stack);
			}
		}
	}

	[HarmonyPatch(typeof(Player), "Load")]
	[HarmonyPostfix]
	public static void Load_Postfix(Player __instance)
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		FieldInfo[] array = new FieldInfo[6] { m_helmetItemField, m_TrinketItemField, m_chestItemField, m_legItemField, m_shoulderItemField, m_utilityItemField };
		Inventory inventory = ((Humanoid)__instance).GetInventory();
		List<ItemData> allItems = inventory.GetAllItems();
		List<ItemData> list = new List<ItemData>();
		foreach (ItemData item in allItems)
		{
			if (item.m_equipped)
			{
				int num = Array.IndexOf(slotTypes, item.m_shared.m_itemType);
				if (num >= 0 && array[num]?.GetValue(__instance) == null)
				{
					list.Add(item);
				}
			}
		}
		foreach (ItemData item2 in list)
		{
			inventory.RemoveItem(item2, item2.m_stack);
			((Humanoid)__instance).EquipItem(item2, false);
		}
	}

	[HarmonyPatch(typeof(Player), "OnDeath")]
	[HarmonyPrefix]
	public static void OnDeath_Prefix(Player __instance)
	{
		FieldInfo[] array = new FieldInfo[6] { m_helmetItemField, m_TrinketItemField, m_chestItemField, m_legItemField, m_shoulderItemField, m_utilityItemField };
		Inventory inventory = ((Humanoid)__instance).GetInventory();
		FieldInfo field = typeof(Inventory).GetField("m_height", BindingFlags.Instance | BindingFlags.NonPublic);
		int num = (int)field.GetValue(inventory);
		field.SetValue(inventory, Mathf.Max(num, 6));
		FieldInfo[] array2 = array;
		for (int i = 0; i < array2.Length; i++)
		{
			object? obj = array2[i]?.GetValue(__instance);
			ItemData val = (ItemData)((obj is ItemData) ? obj : null);
			if (val != null && !inventory.ContainsItem(val))
			{
				inventory.AddItem(val);
			}
		}
	}

	[HarmonyPatch(typeof(Player), "OnDeath")]
	[HarmonyPostfix]
	public static void OnDeath_Postfix(Player __instance)
	{
		Inventory inventory = ((Humanoid)__instance).GetInventory();
		FieldInfo field = typeof(Inventory).GetField("m_height", BindingFlags.Instance | BindingFlags.NonPublic);
		int count = inventory.GetAllItems().Count;
		int num = Mathf.CeilToInt((float)count / (float)inventory.GetWidth());
		field.SetValue(inventory, Mathf.Max(4, num));
	}

	private static void OnEquipmentSlotClicked(int slotIndex)
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		FieldInfo[] array = new FieldInfo[6] { m_helmetItemField, m_TrinketItemField, m_chestItemField, m_legItemField, m_shoulderItemField, m_utilityItemField };
		object? obj = array[slotIndex]?.GetValue(localPlayer);
		ItemData val = (ItemData)((obj is ItemData) ? obj : null);
		if (val != null)
		{
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			if (!inventory.HaveEmptySlot())
			{
				((Character)localPlayer).Message((MessageType)2, "$msg_noroom", 0, (Sprite)null);
				return;
			}
			((Humanoid)localPlayer).UnequipItem(val, false);
			array[slotIndex]?.SetValue(localPlayer, null);
			inventory.AddItem(val);
			typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(inventory, new object[0]);
		}
	}

	private static void CacheFields()
	{
		m_helmetItemField = typeof(Humanoid).GetField("m_helmetItem", BindingFlags.Instance | BindingFlags.NonPublic);
		m_chestItemField = typeof(Humanoid).GetField("m_chestItem", BindingFlags.Instance | BindingFlags.NonPublic);
		m_legItemField = typeof(Humanoid).GetField("m_legItem", BindingFlags.Instance | BindingFlags.NonPublic);
		m_shoulderItemField = typeof(Humanoid).GetField("m_shoulderItem", BindingFlags.Instance | BindingFlags.NonPublic);
		m_utilityItemField = typeof(Humanoid).GetField("m_utilityItem", BindingFlags.Instance | BindingFlags.NonPublic);
		m_TrinketItemField = typeof(Humanoid).GetField("m_trinketItem", BindingFlags.Instance | BindingFlags.NonPublic);
	}

	private static void CreateEquipmentPanel(InventoryGui inventoryGui)
	{
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)equipmentPanel != (Object)null)
		{
			return;
		}
		Transform val = ((Component)inventoryGui).transform.Find("root/Player");
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Transform val2 = val.Find("Bkg");
		if (!((Object)(object)val2 == (Object)null))
		{
			Transform val3 = val.Find("Armor");
			float num = 0f;
			if ((Object)(object)val3 != (Object)null)
			{
				RectTransform component = ((Component)val3).GetComponent<RectTransform>();
				num = component.sizeDelta.x;
			}
			equipmentPanel = new GameObject("EquipmentBkg");
			equipmentPanel.transform.SetParent(val);
			equipmentPanel.transform.SetAsFirstSibling();
			RectTransform val4 = equipmentPanel.AddComponent<RectTransform>();
			val4.anchorMin = new Vector2(1f, 0f);
			val4.anchorMax = new Vector2(1f, 1f);
			val4.pivot = new Vector2(0f, 0.5f);
			val4.sizeDelta = new Vector2(170f, 0f);
			val4.anchoredPosition = new Vector2(num + 20f, 0f);
			Image val5 = equipmentPanel.AddComponent<Image>();
			Image component2 = ((Component)val2).GetComponent<Image>();
			val5.sprite = component2.sprite;
			val5.type = (Type)1;
			val5.pixelsPerUnitMultiplier = component2.pixelsPerUnitMultiplier;
			((Graphic)val5).material = ((Graphic)component2).material;
			((Graphic)val5).color = ((Graphic)component2).color;
		}
	}

	private static void CreateEquipmentSlots()
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		foreach (GameObject equipmentSlotObject in equipmentSlotObjects)
		{
			if ((Object)(object)equipmentSlotObject != (Object)null)
			{
				Object.Destroy((Object)(object)equipmentSlotObject);
			}
		}
		equipmentSlotObjects.Clear();
		if (!((Object)(object)playerGrid == (Object)null) && !((Object)(object)playerGrid.m_elementPrefab == (Object)null) && !((Object)(object)equipmentPanel == (Object)null))
		{
			RectTransform component = equipmentPanel.GetComponent<RectTransform>();
			float x = component.sizeDelta.x;
			Rect rect = component.rect;
			float num = ((Rect)(ref rect)).height;
			if (num < 100f)
			{
				num = 360f;
			}
			string[] array = new string[6] { "Helmet", "Amulet", "Chest", "Legs", "Cape", "Accessory" };
			float[] array2 = new float[6]
			{
				x * 0.25f,
				x * 0.75f,
				x * 0.25f,
				x * 0.25f,
				x * 0.75f,
				x * 0.75f
			};
			float[] array3 = new float[6]
			{
				num * 0.85f,
				num * 0.85f,
				num * 0.55f,
				num * 0.25f,
				num * 0.55f,
				num * 0.25f
			};
			for (int i = 0; i < 6; i++)
			{
				CreateEquipmentSlot(i, array[i], array2[i], array3[i]);
			}
		}
	}

	private static void CreateEquipmentSlot(int slotIndex, string name, float xPosition, float yPosition)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Expected O, but got Unknown
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Expected O, but got Unknown
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Expected O, but got Unknown
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: 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_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Expected O, but got Unknown
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>(playerGrid.m_elementPrefab, equipmentPanel.transform);
		((Object)val).name = "EquipmentSlot_" + name;
		RectTransform component = val.GetComponent<RectTransform>();
		component.anchorMin = new Vector2(0f, 0f);
		component.anchorMax = new Vector2(0f, 0f);
		component.pivot = new Vector2(0.5f, 0.5f);
		component.anchoredPosition = new Vector2(xPosition, yPosition);
		foreach (Transform item in val.transform)
		{
			Transform val2 = item;
			Object.Destroy((Object)(object)((Component)val2).gameObject);
		}
		Button val3 = val.GetComponent<Button>();
		if ((Object)(object)val3 == (Object)null)
		{
			val3 = val.AddComponent<Button>();
		}
		((UnityEventBase)val3.onClick).RemoveAllListeners();
		int capturedIndex = slotIndex;
		((UnityEvent)val3.onClick).AddListener((UnityAction)delegate
		{
			OnEquipmentSlotClicked(capturedIndex);
		});
		GameObject val4 = new GameObject("Icon");
		val4.transform.SetParent(val.transform, false);
		RectTransform val5 = val4.AddComponent<RectTransform>();
		val5.anchorMin = new Vector2(0.15f, 0.15f);
		val5.anchorMax = new Vector2(0.85f, 0.85f);
		val5.sizeDelta = Vector2.zero;
		val5.anchoredPosition = Vector2.zero;
		Image val6 = val4.AddComponent<Image>();
		((Graphic)val6).color = new Color(1f, 1f, 1f, 0f);
		((Graphic)val6).raycastTarget = false;
		GameObject val7 = new GameObject("Label");
		val7.transform.SetParent(val.transform, false);
		RectTransform val8 = val7.AddComponent<RectTransform>();
		val8.anchorMin = Vector2.zero;
		val8.anchorMax = Vector2.one;
		val8.sizeDelta = Vector2.zero;
		val8.anchoredPosition = Vector2.zero;
		Text val9 = val7.AddComponent<Text>();
		val9.text = name;
		val9.font = Font.CreateDynamicFontFromOSFont("Arial", 10);
		((Graphic)val9).color = Color.white;
		val9.alignment = (TextAnchor)4;
		val9.fontSize = 9;
		((Graphic)val9).raycastTarget = false;
		val.SetActive(true);
		equipmentSlotObjects.Add(val);
	}

	private static void UpdateEquippedIcons()
	{
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		FieldInfo[] array = new FieldInfo[6] { m_helmetItemField, m_TrinketItemField, m_chestItemField, m_legItemField, m_shoulderItemField, m_utilityItemField };
		string[] array2 = new string[6] { "Helmet", "Amulet", "Chest", "Legs", "Cape", "Accessory" };
		for (int i = 0; i < 6 && i < equipmentSlotObjects.Count; i++)
		{
			GameObject val = equipmentSlotObjects[i];
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			object? obj = array[i]?.GetValue(localPlayer);
			ItemData val2 = (ItemData)((obj is ItemData) ? obj : null);
			Transform val3 = val.transform.Find("Icon");
			if ((Object)(object)val3 == (Object)null)
			{
				continue;
			}
			Image component = ((Component)val3).GetComponent<Image>();
			if ((Object)(object)component == (Object)null)
			{
				continue;
			}
			Transform val4 = val.transform.Find("Label");
			Text val5 = ((val4 != null) ? ((Component)val4).GetComponent<Text>() : null);
			if (val2 != null)
			{
				component.sprite = val2.GetIcon();
				((Graphic)component).color = Color.white;
				if ((Object)(object)val5 != (Object)null)
				{
					val5.text = "";
				}
			}
			else
			{
				component.sprite = null;
				((Graphic)component).color = new Color(1f, 1f, 1f, 0f);
				if ((Object)(object)val5 != (Object)null)
				{
					val5.text = array2[i];
				}
			}
		}
	}

	static InventoryGuiPatches()
	{
		ItemType[] array = new ItemType[6];
		RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
		slotTypes = (ItemType[])(object)array;
	}
}