From cc9ebe9fc27d6b181e7e6c37f30b8dabc339a4b3 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Thu, 13 Jul 2017 23:32:39 +0300 Subject: [PATCH] Interaction logic tweaking again: - Reverted the item distance calculation change in commit c7fd681 (it made interaction way less precise, as items near the character tended to get focus even if the cursor was nowhere near them), and replaced it with: - Aim assist considers the distance to an item to be 0.0 if the cursor is inside a trigger of the item. - Reverted 769a012 and disabled aim assist when an item is selected. Meaning that now items don't have to be deselected before interacting with another item, but the cursor has to be directly on the other item to make accidental interaction less likely. - Removed some redundant trigger calculations from CanInteractWith. --- .../Source/Characters/Character.cs | 56 +++++++------------ .../BarotraumaShared/Source/Items/Item.cs | 24 ++++---- 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index d4b80158c..66701c31b 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -1011,36 +1011,18 @@ namespace Barotrauma lowerBodyPosition += Submarine.Position; } - Vector2 playerDistanceCheckPosition; - Rectangle itemDisplayRect; + bool insideTrigger = item.IsInsideTrigger(upperBodyPosition) || item.IsInsideTrigger(lowerBodyPosition); + if (item.Prefab.Triggers.Count > 0 && !insideTrigger) return false; - bool insideTrigger = false; - if (item.Prefab.Triggers.Any()) - { - foreach (Rectangle trigger in item.Prefab.Triggers) - { - Rectangle transformedTrigger = new Rectangle( - item.WorldRect.X + trigger.X, - (item.WorldRect.Y + trigger.Y) - ((trigger.Height == 0) ? item.Rect.Height : trigger.Height), - (trigger.Width == 0) ? item.Rect.Width : trigger.Width, - (trigger.Height == 0) ? item.Rect.Height : trigger.Height); - - // Get the point along the line between lowerBodyPosition and upperBodyPosition which is closest to the center of itemDisplayRect - playerDistanceCheckPosition = Vector2.Clamp(transformedTrigger.Center.ToVector2(), lowerBodyPosition, upperBodyPosition); - - if (!transformedTrigger.Contains(upperBodyPosition) && !transformedTrigger.Contains(lowerBodyPosition)) return false; - - insideTrigger = true; - } - if (!insideTrigger) return false; - } - itemDisplayRect = new Rectangle(item.InteractionRect.X, item.InteractionRect.Y - item.InteractionRect.Height, item.InteractionRect.Width, item.InteractionRect.Height); + Rectangle itemDisplayRect = new Rectangle(item.InteractionRect.X, item.InteractionRect.Y - item.InteractionRect.Height, item.InteractionRect.Width, item.InteractionRect.Height); // Get the point along the line between lowerBodyPosition and upperBodyPosition which is closest to the center of itemDisplayRect - playerDistanceCheckPosition = Vector2.Clamp(itemDisplayRect.Center.ToVector2(), lowerBodyPosition, upperBodyPosition); + Vector2 playerDistanceCheckPosition = Vector2.Clamp(itemDisplayRect.Center.ToVector2(), lowerBodyPosition, upperBodyPosition); // Here we get the point on the itemDisplayRect which is closest to playerDistanceCheckPosition - Vector2 rectIntersectionPoint = new Vector2(Math.Max(itemDisplayRect.X, Math.Min(itemDisplayRect.X + itemDisplayRect.Width, playerDistanceCheckPosition.X)), Math.Max(itemDisplayRect.Y, Math.Min(itemDisplayRect.Y + itemDisplayRect.Height, playerDistanceCheckPosition.Y))); + Vector2 rectIntersectionPoint = new Vector2( + MathHelper.Clamp(playerDistanceCheckPosition.X, itemDisplayRect.X, itemDisplayRect.Right), + MathHelper.Clamp(playerDistanceCheckPosition.Y, itemDisplayRect.Y, itemDisplayRect.Bottom)); // If playerDistanceCheckPosition is inside the itemDisplayRect then we consider the character to within 0 distance of the item if (!itemDisplayRect.Contains(playerDistanceCheckPosition)) @@ -1102,22 +1084,22 @@ namespace Barotrauma if (hull != null && item.CurrentHull != hull) continue; if (item.body != null && !item.body.Enabled) continue; if (item.ParentInventory != null) continue; - - float distanceToItem = float.PositiveInfinity; - if (CanInteractWith(item, out distanceToItem)) + + if (CanInteractWith(item)) { - if (item.IsMouseOn(displayPosition)) - { - Console.WriteLine("Name: " + item.Name + " Priority:" + item.InteractPriority); - } if (item.IsMouseOn(displayPosition) && (highestPriorityItemAtPosition == null || ((highestPriorityItemAtPosition.InteractPriority < item.InteractPriority) || (highestPriorityItemAtPosition.InteractPriority == item.InteractPriority && highestPriorityItemAtPosition.GetDrawDepth() > item.GetDrawDepth())))) { highestPriorityItemAtPosition = item; } - else if (aimAssistModifier > 0.0f) + else if (aimAssistModifier > 0.0f && SelectedConstruction == null) { + float distanceToItem = item.IsInsideTrigger(displayPosition) ? 0.0f : Vector2.Distance(item.WorldPosition, displayPosition); + + //aim assist can only be used if no item has been selected + //= can't switch selection to another item without deselecting the current one first UNLESS the cursor is directly on the item + //otherwise it would be too easy to accidentally switch the selected item when rewiring items if (distanceToItem < (100.0f * aimAssistModifier) && (closestItem == null || distanceToItem < closestItemDistance)) { closestItem = item; @@ -1257,15 +1239,15 @@ namespace Barotrauma { SelectCharacter(focusedCharacter); } - else if (IsKeyHit(InputType.Select) && selectedConstruction != null) - { - selectedConstruction = null; - } else if (focusedItem != null) { focusedItem.IsHighlighted = true; focusedItem.TryInteract(this); } + else if (IsKeyHit(InputType.Select) && selectedConstruction != null) + { + selectedConstruction = null; + } } public static void UpdateAnimAll(float deltaTime) diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index 61443cf21..039851237 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -552,17 +552,17 @@ namespace Barotrauma public Rectangle TransformTrigger(Rectangle trigger, bool world = false) { return world ? - new Rectangle( - WorldRect.X + trigger.X, - WorldRect.Y + trigger.Y, - (trigger.Width == 0) ? Rect.Width : trigger.Width, - (trigger.Height == 0) ? Rect.Height : trigger.Height) - : - new Rectangle( - Rect.X + trigger.X, - Rect.Y + trigger.Y, - (trigger.Width == 0) ? Rect.Width : trigger.Width, - (trigger.Height == 0) ? Rect.Height : trigger.Height); + new Rectangle( + WorldRect.X + trigger.X, + WorldRect.Y + trigger.Y, + (trigger.Width == 0) ? Rect.Width : trigger.Width, + (trigger.Height == 0) ? Rect.Height : trigger.Height) + : + new Rectangle( + Rect.X + trigger.X, + Rect.Y + trigger.Y, + (trigger.Width == 0) ? Rect.Width : trigger.Width, + (trigger.Height == 0) ? Rect.Height : trigger.Height); } /// @@ -1033,7 +1033,7 @@ namespace Barotrauma return c != null && c.Character != null && c.Character.CanInteractWith(this); } - public bool TryInteract(Character picker, bool ignoreRequiredItems=false, bool forceSelectKey=false, bool forceActionKey=false) + public bool TryInteract(Character picker, bool ignoreRequiredItems = false, bool forceSelectKey = false, bool forceActionKey = false) { bool hasRequiredSkills = true;