Decompiled source of FastWheelAndDrop v1.0.0

BepInEx/plugins/FastWheelAndDrop.dll

Decompiled a day ago
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<Scrollbar>(__instance, FI_terminalScrollVertical);
			if ((Object)(object)field != (Object)null)
			{
				float num = ((CallbackContext)(ref context)).ReadValue<float>();
				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<GrabbableObject>(__instance, FI_currentlyHeldObjectServer) != (Object)null && GetField<GrabbableObject>(__instance, FI_currentlyHeldObjectServer).itemProperties.itemId == 13)
		{
			return false;
		}
		if ((Object)(object)ShipBuildModeManager.Instance != (Object)null)
		{
			ShipBuildModeManager.Instance.CancelBuildMode(true);
		}
		Animator field2 = GetField<Animator>(__instance, FI_playerBodyAnimator);
		if ((Object)(object)field2 != (Object)null)
		{
			field2.SetBool("GrabValidated", false);
		}
		float num2 = ((CallbackContext)(ref context)).ReadValue<float>();
		bool flag = num2 > 0f;
		int num3 = NextItemSlot(__instance, flag);
		InvokePrivate(__instance, MI_SwitchToItemSlot, num3, null);
		InvokePrivate(__instance, MI_SwitchItemSlotsServerRpc, flag);
		GrabbableObject field3 = GetField<GrabbableObject>(__instance, FI_currentlyHeldObjectServer);
		if ((Object)(object)field3 != (Object)null)
		{
			AudioSource component = ((Component)field3).gameObject.GetComponent<AudioSource>();
			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<GrabbableObject>(__instance, FI_currentlyHeldObjectServer) != (Object)null && GetField<GrabbableObject>(__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<GrabbableObject>(__instance, FI_currentlyHeldObjectServer) != (Object)null && __instance.isHoldingObject;
		if (!flag && flag2)
		{
			DepositItemsDesk val = Object.FindObjectOfType<DepositItemsDesk>();
			GrabbableObject field = GetField<GrabbableObject>(__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<int>(player, FI_currentItemSlot);
		GrabbableObject[] field2 = GetField<GrabbableObject[]>(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<object>(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<T>(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);
		}
	}
}