diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 406aeb08f..a568772cf 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -3719,6 +3719,14 @@ void Player::SwapItem(uint16 src, uint16 dst) } } + // Remove item enchantments for now and restore it later + // Needed for swap sanity checks + ApplyEnchantment(pSrcItem, false); + if (pDstItem) + { + ApplyEnchantment(pDstItem, false); + } + // impossible merge/fill, do real swap InventoryResult msg = EQUIP_ERR_OK; @@ -3738,6 +3746,13 @@ void Player::SwapItem(uint16 src, uint16 dst) if (msg != EQUIP_ERR_OK) { + // Restore enchantments + ApplyEnchantment(pSrcItem, true); + if (pDstItem) + { + ApplyEnchantment(pDstItem, true); + } + SendEquipError(msg, pSrcItem, pDstItem); return; } @@ -3758,10 +3773,24 @@ void Player::SwapItem(uint16 src, uint16 dst) if (msg != EQUIP_ERR_OK) { + // Restore enchantments + ApplyEnchantment(pSrcItem, true); + if (pDstItem) + { + ApplyEnchantment(pDstItem, true); + } + SendEquipError(msg, pDstItem, pSrcItem); return; } + // Restore enchantments + ApplyEnchantment(pSrcItem, true); + if (pDstItem) + { + ApplyEnchantment(pDstItem, true); + } + // Check bag swap with item exchange (one from empty in not bag possition (equipped (not possible in fact) or store) if (Bag* srcBag = pSrcItem->ToBag()) { diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 55b4d078b..854cd44d2 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -172,19 +172,47 @@ void WorldSession::HandleAutoEquipItemOpcode(WorldPacket& recvData) if (!pSrcItem) return; // only at cheat - uint16 dest; - InventoryResult msg = _player->CanEquipItem(NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag()); - if (msg != EQUIP_ERR_OK) + ItemTemplate const* pProto = pSrcItem->GetTemplate(); + if (!pProto) + { + return; + } + + uint8 eslot = _player->FindEquipSlot(pProto, NULL_SLOT, !pSrcItem->IsBag()); + if (eslot == NULL_SLOT) { - _player->SendEquipError(msg, pSrcItem, nullptr); return; } uint16 src = pSrcItem->GetPos(); - if (dest == src) // prevent equip in same slot, only at cheat + uint16 dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot); + if (dest == src) // prevent equip in same slot, only at cheat + { return; + } Item* pDstItem = _player->GetItemByPos(dest); + + // Remove item enchantments for now and restore it later + // Needed for swap sanity checks + if (pDstItem) + { + _player->ApplyEnchantment(pDstItem, false); + } + + InventoryResult msg = _player->CanEquipItem(NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag()); + if (msg != EQUIP_ERR_OK) + { + // Restore enchantments + if (pDstItem) + { + _player->ApplyEnchantment(pDstItem, true); + } + + _player->SendEquipError(msg, pSrcItem, nullptr); + return; + } + if (!pDstItem) // empty slot, simple case { _player->RemoveItem(srcbag, srcslot, true); @@ -193,6 +221,9 @@ void WorldSession::HandleAutoEquipItemOpcode(WorldPacket& recvData) } else // have currently equipped item, not simple case { + // Restore enchantments + _player->ApplyEnchantment(pDstItem, true); + uint8 dstbag = pDstItem->GetBagSlot(); uint8 dstslot = pDstItem->GetSlot();