From c77c598cb65a06560e3c83cadb1477f6b350fbaf Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Sun, 31 Dec 2017 01:59:49 +0200 Subject: [PATCH] Fixed items being dropped when attempting to place them in an itemcontainer slot that's on a normal inventory slot. Closes #200 --- .../Source/Characters/CharacterHUD.cs | 7 + .../Source/Items/CharacterInventory.cs | 45 +++-- .../Source/Items/Inventory.cs | 172 +++++++++++------- 3 files changed, 141 insertions(+), 83 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs index 442936431..c30386797 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs @@ -124,6 +124,8 @@ namespace Barotrauma { character.SelectedCharacter.Inventory.Update(deltaTime); } + + Inventory.UpdateDragging(); } } @@ -234,6 +236,11 @@ namespace Barotrauma if (grabHoldButton.Visible) grabHoldButton.Draw(spriteBatch); } + if (character.Inventory != null && !character.LockHands && character.Stun >= -0.1f) + { + Inventory.DrawDragging(spriteBatch); + } + if (character.FocusedCharacter != null && character.FocusedCharacter.CanBeSelected) { Vector2 startPos = character.DrawPosition + (character.FocusedCharacter.DrawPosition - character.DrawPosition) * 0.7f; diff --git a/Barotrauma/BarotraumaClient/Source/Items/CharacterInventory.cs b/Barotrauma/BarotraumaClient/Source/Items/CharacterInventory.cs index 6c609618e..f61478ce4 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/CharacterInventory.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/CharacterInventory.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System.Collections.Generic; +using System.Linq; namespace Barotrauma { @@ -119,7 +120,7 @@ namespace Barotrauma } - public override void Update(float deltaTime, bool subInventory = false) + public override void Update(float deltaTime, bool isSubInventory = false) { base.Update(deltaTime); @@ -157,19 +158,39 @@ namespace Barotrauma } } + draggingItem = null; GUI.PlayUISound(wasPut ? GUISoundType.PickItem : GUISoundType.PickItemFail); } - if (selectedSlot > -1) + + if (highlightedSubInventorySlot != null) { - UpdateSubInventory(deltaTime, selectedSlot); + UpdateSubInventory(deltaTime, highlightedSubInventorySlot.SlotIndex); + if (highlightedSubInventory.slots == null || + (!highlightedSubInventorySlot.Slot.InteractRect.Contains(PlayerInput.MousePosition) && !highlightedSubInventory.slots.Any(s => s.InteractRect.Contains(PlayerInput.MousePosition)))) + { + highlightedSubInventory = null; + highlightedSubInventorySlot = null; + } } - + else + { + if (selectedSlot?.Inventory == this) + { + var subInventory = GetSubInventory(selectedSlot.SlotIndex); + if (subInventory != null) + { + highlightedSubInventory = subInventory; + highlightedSubInventorySlot = selectedSlot; + } + } + } + if (character == Character.Controlled) { for (int i = 0; i < capacity; i++) { - if (selectedSlot != i && + if ((selectedSlot == null || selectedSlot.SlotIndex != i) && Items[i] != null && Items[i].CanUseOnSelf && character.HasSelectedItem(Items[i])) { //-3 because selected items are in slots 3 and 4 (hands) @@ -220,7 +241,7 @@ namespace Barotrauma } } - selectedSlot = -1; + selectedSlot = null; } public void DrawOwn(SpriteBatch spriteBatch) @@ -270,7 +291,7 @@ namespace Barotrauma { for (int i = 0; i < capacity; i++) { - if (selectedSlot != i && + if ((selectedSlot == null || selectedSlot.SlotIndex != i) && Items[i] != null && Items[i].CanUseOnSelf && character.HasSelectedItem(Items[i])) { useOnSelfButton[i - 3].Draw(spriteBatch); @@ -278,15 +299,11 @@ namespace Barotrauma } } - if (selectedSlot > -1) + for (int i = 0; i < capacity; i++) { - DrawSubInventory(spriteBatch, selectedSlot); - - if (selectedSlot > -1 && - !slots[selectedSlot].IsHighlighted && - (draggingItem == null || draggingItem.Container != Items[selectedSlot])) + if (slots[i].IsHighlighted) { - selectedSlot = -1; + DrawSubInventory(spriteBatch, i); } } } diff --git a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs index 377c51275..30963c6a3 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs @@ -68,6 +68,22 @@ namespace Barotrauma partial class Inventory { + protected class SlotReference + { + public readonly Inventory Inventory; + public readonly InventorySlot Slot; + public readonly int SlotIndex; + + public bool IsSubSlot; + + public SlotReference(Inventory inventory, InventorySlot slot, int slotIndex, bool isSubSlot) + { + Inventory = inventory; + Slot = slot; + SlotIndex = slotIndex; + IsSubSlot = isSubSlot; + } + } public static InventorySlot draggingSlot; public static Item draggingItem; @@ -80,9 +96,12 @@ namespace Barotrauma set { slotsPerRow = Math.Max(1, value); } } - protected int selectedSlot = -1; + protected static SlotReference highlightedSubInventorySlot; + protected static Inventory highlightedSubInventory; - protected InventorySlot[] slots; + protected static SlotReference selectedSlot; + + public InventorySlot[] slots; private Vector2 centerPos; @@ -135,6 +154,11 @@ namespace Barotrauma slots[i] = new InventorySlot(slotRect); } + + if (selectedSlot != null && selectedSlot.Inventory == this) + { + selectedSlot = new SlotReference(this, slots[selectedSlot.SlotIndex], selectedSlot.SlotIndex, selectedSlot.IsSubSlot); + } } public virtual void Update(float deltaTime, bool subInventory = false) @@ -150,22 +174,8 @@ namespace Barotrauma for (int i = 0; i < capacity; i++) { if (slots[i].Disabled) continue; - UpdateSlot(slots[i], i, Items[i], false); + UpdateSlot(slots[i], i, Items[i], subInventory); } - - - if (draggingItem != null && - (draggingSlot == null || (!draggingSlot.InteractRect.Contains(PlayerInput.MousePosition) && draggingItem.ParentInventory == this))) - { - if (!PlayerInput.LeftButtonHeld()) - { - CreateNetworkEvent(); - draggingItem.Drop(); - - GUI.PlayUISound(GUISoundType.DropItem); - } - } - } protected void UpdateSlot(InventorySlot slot, int slotIndex, Item item, bool isSubSlot) @@ -173,20 +183,16 @@ namespace Barotrauma bool mouseOn = slot.InteractRect.Contains(PlayerInput.MousePosition) && !Locked; slot.State = GUIComponent.ComponentState.None; - - if (!(this is CharacterInventory) && !mouseOn && selectedSlot == slotIndex) - { - selectedSlot = -1; - } - + if (mouseOn && - (draggingItem != null || selectedSlot == slotIndex || selectedSlot == -1)) + (draggingItem != null || selectedSlot == null || selectedSlot.Slot == slot) && + (highlightedSubInventory == null || highlightedSubInventory == this || highlightedSubInventorySlot?.Slot == slot)) { slot.State = GUIComponent.ComponentState.Hover; - if (!isSubSlot && selectedSlot == -1) + if (selectedSlot == null || (!selectedSlot.IsSubSlot && isSubSlot)) { - selectedSlot = slotIndex; + selectedSlot = new SlotReference(this, slot, slotIndex, isSubSlot); } if (draggingItem == null) @@ -203,38 +209,29 @@ namespace Barotrauma { doubleClickedItem = item; } - - if (draggingItem != Items[slotIndex]) - { - //selectedSlot = slotIndex; - if (TryPutItem(draggingItem, slotIndex, true, Character.Controlled)) - { - if (slots != null) slots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f); - GUI.PlayUISound(GUISoundType.PickItem); - } - else - { - if (slots != null) slots[slotIndex].ShowBorderHighlight(Color.Red, 0.1f, 0.9f); - GUI.PlayUISound(GUISoundType.PickItemFail); - } - draggingItem = null; - draggingSlot = null; - } - } + } } } + protected Inventory GetSubInventory(int slotIndex) + { + var item = Items[slotIndex]; + if (item == null) return null; + + var container = item.GetComponent(); + if (container == null) return null; + + return container.Inventory; + } + public void UpdateSubInventory(float deltaTime, int slotIndex) { - var item = Items[slotIndex]; - if (item == null) return; + Inventory subInventory = GetSubInventory(slotIndex); + if (subInventory == null) return; - var container = item.GetComponent(); - if (container == null) return; + if (subInventory.slots == null) subInventory.CreateSlots(); - if (container.Inventory.slots == null) container.Inventory.CreateSlots(); - - int itemCapacity = container.Capacity; + int itemCapacity = subInventory.Items.Length; var slot = slots[slotIndex]; new Rectangle(slot.Rect.X - 5, slot.Rect.Y - (40 + 10) * itemCapacity - 5, @@ -246,17 +243,17 @@ namespace Barotrauma for (int i = 0; i < itemCapacity; i++) { subRect.Y = subRect.Y - subRect.Height - 10; - container.Inventory.slots[i].Rect = subRect; - container.Inventory.slots[i].InteractRect = subRect; - container.Inventory.slots[i].InteractRect.Inflate(5, 5); + subInventory.slots[i].Rect = subRect; + subInventory.slots[i].InteractRect = subRect; + subInventory.slots[i].InteractRect.Inflate(5, 5); } - container.Inventory.isSubInventory = true; + subInventory.isSubInventory = true; slots[slotIndex].State = GUIComponent.ComponentState.Hover; - container.Inventory.Update(deltaTime, true); + subInventory.Update(deltaTime, true); } @@ -274,17 +271,6 @@ namespace Barotrauma DrawSlot(spriteBatch, slots[i], Items[i], drawItem); } - if (draggingItem != null && - (draggingSlot == null || (!draggingSlot.InteractRect.Contains(PlayerInput.MousePosition) && draggingItem.ParentInventory == this))) - { - Rectangle dragRect = new Rectangle( - (int)PlayerInput.MousePosition.X - 10, - (int)PlayerInput.MousePosition.Y - 10, - 40, 40); - - DrawSlot(spriteBatch, new InventorySlot(dragRect), draggingItem); - } - for (int i = 0; i < capacity; i++) { if (slots[i].InteractRect.Contains(PlayerInput.MousePosition) && !slots[i].Disabled && Items[i] != null) @@ -373,9 +359,57 @@ namespace Barotrauma container.Inventory.Draw(spriteBatch, true); - if (!containerRect.Contains(PlayerInput.MousePosition)) + } + + public static void UpdateDragging() + { + if (draggingItem != null && PlayerInput.LeftButtonReleased()) { - if (draggingItem == null || draggingItem.Container != item) selectedSlot = -1; + if (selectedSlot == null) + { + draggingItem.ParentInventory?.CreateNetworkEvent(); + draggingItem.Drop(); + GUI.PlayUISound(GUISoundType.DropItem); + } + else if (selectedSlot.Inventory.Items[selectedSlot.SlotIndex] != draggingItem) + { + Inventory selectedInventory = selectedSlot.Inventory; + int slotIndex = selectedSlot.SlotIndex; + if (selectedInventory.TryPutItem(draggingItem, slotIndex, true, Character.Controlled)) + { + if (selectedInventory.slots != null) selectedInventory.slots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f); + GUI.PlayUISound(GUISoundType.PickItem); + } + else + { + if (selectedInventory.slots != null) selectedInventory.slots[slotIndex].ShowBorderHighlight(Color.Red, 0.1f, 0.9f); + GUI.PlayUISound(GUISoundType.PickItemFail); + } + draggingItem = null; + draggingSlot = null; + } + + draggingItem = null; + } + + if (selectedSlot != null && !selectedSlot.Slot.InteractRect.Contains(PlayerInput.MousePosition)) + { + selectedSlot = null; + } + } + + public static void DrawDragging(SpriteBatch spriteBatch) + { + if (draggingItem == null) return; + + if (draggingSlot == null || (!draggingSlot.InteractRect.Contains(PlayerInput.MousePosition))) + { + Rectangle dragRect = new Rectangle( + (int)PlayerInput.MousePosition.X - 10, + (int)PlayerInput.MousePosition.Y - 10, + 40, 40); + + DrawSlot(spriteBatch, new InventorySlot(dragRect), draggingItem); } }