diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Achievements/CriteriaHandler.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Container/Bag.cpp | 47 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Container/Bag.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 675 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 96 | ||||
-rw-r--r-- | src/server/game/Handlers/AzeriteHandler.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/InspectHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 2 |
10 files changed, 376 insertions, 471 deletions
diff --git a/src/server/game/Achievements/CriteriaHandler.cpp b/src/server/game/Achievements/CriteriaHandler.cpp index a9de265d3ba..57a45421017 100644 --- a/src/server/game/Achievements/CriteriaHandler.cpp +++ b/src/server/game/Achievements/CriteriaHandler.cpp @@ -2644,7 +2644,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6 } case CRITERIA_ADDITIONAL_CONDITION_AZERITE_ITEM_LEVEL: // 235 { - Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE); + Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere); if (!heartOfAzeroth || heartOfAzeroth->ToAzeriteItem()->GetLevel() < reqValue) return false; break; @@ -2693,7 +2693,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6 break; case CRITERIA_ADDITIONAL_CONDITION_UNLOCKED_AZERITE_ESSENCE_RANK_LOWER: // 259 { - if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE)) + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere)) if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) if (essence.AzeriteEssenceID == reqValue && essence.Rank < secondaryAsset) @@ -2702,7 +2702,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6 } case CRITERIA_ADDITIONAL_CONDITION_UNLOCKED_AZERITE_ESSENCE_RANK_EQUAL: // 260 { - if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE)) + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere)) if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) if (essence.AzeriteEssenceID == reqValue && essence.Rank == secondaryAsset) @@ -2711,7 +2711,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6 } case CRITERIA_ADDITIONAL_CONDITION_UNLOCKED_AZERITE_ESSENCE_RANK_GREATER: // 261 { - if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE)) + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere)) if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) if (essence.AzeriteEssenceID == reqValue && essence.Rank > secondaryAsset) @@ -2734,7 +2734,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6 return false; break; case CRITERIA_ADDITIONAL_CONDITION_SELECTED_AZERITE_ESSENCE_RANK_LOWER: // 266 - if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE)) + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere)) if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) if (UF::SelectedAzeriteEssences const* selectedEssences = azeriteItem->GetSelectedAzeriteEssences()) for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) @@ -2742,7 +2742,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6 return true; return false; case CRITERIA_ADDITIONAL_CONDITION_SELECTED_AZERITE_ESSENCE_RANK_GREATER: // 267 - if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE)) + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere)) if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) if (UF::SelectedAzeriteEssences const* selectedEssences = azeriteItem->GetSelectedAzeriteEssences()) for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index e6f90796b89..6c50228e32c 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2087,7 +2087,7 @@ void GameObject::Use(Unit* user) } case 2: // Heart Forge { - Item const* item = player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE); + Item const* item = player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere); if (!item) return; diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp index 2b9628034f5..96449083294 100644 --- a/src/server/game/Entities/Item/Container/Bag.cpp +++ b/src/server/game/Entities/Item/Container/Bag.cpp @@ -263,43 +263,6 @@ bool Bag::IsEmpty() const return true; } -uint32 Bag::GetItemCount(uint32 item, Item* eItem) const -{ - Item* pItem; - uint32 count = 0; - for (uint32 i=0; i < GetBagSize(); ++i) - { - pItem = m_bagslot[i]; - if (pItem && pItem != eItem && pItem->GetEntry() == item) - count += pItem->GetCount(); - } - - if (eItem && eItem->GetTemplate()->GetGemProperties()) - { - for (uint32 i=0; i < GetBagSize(); ++i) - { - pItem = m_bagslot[i]; - if (pItem && pItem != eItem && pItem->GetSocketColor(0)) - count += pItem->GetGemCountWithID(item); - } - } - - return count; -} - -uint32 Bag::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem) const -{ - uint32 count = 0; - for (uint32 i = 0; i < GetBagSize(); ++i) - if (Item* pItem = m_bagslot[i]) - if (pItem != skipItem) - if (ItemTemplate const* pProto = pItem->GetTemplate()) - if (pProto->GetItemLimitCategory() == limitCategory) - count += m_bagslot[i]->GetCount(); - - return count; -} - uint8 Bag::GetSlotByItemGUID(ObjectGuid guid) const { for (uint32 i = 0; i < GetBagSize(); ++i) @@ -317,3 +280,13 @@ Item* Bag::GetItemByPos(uint8 slot) const return nullptr; } + +uint32 GetBagSize(Bag const* bag) +{ + return bag->GetBagSize(); +} + +Item* GetItemInBag(Bag const* bag, uint8 slot) +{ + return bag->GetItemByPos(slot); +} diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h index c9906cb85e6..3bf36e3c5ea 100644 --- a/src/server/game/Entities/Item/Container/Bag.h +++ b/src/server/game/Entities/Item/Container/Bag.h @@ -40,8 +40,6 @@ class TC_GAME_API Bag : public Item void RemoveItem(uint8 slot, bool update); Item* GetItemByPos(uint8 slot) const; - uint32 GetItemCount(uint32 item, Item* eItem = nullptr) const; - uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = nullptr) const; uint8 GetSlotByItemGUID(ObjectGuid guid) const; bool IsEmpty() const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0cf360516ac..a81ce529ff5 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -6909,7 +6909,7 @@ void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/, bo if (id == CURRENCY_TYPE_AZERITE) { if (count > 0) - if (Item* heartOfAzeroth = GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE)) + if (Item* heartOfAzeroth = GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere)) heartOfAzeroth->ToAzeriteItem()->GiveXP(uint64(count)); return; } @@ -8153,7 +8153,7 @@ void Player::ApplyAzeritePowers(Item* item, bool apply) } else if (AzeriteEmpoweredItem* azeriteEmpoweredItem = item->ToAzeriteEmpoweredItem()) { - if (!apply || GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_IN_EQUIPMENT)) + if (!apply || GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Equipment)) for (int32 i = 0; i < MAX_AZERITE_EMPOWERED_TIER; ++i) if (AzeritePowerEntry const* azeritePower = sAzeritePowerStore.LookupEntry(azeriteEmpoweredItem->GetSelectedAzeritePower(i))) ApplyAzeritePower(azeriteEmpoweredItem, azeritePower, apply); @@ -9934,128 +9934,53 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c InventoryResult Player::CanUnequipItems(uint32 item, uint32 count) const { - uint32 tempcount = 0; - InventoryResult res = EQUIP_ERR_OK; - - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == item) - { - InventoryResult ires = CanUnequipItem(INVENTORY_SLOT_BAG_0 << 8 | i, false); - if (ires == EQUIP_ERR_OK) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return EQUIP_ERR_OK; - } - else - res = ires; - } - - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == item) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return EQUIP_ERR_OK; - } - - - for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == item) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return EQUIP_ERR_OK; - } - - for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == item) + uint32 tempcount = 0; + bool result = ForEachItem(ItemSearchLocation::Equipment, [this, item, &res, &tempcount, count](Item* pItem) + { + if (pItem->GetEntry() == item) + { + InventoryResult ires = CanUnequipItem(pItem->GetPos(), false); + if (ires == EQUIP_ERR_OK) { tempcount += pItem->GetCount(); if (tempcount >= count) - return EQUIP_ERR_OK; + return ItemSearchCallbackResult::Stop; } + else + res = ires; + } + return ItemSearchCallbackResult::Continue; + }); - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) - if (Bag* pBag = GetBagByPos(i)) - for (uint32 j = 0; j < pBag->GetBagSize(); ++j) - if (Item* pItem = GetItemByPos(i, j)) - if (pItem->GetEntry() == item) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return EQUIP_ERR_OK; - } + if (!result) // we stopped early due to a sucess + return EQUIP_ERR_OK; - // not found req. item count and have unequippable items - return res; + return res; // return latest error if any } uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const { - uint32 count = 0; - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); - for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; i++) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem && pItem->GetEntry() == item) - count += pItem->GetCount(); - - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) - if (Bag* pBag = GetBagByPos(i)) - count += pBag->GetItemCount(item, skipItem); - - if (skipItem && skipItem->GetTemplate()->GetGemProperties()) - for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem && pItem->GetSocketColor(0)) - count += pItem->GetGemCountWithID(item); + bool countGems = skipItem && skipItem->GetTemplate()->GetGemProperties(); + ItemSearchLocation location = ItemSearchLocation::Equipment | ItemSearchLocation::Inventory | ItemSearchLocation::ReagentBank; if (inBankAlso) - { - // checking every item from 39 to 74 (including bank bags) - for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem && pItem->GetEntry() == item) - count += pItem->GetCount(); + location |= ItemSearchLocation::Bank; - for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i) - if (Bag* pBag = GetBagByPos(i)) - count += pBag->GetItemCount(item, skipItem); - - if (skipItem && skipItem->GetTemplate()->GetGemProperties()) - for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem && pItem->GetSocketColor(0)) - count += pItem->GetGemCountWithID(item); - } - - for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem && pItem->GetEntry() == item) + uint32 count = 0; + ForEachItem(location, [&count, item, skipItem, countGems](Item* pItem) + { + if (pItem != skipItem) + { + if (pItem->GetEntry() == item) count += pItem->GetCount(); - if (skipItem && skipItem->GetTemplate()->GetGemProperties()) - for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem && pItem->GetSocketColor(0)) - count += pItem->GetGemCountWithID(item); - - for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem && pItem->GetEntry() == item) - count += pItem->GetCount(); + if (countGems) + count += pItem->GetGemCountWithID(item); + } - if (skipItem && skipItem->GetTemplate()->GetGemProperties()) - for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem && pItem->GetSocketColor(0)) - count += pItem->GetGemCountWithID(item); + return ItemSearchCallbackResult::Continue; + }); return count; } @@ -10063,84 +9988,32 @@ uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const uint32 Player::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem) const { uint32 count = 0; - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); - for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem) - if (ItemTemplate const* pProto = pItem->GetTemplate()) - if (pProto->GetItemLimitCategory() == limitCategory) - count += pItem->GetCount(); - - for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) - if (Bag* pBag = GetBagByPos(i)) - count += pBag->GetItemCountWithLimitCategory(limitCategory, skipItem); - - for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem) - if (ItemTemplate const* pProto = pItem->GetTemplate()) - if (pProto->GetItemLimitCategory() == limitCategory) - count += pItem->GetCount(); - - for (int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i) - if (Bag* pBag = GetBagByPos(i)) - count += pBag->GetItemCountWithLimitCategory(limitCategory, skipItem); - - for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem) - if (ItemTemplate const* pProto = pItem->GetTemplate()) - if (pProto->GetItemLimitCategory() == limitCategory) - count += pItem->GetCount(); - - for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem) - if (ItemTemplate const* pProto = pItem->GetTemplate()) - if (pProto->GetItemLimitCategory() == limitCategory) - count += pItem->GetCount(); + ForEachItem(ItemSearchLocation::Everywhere, [&count, limitCategory, skipItem](Item* item) + { + if (item != skipItem) + if (ItemTemplate const* pProto = item->GetTemplate()) + if (pProto->GetItemLimitCategory() == limitCategory) + count += item->GetCount(); + return ItemSearchCallbackResult::Continue; + }); return count; } Item* Player::GetItemByGuid(ObjectGuid guid) const { - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); - for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetGUID() == guid) - return pItem; - - for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetGUID() == guid) - return pItem; - - for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetGUID() == guid) - return pItem; - - for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetGUID() == guid) - return pItem; - - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) - if (Bag* pBag = GetBagByPos(i)) - for (uint32 j = 0; j < pBag->GetBagSize(); ++j) - if (Item* pItem = pBag->GetItemByPos(j)) - if (pItem->GetGUID() == guid) - return pItem; - - for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i) - if (Bag* pBag = GetBagByPos(i)) - for (uint32 j = 0; j < pBag->GetBagSize(); ++j) - if (Item* pItem = pBag->GetItemByPos(j)) - if (pItem->GetGUID() == guid) - return pItem; + Item* result = nullptr; + ForEachItem(ItemSearchLocation::Everywhere, [&result, guid](Item* item) + { + if (item->GetGUID() == guid) + { + result = item; + return ItemSearchCallbackResult::Stop; + } - return nullptr; + return ItemSearchCallbackResult::Continue; + }); + return result; } Item* Player::GetItemByPos(uint16 pos) const @@ -10231,18 +10104,17 @@ Item* Player::GetShield(bool useable) const Item* Player::GetChildItemByGuid(ObjectGuid guid) const { - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); - for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetGUID() == guid) - return pItem; - - for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetGUID() == guid) - return pItem; - - return nullptr; + Item* result = nullptr; + ForEachItem(ItemSearchLocation::Equipment | ItemSearchLocation::Inventory, [&result, guid](Item* item) + { + if (item->GetGUID() == guid) + { + result = item; + return ItemSearchCallbackResult::Stop; + } + return ItemSearchCallbackResult::Continue; + }); + return result; } WeaponAttackType Player::GetAttackBySlot(uint8 slot, InventoryType inventoryType) @@ -10400,181 +10272,84 @@ void Player::SetInventorySlotCount(uint8 slots) bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const { - uint32 tempcount = 0; - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); - for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; i++) - { - Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return true; - } - } - - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) - { - if (Bag* pBag = GetBagByPos(i)) - { - for (uint32 j = 0; j < pBag->GetBagSize(); j++) - { - Item* pItem = GetItemByPos(i, j); - if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return true; - } - } - } - } - + ItemSearchLocation location = ItemSearchLocation::Equipment | ItemSearchLocation::Inventory | ItemSearchLocation::ReagentBank; if (inBankAlso) - { - for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; i++) - { - Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return true; - } - } - for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) - { - if (Bag* pBag = GetBagByPos(i)) - { - for (uint32 j = 0; j < pBag->GetBagSize(); j++) - { - Item* pItem = GetItemByPos(i, j); - if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return true; - } - } - } - } - } + location |= ItemSearchLocation::Bank; - for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; i++) + uint32 currentCount = 0; + return !ForEachItem(location, [item, count, ¤tCount](Item* pItem) { - Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) + if (pItem->GetEntry() == item && !pItem->IsInTrade()) { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return true; + currentCount += pItem->GetCount(); + if (currentCount >= count) + return ItemSearchCallbackResult::Stop; } - } - - for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; i++) - { - Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return true; - } - } - - return false; + return ItemSearchCallbackResult::Continue; + }); } bool Player::HasItemOrGemWithIdEquipped(uint32 item, uint32 count, uint8 except_slot) const { uint32 tempcount = 0; - for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) - { - if (i == except_slot) - continue; - - Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetEntry() == item) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return true; - } - } ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item); - if (pProto && pProto->GetGemProperties()) + bool includeGems = pProto && pProto->GetGemProperties(); + return !ForEachItem(ItemSearchLocation::Equipment, [item, &tempcount, count, except_slot, includeGems](Item* pItem) { - for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) + if (pItem->GetSlot() != except_slot) { - if (i == except_slot) - continue; + if (pItem->GetEntry() == item) + tempcount += pItem->GetCount(); - Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetSocketColor(0)) - { + if (includeGems) tempcount += pItem->GetGemCountWithID(item); - if (tempcount >= count) - return true; - } + + if (tempcount >= count) + return ItemSearchCallbackResult::Stop; } - } - return false; + return ItemSearchCallbackResult::Continue; + }); } bool Player::HasItemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot) const { uint32 tempcount = 0; - for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) + return !ForEachItem(ItemSearchLocation::Equipment, [&tempcount, limitCategory, count, except_slot](Item* pItem) { - if (i == except_slot) - continue; + if (pItem->GetSlot() == except_slot) + return ItemSearchCallbackResult::Continue; - Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (!pItem) - continue; + if (pItem->GetTemplate()->GetItemLimitCategory() != limitCategory) + return ItemSearchCallbackResult::Continue; - ItemTemplate const* pProto = pItem->GetTemplate(); - if (!pProto) - continue; - - if (pProto->GetItemLimitCategory() == limitCategory) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return true; - } - } + tempcount += pItem->GetCount(); + if (tempcount >= count) + return ItemSearchCallbackResult::Stop; - return false; + return ItemSearchCallbackResult::Continue; + }); } bool Player::HasGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot) const { uint32 tempcount = 0; - for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) + return !ForEachItem(ItemSearchLocation::Equipment, [&tempcount, limitCategory, count, except_slot](Item* pItem) { - if (i == except_slot) - continue; - - Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (!pItem) - continue; + if (pItem->GetSlot() == except_slot) + return ItemSearchCallbackResult::Continue; ItemTemplate const* pProto = pItem->GetTemplate(); if (!pProto) - continue; + return ItemSearchCallbackResult::Continue; - if (pItem->GetSocketColor(0) || pItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT)) - { - tempcount += pItem->GetGemCountWithLimitCategory(limitCategory); - if (tempcount >= count) - return true; - } - } + tempcount += pItem->GetGemCountWithLimitCategory(limitCategory); + if (tempcount >= count) + return ItemSearchCallbackResult::Stop; - return false; + return ItemSearchCallbackResult::Continue; + }); } InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count /*= nullptr*/, uint32* offendingItemId /*= nullptr*/) const @@ -12232,6 +12007,8 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat } } } + + UpdateAverageItemLevelTotal(); } return item; @@ -12488,6 +12265,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) UpdateCriteria(CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); UpdateCriteria(CRITERIA_TYPE_EQUIP_EPIC_ITEM, slot, pItem->GetEntry()); + UpdateAverageItemLevelEquipped(); + return pItem; } @@ -12738,6 +12517,9 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update) pItem->SendUpdateToPlayer(this); AutoUnequipChildItem(pItem); + + if (bag == INVENTORY_SLOT_BAG_0) + UpdateAverageItemLevelEquipped(); } } @@ -12875,6 +12657,10 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) pItem->SetContainedIn(ObjectGuid::Empty); pItem->SetSlot(NULL_SLOT); pItem->SetState(ITEM_REMOVED, this); + + UpdateAverageItemLevelTotal(); + if (bag == INVENTORY_SLOT_BAG_0) + UpdateAverageItemLevelEquipped(); } } @@ -13186,100 +12972,36 @@ void Player::DestroyConjuredItems(bool update) DestroyItem(INVENTORY_SLOT_BAG_0, i, update); } -Item* Player::GetItemByEntry(uint32 entry, ItemSearchLocation where /*= ITEM_SEARCH_DEFAULT*/) const +Item* Player::GetItemByEntry(uint32 entry, ItemSearchLocation where /*= ItemSearchLocation::Default */) const { - if (where & ITEM_SEARCH_IN_EQUIPMENT) - { - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == entry) - return pItem; - - } - - if (where & ITEM_SEARCH_IN_INVENTORY) - { - // in inventory - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == entry) - return pItem; - - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) - if (Bag* pBag = GetBagByPos(i)) - for (uint32 j = 0; j < pBag->GetBagSize(); ++j) - if (Item* pItem = pBag->GetItemByPos(j)) - if (pItem->GetEntry() == entry) - return pItem; - - for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == entry) - return pItem; - } - - if (where & ITEM_SEARCH_IN_BANK) - { - for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == entry) - return pItem; - - for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i) - if (Bag* pBag = GetBagByPos(i)) - for (uint32 j = 0; j < pBag->GetBagSize(); ++j) - if (Item* pItem = pBag->GetItemByPos(j)) - if (pItem->GetEntry() == entry) - return pItem; - } - - if (where & ITEM_SEARCH_IN_REAGENT_BANK) + Item* result = nullptr; + ForEachItem(where, [&result, entry](Item* item) { - for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == entry) - return pItem; - } + if (item->GetEntry() == entry) + { + result = item; + return ItemSearchCallbackResult::Stop; + } - return nullptr; + return ItemSearchCallbackResult::Continue; + }); + return result; } std::vector<Item*> Player::GetItemListByEntry(uint32 entry, bool inBankAlso) const { - std::vector<Item*> itemList = std::vector<Item*>(); - - uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; ++i) - if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (item->GetEntry() == entry) - itemList.push_back(item); - - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) - if (Bag* bag = GetBagByPos(i)) - for (uint32 j = 0; j < bag->GetBagSize(); ++j) - if (Item* item = bag->GetItemByPos(j)) - if (item->GetEntry() == entry) - itemList.push_back(item); - - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; ++i) - if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (item->GetEntry() == entry) - itemList.push_back(item); - + ItemSearchLocation location = ItemSearchLocation::Equipment | ItemSearchLocation::Inventory | ItemSearchLocation::ReagentBank; if (inBankAlso) - { - for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i) - if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (item->GetEntry() == entry) - itemList.push_back(item); - } + location |= ItemSearchLocation::Bank; - for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) - if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (item->GetEntry() == entry) - itemList.push_back(item); + std::vector<Item*> itemList = std::vector<Item*>(); + ForEachItem(location, [&itemList, entry](Item* item) + { + if (item->GetEntry() == entry) + itemList.push_back(item); + return ItemSearchCallbackResult::Continue; + }); return itemList; } @@ -27855,7 +27577,7 @@ void Player::ActivateTalentGroup(ChrSpecializationEntry const* spec) activeGlyphs.IsFullUpdate = true; SendDirectMessage(activeGlyphs.Write()); - if (Item* item = GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE)) + if (Item* item = GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere)) { if (AzeriteItem* azeriteItem = item->ToAzeriteItem()) { @@ -28950,3 +28672,132 @@ uint8 Player::GetItemLimitCategoryQuantity(ItemLimitCategoryEntry const* limitEn return limit; } + +template <typename T> +static bool ForEachEquipmentSlot(InventoryType inventoryType, bool canDualWield, bool canTitanGrip, T callback) +{ + switch (inventoryType) + { + case INVTYPE_HEAD: callback(EQUIPMENT_SLOT_HEAD); return true; + case INVTYPE_NECK: callback(EQUIPMENT_SLOT_NECK); return true; + case INVTYPE_SHOULDERS: callback(EQUIPMENT_SLOT_SHOULDERS); return true; + case INVTYPE_BODY: callback(EQUIPMENT_SLOT_BODY); return true; + case INVTYPE_ROBE: + case INVTYPE_CHEST: callback(EQUIPMENT_SLOT_CHEST); return true; + case INVTYPE_WAIST: callback(EQUIPMENT_SLOT_WAIST); return true; + case INVTYPE_LEGS: callback(EQUIPMENT_SLOT_LEGS); return true; + case INVTYPE_FEET: callback(EQUIPMENT_SLOT_FEET); return true; + case INVTYPE_WRISTS: callback(EQUIPMENT_SLOT_WRISTS); return true; + case INVTYPE_HANDS: callback(EQUIPMENT_SLOT_HANDS); return true; + case INVTYPE_CLOAK: callback(EQUIPMENT_SLOT_BACK); return true; + case INVTYPE_FINGER: + callback(EQUIPMENT_SLOT_FINGER1); + callback(EQUIPMENT_SLOT_FINGER2, true); + return true; + case INVTYPE_TRINKET: + callback(EQUIPMENT_SLOT_TRINKET1); + callback(EQUIPMENT_SLOT_TRINKET2, true); + return true; + case INVTYPE_WEAPON: + callback(EQUIPMENT_SLOT_MAINHAND); + if (canDualWield) + callback(EQUIPMENT_SLOT_OFFHAND, true); + return true; + case INVTYPE_2HWEAPON: + callback(EQUIPMENT_SLOT_MAINHAND); + if (canDualWield && canTitanGrip) + callback(EQUIPMENT_SLOT_OFFHAND, true); + return true; + case INVTYPE_RANGED: + case INVTYPE_RANGEDRIGHT: + case INVTYPE_WEAPONMAINHAND: callback(EQUIPMENT_SLOT_MAINHAND); return true; + case INVTYPE_SHIELD: + case INVTYPE_HOLDABLE: + case INVTYPE_WEAPONOFFHAND: callback(EQUIPMENT_SLOT_OFFHAND); return true; + + case INVTYPE_NON_EQUIP: + case INVTYPE_BAG: + case INVTYPE_TABARD: + case INVTYPE_AMMO: + case INVTYPE_THROWN: + case INVTYPE_QUIVER: + case INVTYPE_RELIC: + default: + return false; + } +} + +void Player::UpdateAverageItemLevelTotal() +{ + std::array<std::tuple<InventoryType, uint32, ObjectGuid>, EQUIPMENT_SLOT_END> bestItemLevels = { }; + bestItemLevels.fill({ INVTYPE_NON_EQUIP, 0, ObjectGuid::Empty }); + float sum = 0; + + ForEachItem(ItemSearchLocation::Everywhere, [this, &bestItemLevels, &sum](Item* item) + { + ItemTemplate const* itemTemplate = item->GetTemplate(); + if (itemTemplate) + { + uint16 dest; + if (item->IsEquipped()) + { + uint32 itemLevel = item->GetItemLevel(this); + InventoryType inventoryType = itemTemplate->GetInventoryType(); + std::tuple<InventoryType, uint32, ObjectGuid>& slotData = bestItemLevels[item->GetSlot()]; + if (itemLevel > std::get<1>(slotData)) + { + sum += itemLevel - std::get<1>(slotData); + slotData = { inventoryType, itemLevel, item->GetGUID() }; + } + } + else if (CanEquipItem(NULL_SLOT, dest, item, true, false) == EQUIP_ERR_OK) + { + uint32 itemLevel = item->GetItemLevel(this); + InventoryType inventoryType = itemTemplate->GetInventoryType(); + ForEachEquipmentSlot(inventoryType, m_canDualWield, m_canTitanGrip, [&bestItemLevels, item, itemLevel, inventoryType, &sum](EquipmentSlots slot, bool checkDuplicateGuid = false) + { + if (checkDuplicateGuid) + { + for (std::tuple<InventoryType, uint32, ObjectGuid> const& slotData : bestItemLevels) + if (std::get<2>(slotData) == item->GetGUID()) + return; + } + + std::tuple<InventoryType, uint32, ObjectGuid>& slotData = bestItemLevels[slot]; + if (itemLevel > std::get<1>(slotData)) + { + sum += itemLevel - std::get<1>(slotData); + slotData = { inventoryType, itemLevel, item->GetGUID() }; + } + }); + } + } + return ItemSearchCallbackResult::Continue; + }); + + // If main hand is a 2h weapon, count it twice + std::tuple<InventoryType, uint32, ObjectGuid> const& mainHand = bestItemLevels[EQUIPMENT_SLOT_MAINHAND]; + if (!m_canTitanGrip && std::get<0>(mainHand) == INVTYPE_2HWEAPON) + sum += std::get<1>(mainHand); + + sum /= 16.0f; + SetAverageItemLevelTotal(sum); +} + +void Player::UpdateAverageItemLevelEquipped() +{ + float totalItemLevel = 0; + for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++) + { + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + { + uint32 itemLevel = pItem->GetItemLevel(this); + totalItemLevel += itemLevel; + if (!m_canTitanGrip && i == EQUIPMENT_SLOT_MAINHAND && pItem->GetTemplate()->GetInventoryType() == INVTYPE_2HWEAPON) // 2h weapon counts twice + totalItemLevel += itemLevel; + } + } + + totalItemLevel /= 16.0; + SetAverageItemLevelEquipped(totalItemLevel); +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index bf512a63fd0..36a9006cb0a 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -111,6 +111,9 @@ namespace WorldPackets } } +TC_GAME_API uint32 GetBagSize(Bag const* bag); +TC_GAME_API Item* GetItemInBag(Bag const* bag, uint8 slot); + typedef std::deque<Mail*> PlayerMails; #define PLAYER_MAX_SKILLS 256 @@ -675,15 +678,23 @@ struct ItemPosCount }; typedef std::vector<ItemPosCount> ItemPosCountVec; -enum ItemSearchLocation +enum class ItemSearchLocation { - ITEM_SEARCH_IN_EQUIPMENT = 0x01, - ITEM_SEARCH_IN_INVENTORY = 0x02, - ITEM_SEARCH_IN_BANK = 0x04, - ITEM_SEARCH_IN_REAGENT_BANK = 0x08, + Equipment = 0x01, + Inventory = 0x02, + Bank = 0x04, + ReagentBank = 0x08, + + Default = Equipment | Inventory, + Everywhere = Equipment | Inventory | Bank | ReagentBank +}; - ITEM_SEARCH_DEFAULT = ITEM_SEARCH_IN_EQUIPMENT | ITEM_SEARCH_IN_INVENTORY, - ITEM_SEARCH_EVERYWHERE = ITEM_SEARCH_IN_EQUIPMENT | ITEM_SEARCH_IN_INVENTORY | ITEM_SEARCH_IN_BANK | ITEM_SEARCH_IN_REAGENT_BANK +DEFINE_ENUM_FLAG(ItemSearchLocation); + +enum class ItemSearchCallbackResult +{ + Stop, + Continue }; enum TransferAbortReason @@ -1159,11 +1170,77 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> /*** STORAGE SYSTEM ***/ /*********************************************************/ + /** + * @brief Iterate over each item in the player storage + * @tparam T ItemSearchCallbackResult ItemCallback(Item* item) + * @param location Locations of the items to iterate over + * @param callback Callback called on each item. Will continue as long as it returns ItemSearchCallbackResult::Continue + */ + template <typename T> + bool ForEachItem(ItemSearchLocation location, T callback) const + { + EnumFlag<ItemSearchLocation> flag = location; + + if (flag.HasFlag(ItemSearchLocation::Equipment)) + for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (callback(pItem) == ItemSearchCallbackResult::Stop) + return false; + + if (flag.HasFlag(ItemSearchLocation::Inventory)) + { + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_BAG_START; i < inventoryEnd; ++i) + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (callback(pItem) == ItemSearchCallbackResult::Stop) + return false; + + for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (callback(pItem) == ItemSearchCallbackResult::Stop) + return false; + + for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) + if (Bag* pBag = GetBagByPos(i)) + for (uint32 j = 0; j < GetBagSize(pBag); ++j) + if (Item* pItem = GetItemInBag(pBag, j)) + if (callback(pItem) == ItemSearchCallbackResult::Stop) + return false; + } + + if (flag.HasFlag(ItemSearchLocation::Bank)) + { + for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i) + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (callback(pItem) == ItemSearchCallbackResult::Stop) + return false; + + for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i) + if (Bag* pBag = GetBagByPos(i)) + for (uint32 j = 0; j < GetBagSize(pBag); ++j) + if (Item* pItem = GetItemInBag(pBag, j)) + if (callback(pItem) == ItemSearchCallbackResult::Stop) + return false; + } + + if (flag.HasFlag(ItemSearchLocation::ReagentBank)) + for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i) + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (callback(pItem) == ItemSearchCallbackResult::Stop) + return false; + + return true; + } + + public: + void UpdateAverageItemLevelTotal(); + void UpdateAverageItemLevelEquipped(); + uint8 FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) const; uint32 GetItemCount(uint32 item, bool inBankAlso = false, Item* skipItem = nullptr) const; uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = nullptr) const; Item* GetItemByGuid(ObjectGuid guid) const; - Item* GetItemByEntry(uint32 entry, ItemSearchLocation where = ITEM_SEARCH_DEFAULT) const; + Item* GetItemByEntry(uint32 entry, ItemSearchLocation where = ItemSearchLocation::Default) const; std::vector<Item*> GetItemListByEntry(uint32 entry, bool inBankAlso = false) const; Item* GetItemByPos(uint16 pos) const; Item* GetItemByPos(uint8 bag, uint8 slot) const; @@ -2471,6 +2548,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void RemovePlayerFlagEx(PlayerFlagsEx flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::PlayerFlagsEx), flags); } void SetPlayerFlagsEx(PlayerFlagsEx flags) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::PlayerFlagsEx), flags); } + void SetAverageItemLevelTotal(float newItemLevel) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::AvgItemLevel, 0), newItemLevel); } + void SetAverageItemLevelEquipped(float newItemLevel) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::AvgItemLevel, 1), newItemLevel); } + uint32 GetCustomizationChoice(uint32 chrCustomizationOptionId) const { int32 choiceIndex = m_playerData->Customizations.FindIndexIf([chrCustomizationOptionId](UF::ChrCustomizationChoice choice) diff --git a/src/server/game/Handlers/AzeriteHandler.cpp b/src/server/game/Handlers/AzeriteHandler.cpp index f93dbca04b4..3fa3a32fe83 100644 --- a/src/server/game/Handlers/AzeriteHandler.cpp +++ b/src/server/game/Handlers/AzeriteHandler.cpp @@ -28,7 +28,7 @@ void WorldSession::HandleAzeriteEssenceUnlockMilestone(WorldPackets::Azerite::Az if (!AzeriteItem::FindHeartForge(_player)) return; - Item* item = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE); + Item* item = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere); if (!item) return; @@ -59,7 +59,7 @@ void WorldSession::HandleAzeriteEssenceActivateEssence(WorldPackets::Azerite::Az { WorldPackets::Azerite::ActivateEssenceFailed activateEssenceResult; activateEssenceResult.AzeriteEssenceID = azeriteEssenceActivateEssence.AzeriteEssenceID; - Item* item = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_IN_EQUIPMENT); + Item* item = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Equipment); if (!item) { activateEssenceResult.Reason = AzeriteEssenceActivateResult::NotEquipped; @@ -200,7 +200,7 @@ void WorldSession::HandleAzeriteEmpoweredItemSelectPower(WorldPackets::Azerite:: return; uint32 azeriteLevel = 0; - Item const* heartOfAzeroth = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE); + Item const* heartOfAzeroth = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere); if (!heartOfAzeroth) return; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index caae1003ccd..5f51fafca25 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1364,6 +1364,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); + pCurrChar->UpdateAverageItemLevelTotal(); + pCurrChar->UpdateAverageItemLevelEquipped(); + m_playerLoading.Clear(); // Handle Login-Achievements (should be handled after loading) diff --git a/src/server/game/Handlers/InspectHandler.cpp b/src/server/game/Handlers/InspectHandler.cpp index c999d26e11a..90f4681bf22 100644 --- a/src/server/game/Handlers/InspectHandler.cpp +++ b/src/server/game/Handlers/InspectHandler.cpp @@ -65,7 +65,7 @@ void WorldSession::HandleInspectOpcode(WorldPackets::Inspect::Inspect& inspect) inspectResult.GuildData->AchievementPoints = guild->GetAchievementMgr().GetAchievementPoints(); } - if (Item const* heartOfAzeroth = player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE)) + if (Item const* heartOfAzeroth = player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere)) if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) inspectResult.AzeriteLevel = azeriteItem->GetEffectiveLevel(); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index d7cfda76147..06ee5111fd6 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5824,7 +5824,7 @@ void Spell::EffectLearnAzeriteEssencePower(SpellEffIndex /*effIndex*/) if (!playerTarget) return; - Item* heartOfAzeroth = playerTarget->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE); + Item* heartOfAzeroth = playerTarget->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere); if (!heartOfAzeroth) return; |