Decompiled source of ScrollHotbar v7.0.0

BepInEx/plugins/ScrollHotbar.dll

Decompiled 2 weeks ago
using System;
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 Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ScrollHotbar")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.5.0")]
[assembly: AssemblyInformationalVersion("1.2.5+7667f4353b7e8ed307f5e72a92cba1bbd905a2c6")]
[assembly: AssemblyProduct("ScrollHotbar")]
[assembly: AssemblyTitle("ScrollHotbar")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.5.0")]
[module: UnverifiableCode]
[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 ScrollHotbar
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("ScrollHotbar", "HotbarScroll", "1.2.6")]
	public class Main : BaseUnityPlugin
	{
		internal static class HotbarSwitchCompat
		{
			private static bool resolved;

			private static MethodInfo hotbarYMethod;

			internal static int GetHotbarRow()
			{
				try
				{
					if (!resolved)
					{
						resolved = true;
						Resolve();
					}
					if (hotbarYMethod == null)
					{
						return 0;
					}
					if (hotbarYMethod.Invoke(null, null) is int num && num >= 0)
					{
						return num;
					}
				}
				catch
				{
				}
				return 0;
			}

			private static void Resolve()
			{
				try
				{
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					foreach (Assembly assembly in assemblies)
					{
						Type type;
						try
						{
							type = assembly.GetType("HotbarSwitch.BepInExPlugin");
						}
						catch
						{
							continue;
						}
						if (!(type == null))
						{
							hotbarYMethod = type.GetMethod("HotbarY", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
							if (hotbarYMethod != null)
							{
								break;
							}
						}
					}
				}
				catch
				{
					hotbarYMethod = null;
				}
			}
		}

		[HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")]
		internal static class ZInputMouseScrollPatch
		{
			private static bool Prefix(ref float __result)
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				Main instance = Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return true;
				}
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					return true;
				}
				if (CameraZoomKey != null && Input.GetKey(CameraZoomKey.Value))
				{
					return true;
				}
				if (instance.UiIsBlocking())
				{
					return true;
				}
				__result = 0f;
				return false;
			}
		}

		private const int HotbarSlots = 8;

		internal static ConfigEntry<KeyCode> CameraZoomKey;

		internal static ConfigEntry<bool> InvertScroll;

		internal static ConfigEntry<string> IgnoredItems;

		private readonly Harmony harmony = new Harmony("ScrollHotbar");

		private ManualLogSource logger;

		private int currentIndex = -1;

		private int pendingIndex = -1;

		private float pendingTimer;

		private const float SelectionDelay = 0.05f;

		internal static Main Instance { get; private set; }

		internal static void LogWarning(string message)
		{
			Main instance = Instance;
			if (instance != null)
			{
				instance.logger.LogWarning((object)message);
			}
		}

		internal static void LogInfo(string message)
		{
			Main instance = Instance;
			if (instance != null)
			{
				instance.logger.LogInfo((object)message);
			}
		}

		private void Awake()
		{
			Instance = this;
			logger = ((BaseUnityPlugin)this).Logger;
			CameraZoomKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotbar Scroll Settings", "Camera Zoom Key", (KeyCode)306, "Hold this key to allow the mouse wheel to control camera zoom.");
			InvertScroll = ((BaseUnityPlugin)this).Config.Bind<bool>("Hotbar Scroll Settings", "Invert Scroll Direction", false, "If true, scrolling up selects lower hotbar slots and vice versa.");
			IgnoredItems = ((BaseUnityPlugin)this).Config.Bind<string>("Hotbar Scroll Settings", "Ignored Items", "$item_hammer, $item_cultivator, $item_hoe", "Comma-separated list of item names that will not scroll the hotbar when held. Example: $item_hammer, $item_cultivator, $item_hoe");
			harmony.PatchAll();
			logger.LogInfo((object)"HotbarScroll 1.2.6 loaded");
		}

		private void Update()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			for (int i = 0; i < 8; i++)
			{
				if (Input.GetKeyDown((KeyCode)(49 + i)) || Input.GetKeyDown((KeyCode)(257 + i)))
				{
					currentIndex = i;
					pendingIndex = -1;
					pendingTimer = 0f;
					break;
				}
			}
			if (CameraZoomKey != null && Input.GetKey(CameraZoomKey.Value))
			{
				pendingIndex = -1;
				pendingTimer = 0f;
				return;
			}
			if (UiIsBlocking())
			{
				pendingIndex = -1;
				pendingTimer = 0f;
				return;
			}
			float axis = Input.GetAxis("Mouse ScrollWheel");
			if (!Mathf.Approximately(axis, 0f))
			{
				if (currentIndex < 0)
				{
					currentIndex = GetCurrentHotbarIndex(localPlayer);
				}
				int num = ((axis > 0f) ? 1 : (-1));
				if (InvertScroll.Value)
				{
					num = -num;
				}
				int num2 = ((pendingIndex >= 0) ? pendingIndex : currentIndex);
				pendingIndex = WrapIndex(num2 + num);
				pendingTimer = 0.05f;
			}
			if (pendingIndex >= 0)
			{
				pendingTimer -= Time.deltaTime;
				if (pendingTimer <= 0f)
				{
					int index = pendingIndex;
					pendingIndex = -1;
					currentIndex = index;
					SelectHotbarSlot(localPlayer, index);
				}
			}
		}

		private static int WrapIndex(int index)
		{
			if (index >= 8)
			{
				return index % 8;
			}
			if (index < 0)
			{
				return (index % 8 + 8) % 8;
			}
			return index;
		}

		private int GetCurrentHotbarIndex(Player player)
		{
			if (((Humanoid)player).m_inventory == null)
			{
				return 0;
			}
			ItemData rightItem = ((Humanoid)player).GetRightItem();
			if (rightItem == null)
			{
				return 0;
			}
			int hotbarRow = HotbarSwitchCompat.GetHotbarRow();
			for (int i = 0; i < 8; i++)
			{
				ItemData itemAt = ((Humanoid)player).m_inventory.GetItemAt(i, hotbarRow);
				if (itemAt == rightItem)
				{
					return i;
				}
			}
			return 0;
		}

		private void SelectHotbarSlot(Player player, int index)
		{
			if (((Humanoid)player).m_inventory != null && index >= 0 && index < 8)
			{
				ItemData itemAt = ((Humanoid)player).m_inventory.GetItemAt(index, HotbarSwitchCompat.GetHotbarRow());
				if (itemAt == null)
				{
					logger.LogInfo((object)$"Slot {index + 1} is empty");
					return;
				}
				((Humanoid)player).EquipItem(itemAt, true);
				logger.LogInfo((object)$"Equipped slot {index + 1} ({itemAt.m_shared.m_name})");
			}
		}

		internal bool UiIsBlocking()
		{
			try
			{
				if (Menu.IsVisible())
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.IsVisible())
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				if (Minimap.IsOpen())
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null && IsIgnoredItem(((Humanoid)localPlayer).GetRightItem()))
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static bool IsIgnoredItem(ItemData item)
		{
			if (item == null)
			{
				return false;
			}
			string name = item.m_shared.m_name;
			string text = IgnoredItems?.Value ?? "";
			string[] array = text.Split(new char[1] { ',' });
			foreach (string text2 in array)
			{
				if (text2.Trim() == name)
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}