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 equipmentSlotObjects = new List(); 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 allItems = inventory.GetAllItems(); List list = new List(); 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(); num = component.sizeDelta.x; } equipmentPanel = new GameObject("EquipmentBkg"); equipmentPanel.transform.SetParent(val); equipmentPanel.transform.SetAsFirstSibling(); RectTransform val4 = equipmentPanel.AddComponent(); 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 component2 = ((Component)val2).GetComponent(); 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(); 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(playerGrid.m_elementPrefab, equipmentPanel.transform); ((Object)val).name = "EquipmentSlot_" + name; RectTransform component = val.GetComponent(); 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