Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HotbarSwitch v0.5.2
plugins\HotbarSwitch.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace HotbarSwitch; [BepInPlugin("cjayride.HotbarSwitch", "Hotbar Switch", "0.5.2")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Inventory), "GetItemAt", new Type[] { typeof(int), typeof(int) })] private static class GetItemAt_Patch { private static void Prefix(ref int y) { if (readingHotbar && y == 0) { y = HotbarY(); } } } [HarmonyPatch(typeof(Inventory), "GetBoundItems")] private static class GetBoundItems_Patch { private static bool Prefix(Inventory __instance, List<ItemData> bound) { int num = HotbarY(); if (num <= 0) { return true; } bound.Clear(); int width = __instance.GetWidth(); for (int i = 0; i < width; i++) { ItemData itemAt = __instance.GetItemAt(i, num); if (itemAt != null) { bound.Add(itemAt); } } return false; } } [HarmonyPatch(typeof(Player), "UseHotbarItem")] private static class UseHotbarItem_Patch { private static void Prefix() { readingHotbar = true; } private static void Postfix() { readingHotbar = false; } } [HarmonyPatch(typeof(HotkeyBar), "UpdateIcons")] private static class UpdateIcons_Patch { private static void Prefix() { readingHotbar = true; } private static void Postfix() { readingHotbar = false; if ((Object)(object)Player.m_localPlayer != (Object)null) { PaintHotkeyBars(Player.m_localPlayer); } } } public static ConfigEntry<bool> modEnabled; public static ConfigEntry<int> rowsToSwitch; public static ConfigEntry<string> hotKey; internal static int activeRow; private static bool readingHotbar; private Harmony harmony; private static FieldInfo elementsField; private static FieldInfo iconField; private static FieldInfo amountField; private static FieldInfo durabilityField; private static FieldInfo equippedField; private static PropertyInfo amountText; private static MethodInfo durabilitySetValue; private static HotkeyBar[] cachedBars; private static float cachedBarsAt; private void Awake() { modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); rowsToSwitch = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RowsToSwitch", 2, "How many inventory rows the hotkey cycles as the hotbar. Items stay in their original slots."); hotKey = ((BaseUnityPlugin)this).Config.Bind<string>("General", "HotKey", "`", "Hotkey to switch which inventory row is shown on the hotbar. Use https://docs.unity3d.com/Manual/ConventionalGameInput.html"); Type type = AccessTools.Inner(typeof(HotkeyBar), "ElementData"); if (type == null) { type = AccessTools.Inner(typeof(HotkeyBar), "Element"); } elementsField = AccessTools.Field(typeof(HotkeyBar), "m_elements"); if (type != null) { iconField = AccessTools.Field(type, "m_icon"); amountField = AccessTools.Field(type, "m_amount"); durabilityField = AccessTools.Field(type, "m_durability"); equippedField = AccessTools.Field(type, "m_equiped"); if (equippedField == null) { equippedField = AccessTools.Field(type, "m_equipped"); } if (amountField != null) { amountText = amountField.FieldType.GetProperty("text"); } if (durabilityField != null) { durabilitySetValue = AccessTools.Method(durabilityField.FieldType, "SetValue", new Type[1] { typeof(float) }, (Type[])null); } } if (modEnabled.Value) { harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), ((BaseUnityPlugin)this).Info.Metadata.GUID); } } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { if (modEnabled.Value && !AedenthornUtils.IgnoreKeyPresses() && AedenthornUtils.CheckKeyDown(hotKey.Value) && !((Object)(object)Player.m_localPlayer == (Object)null)) { int num = Math.Max(1, Math.Min(((Humanoid)Player.m_localPlayer).GetInventory().GetHeight(), rowsToSwitch.Value)); activeRow = (activeRow + 1) % num; } } private void LateUpdate() { if (modEnabled.Value && !((Object)(object)Player.m_localPlayer == (Object)null)) { PaintHotkeyBars(Player.m_localPlayer); } } internal static int HotbarY() { if (!modEnabled.Value || (Object)(object)Player.m_localPlayer == (Object)null) { return 0; } int num = Math.Max(1, Math.Min(((Humanoid)Player.m_localPlayer).GetInventory().GetHeight(), rowsToSwitch.Value)); if (activeRow >= num) { activeRow = 0; } return activeRow; } private static void PaintHotkeyBars(Player player) { if (elementsField == null || iconField == null) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); int num = HotbarY(); int width = inventory.GetWidth(); if (cachedBars == null || Time.unscaledTime - cachedBarsAt > 2f) { cachedBars = Resources.FindObjectsOfTypeAll<HotkeyBar>(); cachedBarsAt = Time.unscaledTime; } HotkeyBar[] array = cachedBars; foreach (HotkeyBar val in array) { if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled && elementsField.GetValue(val) is IList list && IsMainHotkeyBar(val, list.Count, width)) { int num2 = list.Count; if (num2 > width) { num2 = width; } for (int j = 0; j < num2; j++) { PaintSlot(list[j], inventory.GetItemAt(j, num)); } } } } private static bool IsMainHotkeyBar(HotkeyBar bar, int elementCount, int width) { if (elementCount < width) { return false; } Transform val = ((Component)bar).transform; for (int i = 0; i < 6; i++) { if (!((Object)(object)val != (Object)null)) { break; } string name = ((Object)val).name; if (name != null) { string text = name.ToLower(); if (text.IndexOf("quick") >= 0 || text.IndexOf("extra") >= 0 || text.IndexOf("equip") >= 0) { return false; } } val = val.parent; } return true; } private static void PaintSlot(object element, ItemData item) { if (element == null) { return; } object? value = iconField.GetValue(element); Image val = (Image)((value is Image) ? value : null); if ((Object)(object)val != (Object)null) { if (item == null) { ((Behaviour)val).enabled = false; val.sprite = null; } else { ((Behaviour)val).enabled = true; val.sprite = item.GetIcon(); } } if (amountField != null && amountText != null) { object value2 = amountField.GetValue(element); if (value2 != null) { amountText.SetValue(value2, (item != null && item.m_stack > 1) ? item.m_stack.ToString() : "", null); } } if (durabilityField != null) { object? value3 = durabilityField.GetValue(element); Component val2 = (Component)((value3 is Component) ? value3 : null); if ((Object)(object)val2 != (Object)null) { bool flag = item?.m_shared.m_useDurability ?? false; val2.gameObject.SetActive(flag); if (flag && durabilitySetValue != null) { durabilitySetValue.Invoke(val2, new object[1] { item.GetDurabilityPercentage() }); } } } if (equippedField != null) { object? value4 = equippedField.GetValue(element); GameObject val3 = (GameObject)((value4 is GameObject) ? value4 : null); if ((Object)(object)val3 != (Object)null) { val3.SetActive(item?.m_equipped ?? false); } } } } public class AedenthornUtils { public static bool IgnoreKeyPresses(bool extra = false) { if (!extra) { if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog()) { if ((Object)(object)Chat.instance != (Object)null) { return Chat.instance.HasFocus(); } return false; } return true; } if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible()) { if ((Object)(object)TextViewer.instance != (Object)null) { return TextViewer.instance.IsVisible(); } return false; } return true; } public static bool CheckKeyDown(string value) { try { return Input.GetKeyDown(value.ToLower()); } catch { return false; } } }