diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index 55edf0035..a6b883796 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -1809,7 +1809,7 @@ void UpdateSpellTarget(spell_id spell) */ bool TryDropItem() { - auto &myPlayer = Players[MyPlayerId]; + auto &myPlayer = *MyPlayer; if (myPlayer.HoldItem.isEmpty()) { return false; @@ -1828,18 +1828,21 @@ bool TryDropItem() } } - cursPosition = myPlayer.position.future + Direction::SouthEast; - if (!DropItemBeforeTrig()) { - // Try to drop on the other side - cursPosition = myPlayer.position.future + Direction::SouthWest; - DropItemBeforeTrig(); - } - - if (pcurs != CURSOR_HAND) { - myPlayer.Say(HeroSpeech::WhereWouldIPutThis); + Point position = myPlayer.position.future; + Direction direction = myPlayer._pdir; + if (!CanPut(position, direction)) { + direction = Opposite(direction); + // if we can't drop in front of the player, can we drop it behind? + if (!CanPut(position, direction)) { + myPlayer.Say(HeroSpeech::WhereWouldIPutThis); + return false; + } } - return pcurs == CURSOR_HAND; + NetSendCmdPItem(true, CMD_PUTITEM, position + direction, myPlayer.HoldItem); + myPlayer.HoldItem.Clear(); + NewCursor(CURSOR_HAND); + return true; } void PerformSpellAction() diff --git a/Source/diablo.cpp b/Source/diablo.cpp index ed44cd3d1..d77672f06 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -343,7 +343,8 @@ void LeftMouseDown(int wParam) } else if (sbookflag && GetRightPanel().Contains(MousePosition)) { CheckSBook(); } else if (!MyPlayer->HoldItem.isEmpty()) { - if (TryInvPut()) { + Point currentPosition = MyPlayer->position.tile; + if (CanPut(currentPosition, GetDirection(currentPosition, cursPosition))) { NetSendCmdPItem(true, CMD_PUTITEM, cursPosition, MyPlayer->HoldItem); NewCursor(CURSOR_HAND); } diff --git a/Source/inv.cpp b/Source/inv.cpp index deb379581..71ff7f5ac 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -1736,27 +1736,24 @@ bool CanPut(Point position) return true; } -bool TryInvPut() +bool CanPut(Point position, Direction dir) { if (ActiveItemCount >= MAXITEMS) return false; - auto &myPlayer = Players[MyPlayerId]; - - Direction dir = GetDirection(myPlayer.position.tile, cursPosition); - if (CanPut(myPlayer.position.tile + dir)) { + if (CanPut(position + dir)) { return true; } - if (CanPut(myPlayer.position.tile + Left(dir))) { + if (CanPut(position + Left(dir))) { return true; } - if (CanPut(myPlayer.position.tile + Right(dir))) { + if (CanPut(position + Right(dir))) { return true; } - return CanPut(myPlayer.position.tile); + return CanPut(position); } int InvPutItem(Player &player, Point position, Item &item) @@ -2163,17 +2160,6 @@ int CalculateGold(Player &player) return gold; } -bool DropItemBeforeTrig() -{ - if (!TryInvPut()) { - return false; - } - - NetSendCmdPItem(true, CMD_PUTITEM, cursPosition, Players[MyPlayerId].HoldItem); - NewCursor(CURSOR_HAND); - return true; -} - Size GetInventorySize(const Item &item) { int itemSizeIndex = item._iCurs + CURSOR_FIRSTITEM; diff --git a/Source/inv.h b/Source/inv.h index fe8a615aa..b5da7d856 100644 --- a/Source/inv.h +++ b/Source/inv.h @@ -198,8 +198,23 @@ void AutoGetItem(int pnum, Item *item, int ii); */ int FindGetItem(int32_t iseed, _item_indexes idx, uint16_t ci); void SyncGetItem(Point position, int32_t iseed, _item_indexes idx, uint16_t ci); + +/** + * @brief Checks if the tile has room for an item + * @param position tile coordinates + * @return True if the space is free of obstructions, false if blocked + */ bool CanPut(Point position); -bool TryInvPut(); + +/** + * @brief Checks for free spaces in the three "adjacent" tiles in the given direction and also the given position. + * @see CanPut + * @param position base tile coordinates + * @param facing direction to check, tiles "left" and "right" of this direction will also be checked. + * @return True if any of the four tiles checked can accept an item, false if all blocked + */ +bool CanPut(Point position, Direction facing); + int InvPutItem(Player &player, Point position, Item &item); int SyncPutItem(Player &player, Point position, int idx, uint16_t icreateinfo, int iseed, int Id, int dur, int mdur, int ch, int mch, int ivalue, uint32_t ibuff, int toHit, int maxDam, int minStr, int minMag, int minDex, int ac); int SyncDropItem(Point position, int idx, uint16_t icreateinfo, int iseed, int id, int dur, int mdur, int ch, int mch, int ivalue, uint32_t ibuff, int toHit, int maxDam, int minStr, int minMag, int minDex, int ac); @@ -212,7 +227,6 @@ Item &GetInventoryItem(Player &player, int location); bool UseInvItem(int pnum, int cii); void DoTelekinesis(); int CalculateGold(Player &player); -bool DropItemBeforeTrig(); /** * @brief Gets the size, in inventory cells, of the given item.