diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index 7cbb2a388..9e4f7b0ba 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -566,7 +566,7 @@ Point GetSlotCoord(int slot) } /** - * Return the item id of the current tile + * Return the item id of the current slot */ int GetItemIdOnSlot(int slot) { @@ -605,9 +605,7 @@ Size GetItemSizeOnSlot(int slot) void ResetInvCursorPosition() { Point mousePos {}; - if (Slot < SLOTXY_INV_FIRST) { - mousePos = InvGetEquipSlotCoordFromInvSlot((inv_xy_slot)Slot); - } else if (Slot < SLOTXY_BELT_FIRST) { + if (Slot >= SLOTXY_INV_FIRST && Slot <= SLOTXY_INV_LAST) { int8_t itemInvId = GetItemIdOnSlot(Slot); // search the 'first slot' for that item in the inventory, it should have the positive number of that same InvId @@ -626,8 +624,10 @@ void ResetInvCursorPosition() mousePos = GetSlotCoord(Slot); mousePos.x += ((itemSize.width - 1) * InventorySlotSizeInPixels.width) / 2; mousePos.y += ((itemSize.height - 1) * InventorySlotSizeInPixels.height) / 2; - } else { + } else if (Slot >= SLOTXY_BELT_FIRST && Slot <= SLOTXY_BELT_LAST) { mousePos = GetSlotCoord(Slot); + } else { + mousePos = InvGetEquipSlotCoordFromInvSlot((inv_xy_slot)Slot); } mousePos.x += (InventorySlotSizeInPixels.width / 2); @@ -636,6 +636,23 @@ void ResetInvCursorPosition() SetCursorPos(mousePos); } +int FindClosestInventorySlot(Point mousePos) +{ + int shortestDistance = std::numeric_limits::max(); + int bestSlot = 0; + mousePos += Displacement { -INV_SLOT_HALF_SIZE_PX, INV_SLOT_HALF_SIZE_PX }; + + for (int i = 0; i < NUM_XY_SLOTS; i++) { + int distance = mousePos.ManhattanDistance(GetSlotCoord(i)); + if (distance < shortestDistance) { + shortestDistance = distance; + bestSlot = i; + } + } + + return bestSlot; +} + /** * Move the cursor around in our inventory * If mouse coords are at SLOTXY_CHEST_LAST, consider this center of equipment @@ -654,7 +671,7 @@ void InvMove(AxisDirection dir) // normalize slots if (Slot < 0) - Slot = 0; + Slot = FindClosestInventorySlot(mousePos); else if (Slot >= SLOTXY_HEAD_FIRST && Slot <= SLOTXY_HEAD_LAST) Slot = SLOTXY_HEAD_FIRST; else if (Slot >= SLOTXY_HAND_LEFT_FIRST && Slot <= SLOTXY_HAND_LEFT_LAST) @@ -1230,6 +1247,7 @@ void HandleRightStickMotion() { // move cursor sgbControllerActive = false; + InvalidateInventorySlot(); int x = MousePosition.x; int y = MousePosition.y; acc.Pool(&x, &y, 2); @@ -1248,6 +1266,11 @@ void HandleRightStickMotion() } } +void InvalidateInventorySlot() +{ + Slot = -1; +} + /** * @brief Moves the mouse to the first inventory slot. */ diff --git a/Source/controls/plrctrls.h b/Source/controls/plrctrls.h index 0a2740d1a..1c36d8caf 100644 --- a/Source/controls/plrctrls.h +++ b/Source/controls/plrctrls.h @@ -42,6 +42,7 @@ void PerformPrimaryAction(); // Open chests, doors, pickup items. void PerformSecondaryAction(); bool TryDropItem(); +void InvalidateInventorySlot(); void FocusOnInventory(); void PerformSpellAction(); void StoreSpellCoords(); diff --git a/Source/controls/touch/event_handlers.cpp b/Source/controls/touch/event_handlers.cpp index 3cdfc2dd6..148efb9eb 100644 --- a/Source/controls/touch/event_handlers.cpp +++ b/Source/controls/touch/event_handlers.cpp @@ -3,6 +3,7 @@ #include "controls/touch/event_handlers.h" #include "control.h" +#include "controls/plrctrls.h" #include "cursor.h" #include "diablo.h" #include "engine.h" @@ -31,6 +32,7 @@ void SimulateMouseMovement(const SDL_Event &event) float y = event.tfinger.y; MousePosition = ScaleToScreenCoordinates(x, y); sgbControllerActive = false; + InvalidateInventorySlot(); } bool HandleGameMenuInteraction(const SDL_Event &event) diff --git a/Source/miniwin/misc_msg.cpp b/Source/miniwin/misc_msg.cpp index f4e3a89f2..6518513e6 100644 --- a/Source/miniwin/misc_msg.cpp +++ b/Source/miniwin/misc_msg.cpp @@ -502,6 +502,8 @@ bool FetchMessage_Real(tagMSG *lpMsg) lpMsg->message = DVL_WM_MOUSEMOVE; lpMsg->lParam = PositionForMouse(e.motion.x, e.motion.y); lpMsg->wParam = KeystateForMouse(0); + if (!sgbControllerActive && invflag) + InvalidateInventorySlot(); break; case SDL_MOUSEBUTTONDOWN: { int button = e.button.button;