Browse Source

SyncPutItem: Always use passed coordinates for item position

pull/5434/head
obligaron 3 years ago committed by Anders Jenbo
parent
commit
ba65d5fbff
  1. 7
      Source/controls/plrctrls.cpp
  2. 5
      Source/diablo.cpp
  3. 5
      Source/inv.cpp
  4. 50
      Source/msg.cpp

7
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<Point> 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;

5
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<Point> itemTile = FindAdjacentPositionForItem(currentPosition, GetDirection(currentPosition, cursPosition));
if (itemTile) {
NetSendCmdPItem(true, CMD_PUTITEM, *itemTile, MyPlayer->HoldItem);
NewCursor(CURSOR_HAND);
}
} else {

5
Source/inv.cpp

@ -1817,11 +1817,10 @@ int SyncPutItem(const Player &player, Point position, _item_indexes idx, uint16_
return -1;
}
std::optional<Point> 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)

50
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);

Loading…
Cancel
Save