Decompiled source of ExtraSlots v1.0.0

plugins/ExtraSlots.dll

Decompiled 15 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ExtraSlots")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ExtraSlots")]
[assembly: AssemblyTitle("ExtraSlots")]
[assembly: AssemblyVersion("1.0.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 ExtraSlots
{
	internal static class ExtraSlotKeys
	{
		private const int FirstKey = 100;

		private static readonly FieldInfo InputActions = AccessTools.Field(typeof(InputManager), "inputActions");

		public static void Install()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_006d: 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)
			Dictionary<InputKey, InputAction> dictionary = (Dictionary<InputKey, InputAction>)InputActions.GetValue(InputManager.instance);
			for (int i = 3; i < 9; i++)
			{
				int num = i + 1;
				InputKey key = KeyFor(i);
				if (!dictionary.ContainsKey(key))
				{
					InputAction val = new InputAction($"ExtraInventory{num}", (InputActionType)0, $"<Keyboard>/{num}", (string)null, (string)null, (string)null);
					InputActionSetupExtensions.AddBinding(val, $"<Keyboard>/numpad{num}", (string)null, (string)null, (string)null);
					val.Enable();
					dictionary[key] = val;
				}
			}
		}

		public static bool Pressed(int slot)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (slot < 3 || slot >= 9)
			{
				return false;
			}
			return SemiFunc.InputDown(KeyFor(slot));
		}

		private static InputKey KeyFor(int slot)
		{
			return (InputKey)(100 + slot - 3);
		}
	}
	[BepInPlugin("com.repo.extraslots", "ExtraSlots", "1.0.0")]
	[BepInProcess("REPO.exe")]
	public class ExtraSlotsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.repo.extraslots";

		public const string PluginVersion = "1.0.0";

		public const int VanillaSlots = 3;

		public const int MaxSlots = 9;

		public const int MinSlots = 0;

		internal static ManualLogSource Log;

		internal static SlotSettings Settings;

		private bool _dirty;

		private float _next;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = new SlotSettings(((BaseUnityPlugin)this).Config);
			Settings.Enabled.SettingChanged += OnSettingChanged;
			Settings.Slots.SettingChanged += OnSettingChanged;
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			Log.LogInfo((object)"ExtraSlots 1.0.0 loaded");
		}

		private void Update()
		{
			if (!(Time.unscaledTime < _next))
			{
				_next = Time.unscaledTime + 0.5f;
				if (_dirty)
				{
					_dirty = false;
					SlotGate.Forget();
				}
				SlotGate.Ensure();
			}
		}

		private void OnSettingChanged(object sender, EventArgs args)
		{
			_dirty = true;
		}
	}
	internal class SlotSettings
	{
		public readonly ConfigEntry<bool> Enabled;

		public readonly ConfigEntry<int> Slots;

		public SlotSettings(ConfigFile config)
		{
			Enabled = config.Bind<bool>("Inventory", "Enabled", true, "Change how many item slots a player has. Off gives the game's own three slots back.");
			Slots = config.Bind<int>("Inventory", "Slots", 9, "Item slots per player, 0 to 9. 0 means no slots at all. Slots 4 to 9 use the number keys 4 to 9.");
		}
	}
	[HarmonyPatch(typeof(Inventory), "Awake")]
	internal static class InventoryPatch
	{
		private static void Postfix(Inventory __instance)
		{
			SlotGate.Resize(__instance);
		}
	}
	[HarmonyPatch(typeof(Inventory), "GetSpotByIndex")]
	internal static class SpotLookupPatch
	{
		private static bool Prefix(Inventory __instance, int index, ref InventorySpot __result)
		{
			if (index >= 0 && index < __instance.GetAllSpots().Count)
			{
				return true;
			}
			__result = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(Inventory), "InventorySpotAddAtIndex")]
	internal static class SpotAddPatch
	{
		private static bool Prefix(Inventory __instance, InventorySpot spot, int index)
		{
			if (index >= 0 && index < __instance.GetAllSpots().Count)
			{
				return true;
			}
			((Component)spot).gameObject.SetActive(false);
			return false;
		}
	}
	[HarmonyPatch(typeof(InventorySpot), "Update")]
	internal static class SpotPatch
	{
		private static void Postfix(InventorySpot __instance)
		{
			SlotGate.SpotInput(__instance);
		}
	}
	[HarmonyPatch(typeof(InputManager), "Awake")]
	internal static class InputPatch
	{
		private static void Postfix()
		{
			ExtraSlotKeys.Install();
		}
	}
	internal static class SlotGate
	{
		private const float FallbackStep = 40f;

		private static readonly MethodInfo HandleInput = AccessTools.Method(typeof(InventorySpot), "HandleInput", (Type[])null, (Type[])null);

		private static Inventory _lastInventory;

		private static int _lastSlots = -1;

		public static void Forget()
		{
			_lastInventory = null;
		}

		public static void Ensure()
		{
			Inventory instance = Inventory.instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				Resize(instance);
			}
		}

		public static void Resize(Inventory inventory)
		{
			if ((Object)(object)inventory != (Object)(object)Inventory.instance)
			{
				return;
			}
			int num = SlotCount();
			if ((Object)(object)_lastInventory == (Object)(object)inventory && _lastSlots == num)
			{
				return;
			}
			InventorySpot[] array = Object.FindObjectsOfType<InventorySpot>(true);
			if (array.Length < 2)
			{
				return;
			}
			Measure(array, out var step, out var baseline);
			List<InventorySpot> allSpots = inventory.GetAllSpots();
			for (int i = 0; i < num; i++)
			{
				InventorySpot val = Find(array, i);
				if ((Object)(object)val == (Object)null)
				{
					val = Clone(array, num);
					if ((Object)(object)val == (Object)null)
					{
						return;
					}
					val.inventorySpotIndex = i;
				}
				((Component)val).gameObject.SetActive(true);
				Relabel(val, i + 1);
				Place(val, i, num, step, baseline);
			}
			InventorySpot[] array2 = array;
			foreach (InventorySpot val2 in array2)
			{
				if (val2.inventorySpotIndex >= num)
				{
					((Component)val2).gameObject.SetActive(false);
				}
			}
			while (allSpots.Count > num)
			{
				allSpots.RemoveAt(allSpots.Count - 1);
			}
			while (allSpots.Count < num)
			{
				allSpots.Add(null);
			}
			_lastInventory = inventory;
			_lastSlots = num;
			ExtraSlotsPlugin.Log.LogInfo((object)$"Item slots: {num}");
		}

		public static void SpotInput(InventorySpot spot)
		{
			int inventorySpotIndex = spot.inventorySpotIndex;
			if (inventorySpotIndex >= 3 && ExtraSlotKeys.Pressed(inventorySpotIndex))
			{
				HandleInput.Invoke(spot, null);
			}
		}

		private static int SlotCount()
		{
			if (!ExtraSlotsPlugin.Settings.Enabled.Value)
			{
				return 3;
			}
			return Mathf.Clamp(ExtraSlotsPlugin.Settings.Slots.Value, 0, 9);
		}

		private static InventorySpot Find(InventorySpot[] spots, int index)
		{
			foreach (InventorySpot val in spots)
			{
				if (val.inventorySpotIndex == index)
				{
					return val;
				}
			}
			return null;
		}

		private static InventorySpot Clone(InventorySpot[] spots, int wanted)
		{
			InventorySpot val = null;
			foreach (InventorySpot val2 in spots)
			{
				if (((Component)val2).gameObject.activeSelf && val2.inventorySpotIndex < wanted && ((Object)(object)val == (Object)null || val2.inventorySpotIndex > val.inventorySpotIndex))
				{
					val = val2;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			InventorySpot obj = Object.Instantiate<InventorySpot>(val, ((Component)val).transform.parent);
			((Object)obj).name = ((Object)val).name + " Extra";
			return obj;
		}

		private static void Place(InventorySpot spot, int index, int wanted, float step, float baseline)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)spot).transform;
			float num = ((float)index - (float)(wanted - 1) * 0.5f) * step;
			val.anchoredPosition = new Vector2(num, baseline);
		}

		private static void Measure(InventorySpot[] spots, out float step, out float baseline)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//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)
			InventorySpot val = null;
			InventorySpot val2 = null;
			foreach (InventorySpot val3 in spots)
			{
				if ((Object)(object)val == (Object)null || val3.inventorySpotIndex < val.inventorySpotIndex)
				{
					val2 = val;
					val = val3;
				}
				else if ((Object)(object)val2 == (Object)null || val3.inventorySpotIndex < val2.inventorySpotIndex)
				{
					val2 = val3;
				}
			}
			RectTransform val4 = (RectTransform)((Component)val).transform;
			baseline = val4.anchoredPosition.y;
			RectTransform val5 = (RectTransform)((Component)val2).transform;
			step = val5.anchoredPosition.x - val4.anchoredPosition.x;
			if (step < 0.01f)
			{
				step = 40f;
			}
		}

		private static void Relabel(InventorySpot spot, int number)
		{
			string text = number.ToString();
			TextMeshProUGUI[] componentsInChildren = ((Component)spot).GetComponentsInChildren<TextMeshProUGUI>(true);
			foreach (TextMeshProUGUI val in componentsInChildren)
			{
				string text2 = ((((TMP_Text)val).text == null) ? string.Empty : ((TMP_Text)val).text.Trim());
				if (text2.Length == 1 && int.TryParse(text2, out var _))
				{
					((TMP_Text)val).text = text;
				}
			}
		}
	}
}