diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp index 532f4d48bb1..3ad2b8610f0 100644 --- a/src/creatures/combat/combat.cpp +++ b/src/creatures/combat/combat.cpp @@ -946,7 +946,7 @@ void Combat::setupChain(const std::shared_ptr &weapon) { } const auto &weaponType = weapon->getWeaponType(); - if (weaponType == WEAPON_NONE || weaponType == WEAPON_SHIELD || weaponType == WEAPON_AMMO || weaponType == WEAPON_DISTANCE) { + if (weaponType == WEAPON_NONE || weaponType == WEAPON_SHIELD || weaponType == WEAPON_AMMO || weaponType == WEAPON_DISTANCE || weaponType == WEAPON_MISSILE) { return; } diff --git a/src/game/game.cpp b/src/game/game.cpp index 53e887c9096..7adaf196dff 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -3153,28 +3153,40 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* = auto slotItem = player->getInventoryItem(slot); auto equipItem = searchForItem(backpack, it.id, hasTier, tier); + ReturnValue ret = RETURNVALUE_NOERROR; if (slotItem && slotItem->getID() == it.id && (!it.stackable || slotItem->getItemCount() == slotItem->getStackSize() || !equipItem)) { - internalMoveItem(slotItem->getParent(), player, CONST_SLOT_WHEREEVER, slotItem, slotItem->getItemCount(), nullptr); + ret = internalMoveItem(slotItem->getParent(), player, CONST_SLOT_WHEREEVER, slotItem, slotItem->getItemCount(), nullptr); g_logger().debug("Item {} was unequipped", slotItem->getName()); } else if (equipItem) { + // Shield slot item + const auto &rightItem = player->getInventoryItem(CONST_SLOT_RIGHT); + // Check Ammo item if (it.weaponType == WEAPON_AMMO) { - auto quiver = player->getInventoryItem(CONST_SLOT_RIGHT); - if (quiver && quiver->isQuiver()) { - internalMoveItem(equipItem->getParent(), quiver->getContainer(), 0, equipItem, equipItem->getItemCount(), nullptr); - return; + if (rightItem && rightItem->isQuiver()) { + ret = internalMoveItem(equipItem->getParent(), rightItem->getContainer(), 0, equipItem, equipItem->getItemCount(), nullptr); + } + } else { + const int32_t &slotPosition = equipItem->getSlotPosition(); + // Checks if a two-handed item is being equipped in the left slot when the right slot is already occupied and move to backpack + if (slotPosition & SLOTP_LEFT && rightItem && (slotPosition & SLOTP_TWO_HAND)) { + ret = internalCollectManagedItems(player, rightItem, getObjectCategory(rightItem), false); } - } - if (slotItem) { - internalMoveItem(slotItem->getParent(), player, INDEX_WHEREEVER, slotItem, slotItem->getItemCount(), nullptr); - g_logger().debug("Item {} was moved back to player", slotItem->getName()); - } + if (slotItem) { + ret = internalMoveItem(slotItem->getParent(), player, INDEX_WHEREEVER, slotItem, slotItem->getItemCount(), nullptr); + g_logger().debug("Item {} was moved back to player", slotItem->getName()); + } - auto ret = internalMoveItem(equipItem->getParent(), player, slot, equipItem, equipItem->getItemCount(), nullptr); - if (ret == RETURNVALUE_NOERROR) { - g_logger().debug("Item {} was equipped", equipItem->getName()); + ret = internalMoveItem(equipItem->getParent(), player, slot, equipItem, equipItem->getItemCount(), nullptr); + if (ret == RETURNVALUE_NOERROR) { + g_logger().debug("Item {} was equipped", equipItem->getName()); + } } } + + if (ret != RETURNVALUE_NOERROR) { + player->sendCancelMessage(ret); + } } void Game::playerMove(uint32_t playerId, Direction direction) {