diff --git a/Source/control.cpp b/Source/control.cpp index ab2075663..26270d4de 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -852,10 +852,10 @@ void DrawInfoBox(const Surface &out) InfoColor = UiFlags::ColorWhite; ClearPanel(); } + auto &myPlayer = Players[MyPlayerId]; if (spselflag || trigflag) { InfoColor = UiFlags::ColorWhite; - } else if (pcurs >= CURSOR_FIRSTITEM) { - auto &myPlayer = Players[MyPlayerId]; + } else if (!myPlayer.HoldItem.isEmpty()) { if (myPlayer.HoldItem._itype == ItemType::Gold) { int nGold = myPlayer.HoldItem._ivalue; InfoString = fmt::format(ngettext("{:d} gold piece", "{:d} gold pieces", nGold), nGold); diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index a0a326c3d..bcded078f 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -713,16 +713,16 @@ void ResetInvCursorPosition() mousePos = GetSlotCoord(Slot); } - if (pcurs >= CURSOR_FIRSTITEM) { + if (!MyPlayer->HoldItem.isEmpty()) { mousePos += Displacement { -INV_SLOT_HALF_SIZE_PX, -INV_SLOT_HALF_SIZE_PX }; } } else if (Slot >= SLOTXY_BELT_FIRST && Slot <= SLOTXY_BELT_LAST) { mousePos = GetSlotCoord(Slot); - if (pcurs >= CURSOR_FIRSTITEM) + if (!MyPlayer->HoldItem.isEmpty()) mousePos += Displacement { -INV_SLOT_HALF_SIZE_PX, -INV_SLOT_HALF_SIZE_PX }; } else { mousePos = InvGetEquipSlotCoordFromInvSlot((inv_xy_slot)Slot); - if (pcurs >= CURSOR_FIRSTITEM) { + if (!MyPlayer->HoldItem.isEmpty()) { Size itemSize = GetInventorySize(MyPlayer->HoldItem); mousePos += Displacement { -INV_SLOT_HALF_SIZE_PX, -INV_SLOT_HALF_SIZE_PX * itemSize.height }; } @@ -1085,7 +1085,7 @@ void StashMove(AxisDirection dir) // Jump from general inventory to stash if (Slot >= SLOTXY_INV_FIRST && Slot <= SLOTXY_INV_LAST) { int firstSlot = Slot; - if (pcurs < CURSOR_FIRSTITEM) { + if (MyPlayer->HoldItem.isEmpty()) { int8_t itemId = GetItemIdOnSlot(Slot); if (itemId != 0) { firstSlot = FindFirstSlotOnItem(itemId); @@ -1848,7 +1848,7 @@ void PerformSpellAction() return; if (invflag) { - if (pcurs >= CURSOR_FIRSTITEM) + if (!MyPlayer->HoldItem.isEmpty()) TryDropItem(); else if (pcurs > CURSOR_HAND) { TryIconCurs(); @@ -1864,7 +1864,7 @@ void PerformSpellAction() return; } - if (pcurs >= CURSOR_FIRSTITEM && !TryDropItem()) + if (!MyPlayer->HoldItem.isEmpty() && !TryDropItem()) return; if (pcurs > CURSOR_HAND) NewCursor(CURSOR_HAND); @@ -1963,7 +1963,7 @@ void PerformSecondaryAction() return; } - if (pcurs >= CURSOR_FIRSTITEM && !TryDropItem()) + if (!MyPlayer->HoldItem.isEmpty() && !TryDropItem()) return; if (pcurs > CURSOR_HAND) NewCursor(CURSOR_HAND); diff --git a/Source/controls/touch/event_handlers.cpp b/Source/controls/touch/event_handlers.cpp index 512c46ed6..9915e1547 100644 --- a/Source/controls/touch/event_handlers.cpp +++ b/Source/controls/touch/event_handlers.cpp @@ -89,7 +89,7 @@ bool HandleSpeedBookInteraction(const SDL_Event &event) void HandleBottomPanelInteraction(const SDL_Event &event) { - if (pcurs >= CURSOR_FIRSTITEM) + if (!MyPlayer->HoldItem.isEmpty()) return; ClearPanBtn(); @@ -118,7 +118,7 @@ void HandleCharacterPanelInteraction(const SDL_Event &event) void HandleStashPanelInteraction(const SDL_Event &event) { - if (pcurs >= CURSOR_FIRSTITEM) + if (!MyPlayer->HoldItem.isEmpty()) return; if (event.type != SDL_FINGERUP) { diff --git a/Source/controls/touch/renderers.cpp b/Source/controls/touch/renderers.cpp index 21ec4728e..414ab802f 100644 --- a/Source/controls/touch/renderers.cpp +++ b/Source/controls/touch/renderers.cpp @@ -466,7 +466,7 @@ VirtualGamepadButtonType SecondaryActionButtonRenderer::GetButtonType() VirtualGamepadButtonType SpellActionButtonRenderer::GetButtonType() { - if (pcurs >= CURSOR_FIRSTITEM) + if (!MyPlayer->HoldItem.isEmpty()) return GetDropButtonType(virtualPadButton->isHeld); if (invflag && pcursinvitem != -1 && pcurs == CURSOR_HAND) { diff --git a/Source/cursor.cpp b/Source/cursor.cpp index 86d8b272f..6853c58c5 100644 --- a/Source/cursor.cpp +++ b/Source/cursor.cpp @@ -68,6 +68,7 @@ const uint16_t InvItemWidth2[] = { // clang-format on }; constexpr uint16_t InvItems1Size = sizeof(InvItemWidth1) / sizeof(InvItemWidth1[0]); +constexpr uint16_t InvItems2Size = sizeof(InvItemWidth2) / sizeof(InvItemWidth2[0]); /** Maps from objcurs.cel frame number to frame height. */ const uint16_t InvItemHeight1[InvItems1Size] = { @@ -93,7 +94,7 @@ const uint16_t InvItemHeight1[InvItems1Size] = { 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, }; -const uint16_t InvItemHeight2[] = { +const uint16_t InvItemHeight2[InvItems2Size] = { 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, @@ -105,8 +106,6 @@ const uint16_t InvItemHeight2[] = { } // namespace -/** Pixel size of the current cursor image */ -Size cursSize; /** Current highlighted monster */ int pcursmonst = -1; @@ -172,7 +171,6 @@ void NewCursor(int cursId) MyPlayer->HoldItem._itype = ItemType::None; } pcurs = cursId; - cursSize = cursId == CURSOR_NONE ? Size { 0, 0 } : GetInvItemSize(cursId); if (IsHardwareCursorEnabled() && ControlDevice == ControlTypes::KeyboardAndMouse) { if (ArtCursor.surface == nullptr && cursId == CURSOR_NONE) @@ -190,8 +188,8 @@ void CelDrawCursor(const Surface &out, Point position, int cursId) { const auto &sprite = GetInvItemSprite(cursId); const int frame = GetInvItemFrame(cursId); - if (IsItemSprite(cursId)) { - const auto &heldItem = Players[MyPlayerId].HoldItem; + if (!MyPlayer->HoldItem.isEmpty()) { + const auto &heldItem = MyPlayer->HoldItem; CelBlitOutlineTo(out, GetOutlineColor(heldItem, true), position, sprite, frame, false); CelDrawItem(heldItem, out, position, sprite, frame); } else { @@ -367,7 +365,7 @@ void CheckCursMove() if (myPlayer._pInvincible) { return; } - if (pcurs >= CURSOR_FIRSTITEM || spselflag) { + if (!myPlayer.HoldItem.isEmpty() || spselflag) { cursPosition = { mx, my }; return; } diff --git a/Source/cursor.h b/Source/cursor.h index 06aab1640..4520b45ea 100644 --- a/Source/cursor.h +++ b/Source/cursor.h @@ -32,7 +32,6 @@ enum cursor_id : uint8_t { CURSOR_FIRSTITEM, }; -extern DVL_API_FOR_TEST Size cursSize; extern int pcursmonst; extern int8_t pcursinvitem; extern uint16_t pcursstashitem; @@ -51,11 +50,6 @@ void CheckRportal(); void CheckTown(); void CheckCursMove(); -inline bool IsItemSprite(int cursId) -{ - return cursId >= CURSOR_FIRSTITEM; -} - void CelDrawCursor(const Surface &out, Point position, int cursId); /** Returns the sprite for the given inventory index. */ diff --git a/Source/debug.cpp b/Source/debug.cpp index a033038a6..cebe158b5 100644 --- a/Source/debug.cpp +++ b/Source/debug.cpp @@ -783,7 +783,7 @@ std::string DebugCmdItemInfo(const string_view parameter) { auto &myPlayer = Players[MyPlayerId]; Item *pItem = nullptr; - if (pcurs >= CURSOR_FIRSTITEM) { + if (!myPlayer.HoldItem.isEmpty()) { pItem = &myPlayer.HoldItem; } else if (pcursinvitem != -1) { if (pcursinvitem <= INVITEM_INV_LAST) diff --git a/Source/diablo.cpp b/Source/diablo.cpp index d12f2f60c..3be2988d6 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -342,9 +342,9 @@ void LeftMouseDown(int wParam) CheckStashButtonPress(MousePosition); } else if (sbookflag && GetRightPanel().Contains(MousePosition)) { CheckSBook(); - } else if (pcurs >= CURSOR_FIRSTITEM) { + } else if (!MyPlayer->HoldItem.isEmpty()) { if (TryInvPut()) { - NetSendCmdPItem(true, CMD_PUTITEM, cursPosition, Players[MyPlayerId].HoldItem); + NetSendCmdPItem(true, CMD_PUTITEM, cursPosition, MyPlayer->HoldItem); NewCursor(CURSOR_HAND); } } else { diff --git a/Source/hwcursor.cpp b/Source/hwcursor.cpp index a8c5091ef..2b4883876 100644 --- a/Source/hwcursor.cpp +++ b/Source/hwcursor.cpp @@ -98,7 +98,7 @@ bool SetHardwareCursor(SDL_Surface *surface, HotpointPosition hotpointPosition) bool SetHardwareCursorFromSprite(int pcurs) { - const bool isItem = IsItemSprite(pcurs); + const bool isItem = !MyPlayer->HoldItem.isEmpty(); if (isItem && !*sgOptions.Graphics.hardwareCursorForItems) return false; diff --git a/Source/inv.cpp b/Source/inv.cpp index bd58c4560..ad6d99b72 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -582,7 +582,7 @@ void CheckInvPaste(int pnum, Point cursorPosition) CalcPlrInv(player, true); if (pnum == MyPlayerId) { if (cn == CURSOR_HAND && !IsHardwareCursor()) - SetCursorPos(MousePosition + Displacement(cursSize / 2)); + SetCursorPos(MousePosition + Displacement { itemSize * INV_SLOT_HALF_SIZE_PX }); NewCursor(cn); } } @@ -856,6 +856,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove, bool dropIt NewCursor(holdItem._iCurs + CURSOR_FIRSTITEM); if (!IsHardwareCursor() && !dropItem) { // For a hardware cursor, we set the "hot point" to the center of the item instead. + Size cursSize = GetInvItemSize(holdItem._iCurs + CURSOR_FIRSTITEM); SetCursorPos(cursorPosition - Displacement(cursSize / 2)); } } @@ -1596,7 +1597,7 @@ void TransferItemToStash(Player &player, int location) void CheckInvItem(bool isShiftHeld, bool isCtrlHeld) { - if (pcurs >= CURSOR_FIRSTITEM) { + if (!MyPlayer->HoldItem.isEmpty()) { CheckInvPaste(MyPlayerId, MousePosition); } else if (IsStashOpen && isCtrlHeld) { TransferItemToStash(*MyPlayer, pcursinvitem); @@ -1627,7 +1628,7 @@ void InvGetItem(int pnum, int ii) auto &player = Players[pnum]; - if (MyPlayerId == pnum && pcurs >= CURSOR_FIRSTITEM) + if (MyPlayerId == pnum && !player.HoldItem.isEmpty()) NetSendCmdPItem(true, CMD_SYNCPUTITEM, player.position.tile, player.HoldItem); item._iCreateInfo &= ~CF_PREGEN; @@ -1635,12 +1636,11 @@ void InvGetItem(int pnum, int ii) CheckQuestItem(player, player.HoldItem); UpdateBookLevel(player, player.HoldItem); player.HoldItem._iStatFlag = player.CanUseItem(player.HoldItem); - bool cursorUpdated = false; if (player.HoldItem._itype == ItemType::Gold && GoldAutoPlace(player, player.HoldItem)) - cursorUpdated = true; + player.HoldItem._itype == ItemType::None; CleanupItems(ii); pcursitem = -1; - if (!cursorUpdated) + if (!player.HoldItem.isEmpty()) NewCursor(player.HoldItem._iCurs + CURSOR_FIRSTITEM); } diff --git a/Source/miniwin/misc_msg.cpp b/Source/miniwin/misc_msg.cpp index 7db9000e1..3ab3446be 100644 --- a/Source/miniwin/misc_msg.cpp +++ b/Source/miniwin/misc_msg.cpp @@ -296,7 +296,7 @@ bool FalseAvail(const char *name, int value) */ bool BlurInventory() { - if (pcurs >= CURSOR_FIRSTITEM) { + if (!MyPlayer->HoldItem.isEmpty()) { if (!TryDropItem()) { Players[MyPlayerId].Say(HeroSpeech::WhereWouldIPutThis); return false; diff --git a/Source/player.cpp b/Source/player.cpp index 76ef0c5b7..86eef5725 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -3136,7 +3136,7 @@ StartPlayerKill(int pnum, int earflag) if (pnum == MyPlayerId) { drawhpflag = true; - if (pcurs >= CURSOR_FIRSTITEM) { + if (!player.HoldItem.isEmpty()) { DeadItem(player, std::move(player.HoldItem), { 0, 0 }); NewCursor(CURSOR_HAND); } diff --git a/Source/qol/stash.cpp b/Source/qol/stash.cpp index e9602340e..734a3f781 100644 --- a/Source/qol/stash.cpp +++ b/Source/qol/stash.cpp @@ -225,6 +225,7 @@ void CheckStashCut(Point cursorPosition, bool automaticMove) NewCursor(holdItem._iCurs + CURSOR_FIRSTITEM); if (!IsHardwareCursor()) { // For a hardware cursor, we set the "hot point" to the center of the item instead. + Size cursSize = GetInvItemSize(holdItem._iCurs + CURSOR_FIRSTITEM); SetCursorPos(cursorPosition - Displacement(cursSize / 2)); } } @@ -381,7 +382,7 @@ void DrawStash(const Surface &out) void CheckStashItem(Point mousePosition, bool isShiftHeld, bool isCtrlHeld) { - if (pcurs >= CURSOR_FIRSTITEM) { + if (!MyPlayer->HoldItem.isEmpty()) { CheckStashPaste(mousePosition); } else if (isCtrlHeld) { TransferItemToInventory(*MyPlayer, pcursstashitem); diff --git a/Source/scrollrt.cpp b/Source/scrollrt.cpp index db1dbd0c0..1086eae8a 100644 --- a/Source/scrollrt.cpp +++ b/Source/scrollrt.cpp @@ -265,12 +265,17 @@ bool ShouldShowCursor() */ void DrawCursor(const Surface &out) { - if (pcurs <= CURSOR_NONE || cursSize.width == 0 || cursSize.height == 0 || !ShouldShowCursor()) { + if (pcurs <= CURSOR_NONE || !ShouldShowCursor()) { + return; + } + + Size cursSize = GetInvItemSize(pcurs); + if (cursSize.width == 0 || cursSize.height == 0) { return; } // Copy the buffer before the item cursor and its 1px outline are drawn to a temporary buffer. - const int outlineWidth = IsItemSprite(pcurs) ? 1 : 0; + const int outlineWidth = !MyPlayer->HoldItem.isEmpty() ? 1 : 0; if (MousePosition.x < -cursSize.width - outlineWidth || MousePosition.x - outlineWidth >= out.w() || MousePosition.y < -cursSize.height - outlineWidth || MousePosition.y - outlineWidth >= out.h()) return; @@ -1573,7 +1578,7 @@ void ScrollView() { bool scroll; - if (pcurs >= CURSOR_FIRSTITEM) + if (!MyPlayer->HoldItem.isEmpty()) return; scroll = false; diff --git a/Source/towners.cpp b/Source/towners.cpp index 2fcff2209..8b53d4085 100644 --- a/Source/towners.cpp +++ b/Source/towners.cpp @@ -876,7 +876,7 @@ void TalkToTowner(Player &player, int t) if (player.position.tile.WalkingDistance(towner.position) >= 2) return; - if (pcurs >= CURSOR_FIRSTITEM) { + if (!player.HoldItem.isEmpty()) { return; } diff --git a/test/cursor_test.cpp b/test/cursor_test.cpp index 36190478d..61bde6f5a 100644 --- a/test/cursor_test.cpp +++ b/test/cursor_test.cpp @@ -1,15 +1,11 @@ #include #include "cursor.h" -#include "itemdat.h" using namespace devilution; -TEST(Cursor, SetCursor) +TEST(Cursor, NewCursor) { - int i = ICURS_SPIKED_CLUB + CURSOR_FIRSTITEM; - NewCursor(i); - EXPECT_EQ(pcurs, i); - EXPECT_EQ(cursSize.width, 1 * 28); - EXPECT_EQ(cursSize.height, 3 * 28); + NewCursor(CURSOR_HOURGLASS); + EXPECT_EQ(pcurs, CURSOR_HOURGLASS); }