using 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.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Fast Wheel And Drop")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Fast Wheel And Drop")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f8f58401-6c9e-4784-b94f-ce0ce0a083cd")] [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 FastWheelAndDrop; [BepInPlugin("com.openai.fastwheelanddrop", "Fast Wheel And Drop", "1.0.0")] [BepInProcess("Lethal Company.exe")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.openai.fastwheelanddrop"; public const string PluginName = "Fast Wheel And Drop"; public const string PluginVersion = "1.0.0"; private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown Harmony val = new Harmony("com.openai.fastwheelanddrop"); val.PatchAll(typeof(PlayerControllerBPatches)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Fast Wheel And Drop loaded."); } } [HarmonyPatch] internal static class PlayerControllerBPatches { private static readonly Type TPlayer = typeof(PlayerControllerB); private static readonly MethodInfo MI_SwitchToItemSlot = AccessTools.Method(TPlayer, "SwitchToItemSlot", new Type[2] { typeof(int), typeof(GrabbableObject) }, (Type[])null); private static readonly MethodInfo MI_SwitchItemSlotsServerRpc = AccessTools.Method(TPlayer, "SwitchItemSlotsServerRpc", new Type[1] { typeof(bool) }, (Type[])null); private static readonly MethodInfo MI_DiscardHeldObject = AccessTools.Method(TPlayer, "DiscardHeldObject", new Type[4] { typeof(bool), typeof(NetworkObject), typeof(Vector3), typeof(bool) }, (Type[])null); private static readonly FieldInfo FI_inTerminalMenu = AccessTools.Field(TPlayer, "inTerminalMenu"); private static readonly FieldInfo FI_isPlayerControlled = AccessTools.Field(TPlayer, "isPlayerControlled"); private static readonly FieldInfo FI_isTestingPlayer = AccessTools.Field(TPlayer, "isTestingPlayer"); private static readonly FieldInfo FI_isHostPlayerObject = AccessTools.Field(TPlayer, "isHostPlayerObject"); private static readonly FieldInfo FI_isTypingChat = AccessTools.Field(TPlayer, "isTypingChat"); private static readonly FieldInfo FI_isGrabbingObjectAnimation = AccessTools.Field(TPlayer, "isGrabbingObjectAnimation"); private static readonly FieldInfo FI_quickMenuManager = AccessTools.Field(TPlayer, "quickMenuManager"); private static readonly FieldInfo FI_inSpecialInteractAnimation = AccessTools.Field(TPlayer, "inSpecialInteractAnimation"); private static readonly FieldInfo FI_throwingObject = AccessTools.Field(TPlayer, "throwingObject"); private static readonly FieldInfo FI_twoHanded = AccessTools.Field(TPlayer, "twoHanded"); private static readonly FieldInfo FI_activatingItem = AccessTools.Field(TPlayer, "activatingItem"); private static readonly FieldInfo FI_jetpackControls = AccessTools.Field(TPlayer, "jetpackControls"); private static readonly FieldInfo FI_disablingJetpackControls = AccessTools.Field(TPlayer, "disablingJetpackControls"); private static readonly FieldInfo FI_currentlyHeldObjectServer = AccessTools.Field(TPlayer, "currentlyHeldObjectServer"); private static readonly FieldInfo FI_playerBodyAnimator = AccessTools.Field(TPlayer, "playerBodyAnimator"); private static readonly FieldInfo FI_terminalScrollVertical = AccessTools.Field(TPlayer, "terminalScrollVertical"); private static readonly FieldInfo FI_itemSlots = AccessTools.Field(TPlayer, "ItemSlots"); private static readonly FieldInfo FI_currentItemSlot = AccessTools.Field(TPlayer, "currentItemSlot"); [HarmonyPrefix] [HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")] private static bool ScrollMouse_performed_Prefix(PlayerControllerB __instance, CallbackContext context) { if ((Object)(object)__instance == (Object)null) { return true; } if (GetBool(__instance, FI_inTerminalMenu)) { Scrollbar field = GetField(__instance, FI_terminalScrollVertical); if ((Object)(object)field != (Object)null) { float num = ((CallbackContext)(ref context)).ReadValue(); field.value += num / 3f; } return false; } if ((!((NetworkBehaviour)__instance).IsOwner || !GetBool(__instance, FI_isPlayerControlled) || (((NetworkBehaviour)__instance).IsServer && !GetBool(__instance, FI_isHostPlayerObject))) && !GetBool(__instance, FI_isTestingPlayer)) { return false; } if (GetBool(__instance, FI_isGrabbingObjectAnimation) || GetQuickMenuOpen(__instance) || GetBool(__instance, FI_inSpecialInteractAnimation) || GetBool(__instance, FI_throwingObject) || GetBool(__instance, FI_isTypingChat) || GetBool(__instance, FI_twoHanded) || GetBool(__instance, FI_activatingItem)) { return false; } if ((GetBool(__instance, FI_jetpackControls) || GetBool(__instance, FI_disablingJetpackControls)) && (Object)(object)GetField(__instance, FI_currentlyHeldObjectServer) != (Object)null && GetField(__instance, FI_currentlyHeldObjectServer).itemProperties.itemId == 13) { return false; } if ((Object)(object)ShipBuildModeManager.Instance != (Object)null) { ShipBuildModeManager.Instance.CancelBuildMode(true); } Animator field2 = GetField(__instance, FI_playerBodyAnimator); if ((Object)(object)field2 != (Object)null) { field2.SetBool("GrabValidated", false); } float num2 = ((CallbackContext)(ref context)).ReadValue(); bool flag = num2 > 0f; int num3 = NextItemSlot(__instance, flag); InvokePrivate(__instance, MI_SwitchToItemSlot, num3, null); InvokePrivate(__instance, MI_SwitchItemSlotsServerRpc, flag); GrabbableObject field3 = GetField(__instance, FI_currentlyHeldObjectServer); if ((Object)(object)field3 != (Object)null) { AudioSource component = ((Component)field3).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)field3.itemProperties != (Object)null && (Object)(object)field3.itemProperties.grabSFX != (Object)null) { component.PlayOneShot(field3.itemProperties.grabSFX, 0.6f); } } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerControllerB), "Discard_performed")] private static bool Discard_performed_Prefix(PlayerControllerB __instance, CallbackContext context) { //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return true; } if (!((NetworkBehaviour)__instance).IsOwner || !GetBool(__instance, FI_isPlayerControlled) || (((NetworkBehaviour)__instance).IsServer && !GetBool(__instance, FI_isHostPlayerObject))) { return false; } if (!((CallbackContext)(ref context)).performed) { return false; } if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.localPlayerUsingController && (Object)(object)ShipBuildModeManager.Instance != (Object)null && ShipBuildModeManager.Instance.InBuildMode) { ShipBuildModeManager.Instance.StoreObjectLocalClient(); return false; } if (GetBool(__instance, FI_isGrabbingObjectAnimation) || GetBool(__instance, FI_isTypingChat) || GetBool(__instance, FI_inSpecialInteractAnimation) || GetBool(__instance, FI_activatingItem)) { return false; } if ((GetBool(__instance, FI_jetpackControls) || GetBool(__instance, FI_disablingJetpackControls)) && (Object)(object)GetField(__instance, FI_currentlyHeldObjectServer) != (Object)null && GetField(__instance, FI_currentlyHeldObjectServer).itemProperties.itemId == 13) { return false; } if ((Object)(object)ShipBuildModeManager.Instance != (Object)null) { ShipBuildModeManager.Instance.CancelBuildMode(true); } bool flag = GetBool(__instance, FI_throwingObject); bool flag2 = (Object)(object)GetField(__instance, FI_currentlyHeldObjectServer) != (Object)null && __instance.isHoldingObject; if (!flag && flag2) { DepositItemsDesk val = Object.FindObjectOfType(); GrabbableObject field = GetField(__instance, FI_currentlyHeldObjectServer); if ((Object)(object)val != (Object)null && (Object)(object)field != (Object)null) { Bounds bounds = ((Collider)val.triggerCollider).bounds; if (((Bounds)(ref bounds)).Contains(((Component)field).transform.position)) { val.PlaceItemOnCounter(__instance); return false; } } InvokePrivate(__instance, MI_DiscardHeldObject, false, null, (object)default(Vector3), true); } return false; } private static int NextItemSlot(PlayerControllerB player, bool forward) { int field = GetField(player, FI_currentItemSlot); GrabbableObject[] field2 = GetField(player, FI_itemSlots); if (field2 == null || field2.Length == 0) { return field; } if (field == 50) { return (!forward) ? (field2.Length - 1) : 0; } if (forward) { return (field + 1) % field2.Length; } return (field == 0) ? (field2.Length - 1) : (field - 1); } private static bool GetQuickMenuOpen(PlayerControllerB player) { object field = GetField(player, FI_quickMenuManager); if (field == null) { return false; } FieldInfo field2 = field.GetType().GetField("isMenuOpen", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null && field2.FieldType == typeof(bool)) { return (bool)field2.GetValue(field); } PropertyInfo property = field.GetType().GetProperty("isMenuOpen", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.PropertyType == typeof(bool)) { return (bool)property.GetValue(field); } return false; } private static T GetField(PlayerControllerB player, FieldInfo fi) { if ((Object)(object)player == (Object)null || fi == null) { return default(T); } object value = fi.GetValue(player); if (value == null) { return default(T); } return (value is T val) ? val : ((T)value); } private static bool GetBool(PlayerControllerB player, FieldInfo fi) { if ((Object)(object)player == (Object)null || fi == null) { return false; } object value = fi.GetValue(player); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static void InvokePrivate(PlayerControllerB player, MethodInfo method, params object[] args) { if (!((Object)(object)player == (Object)null) && !(method == null)) { method.Invoke(player, args); } } }