diff --git a/LootRadiusPlugin.cs b/LootRadiusPlugin.cs index f054c1f..d9a16dd 100644 --- a/LootRadiusPlugin.cs +++ b/LootRadiusPlugin.cs @@ -4,7 +4,7 @@ using DrakiaXYZ.LootRadius.Patches; namespace DrakiaXYZ.LootRadius { - [BepInPlugin("xyz.drakia.lootradius", "DrakiaXYZ-LootRadius", "1.0.0")] + [BepInPlugin("xyz.drakia.lootradius", "DrakiaXYZ-LootRadius", "1.0.1")] [BepInDependency("com.spt-aki.core", "3.8.0")] public class LootRadiusPlugin : BaseUnityPlugin { @@ -17,6 +17,7 @@ namespace DrakiaXYZ.LootRadius new GameStartedPatch().Enable(); new LootPanelOpenPatch().Enable(); new LootPanelClosePatch().Enable(); + new QuestItemDragPatch().Enable(); } } } diff --git a/Patches/LootPanelOpenPatch.cs b/Patches/LootPanelOpenPatch.cs index c8653be..d5fcb56 100644 --- a/Patches/LootPanelOpenPatch.cs +++ b/Patches/LootPanelOpenPatch.cs @@ -72,24 +72,17 @@ namespace DrakiaXYZ.LootRadius.Patches return; } - // Collect the items around the player, and add them to the fake stash var grid = _stash.Grids[0]; Vector3 playerPosition = Singleton.Instance.MainPlayer.Position; + + // First find any items directly near the player's feet, to allow them to loot things like items slightly under the floor + Collider[] floorItemColliders = Physics.OverlapSphere(playerPosition, 0.35f, _interactiveLayerMask); + AddAllowedItems(grid, floorItemColliders, true); + + // Then collect items around the player body, based on the loot radius playerPosition += (Vector3.up * 0.5f); - Collider[] colliders = Physics.OverlapSphere(playerPosition, Settings.LootRadius.Value, _interactiveLayerMask); - if (colliders.Length > 0) - { - foreach (Collider collider in colliders) - { - var item = collider.gameObject.GetComponentInParent(); - if (item != null && item.Item.Parent.Container != grid && (IsCloseEnough(item.transform.position) || IsLineOfSight(item.transform.position))) - { - item.Item.OriginalAddress = item.Item.CurrentAddress; - _removeMethod.Invoke(item.Item.CurrentAddress, new object[] { item.Item, string.Empty, false }); - _addMethod.Invoke(grid, new object[] { item.Item }); - } - } - } + Collider[] nearbyItemColliders = Physics.OverlapSphere(playerPosition, Settings.LootRadius.Value, _interactiveLayerMask); + AddAllowedItems(grid, nearbyItemColliders, false); // Show the stash in the inventory panel ____simpleStashPanel.Configure(_stash, inventoryController, sourceContext.CreateChild(_stash)); @@ -99,20 +92,20 @@ namespace DrakiaXYZ.LootRadius.Patches _rightPaneField.SetValue(ItemUiContext.Instance, new LootItemClass[] { _stash }); } - /** - * Return true if the item is close enough to the player's feet to bypass the line of sight check - */ - private static bool IsCloseEnough(Vector3 endPos) + private static void AddAllowedItems(StashGridClass grid, Collider[] colliders, bool ignoreLineOfSight) { - float sqDist = (Singleton.Instance.MainPlayer.Position - endPos).sqrMagnitude; - if (sqDist < 0.5f) + foreach (Collider collider in colliders) { - return true; + var item = collider.gameObject.GetComponentInParent(); + if (item != null && item.Item.Parent.Container != grid && (ignoreLineOfSight || IsLineOfSight(item.transform.position))) + { + item.Item.OriginalAddress = item.Item.CurrentAddress; + _removeMethod.Invoke(item.Item.CurrentAddress, new object[] { item.Item, string.Empty, false }); + _addMethod.Invoke(grid, new object[] { item.Item }); + } } - - return false; } - + /** * Return true if the end position is within line of sight of the player */ diff --git a/Patches/QuestItemDragPatch.cs b/Patches/QuestItemDragPatch.cs new file mode 100644 index 0000000..b62ce2c --- /dev/null +++ b/Patches/QuestItemDragPatch.cs @@ -0,0 +1,41 @@ +using Aki.Reflection.Patching; +using EFT.InventoryLogic; +using EFT.UI.DragAndDrop; +using HarmonyLib; +using System.Linq; +using System.Reflection; + +namespace DrakiaXYZ.LootRadius.Patches +{ + internal class QuestItemDragPatch : ModulePatch + { + private static FieldInfo _itemOwnerField; + protected override MethodBase GetTargetMethod() + { + _itemOwnerField = AccessTools.GetDeclaredFields(typeof(GridView)).Single(x => x.FieldType == typeof(IItemOwner)); + + return typeof(GridView).GetMethod(nameof(GridView.CanDrag)); + } + + [PatchPrefix] + public static bool PatchPrefix(GridView __instance, ref bool __result, ItemContextAbstractClass itemContext) + { + // If not the RadiusStash GridView, run original + IItemOwner gridOwner = _itemOwnerField.GetValue(__instance) as IItemOwner; + if (gridOwner.ID != "RadiusStash") + { + return true; + } + + // If this is a quest item, return false + if (itemContext.Item.QuestItem) + { + __result = false; + return false; + } + + // Otherwise allow original function to run + return true; + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 3eef2eb..af32903 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.0.1.0")] +[assembly: AssemblyFileVersion("1.0.1.0")] diff --git a/SPT-LootRadius.csproj b/SPT-LootRadius.csproj index d2d6dae..96bff44 100644 --- a/SPT-LootRadius.csproj +++ b/SPT-LootRadius.csproj @@ -128,6 +128,7 @@ +