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 FishNet.Object;
using HarmonyLib;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("BulkPickupMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BulkPickupMod")]
[assembly: AssemblyTitle("BulkPickupMod")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BulkPickupMod;
[BepInPlugin("com.bulkpickup.htf", "BulkPickupMod", "1.3.0")]
[BepInProcess("How to Fish")]
public class BulkPickupMod : BaseUnityPlugin
{
[HarmonyPatch(typeof(BossManager), "SpawnBossTrophy")]
private static class BossTrophyPatch
{
[HarmonyPrefix]
private static void Prefix()
{
_taggingBossDrops = true;
}
[HarmonyPostfix]
private static void Postfix()
{
_taggingBossDrops = false;
}
}
[HarmonyPatch(typeof(ItemManager), "Add", new Type[]
{
typeof(Item),
typeof(Collider),
typeof(Collider[])
})]
private static class ItemAddPatch
{
[HarmonyPostfix]
private static void Postfix(Item item)
{
if (_taggingBossDrops && (Object)(object)item != (Object)null)
{
_bossDropItems.Add(item);
}
}
}
[HarmonyPatch(typeof(AudioManager), "PlayPlayerClip")]
private static class AudioPatch
{
[HarmonyPrefix]
private static bool Prefix(string clip, Player player, bool variation, AudioDistance distance, float volume, float minDelay)
{
if (_playOneSound && _bulkItems.Count > 0 && clip == "PickUp")
{
return false;
}
return true;
}
}
public const string PluginGuid = "com.bulkpickup.htf";
public const string PluginName = "BulkPickupMod";
public const string PluginVersion = "1.3.0";
public static ConfigEntry<float> PickupRadius;
public static ConfigEntry<string> PickupModifier;
public static ConfigEntry<bool> AutoPickupEnabled;
public static ConfigEntry<float> AutoPickupInterval;
public static ConfigEntry<bool> IgnoreFullInventory;
public static ConfigEntry<bool> PlayPickupSoundOnce;
public static ConfigEntry<bool> PickupFish;
public static ConfigEntry<bool> PickupWeapons;
public static ConfigEntry<bool> PickupCreatures;
public static ConfigEntry<bool> PickupItems;
public static ConfigEntry<bool> PickupBossDrops;
private static readonly HashSet<Item> _bulkItems = new HashSet<Item>();
private static readonly HashSet<Item> _bossDropItems = new HashSet<Item>();
private static bool _taggingBossDrops;
private static bool _playOneSound;
private float _nextAutoScan;
private void Awake()
{
PickupRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PickupRadius", 5f, "World scan radius in Unity meters.");
PickupModifier = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PickupModifier", "LeftShift", "Modifier key for bulk pickup. Options: LeftShift, RightShift, None.");
AutoPickupEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto", "AutoPickupEnabled", false, "Automatically bulk-pickup everything in radius every AutoPickupInterval seconds (no key needed).");
AutoPickupInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Auto", "AutoPickupInterval", 0.5f, "Time interval (seconds) between automatic scans.");
IgnoreFullInventory = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IgnoreFullInventory", true, "Prevents scan attempts if the local inventory is completely full.");
PlayPickupSoundOnce = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PlayPickupSoundOnce", true, "Plays one pickup sound instead of one per item.");
PickupFish = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "PickupFish", true, "Bulk-pick up Fish-type items.");
PickupWeapons = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "PickupWeapons", true, "Bulk-pick up Weapon-type items.");
PickupCreatures = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "PickupCreatures", true, "Bulk-pick up non-fish Creature-type items (birds, crabs, albatross, etc.).");
PickupItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "PickupItems", true, "Bulk-pick up all other Item-type items (tools, bait, junk, other).");
PickupBossDrops = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "PickupBossDrops", true, "Bulk-pick up boss/mini-boss trophy and meat drops independently of other filters.");
Harmony.CreateAndPatchAll(typeof(BulkPickupMod), "com.bulkpickup.htf");
((BaseUnityPlugin)this).Logger.LogInfo((object)"BulkPickupMod v1.3.0 loaded.");
}
private void Update()
{
Player localPlayer = Player.LocalPlayer;
if (Object.op_Implicit((Object)(object)localPlayer) && !localPlayer.BlockInputs)
{
if (AutoPickupEnabled.Value && Time.time >= _nextAutoScan)
{
_nextAutoScan = Time.time + Mathf.Max(0.1f, AutoPickupInterval.Value);
TryBulkPickup(localPlayer);
}
if (ModifierHeld() && PickupPressedThisFrame())
{
TryBulkPickup(localPlayer);
}
}
}
private bool ModifierHeld()
{
if (Keyboard.current == null)
{
return false;
}
string text = PickupModifier.Value.Trim().ToLower();
if (!(text == "rightshift"))
{
if (text == "none")
{
return true;
}
return ((ButtonControl)Keyboard.current.leftShiftKey).isPressed;
}
return ((ButtonControl)Keyboard.current.rightShiftKey).isPressed;
}
private bool PickupPressedThisFrame()
{
if ((Object)(object)GameInfo.Input == (Object)null || (Object)(object)GameInfo.Input.actions == (Object)null)
{
return false;
}
InputAction val = GameInfo.Input.actions["PlayerPickUp"];
if (val != null)
{
return val.WasPressedThisFrame();
}
return false;
}
private static void TryBulkPickup(Player player)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Invalid comparison between Unknown and I4
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Invalid comparison between Unknown and I4
Vector3 playerPos = player.Transform.position;
float num = PickupRadius.Value * PickupRadius.Value;
List<Item> list = null;
foreach (KeyValuePair<Transform, Item> item in ItemManager.Items)
{
Item value = item.Value;
if (!Object.op_Implicit((Object)(object)value) || !value.CanPickUp || !value.IsInteractable || value.HasPlayerHolder || value.IsInInventory || value.IsDestroying || ((NetworkBehaviour)value).IsDeinitializing || (Object)(object)value.SyncedHolder != (Object)null)
{
continue;
}
Vector3 val = ((Component)value).transform.position - playerPos;
if (((Vector3)(ref val)).sqrMagnitude > num)
{
continue;
}
if (!PickupBossDrops.Value || !_bossDropItems.Contains(value))
{
ItemType type = value.Type;
if ((int)type != 1)
{
if ((int)type == 2)
{
if (!PickupWeapons.Value)
{
continue;
}
}
else if ((Object)(object)value.Creature != (Object)null)
{
if (!PickupCreatures.Value)
{
continue;
}
}
else if (!PickupItems.Value)
{
continue;
}
}
else if (!PickupFish.Value)
{
continue;
}
}
if (list == null)
{
list = new List<Item>();
}
list.Add(value);
}
if (list == null || (IgnoreFullInventory.Value && IsInventoryFull(player.Inventory, list)))
{
return;
}
list.Sort(delegate(Item a, Item b)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
Vector3 val2 = ((Component)a).transform.position - playerPos;
float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
val2 = ((Component)b).transform.position - playerPos;
return sqrMagnitude.CompareTo(((Vector3)(ref val2)).sqrMagnitude);
});
bool flag = PlayPickupSoundOnce.Value && list.Count > 1;
bool flag2 = false;
_bulkItems.Clear();
foreach (Item item2 in list)
{
_bulkItems.Add(item2);
}
_playOneSound = flag;
foreach (Item item3 in list)
{
if (Object.op_Implicit((Object)(object)item3) && !item3.HasPlayerHolder && !item3.IsInInventory && !item3.IsDestroying && !((NetworkBehaviour)item3).IsDeinitializing)
{
item3.PickUp(player, true, true);
flag2 = true;
}
}
_bulkItems.Clear();
_playOneSound = false;
if (flag && flag2)
{
AudioManager.PlayPlayerClip("PickUp", player, false, (AudioDistance)0, 0.2f, 0.1f);
}
}
private static bool IsInventoryFull(PlayerInventory inventory, List<Item> candidates)
{
if (!Object.op_Implicit((Object)(object)inventory))
{
return false;
}
try
{
int value = Traverse.Create((object)inventory).Method("GetTotalSlots", Array.Empty<object>()).GetValue<int>();
IDictionary<byte, Item> value2 = Traverse.Create((object)inventory).Field("_items").GetValue<IDictionary<byte, Item>>();
if (value <= 0)
{
return false;
}
int num = 0;
foreach (KeyValuePair<byte, Item> item in value2)
{
if ((Object)(object)item.Value != (Object)null)
{
num++;
}
}
if (num < value)
{
return false;
}
Type type = AccessTools.TypeByName("StackableItems.StackManager");
if (type == null)
{
return true;
}
MethodInfo method = type.GetMethod("GetStackCount", BindingFlags.Static | BindingFlags.Public);
PropertyInfo property = type.GetProperty("MaxStackSize", BindingFlags.Static | BindingFlags.Public);
int num2 = ((property != null) ? ((int)property.GetValue(null, null)) : 64);
foreach (Item candidate in candidates)
{
if (!Object.op_Implicit((Object)(object)candidate))
{
continue;
}
string text = ((Object)candidate).name.Replace("(Clone)", "").Trim();
bool flag = false;
foreach (KeyValuePair<byte, Item> item2 in value2)
{
Item value3 = item2.Value;
if (!((Object)(object)value3 == (Object)null) && !((Object)(object)value3.Weapon != (Object)null) && ((Object)value3).name.Replace("(Clone)", "").Trim() == text)
{
int num3 = ((method != null) ? ((int)method.Invoke(null, new object[2] { inventory, item2.Key })) : 0);
if (1 + num3 < num2)
{
flag = true;
break;
}
}
}
if (flag)
{
return false;
}
}
return true;
}
catch
{
return false;
}
}
}