Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of FastSlots v1.0.2
BepInEx/plugins/FastSlots.dll
Decompiled a month agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using GameNetcodeStuff; using HarmonyLib; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("FastSlots")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("FastSlots")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a72f02b8-2b77-417b-b41a-dc8936c5b39a")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace FastSlots; [BepInPlugin("FastSlots", "FastSlots", "1.0.2")] public class FastSlotsPlugin : BaseUnityPlugin { private void Awake() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) new Harmony("FastSlots").PatchAll(); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] public static class PlayerUpdatePatch { private static readonly MethodInfo SwitchToItemSlot = AccessTools.Method(typeof(PlayerControllerB), "SwitchToItemSlot", new Type[2] { typeof(int), typeof(GrabbableObject) }, (Type[])null); private static readonly Key[] SlotKeys; [HarmonyPostfix] private static void Postfix(PlayerControllerB __instance) { if (IsControllable(__instance)) { Keyboard current = Keyboard.current; if (current != null) { Traverse t = Traverse.Create((object)__instance); TryPlayEmote(__instance, current, t); TrySwitchSlot(__instance, current, t); } } } private static bool IsControllable(PlayerControllerB p) { return ((NetworkBehaviour)p).IsOwner && p.isPlayerControlled && !p.isTypingChat && !p.quickMenuManager.isMenuOpen; } private static void TryPlayEmote(PlayerControllerB p, Keyboard kb, Traverse t) { int num = (((ButtonControl)kb.downArrowKey).wasPressedThisFrame ? 1 : (((ButtonControl)kb.upArrowKey).wasPressedThisFrame ? 2 : (-1))); if (num != -1) { t.Method("StartPerformingEmoteServerRpc", Array.Empty<object>()).GetValue(); p.playerBodyAnimator.SetInteger("emoteNumber", num); } } private static void TrySwitchSlot(PlayerControllerB p, Keyboard kb, Traverse t) { if (CanSwitchSlot(p, t)) { int pressedSlot = GetPressedSlot(kb); if (pressedSlot != -1 && pressedSlot < p.ItemSlots.Length && pressedSlot != p.currentItemSlot) { PerformSlotSwitch(p, t, pressedSlot); } } } private static bool CanSwitchSlot(PlayerControllerB p, Traverse t) { return t.Field("timeSinceSwitchingSlots").GetValue<float>() >= 0.3f && !p.isGrabbingObjectAnimation && !p.inSpecialInteractAnimation && !p.twoHanded && !p.activatingItem && !t.Field("throwingObject").GetValue<bool>(); } private static int GetPressedSlot(Keyboard kb) { for (int i = 0; i < SlotKeys.Length; i++) { if (((ButtonControl)kb[SlotKeys[i]]).wasPressedThisFrame) { return i; } } return -1; } private static void PerformSlotSwitch(PlayerControllerB p, Traverse t, int slot) { ShipBuildModeManager instance = ShipBuildModeManager.Instance; if (instance != null) { instance.CancelBuildMode(true); } p.playerBodyAnimator.SetBool("GrabValidated", false); SwitchToItemSlot.Invoke(p, new object[2] { slot, null }); t.Method("SwitchToSlotServerRpc", new object[1] { slot }).GetValue(); GrabbableObject currentlyHeldObjectServer = p.currentlyHeldObjectServer; if (currentlyHeldObjectServer != null) { AudioSource component = ((Component)currentlyHeldObjectServer).gameObject.GetComponent<AudioSource>(); if (component != null) { component.PlayOneShot(currentlyHeldObjectServer.itemProperties.grabSFX, 0.6f); } } t.Field("timeSinceSwitchingSlots").SetValue((object)0f); } static PlayerUpdatePatch() { Key[] array = new Key[7]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); SlotKeys = (Key[])(object)array; } } [HarmonyPatch(typeof(PlayerControllerB), "PerformEmote")] public static class EmotePatch { private static readonly Key[] BlockedKeys = (Key[])(object)new Key[2] { (Key)41, (Key)42 }; [HarmonyPrefix] private static bool Prefix() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current == null) { return true; } Key[] blockedKeys = BlockedKeys; foreach (Key val in blockedKeys) { if (((ButtonControl)current[val]).isPressed) { return false; } } return true; } }