using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterItemHandling.Data;
using GameNetcodeStuff;
using HarmonyLib;
using TMPro;
using Unity.Netcode;
using UnityEngine;
[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("Yan01h")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod for Lethal Company")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2+a76f58271d4f6e06d55ab21884d965b3130c9ecd")]
[assembly: AssemblyProduct("BetterItemHandling1.1.2")]
[assembly: AssemblyTitle("BetterItemHandling1.1.2")]
[assembly: AssemblyVersion("1.1.2.0")]
namespace BetterItemHandling
{
[BepInPlugin("Yan01h.BetterItemHandling", "BetterItemHandling", "1.1.2")]
public class Plugin : BaseUnityPlugin
{
private const string ModGUID = "Yan01h.BetterItemHandling";
private const string ModName = "BetterItemHandling";
private const string ModVersion = "1.1.2";
public static ConfigEntry<bool> ConfigAllowDropAllScrap;
public static ConfigEntry<bool> ConfigDropAllRequiresDoublePress;
public static ConfigEntry<float> ConfigDoublePressTimeWindow;
public static ConfigEntry<bool> ConfigAllowPlaceAllScrapOnDesk;
private readonly Harmony _harmony = new Harmony("Yan01h.BetterItemHandling");
public static ManualLogSource Log { get; private set; }
public void Awake()
{
Log = Logger.CreateLogSource("Yan01h.BetterItemHandling");
Log.LogInfo((object)"Loading BetterItemHandling (v1.1.2)");
ConfigAllowDropAllScrap = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowDropAllScrap", true, "Allows dropping all scrap when pressing your drop key on an empty slot");
ConfigDropAllRequiresDoublePress = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DropAllRequiresDoublePress", true, "Requires the drop key to be pressed twice on order to drop everything");
ConfigDoublePressTimeWindow = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DoublePressTimeWindow", 0.25f, "The amount of time in which the second press needs to occur for it to count as a double press in seconds");
ConfigAllowPlaceAllScrapOnDesk = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowPlaceAllScrapOnDesk", true, "Allows to quickly place all scrap in your inventory on the deposit desk when pressing your sprint key");
PlayerControllerData.SwitchToItemSlot = typeof(PlayerControllerB).GetMethod("SwitchToItemSlot", BindingFlags.Instance | BindingFlags.NonPublic);
_harmony.PatchAll();
Log.LogInfo((object)"Plugin: BetterItemHandling, Version: 1.1.2 loaded!");
}
}
}
namespace BetterItemHandling.Patches
{
[HarmonyPatch(typeof(DepositItemsDesk))]
internal class DepositItemsDeskPatches
{
private static int _slotIndex = -1;
[HarmonyPostfix]
[HarmonyPatch("PlaceItemOnCounter")]
internal static void PlaceItemOnCounterPostfix(DepositItemsDesk __instance)
{
if (!Plugin.ConfigAllowPlaceAllScrapOnDesk.Value)
{
return;
}
bool num = IngamePlayerSettings.Instance.playerInput.actions.FindAction("Sprint", false).IsPressed();
int itemSlotCount = PlayerControllerData.GetItemSlotCount();
if (num && _slotIndex != itemSlotCount)
{
do
{
_slotIndex++;
if (_slotIndex == itemSlotCount)
{
return;
}
}
while ((Object)(object)PlayerControllerData.Controller.ItemSlots[_slotIndex] == (Object)null || !PlayerControllerData.Controller.ItemSlots[_slotIndex].itemProperties.isScrap);
Plugin.Log.LogInfo((object)$"Placing item at index {_slotIndex} on the deposit desk");
PlayerControllerData.SwitchToItemSlot.Invoke(PlayerControllerData.Controller, new object[2] { _slotIndex, null });
__instance.PlaceItemOnCounter(PlayerControllerData.Controller);
}
else
{
_slotIndex = -1;
}
}
}
[HarmonyPatch(typeof(GrabbableObject))]
internal class GrabbableObjectPatches
{
[HarmonyPostfix]
[HarmonyPatch("InteractItem")]
internal static void InteractItem(GrabbableObject __instance)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
if (!__instance.grabbable)
{
return;
}
int num = -1;
int itemSlotCount = PlayerControllerData.GetItemSlotCount();
for (int i = 0; i < itemSlotCount; i++)
{
if ((Object)(object)PlayerControllerData.Controller.ItemSlots[i] == (Object)null)
{
num = i;
break;
}
}
if (num == -1 || PlayerControllerData.IsTwoHanded)
{
Plugin.Log.LogInfo((object)"No space available! Dropping item...");
PlayerControllerData.Controller.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true);
}
if (!__instance.itemProperties.twoHanded)
{
PlayerControllerData.IsTwoHanded = false;
}
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class PlayerControllerBPatches
{
private static bool _discardPressedFirst;
private static float _discardPressedLast;
[HarmonyPrefix]
[HarmonyPatch("BeginGrabObject")]
internal static void BeginGrabObjectPrefix(PlayerControllerB __instance)
{
PlayerControllerData.Controller = __instance;
if (__instance.twoHanded)
{
Plugin.Log.LogInfo((object)"Player is carrying two handed item");
__instance.twoHanded = false;
PlayerControllerData.IsTwoHanded = true;
}
else
{
PlayerControllerData.IsTwoHanded = false;
}
}
[HarmonyPostfix]
[HarmonyPatch("BeginGrabObject")]
internal static void BeginGrabObjectPostfix(PlayerControllerB __instance)
{
if (PlayerControllerData.IsTwoHanded)
{
Plugin.Log.LogInfo((object)"Item was two handed, reseting PlayerControllerB.twoHanded");
PlayerControllerData.IsTwoHanded = false;
__instance.twoHanded = true;
}
}
[HarmonyPostfix]
[HarmonyPatch("SetHoverTipAndCurrentInteractTrigger")]
internal static void SetHoverTipAndCurrentInteractTriggerPostfix(PlayerControllerB __instance)
{
bool flag = IngamePlayerSettings.Instance.playerInput.actions.FindAction("Sprint", false).IsPressed();
if (((TMP_Text)__instance.cursorTip).text == "Inventory full!" || (((TMP_Text)__instance.cursorTip).text == "Grab : [E]" && __instance.twoHanded))
{
((TMP_Text)__instance.cursorTip).text = "Swap : [E]";
}
else if (flag && ((TMP_Text)__instance.cursorTip).text == "Sell item : [E]")
{
((TMP_Text)__instance.cursorTip).text = "Sell All : [E]";
}
}
[HarmonyPostfix]
[HarmonyPatch("Discard_performed")]
internal static void Discard_performedPostfix(PlayerControllerB __instance)
{
//IL_0071: 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)
if (!Plugin.ConfigAllowDropAllScrap.Value || !__instance.isPlayerControlled || !ShouldDropAll(__instance))
{
return;
}
int currentItemSlot = __instance.currentItemSlot;
int itemSlotCount = PlayerControllerData.GetItemSlotCount(__instance);
for (int i = 0; i < itemSlotCount; i++)
{
GrabbableObject val = __instance.ItemSlots[i];
if ((Object)(object)val != (Object)null && val.itemProperties.isScrap)
{
PlayerControllerData.SwitchToItemSlot.Invoke(__instance, new object[2] { i, null });
__instance.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true);
}
}
PlayerControllerData.SwitchToItemSlot.Invoke(__instance, new object[2] { currentItemSlot, null });
}
private static bool ShouldDropAll(PlayerControllerB controller)
{
if (!Plugin.ConfigDropAllRequiresDoublePress.Value && (Object)(object)controller.ItemSlots[controller.currentItemSlot] == (Object)null)
{
return true;
}
if (_discardPressedFirst)
{
if (Time.time - _discardPressedLast <= Plugin.ConfigDoublePressTimeWindow.Value)
{
_discardPressedFirst = false;
return true;
}
}
else
{
_discardPressedFirst = true;
}
_discardPressedLast = Time.time;
return false;
}
}
}
namespace BetterItemHandling.Data
{
internal static class PlayerControllerData
{
internal static PlayerControllerB Controller { get; set; }
internal static bool IsTwoHanded { get; set; }
internal static MethodInfo SwitchToItemSlot { get; set; }
internal static int GetItemSlotCount(PlayerControllerB controller = null)
{
MethodInfo methodInfo = AccessTools.Method(typeof(PlayerControllerB), "NextItemSlot", (Type[])null, (Type[])null);
if ((Object)(object)controller == (Object)null)
{
controller = Controller;
}
int currentItemSlot = controller.currentItemSlot;
int num = 1;
while ((controller.currentItemSlot = (int)methodInfo.Invoke(controller, new object[1] { true })) != currentItemSlot)
{
num++;
if (num > controller.ItemSlots.Length)
{
break;
}
}
controller.currentItemSlot = currentItemSlot;
return num;
}
}
}