@@ -3473,6 +3473,10 @@ uint64_t Game::getItemMarketPrice(const std::map<uint16_t, uint64_t> &itemMap, b
34733473}
34743474
34753475std::shared_ptr<Item> searchForItem (const std::shared_ptr<Container> &container, uint16_t itemId, bool hasTier /* = false*/ , uint8_t tier /* = 0*/ ) {
3476+ if (!container) {
3477+ return nullptr ;
3478+ }
3479+
34763480 for (ContainerIterator it = container->iterator (); it.hasNext (); it.advance ()) {
34773481 if ((*it)->getID () == itemId && (!hasTier || (*it)->getTier () == tier)) {
34783482 return *it;
@@ -3515,6 +3519,32 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* =
35153519 return ;
35163520 }
35173521
3522+ const ItemType &it = Item::items[itemId];
3523+ Slots_t slot = getSlotType (it);
3524+
3525+ if (slot == CONST_SLOT_NECKLACE) {
3526+ if (!player->canEquipNecklace ()) {
3527+ return ;
3528+ }
3529+ } else if (slot == CONST_SLOT_RING) {
3530+ if (!player->canEquipRing ()) {
3531+ return ;
3532+ }
3533+ } else if (!player->canDoAction ()) {
3534+ uint32_t delay = player->getNextActionTime ();
3535+ if (delay > 0 ) {
3536+ const auto &task = createPlayerTask (
3537+ delay,
3538+ [this , playerId, itemId, hasTier, tier] {
3539+ playerEquipItem (playerId, itemId, hasTier, tier);
3540+ },
3541+ __FUNCTION__
3542+ );
3543+ player->setNextActionTask (task);
3544+ }
3545+ return ;
3546+ }
3547+
35183548 if (player->hasCondition (CONDITION_FEARED)) {
35193549 /*
35203550 * When player is feared the player can´t equip any items.
@@ -3524,32 +3554,22 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* =
35243554 }
35253555
35263556 const auto &item = player->getInventoryItem (CONST_SLOT_BACKPACK);
3527- if (!item) {
3528- return ;
3529- }
3530-
3531- const std::shared_ptr<Container> &backpack = item->getContainer ();
3532- if (!backpack) {
3533- return ;
3534- }
3535-
3536- if (player->getFreeBackpackSlots () == 0 ) {
3537- player->sendCancelMessage (RETURNVALUE_NOTENOUGHROOM);
3538- return ;
3539- }
3540-
3541- const ItemType &it = Item::items[itemId];
3542- Slots_t slot = getSlotType (it);
3557+ const auto &backpack = item ? item->getContainer () : nullptr ;
35433558
35443559 const auto &slotItem = player->getInventoryItem (slot);
3545- const auto &equipItem = searchForItem (backpack, it.id , hasTier, tier);
3560+ auto equipItem = searchForItem (backpack, it.id , hasTier, tier);
3561+ if (!equipItem) {
3562+ const auto &lootPouch = player->getLootPouch ();
3563+ equipItem = searchForItem (lootPouch, it.id , hasTier, tier);
3564+ }
35463565 ReturnValue ret = RETURNVALUE_NOERROR;
3547- if (slotItem && slotItem-> getID () == it. id && (!it. stackable || slotItem-> getItemCount () == slotItem-> getStackSize () || !equipItem)) {
3548- ret = internalMoveItem (slotItem-> getParent (), player, CONST_SLOT_WHEREEVER, slotItem, slotItem->getItemCount (), nullptr );
3549- g_logger (). debug ( " Item {} was unequipped " , slotItem-> getName () );
3566+
3567+ if (slotItem && slotItem-> getID () == it. id && (!hasTier || slotItem->getTier () == tier) && !equipItem) {
3568+ ret = internalCollectManagedItems (player , slotItem, getObjectCategory (slotItem), false );
35503569 } else if (equipItem) {
35513570 // Shield slot item
35523571 const auto &rightItem = player->getInventoryItem (CONST_SLOT_RIGHT);
3572+
35533573 // Check Ammo item
35543574 if (it.weaponType == WEAPON_AMMO) {
35553575 if (rightItem && rightItem->isQuiver ()) {
@@ -3559,62 +3579,39 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t itemId, bool hasTier /* =
35593579 const auto &leftItem = player->getInventoryItem (CONST_SLOT_LEFT);
35603580
35613581 const int32_t &slotPosition = equipItem->getSlotPosition ();
3562-
35633582 // Checks if a two-handed item is being equipped in the left slot when the right slot is already occupied and move to backpack
35643583 if (
35653584 (slotPosition & SLOTP_LEFT)
35663585 && (slotPosition & SLOTP_TWO_HAND)
35673586 && rightItem
3568- && !(it.weaponType == WEAPON_DISTANCE)
35693587 && !rightItem->isQuiver ()
3570- && (!leftItem || leftItem->getWeaponType () != WEAPON_DISTANCE)
35713588 ) {
35723589 ret = internalCollectManagedItems (player, rightItem, getObjectCategory (rightItem), false );
35733590 }
35743591
3575- /* FIX: Auto-unequip shield when equipping two-handed bow */
3576- if (slot == CONST_SLOT_LEFT && (slotPosition & SLOTP_TWO_HAND) && equipItem->getWeaponType () == WEAPON_DISTANCE) {
3577- if (rightItem && !rightItem->isQuiver ()) {
3578- // Unequip item from right slot (shield or other item)
3579- ret = internalMoveItem (rightItem->getParent (), player, INDEX_WHEREEVER, rightItem, rightItem->getItemCount (), nullptr );
3580- if (ret == RETURNVALUE_NOERROR) {
3581- g_logger ().debug (" Item {} was unequipped to equip two-handed bow" , rightItem->getName ());
3582- } else {
3583- player->sendCancelMessage (ret);
3584- return ;
3585- }
3586- }
3587- }
3588-
35893592 // Check if trying to equip a shield while a two-handed weapon is equipped in the left slot
3590- if (slot == CONST_SLOT_RIGHT && leftItem && leftItem->getSlotPosition () & SLOTP_TWO_HAND) {
3591- // FIX: Don't unequip bow if quiver is equipped */
3592- if (!it.isQuiver () || leftItem->getWeaponType () != WEAPON_DISTANCE) {
3593- // Unequip the two-handed weapon from the left slot
3594- ret = internalMoveItem (leftItem->getParent (), player, INDEX_WHEREEVER, leftItem, leftItem->getItemCount (), nullptr );
3595- if (ret == RETURNVALUE_NOERROR) {
3596- g_logger ().debug (" Two-handed weapon {} was unequipped to equip shield" , leftItem->getName ());
3597- } else {
3598- player->sendCancelMessage (ret);
3599- return ;
3600- }
3593+ if (slot == CONST_SLOT_RIGHT && !it.isQuiver () && leftItem && leftItem->getSlotPosition () & SLOTP_TWO_HAND) {
3594+ ret = internalMoveItem (leftItem->getParent (), player, INDEX_WHEREEVER, leftItem, leftItem->getItemCount (), nullptr );
3595+ if (ret != RETURNVALUE_NOERROR) {
3596+ player->sendCancelMessage (ret);
3597+ return ;
36013598 }
36023599 }
36033600
3604- if (slotItem) {
3605- ret = internalMoveItem (slotItem->getParent (), player, INDEX_WHEREEVER, slotItem, slotItem->getItemCount (), nullptr );
3606- g_logger ().debug (" Item {} was moved back to player" , slotItem->getName ());
3607- }
3608-
36093601 ret = internalMoveItem (equipItem->getParent (), player, slot, equipItem, equipItem->getItemCount (), nullptr );
3610- if (ret == RETURNVALUE_NOERROR) {
3611- g_logger ().debug (" Item {} was equipped" , equipItem->getName ());
3612- }
36133602 }
36143603 }
36153604
36163605 if (ret != RETURNVALUE_NOERROR) {
36173606 player->sendCancelMessage (ret);
3607+ return ;
3608+ }
3609+ if (slot == CONST_SLOT_NECKLACE) {
3610+ player->setNextNecklaceAction (OTSYS_TIME () + g_configManager ().getNumber (ACTIONS_DELAY_INTERVAL));
3611+ } else if (slot == CONST_SLOT_RING) {
3612+ player->setNextRingAction (OTSYS_TIME () + g_configManager ().getNumber (ACTIONS_DELAY_INTERVAL));
3613+ } else {
3614+ player->setNextAction (OTSYS_TIME () + g_configManager ().getNumber (ACTIONS_DELAY_INTERVAL));
36183615 }
36193616}
36203617
@@ -4140,14 +4137,13 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position &fromPos, uin
41404137 return ;
41414138 }
41424139
4143- if (g_configManager ().getBoolean (ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS)) {
4144- if (std::shared_ptr<HouseTile> houseTile = std::dynamic_pointer_cast<HouseTile>(item->getTile ())) {
4145- const auto &house = houseTile->getHouse ();
4146- if (house && item->getRealParent () && item->getRealParent () != player && (!house->isInvited (player) || house->getHouseAccessLevel (player) == HOUSE_GUEST)) {
4147- player->sendCancelMessage (RETURNVALUE_CANNOTUSETHISOBJECT);
4148- return ;
4149- }
4150- }
4140+ bool canUseHouseItem = !g_configManager ().getBoolean (ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS) || InternalGame::playerCanUseItemOnHouseTile (player, item);
4141+ if (!canUseHouseItem && item->hasOwner () && !item->isOwner (player)) {
4142+ player->sendCancelMessage (RETURNVALUE_ITEMISNOTYOURS);
4143+ return ;
4144+ } else if (!canUseHouseItem) {
4145+ player->sendCancelMessage (RETURNVALUE_ITEMCANNOTBEMOVEDTHERE);
4146+ return ;
41514147 }
41524148
41534149 const ItemType &it = Item::items[item->getID ()];
0 commit comments