From ba65d5fbff5adb266df09a70db60c01ab473fd38 Mon Sep 17 00:00:00 2001 From: obligaron Date: Thu, 20 Oct 2022 19:05:37 +0200 Subject: [PATCH] SyncPutItem: Always use passed coordinates for item position --- Source/controls/plrctrls.cpp | 7 +++-- Source/diablo.cpp | 5 ++-- Source/inv.cpp | 5 ++-- Source/msg.cpp | 50 +++++++++++++++++------------------- 4 files changed, 31 insertions(+), 36 deletions(-) diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index 3c2c7893d..7daf9f832 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -1981,14 +1981,13 @@ bool TryDropItem() } } - Point position = myPlayer.position.future; - Direction direction = myPlayer._pdir; - if (!FindAdjacentPositionForItem(position, direction)) { + std::optional itemTile = FindAdjacentPositionForItem(myPlayer.position.future, myPlayer._pdir); + if (!itemTile) { myPlayer.Say(HeroSpeech::WhereWouldIPutThis); return false; } - NetSendCmdPItem(true, CMD_PUTITEM, position + direction, myPlayer.HoldItem); + NetSendCmdPItem(true, CMD_PUTITEM, *itemTile, myPlayer.HoldItem); myPlayer.HoldItem.clear(); NewCursor(CURSOR_HAND); return true; diff --git a/Source/diablo.cpp b/Source/diablo.cpp index c99f194ec..668b19f99 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -346,8 +346,9 @@ void LeftMouseDown(uint16_t modState) CheckSBook(); } else if (!MyPlayer->HoldItem.isEmpty()) { Point currentPosition = MyPlayer->position.tile; - if (FindAdjacentPositionForItem(currentPosition, GetDirection(currentPosition, cursPosition))) { - NetSendCmdPItem(true, CMD_PUTITEM, cursPosition, MyPlayer->HoldItem); + std::optional itemTile = FindAdjacentPositionForItem(currentPosition, GetDirection(currentPosition, cursPosition)); + if (itemTile) { + NetSendCmdPItem(true, CMD_PUTITEM, *itemTile, MyPlayer->HoldItem); NewCursor(CURSOR_HAND); } } else { diff --git a/Source/inv.cpp b/Source/inv.cpp index 62bb281b3..712cbbce3 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -1817,11 +1817,10 @@ int SyncPutItem(const Player &player, Point position, _item_indexes idx, uint16_ return -1; } - std::optional itemTile = FindAdjacentPositionForItem(player.position.tile, GetDirection(player.position.tile, position)); - if (!itemTile) + if (ActiveItemCount >= MAXITEMS) return -1; - return SyncDropItem(*itemTile, idx, icreateinfo, iseed, id, dur, mdur, ch, mch, ivalue, ibuff, toHit, maxDam, minStr, minMag, minDex, ac); + return SyncDropItem(position, idx, icreateinfo, iseed, id, dur, mdur, ch, mch, ivalue, ibuff, toHit, maxDam, minStr, minMag, minDex, ac); } int SyncDropItem(Point position, _item_indexes 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) diff --git a/Source/msg.cpp b/Source/msg.cpp index 8aeb9f671..529123055 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -154,6 +154,25 @@ DLevel &GetDeltaLevel(const Player &player) return GetDeltaLevel(level); } +Point GetItemPosition(Point position) +{ + if (CanPut(position)) + return position; + + for (int k = 1; k < 50; k++) { + for (int j = -k; j <= k; j++) { + int yy = position.y + j; + for (int l = -k; l <= k; l++) { + int xx = position.x + l; + if (CanPut({ xx, yy })) + return { xx, yy }; + } + } + } + + return position; +} + /** * @brief Throttles that a player command is only sent once per game tick. * This is a workaround for a desync that happens when a command is processed in different game ticks for different clients. See https://github.com/diasurgical/devilutionX/issues/2681 for details. @@ -964,11 +983,11 @@ int SyncPutEar(const TEar &ear) ear.heroname); } -int SyncPutItem(const Player &player, const TItem &item) +int SyncPutItem(const Player &player, Point position, const TItem &item) { return SyncPutItem( player, - player.position.tile, + position, item.wIndx, item.wCI, item.dwSeed, @@ -991,14 +1010,14 @@ int SyncPutItem(const Player &player, const TCmdGItem &message) { if (message.def.wIndx == IDI_EAR) return SyncPutEar(message.ear); - return SyncPutItem(player, message.item); + return SyncPutItem(player, GetItemPosition({ message.x, message.y }), message.item); } int SyncPutItem(const Player &player, const TCmdPItem &message) { if (message.def.wIndx == IDI_EAR) return SyncPutEar(message.ear); - return SyncPutItem(player, message.item); + return SyncPutItem(player, GetItemPosition({ message.x, message.y }), message.item); } int SyncDropItem(Point position, const TCmdPItem message) @@ -2611,29 +2630,6 @@ void DeltaSaveLevel() DeltaLeaveSync(localLevel); } -namespace { - -Point GetItemPosition(Point position) -{ - if (CanPut(position)) - return position; - - for (int k = 1; k < 50; k++) { - for (int j = -k; j <= k; j++) { - int yy = position.y + j; - for (int l = -k; l <= k; l++) { - int xx = position.x + l; - if (CanPut({ xx, yy })) - return { xx, yy }; - } - } - } - - return position; -} - -} // namespace - uint8_t GetLevelForMultiplayer(const Player &player) { return GetLevelForMultiplayer(player.plrlevel, player.plrIsOnSetLevel);