diff --git a/.gitignore b/.gitignore index 9491a2f..c0f0c51 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ bld/ [Oo]ut/ [Ll]og/ [Ll]ogs/ +[Pp]ackage/ # Visual Studio 2015/2017 cache/options directory .vs/ diff --git a/Helpers/Settings.cs b/Helpers/Settings.cs index 7be5475..d285afe 100644 --- a/Helpers/Settings.cs +++ b/Helpers/Settings.cs @@ -23,8 +23,8 @@ namespace DrakiaXYZ.LootRadius.Helpers "Loot Radius", 2f, new ConfigDescription( - "The distance to include loot from. Note that increasing this may result in pulling loot through walls/floors", - null, + "The distance to include loot from", + new AcceptableValueRange(0f, 10f), new ConfigurationManagerAttributes { }))); RecalcOrder(); diff --git a/Patches/LootPanelOpenPatch.cs b/Patches/LootPanelOpenPatch.cs index 8397566..c8653be 100644 --- a/Patches/LootPanelOpenPatch.cs +++ b/Patches/LootPanelOpenPatch.cs @@ -75,13 +75,14 @@ namespace DrakiaXYZ.LootRadius.Patches // Collect the items around the player, and add them to the fake stash var grid = _stash.Grids[0]; Vector3 playerPosition = Singleton.Instance.MainPlayer.Position; + 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) + 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 }); @@ -97,5 +98,36 @@ 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) + { + float sqDist = (Singleton.Instance.MainPlayer.Position - endPos).sqrMagnitude; + if (sqDist < 0.5f) + { + return true; + } + + return false; + } + + /** + * Return true if the end position is within line of sight of the player + */ + private static bool IsLineOfSight(Vector3 endPos) + { + // Start at the player's head + Vector3 startPos = Singleton.Instance.MainPlayer.MainParts[BodyPartType.head].Position; + + // LineCast returns true if it hits a HighPolyCollider, indicating the item isn't within line of sight of the player's head + if (Physics.Linecast(startPos, endPos, LayerMaskClass.HighPolyWithTerrainMask)) + { + return false; + } + + return true; + } } }