From 822a0cd22a3e075cb510f7cff0adae010440a4ce Mon Sep 17 00:00:00 2001 From: staphen Date: Sun, 27 Mar 2022 02:39:16 -0400 Subject: [PATCH] Fix auto-equip network messages --- Source/inv.cpp | 135 +++++++++++++++++++++++++++------------------- Source/inv.h | 8 +++ Source/msg.cpp | 13 ++--- Source/player.cpp | 26 ++++----- 4 files changed, 105 insertions(+), 77 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index 3299cbe44..3f37a1d20 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -262,6 +262,15 @@ bool CanEquip(Player &player, const Item &item, inv_body_loc bodyLocation) } } +void ChangeEquipment(Player &player, inv_body_loc bodyLocation, const Item &item) +{ + player.InvBody[bodyLocation] = item; + + if (&player == MyPlayer) { + NetSendCmdChItem(false, bodyLocation); + } +} + bool AutoEquip(int playerId, const Item &item, inv_body_loc bodyLocation, bool persistItem) { auto &player = Players[playerId]; @@ -271,13 +280,12 @@ bool AutoEquip(int playerId, const Item &item, inv_body_loc bodyLocation, bool p } if (persistItem) { - player.InvBody[bodyLocation] = item; + ChangeEquipment(player, bodyLocation, item); if (*sgOptions.Audio.autoEquipSound && playerId == MyPlayerId) { PlaySFX(ItemInvSnds[ItemCAnimTbl[item._iCurs]]); } - NetSendCmdChItem(false, bodyLocation); CalcPlrInv(player, true); } @@ -432,11 +440,12 @@ void CheckInvPaste(int pnum, Point cursorPosition) } }; inv_body_loc slot = iLocToInvLoc(il); - NetSendCmdChItem(false, slot); - if (player.InvBody[slot].isEmpty()) - player.InvBody[slot] = player.HoldItem; - else - cn = SwapItem(player.InvBody[slot], player.HoldItem); + Item previouslyEquippedItem = player.InvBody[slot]; + ChangeEquipment(player, slot, player.HoldItem); + if (!previouslyEquippedItem.isEmpty()) { + player.HoldItem = previouslyEquippedItem; + cn = previouslyEquippedItem._iCurs + CURSOR_FIRSTITEM; + } break; } case ILOC_ONEHAND: @@ -444,23 +453,28 @@ void CheckInvPaste(int pnum, Point cursorPosition) if (player.InvBody[INVLOC_HAND_LEFT].isEmpty()) { if ((player.InvBody[INVLOC_HAND_RIGHT].isEmpty() || player.InvBody[INVLOC_HAND_RIGHT]._iClass != player.HoldItem._iClass) || (player._pClass == HeroClass::Bard && player.InvBody[INVLOC_HAND_RIGHT]._iClass == ICLASS_WEAPON && player.HoldItem._iClass == ICLASS_WEAPON)) { - NetSendCmdChItem(false, INVLOC_HAND_LEFT); - player.InvBody[INVLOC_HAND_LEFT] = player.HoldItem; + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem); } else { - NetSendCmdChItem(false, INVLOC_HAND_RIGHT); - cn = SwapItem(player.InvBody[INVLOC_HAND_RIGHT], player.HoldItem); + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_RIGHT]; + ChangeEquipment(player, INVLOC_HAND_RIGHT, player.HoldItem); + player.HoldItem = previouslyEquippedItem; + cn = previouslyEquippedItem._iCurs + CURSOR_FIRSTITEM; } break; } if ((player.InvBody[INVLOC_HAND_RIGHT].isEmpty() || player.InvBody[INVLOC_HAND_RIGHT]._iClass != player.HoldItem._iClass) || (player._pClass == HeroClass::Bard && player.InvBody[INVLOC_HAND_RIGHT]._iClass == ICLASS_WEAPON && player.HoldItem._iClass == ICLASS_WEAPON)) { - NetSendCmdChItem(false, INVLOC_HAND_LEFT); - cn = SwapItem(player.InvBody[INVLOC_HAND_LEFT], player.HoldItem); + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_LEFT]; + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem); + player.HoldItem = previouslyEquippedItem; + cn = previouslyEquippedItem._iCurs + CURSOR_FIRSTITEM; break; } - NetSendCmdChItem(false, INVLOC_HAND_RIGHT); - cn = SwapItem(player.InvBody[INVLOC_HAND_RIGHT], player.HoldItem); + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_RIGHT]; + ChangeEquipment(player, INVLOC_HAND_RIGHT, player.HoldItem); + player.HoldItem = previouslyEquippedItem; + cn = previouslyEquippedItem._iCurs + CURSOR_FIRSTITEM; break; } if (player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { @@ -468,29 +482,35 @@ void CheckInvPaste(int pnum, Point cursorPosition) || (player._pClass == HeroClass::Barbarian && (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Sword || player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Mace))) { if ((player.InvBody[INVLOC_HAND_LEFT].isEmpty() || player.InvBody[INVLOC_HAND_LEFT]._iClass != player.HoldItem._iClass) || (player._pClass == HeroClass::Bard && player.InvBody[INVLOC_HAND_LEFT]._iClass == ICLASS_WEAPON && player.HoldItem._iClass == ICLASS_WEAPON)) { - NetSendCmdChItem(false, INVLOC_HAND_RIGHT); - player.InvBody[INVLOC_HAND_RIGHT] = player.HoldItem; + ChangeEquipment(player, INVLOC_HAND_RIGHT, player.HoldItem); break; } - NetSendCmdChItem(false, INVLOC_HAND_LEFT); - cn = SwapItem(player.InvBody[INVLOC_HAND_LEFT], player.HoldItem); + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_LEFT]; + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem); + player.HoldItem = previouslyEquippedItem; + cn = previouslyEquippedItem._iCurs + CURSOR_FIRSTITEM; break; } - NetSendCmdDelItem(false, INVLOC_HAND_LEFT); - NetSendCmdChItem(false, INVLOC_HAND_RIGHT); - SwapItem(player.InvBody[INVLOC_HAND_RIGHT], player.InvBody[INVLOC_HAND_LEFT]); - cn = SwapItem(player.InvBody[INVLOC_HAND_RIGHT], player.HoldItem); + Item twoHandedWeapon = player.InvBody[INVLOC_HAND_LEFT]; + RemoveEquipment(player, INVLOC_HAND_LEFT, false); + ChangeEquipment(player, INVLOC_HAND_RIGHT, player.HoldItem); + player.HoldItem = twoHandedWeapon; + cn = twoHandedWeapon._iCurs + CURSOR_FIRSTITEM; break; } if ((!player.InvBody[INVLOC_HAND_LEFT].isEmpty() && player.InvBody[INVLOC_HAND_LEFT]._iClass == player.HoldItem._iClass) && !(player._pClass == HeroClass::Bard && player.InvBody[INVLOC_HAND_LEFT]._iClass == ICLASS_WEAPON && player.HoldItem._iClass == ICLASS_WEAPON)) { - NetSendCmdChItem(false, INVLOC_HAND_LEFT); - cn = SwapItem(player.InvBody[INVLOC_HAND_LEFT], player.HoldItem); - break; + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_LEFT]; + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem); + player.HoldItem = previouslyEquippedItem; + cn = previouslyEquippedItem._iCurs + CURSOR_FIRSTITEM; + } else { + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_RIGHT]; + ChangeEquipment(player, INVLOC_HAND_RIGHT, player.HoldItem); + player.HoldItem = previouslyEquippedItem; + cn = previouslyEquippedItem._iCurs + CURSOR_FIRSTITEM; } - NetSendCmdChItem(false, INVLOC_HAND_RIGHT); - cn = SwapItem(player.InvBody[INVLOC_HAND_RIGHT], player.HoldItem); break; case ILOC_TWOHAND: if (!player.InvBody[INVLOC_HAND_LEFT].isEmpty() && !player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { @@ -512,22 +532,27 @@ void CheckInvPaste(int pnum, Point cursorPosition) if (!done2h) return; - if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield) - player.InvBody[INVLOC_HAND_RIGHT]._itype = ItemType::None; - else + if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield) { + RemoveEquipment(player, INVLOC_HAND_RIGHT, false); + } else { + // CMD_CHANGEPLRITEMS will eventually be sent for the left hand player.InvBody[INVLOC_HAND_LEFT]._itype = ItemType::None; + } } - NetSendCmdDelItem(false, INVLOC_HAND_RIGHT); - - if (!player.InvBody[INVLOC_HAND_LEFT].isEmpty() || !player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { - NetSendCmdChItem(false, INVLOC_HAND_LEFT); - if (player.InvBody[INVLOC_HAND_LEFT].isEmpty()) - SwapItem(player.InvBody[INVLOC_HAND_LEFT], player.InvBody[INVLOC_HAND_RIGHT]); - cn = SwapItem(player.InvBody[INVLOC_HAND_LEFT], player.HoldItem); + if (player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_LEFT]; + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem); + if (!previouslyEquippedItem.isEmpty()) { + player.HoldItem = previouslyEquippedItem; + cn = previouslyEquippedItem._iCurs + CURSOR_FIRSTITEM; + } } else { - NetSendCmdChItem(false, INVLOC_HAND_LEFT); - player.InvBody[INVLOC_HAND_LEFT] = player.HoldItem; + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_RIGHT]; + RemoveEquipment(player, INVLOC_HAND_RIGHT, false); + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem); + player.HoldItem = previouslyEquippedItem; + cn = previouslyEquippedItem._iCurs + CURSOR_FIRSTITEM; } break; case ILOC_UNEQUIPABLE: @@ -665,8 +690,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove, bool dropIt } if (!automaticMove || automaticallyMoved) { - NetSendCmdDelItem(false, INVLOC_HEAD); - headItem._itype = ItemType::None; + RemoveEquipment(player, INVLOC_HEAD, false); } } @@ -679,8 +703,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove, bool dropIt } if (!automaticMove || automaticallyMoved) { - NetSendCmdDelItem(false, INVLOC_RING_LEFT); - leftRingItem._itype = ItemType::None; + RemoveEquipment(player, INVLOC_RING_LEFT, false); } } @@ -693,8 +716,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove, bool dropIt } if (!automaticMove || automaticallyMoved) { - NetSendCmdDelItem(false, INVLOC_RING_RIGHT); - rightRingItem._itype = ItemType::None; + RemoveEquipment(player, INVLOC_RING_RIGHT, false); } } @@ -707,8 +729,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove, bool dropIt } if (!automaticMove || automaticallyMoved) { - NetSendCmdDelItem(false, INVLOC_AMULET); - amuletItem._itype = ItemType::None; + RemoveEquipment(player, INVLOC_AMULET, false); } } @@ -721,8 +742,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove, bool dropIt } if (!automaticMove || automaticallyMoved) { - NetSendCmdDelItem(false, INVLOC_HAND_LEFT); - leftHandItem._itype = ItemType::None; + RemoveEquipment(player, INVLOC_HAND_LEFT, false); } } @@ -735,8 +755,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove, bool dropIt } if (!automaticMove || automaticallyMoved) { - NetSendCmdDelItem(false, INVLOC_HAND_RIGHT); - rightHandItem._itype = ItemType::None; + RemoveEquipment(player, INVLOC_HAND_RIGHT, false); } } @@ -749,8 +768,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove, bool dropIt } if (!automaticMove || automaticallyMoved) { - NetSendCmdDelItem(false, INVLOC_CHEST); - chestItem._itype = ItemType::None; + RemoveEquipment(player, INVLOC_CHEST, false); } } @@ -1357,6 +1375,15 @@ void DrawInvBelt(const Surface &out) } } +void RemoveEquipment(Player &player, inv_body_loc bodyLocation, bool hiPri) +{ + if (&player == MyPlayer) { + NetSendCmdDelItem(hiPri, bodyLocation); + } + + player.InvBody[bodyLocation]._itype = ItemType::None; +} + bool AutoPlaceItemInBelt(Player &player, const Item &item, bool persistItem) { if (!CanBePlacedOnBelt(item)) { diff --git a/Source/inv.h b/Source/inv.h index 3c3149301..e8bf94519 100644 --- a/Source/inv.h +++ b/Source/inv.h @@ -111,6 +111,14 @@ void DrawInv(const Surface &out); void DrawInvBelt(const Surface &out); +/** + * @brief Removes equipment from the specified location on the player's body. + * @param player The player from which equipment will be removed. + * @param bodyLocation The location from which equipment will be removed. + * @param hiPri Priority of the network message to sync player equipment. + */ +void RemoveEquipment(Player &player, inv_body_loc bodyLocation, bool hiPri); + /** * @brief Checks whether or not auto-equipping behavior is enabled for the given player and item. * @param player The player to check. diff --git a/Source/msg.cpp b/Source/msg.cpp index 7378dc95a..b61ee3a29 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -2615,15 +2615,16 @@ void NetSendCmdChItem(bool bHiPri, BYTE bLoc) { TCmdChItem cmd; - auto &myPlayer = Players[MyPlayerId]; + Player &myPlayer = Players[MyPlayerId]; + Item &item = myPlayer.InvBody[bLoc]; cmd.bCmd = CMD_CHANGEPLRITEMS; cmd.bLoc = bLoc; - cmd.wIndx = myPlayer.HoldItem.IDidx; - cmd.wCI = myPlayer.HoldItem._iCreateInfo; - cmd.dwSeed = myPlayer.HoldItem._iSeed; - cmd.bId = myPlayer.HoldItem._iIdentified ? 1 : 0; - cmd.dwBuff = myPlayer.HoldItem.dwBuff; + cmd.wIndx = item.IDidx; + cmd.wCI = item._iCreateInfo; + cmd.dwSeed = item._iSeed; + cmd.bId = item._iIdentified ? 1 : 0; + cmd.dwBuff = item.dwBuff; if (bHiPri) NetSendHiPri(MyPlayerId, (byte *)&cmd, sizeof(cmd)); diff --git a/Source/player.cpp b/Source/player.cpp index 8a017072f..ee7ab1714 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -730,8 +730,7 @@ bool WeaponDecay(Player &player, int ii) if (!player.InvBody[ii].isEmpty() && player.InvBody[ii]._iClass == ICLASS_WEAPON && (player.InvBody[ii]._iDamAcFlags & ISPLHF_DECAY) != 0) { player.InvBody[ii]._iPLDam -= 5; if (player.InvBody[ii]._iPLDam <= -100) { - NetSendCmdDelItem(true, ii); - player.InvBody[ii]._itype = ItemType::None; + RemoveEquipment(player, static_cast(ii), true); CalcPlrInv(player, true); return true; } @@ -767,8 +766,7 @@ bool DamageWeapon(int pnum, int durrnd) player.InvBody[INVLOC_HAND_LEFT]._iDurability--; if (player.InvBody[INVLOC_HAND_LEFT]._iDurability <= 0) { - NetSendCmdDelItem(true, INVLOC_HAND_LEFT); - player.InvBody[INVLOC_HAND_LEFT]._itype = ItemType::None; + RemoveEquipment(player, INVLOC_HAND_LEFT, true); CalcPlrInv(player, true); return true; } @@ -781,8 +779,7 @@ bool DamageWeapon(int pnum, int durrnd) player.InvBody[INVLOC_HAND_RIGHT]._iDurability--; if (player.InvBody[INVLOC_HAND_RIGHT]._iDurability == 0) { - NetSendCmdDelItem(true, INVLOC_HAND_RIGHT); - player.InvBody[INVLOC_HAND_RIGHT]._itype = ItemType::None; + RemoveEquipment(player, INVLOC_HAND_RIGHT, true); CalcPlrInv(player, true); return true; } @@ -795,8 +792,7 @@ bool DamageWeapon(int pnum, int durrnd) player.InvBody[INVLOC_HAND_RIGHT]._iDurability--; if (player.InvBody[INVLOC_HAND_RIGHT]._iDurability == 0) { - NetSendCmdDelItem(true, INVLOC_HAND_RIGHT); - player.InvBody[INVLOC_HAND_RIGHT]._itype = ItemType::None; + RemoveEquipment(player, INVLOC_HAND_RIGHT, true); CalcPlrInv(player, true); return true; } @@ -809,8 +805,7 @@ bool DamageWeapon(int pnum, int durrnd) player.InvBody[INVLOC_HAND_LEFT]._iDurability--; if (player.InvBody[INVLOC_HAND_LEFT]._iDurability == 0) { - NetSendCmdDelItem(true, INVLOC_HAND_LEFT); - player.InvBody[INVLOC_HAND_LEFT]._itype = ItemType::None; + RemoveEquipment(player, INVLOC_HAND_LEFT, true); CalcPlrInv(player, true); return true; } @@ -1308,8 +1303,7 @@ void DamageParryItem(int pnum) player.InvBody[INVLOC_HAND_LEFT]._iDurability--; if (player.InvBody[INVLOC_HAND_LEFT]._iDurability == 0) { - NetSendCmdDelItem(true, INVLOC_HAND_LEFT); - player.InvBody[INVLOC_HAND_LEFT]._itype = ItemType::None; + RemoveEquipment(player, INVLOC_HAND_LEFT, true); CalcPlrInv(player, true); } } @@ -1318,8 +1312,7 @@ void DamageParryItem(int pnum) if (player.InvBody[INVLOC_HAND_RIGHT]._iDurability != DUR_INDESTRUCTIBLE) { player.InvBody[INVLOC_HAND_RIGHT]._iDurability--; if (player.InvBody[INVLOC_HAND_RIGHT]._iDurability == 0) { - NetSendCmdDelItem(true, INVLOC_HAND_RIGHT); - player.InvBody[INVLOC_HAND_RIGHT]._itype = ItemType::None; + RemoveEquipment(player, INVLOC_HAND_RIGHT, true); CalcPlrInv(player, true); } } @@ -1387,11 +1380,10 @@ void DamageArmor(int pnum) } if (a != 0) { - NetSendCmdDelItem(true, INVLOC_CHEST); + RemoveEquipment(player, INVLOC_CHEST, true); } else { - NetSendCmdDelItem(true, INVLOC_HEAD); + RemoveEquipment(player, INVLOC_HEAD, true); } - pi->_itype = ItemType::None; CalcPlrInv(player, true); }