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 PickupRadius; public static ConfigEntry PickupModifier; public static ConfigEntry AutoPickupEnabled; public static ConfigEntry AutoPickupInterval; public static ConfigEntry IgnoreFullInventory; public static ConfigEntry PlayPickupSoundOnce; public static ConfigEntry PickupFish; public static ConfigEntry PickupWeapons; public static ConfigEntry PickupCreatures; public static ConfigEntry PickupItems; public static ConfigEntry PickupBossDrops; private static readonly HashSet _bulkItems = new HashSet(); private static readonly HashSet _bossDropItems = new HashSet(); private static bool _taggingBossDrops; private static bool _playOneSound; private float _nextAutoScan; private void Awake() { PickupRadius = ((BaseUnityPlugin)this).Config.Bind("General", "PickupRadius", 5f, "World scan radius in Unity meters."); PickupModifier = ((BaseUnityPlugin)this).Config.Bind("General", "PickupModifier", "LeftShift", "Modifier key for bulk pickup. Options: LeftShift, RightShift, None."); AutoPickupEnabled = ((BaseUnityPlugin)this).Config.Bind("Auto", "AutoPickupEnabled", false, "Automatically bulk-pickup everything in radius every AutoPickupInterval seconds (no key needed)."); AutoPickupInterval = ((BaseUnityPlugin)this).Config.Bind("Auto", "AutoPickupInterval", 0.5f, "Time interval (seconds) between automatic scans."); IgnoreFullInventory = ((BaseUnityPlugin)this).Config.Bind("General", "IgnoreFullInventory", true, "Prevents scan attempts if the local inventory is completely full."); PlayPickupSoundOnce = ((BaseUnityPlugin)this).Config.Bind("General", "PlayPickupSoundOnce", true, "Plays one pickup sound instead of one per item."); PickupFish = ((BaseUnityPlugin)this).Config.Bind("Filter", "PickupFish", true, "Bulk-pick up Fish-type items."); PickupWeapons = ((BaseUnityPlugin)this).Config.Bind("Filter", "PickupWeapons", true, "Bulk-pick up Weapon-type items."); PickupCreatures = ((BaseUnityPlugin)this).Config.Bind("Filter", "PickupCreatures", true, "Bulk-pick up non-fish Creature-type items (birds, crabs, albatross, etc.)."); PickupItems = ((BaseUnityPlugin)this).Config.Bind("Filter", "PickupItems", true, "Bulk-pick up all other Item-type items (tools, bait, junk, other)."); PickupBossDrops = ((BaseUnityPlugin)this).Config.Bind("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 list = null; foreach (KeyValuePair 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(); } 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 candidates) { if (!Object.op_Implicit((Object)(object)inventory)) { return false; } try { int value = Traverse.Create((object)inventory).Method("GetTotalSlots", Array.Empty()).GetValue(); IDictionary value2 = Traverse.Create((object)inventory).Field("_items").GetValue>(); if (value <= 0) { return false; } int num = 0; foreach (KeyValuePair 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 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; } } }