diff options
author | Shauren <shauren.trinity@gmail.com> | 2024-05-13 00:30:31 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2024-05-13 00:30:31 +0200 |
commit | 6f9e359701bd75705f73f23af65affb5a5bed573 (patch) | |
tree | 021e9ae43f75e04af31364536a95042457af9262 /src | |
parent | 2c286b5fb6b23bf8354af06f884aabe98c66d254 (diff) |
Core/Items: Implemented reagent bag
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 438 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/VoidStorageHandler.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 2 |
5 files changed, 149 insertions, 310 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 36dc7f8d4f1..ea44e883944 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7830,7 +7830,7 @@ void Player::DuelComplete(DuelCompleteType type) void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemAuras /*= true*/) { - if (slot >= INVENTORY_SLOT_BAG_END || !item) + if (slot >= REAGENT_BAG_SLOT_END || !item) return; ItemTemplate const* proto = item->GetTemplate(); @@ -7866,7 +7866,7 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemA void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply) { ItemTemplate const* proto = item->GetTemplate(); - if (slot >= INVENTORY_SLOT_BAG_END || !proto) + if (slot >= REAGENT_BAG_SLOT_END || !proto) return; uint32 itemLevel = item->GetItemLevel(this); @@ -8180,7 +8180,7 @@ void Player::CastAllObtainSpells() if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) ApplyItemObtainSpells(item, true); - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = INVENTORY_SLOT_BAG_START; i < REAGENT_BAG_SLOT_END; ++i) { Bag* bag = GetBagByPos(i); if (!bag) @@ -8359,7 +8359,7 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, void Player::UpdateEquipSpellsAtFormChange() { - for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (m_items[i] && !m_items[i]->IsBroken() && CanUseAttackType(Player::GetAttackBySlot(i, m_items[i]->GetTemplate()->GetInventoryType()))) { @@ -8869,7 +8869,7 @@ void Player::_RemoveAllItemMods() { TC_LOG_DEBUG("entities.player.items", "_RemoveAllItemMods start."); - for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (m_items[i]) { @@ -8890,7 +8890,7 @@ void Player::_RemoveAllItemMods() } } - for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (m_items[i]) { @@ -8909,7 +8909,7 @@ void Player::_ApplyAllItemMods() { TC_LOG_DEBUG("entities.player.items", "_ApplyAllItemMods start."); - for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (m_items[i]) { @@ -8925,7 +8925,7 @@ void Player::_ApplyAllItemMods() } } - for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (m_items[i]) { @@ -8951,7 +8951,7 @@ void Player::_ApplyAllItemMods() void Player::_ApplyAllLevelScaleItemMods(bool apply) { - for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (m_items[i]) { @@ -8974,7 +8974,7 @@ void Player::_ApplyAllLevelScaleItemMods(bool apply) void Player::ApplyAllAzeriteItemMods(bool apply) { - for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (m_items[i]) { @@ -8988,7 +8988,7 @@ void Player::ApplyAllAzeriteItemMods(bool apply) void Player::ApplyAllAzeriteEmpoweredItemMods(bool apply) { - for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (m_items[i]) { @@ -9188,11 +9188,7 @@ void Player::SendRespecWipeConfirm(ObjectGuid const& guid, uint32 cost, SpecRese uint8 Player::FindEquipSlot(Item const* item, uint32 slot, bool swap) const { - uint8 slots[4]; - slots[0] = NULL_SLOT; - slots[1] = NULL_SLOT; - slots[2] = NULL_SLOT; - slots[3] = NULL_SLOT; + std::array<uint8, 4> slots = { NULL_SLOT, NULL_SLOT, NULL_SLOT, NULL_SLOT }; switch (item->GetTemplate()->GetInventoryType()) { case INVTYPE_HEAD: @@ -9276,10 +9272,10 @@ uint8 Player::FindEquipSlot(Item const* item, uint32 slot, bool swap) const slots[0] = EQUIPMENT_SLOT_MAINHAND; break; case INVTYPE_BAG: - slots[0] = INVENTORY_SLOT_BAG_START + 0; - slots[1] = INVENTORY_SLOT_BAG_START + 1; - slots[2] = INVENTORY_SLOT_BAG_START + 2; - slots[3] = INVENTORY_SLOT_BAG_START + 3; + if (item->GetTemplate()->GetClass() != ITEM_CLASS_CONTAINER || item->GetTemplate()->GetSubClass() != ITEM_SUBCLASS_REAGENT_CONTAINER) + slots = { INVENTORY_SLOT_BAG_START + 0, INVENTORY_SLOT_BAG_START + 1, INVENTORY_SLOT_BAG_START + 2, INVENTORY_SLOT_BAG_START + 3 }; + else + slots[0] = REAGENT_BAG_SLOT_START; break; case INVTYPE_PROFESSION_TOOL: case INVTYPE_PROFESSION_GEAR: @@ -9287,7 +9283,7 @@ uint8 Player::FindEquipSlot(Item const* item, uint32 slot, bool swap) const bool isProfessionTool = item->GetTemplate()->GetInventoryType() == INVTYPE_PROFESSION_TOOL; // Validate item class - if (!(item->GetTemplate()->GetClass() == ITEM_CLASS_PROFESSION)) + if (item->GetTemplate()->GetClass() != ITEM_CLASS_PROFESSION) return NULL_SLOT; // Check if player has profession skill @@ -9330,7 +9326,7 @@ uint8 Player::FindEquipSlot(Item const* item, uint32 slot, bool swap) const else { slots[0] = PROFESSION_SLOT_PROFESSION1_GEAR1 + professionSlot * PROFESSION_SLOT_MAX_COUNT; - slots[0] = PROFESSION_SLOT_PROFESSION1_GEAR2 + professionSlot * PROFESSION_SLOT_MAX_COUNT; + slots[1] = PROFESSION_SLOT_PROFESSION1_GEAR2 + professionSlot * PROFESSION_SLOT_MAX_COUNT; } break; @@ -9584,28 +9580,6 @@ Bag* Player::GetBagByPos(uint8 bag) const return nullptr; } -uint32 Player::GetFreeInventorySpace() const -{ - uint32 freeSpace = 0; - - // Check backpack - for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; ++slot) - { - Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot); - if (!item) - freeSpace += 1; - } - - // Check bags - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) - { - if (Bag* bag = GetBagByPos(i)) - freeSpace += bag->GetFreeSlots(); - } - - return freeSpace; -} - Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable /*= false*/) const { uint8 slot; @@ -9691,6 +9665,8 @@ bool Player::IsInventoryPos(uint8 bag, uint8 slot) return true; if (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END) return true; + if (bag >= REAGENT_BAG_SLOT_START && bag < REAGENT_BAG_SLOT_END) + return true; if (bag == INVENTORY_SLOT_BAG_0 && (slot >= CHILD_EQUIPMENT_SLOT_START && slot < CHILD_EQUIPMENT_SLOT_END)) return true; return false; @@ -10152,7 +10128,7 @@ InventoryResult Player::CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, Ite return EQUIP_ERR_WRONG_BAG_TYPE; // specialized bag mode or non-specialized - if (non_specialized != (pBagProto->GetClass() == ITEM_CLASS_CONTAINER && pBagProto->GetSubClass() == ITEM_SUBCLASS_CONTAINER)) + if (non_specialized != (pBagProto->GetClass() == ITEM_CLASS_CONTAINER && (pBagProto->GetSubClass() == ITEM_SUBCLASS_CONTAINER || pBagProto->GetSubClass() == ITEM_SUBCLASS_REAGENT_CONTAINER))) return EQUIP_ERR_WRONG_BAG_TYPE; if (!ItemCanGoIntoBag(pProto, pBagProto)) @@ -10284,42 +10260,65 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des // check count of items (skip for auto move for same player from bank) uint32 no_similar_count = 0; // can't store this amount similar items - InventoryResult res = CanTakeMoreSimilarItems(entry, count, pItem, &no_similar_count); - if (res != EQUIP_ERR_OK) + auto tryHandleInvStoreResult = [&](InventoryResult res) -> Optional<InventoryResult> { - if (count == no_similar_count) + if (res != EQUIP_ERR_OK) { if (no_space_count) - *no_space_count = no_similar_count; + *no_space_count = count + no_similar_count; return res; } - count -= no_similar_count; - } - // in specific slot - if (bag != NULL_BAG && slot != NULL_SLOT) - { - res = CanStoreItem_InSpecificSlot(bag, slot, dest, pProto, count, swap, pItem); - if (res != EQUIP_ERR_OK) + if (count == 0) { + if (no_similar_count == 0) + return EQUIP_ERR_OK; if (no_space_count) *no_space_count = count + no_similar_count; - return res; + return EQUIP_ERR_ITEM_MAX_COUNT; } - if (count == 0) + // not handled + return {}; + }; + + auto tryHandleBagStoreResult = [&](InventoryResult res) -> Optional<InventoryResult> + { + if (res == EQUIP_ERR_OK && count == 0) { if (no_similar_count == 0) return EQUIP_ERR_OK; - if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_ITEM_MAX_COUNT; } + + // not handled + return {}; + }; + + InventoryResult res = CanTakeMoreSimilarItems(entry, count, pItem, &no_similar_count); + if (res != EQUIP_ERR_OK) + { + if (count == no_similar_count) + { + if (no_space_count) + *no_space_count = no_similar_count; + return res; + } + count -= no_similar_count; + } + + // in specific slot + if (bag != NULL_BAG && slot != NULL_SLOT) + { + res = CanStoreItem_InSpecificSlot(bag, slot, dest, pProto, count, swap, pItem); + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; } // not specific slot or have space for partly store only in specific slot - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + uint8 inventorySlotEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); // in specific bag if (bag != NULL_BAG) @@ -10330,40 +10329,12 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des if (bag == INVENTORY_SLOT_BAG_0) // inventory { res = CanStoreItem_InInventorySlots(CHILD_EQUIPMENT_SLOT_START, CHILD_EQUIPMENT_SLOT_END, dest, pProto, count, true, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } - - res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventoryEnd, dest, pProto, count, true, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventorySlotEnd, dest, pProto, count, true, pItem, bag, slot); + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; } else // equipped bag { @@ -10372,22 +10343,8 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des if (res != EQUIP_ERR_OK) res = CanStoreItem_InBag(bag, dest, pProto, count, true, true, pItem, NULL_BAG, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; } } @@ -10397,41 +10354,13 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des if (pItem && pItem->HasItemFlag(ITEM_FIELD_FLAG_CHILD)) { res = CanStoreItem_InInventorySlots(CHILD_EQUIPMENT_SLOT_START, CHILD_EQUIPMENT_SLOT_END, dest, pProto, count, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } - } - - res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventoryEnd, dest, pProto, count, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; } - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventorySlotEnd, dest, pProto, count, false, pItem, bag, slot); + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; } else // equipped bag { @@ -10439,22 +10368,8 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des if (res != EQUIP_ERR_OK) res = CanStoreItem_InBag(bag, dest, pProto, count, false, true, pItem, NULL_BAG, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; } } @@ -10464,76 +10379,38 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des if (pProto->GetMaxStackSize() != 1) { res = CanStoreItem_InInventorySlots(CHILD_EQUIPMENT_SLOT_START, CHILD_EQUIPMENT_SLOT_END, dest, pProto, count, true, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } - - res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventoryEnd, dest, pProto, count, true, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventorySlotEnd, dest, pProto, count, true, pItem, bag, slot); + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; if (pProto->GetBagFamily()) { for (uint32 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { res = CanStoreItem_InBag(i, dest, pProto, count, true, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - continue; - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; + if (Optional<InventoryResult> res2 = tryHandleBagStoreResult(res)) + return *res2; + } + } - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + if (pProto->IsCraftingReagent()) + { + for (uint32 i = REAGENT_BAG_SLOT_START; i < REAGENT_BAG_SLOT_END; i++) + { + res = CanStoreItem_InBag(i, dest, pProto, count, true, true, pItem, bag, slot); + if (Optional<InventoryResult> res2 = tryHandleBagStoreResult(res)) + return *res2; } } for (uint32 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { res = CanStoreItem_InBag(i, dest, pProto, count, true, true, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - continue; - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + if (Optional<InventoryResult> res2 = tryHandleBagStoreResult(res)) + return *res2; } } @@ -10543,18 +10420,18 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des for (uint32 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { res = CanStoreItem_InBag(i, dest, pProto, count, false, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - continue; - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; + if (Optional<InventoryResult> res2 = tryHandleBagStoreResult(res)) + return *res2; + } + } - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + if (pProto->IsCraftingReagent()) + { + for (uint32 i = REAGENT_BAG_SLOT_START; i < REAGENT_BAG_SLOT_END; i++) + { + res = CanStoreItem_InBag(i, dest, pProto, count, false, true, pItem, bag, slot); + if (Optional<InventoryResult> res2 = tryHandleBagStoreResult(res)) + return *res2; } } @@ -10564,64 +10441,41 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des if (pItem && pItem->HasItemFlag(ITEM_FIELD_FLAG_CHILD)) { res = CanStoreItem_InInventorySlots(CHILD_EQUIPMENT_SLOT_START, CHILD_EQUIPMENT_SLOT_END, dest, pProto, count, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; } // search free slot - uint8 searchSlotStart = INVENTORY_SLOT_ITEM_START; // new bags can be directly equipped - if (!pItem && pProto->GetClass() == ITEM_CLASS_CONTAINER && pProto->GetSubClass() == ITEM_SUBCLASS_CONTAINER && + if (!pItem && pProto->GetClass() == ITEM_CLASS_CONTAINER && (pProto->GetBonding() == BIND_NONE || pProto->GetBonding() == BIND_ON_ACQUIRE)) - searchSlotStart = INVENTORY_SLOT_BAG_START; - - res = CanStoreItem_InInventorySlots(searchSlotStart, inventoryEnd, dest, pProto, count, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; + switch (pProto->GetSubClass()) + { + case ITEM_SUBCLASS_CONTAINER: + res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_BAG_START, INVENTORY_SLOT_BAG_END, dest, pProto, count, false, pItem, bag, slot); + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; + break; + case ITEM_SUBCLASS_REAGENT_CONTAINER: + res = CanStoreItem_InInventorySlots(REAGENT_BAG_SLOT_START, REAGENT_BAG_SLOT_END, dest, pProto, count, false, pItem, bag, slot); + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; + break; + default: + break; + } } - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventorySlotEnd, dest, pProto, count, false, pItem, bag, slot); + if (Optional<InventoryResult> res2 = tryHandleInvStoreResult(res)) + return *res2; for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { res = CanStoreItem_InBag(i, dest, pProto, count, false, true, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - continue; - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_ITEM_MAX_COUNT; - } + if (Optional<InventoryResult> res2 = tryHandleBagStoreResult(res)) + return *res2; } if (no_space_count) @@ -10639,11 +10493,11 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending // counts uint32 inventoryCounts[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START] = {}; - uint32 bagCounts[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE] = {}; + uint32 bagCounts[AsUnderlyingType(REAGENT_BAG_SLOT_END) - AsUnderlyingType(INVENTORY_SLOT_BAG_START)][MAX_BAG_SIZE] = {}; // Item pointers Item* inventoryPointers[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START] = {}; - Item* bagPointers[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE] = {}; + Item* bagPointers[AsUnderlyingType(REAGENT_BAG_SLOT_END) - AsUnderlyingType(INVENTORY_SLOT_BAG_START)][MAX_BAG_SIZE] = {}; uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); @@ -10659,7 +10513,7 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending } } - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + for (uint8 i = INVENTORY_SLOT_BAG_START; i < REAGENT_BAG_SLOT_END; i++) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) { @@ -10730,7 +10584,7 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending if (b_found) continue; - for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t) + for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < REAGENT_BAG_SLOT_END; ++t) { if (Bag* bag = GetBagByPos(t)) { @@ -10765,14 +10619,14 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending { bool b_found = false; - for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t) + for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < REAGENT_BAG_SLOT_END; ++t) { if (Bag* bag = GetBagByPos(t)) { pBagProto = bag->GetTemplate(); // not plain container check - if (pBagProto && (pBagProto->GetClass() != ITEM_CLASS_CONTAINER || pBagProto->GetSubClass() != ITEM_SUBCLASS_CONTAINER) && + if (pBagProto && (pBagProto->GetClass() != ITEM_CLASS_CONTAINER || (pBagProto->GetSubClass() != ITEM_SUBCLASS_CONTAINER && pBagProto->GetSubClass() != ITEM_SUBCLASS_REAGENT_CONTAINER)) && ItemCanGoIntoBag(pProto, pBagProto)) { for (uint32 j = 0; j < bag->GetBagSize(); j++) @@ -10812,14 +10666,14 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending continue; // search free slot in bags - for (uint8 t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t) + for (uint8 t = INVENTORY_SLOT_BAG_START; !b_found && t < REAGENT_BAG_SLOT_END; ++t) { if (Bag* bag = GetBagByPos(t)) { pBagProto = bag->GetTemplate(); // special bag already checked - if (pBagProto && (pBagProto->GetClass() != ITEM_CLASS_CONTAINER || pBagProto->GetSubClass() != ITEM_SUBCLASS_CONTAINER)) + if (pBagProto && (pBagProto->GetClass() != ITEM_CLASS_CONTAINER || (pBagProto->GetSubClass() != ITEM_SUBCLASS_CONTAINER && pBagProto->GetSubClass() != ITEM_SUBCLASS_REAGENT_CONTAINER))) continue; for (uint32 j = 0; j < bag->GetBagSize(); j++) @@ -11658,7 +11512,7 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool AddEnchantmentDurations(pItem); AddItemDurations(pItem); - if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < REAGENT_BAG_SLOT_END)) ApplyItemObtainSpells(pItem, true); return pItem; @@ -11697,7 +11551,7 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool pItem2->SetState(ITEM_CHANGED, this); - if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < REAGENT_BAG_SLOT_END)) ApplyItemObtainSpells(pItem2, true); return pItem2; @@ -12030,7 +11884,7 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update) if (bag == INVENTORY_SLOT_BAG_0) { - if (slot < INVENTORY_SLOT_BAG_END) + if (slot < REAGENT_BAG_SLOT_END) { // item set bonuses applied only at equip and removed at unequip, and still active for broken items ItemTemplate const* pProto = ASSERT_NOTNULL(pItem->GetTemplate()); @@ -12183,7 +12037,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) SetInvSlot(slot, ObjectGuid::Empty); // equipment and equipped bags can have applied bonuses - if (slot < INVENTORY_SLOT_BAG_END) + if (slot < REAGENT_BAG_SLOT_END) { // item set bonuses applied only at equip and removed at unequip, and still active for broken items if (pProto->GetItemSet()) @@ -12281,7 +12135,7 @@ uint32 Player::DestroyItemCount(uint32 itemEntry, uint32 count, bool update, boo } // in inventory bags - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + for (uint8 i = INVENTORY_SLOT_BAG_START; i < REAGENT_BAG_SLOT_END; i++) { if (Bag* bag = GetBagByPos(i)) { @@ -12316,7 +12170,7 @@ uint32 Player::DestroyItemCount(uint32 itemEntry, uint32 count, bool update, boo } // in equipment and bag list - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) + for (uint8 i = EQUIPMENT_SLOT_START; i < REAGENT_BAG_SLOT_END; i++) { if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { @@ -12509,7 +12363,7 @@ void Player::DestroyZoneLimitedItem(bool update, uint32 new_zone) DestroyItem(INVENTORY_SLOT_BAG_0, i, update); // in inventory bags - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + for (uint8 i = INVENTORY_SLOT_BAG_START; i < REAGENT_BAG_SLOT_END; i++) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) if (Item* pItem = pBag->GetItemByPos(j)) @@ -12517,7 +12371,7 @@ void Player::DestroyZoneLimitedItem(bool update, uint32 new_zone) DestroyItem(i, j, update); // in equipment and bag list - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) + for (uint8 i = EQUIPMENT_SLOT_START; i < REAGENT_BAG_SLOT_END; i++) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(), new_zone)) DestroyItem(INVENTORY_SLOT_BAG_0, i, update); @@ -12538,7 +12392,7 @@ void Player::DestroyConjuredItems(bool update) DestroyItem(INVENTORY_SLOT_BAG_0, i, update); // in inventory bags - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + for (uint8 i = INVENTORY_SLOT_BAG_START; i < REAGENT_BAG_SLOT_END; i++) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) if (Item* pItem = pBag->GetItemByPos(j)) @@ -12546,7 +12400,7 @@ void Player::DestroyConjuredItems(bool update) DestroyItem(i, j, update); // in equipment and bag list - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) + for (uint8 i = EQUIPMENT_SLOT_START; i < REAGENT_BAG_SLOT_END; i++) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->IsConjuredConsumable()) DestroyItem(INVENTORY_SLOT_BAG_0, i, update); @@ -13074,7 +12928,7 @@ void Player::SwapItem(uint16 src, uint16 dst) // if inventory item was moved, check if we can remove dependent auras, because they were not removed in Player::RemoveItem (update was set to false) // do this after swaps are done, we pass nullptr because both weapons could be swapped and none of them should be ignored - if ((srcbag == INVENTORY_SLOT_BAG_0 && srcslot < INVENTORY_SLOT_BAG_END) || (dstbag == INVENTORY_SLOT_BAG_0 && dstslot < INVENTORY_SLOT_BAG_END)) + if ((srcbag == INVENTORY_SLOT_BAG_0 && srcslot < REAGENT_BAG_SLOT_END) || (dstbag == INVENTORY_SLOT_BAG_0 && dstslot < REAGENT_BAG_SLOT_END)) ApplyItemDependentAuras((Item*)nullptr, false); // if player is moving bags and is looting an item inside this bag @@ -13498,7 +13352,7 @@ void Player::RemoveArenaEnchantments(EnchantmentSlot slot) pItem->ClearEnchantment(slot); // in inventory bags - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = INVENTORY_SLOT_BAG_START; i < REAGENT_BAG_SLOT_END; ++i) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) if (Item* pItem = pBag->GetItemByPos(j)) @@ -13895,7 +13749,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool void Player::UpdateSkillEnchantments(uint16 skill_id, uint16 curr_value, uint16 new_value) { - for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint8 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (m_items[i]) { diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 95eaa6ac681..641f6c43826 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1375,7 +1375,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> Item* GetUseableItemByPos(uint8 bag, uint8 slot) const; Bag* GetBagByPos(uint8 slot) const; std::vector<Item*> GetCraftingReagentItemsToDeposit(); - uint32 GetFreeInventorySpace() const; Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const; Item* GetShield(bool useable = false) const; Item* GetChildItemByGuid(ObjectGuid guid) const; diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 4e7c154ceed..e166d69ac48 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -305,7 +305,7 @@ void WorldSession::HandleAutoEquipItemOpcode(WorldPackets::Item::AutoEquipItem& // if inventory item was moved, check if we can remove dependent auras, because they were not removed in Player::RemoveItem (update was set to false) // do this after swaps are done, we pass nullptr because both weapons could be swapped and none of them should be ignored - if ((autoEquipItem.PackSlot == INVENTORY_SLOT_BAG_0 && autoEquipItem.Slot < INVENTORY_SLOT_BAG_END) || (dstbag == INVENTORY_SLOT_BAG_0 && dstslot < INVENTORY_SLOT_BAG_END)) + if ((autoEquipItem.PackSlot == INVENTORY_SLOT_BAG_0 && autoEquipItem.Slot < REAGENT_BAG_SLOT_END) || (dstbag == INVENTORY_SLOT_BAG_0 && dstslot < REAGENT_BAG_SLOT_END)) _player->ApplyItemDependentAuras((Item*)nullptr, false); } } diff --git a/src/server/game/Handlers/VoidStorageHandler.cpp b/src/server/game/Handlers/VoidStorageHandler.cpp index 1d143c8a820..2ab4ee8fb8f 100644 --- a/src/server/game/Handlers/VoidStorageHandler.cpp +++ b/src/server/game/Handlers/VoidStorageHandler.cpp @@ -108,21 +108,7 @@ void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStor return; } - uint32 freeBagSlots = 0; - if (!voidStorageTransfer.Withdrawals.empty()) - { - // make this a Player function - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) - if (Bag* bag = _player->GetBagByPos(i)) - freeBagSlots += bag->GetFreeSlots(); - - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + _player->GetInventorySlotCount(); - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; i++) - if (!_player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - ++freeBagSlots; - } - - if (voidStorageTransfer.Withdrawals.size() > freeBagSlots) + if (!voidStorageTransfer.Withdrawals.empty() && voidStorageTransfer.Withdrawals.size() > _player->GetFreeInventorySlotCount(ItemSearchLocation::Inventory)) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); return; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 8304e18df69..53d14d7ea69 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -7700,7 +7700,7 @@ SpellCastResult Spell::CheckItems(int32* param1 /*= nullptr*/, int32* param2 /*= // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items, // so we need to make sure there is at least one free space in the player's inventory if (spellEffectInfo.Effect == SPELL_EFFECT_CREATE_LOOT) - if (target->ToPlayer()->GetFreeInventorySpace() == 0) + if (target->ToPlayer()->GetFreeInventorySlotCount(ItemSearchLocation::Inventory) == 0) { player->SendEquipError(EQUIP_ERR_INV_FULL, nullptr, nullptr, spellEffectInfo.ItemType); return SPELL_FAILED_DONT_REPORT; |