Decompiled source of InputTweaks v1.1.1

InputTweaks.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("InputTweaks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Riintouge")]
[assembly: AssemblyProduct("InputTweaks")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("cbd7a961-cdeb-4db5-af2c-ada574c3197f")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.1.1.0")]
namespace InputTweaks;

[BepInPlugin("com.riintouge.inputtweaks", "Input Tweaks", "1.1.1")]
[BepInProcess("valheim.exe")]
public class InputTweaks : BaseUnityPlugin
{
	[HarmonyPatch(typeof(ArmorStand))]
	public class ArmorStandPatch
	{
		public static bool CanAttach(ArmorStand armorStand, ArmorStandSlot slot, ItemData item)
		{
			return Traverse.Create((object)armorStand).Method("CanAttach", new Type[2]
			{
				typeof(ArmorStandSlot),
				typeof(ItemData)
			}, (object[])null).GetValue<bool>(new object[2] { slot, item });
		}

		public static void RPC_DropItem(ArmorStand armorStand, int index)
		{
			Traverse.Create((object)armorStand).Field("m_nview").GetValue<ZNetView>()
				.InvokeRPC(ZNetView.Everybody, "RPC_DropItem", new object[1] { index });
		}
	}

	internal class ButtonRightClickComponent : MonoBehaviour
	{
		public ButtonClickedEvent OnRightClick = new ButtonClickedEvent();
	}

	[HarmonyPatch(typeof(Button))]
	private class ButtonPatch
	{
		[HarmonyPatch("OnPointerClick")]
		[HarmonyPostfix]
		private static void OnPointerClickPostfix(Button __instance, PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)eventData.button == 1 && ((UIBehaviour)__instance).IsActive() && ((Selectable)__instance).IsInteractable())
			{
				ButtonRightClickComponent component = ((Component)__instance).GetComponent<ButtonRightClickComponent>();
				if ((Object)(object)component != (Object)null)
				{
					Common.DebugMessage("RCLK: Activating RightClickButtonComponent");
					((UnityEvent)component.OnRightClick).Invoke();
				}
			}
		}
	}

	[HarmonyPatch(typeof(Hud))]
	public class HudPatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(Hud __instance)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			KeyCode value = ToggleHudKey.Value;
			if ((Object)(object)Player.m_localPlayer != (Object)null && (int)value != 0 && ZInput.GetKeyDown(value, true))
			{
				__instance.m_userHidden = !__instance.m_userHidden;
			}
		}
	}

	[HarmonyPatch(typeof(Inventory))]
	public class InventoryPatch
	{
		public static void Changed(Inventory inv)
		{
			Traverse.Create((object)inv).Method("Changed", Array.Empty<object>()).GetValue();
		}
	}

	[HarmonyPatch(typeof(InventoryGrid))]
	public class InventoryGridPatch
	{
		public static Vector2i GetButtonPos(InventoryGrid grid, UIInputHandler element)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return GetButtonPos(grid, ((Component)element).gameObject);
		}

		public static Vector2i GetButtonPos(InventoryGrid grid, GameObject go)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			return Traverse.Create((object)grid).Method("GetButtonPos", new Type[1] { typeof(GameObject) }, (object[])null).GetValue<Vector2i>(new object[1] { go });
		}

		public static void OnRightClick(InventoryGrid grid, UIInputHandler element)
		{
			Traverse.Create((object)grid).Method("OnRightClick", new Type[1] { typeof(UIInputHandler) }, (object[])null).GetValue(new object[1] { element });
		}

		public static int Width(InventoryGrid grid)
		{
			return Traverse.Create((object)grid).Field("m_width").GetValue<int>();
		}

		[HarmonyPatch("OnLeftClick")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> OnLeftClickTranspiler(IEnumerable<CodeInstruction> instructionsIn)
		{
			if (!InitialSwapMoveAndSplit)
			{
				return instructionsIn;
			}
			return Common.SwapShiftAndCtrl(instructionsIn);
		}
	}

	[HarmonyPatch(typeof(InventoryGui))]
	public class InventoryGuiPatch
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<InventoryButton, bool> <>9__14_0;

			public static Func<InventoryButton, bool> <>9__14_1;

			public static Action<InventoryButton> <>9__16_0;

			public static Action<InventoryButton> <>9__16_1;

			public static UnityAction <>9__35_0;

			public static Func<bool> <>9__40_1;

			public static Func<bool> <>9__40_0;

			public static Func<bool> <>9__41_0;

			internal bool <GetHoveredButton>b__14_0(InventoryButton x)
			{
				return Common.IsCursorOver(((Component)x.inputHandler).gameObject);
			}

			internal bool <GetHoveredButton>b__14_1(InventoryButton x)
			{
				return Common.IsCursorOver(((Component)x.inputHandler).gameObject);
			}

			internal void <EndDrag>b__16_0(InventoryButton x)
			{
				x.considerForDrag = false;
			}

			internal void <EndDrag>b__16_1(InventoryButton x)
			{
				x.considerForDrag = false;
			}

			internal void <AwakePostfix>b__35_0()
			{
				if (!IsEnabled.Value)
				{
					return;
				}
				if (!AllowRightClickDrop.Value)
				{
					VanillaDragState.ClearDrag();
					return;
				}
				VanillaDragState vanillaDragState = new VanillaDragState();
				if (vanillaDragState.isValid && PlayerDropFromInv(vanillaDragState.dragInventory, vanillaDragState.dragItem, 1) && vanillaDragState.Decrement())
				{
					vanillaDragState = new VanillaDragState();
					if (vanillaDragState.isValid)
					{
						vanillaDragState.UpdateTooltip();
					}
					else
					{
						VanillaDragState.ClearDrag();
					}
				}
			}

			internal bool <OnRightClickItemPrefix>b__40_1()
			{
				return Common.CheckModifier(ModifierKeyEnum.Move);
			}

			internal bool <OnRightClickItemPrefix>b__40_0()
			{
				return Common.CheckModifier(ModifierKeyEnum.Split);
			}

			internal bool <OnSelectedItemPrefix>b__41_0()
			{
				return Common.CheckModifier(ModifierKeyEnum.Split);
			}
		}

		private static bool IgnoreUpdateItemDragRightMouseReset = false;

		private static bool SkipNextUpdate = false;

		private static bool SingleDropCoolDown = false;

		private static AbstractInventoryGuiCursorContext MouseContext = null;

		private static VanillaDragState CurrentDragState = new VanillaDragState();

		private static List<InventoryButton> PlayerButtons = new List<InventoryButton>();

		private static bool ForceContainerButtonUpdate = false;

		private static List<InventoryButton> ContainerButtons = new List<InventoryButton>();

		private static InventoryButton CurrentButton = null;

		private static Component LastWorldComponent = null;

		private static Component CurrentWorldComponent = null;

		private static GameObject WorldInteractionPreviewDragObject = null;

		private static void CollectInventoryButtons(InventoryGrid playerGrid, InventoryGrid containerGrid)
		{
			int num;
			if (PlayerButtons.Count == 0)
			{
				num = ((ContainerButtons.Count == 0) ? 1 : 0);
				if (num != 0)
				{
					Common.DebugMessage("INFO: Attempting to index PlayerButtons");
					CollectInventoryButtons(playerGrid, PlayerButtons);
					Common.DebugMessage($"INFO: Indexed {PlayerButtons.Count} player buttons");
				}
			}
			else
			{
				num = 0;
			}
			if (num != 0 || ForceContainerButtonUpdate)
			{
				Common.DebugMessage("INFO: Attempting to index ContainerButtons");
				CollectInventoryButtons(containerGrid, ContainerButtons);
				Common.DebugMessage($"INFO: Indexed {ContainerButtons.Count} container buttons");
				ForceContainerButtonUpdate = false;
			}
		}

		private static void CollectInventoryButtons(InventoryGrid grid, List<InventoryButton> buttons)
		{
			//IL_0050: 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_0057: 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)
			//IL_006b: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			buttons.Clear();
			Inventory val = ((grid != null) ? grid.GetInventory() : null);
			if (val == null)
			{
				return;
			}
			int width = val.GetWidth();
			int height = val.GetHeight();
			if (width <= 0 || height <= 0)
			{
				return;
			}
			ListExtra.Resize<InventoryButton>(buttons, width * height, (InventoryButton)null);
			UIInputHandler[] componentsInChildren = ((Component)grid).GetComponentsInChildren<UIInputHandler>();
			foreach (UIInputHandler val2 in componentsInChildren)
			{
				Vector2i buttonPos = InventoryGridPatch.GetButtonPos(grid, val2);
				if (buttonPos.x != -1 && buttonPos.y != -1)
				{
					int index = buttonPos.x + buttonPos.y * width;
					buttons[index] = new InventoryButton
					{
						inputHandler = val2,
						grid = grid,
						gridPos = buttonPos,
						considerForDrag = true,
						representsExistingItem = (val.GetItemAt(buttonPos.x, buttonPos.y) != null)
					};
				}
			}
		}

		internal static InventoryButton GetHoveredButton(InventoryGrid playerGrid, InventoryGrid containerGrid)
		{
			if ((Object)(object)playerGrid != (Object)null && ((Component)playerGrid).gameObject.activeInHierarchy && Common.IsCursorOver(((Component)playerGrid).gameObject))
			{
				return PlayerButtons.Where((InventoryButton x) => Common.IsCursorOver(((Component)x.inputHandler).gameObject)).FirstOrDefault();
			}
			if ((Object)(object)containerGrid != (Object)null && ((Component)containerGrid).gameObject.activeInHierarchy && Common.IsCursorOver(((Component)containerGrid).gameObject))
			{
				return ContainerButtons.Where((InventoryButton x) => Common.IsCursorOver(((Component)x.inputHandler).gameObject)).FirstOrDefault();
			}
			return null;
		}

		private static void UpdateContext(InventoryGrid playerGrid, InventoryGrid containerGrid)
		{
			if (MouseContext != null)
			{
				AbstractInventoryGuiCursorContext.State state = MouseContext.Think(CurrentDragState);
				if ((uint)(state - 2) <= 1u && FrameInputs.Current.None)
				{
					EndDrag(clearContext: true);
				}
			}
		}

		private static void EndDrag(bool clearContext)
		{
			PlayerButtons.ForEach(delegate(InventoryButton x)
			{
				x.considerForDrag = false;
			});
			ContainerButtons.ForEach(delegate(InventoryButton x)
			{
				x.considerForDrag = false;
			});
			if (clearContext)
			{
				MouseContext?.End();
				MouseContext = null;
			}
		}

		public static void UpdateSingleDrop(InventoryGrid m_playerGrid, InventoryGrid m_containerGrid)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (MouseContext != null || CurrentDragState.isValid || FrameInputs.Current.Any)
			{
				return;
			}
			if (!ZInput.GetKey(SingleDropKey.Value, true))
			{
				SingleDropCoolDown = false;
			}
			else if (!SingleDropCoolDown)
			{
				SingleDropCoolDown = true;
				InventoryButton hoveredButton = GetHoveredButton(m_playerGrid, m_containerGrid);
				if (hoveredButton != null)
				{
					ItemData curItem = hoveredButton.curItem;
					PlayerDropFromInv(hoveredButton.grid.GetInventory(), curItem, (!Common.CheckModifier(StackDropModifier.Value)) ? 1 : curItem.m_stack);
				}
			}
		}

		private static bool PlayerDropFromInv(Inventory inv, ItemData item, int count)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (MouseContext == null && ((Humanoid)Player.m_localPlayer).DropItem(inv, item, count))
			{
				Traverse.Create((object)InventoryGui.instance).Field("m_moveItemEffects").GetValue<EffectList>()
					.Create(((Component)InventoryGui.instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
				return true;
			}
			return false;
		}

		private static void UpdateMouseWheel(InventoryGui inventoryGui, InventoryGrid playerGrid, InventoryGrid containerGrid)
		{
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			if (MouseContext != null || CurrentDragState.isValid || FrameInputs.Current.Any)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			float mouseScrollWheel = ZInput.GetMouseScrollWheel();
			if ((Object)(object)localPlayer == (Object)null || mouseScrollWheel == 0f)
			{
				return;
			}
			if (((Component)inventoryGui.m_splitPanel).gameObject.activeInHierarchy)
			{
				Transform obj = inventoryGui.m_splitPanel.Find("win_bkg");
				if (Common.IsCursorOver((RectTransform)(object)((obj is RectTransform) ? obj : null)))
				{
					Slider splitSlider = inventoryGui.m_splitSlider;
					splitSlider.value = Mathf.Clamp(splitSlider.value + ((mouseScrollWheel > 0f) ? 1f : (-1f)), splitSlider.minValue, splitSlider.maxValue);
					Traverse.Create((object)inventoryGui).Method("OnSplitSliderChanged", new Type[1] { typeof(float) }, (object[])null).GetValue(new object[1] { Mathf.Clamp(splitSlider.value, splitSlider.minValue, splitSlider.maxValue) });
				}
			}
			else
			{
				if (CurrentButton == null)
				{
					return;
				}
				Inventory inventory = CurrentButton.grid.GetInventory();
				Vector2i gridPos = CurrentButton.gridPos;
				ItemData itemAt = inventory.GetItemAt(gridPos.x, gridPos.y);
				if (itemAt == null || itemAt.m_stack < 1)
				{
					return;
				}
				bool flag = (Object)(object)CurrentButton.grid == (Object)(object)containerGrid;
				WheelActionEnum value = (flag ? ContainerWheelAction : PlayerWheelAction).Value;
				if (value != 0)
				{
					bool pull = value == WheelActionEnum.PullUpPushDown == mouseScrollWheel > 0f;
					if (flag)
					{
						MoveOne(localPlayer, pull, itemAt, containerGrid, playerGrid);
					}
					else if (inventoryGui.IsContainerOpen())
					{
						MoveOne(localPlayer, pull, itemAt, playerGrid, containerGrid);
					}
					else
					{
						MoveOne(localPlayer, pull, itemAt, playerGrid, null);
					}
				}
			}
		}

		private static void MoveOne(Player player, bool pull, ItemData item, InventoryGrid owningGrid, InventoryGrid otherGrid)
		{
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)otherGrid == (Object)(object)owningGrid)
			{
				otherGrid = null;
			}
			Inventory inventory = owningGrid.GetInventory();
			Inventory val = ((otherGrid != null) ? otherGrid.GetInventory() : null);
			if (pull)
			{
				if (item.m_shared.m_maxStackSize == 1)
				{
					if (val == null)
					{
						Common.DebugMessage("PULL: Doesn't make sense");
						return;
					}
					if (!inventory.HaveEmptySlot())
					{
						Common.DebugMessage("PULL: No empty slots");
						return;
					}
				}
				else if (item.m_stack == item.m_shared.m_maxStackSize)
				{
					if (val == null)
					{
						Common.DebugMessage("PULL: Doesn't make sense");
						return;
					}
					ItemData val2 = Common.FindLargestPartialStack(item, owningGrid);
					if (val2 == null)
					{
						if (!inventory.HaveEmptySlot())
						{
							Common.DebugMessage("PULL: No space");
							return;
						}
					}
					else
					{
						item = val2;
					}
				}
				if (val != null)
				{
					ItemData val3 = (ItemData)((item.m_shared.m_maxStackSize > 1) ? ((object)Common.EquivalentStackables(item, otherGrid).FirstOrDefault()) : ((object)Common.FindFirstSimilarItemInInventory(item, val)));
					if (val3 == null && item.m_stack == item.m_shared.m_maxStackSize && item.m_shared.m_maxStackSize > 1)
					{
						ItemData val4 = Common.FindSmallestPartialStack(item, otherGrid);
						if (val4 != null && inventory.AddItem(item.m_dropPrefab, 1))
						{
							Common.DebugMessage("PULL: One item");
							val.RemoveOneItem(val4);
							return;
						}
					}
					else if (val3 == null || val3.m_stack < 1)
					{
						Common.DebugMessage("PULL: No similar item");
					}
					else
					{
						if (val3 == item)
						{
							Common.DebugMessage("PULL: Found self");
							return;
						}
						if (val3.m_shared.m_maxStackSize == 1)
						{
							Common.DebugMessage("PULL: Single");
							inventory.MoveItemToThis(val, val3);
							return;
						}
						if (val.RemoveOneItem(val3))
						{
							Common.DebugMessage("PULL: One item");
							ItemData obj = item;
							obj.m_stack++;
							InventoryPatch.Changed(inventory);
							return;
						}
					}
				}
				ItemData val5 = Common.EquivalentStackables(item, owningGrid).FirstOrDefault();
				if (val5 == null || val5.m_stack < 1)
				{
					Common.DebugMessage("PULL: No similar item");
				}
				else if (val5 == item)
				{
					Common.DebugMessage("PULL: Found self");
				}
				else if (inventory.RemoveOneItem(val5))
				{
					Common.DebugMessage("PULL: One item");
					ItemData obj2 = item;
					obj2.m_stack++;
					InventoryPatch.Changed(val);
				}
				return;
			}
			if (val != null)
			{
				if (item.m_stack == 1)
				{
					Common.DebugMessage("PUSH: Single or last");
					((Humanoid)player).RemoveEquipAction(item);
					((Humanoid)player).UnequipItem(item, true);
					val.MoveItemToThis(inventory, item);
					UITooltip.HideTooltip();
					return;
				}
				if (item.m_stack == item.m_shared.m_maxStackSize)
				{
					item = Common.FindSmallestPartialStack(item, owningGrid) ?? item;
				}
				if (val.AddItem(item.m_dropPrefab, 1))
				{
					Common.DebugMessage("PUSH: One item");
					inventory.RemoveOneItem(item);
				}
				return;
			}
			ItemData val6 = Common.FindLargestPartialStack(item, owningGrid);
			if (val6 != null)
			{
				Common.DebugMessage("PUSH: One item to sibling");
				val6.m_stack++;
				InventoryPatch.Changed(val);
				inventory.RemoveOneItem(item);
				if (item.m_stack < 1)
				{
					UITooltip.HideTooltip();
				}
			}
			else if (item.m_stack == 1)
			{
				Common.DebugMessage("PUSH: Doesn't make sense");
			}
			else
			{
				Vector2i val7 = FindEmptySlot(inventory, TopFirst(inventory, item));
				if (val7.x < 0 || val7.y < 0)
				{
					Common.DebugMessage("PUSH: No empty slot");
					return;
				}
				Common.DebugMessage("PUSH: One item to empty slot");
				AddItem(inventory, item, 1, val7.x, val7.y);
			}
		}

		private static void UpdateWorldInteractionDragPreview(InventoryGui inventoryGui, Button dropButton)
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			LastWorldComponent = CurrentWorldComponent;
			CurrentWorldComponent = null;
			VanillaDragState vanillaDragState = new VanillaDragState();
			if ((Object)(object)vanillaDragState.dragObject != (Object)null && (Object)(object)vanillaDragState.dragObject != (Object)(object)WorldInteractionPreviewDragObject)
			{
				return;
			}
			Transform transform = ((Component)dropButton).transform;
			Transform transform2 = ((Component)transform.parent).transform;
			for (int i = 0; i < transform2.childCount; i++)
			{
				Transform child = transform2.GetChild(i);
				RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null);
				if ((Object)(object)val != (Object)(object)transform && ((Component)val).gameObject.activeInHierarchy && Common.IsCursorOver(val))
				{
					ClearWorldInteractionDragPreview();
					return;
				}
			}
			CurrentWorldComponent = (Component)(object)RaycastComponentForWorldInteraction<Piece>(out RaycastHit hit);
			if ((Object)(object)CurrentWorldComponent != (Object)(object)LastWorldComponent)
			{
				VanillaDragState.ClearDrag();
			}
			string hoverPrefabName = GetHoverPrefabName(CurrentWorldComponent, hit);
			if (hoverPrefabName == null)
			{
				ClearWorldInteractionDragPreview();
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(hoverPrefabName);
			ItemData val2 = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData);
			if (val2 != null)
			{
				SetWorldInteractionDragPreview(inventoryGui, val2);
			}
			else
			{
				ClearWorldInteractionDragPreview();
			}
		}

		private static T RaycastComponentForWorldInteraction<T>(out RaycastHit hit) where T : Component
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			Ray val = ((Component)GameCamera.instance).GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);
			Player localPlayer = Player.m_localPlayer;
			int value = Traverse.Create((object)localPlayer).Field("m_interactMask").GetValue<int>();
			if (!Physics.Raycast(val, ref hit, 50f, value))
			{
				return default(T);
			}
			if (Vector3.Distance(((RaycastHit)(ref hit)).point, ((Character)localPlayer).m_eye.position) > localPlayer.m_maxInteractDistance)
			{
				return default(T);
			}
			return ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<T>();
		}

		private static string GetHoverPrefabName(Component component, RaycastHit hit)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			if (InteractWithArmorStands.Value)
			{
				ArmorStand componentInParent = component.GetComponentInParent<ArmorStand>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					ItemType item = ItemTypeForArmorStandPoint(hit);
					for (int i = 0; i < componentInParent.m_slots.Count; i++)
					{
						ArmorStandSlot val = componentInParent.m_slots[i];
						if (val.m_supportedTypes.Count == 0 || val.m_supportedTypes.Contains(item))
						{
							if (!componentInParent.HaveAttachment(i))
							{
								return null;
							}
							return Traverse.Create((object)componentInParent).Field("m_nview").GetValue<ZNetView>()
								.GetZDO()
								.GetString(i + "_item", "");
						}
					}
					return null;
				}
			}
			if (InteractWithItemStands.Value)
			{
				ItemStand componentInParent2 = component.GetComponentInParent<ItemStand>();
				if ((Object)(object)componentInParent2 != (Object)null)
				{
					return Traverse.Create((object)componentInParent2).Field("m_visualName").GetValue<string>();
				}
			}
			return null;
		}

		private static void SetWorldInteractionDragPreview(InventoryGui inventoryGui, ItemData item)
		{
			VanillaDragState vanillaDragState = new VanillaDragState();
			if ((Object)(object)vanillaDragState.dragObject != (Object)null && (Object)(object)vanillaDragState.dragObject == (Object)(object)WorldInteractionPreviewDragObject)
			{
				if (!Common.ItemsAreSimilarButDistinct(vanillaDragState.dragItem, item, considerQuality: true))
				{
					Traverse.Create((object)inventoryGui).Field("m_dragInventory").SetValue((object)null);
					Traverse.Create((object)inventoryGui).Field("m_dragItem").SetValue((object)item);
					Traverse.Create((object)inventoryGui).Field("m_dragAmount").SetValue((object)0);
				}
			}
			else
			{
				SetupDragItem(inventoryGui, item, null, 0);
				WorldInteractionPreviewDragObject = new VanillaDragState().dragObject;
			}
		}

		private static void ClearWorldInteractionDragPreview()
		{
			if ((Object)(object)WorldInteractionPreviewDragObject != (Object)null && (Object)(object)new VanillaDragState().dragObject == (Object)(object)WorldInteractionPreviewDragObject)
			{
				WorldInteractionPreviewDragObject = null;
				VanillaDragState.ClearDrag();
			}
		}

		private static void InteractWithArmorStand(RaycastHit hit, ArmorStand armorStand)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			VanillaDragState vanillaDragState = new VanillaDragState();
			if (vanillaDragState.isValid)
			{
				for (int i = 0; i < armorStand.m_slots.Count; i++)
				{
					ItemData dragItem = vanillaDragState.dragItem;
					ArmorStandSlot val = armorStand.m_slots[i];
					if (armorStand.HaveAttachment(i))
					{
						if (ArmorStandPatch.CanAttach(armorStand, val, dragItem))
						{
							ArmorStandPatch.RPC_DropItem(armorStand, i);
							break;
						}
					}
					else if (val.m_switch.UseItem((Humanoid)(object)localPlayer, vanillaDragState.dragItem))
					{
						VanillaDragState.ClearDrag();
						break;
					}
				}
				return;
			}
			ItemType item = ItemTypeForArmorStandPoint(hit);
			for (int j = 0; j < armorStand.m_slots.Count; j++)
			{
				ArmorStandSlot val2 = armorStand.m_slots[j];
				if (val2.m_supportedTypes.Count == 0 || val2.m_supportedTypes.Contains(item))
				{
					if (armorStand.HaveAttachment(j))
					{
						ArmorStandPatch.RPC_DropItem(armorStand, j);
					}
					break;
				}
			}
		}

		private static ItemType ItemTypeForArmorStandPoint(RaycastHit hit)
		{
			//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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			Bounds bounds = ((RaycastHit)(ref hit)).collider.bounds;
			float num = ((Bounds)(ref bounds)).max.y - ((Bounds)(ref bounds)).min.y;
			float num2 = (((RaycastHit)(ref hit)).point.y - ((Bounds)(ref bounds)).min.y) / num;
			if (!(num2 >= 0.9375f))
			{
				if (!(num2 >= 0.875f))
				{
					if (!(num2 >= 0.75f))
					{
						if (!(num2 >= 0.625f))
						{
							if (!(num2 >= 0.5f))
							{
								if (!(num2 >= 0.375f))
								{
									return (ItemType)11;
								}
								return (ItemType)5;
							}
							return (ItemType)3;
						}
						return (ItemType)18;
					}
					return (ItemType)7;
				}
				return (ItemType)17;
			}
			return (ItemType)6;
		}

		private static void InteractWithContainer(Container container, InventoryGui inventoryGui)
		{
			Container value = Traverse.Create((object)inventoryGui).Field("m_currentContainer").GetValue<Container>();
			Traverse.Create((object)inventoryGui).Method("CloseContainer", Array.Empty<object>()).GetValue();
			if ((Object)(object)container != (Object)(object)value)
			{
				container.Interact((Humanoid)(object)Player.m_localPlayer, false, false);
			}
		}

		private static void InteractWithItemStand(ItemStand itemStand)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (itemStand.HaveAttachment())
			{
				itemStand.Interact((Humanoid)(object)localPlayer, false, false);
			}
			else
			{
				if (!PrivateArea.CheckAccess(((Component)itemStand).transform.position, 0f, true, false))
				{
					return;
				}
				VanillaDragState vanillaDragState = new VanillaDragState();
				itemStand.UseItem((Humanoid)(object)localPlayer, vanillaDragState.dragItem);
				ItemData value = Traverse.Create((object)itemStand).Field("m_queuedItem").GetValue<ItemData>();
				if (vanillaDragState.dragItem == value && new VanillaDragState().Decrement())
				{
					vanillaDragState = new VanillaDragState();
					if (vanillaDragState.isValid)
					{
						vanillaDragState.UpdateTooltip();
					}
					else
					{
						VanillaDragState.ClearDrag();
					}
				}
			}
		}

		public static bool AddItem(Inventory inventory, ItemData item, int amount, int x, int y)
		{
			return Traverse.Create((object)inventory).Method("AddItem", new Type[4]
			{
				typeof(ItemData),
				typeof(int),
				typeof(int),
				typeof(int)
			}, (object[])null).GetValue<bool>(new object[4] { item, amount, x, y });
		}

		public static Vector2i FindEmptySlot(Inventory inventory, bool topFirst)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			return Traverse.Create((object)inventory).Method("FindEmptySlot", new Type[1] { typeof(bool) }, (object[])null).GetValue<Vector2i>(new object[1] { topFirst });
		}

		public static void SetupDragItem(InventoryGui instance, ItemData item, Inventory inventory, int amount)
		{
			Traverse.Create((object)instance).Method("SetupDragItem", new Type[3]
			{
				typeof(ItemData),
				typeof(Inventory),
				typeof(int)
			}, (object[])null).GetValue(new object[3] { item, inventory, amount });
		}

		public static bool TopFirst(Inventory inventory, ItemData item)
		{
			return Traverse.Create((object)inventory).Method("TopFirst", new Type[1] { typeof(ItemData) }, (object[])null).GetValue<bool>(new object[1] { item });
		}

		public static void UpdateCraftingPanel(InventoryGui instance, bool focusView = false)
		{
			Traverse.Create((object)instance).Method("UpdateCraftingPanel", new Type[1] { typeof(bool) }, (object[])null).GetValue(new object[1] { focusView });
		}

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePostfix(Button ___m_dropButton)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			ButtonClickedEvent onRightClick = ((Component)___m_dropButton).gameObject.AddComponent<ButtonRightClickComponent>().OnRightClick;
			object obj = <>c.<>9__35_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					if (IsEnabled.Value)
					{
						if (!AllowRightClickDrop.Value)
						{
							VanillaDragState.ClearDrag();
						}
						else
						{
							VanillaDragState vanillaDragState = new VanillaDragState();
							if (vanillaDragState.isValid && PlayerDropFromInv(vanillaDragState.dragInventory, vanillaDragState.dragItem, 1) && vanillaDragState.Decrement())
							{
								vanillaDragState = new VanillaDragState();
								if (vanillaDragState.isValid)
								{
									vanillaDragState.UpdateTooltip();
								}
								else
								{
									VanillaDragState.ClearDrag();
								}
							}
						}
					}
				};
				<>c.<>9__35_0 = val;
				obj = (object)val;
			}
			((UnityEvent)onRightClick).AddListener((UnityAction)obj);
		}

		[HarmonyPatch("CloseContainer")]
		[HarmonyPostfix]
		private static void CloseContainerPostfix()
		{
			MouseContext?.End();
			EndDrag(clearContext: true);
			ContainerButtons.Clear();
		}

		[HarmonyPatch("Hide")]
		[HarmonyPostfix]
		private static void HidePostfix()
		{
			MouseContext?.End();
			VanillaDragState.ClearDrag();
			EndDrag(clearContext: true);
			OnDestroyPrefix();
		}

		[HarmonyPatch("OnDestroy")]
		[HarmonyPrefix]
		private static void OnDestroyPrefix()
		{
			IgnoreUpdateItemDragRightMouseReset = false;
			SkipNextUpdate = true;
			SingleDropCoolDown = false;
			MouseContext = null;
			PlayerButtons.Clear();
			ContainerButtons.Clear();
			CurrentButton = null;
		}

		[HarmonyPatch("OnDropOutside")]
		[HarmonyPrefix]
		private static bool OnDropOutsidePrefix(InventoryGui __instance)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit hit;
			Piece val = RaycastComponentForWorldInteraction<Piece>(out hit);
			if ((Object)(object)val == (Object)null)
			{
				ClearWorldInteractionDragPreview();
				return true;
			}
			if (InteractWithArmorStands.Value)
			{
				ArmorStand componentInParent = ((Component)val).GetComponentInParent<ArmorStand>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					Common.DebugMessage("INTR: Hit ArmorStand");
					InteractWithArmorStand(hit, componentInParent);
					return false;
				}
			}
			if (InteractWithContainers.Value)
			{
				Container componentInParent2 = ((Component)val).GetComponentInParent<Container>();
				if ((Object)(object)componentInParent2 != (Object)null)
				{
					Common.DebugMessage("INTR: Hit Container");
					InteractWithContainer(componentInParent2, __instance);
					return false;
				}
			}
			if (InteractWithItemStands.Value)
			{
				ItemStand componentInParent3 = ((Component)val).GetComponentInParent<ItemStand>();
				if ((Object)(object)componentInParent3 != (Object)null)
				{
					Common.DebugMessage("INTR: Hit ItemStand");
					InteractWithItemStand(componentInParent3);
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch("OnRightClickItem")]
		[HarmonyPrefix]
		private static bool OnRightClickItemPrefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Vector2i pos, InventoryGrid ___m_playerGrid, InventoryGrid ___m_containerGrid)
		{
			if (!IsEnabled.Value)
			{
				return true;
			}
			FrameInputs.Update();
			if (VanillaDragState.IsValid())
			{
				Common.DebugMessage("INFO: Start SingleSmearContext");
				MouseContext = new SingleSmearContext(___m_playerGrid, PlayerButtons, ___m_containerGrid, ContainerButtons);
				return false;
			}
			if (item != null && item.m_shared.m_maxStackSize != 1)
			{
				if (Common.CheckModifier(ModifierKeyEnum.Move))
				{
					int amount = (SplitRoundsUp.Value ? Mathf.CeilToInt((float)item.m_stack / 2f) : Mathf.Max(1, Mathf.FloorToInt((float)item.m_stack / 2f)));
					SetupDragItem(__instance, item, grid.GetInventory(), amount);
					Common.DebugMessage("INFO: Start BlockingMouseContext (RMB, split, immediate)");
					MouseContext = new BlockingCursorContext(() => Common.CheckModifier(ModifierKeyEnum.Move));
					return false;
				}
				if (Common.CheckModifier(ModifierKeyEnum.Split))
				{
					if (item.m_stack == 1)
					{
						SetupDragItem(__instance, item, grid.GetInventory(), 1);
					}
					else
					{
						Traverse.Create((object)__instance).Method("ShowSplitDialog", new Type[2]
						{
							typeof(ItemData),
							typeof(Inventory)
						}, (object[])null).GetValue(new object[2]
						{
							item,
							grid.GetInventory()
						});
						int num = (SplitRoundsUp.Value ? Mathf.CeilToInt((float)item.m_stack / 2f) : Mathf.FloorToInt((float)item.m_stack / 2f));
						__instance.m_splitSlider.value = num;
						Traverse.Create((object)__instance).Method("OnSplitSliderChanged", new Type[1] { typeof(float) }, (object[])null).GetValue(new object[1] { num });
					}
					Common.DebugMessage("INFO: Start BlockingMouseContext (RMB, split, dialog)");
					MouseContext = new BlockingCursorContext(() => Common.CheckModifier(ModifierKeyEnum.Split));
					return false;
				}
			}
			Common.DebugMessage("CNTX: Start BlockingMouseContext (RMB)");
			MouseContext = new BlockingCursorContext(null);
			return true;
		}

		[HarmonyPatch("OnSelectedItem")]
		[HarmonyPrefix]
		private static bool OnSelectedItemPrefix(InventoryGrid grid, ItemData item, Vector2i pos, Modifier mod, InventoryGrid ___m_playerGrid, InventoryGrid ___m_containerGrid, out Tuple<Inventory, Vector2i> __state)
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			__state = null;
			if (!IsEnabled.Value)
			{
				return true;
			}
			FrameInputs.Update();
			if (MouseContext != null)
			{
				if (MouseContext.CurrentState == AbstractInventoryGuiCursorContext.State.ActiveValid)
				{
					Common.DebugMessage($"CNTX: Selecting something for {MouseContext.GetType()}");
					return true;
				}
				return false;
			}
			if (FrameInputs.Current.successiveClicks > 1)
			{
				if (AllowDoubleClickCollect.Value)
				{
					Common.DebugMessage("CNTX: Start MultiClickContext");
					MouseContext = new MultiClickContext(___m_playerGrid, PlayerButtons, ___m_containerGrid, ContainerButtons);
					return true;
				}
				Common.DebugMessage("CNTX: Start BlockingMouseContext (LMB, collect)");
				MouseContext = new BlockingCursorContext(null);
				return true;
			}
			VanillaDragState vanillaDragState = new VanillaDragState();
			if (vanillaDragState.isValid)
			{
				__state = new Tuple<Inventory, Vector2i>(vanillaDragState.dragInventory, vanillaDragState.dragItem.m_gridPos);
				return true;
			}
			bool flag = Common.CheckModifier(ModifierKeyEnum.Move);
			bool flag2 = Common.CheckModifier(ModifierKeyEnum.Split);
			if (flag && flag2)
			{
				Common.DebugMessage("CNTX: Start FilteredStackMoveContext");
				MouseContext = new FilteredStackMoveContext(___m_playerGrid, PlayerButtons, ___m_containerGrid, ContainerButtons);
				return false;
			}
			if (flag)
			{
				Common.DebugMessage("CNTX: Start StackMoveContext");
				MouseContext = new StackMoveContext(___m_playerGrid, PlayerButtons, ___m_containerGrid, ContainerButtons);
				return false;
			}
			if (flag2)
			{
				Common.DebugMessage("CNTX: Start BlockingMouseContext (LMB, split)");
				MouseContext = new BlockingCursorContext(() => Common.CheckModifier(ModifierKeyEnum.Split));
				return true;
			}
			Common.DebugMessage("CNTX: Start BlockingMouseContext (LMB)");
			MouseContext = new BlockingCursorContext(null);
			return true;
		}

		[HarmonyPatch("OnSelectedItem")]
		[HarmonyPostfix]
		private static void OnSelectedItemPostfix(InventoryGui __instance, InventoryGrid grid, ItemData item, Vector2i pos, Modifier mod, InventoryGrid ___m_playerGrid, InventoryGrid ___m_containerGrid, ref Tuple<Inventory, Vector2i> __state)
		{
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled.Value)
			{
				return;
			}
			if (MouseContext is BlockingCursorContext)
			{
				if (Common.CheckModifier(ModifierKeyEnum.Split))
				{
					if (!SplitRoundsUp.Value)
					{
						int num = Mathf.Max(1, Mathf.FloorToInt((float)item.m_stack / 2f));
						__instance.m_splitSlider.value = num;
						Traverse.Create((object)__instance).Method("OnSplitSliderChanged", new Type[1] { typeof(float) }, (object[])null).GetValue(new object[1] { num });
					}
				}
				else if (Common.CheckModifier(ModifierKeyEnum.None))
				{
					Common.DebugMessage("CNTX: Start StackCollectContext");
					MouseContext = new StackCollectContext(___m_playerGrid, PlayerButtons, ___m_containerGrid, ContainerButtons);
				}
			}
			else if (__state != null && !VanillaDragState.IsValid())
			{
				ItemData val = GetHoveredButton(___m_playerGrid, ___m_containerGrid)?.curItem;
				if (val == null || val.m_stack <= 0)
				{
					Common.DebugMessage("CNTX: Cannot smear a null or empty item");
					return;
				}
				Common.DebugMessage("CNTX: Start StackSmearContext");
				MouseContext = new StackSmearContext(___m_playerGrid, PlayerButtons, ___m_containerGrid, ContainerButtons, __state.Item1, __state.Item2);
			}
		}

		[HarmonyPatch("SetupDragItem")]
		[HarmonyPrefix]
		private static bool SetupDragItemPrefix(ItemData item, Inventory inventory, int amount)
		{
			if (IgnoreUpdateItemDragRightMouseReset)
			{
				IgnoreUpdateItemDragRightMouseReset = false;
				return !FrameInputs.Current.Right;
			}
			return true;
		}

		[HarmonyPatch("Show")]
		[HarmonyPostfix]
		private static void ShowPostfix(Container container, int activeGroup = 1)
		{
			ForceContainerButtonUpdate = true;
		}

		[HarmonyPatch("ShowSplitDialog")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ShowSplitDialogTranspiler(IEnumerable<CodeInstruction> instructionsIn)
		{
			if (!InitialSwapMoveAndSplit)
			{
				return instructionsIn;
			}
			return Common.SwapShiftAndCtrl(instructionsIn);
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(int ___m_hiddenFrames, InventoryGrid ___m_playerGrid, InventoryGrid ___m_containerGrid)
		{
			if (___m_hiddenFrames == 0 && !SkipNextUpdate)
			{
				CollectInventoryButtons(___m_playerGrid, ___m_containerGrid);
			}
			SkipNextUpdate = false;
		}

		[HarmonyPatch("UpdateItemDrag")]
		[HarmonyPrefix]
		private static void UpdateItemDragPrefix(InventoryGui __instance, InventoryGrid ___m_playerGrid, InventoryGrid ___m_containerGrid, Button ___m_dropButton)
		{
			if (IsEnabled.Value && (PlayerButtons.Count != 0 || ContainerButtons.Count != 0))
			{
				FrameInputs.Update();
				CurrentDragState = new VanillaDragState();
				CurrentButton = GetHoveredButton(___m_playerGrid, ___m_containerGrid);
				UpdateContext(___m_playerGrid, ___m_containerGrid);
				UpdateSingleDrop(___m_playerGrid, ___m_containerGrid);
				UpdateMouseWheel(__instance, ___m_playerGrid, ___m_containerGrid);
				UpdateWorldInteractionDragPreview(__instance, ___m_dropButton);
				IgnoreUpdateItemDragRightMouseReset = CurrentDragState.isValid;
			}
		}
	}

	public enum WheelActionEnum
	{
		None,
		PullUpPushDown,
		PushUpPullDown
	}

	public enum ModifierKeyEnum
	{
		None,
		Alt,
		Command,
		Ctrl,
		Move,
		Shift,
		Split
	}

	public static ConfigEntry<bool> IsEnabled;

	public static ConfigEntry<bool> LoadOnStart;

	public static ConfigEntry<bool> DebugMessages;

	public static ConfigEntry<bool> SelectSwappedItem;

	public static ConfigEntry<bool> SplitRoundsUp;

	public static ConfigEntry<bool> SwapMoveAndSplit;

	public static bool InitialSwapMoveAndSplit;

	public static ConfigEntry<KeyCode> ToggleHudKey;

	public static ConfigEntry<bool> KeepRemainderOnCursor;

	public static ConfigEntry<bool> AllowDoubleClickCollect;

	public static ConfigEntry<int> SuccessiveClickRadius;

	public static ConfigEntry<float> SuccessiveClickWindow;

	public static ConfigEntry<bool> AllowRightClickDrop;

	public static ConfigEntry<KeyCode> SingleDropKey;

	public static ConfigEntry<ModifierKeyEnum> StackDropModifier;

	public static ConfigEntry<WheelActionEnum> ContainerWheelAction;

	public static ConfigEntry<WheelActionEnum> PlayerWheelAction;

	public static ConfigEntry<bool> InteractWithArmorStands;

	public static ConfigEntry<bool> InteractWithContainers;

	public static ConfigEntry<bool> InteractWithItemStands;

	private readonly Harmony Harmony = new Harmony("com.riintouge.inputtweaks");

	private void Awake()
	{
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Expected O, but got Unknown
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Expected O, but got Unknown
		IsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Core", "Enable", true, "Whether this plugin has any effect when loaded.");
		LoadOnStart = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Core", "LoadOnStart", true, "Whether this plugin loads on game start.");
		DebugMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "DebugMessages", false, "Whether to print plugin-specific trace/debug/warning/error messages.");
		SelectSwappedItem = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "SelectSwappedItem", false, "Whether selecting a second item with an item already selected will automatically select the second item after the swap. This mimics Minecraft's transient cursor item slot.");
		SplitRoundsUp = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "SplitRoundsUp", true, "Whether stack splits round up when the stack has an odd number of items.");
		SwapMoveAndSplit = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "SwapMoveAndSplit", true, "Whether [SHIFT] as split and [CTRL] as move swap behavior. Changes will not apply until the game is restarted.");
		InitialSwapMoveAndSplit = SwapMoveAndSplit.Value;
		ToggleHudKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("1 - General", "ToggleHudKey", (KeyCode)0, "Toggle the HUD when pressed. Unset by default as [F1], Minecraft's default, conflicts with configuration managers. For reference, vanilla's default is [CTRL] + [F3].");
		KeepRemainderOnCursor = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Cursor Context", "KeepRemainderOnCursor", false, "Whether an unbalanced stack smear leaves the remainder on the cursor for further action.");
		AllowDoubleClickCollect = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Double-click", "AllowDoubleClickCollect", true, "Whether double-clicking on a partial stack will collect similar items from other stacks.");
		SuccessiveClickRadius = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Double-click", "SuccessiveClickRadius", 3, new ConfigDescription("The range, in pixels, in which a click may count as a successor to the initial click in the series.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
		SuccessiveClickWindow = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Double-click", "SuccessiveClickWindow", 0.25f, new ConfigDescription("The interval, in seconds, in which a click may count as the successor to the previous click in the series.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>()));
		AllowRightClickDrop = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Drop Shortcuts", "AllowRightClickDrop", true, "Whether right-clicking with a stack outside of the inventory drops a single item from the stack.");
		SingleDropKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("4 - Drop Shortcuts", "SingleDropKey", (KeyCode)113, "Drop one item from the stack below the cursor when this key is pressed. Conflicts with auto-run by default.");
		StackDropModifier = ((BaseUnityPlugin)this).Config.Bind<ModifierKeyEnum>("4 - Drop Shortcuts", "StackDropModifier", ModifierKeyEnum.Move, "Drop the entire stack below the cursor when this modifier is pressed when SingleDropKey is pressed.");
		ContainerWheelAction = ((BaseUnityPlugin)this).Config.Bind<WheelActionEnum>("5 - Mouse Wheel", "ContainerWheelAction", WheelActionEnum.PushUpPullDown, "How items in a container will be moved when the mouse wheel is turned.");
		PlayerWheelAction = ((BaseUnityPlugin)this).Config.Bind<WheelActionEnum>("5 - Mouse Wheel", "PlayerWheelAction", WheelActionEnum.PullUpPushDown, "How items in the player's inventory will be moved when the mouse wheel is turned.");
		InteractWithArmorStands = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - World Interactions", "InteractWithArmorStands", true, "Whether armor stands can be interacted with while the inventory GUI is open.");
		InteractWithContainers = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - World Interactions", "InteractWithContainers", true, "Whether containers can be interacted with while the inventory GUI is open.");
		InteractWithItemStands = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - World Interactions", "InteractWithItemStands", true, "Whether item stands can be interacted with while the inventory GUI is open.");
		if (LoadOnStart.Value)
		{
			InitialSwapMoveAndSplit = SwapMoveAndSplit.Value;
			Harmony.PatchAll();
		}
	}
}
public class Common
{
	public const int LeftControlInt = 306;

	public const int RightControlInt = 305;

	public const int LeftShiftInt = 304;

	public const int RightShiftInt = 303;

	public static bool AnyAlt()
	{
		if (!ZInput.GetKey((KeyCode)308, true))
		{
			return ZInput.GetKey((KeyCode)307, true);
		}
		return true;
	}

	public static bool AnyCommand()
	{
		if (!ZInput.GetKey((KeyCode)310, true))
		{
			return ZInput.GetKey((KeyCode)309, true);
		}
		return true;
	}

	public static bool AnyCtrl()
	{
		if (!ZInput.GetKey((KeyCode)306, true))
		{
			return ZInput.GetKey((KeyCode)305, true);
		}
		return true;
	}

	public static bool AnyShift()
	{
		if (!ZInput.GetKey((KeyCode)304, true))
		{
			return ZInput.GetKey((KeyCode)303, true);
		}
		return true;
	}

	public static bool CanStackOnto(ItemData item, ItemData target)
	{
		if (ItemsAreSimilarButDistinct(item, target, considerQuality: true) && target.m_shared.m_maxStackSize > 1)
		{
			return target.m_stack < target.m_shared.m_maxStackSize;
		}
		return false;
	}

	public static bool CheckModifier(InputTweaks.ModifierKeyEnum modifier)
	{
		switch (modifier)
		{
		case InputTweaks.ModifierKeyEnum.Alt:
			return AnyAlt();
		case InputTweaks.ModifierKeyEnum.Command:
			return AnyCommand();
		case InputTweaks.ModifierKeyEnum.Ctrl:
			return AnyCtrl();
		case InputTweaks.ModifierKeyEnum.Move:
			if (!InputTweaks.InitialSwapMoveAndSplit)
			{
				return AnyCtrl();
			}
			return AnyShift();
		case InputTweaks.ModifierKeyEnum.Split:
			if (!InputTweaks.InitialSwapMoveAndSplit)
			{
				return AnyShift();
			}
			return AnyCtrl();
		case InputTweaks.ModifierKeyEnum.Shift:
			return AnyShift();
		default:
			if (!AnyAlt() && !AnyCommand() && !AnyCtrl())
			{
				return !AnyShift();
			}
			return false;
		}
	}

	public static void DebugMessage(string message)
	{
		if (InputTweaks.DebugMessages.Value)
		{
			Debug.Log((object)message);
		}
	}

	public static List<ItemData> EquivalentStackables(ItemData item, InventoryGrid grid)
	{
		int width = InputTweaks.InventoryGridPatch.Width(grid);
		return (from x in grid.GetInventory().GetAllItems()
			where CanStackOnto(x, item)
			orderby x.m_stack, x.m_gridPos.x + x.m_gridPos.y * width
			select x).ToList();
	}

	public static ItemData FindFirstSimilarItemInInventory(ItemData item, Inventory inv)
	{
		foreach (ItemData allItem in inv.GetAllItems())
		{
			if (item != allItem && item.m_shared.m_name.Equals(allItem.m_shared.m_name) && item.m_quality == allItem.m_quality)
			{
				return allItem;
			}
		}
		if (item.m_shared.m_maxStackSize == 1)
		{
			foreach (ItemData allItem2 in inv.GetAllItems())
			{
				if (item != allItem2 && item.m_shared.m_name.Equals(allItem2.m_shared.m_name))
				{
					return allItem2;
				}
			}
		}
		return null;
	}

	public static ItemData FindLargestPartialStack(ItemData item, InventoryGrid grid)
	{
		if (item.m_shared.m_maxStackSize == 1)
		{
			return null;
		}
		int width = InputTweaks.InventoryGridPatch.Width(grid);
		return ((IEnumerable<ItemData>)(from x in grid.GetInventory().GetAllItems()
			where ItemsAreSimilarButDistinct(item, x, considerQuality: true)
			orderby x.m_stack descending, x.m_gridPos.x + x.m_gridPos.y * width
			select x)).FirstOrDefault((Func<ItemData, bool>)((ItemData x) => x.m_stack < x.m_shared.m_maxStackSize));
	}

	public static ItemData FindSmallestPartialStack(ItemData item, InventoryGrid grid)
	{
		if (item.m_shared.m_maxStackSize == 1)
		{
			return null;
		}
		int width = InputTweaks.InventoryGridPatch.Width(grid);
		return ((IEnumerable<ItemData>)(from x in grid.GetInventory().GetAllItems()
			where ItemsAreSimilarButDistinct(item, x, considerQuality: true)
			orderby x.m_stack, x.m_gridPos.x + x.m_gridPos.y * width
			select x)).FirstOrDefault((Func<ItemData, bool>)((ItemData x) => x.m_stack < x.m_shared.m_maxStackSize));
	}

	public static bool IsCursorOver(GameObject go)
	{
		Transform obj = ((go != null) ? go.transform : null);
		return IsCursorOver((RectTransform)(object)((obj is RectTransform) ? obj : null));
	}

	public static bool IsCursorOver(RectTransform rectTransform)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)rectTransform != (Object)null)
		{
			return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Vector2.op_Implicit(Input.mousePosition));
		}
		return false;
	}

	public static bool ItemsAreSimilarButDistinct(ItemData item, ItemData other, bool considerQuality)
	{
		if (item != null && other != null && item != other && item.m_shared.m_name == other.m_shared.m_name)
		{
			if (considerQuality)
			{
				return item.m_quality == other.m_quality;
			}
			return true;
		}
		return false;
	}

	public static IEnumerable<CodeInstruction> SwapShiftAndCtrl(IEnumerable<CodeInstruction> instructionsIn)
	{
		foreach (CodeInstruction item in instructionsIn)
		{
			if (item.opcode == OpCodes.Ldc_I4 && (int)item.operand == 304)
			{
				item.operand = 306;
			}
			else if (item.opcode == OpCodes.Ldc_I4 && (int)item.operand == 303)
			{
				item.operand = 305;
			}
			else if (item.opcode == OpCodes.Ldc_I4 && (int)item.operand == 306)
			{
				item.operand = 304;
			}
			else if (item.opcode == OpCodes.Ldc_I4 && (int)item.operand == 305)
			{
				item.operand = 303;
			}
			yield return item;
		}
	}

	public static List<CodeInstruction> SwapMoveAndSplitInSwitch(IEnumerable<CodeInstruction> instructionsIn)
	{
		List<CodeInstruction> list = new List<CodeInstruction>(instructionsIn);
		for (int i = 0; i + 2 < list.Count; i++)
		{
			CodeInstruction obj = list[i];
			CodeInstruction val = list[i + 2];
			if (obj.opcode == OpCodes.Ldarg_S && val.opcode == OpCodes.Bne_Un)
			{
				CodeInstruction val2 = list[i + 1];
				if (val2.opcode == OpCodes.Ldc_I4_1)
				{
					val2.opcode = OpCodes.Ldc_I4_2;
				}
				else if (val2.opcode == OpCodes.Ldc_I4_2)
				{
					val2.opcode = OpCodes.Ldc_I4_1;
				}
			}
		}
		return list;
	}
}
public class InventoryButton
{
	public enum SelectionState
	{
		Normal,
		Highlighted,
		Pressed,
		Selected,
		Disabled
	}

	private static readonly PropertyInfo CurrentSelectionStateProperty;

	private static readonly MethodInfo DoStateTransitionMethod;

	public UIInputHandler inputHandler;

	public InventoryGrid grid;

	public Vector2i gridPos;

	public bool representsExistingItem;

	public bool considerForDrag;

	public ItemData curItem
	{
		get
		{
			if (!((Object)(object)grid != (Object)null))
			{
				return null;
			}
			return grid.GetInventory().GetItemAt(gridPos.x, gridPos.y);
		}
	}

	static InventoryButton()
	{
		CurrentSelectionStateProperty = AccessTools.Property(typeof(Selectable), "currentSelectionState");
		DoStateTransitionMethod = AccessTools.Method(typeof(Selectable), "DoStateTransition", new Type[2]
		{
			CurrentSelectionStateProperty.PropertyType,
			typeof(bool)
		}, (Type[])null);
	}

	public void SetSelectionState(SelectionState state, bool instant)
	{
		DoStateTransitionMethod.Invoke(((Component)inputHandler).GetComponent<Button>(), new object[2]
		{
			(int)state,
			instant
		});
	}
}
public struct Lockable<T>
{
	public T value;

	public T Value
	{
		get
		{
			return value;
		}
		set
		{
			if (!Locked)
			{
				this.value = value;
			}
		}
	}

	public bool Locked { get; set; }

	public Lockable(bool locked, T value)
	{
		Locked = locked;
		this.value = value;
	}
}
public class ContextState
{
	public bool Active { get; protected set; } = true;


	public bool Valid { get; protected set; } = true;


	public ContextState SetActive(bool value)
	{
		if (Active && !value)
		{
			Common.DebugMessage("CNTX: Changing state from Active to Inactive");
			Active = value;
		}
		return this;
	}

	public ContextState SetValid(bool value)
	{
		if (Valid && !value)
		{
			Common.DebugMessage("CNTX: Changing state from Valid to Invalid");
			Valid = value;
		}
		return this;
	}
}
public abstract class AbstractInventoryGuiCursorContext
{
	public enum State
	{
		ActiveValid,
		ActiveInvalid,
		DoneValid,
		DoneInvalid
	}

	public virtual State CurrentState { get; protected set; }

	protected virtual bool UserInputSatisfied()
	{
		return true;
	}

	public abstract State Think(VanillaDragState dragState);

	protected virtual State SetState(State state)
	{
		if (CurrentState != state)
		{
			Common.DebugMessage($"CNTX: Changing state from {CurrentState} to {state}");
			CurrentState = state;
		}
		return state;
	}

	public abstract void End();
}
public class BlockingCursorContext : AbstractInventoryGuiCursorContext
{
	protected Func<bool> blockRequirement;

	public BlockingCursorContext(Func<bool> blockRequirement)
	{
		this.blockRequirement = blockRequirement;
	}

	public override State Think(VanillaDragState dragState)
	{
		if (CurrentState == State.DoneValid || CurrentState == State.DoneInvalid)
		{
			return CurrentState;
		}
		if (FrameInputs.Current.None)
		{
			return SetState(State.DoneValid);
		}
		if (CurrentState == State.ActiveInvalid || (blockRequirement != null && !blockRequirement()))
		{
			return SetState(State.ActiveInvalid);
		}
		return SetState(State.ActiveValid);
	}

	public override void End()
	{
		Common.DebugMessage("CNTX: Ending BlockingCursorContext");
	}
}
public abstract class InventoryButtonTrackingContext : AbstractInventoryGuiCursorContext
{
	protected InventoryGrid playerGrid;

	protected List<InventoryButton> playerButtons;

	protected InventoryGrid containerGrid;

	protected List<InventoryButton> containerButtons;

	protected InventoryButton firstButton;

	protected InventoryButton previousButton;

	protected InventoryButton currentButton;

	protected List<InventoryButton> highlightedButtons = new List<InventoryButton>();

	public InventoryButtonTrackingContext(InventoryGrid playerGrid, List<InventoryButton> playerButtons, InventoryGrid containerGrid, List<InventoryButton> containerButtons)
	{
		if ((Object)(object)playerGrid == (Object)null || playerButtons == null || containerButtons == null)
		{
			Common.DebugMessage("CNTX: One or more null arguments");
			CurrentState = State.DoneInvalid;
			return;
		}
		this.playerGrid = playerGrid;
		this.playerButtons = playerButtons;
		this.containerGrid = containerGrid;
		this.containerButtons = containerButtons;
		firstButton = InputTweaks.InventoryGuiPatch.GetHoveredButton(this.playerGrid, this.containerGrid);
		if (firstButton == null)
		{
			Common.DebugMessage("CNTX: Started on a null button");
			CurrentState = State.DoneInvalid;
		}
		else
		{
			VanillaDragState vanillaDragState = new VanillaDragState();
			UpdateInventoryButtons(playerGrid, this.playerButtons, vanillaDragState.dragItem);
			UpdateInventoryButtons(containerGrid, this.containerButtons, vanillaDragState.dragItem);
		}
	}

	protected void UpdateInventoryButtons(InventoryGrid grid, List<InventoryButton> buttons, ItemData dragItem)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		Inventory inventory = grid.GetInventory();
		foreach (InventoryButton button in buttons)
		{
			Vector2i gridPos = button.gridPos;
			ItemData itemAt = inventory.GetItemAt(gridPos.x, gridPos.y);
			button.considerForDrag = itemAt == null || dragItem == null || itemAt == dragItem || Common.CanStackOnto(dragItem, itemAt);
			button.representsExistingItem = itemAt != null;
		}
	}

	public override State Think(VanillaDragState dragState)
	{
		if (CurrentState == State.DoneValid || CurrentState == State.DoneInvalid)
		{
			return CurrentState;
		}
		previousButton = currentButton;
		currentButton = InputTweaks.InventoryGuiPatch.GetHoveredButton(playerGrid, containerGrid);
		highlightedButtons.ForEach(delegate(InventoryButton x)
		{
			x.SetSelectionState(InventoryButton.SelectionState.Highlighted, instant: true);
		});
		return State.ActiveValid;
	}

	public override void End()
	{
		highlightedButtons.ForEach(delegate(InventoryButton x)
		{
			x.SetSelectionState(InventoryButton.SelectionState.Normal, instant: false);
		});
		highlightedButtons.Clear();
	}
}
public class MultiClickContext : InventoryButtonTrackingContext
{
	protected bool collected;

	public MultiClickContext(InventoryGrid playerGrid, List<InventoryButton> playerButtons, InventoryGrid containerGrid, List<InventoryButton> containerButtons)
		: base(playerGrid, playerButtons, containerGrid, containerButtons)
	{
		if (CurrentState == State.ActiveValid && firstButton == null)
		{
			SetState(State.ActiveInvalid);
		}
	}

	protected bool CollectFromInto(InventoryGrid grid, ItemData item)
	{
		List<ItemData> list = Common.EquivalentStackables(item, grid).ToList();
		Common.DebugMessage($"DBLC: Collecting {item} from {list.Count} equivalent stacks");
		Inventory inventory = grid.GetInventory();
		foreach (ItemData item2 in list)
		{
			int num = Mathf.Min(item.m_shared.m_maxStackSize - item.m_stack, item2.m_stack);
			Common.DebugMessage($"DBLC: Moving {num} item(s)");
			if (inventory.RemoveItem(item2, num))
			{
				item.m_stack += num;
			}
		}
		return item.m_stack < item.m_shared.m_maxStackSize;
	}

	public override State Think(VanillaDragState dragState)
	{
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		base.Think(dragState);
		if (CurrentState == State.DoneValid || CurrentState == State.DoneInvalid)
		{
			return CurrentState;
		}
		if (FrameInputs.Current.successiveClicks == 0)
		{
			return SetState((CurrentState == State.ActiveValid) ? State.DoneValid : State.DoneInvalid);
		}
		if (CurrentState == State.ActiveInvalid || !UserInputSatisfied() || currentButton != firstButton)
		{
			return SetState(State.ActiveInvalid);
		}
		if (collected)
		{
			return SetState(State.ActiveValid);
		}
		InventoryGrid grid = currentButton.grid;
		Inventory inventory = grid.GetInventory();
		Vector2i gridPos = currentButton.gridPos;
		ItemData itemAt = inventory.GetItemAt(gridPos.x, gridPos.y);
		if (itemAt == null)
		{
			return SetState(State.DoneInvalid);
		}
		if (itemAt.m_stack < itemAt.m_shared.m_maxStackSize)
		{
			InventoryGrid val = (((Object)(object)grid == (Object)(object)playerGrid) ? containerGrid : playerGrid);
			if (CollectFromInto(grid, itemAt))
			{
				CollectFromInto(val, itemAt);
			}
			InputTweaks.InventoryPatch.Changed(inventory);
			InputTweaks.InventoryPatch.Changed(val.GetInventory());
		}
		InputTweaks.InventoryGuiPatch.SetupDragItem(InventoryGui.instance, itemAt, inventory, itemAt.m_stack);
		collected = true;
		return SetState(State.ActiveValid);
	}

	public override void End()
	{
		Common.DebugMessage("CNTX: Ending MultiClickContext");
	}

	protected override bool UserInputSatisfied()
	{
		if (FrameInputs.Current.successiveClicks > 0)
		{
			return Common.CheckModifier(InputTweaks.ModifierKeyEnum.None);
		}
		return false;
	}
}
public class StackMoveContext : InventoryButtonTrackingContext
{
	public StackMoveContext(InventoryGrid playerGrid, List<InventoryButton> playerButtons, InventoryGrid containerGrid, List<InventoryButton> containerButtons)
		: base(playerGrid, playerButtons, containerGrid, containerButtons)
	{
	}

	public override State Think(VanillaDragState dragState)
	{
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		base.Think(dragState);
		if (CurrentState == State.DoneValid || CurrentState == State.DoneInvalid)
		{
			return CurrentState;
		}
		if (FrameInputs.Current.None)
		{
			return SetState(State.DoneValid);
		}
		if (dragState.isValid)
		{
			return SetState(State.DoneInvalid);
		}
		if (CurrentState == State.ActiveInvalid || !UserInputSatisfied())
		{
			return SetState(State.ActiveInvalid);
		}
		if (currentButton == null || currentButton == previousButton)
		{
			return SetState(State.ActiveValid);
		}
		if (currentButton != firstButton)
		{
			firstButton.SetSelectionState(InventoryButton.SelectionState.Normal, instant: false);
		}
		InventoryGrid grid = currentButton.grid;
		Inventory inventory = grid.GetInventory();
		Vector2i gridPos = currentButton.gridPos;
		ItemData itemAt = inventory.GetItemAt(gridPos.x, gridPos.y);
		grid.m_onSelected(grid, itemAt, gridPos, (Modifier)2);
		return SetState(State.ActiveValid);
	}

	public override void End()
	{
		Common.DebugMessage("CNTX: Ending StackMoveContext");
		base.End();
		VanillaDragState.ClearDrag();
	}

	protected override bool UserInputSatisfied()
	{
		if (FrameInputs.Current.LeftOnly && Common.CheckModifier(InputTweaks.ModifierKeyEnum.Move))
		{
			return !Common.CheckModifier(InputTweaks.ModifierKeyEnum.Split);
		}
		return false;
	}
}
public class FilteredStackMoveContext : InventoryButtonTrackingContext
{
	protected string itemName;

	public FilteredStackMoveContext(InventoryGrid playerGrid, List<InventoryButton> playerButtons, InventoryGrid containerGrid, List<InventoryButton> containerButtons)
		: base(playerGrid, playerButtons, containerGrid, containerButtons)
	{
		if (CurrentState != State.DoneValid || CurrentState != State.DoneInvalid)
		{
			itemName = firstButton.curItem?.m_shared?.m_name;
			if (itemName == null)
			{
				SetState(State.DoneInvalid);
			}
		}
	}

	public override State Think(VanillaDragState dragState)
	{
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		base.Think(dragState);
		if (CurrentState == State.DoneValid || CurrentState == State.DoneInvalid)
		{
			return CurrentState;
		}
		if (FrameInputs.Current.None)
		{
			return SetState(State.DoneValid);
		}
		if (dragState.isValid)
		{
			return SetState(State.DoneInvalid);
		}
		if (CurrentState == State.ActiveInvalid || !UserInputSatisfied())
		{
			return SetState(State.ActiveInvalid);
		}
		if (currentButton == null || currentButton == previousButton)
		{
			return SetState(State.ActiveValid);
		}
		if (currentButton != firstButton)
		{
			firstButton.SetSelectionState(InventoryButton.SelectionState.Normal, instant: false);
		}
		InventoryGrid grid = currentButton.grid;
		Inventory inventory = grid.GetInventory();
		Vector2i gridPos = currentButton.gridPos;
		ItemData itemAt = inventory.GetItemAt(gridPos.x, gridPos.y);
		if (itemAt != null && itemAt.m_shared.m_name.Equals(itemName))
		{
			grid.m_onSelected(grid, itemAt, gridPos, (Modifier)2);
		}
		return SetState(State.ActiveValid);
	}

	public override void End()
	{
		Common.DebugMessage("CNTX: Ending FilteredStackMoveContext");
		base.End();
		VanillaDragState.ClearDrag();
	}

	protected override bool UserInputSatisfied()
	{
		if (FrameInputs.Current.LeftOnly && Common.AnyShift())
		{
			return Common.AnyCtrl();
		}
		return false;
	}
}
public class StackSmearContext : InventoryButtonTrackingContext
{
	protected List<InventoryButton> smearedButtons = new List<InventoryButton>();

	protected Inventory swappedInv;

	protected Vector2i swappedPos;

	public StackSmearContext(InventoryGrid playerGrid, List<InventoryButton> playerButtons, InventoryGrid containerGrid, List<InventoryButton> containerButtons, Inventory swappedInv, Vector2i swappedPos)
		: base(playerGrid, playerButtons, containerGrid, containerButtons)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		if (CurrentState == State.DoneInvalid || VanillaDragState.IsValid())
		{
			CurrentState = State.DoneInvalid;
			return;
		}
		firstButton.considerForDrag = false;
		smearedButtons.Add(firstButton);
		this.swappedInv = swappedInv;
		this.swappedPos = swappedPos;
		if ((firstButton.curItem?.m_stack ?? 0) <= 1)
		{
			CurrentState = State.DoneValid;
		}
	}

	public override State Think(VanillaDragState dragState)
	{
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		base.Think(dragState);
		if (CurrentState == State.DoneValid || CurrentState == State.DoneInvalid)
		{
			return CurrentState;
		}
		if (FrameInputs.Current.None)
		{
			return SetState(State.DoneValid);
		}
		if (dragState.isValid)
		{
			return SetState(State.DoneInvalid);
		}
		if (CurrentState == State.ActiveInvalid || !UserInputSatisfied())
		{
			return SetState(State.ActiveInvalid);
		}
		if (currentButton == null || currentButton == previousButton || currentButton == firstButton || !currentButton.considerForDrag)
		{
			return SetState(State.ActiveValid);
		}
		ItemData curItem = currentButton.curItem;
		if (curItem == null || Common.CanStackOnto(firstButton.curItem, curItem))
		{
			Vector2i gridPos = currentButton.gridPos;
			Common.DebugMessage($"CNTX: Left, into ({gridPos})");
			currentButton.SetSelectionState(InventoryButton.SelectionState.Highlighted, instant: true);
			currentButton.considerForDrag = false;
			highlightedButtons.Add(currentButton);
			smearedButtons.Add(currentButton);
		}
		else
		{
			Common.DebugMessage($"CNTX: Cannot stack {firstButton.curItem} onto {curItem}");
		}
		return SetState(State.ActiveValid);
	}

	public override void End()
	{
		//IL_0049: 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_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		Common.DebugMessage("CNTX: Ending StackSmearContext");
		bool flag = true;
		if (CurrentState == State.DoneValid)
		{
			if (smearedButtons.Count == 1)
			{
				if (InputTweaks.SelectSwappedItem.Value && swappedInv != null && firstButton.gridPos != swappedPos)
				{
					ItemData curItem = firstButton.curItem;
					ItemData itemAt = swappedInv.GetItemAt(swappedPos.x, swappedPos.y);
					if (itemAt != null && !Common.CanStackOnto(curItem, itemAt))
					{
						Common.DebugMessage("INFO: Selecting swapped item");
						InputTweaks.InventoryGuiPatch.SetupDragItem(InventoryGui.instance, itemAt, swappedInv, itemAt.m_stack);
						flag = false;
					}
				}
			}
			else
			{
				ItemData val = firstButton?.curItem;
				if (val != null)
				{
					int num = Mathf.Max(1, Mathf.FloorToInt((float)val.m_stack / (float)smearedButtons.Count));
					int num2 = val.m_stack - num;
					foreach (InventoryButton smearedButton in smearedButtons)
					{
						if (smearedButton != firstButton)
						{
							if (val.m_stack < 2 * num)
							{
								break;
							}
							Inventory inventory = smearedButton.grid.GetInventory();
							Vector2i gridPos = smearedButton.gridPos;
							if (InputTweaks.InventoryGuiPatch.AddItem(inventory, val, num, gridPos.x, gridPos.y))
							{
								num2 -= num;
							}
						}
					}
					if (InputTweaks.KeepRemainderOnCursor.Value && num2 > 0)
					{
						InputTweaks.InventoryGuiPatch.SetupDragItem(InventoryGui.instance, val, firstButton.grid.GetInventory(), num2);
						flag = false;
					}
				}
			}
		}
		base.End();
		if (flag)
		{
			VanillaDragState.ClearDrag();
		}
	}

	protected override bool UserInputSatisfied()
	{
		if (FrameInputs.Current.LeftOnly)
		{
			return Common.CheckModifier(InputTweaks.ModifierKeyEnum.None);
		}
		return false;
	}
}
public class StackCollectContext : InventoryButtonTrackingContext
{
	public StackCollectContext(InventoryGrid playerGrid, List<InventoryButton> playerButtons, InventoryGrid containerGrid, List<InventoryButton> containerButtons)
		: base(playerGrid, playerButtons, containerGrid, containerButtons)
	{
		if (CurrentState == State.DoneInvalid || !VanillaDragState.IsValid())
		{
			CurrentState = State.DoneInvalid;
		}
	}

	public override State Think(VanillaDragState dragState)
	{
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		base.Think(dragState);
		if (CurrentState == State.DoneValid || CurrentState == State.DoneInvalid)
		{
			return CurrentState;
		}
		if (FrameInputs.Current.None)
		{
			return SetState(State.DoneValid);
		}
		if (!dragState.isValid)
		{
			return SetState(State.DoneInvalid);
		}
		if (CurrentState == State.ActiveInvalid || !UserInputSatisfied())
		{
			return SetState(State.ActiveInvalid);
		}
		if (currentButton == null || currentButton == previousButton || currentButton == firstButton)
		{
			return SetState(State.ActiveValid);
		}
		ItemData curItem = currentButton.curItem;
		ItemData curItem2 = firstButton.curItem;
		if (Common.CanStackOnto(curItem, curItem2))
		{
			Common.DebugMessage($"CNTX: Left, from ({currentButton.gridPos})");
			Inventory inventory = currentButton.grid.GetInventory();
			Inventory inventory2 = firstButton.grid.GetInventory();
			int num = Mathf.Min(curItem2.m_shared.m_maxStackSize - curItem2.m_stack, curItem.m_stack);
			Common.DebugMessage($"CNTX: Moving {num} item(s)");
			if (inventory.RemoveItem(curItem, num))
			{
				curItem2.m_stack += num;
				if (dragState.Increment(num))
				{
					dragState = new VanillaDragState();
					dragState.UpdateTooltip();
					UITooltip.HideTooltip();
				}
				if (inventory2 != inventory)
				{
					InputTweaks.InventoryPatch.Changed(inventory2);
				}
			}
		}
		else
		{
			Common.DebugMessage($"CNTX: Cannot stack {curItem} onto {curItem2}");
		}
		return SetState(State.ActiveValid);
	}

	public override void End()
	{
		Common.DebugMessage("CNTX: Ending StackCollectContext");
		base.End();
	}

	protected override bool UserInputSatisfied()
	{
		if (FrameInputs.Current.LeftOnly)
		{
			return Common.CheckModifier(InputTweaks.ModifierKeyEnum.None);
		}
		return false;
	}
}
public class SingleSmearContext : InventoryButtonTrackingContext
{
	public SingleSmearContext(InventoryGrid playerGrid, List<InventoryButton> playerButtons, InventoryGrid containerGrid, List<InventoryButton> containerButtons)
		: base(playerGrid, playerButtons, containerGrid, containerButtons)
	{
	}

	public override State Think(VanillaDragState dragState)
	{
		//IL_009e: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		base.Think(dragState);
		if (CurrentState == State.DoneValid || CurrentState == State.DoneInvalid)
		{
			return CurrentState;
		}
		if (FrameInputs.Current.None || !dragState.isValid)
		{
			return SetState(State.DoneValid);
		}
		if (CurrentState == State.ActiveInvalid || !UserInputSatisfied())
		{
			return SetState(State.ActiveInvalid);
		}
		if (currentButton == null || currentButton == previousButton || !currentButton.considerForDrag)
		{
			return SetState(State.ActiveValid);
		}
		Inventory inventory = currentButton.grid.GetInventory();
		ItemData dragItem = dragState.dragItem;
		Vector2i gridPos = currentButton.gridPos;
		bool flag = false;
		if (!InputTweaks.InventoryGuiPatch.AddItem(inventory, dragItem, 1, gridPos.x, gridPos.y))
		{
			if (currentButton.curItem != dragItem)
			{
				return SetState(State.ActiveValid);
			}
			flag = true;
		}
		Common.DebugMessage($"CNTX: Right, into ({gridPos})");
		currentButton.SetSelectionState(InventoryButton.SelectionState.Highlighted, instant: true);
		currentButton.considerForDrag = false;
		highlightedButtons.Add(currentButton);
		if (!flag && dragState.dragItem.m_stack <= 0)
		{
			Inventory inventory2 = playerGrid.GetInventory();
			(inventory2.ContainsItem(dragItem) ? inventory2 : containerGrid.GetInventory()).RemoveItem(dragItem);
		}
		if (dragState.Decrement())
		{
			new VanillaDragState().UpdateTooltip();
		}
		return SetState(State.ActiveValid);
	}

	public override void End()
	{
		Common.DebugMessage("CNTX: Ending SingleSmearContext");
		base.End();
	}

	protected override bool UserInputSatisfied()
	{
		if (FrameInputs.Current.RightOnly)
		{
			return Common.CheckModifier(InputTweaks.ModifierKeyEnum.None);
		}
		return false;
	}
}
public class VanillaDragState
{
	public readonly GameObject dragObject;

	public readonly Inventory dragInventory;

	public readonly ItemData dragItem;

	public readonly int dragAmount;

	public readonly bool isValid;

	public VanillaDragState()
	{
		InventoryGui instance = InventoryGui.instance;
		dragObject = Traverse.Create((object)instance).Field("m_dragGo").GetValue<GameObject>();
		if ((Object)(object)dragObject == (Object)null)
		{
			dragInventory = null;
			dragItem = null;
			dragAmount = 0;
		}
		else
		{
			dragInventory = Traverse.Create((object)instance).Field("m_dragInventory").GetValue<Inventory>();
			dragItem = Traverse.Create((object)instance).Field("m_dragItem").GetValue<ItemData>();
			dragAmount = Traverse.Create((object)instance).Field("m_dragAmount").GetValue<int>();
			isValid = (Object)(object)dragObject != (Object)null && dragInventory != null && dragItem != null && dragAmount > 0 && dragInventory.ContainsItem(dragItem);
		}
	}

	protected VanillaDragState(GameObject dragObject, Inventory dragInventory, ItemData dragItem, int dragAmount, bool isValid)
	{
		this.dragObject = dragObject;
		this.dragInventory = dragInventory;
		this.dragItem = dragItem;
		this.dragAmount = dragAmount;
		this.isValid = isValid;
	}

	public VanillaDragState Clone()
	{
		return new VanillaDragState(dragObject, dragInventory, dragItem, dragAmount, isValid);
	}

	public bool Increment(int count = 1)
	{
		Common.DebugMessage("INFO: VanillaDragState.Increment()");
		if (!isValid)
		{
			return false;
		}
		Traverse.Create((object)InventoryGui.instance).Field("m_dragAmount").SetValue((object)(dragAmount + count));
		return true;
	}

	public bool Decrement(int count = 1)
	{
		Common.DebugMessage("INFO: VanillaDragState.Decrement()");
		if (!isValid)
		{
			return false;
		}
		Traverse.Create((object)InventoryGui.instance).Field("m_dragAmount").SetValue((object)(dragAmount - count));
		return true;
	}

	public void UpdateTooltip()
	{
		Common.DebugMessage("INFO: VanillaDragState.UpdateTooltip()");
		if (isValid)
		{
			((Component)dragObject.transform.Find("icon")).GetComponent<Image>().sprite = dragItem.GetIcon();
			((Component)dragObject.transform.Find("name")).GetComponent<TMP_Text>().text = dragItem.m_shared.m_name;
			TMP_Text component = ((Component)dragObject.transform.Find("amount")).GetComponent<TMP_Text>();
			object text;
			if (dragAmount <= 1)
			{
				text = "";
			}
			else
			{
				int num = dragAmount;
				text = num.ToString();
			}
			component.text = (string)text;
		}
	}

	public static void ClearDrag()
	{
		InputTweaks.InventoryGuiPatch.SetupDragItem(InventoryGui.instance, null, null, 1);
	}

	public static bool IsValid()
	{
		return new VanillaDragState().isValid;
	}
}
public class FrameInputs
{
	public enum ButtonDelta
	{
		None,
		Pressed,
		Held,
		Released
	}

	public const int LeftButton = 0;

	public const int RightButton = 1;

	public const int AllButtons = 2;

	public static FrameInputs Prior = null;

	public static FrameInputs Current = new FrameInputs(skipInit: true);

	public static double FrameTimeOfLastUpdate = 0.0;

	private static double LeftDownLast;

	private static Vector2i SuccessiveClicksFirstPos;

	private static int SuccessiveClicks;

	private readonly int mouseButtons;

	private readonly ButtonDelta[] buttonDeltas = new ButtonDelta[2];

	public readonly Vector2i mousePos;

	public readonly bool isDoubleClick;

	public readonly int successiveClicks;

	public bool Left => Test(0);

	public bool Right => Test(1);

	public bool LeftOnly => Only(0);

	public bool RightOnly => Only(1);

	public bool None => mouseButtons == 0;

	public bool Any => mouseButtons > 0;

	public bool Exclusive => (mouseButtons & (mouseButtons - 1)) == 0;

	public ButtonDelta LeftDelta => buttonDeltas[0];

	public ButtonDelta RightDelta => buttonDeltas[1];

	protected FrameInputs(bool skipInit)
	{
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: 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_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		if (skipInit)
		{
			return;
		}
		for (int i = 0; i < 2; i++)
		{
			mouseButtons |= (ZInput.GetMouseButton(i) ? (1 << i) : 0);
			buttonDeltas[i] = (Test(i) ? ((!Prior.Test(i)) ? ButtonDelta.Pressed : ButtonDelta.Held) : (Prior.Test(i) ? ButtonDelta.Released : ButtonDelta.None));
		}
		mousePos = new Vector2i(Input.mousePosition);
		double timeAsDouble = Time.timeAsDouble;
		double num = timeAsDouble - LeftDownLast;
		if (LeftDelta == ButtonDelta.Pressed)
		{
			LeftDownLast = timeAsDouble;
			if (SuccessiveClicks == 0)
			{
				SuccessiveClicksFirstPos = mousePos;
				SuccessiveClicks++;
			}
			else
			{
				Vector2i val = mousePos - SuccessiveClicksFirstPos;
				if (((Vector2i)(ref val)).Magnitude() < InputTweaks.SuccessiveClickRadius.Value)
				{
					SuccessiveClicks++;
					Common.DebugMessage($"DBLC: SuccessiveClicks {SuccessiveClicks}");
				}
				else
				{
					SuccessiveClicksFirstPos = mousePos;
					SuccessiveClicks = 1;
					Common.DebugMessage("DBLC: SuccessiveClicks reset (distance)");
				}
			}
		}
		else if (LeftDelta == ButtonDelta.None && num > (double)InputTweaks.SuccessiveClickWindow.Value && SuccessiveClicks > 0)
		{
			SuccessiveClicks = 0;
			Common.DebugMessage("DBLC: SuccessiveClicks reset (time)");
		}
		successiveClicks = SuccessiveClicks;
		isDoubleClick = successiveClicks == 2;
	}

	public bool Test(int mouseButton)
	{
		return (mouseButtons & (1 << mouseButton)) > 0;
	}

	public bool Only(int mouseButton)
	{
		int num = 1 << mouseButton;
		return (mouseButtons & num) == num;
	}

	public ButtonDelta Delta(int mouseButton)
	{
		if (!Current.Test(mouseButton))
		{
			if (!Prior.Test(mouseButton))
			{
				return ButtonDelta.None;
			}
			return ButtonDelta.Released;
		}
		if (!Prior.Test(mouseButton))
		{
			return ButtonDelta.Pressed;
		}
		return ButtonDelta.Held;
	}

	public static bool Update()
	{
		double timeAsDouble = Time.timeAsDouble;
		if (timeAsDouble == FrameTimeOfLastUpdate)
		{
			return false;
		}
		Prior = Current;
		Current = new FrameInputs(skipInit: false);
		FrameTimeOfLastUpdate = timeAsDouble;
		return true;
	}
}