Decompiled source of InventoryControls v1.6.1

BepInEx/plugins/InventoryControls/InventoryControls.dll

Decompiled 4 days 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.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ByteSizeMetal")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 ByteSizeMetal")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0")]
[assembly: AssemblyProduct("Inventory Controls")]
[assembly: AssemblyTitle("InventoryControls")]
[assembly: AssemblyMetadata("Author", "ByteSizeMetal")]
[assembly: AssemblyVersion("1.4.0.0")]
[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 InventoryControls
{
	public enum ControllerButton
	{
		None,
		DpadLeft,
		DpadRight,
		DpadUp,
		DpadDown,
		LeftShoulder,
		RightShoulder,
		LeftTrigger,
		RightTrigger,
		LeftStick,
		RightStick,
		South,
		East,
		West,
		North,
		Start,
		Select
	}
	public enum WheelBinding
	{
		None,
		Up,
		Down
	}
	internal sealed class ActionBinding
	{
		private readonly ConfigEntry<KeyCode> _keyboard;

		private readonly ConfigEntry<KeyCode> _keyModifier;

		private readonly ConfigEntry<KeyCode> _keyModifier2;

		private readonly ConfigEntry<ControllerButton> _controller;

		private readonly ConfigEntry<ControllerButton> _modifier;

		private readonly ConfigEntry<WheelBinding> _wheel;

		private KeyCode _mainKey;

		private KeyCode[] _modifiers = Array.Empty<KeyCode>();

		private static readonly Dictionary<KeyCode, Key> KeyCache = new Dictionary<KeyCode, Key>();

		internal ActionBinding(ConfigFile config, string name, KeyCode keyboard, ControllerButton controller)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			string text = "Bindings - " + name;
			KeyboardShortcut value = config.Bind<KeyboardShortcut>(text, "Keyboard or mouse", new KeyboardShortcut(keyboard, Array.Empty<KeyCode>()), "Legacy shortcut retained for migration. Use Keyboard / Mouse Key and modifier settings instead.").Value;
			KeyCode[] array = ((KeyboardShortcut)(ref value)).Modifiers.ToArray();
			_keyboard = config.Bind<KeyCode>(text, "Keyboard / Mouse Key", ((KeyboardShortcut)(ref value)).MainKey, "Choose a keyboard key or Mouse0 through Mouse4. None disables the keyboard/mouse binding.");
			_keyModifier = config.Bind<KeyCode>(text, "Keyboard Modifier", (KeyCode)((array.Length != 0) ? ((int)array[0]) : 0), "Optional key that must also be held, for example LeftShift or LeftControl. None means no modifier.");
			_keyModifier2 = config.Bind<KeyCode>(text, "Keyboard Modifier 2", (KeyCode)((array.Length > 1) ? ((int)array[1]) : 0), "Optional second modifier key for a three-key shortcut.");
			_controller = config.Bind<ControllerButton>(text, "Controller button", controller, "Choose a controller button. South = Xbox A / PlayStation Cross; East = B / Circle; West = X / Square; North = Y / Triangle. None disables it.");
			_modifier = config.Bind<ControllerButton>(text, "Controller modifier", ControllerButton.None, "Optional controller button that must also be held.");
			_wheel = config.Bind<WheelBinding>(text, "Mouse wheel", WheelBinding.None, "Optional mouse-wheel direction. Does not require a keyboard shortcut.");
			CacheShortcut();
			_keyboard.SettingChanged += delegate
			{
				CacheShortcut();
			};
			_keyModifier.SettingChanged += delegate
			{
				CacheShortcut();
			};
			_keyModifier2.SettingChanged += delegate
			{
				CacheShortcut();
			};
		}

		private void CacheShortcut()
		{
			//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_0017: 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)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected I4, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected I4, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected I4, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected I4, but got Unknown
			_mainKey = _keyboard.Value;
			if ((int)_keyModifier.Value == 0)
			{
				_modifiers = (KeyCode[])(((int)_keyModifier2.Value == 0) ? ((Array)Array.Empty<KeyCode>()) : ((Array)new KeyCode[1] { (KeyCode)(int)_keyModifier2.Value }));
				return;
			}
			_modifiers = (KeyCode[])(object)(((int)_keyModifier2.Value != 0) ? new KeyCode[2]
			{
				(KeyCode)(int)_keyModifier.Value,
				(KeyCode)(int)_keyModifier2.Value
			} : new KeyCode[1] { (KeyCode)(int)_keyModifier.Value });
		}

		internal bool Pressed()
		{
			return Sample().AnyPressed;
		}

		internal BindingSample Sample()
		{
			//IL_0009: 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)
			BindingSample result = default(BindingSample);
			ButtonControl val = KeyButton(_mainKey);
			if (val != null)
			{
				result.Connected |= BindingSource.KeyboardMouse;
				bool flag = true;
				for (int i = 0; i < _modifiers.Length; i++)
				{
					ButtonControl obj = KeyButton(_modifiers[i]);
					if (obj == null || !obj.isPressed)
					{
						flag = false;
						break;
					}
				}
				if (flag && val.wasPressedThisFrame)
				{
					result.Pressed |= BindingSource.KeyboardMouse;
				}
				if (flag && val.isPressed)
				{
					result.Held |= BindingSource.KeyboardMouse;
				}
			}
			ButtonControl val2 = PadButton(_controller.Value);
			int num;
			if (val2 != null)
			{
				result.Connected |= BindingSource.Controller;
				if (_modifier.Value != ControllerButton.None)
				{
					ButtonControl obj2 = PadButton(_modifier.Value);
					if (obj2 == null)
					{
						num = 0;
					}
					else
					{
						num = (obj2.isPressed ? 1 : 0);
						if (num != 0)
						{
							goto IL_00dc;
						}
					}
					goto IL_00f0;
				}
				num = 1;
				goto IL_00dc;
			}
			goto IL_0106;
			IL_00dc:
			if (val2.wasPressedThisFrame)
			{
				result.Pressed |= BindingSource.Controller;
			}
			goto IL_00f0;
			IL_0106:
			if (_wheel.Value != WheelBinding.None && Mouse.current != null)
			{
				float y = ((InputControl<Vector2>)(object)Mouse.current.scroll).ReadValue().y;
				if ((_wheel.Value == WheelBinding.Up) ? (y > 0f) : (y < 0f))
				{
					result.WheelPulse = true;
				}
			}
			return result;
			IL_00f0:
			if (num != 0 && val2.isPressed)
			{
				result.Held |= BindingSource.Controller;
			}
			goto IL_0106;
		}

		private unsafe static ButtonControl KeyButton(KeyCode code)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected I4, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Invalid comparison between Unknown and I4
			//IL_00e4: 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)
			//IL_0104: Expected I4, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected I4, but got Unknown
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)code == 0)
			{
				return null;
			}
			if ((int)code >= 323 && (int)code <= 327)
			{
				Mouse current = Mouse.current;
				if (current == null)
				{
					return null;
				}
				return (ButtonControl)((code - 323) switch
				{
					0 => current.leftButton, 
					1 => current.rightButton, 
					2 => current.middleButton, 
					3 => current.backButton, 
					_ => current.forwardButton, 
				});
			}
			Keyboard current2 = Keyboard.current;
			if (current2 == null)
			{
				return null;
			}
			if (KeyCache.TryGetValue(code, out var value))
			{
				if ((int)value != 0)
				{
					return (ButtonControl)(object)current2[value];
				}
				return null;
			}
			string text = ((object)(*(KeyCode*)(&code))/*cast due to .constrained prefix*/).ToString();
			if (text.StartsWith("Alpha", StringComparison.Ordinal))
			{
				text = "Digit" + text.Substring(5);
			}
			else if (text.StartsWith("Keypad", StringComparison.Ordinal))
			{
				text = "Numpad" + text.Substring(6);
			}
			if ((int)code != 13)
			{
				switch (code - 266)
				{
				default:
					switch (code - 305)
					{
					case 1:
						text = "LeftCtrl";
						break;
					case 0:
						text = "RightCtrl";
						break;
					case 5:
					case 6:
						text = "LeftMeta";
						break;
					case 4:
					case 7:
						text = "RightMeta";
						break;
					}
					break;
				case 0:
					text = "NumpadPeriod";
					break;
				case 1:
					text = "NumpadDivide";
					break;
				case 2:
					text = "NumpadMultiply";
					break;
				case 3:
					text = "NumpadMinus";
					break;
				case 4:
					text = "NumpadPlus";
					break;
				}
			}
			else
			{
				text = "Enter";
			}
			if (!Enum.TryParse<Key>(text, ignoreCase: true, out Key result))
			{
				result = (Key)0;
			}
			KeyCache[code] = result;
			if ((int)result == 0)
			{
				return null;
			}
			return (ButtonControl)(object)current2[result];
		}

		private static ButtonControl PadButton(ControllerButton binding)
		{
			Gamepad current = Gamepad.current;
			if (current == null)
			{
				return null;
			}
			return (ButtonControl)(binding switch
			{
				ControllerButton.DpadLeft => current.dpad.left, 
				ControllerButton.DpadRight => current.dpad.right, 
				ControllerButton.DpadUp => current.dpad.up, 
				ControllerButton.DpadDown => current.dpad.down, 
				ControllerButton.LeftShoulder => current.leftShoulder, 
				ControllerButton.RightShoulder => current.rightShoulder, 
				ControllerButton.LeftTrigger => current.leftTrigger, 
				ControllerButton.RightTrigger => current.rightTrigger, 
				ControllerButton.LeftStick => current.leftStickButton, 
				ControllerButton.RightStick => current.rightStickButton, 
				ControllerButton.South => current.buttonSouth, 
				ControllerButton.East => current.buttonEast, 
				ControllerButton.West => current.buttonWest, 
				ControllerButton.North => current.buttonNorth, 
				ControllerButton.Start => current.startButton, 
				ControllerButton.Select => current.selectButton, 
				_ => null, 
			});
		}
	}
	public sealed class HotbarHighlight : MaskableGraphic
	{
		internal float Thickness = 4f;

		protected override void OnPopulateMesh(VertexHelper mesh)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			mesh.Clear();
			Rect rect = ((Graphic)this).rectTransform.rect;
			Rect rect2 = rect;
			((Rect)(ref rect2)).xMin = ((Rect)(ref rect2)).xMin - 2f;
			((Rect)(ref rect2)).xMax = ((Rect)(ref rect2)).xMax + 2f;
			((Rect)(ref rect2)).yMin = ((Rect)(ref rect2)).yMin - 2f;
			((Rect)(ref rect2)).yMax = ((Rect)(ref rect2)).yMax + 2f;
			Border(mesh, rect2, Thickness + 3f, new Color(0.08f, 1f, 0.12f, 0.18f));
			Border(mesh, rect, Thickness, new Color(0.15f, 1f, 0.08f, 1f));
			((Rect)(ref rect)).xMin = ((Rect)(ref rect)).xMin + Thickness;
			((Rect)(ref rect)).xMax = ((Rect)(ref rect)).xMax - Thickness;
			((Rect)(ref rect)).yMin = ((Rect)(ref rect)).yMin + Thickness;
			((Rect)(ref rect)).yMax = ((Rect)(ref rect)).yMax - Thickness;
			Border(mesh, rect, 0.8f, new Color(0.7f, 1f, 0.55f, 0.9f));
		}

		private static void Border(VertexHelper mesh, Rect rect, float width, Color color)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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)
			if (!(((Rect)(ref rect)).width <= 0f) && !(((Rect)(ref rect)).height <= 0f))
			{
				float num = Mathf.Min(width, Mathf.Min(((Rect)(ref rect)).width, ((Rect)(ref rect)).height) * 0.5f);
				Quad(mesh, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMin, ((Rect)(ref rect)).xMax, ((Rect)(ref rect)).yMin + num, color);
				Quad(mesh, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMax - num, ((Rect)(ref rect)).xMax, ((Rect)(ref rect)).yMax, color);
				Quad(mesh, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMin + num, ((Rect)(ref rect)).xMin + num, ((Rect)(ref rect)).yMax - num, color);
				Quad(mesh, ((Rect)(ref rect)).xMax - num, ((Rect)(ref rect)).yMin + num, ((Rect)(ref rect)).xMax, ((Rect)(ref rect)).yMax - num, color);
			}
		}

		private static void Quad(VertexHelper mesh, float left, float bottom, float right, float top, Color color)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0020: 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)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!(right <= left) && !(top <= bottom))
			{
				int currentVertCount = mesh.currentVertCount;
				mesh.AddVert(new Vector3(left, bottom), Color32.op_Implicit(color), Vector4.op_Implicit(Vector2.zero));
				mesh.AddVert(new Vector3(left, top), Color32.op_Implicit(color), Vector4.op_Implicit(Vector2.zero));
				mesh.AddVert(new Vector3(right, top), Color32.op_Implicit(color), Vector4.op_Implicit(Vector2.zero));
				mesh.AddVert(new Vector3(right, bottom), Color32.op_Implicit(color), Vector4.op_Implicit(Vector2.zero));
				mesh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2);
				mesh.AddTriangle(currentVertCount, currentVertCount + 2, currentVertCount + 3);
			}
		}
	}
	internal static class HotbarLayout
	{
		internal const float Available = 660f;

		internal static float FitPadding(float padding, float width, int count)
		{
			if (count < 2 || width <= 660f)
			{
				return padding;
			}
			float num = padding - (width - 660f) / (2f * (float)(count - 1));
			if (!(num > 0f))
			{
				return 0f;
			}
			return num;
		}

		internal static int Rank(int ordinal, int mainOrdinal, int count)
		{
			if (count <= 0 || ordinal < 0 || ordinal >= count)
			{
				return -1;
			}
			if (mainOrdinal < 0 || mainOrdinal >= count)
			{
				return ordinal;
			}
			return (ordinal - mainOrdinal + count + (count - 1) / 2) % count;
		}
	}
	internal sealed class HotbarPresentation : IDisposable
	{
		private readonly FieldRef<InventorySpot, float> _offset = AccessTools.FieldRefAccess<InventorySpot, float>("layoutOffsetX");

		private readonly Action<InventorySpot, float> _setOffset = AccessTools.MethodDelegate<Action<InventorySpot, float>>(AccessTools.DeclaredMethod(typeof(InventorySpot), "LayoutOffsetSet", new Type[1] { typeof(float) }, (Type[])null), (object)null, true);

		private readonly FieldRef<InventoryUI, InventorySpot[]> _uiSpots = AccessTools.FieldRefAccess<InventoryUI, InventorySpot[]>("inventorySpots");

		private readonly FieldRef<InventoryUI, float[]> _slotX = AccessTools.FieldRefAccess<InventoryUI, float[]>("slotPositionsX");

		private readonly FieldRef<InventoryUI, float> _center = AccessTools.FieldRefAccess<InventoryUI, float>("slotCenterX");

		private readonly FieldRef<InventoryUI, float> _padding = AccessTools.FieldRefAccess<InventoryUI, float>("buttonPadding");

		private readonly FieldRef<InventoryUI, string[]> _previous = AccessTools.FieldRefAccess<InventoryUI, string[]>("previousBindings");

		private readonly Action<InventoryUI> _setup = AccessTools.MethodDelegate<Action<InventoryUI>>(AccessTools.DeclaredMethod(typeof(InventoryUI), "LayoutSetup", Type.EmptyTypes, (Type[])null), (object)null, true);

		private readonly InventorySpot[] _spots = (InventorySpot[])(object)new InventorySpot[9];

		private readonly float[] _baseOffsets = new float[9];

		private readonly float[] _ownOffsets = new float[9];

		private readonly float[] _positions = new float[9];

		private readonly int[] _indices = new int[9];

		private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];

		private InventoryUI _ui;

		private InventoryBattery[] _batteries = Array.Empty<InventoryBattery>();

		private Vector3[] _batteryOffsets = Array.Empty<Vector3>();

		private int _childCount = -1;

		private int _slotCount = -1;

		private HotbarHighlight _highlight;

		private RectTransform _highlightRect;

		private float _nativePadding;

		private float _fittedPadding = float.MaxValue;

		private void Relist(InventoryUI ui, int count)
		{
			InventorySpot[] array = _uiSpots.Invoke(ui);
			bool flag = array == null;
			if (array != null)
			{
				InventorySpot[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					if ((Object)(object)array2[i] == (Object)null)
					{
						flag = true;
					}
				}
			}
			if (flag || (array.Length != count && ((Component)ui).GetComponentsInChildren<InventorySpot>(true).Length != array.Length))
			{
				_setup(ui);
				InventorySpot[] array3 = _uiSpots.Invoke(ui);
				float[] array4 = _slotX.Invoke(ui);
				float num = 0f;
				for (int j = 0; j < array3.Length; j++)
				{
					array4[j] = ((SemiUI)array3[j]).showPosition.x;
					num += array4[j];
				}
				_center.Invoke(ui) = ((array3.Length == 0) ? 0f : (num / (float)array3.Length));
			}
		}

		private void SetPadding(InventoryUI ui, float value)
		{
			if (!Mathf.Approximately(_padding.Invoke(ui), value))
			{
				_padding.Invoke(ui) = value;
				string[] array = _previous.Invoke(ui);
				if (array != null)
				{
					Array.Clear(array, 0, array.Length);
				}
			}
		}

		internal void RestoreOffsets()
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < _spots.Length; i++)
			{
				InventorySpot val = _spots[i];
				if ((Object)(object)val != (Object)null && _ownOffsets[i] != 0f && Mathf.Abs(_offset.Invoke(val) - (_baseOffsets[i] + _ownOffsets[i])) < 0.01f)
				{
					_setOffset(val, _baseOffsets[i]);
				}
				_ownOffsets[i] = 0f;
			}
			for (int j = 0; j < _batteries.Length; j++)
			{
				if ((Object)(object)_batteries[j] != (Object)null && _batteryOffsets[j] != Vector3.zero)
				{
					Transform transform = ((Component)_batteries[j]).transform;
					transform.localPosition -= _batteryOffsets[j];
				}
				_batteryOffsets[j] = Vector3.zero;
			}
		}

		internal void Update(NativeInventory inventory, int mainSlot, bool enabled, bool center, bool highlight, float thickness, float padding, float spacing = 0f)
		{
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a7: Expected O, but got Unknown
			//IL_05af: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b9: Expected O, but got Unknown
			//IL_063c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0641: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_0648: Unknown result type (might be due to invalid IL or missing references)
			//IL_064a: Unknown result type (might be due to invalid IL or missing references)
			//IL_065f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Unknown result type (might be due to invalid IL or missing references)
			//IL_0669: Unknown result type (might be due to invalid IL or missing references)
			//IL_066b: Unknown result type (might be due to invalid IL or missing references)
			//IL_066d: Unknown result type (might be due to invalid IL or missing references)
			//IL_066f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Unknown result type (might be due to invalid IL or missing references)
			//IL_0678: Unknown result type (might be due to invalid IL or missing references)
			//IL_067a: Unknown result type (might be due to invalid IL or missing references)
			//IL_067f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_0694: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			RestoreOffsets();
			InventoryUI instance = InventoryUI.instance;
			if ((Object)(object)_ui != (Object)(object)instance)
			{
				if ((Object)(object)_highlight != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)_highlight).gameObject);
				}
				_highlight = null;
				_highlightRect = null;
				_ui = instance;
				_childCount = (_slotCount = -1);
				_batteries = Array.Empty<InventoryBattery>();
				_batteryOffsets = Array.Empty<Vector3>();
				_fittedPadding = float.MaxValue;
				if ((Object)(object)instance != (Object)null)
				{
					_nativePadding = _padding.Invoke(instance);
				}
			}
			if ((Object)(object)instance == (Object)null || !enabled)
			{
				if ((Object)(object)instance != (Object)null)
				{
					SetPadding(instance, _nativePadding);
				}
				if ((Object)(object)_highlight != (Object)null)
				{
					((Behaviour)_highlight).enabled = false;
				}
				return;
			}
			SetPadding(instance, Mathf.Min(_fittedPadding, _nativePadding + Mathf.Max(0f, spacing) * 0.5f));
			bool flag = false;
			for (int i = 0; i < _spots.Length; i++)
			{
				if ((Object)(object)_spots[i] != (Object)(object)inventory.SpotAt(i))
				{
					flag = true;
				}
			}
			Array.Clear(_spots, 0, _spots.Length);
			int num = 0;
			int num2 = -1;
			Transform val = null;
			bool flag2 = true;
			for (int j = 0; j < inventory.Count; j++)
			{
				InventorySpot val2 = inventory.SpotAt(j);
				if (!((Object)(object)val2 == (Object)null))
				{
					_spots[j] = val2;
					_indices[num] = j;
					_baseOffsets[j] = _offset.Invoke(val2);
					_positions[num] = ((SemiUI)val2).showPosition.x + _baseOffsets[j];
					if (num == 0)
					{
						val = ((Component)val2).transform.parent;
					}
					else if ((Object)(object)((Component)val2).transform.parent != (Object)(object)val)
					{
						flag2 = false;
					}
					if (j == mainSlot)
					{
						num2 = num;
					}
					num++;
				}
			}
			int childCount = ((Component)instance).transform.childCount;
			if (_childCount != childCount || _slotCount != num || flag)
			{
				Relist(instance, num);
				_batteries = ((Component)instance).GetComponentsInChildren<InventoryBattery>(true);
				_batteryOffsets = (Vector3[])(object)new Vector3[_batteries.Length];
				_childCount = childCount;
				_slotCount = num;
			}
			if (num > 1)
			{
				InventorySpot[] obj = _uiSpots.Invoke(instance);
				if (obj != null && obj.Length == num)
				{
					float num3 = float.MaxValue;
					float num4 = float.MinValue;
					for (int k = 0; k < num; k++)
					{
						num3 = Mathf.Min(num3, _positions[k]);
						num4 = Mathf.Max(num4, _positions[k]);
					}
					float num5 = num4 - num3;
					Transform transform = ((Component)_spots[_indices[0]]).transform;
					Transform obj2 = ((transform is RectTransform) ? transform : null);
					float num6;
					if (obj2 == null)
					{
						num6 = 0f;
					}
					else
					{
						Rect rect = ((RectTransform)obj2).rect;
						num6 = ((Rect)(ref rect)).width;
					}
					float width = num5 + num6;
					float num7 = HotbarLayout.FitPadding(_padding.Invoke(instance), width, num);
					if (num7 < _padding.Invoke(instance))
					{
						_fittedPadding = num7;
					}
				}
			}
			if (center && num2 >= 0 && flag2)
			{
				Array.Sort(_positions, 0, num);
				for (int l = 0; l < num; l++)
				{
					int num8 = _indices[l];
					InventorySpot val3 = _spots[num8];
					float num9 = ((SemiUI)val3).showPosition.x + _baseOffsets[num8];
					_ownOffsets[num8] = _positions[HotbarLayout.Rank(l, num2, num)] - num9;
					_setOffset(val3, _baseOffsets[num8] + _ownOffsets[num8]);
				}
				for (int m = 0; m < _batteries.Length; m++)
				{
					InventoryBattery val4 = _batteries[m];
					if (!((Object)(object)val4 == (Object)null) && !((Object)(object)((Component)val4).GetComponentInParent<InventorySpot>() != (Object)null))
					{
						int inventorySpot = val4.inventorySpot;
						if (inventorySpot >= 0 && inventorySpot < _spots.Length && !((Object)(object)_spots[inventorySpot] == (Object)null) && !((Object)(object)((Component)val4).transform.parent == (Object)null))
						{
							Vector3 val5 = ((Component)_spots[inventorySpot]).transform.parent.TransformVector(new Vector3(_ownOffsets[inventorySpot], 0f, 0f));
							_batteryOffsets[m] = ((Component)val4).transform.parent.InverseTransformVector(val5);
							Transform transform2 = ((Component)val4).transform;
							transform2.localPosition += _batteryOffsets[m];
						}
					}
				}
			}
			InventorySpot val6 = ((mainSlot >= 0 && mainSlot < _spots.Length) ? _spots[mainSlot] : null);
			if (!highlight || !inventory.CanAct || ((SemiUI)instance).isHidden || !((Object)(object)val6 != (Object)null) || !((Component)val6).gameObject.activeInHierarchy)
			{
				if ((Object)(object)_highlight != (Object)null)
				{
					((Behaviour)_highlight).enabled = false;
				}
				return;
			}
			Transform transform3 = ((Component)val6).transform;
			RectTransform val7 = (RectTransform)(object)((transform3 is RectTransform) ? transform3 : null);
			if (!((Object)(object)val7 == (Object)null))
			{
				if ((Object)(object)_highlight == (Object)null)
				{
					GameObject val8 = new GameObject("Inventory Controls Main Item", new Type[3]
					{
						typeof(RectTransform),
						typeof(CanvasRenderer),
						typeof(HotbarHighlight)
					});
					_highlightRect = (RectTransform)val8.transform;
					((Transform)_highlightRect).SetParent(((Component)instance).transform, false);
					_highlight = val8.GetComponent<HotbarHighlight>();
					((Graphic)_highlight).raycastTarget = false;
					val8.AddComponent<LayoutElement>().ignoreLayout = true;
				}
				((Behaviour)_highlight).enabled = true;
				if (((Transform)_highlightRect).GetSiblingIndex() != ((Component)instance).transform.childCount - 1)
				{
					((Transform)_highlightRect).SetAsLastSibling();
				}
				val7.GetWorldCorners(_corners);
				Vector3 val9 = ((Component)instance).transform.InverseTransformPoint(_corners[0]);
				Vector3 val10 = val9;
				for (int n = 1; n < 4; n++)
				{
					Vector3 val11 = ((Component)instance).transform.InverseTransformPoint(_corners[n]);
					val9 = Vector3.Min(val9, val11);
					val10 = Vector3.Max(val10, val11);
				}
				((Transform)_highlightRect).localPosition = (val9 + val10) * 0.5f;
				_highlightRect.sizeDelta = new Vector2(val10.x - val9.x + 2f * padding, val10.y - val9.y + 2f * padding);
				if (!Mathf.Approximately(_highlight.Thickness, thickness))
				{
					_highlight.Thickness = thickness;
					((Graphic)_highlight).SetVerticesDirty();
				}
			}
		}

		public void Dispose()
		{
			RestoreOffsets();
			if ((Object)(object)_ui != (Object)null)
			{
				SetPadding(_ui, _nativePadding);
			}
			if ((Object)(object)_highlight != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_highlight).gameObject);
			}
			_highlight = null;
			_highlightRect = null;
		}
	}
	internal static class InventoryCapacity
	{
		internal static int Limit(bool slrDetected, bool inventoryUpgradeEnabled, int upgradeLevel)
		{
			if (!(slrDetected && inventoryUpgradeEnabled))
			{
				return 3;
			}
			return 3 + Math.Min(6, Math.Max(0, upgradeLevel));
		}
	}
	internal sealed class InventoryCommands
	{
		private enum Phase
		{
			Idle,
			Storing,
			Drawing
		}

		private Phase _phase;

		private object _identity;

		private readonly Queue<int> _steps = new Queue<int>();

		private bool _putAway;

		private int _dropItem;

		private int _putAwayItem;

		private int _source;

		private int _target;

		private int _targetSlot = -1;

		private int _cursor = -1;

		private int _lastItem;

		private int _directSlot = -1;

		private float _deadline;

		private float _queuedUntil;

		public float Timeout = 2f;

		public string LastResult { get; private set; }

		public int MainSlot { get; private set; } = -1;

		public void Cancel()
		{
			_steps.Clear();
			_putAway = false;
			_phase = Phase.Idle;
			_source = (_target = (_dropItem = (_putAwayItem = 0)));
			_targetSlot = (_directSlot = -1);
		}

		public void SelectSlot(int slot, float now)
		{
			StopCycling();
			_directSlot = slot;
			_queuedUntil = now + Timeout * 2f;
		}

		public void StopCycling()
		{
			_steps.Clear();
			_putAway = false;
			_dropItem = (_putAwayItem = 0);
			_directSlot = -1;
			if (_phase == Phase.Storing)
			{
				_target = 0;
			}
		}

		public void Tick(IInventoryView view, float now, int direction, bool putAway, int dropItem = 0, int putAwayItem = 0)
		{
			if (_identity != view.Identity)
			{
				Cancel();
				int cursor = (MainSlot = -1);
				_cursor = cursor;
				_lastItem = 0;
				_identity = view.Identity;
			}
			if (!view.CanAct)
			{
				Cancel();
				return;
			}
			ObserveSelection(view);
			EnsureReadySelection(view);
			if (dropItem != 0)
			{
				_steps.Clear();
				_putAway = false;
				_putAwayItem = 0;
				_dropItem = dropItem;
				_directSlot = -1;
				if (_phase == Phase.Storing)
				{
					_target = 0;
				}
				_queuedUntil = now + Timeout;
			}
			else if (putAway)
			{
				_steps.Clear();
				_putAway = true;
				_putAwayItem = ((putAwayItem != 0) ? putAwayItem : view.Held);
				_dropItem = 0;
				_directSlot = -1;
				if (_phase == Phase.Storing)
				{
					_target = 0;
				}
				_queuedUntil = now + Timeout;
			}
			else if (direction != 0 && _steps.Count < 16)
			{
				_steps.Enqueue(Math.Sign(direction));
				_queuedUntil = now + Timeout * 2f;
				_directSlot = -1;
			}
			if (_phase != Phase.Idle && now > _deadline)
			{
				LastResult = "Timed out waiting for the game's inventory animation";
				Cancel();
				return;
			}
			if (_phase == Phase.Storing)
			{
				if (!view.StoredAndSettled(_source) || view.Held == _source)
				{
					return;
				}
				if (view.Held != 0)
				{
					LastResult = "Manual item change interrupted cycling";
					Cancel();
					return;
				}
				_phase = Phase.Idle;
				if (_target != 0 && !_putAway && _dropItem == 0)
				{
					if (view.Available(_targetSlot) && view.ItemAt(_targetSlot) == _target)
					{
						StartDraw(view, now, _targetSlot);
					}
					else
					{
						LastResult = "Target item changed while storing";
					}
					return;
				}
			}
			if (_phase == Phase.Drawing)
			{
				if (view.Held != _target || view.HeldBusy)
				{
					return;
				}
				_phase = Phase.Idle;
			}
			if (now > _queuedUntil)
			{
				_steps.Clear();
				_putAway = false;
				_dropItem = 0;
				_directSlot = -1;
			}
			if (view.HeldBusy)
			{
				return;
			}
			EnsureReadySelection(view);
			if (_dropItem != 0)
			{
				int dropItem2 = _dropItem;
				_dropItem = 0;
				if (view.Held != dropItem2)
				{
					LastResult = "Held item changed; drop cancelled";
				}
				else
				{
					LastResult = (view.DropHeld(dropItem2) ? "Dropped held item; removed from hotbar" : "Game rejected drop request");
				}
			}
			else if (_putAway)
			{
				_putAway = false;
				if (_putAwayItem != 0 && view.Held != _putAwayItem)
				{
					LastResult = "Held item changed; storage cancelled";
				}
				else if (view.Held == 0)
				{
					int num2 = SlotPolicy.Ready(view, _lastItem, _cursor);
					if (num2 >= 0)
					{
						StartDraw(view, now, num2);
					}
					else
					{
						LastResult = "No inventory item is ready yet";
					}
				}
				else if (!view.CanStoreHeld)
				{
					LastResult = "Held object cannot go in inventory";
				}
				else
				{
					int num3 = SlotPolicy.FirstFree(view);
					if (num3 < 0)
					{
						LastResult = "Inventory full; held item kept in hand";
					}
					else
					{
						StartStore(view, now, num3, -1);
					}
				}
			}
			else if (_directSlot >= 0)
			{
				Direct(view, now);
			}
			else
			{
				if (_steps.Count == 0)
				{
					return;
				}
				int direction2 = _steps.Dequeue();
				if (view.Held != 0)
				{
					if (!view.CanStoreHeld)
					{
						LastResult = "Held object cannot go in inventory";
						_steps.Clear();
						return;
					}
					int heldOrigin = view.HeldOrigin;
					int num4 = ((heldOrigin >= 0 && view.Available(heldOrigin) && view.ItemAt(heldOrigin) == 0) ? heldOrigin : SlotPolicy.FirstFree(view));
					if (num4 < 0)
					{
						LastResult = "Inventory full; held item kept in hand";
						_steps.Clear();
						return;
					}
					int num5 = SlotPolicy.Next(view, num4, direction2, num4);
					if (num5 < 0 || num5 == num4)
					{
						LastResult = "No other occupied slot";
					}
					else
					{
						StartStore(view, now, num4, num5);
					}
				}
				else
				{
					int num6 = SlotPolicy.Next(view, _cursor, direction2);
					if (num6 >= 0)
					{
						StartDraw(view, now, num6);
					}
					else
					{
						LastResult = "No occupied slots";
					}
				}
			}
		}

		private void Direct(IInventoryView view, float now)
		{
			int directSlot = _directSlot;
			int num = view.ItemAt(directSlot);
			if (num != 0 && !view.StoredAndSettled(num))
			{
				return;
			}
			_directSlot = -1;
			if (!view.Available(directSlot))
			{
				LastResult = "Slot is no longer available";
				return;
			}
			if (view.Held == 0)
			{
				if (num != 0)
				{
					StartDraw(view, now, directSlot);
				}
				return;
			}
			if (!view.CanStoreHeld)
			{
				LastResult = "Held object cannot go in inventory; kept in hand";
				return;
			}
			if (num == 0)
			{
				StartStore(view, now, directSlot, -1);
				return;
			}
			int heldOrigin = view.HeldOrigin;
			int num2 = ((heldOrigin >= 0 && view.Available(heldOrigin) && view.ItemAt(heldOrigin) == 0) ? heldOrigin : SlotPolicy.FirstFree(view));
			if (num2 < 0)
			{
				LastResult = "Inventory full; held item kept in hand";
			}
			else
			{
				StartStore(view, now, num2, directSlot);
			}
		}

		private int RememberedSlot(IInventoryView view)
		{
			if (_lastItem != 0)
			{
				for (int i = 0; i < view.Count; i++)
				{
					if (view.Available(i) && view.ItemAt(i) == _lastItem)
					{
						return i;
					}
				}
			}
			return -1;
		}

		private void ObserveSelection(IInventoryView view)
		{
			if (view.Held != 0 && view.CanStoreHeld)
			{
				if (_lastItem != view.Held)
				{
					_lastItem = view.Held;
					_cursor = -1;
				}
				if (view.Available(view.HeldOrigin))
				{
					_cursor = view.HeldOrigin;
				}
			}
			int num = RememberedSlot(view);
			if (num >= 0)
			{
				_cursor = num;
			}
			MainSlot = ((view.Available(_cursor) && (num >= 0 || (view.Held == _lastItem && view.CanStoreHeld))) ? _cursor : (-1));
		}

		private void EnsureReadySelection(IInventoryView view)
		{
			if (_phase == Phase.Idle && view.Held == 0 && !view.HeldBusy)
			{
				int num = SlotPolicy.Ready(view, _lastItem, _cursor);
				if (num >= 0)
				{
					_lastItem = view.ItemAt(num);
					_cursor = num;
				}
				MainSlot = num;
			}
		}

		private void StartStore(IInventoryView view, float now, int slot, int next)
		{
			int held = view.Held;
			int target = ((next >= 0) ? view.ItemAt(next) : 0);
			if (!view.Store(slot))
			{
				LastResult = "Game rejected storage request";
				return;
			}
			_source = held;
			_targetSlot = next;
			_target = target;
			_cursor = slot;
			_phase = Phase.Storing;
			_deadline = now + Timeout;
			LastResult = "Putting held item away";
		}

		private void StartDraw(IInventoryView view, float now, int slot)
		{
			int num = view.ItemAt(slot);
			if (num == 0 || !view.Draw(slot))
			{
				LastResult = "Game rejected selection request";
				return;
			}
			_target = num;
			_targetSlot = slot;
			_phase = Phase.Drawing;
			_deadline = now + Timeout;
			LastResult = "Selecting occupied slot " + (slot + 1);
		}
	}
	internal sealed class NativeInventory : IInventoryView
	{
		private readonly FieldRef<PhysGrabber, bool> _grabbed = AccessTools.FieldRefAccess<PhysGrabber, bool>("grabbed");

		private readonly FieldRef<PhysGrabber, PhysGrabObject> _grabbedObject = AccessTools.FieldRefAccess<PhysGrabber, PhysGrabObject>("grabbedPhysGrabObject");

		private readonly FieldRef<PhysGrabber, PhysGrabObject> _overrideObject = AccessTools.FieldRefAccess<PhysGrabber, PhysGrabObject>("overrideGrabTarget");

		private readonly FieldRef<ItemEquippable, bool> _equipping = AccessTools.FieldRefAccess<ItemEquippable, bool>("isEquipping");

		private readonly FieldRef<ItemEquippable, bool> _unequipping = AccessTools.FieldRefAccess<ItemEquippable, bool>("isUnequipping");

		private readonly FieldRef<ItemEquippable, int> _origin = AccessTools.FieldRefAccess<ItemEquippable, int>("inventorySpotIndex");

		private readonly FieldRef<PlayerAvatar, bool> _disabled = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isDisabled");

		private readonly FieldRef<PlayerController, float> _inputDisable = AccessTools.FieldRefAccess<PlayerController, float>("InputDisableTimer");

		private readonly FieldRef<StatsManager, SortedDictionary<string, Dictionary<string, int>>> _stats = AccessTools.FieldRefAccess<StatsManager, SortedDictionary<string, Dictionary<string, int>>>("dictionaryOfDictionaries");

		private readonly Func<ItemEquippable, int> _state = StateReader();

		private readonly InventorySpot[] _spots = (InventorySpot[])(object)new InventorySpot[9];

		private readonly Dictionary<int, int> _origins = new Dictionary<int, int>();

		private Inventory _inventory;

		private PhysGrabber _grabber;

		private ItemEquippable _held;

		private PhysGrabObject _heldObject;

		private bool _hasHeldObject;

		private ConfigEntry<bool> _slrEnabled;

		private bool _slrDetected;

		private string _steamId;

		public object Identity => _inventory;

		public bool CanAct { get; private set; }

		public int Count { get; private set; }

		public int Held
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_held))
				{
					if (!Object.op_Implicit((Object)(object)_heldObject))
					{
						return 0;
					}
					return ((Object)_heldObject).GetInstanceID();
				}
				return ((Object)_held).GetInstanceID();
			}
		}

		public bool CanStoreHeld
		{
			get
			{
				if (Object.op_Implicit((Object)(object)_held))
				{
					return !_inventory.IsItemEquipped(_held);
				}
				return false;
			}
		}

		public bool HeldBusy
		{
			get
			{
				if (!_hasHeldObject || _grabbed.Invoke(_grabber))
				{
					if (Object.op_Implicit((Object)(object)_held))
					{
						return Busy(_held);
					}
					return false;
				}
				return true;
			}
		}

		public int HeldOrigin
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_held) || !_origins.TryGetValue(((Object)_held).GetInstanceID(), out var value))
				{
					return -1;
				}
				return value;
			}
		}

		public NativeInventory()
		{
			try
			{
				_slrDetected = Chainloader.PluginInfos.TryGetValue("SolarAaron.SLRUpgradePack", out var value) && (Object)(object)value.Instance != (Object)null;
				if (_slrDetected)
				{
					object obj = AccessTools.Property(((object)value.Instance).GetType(), "InventorySlotUpgradeInstance")?.GetValue(null);
					if (obj != null)
					{
						_slrEnabled = AccessTools.Property(obj.GetType(), "UpgradeEnabled")?.GetValue(obj) as ConfigEntry<bool>;
					}
					Plugin.Log.LogInfo((object)((_slrEnabled != null) ? "Optional SLR inventory support enabled automatically (0.6.0 layout)." : "SLR inventory API unavailable; standalone controls remain active for vanilla slots."));
				}
				else
				{
					Plugin.Log.LogInfo((object)"SLRUpgradePack absent; standalone controls active for the three vanilla slots.");
				}
			}
			catch (Exception ex)
			{
				_slrEnabled = null;
				Plugin.Log.LogWarning((object)("Optional SLR support unavailable; standalone controls remain active. " + ex.GetBaseException().Message));
			}
		}

		internal static bool GameplayAvailable()
		{
			if (!Application.isFocused || Time.timeScale <= 0f || (Object)(object)Inventory.instance == (Object)null || (Object)(object)PhysGrabber.instance == (Object)null || (Object)(object)PlayerController.instance == (Object)null || (Object)(object)InputManager.instance == (Object)null)
			{
				return false;
			}
			InputAction action = InputManager.instance.GetAction((InputKey)19);
			if (action != null && action.enabled && SemiFunc.NoTextInputsActive() && SemiFunc.NoExternalTextInputActive() && !SemiFunc.IsSpectating())
			{
				return !SemiFunc.RunIsArena();
			}
			return false;
		}

		public void Refresh()
		{
			Inventory instance = Inventory.instance;
			if ((Object)(object)_inventory != (Object)(object)instance)
			{
				_inventory = instance;
				_origins.Clear();
				_steamId = null;
				Array.Clear(_spots, 0, _spots.Length);
			}
			_grabber = PhysGrabber.instance;
			_held = null;
			_heldObject = null;
			_hasHeldObject = false;
			CanAct = GameplayAvailable();
			Count = 0;
			if ((Object)(object)_inventory == (Object)null || (Object)(object)_grabber == (Object)null || (Object)(object)PlayerController.instance == (Object)null)
			{
				return;
			}
			PlayerAvatar val = SemiFunc.PlayerAvatarLocal();
			if ((Object)(object)val == (Object)null || _disabled.Invoke(val) || _inputDisable.Invoke(PlayerController.instance) > 0f)
			{
				CanAct = false;
			}
			if (_steamId == null && (Object)(object)val != (Object)null)
			{
				_steamId = SemiFunc.PlayerGetSteamID(val);
			}
			int value = 0;
			if (_slrEnabled != null && _slrEnabled.Value && (Object)(object)StatsManager.instance != (Object)null && _steamId != null)
			{
				SortedDictionary<string, Dictionary<string, int>> sortedDictionary = _stats.Invoke(StatsManager.instance);
				if (sortedDictionary != null && sortedDictionary.TryGetValue("playerUpgradeInventorySlot", out var value2))
				{
					value2.TryGetValue(_steamId, out value);
				}
			}
			int num = InventoryCapacity.Limit(_slrDetected, _slrEnabled?.Value ?? false, value);
			Array.Clear(_spots, 0, _spots.Length);
			List<InventorySpot> allSpots = _inventory.GetAllSpots();
			if (allSpots != null)
			{
				foreach (InventorySpot item in allSpots)
				{
					if ((Object)(object)item == (Object)null || !((Component)item).gameObject.activeInHierarchy)
					{
						continue;
					}
					int inventorySpotIndex = item.inventorySpotIndex;
					if (inventorySpotIndex >= 0 && inventorySpotIndex < num && inventorySpotIndex < _spots.Length)
					{
						_spots[inventorySpotIndex] = item;
						Count = Math.Max(Count, inventorySpotIndex + 1);
						if ((Object)(object)item.CurrentItem != (Object)null)
						{
							_origins[((Object)item.CurrentItem).GetInstanceID()] = inventorySpotIndex;
						}
					}
				}
			}
			PhysGrabObject val2 = (_grabbed.Invoke(_grabber) ? _grabbedObject.Invoke(_grabber) : _overrideObject.Invoke(_grabber));
			if ((Object)(object)val2 != (Object)null)
			{
				_heldObject = val2;
				_hasHeldObject = true;
				_held = ((Component)val2).GetComponent<ItemEquippable>();
				if ((Object)(object)_held != (Object)null && !_grabbed.Invoke(_grabber) && _inventory.IsItemEquipped(_held))
				{
					_held = null;
					_heldObject = null;
					_hasHeldObject = false;
				}
			}
		}

		public bool Available(int slot)
		{
			if (slot >= 0 && slot < Count)
			{
				return (Object)(object)_spots[slot] != (Object)null;
			}
			return false;
		}

		internal InventorySpot SpotAt(int slot)
		{
			if (!Available(slot))
			{
				return null;
			}
			return _spots[slot];
		}

		public int ItemAt(int slot)
		{
			if (!Available(slot) || !((Object)(object)_spots[slot].CurrentItem != (Object)null))
			{
				return 0;
			}
			return ((Object)_spots[slot].CurrentItem).GetInstanceID();
		}

		public bool StoredAndSettled(int id)
		{
			for (int i = 0; i < Count; i++)
			{
				if (ItemAt(i) == id)
				{
					return !Busy(_spots[i].CurrentItem);
				}
			}
			return false;
		}

		private bool Busy(ItemEquippable item)
		{
			int num = _state(item);
			if (num != 1 && num != 3 && !_equipping.Invoke(item))
			{
				return _unequipping.Invoke(item);
			}
			return true;
		}

		private static Func<ItemEquippable, int> StateReader()
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(ItemEquippable), "currentState");
			if (fieldInfo == null || !fieldInfo.FieldType.IsEnum || Enum.GetUnderlyingType(fieldInfo.FieldType) != typeof(int))
			{
				throw new MissingFieldException("ItemEquippable.currentState");
			}
			DynamicMethod dynamicMethod = new DynamicMethod("SLRInventoryControls_ReadItemState", typeof(int), new Type[1] { typeof(ItemEquippable) }, typeof(ItemEquippable), skipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<ItemEquippable, int>)dynamicMethod.CreateDelegate(typeof(Func<ItemEquippable, int>));
		}

		public bool Store(int slot)
		{
			if (!CanAct || !CanStoreHeld || HeldBusy || !Available(slot) || ItemAt(slot) != 0 || (Object)(object)_grabber.photonView == (Object)null)
			{
				return false;
			}
			_held.RequestEquip(slot, _grabber.photonView.ViewID);
			_origins[((Object)_held).GetInstanceID()] = slot;
			return true;
		}

		public bool Draw(int slot)
		{
			if (!CanAct || Held != 0 || !Available(slot) || ItemAt(slot) == 0 || Busy(_spots[slot].CurrentItem))
			{
				return false;
			}
			_spots[slot].CurrentItem.RequestUnequip();
			return true;
		}

		public bool DropHeld(int expectedItem)
		{
			if (!CanAct || expectedItem == 0 || Held != expectedItem || HeldBusy || !_grabbed.Invoke(_grabber))
			{
				return false;
			}
			if ((Object)(object)_held != (Object)null && _inventory.IsItemEquipped(_held))
			{
				return false;
			}
			_grabber.ReleaseObject(-1, 0.2f);
			_origins.Remove(expectedItem);
			return true;
		}

		internal void RememberSlot(ItemEquippable item)
		{
			if ((Object)(object)_inventory != (Object)null && (Object)(object)item != (Object)null && _inventory.IsItemEquipped(item))
			{
				int num = _origin.Invoke(item);
				if (num >= 0 && num < 9)
				{
					_origins[((Object)item).GetInstanceID()] = num;
				}
			}
		}
	}
	[BepInPlugin("local.SLRInventoryControls", "Inventory Controls", "1.6.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[DefaultExecutionOrder(10000)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "local.SLRInventoryControls";

		public const string Name = "Inventory Controls";

		public const string Version = "1.6.1";

		internal static ManualLogSource Log;

		private static Plugin _instance;

		private ConfigEntry<bool> _enabled;

		private ConfigEntry<bool> _debug;

		private ConfigEntry<bool> _centerMain;

		private ConfigEntry<bool> _highlightMain;

		private ConfigEntry<bool> _keepHeld;

		private ConfigEntry<float> _timeout;

		private ConfigEntry<float> _holdSeconds;

		private ConfigEntry<float> _outlineThickness;

		private ConfigEntry<float> _outlinePadding;

		private ActionBinding _left;

		private ActionBinding _right;

		private ActionBinding _stow;

		private NativeInventory _inventory;

		private HotbarPresentation _hotbar;

		private ConfigEntry<float> _slotSpacing;

		private readonly InventoryCommands _commands = new InventoryCommands();

		private readonly PutAwayGesture _gesture = new PutAwayGesture();

		private BindingSample _stowSample;

		private object _inventoryIdentity;

		private int _inputFrame = -1;

		private int _direction;

		private bool _ready;

		private bool _claimsInput;

		private float _retryAt;

		private string _lastResult;

		private void Awake()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Expected O, but got Unknown
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Expected O, but got Unknown
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Expected O, but got Unknown
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Expected O, but got Unknown
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Expected O, but got Unknown
			_instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable occupied-slot cycling, tap-to-store / re-equip, and hold-to-drop controls.");
			_timeout = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Switch timeout seconds", 2f, new ConfigDescription("Maximum wait for one inventory animation/network request. No item is dropped on timeout.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>()));
			_holdSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Hold to drop seconds", 0.4f, new ConfigDescription("Tap Put Away to store the held item in the first free slot, or re-equip the remembered / next ready hotbar item with empty hands. Hold this long to drop a held item instead. Mouse wheel always acts as a tap.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
			_keepHeld = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Never drop from slot keys", true, "Number and SLR slot keys swap items instead of dropping what you hold: it goes back to its slot, then the new item comes out. If that isn't possible, such as carrying a valuable or having a full inventory, what you hold stays in your hand. Letting go, holding Put Away, damage and physics still drop items as normal.");
			_debug = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Log actions", false, "Log command changes for testing. Keep off during normal play.");
			_centerMain = ((BaseUnityPlugin)this).Config.Bind<bool>("Hotbar", "Center main item", true, "Rotate displayed slot positions to keep the equipped / ready-to-re-equip item in the middle. Slot IDs, bindings and item ownership stay unchanged.");
			_highlightMain = ((BaseUnityPlugin)this).Config.Bind<bool>("Hotbar", "Highlight main item", true, "Draw a bright green border around the equipped / ready-to-re-equip slot.");
			_outlineThickness = ((BaseUnityPlugin)this).Config.Bind<float>("Hotbar", "Outline thickness", 4f, new ConfigDescription("Thickness of the bright green border in UI units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			_slotSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Hotbar", "Extra slot spacing", 8f, new ConfigDescription("Extra space between slots in UI units, so key labels clear the green border. The bar narrows itself if it would run off screen. 0 uses the game's spacing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 24f), Array.Empty<object>()));
			_outlinePadding = ((BaseUnityPlugin)this).Config.Bind<float>("Hotbar", "Outline padding", 4f, new ConfigDescription("Extra space around the selected slot's rectangle in UI units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 12f), Array.Empty<object>()));
			_left = new ActionBinding(((BaseUnityPlugin)this).Config, "Cycle Left", (KeyCode)91, ControllerButton.DpadLeft);
			_right = new ActionBinding(((BaseUnityPlugin)this).Config, "Cycle Right", (KeyCode)93, ControllerButton.DpadRight);
			_stow = new ActionBinding(((BaseUnityPlugin)this).Config, "Put Away", (KeyCode)96, ControllerButton.DpadDown);
			try
			{
				_inventory = new NativeInventory();
				Harmony val = new Harmony("local.SLRInventoryControls");
				val.Patch((MethodBase)AccessTools.Method(typeof(InventorySpot), "HandleInput", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "HandleInputPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)AccessTools.Method(typeof(ItemEquippable), "RequestUnequip", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "RememberOriginPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_ready = true;
				try
				{
					_hotbar = new HotbarPresentation();
					HarmonyMethod val2 = new HarmonyMethod(typeof(Plugin), "HotbarLayoutPrefix", (Type[])null)
					{
						priority = 800
					};
					string[] array = new string[3] { "LateUpdate", "LayoutSetup", "Start" };
					foreach (string text in array)
					{
						val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(InventoryUI), text, Type.EmptyTypes, (Type[])null), val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					if (Chainloader.PluginInfos.TryGetValue("SolarAaron.SLRUpgradePack", out var value) && (Object)(object)value.Instance != (Object)null)
					{
						Type type = ((object)value.Instance).GetType().Assembly.GetType("SLRUpgradePack.UpgradeManagers.InventoryUIStartPatch");
						MethodInfo methodInfo = ((type == null) ? null : AccessTools.DeclaredMethod(type, "Postfix", (Type[])null, (Type[])null));
						if (methodInfo != null)
						{
							val.Patch((MethodBase)methodInfo, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						}
					}
				}
				catch (Exception error)
				{
					DisableHotbar(error);
				}
				Log.LogInfo((object)"Ready. Standalone inventory controls active. Remap Cycle Left, Cycle Right and Put Away in REPOConfig / Inventory Controls. Optional SLR support activates automatically when detected.");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Inventory controls disabled: incompatible game/mod API. " + ex));
			}
		}

		private void ReadInput()
		{
			if (_inputFrame != Time.frameCount)
			{
				_inputFrame = Time.frameCount;
				_stowSample = _stow.Sample();
				bool flag = _left.Pressed();
				bool flag2 = _right.Pressed();
				bool flag3 = _stowSample.AnyPressed || _stowSample.AnyHeld || _gesture.Active;
				_claimsInput = flag3 || flag || flag2;
				_direction = ((!flag3 && flag != flag2) ? ((!flag) ? 1 : (-1)) : 0);
			}
		}

		private void LateUpdate()
		{
			if (!_ready || Time.unscaledTime < _retryAt)
			{
				UpdateHotbar(enabled: false);
				return;
			}
			try
			{
				ReadInput();
				_inventory.Refresh();
				_commands.Timeout = _timeout.Value;
				if (_inventoryIdentity != _inventory.Identity)
				{
					_gesture.Cancel();
					_commands.Cancel();
					_inventoryIdentity = _inventory.Identity;
				}
				if (!_enabled.Value || !_inventory.CanAct)
				{
					_gesture.Cancel();
					_commands.Cancel();
				}
				else
				{
					if (_stowSample.AnyPressed)
					{
						_commands.StopCycling();
					}
					PutAwayDecision putAwayDecision = _gesture.Tick(_stowSample, Time.unscaledTime, _holdSeconds.Value, _inventory.Held, canAct: true);
					_commands.Tick(_inventory, Time.unscaledTime, _direction, putAwayDecision.Action == PutAwayAction.Store, (putAwayDecision.Action == PutAwayAction.Drop) ? putAwayDecision.Item : 0, (putAwayDecision.Action == PutAwayAction.Store) ? putAwayDecision.Item : 0);
				}
				if (_debug.Value && _commands.LastResult != _lastResult && _commands.LastResult != null)
				{
					_lastResult = _commands.LastResult;
					Log.LogInfo((object)_lastResult);
				}
			}
			catch (Exception ex)
			{
				_gesture.Cancel();
				_commands.Cancel();
				_retryAt = Time.unscaledTime + 5f;
				Log.LogWarning((object)("Inventory input paused for five seconds after an error: " + ex.GetBaseException().Message));
			}
			UpdateHotbar(_enabled.Value && Time.unscaledTime >= _retryAt);
		}

		private void UpdateHotbar(bool enabled)
		{
			try
			{
				_hotbar?.Update(_inventory, _commands.MainSlot, enabled, _centerMain.Value, _highlightMain.Value, _outlineThickness.Value, _outlinePadding.Value, _slotSpacing.Value);
			}
			catch (Exception error)
			{
				DisableHotbar(error);
			}
		}

		private void DisableHotbar(Exception error)
		{
			try
			{
				_hotbar?.Dispose();
			}
			catch
			{
			}
			_hotbar = null;
			Log.LogWarning((object)("Hotbar visuals disabled for this launch; inventory controls remain available: " + error.GetBaseException().Message));
		}

		private static void HotbarLayoutPrefix()
		{
			try
			{
				_instance?._hotbar?.RestoreOffsets();
			}
			catch (Exception error)
			{
				_instance?.DisableHotbar(error);
			}
		}

		private static bool HandleInputPrefix(InventorySpot __instance)
		{
			Plugin instance = _instance;
			if ((Object)(object)instance == (Object)null || !instance._ready || !instance._enabled.Value || Time.unscaledTime < instance._retryAt || !NativeInventory.GameplayAvailable())
			{
				return true;
			}
			instance.ReadInput();
			if (instance._claimsInput)
			{
				return false;
			}
			instance._gesture.Cancel();
			if (instance._keepHeld.Value && instance._inventory.CanAct && instance._inventory.Available(__instance.inventorySpotIndex))
			{
				instance._commands.SelectSlot(__instance.inventorySpotIndex, Time.unscaledTime);
				return false;
			}
			instance._commands.Cancel();
			return true;
		}

		private static void RememberOriginPrefix(ItemEquippable __instance)
		{
			Plugin instance = _instance;
			if (instance != null && instance._ready)
			{
				_instance._inventory.RememberSlot(__instance);
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_instance == (Object)(object)this)
			{
				_hotbar?.Dispose();
				_gesture.Cancel();
				_commands.Cancel();
				_instance = null;
			}
		}
	}
	[Flags]
	internal enum BindingSource
	{
		None = 0,
		KeyboardMouse = 1,
		Controller = 2
	}
	internal struct BindingSample
	{
		public BindingSource Pressed;

		public BindingSource Held;

		public BindingSource Connected;

		public bool WheelPulse;

		public bool AnyPressed
		{
			get
			{
				if (Pressed == BindingSource.None)
				{
					return WheelPulse;
				}
				return true;
			}
		}

		public bool AnyHeld => Held != BindingSource.None;
	}
	internal enum PutAwayAction
	{
		None,
		Store,
		Drop
	}
	internal struct PutAwayDecision
	{
		public PutAwayAction Action;

		public int Item;

		public PutAwayDecision(PutAwayAction action, int item)
		{
			Action = action;
			Item = item;
		}
	}
	internal sealed class PutAwayGesture
	{
		private bool _active;

		private bool _triggered;

		private BindingSource _sources;

		private float _started;

		private int _item;

		public bool Active => _active;

		public void Cancel()
		{
			_active = (_triggered = false);
			_sources = BindingSource.None;
			_item = 0;
		}

		public PutAwayDecision Tick(BindingSample input, float now, float holdSeconds, int heldItem, bool canAct)
		{
			if (!canAct)
			{
				Cancel();
				return default(PutAwayDecision);
			}
			if (!_active)
			{
				if (input.Pressed == BindingSource.None)
				{
					if (input.WheelPulse)
					{
						return new PutAwayDecision(PutAwayAction.Store, heldItem);
					}
					return default(PutAwayDecision);
				}
				_active = true;
				_triggered = false;
				_sources = input.Pressed;
				_started = now;
				_item = heldItem;
			}
			if ((_sources & input.Connected) == 0)
			{
				Cancel();
				return default(PutAwayDecision);
			}
			if (_item == 0 && heldItem != 0)
			{
				_item = heldItem;
			}
			else if (_item != 0 && heldItem != _item)
			{
				_triggered = true;
			}
			bool flag = (_sources & input.Held) != 0;
			if (!_triggered && now - _started >= Math.Max(0.1f, holdSeconds))
			{
				_triggered = true;
				PutAwayDecision result = ((_item != 0) ? new PutAwayDecision(PutAwayAction.Drop, _item) : default(PutAwayDecision));
				if (!flag)
				{
					Cancel();
				}
				return result;
			}
			if (flag)
			{
				return default(PutAwayDecision);
			}
			PutAwayDecision result2 = ((!_triggered) ? new PutAwayDecision(PutAwayAction.Store, _item) : default(PutAwayDecision));
			Cancel();
			return result2;
		}
	}
	internal static class SlotPolicy
	{
		public static int FirstFree(IInventoryView view)
		{
			for (int i = 0; i < view.Count; i++)
			{
				if (view.Available(i) && view.ItemAt(i) == 0)
				{
					return i;
				}
			}
			return -1;
		}

		public static int Next(IInventoryView view, int anchor, int direction, int virtualOccupied = -1)
		{
			if (view.Count == 0 || direction == 0)
			{
				return -1;
			}
			int num = ((anchor >= 0 && anchor < view.Count) ? anchor : ((direction > 0) ? (view.Count - 1) : 0));
			for (int i = 1; i <= view.Count; i++)
			{
				int num2 = (num + direction * i) % view.Count;
				if (num2 < 0)
				{
					num2 += view.Count;
				}
				if (view.Available(num2) && (view.ItemAt(num2) != 0 || num2 == virtualOccupied))
				{
					return num2;
				}
			}
			return -1;
		}

		public static int Ready(IInventoryView view, int preferredItem, int anchor)
		{
			for (int i = 0; i < view.Count; i++)
			{
				if (view.Available(i) && view.ItemAt(i) != 0 && view.ItemAt(i) == preferredItem && view.StoredAndSettled(preferredItem))
				{
					return i;
				}
			}
			if (view.Available(anchor) && view.ItemAt(anchor) != 0 && view.StoredAndSettled(view.ItemAt(anchor)))
			{
				return anchor;
			}
			int num = ((anchor >= 0 && anchor < view.Count) ? anchor : (view.Count - 1));
			for (int j = 1; j <= view.Count; j++)
			{
				int num2 = (num + j) % view.Count;
				int num3 = (view.Available(num2) ? view.ItemAt(num2) : 0);
				if (num3 != 0 && view.StoredAndSettled(num3))
				{
					return num2;
				}
			}
			return -1;
		}
	}
	internal interface IInventoryView
	{
		object Identity { get; }

		bool CanAct { get; }

		int Count { get; }

		int Held { get; }

		bool CanStoreHeld { get; }

		bool HeldBusy { get; }

		int HeldOrigin { get; }

		bool Available(int slot);

		int ItemAt(int slot);

		bool StoredAndSettled(int itemId);

		bool Draw(int slot);

		bool Store(int slot);

		bool DropHeld(int expectedItem);
	}
}