diff options
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 351 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 52 | ||||
| -rw-r--r-- | src/server/game/Handlers/BankHandler.cpp | 18 |
3 files changed, 365 insertions, 56 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 69ccd616544..e48c95d89ad 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3665,7 +3665,7 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c { if (target == this) { - for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + for (uint8 i = EQUIPMENT_SLOT_START; i < BANK_SLOT_BAG_END; ++i) { if (m_items[i] == nullptr) continue; @@ -3673,15 +3673,7 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c m_items[i]->BuildCreateUpdateBlockForPlayer(data, target); } - for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i) - { - if (m_items[i] == nullptr) - continue; - - m_items[i]->BuildCreateUpdateBlockForPlayer(data, target); - } - - for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) + for (uint8 i = KEYRING_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) { if (m_items[i] == nullptr) continue; @@ -3822,7 +3814,7 @@ void Player::DestroyForPlayer(Player* target) const if (target == this) { - for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + for (uint8 i = EQUIPMENT_SLOT_START; i < BANK_SLOT_BAG_END; ++i) { if (m_items[i] == nullptr) continue; @@ -3830,15 +3822,7 @@ void Player::DestroyForPlayer(Player* target) const m_items[i]->DestroyForPlayer(target); } - for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i) - { - if (m_items[i] == nullptr) - continue; - - m_items[i]->DestroyForPlayer(target); - } - - for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) + for (uint8 i = KEYRING_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) { if (m_items[i] == nullptr) continue; @@ -9075,6 +9059,15 @@ uint32 Player::GetFreeInventorySlotCount(EnumFlag<ItemSearchLocation> location / ++freeSlotCount; } + if (location.HasFlag(ItemSearchLocation::ReagentBank)) + { + for (uint8 i = REAGENT_BAG_SLOT_START; i < REAGENT_BAG_SLOT_END; ++i) + if (Bag* bag = GetBagByPos(i)) + for (uint32 j = 0; j < GetBagSize(bag); ++j) + if (!GetItemInBag(bag, j)) + ++freeSlotCount; + } + return freeSlotCount; } @@ -9109,7 +9102,7 @@ uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const { bool countGems = skipItem && skipItem->GetTemplate()->GetGemProperties(); - ItemSearchLocation location = ItemSearchLocation::Equipment | ItemSearchLocation::Inventory | ItemSearchLocation::KeyRing; + ItemSearchLocation location = ItemSearchLocation::Equipment | ItemSearchLocation::Inventory | ItemSearchLocation::ReagentBank; if (inBankAlso) location |= ItemSearchLocation::Bank; @@ -9208,7 +9201,8 @@ Item* Player::GetUseableItemByPos(uint8 bag, uint8 slot) const Bag* Player::GetBagByPos(uint8 bag) const { if ((bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END) - || (bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END)) + || (bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END) + || (bag >= REAGENT_BAG_SLOT_START && bag < REAGENT_BAG_SLOT_END)) if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, bag)) return item->ToBag(); return nullptr; @@ -9321,6 +9315,10 @@ bool Player::IsInventoryPos(uint8 bag, uint8 slot) return true; if (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END) return true; + if (bag == INVENTORY_SLOT_BAG_0 && (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END)) + return true; + if (bag == INVENTORY_SLOT_BAG_0 && (slot >= CHILD_EQUIPMENT_SLOT_START && slot < CHILD_EQUIPMENT_SLOT_END)) + return true; return false; } @@ -9332,6 +9330,8 @@ bool Player::IsEquipmentPos(uint8 bag, uint8 slot) return true; if (bag == INVENTORY_SLOT_BAG_0 && (slot >= INVENTORY_SLOT_BAG_START && slot < INVENTORY_SLOT_BAG_END)) return true; + if (bag == INVENTORY_SLOT_BAG_0 && (slot >= REAGENT_BAG_SLOT_START && slot < REAGENT_BAG_SLOT_END)) + return true; return false; } @@ -9354,9 +9354,16 @@ bool Player::IsBagPos(uint16 pos) return true; if (bag == INVENTORY_SLOT_BAG_0 && (slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END)) return true; + if (bag == INVENTORY_SLOT_BAG_0 && (slot >= REAGENT_BAG_SLOT_START && slot < REAGENT_BAG_SLOT_END)) + return true; return false; } +bool Player::IsChildEquipmentPos(uint8 bag, uint8 slot) +{ + return bag == INVENTORY_SLOT_BAG_0 && (slot >= CHILD_EQUIPMENT_SLOT_START && slot < CHILD_EQUIPMENT_SLOT_END); +} + bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const { // post selected @@ -9381,6 +9388,10 @@ bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const if (slot >= INVENTORY_SLOT_BAG_START && slot < INVENTORY_SLOT_BAG_END) return true; + // reagent bag equip slots + if (slot >= REAGENT_BAG_SLOT_START && slot < REAGENT_BAG_SLOT_END) + return true; + // backpack slots if (slot >= INVENTORY_SLOT_ITEM_START && slot < INVENTORY_SLOT_ITEM_START + GetInventorySlotCount()) return true; @@ -9393,6 +9404,10 @@ bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const if (slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END) return true; + // keyring slots + if (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END) + return true; + return false; } @@ -9455,7 +9470,7 @@ void Player::SetInventorySlotCount(uint8 slots) bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const { - ItemSearchLocation location = ItemSearchLocation::Equipment | ItemSearchLocation::Inventory | ItemSearchLocation::KeyRing; + ItemSearchLocation location = ItemSearchLocation::Equipment | ItemSearchLocation::Inventory | ItemSearchLocation::ReagentBank; if (inBankAlso) location |= ItemSearchLocation::Bank; @@ -9625,6 +9640,13 @@ bool Player::HasItemTotemCategory(uint32 TotemCategory) const return true; } + for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) + { + item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i); + if (item && DB2Manager::IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory)) + return true; + } + Bag* bag; for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { @@ -9640,7 +9662,7 @@ bool Player::HasItemTotemCategory(uint32 TotemCategory) const } } - for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) + for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i) { item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i); if (item && DB2Manager::IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory)) @@ -9664,6 +9686,12 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP { if (pSrcItem->IsNotEmptyBag() && !IsBagPos(uint16(bag) << 8 | slot)) return EQUIP_ERR_DESTROY_NONEMPTY_BAG; + + if (pSrcItem->HasItemFlag(ITEM_FIELD_FLAG_CHILD) && !IsEquipmentPos(bag, slot) && !IsChildEquipmentPos(bag, slot)) + return EQUIP_ERR_WRONG_BAG_TYPE_3; + + if (!pSrcItem->HasItemFlag(ITEM_FIELD_FLAG_CHILD) && IsChildEquipmentPos(bag, slot)) + return EQUIP_ERR_WRONG_BAG_TYPE_3; } // empty specific slot - check item fit to slot @@ -9672,7 +9700,7 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP if (bag == INVENTORY_SLOT_BAG_0) { // keyring case - if (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END && !(pProto->GetBagFamily() & BAG_FAMILY_MASK_KEYS)) + if (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START + KEYRING_SLOT_START - KEYRING_SLOT_END && !(pProto->GetBagFamily() & BAG_FAMILY_MASK_KEYS)) return EQUIP_ERR_WRONG_BAG_TYPE; // prevent cheating @@ -9925,6 +9953,24 @@ 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) { @@ -9972,6 +10018,49 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des // search free slot in bag for place to if (bag == INVENTORY_SLOT_BAG_0) // inventory { + if (pProto->GetBagFamily() & BAG_FAMILY_MASK_KEYS) + { + uint32 keyringSize = KEYRING_SLOT_END - KEYRING_SLOT_START; + res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, KEYRING_SLOT_START + keyringSize, 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 (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) { @@ -10020,6 +10109,24 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des // search stack for merge to 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) { @@ -10079,6 +10186,28 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des // search free slot - special bag case if (pProto->GetBagFamily()) { + if (pProto->GetBagFamily() & BAG_FAMILY_MASK_KEYS) + { + uint32 keyringSize = KEYRING_SLOT_END - KEYRING_SLOT_START; + res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, KEYRING_SLOT_START + keyringSize, 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; + } + } + 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); @@ -10100,6 +10229,27 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des if (pItem && pItem->IsNotEmptyBag()) return EQUIP_ERR_BAG_IN_BAG; + 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; + } + } + // search free slot uint8 searchSlotStart = INVENTORY_SLOT_ITEM_START; // new bags can be directly equipped @@ -10158,10 +10308,12 @@ 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 keyringCounts[KEYRING_SLOT_END - KEYRING_SLOT_START] = {}; // 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* keyringPointers[KEYRING_SLOT_END - KEYRING_SLOT_START] = {}; uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); @@ -10177,6 +10329,17 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending } } + for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + // build items in key ring 'bag' + item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); + if (item2 && !item2->IsInTrade()) + { + keyringCounts[i - KEYRING_SLOT_START] = item2->GetCount(); + keyringPointers[i - KEYRING_SLOT_START] = item2; + } + } + 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++) @@ -10230,6 +10393,25 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending { bool b_found = false; + for (uint8 t = KEYRING_SLOT_START; t < KEYRING_SLOT_END; ++t) + { + item2 = keyringPointers[t - KEYRING_SLOT_START]; + if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && keyringCounts[t - KEYRING_SLOT_START] < pProto->GetMaxStackSize()) + { + keyringCounts[t - KEYRING_SLOT_START] += remaining_count; + remaining_count = keyringCounts[t - KEYRING_SLOT_START] < pProto->GetMaxStackSize() ? 0 : keyringCounts[t - KEYRING_SLOT_START] - pProto->GetMaxStackSize(); + + b_found = remaining_count == 0; + + // if no pieces of the stack remain, then stop checking keyring + if (b_found) + break; + } + } + + if (b_found) + continue; + for (int t = INVENTORY_SLOT_ITEM_START; t < inventoryEnd; ++t) { item2 = inventoryPointers[t-INVENTORY_SLOT_ITEM_START]; @@ -10283,6 +10465,25 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending { bool b_found = false; + if (pProto->GetBagFamily() & BAG_FAMILY_MASK_KEYS) + { + uint32 keyringSize = KEYRING_SLOT_END - KEYRING_SLOT_START; + for (uint32 t = KEYRING_SLOT_START; t < KEYRING_SLOT_START + keyringSize; ++t) + { + if (keyringCounts[t - KEYRING_SLOT_START] == 0) + { + keyringCounts[t - KEYRING_SLOT_START] = remaining_count; + keyringPointers[t - KEYRING_SLOT_START] = item; + + b_found = true; + break; + } + } + } + + if (b_found) + continue; + for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t) { if (Bag* bag = GetBagByPos(t)) @@ -10840,7 +11041,7 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec& dest return EQUIP_ERR_OK; } - return EQUIP_ERR_BANK_FULL; + return EQUIP_ERR_BANK_FULL; } InventoryResult Player::CanUseItem(Item* pItem, bool not_loading) const @@ -11046,6 +11247,21 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat if (addToCollection) GetSession()->GetCollectionMgr()->OnItemAdded(item); + if (ItemChildEquipmentEntry const* childItemEntry = sDB2Manager.GetItemChildEquipment(itemId)) + { + if (ItemTemplate const* childTemplate = sObjectMgr->GetItemTemplate(childItemEntry->ChildItemID)) + { + ItemPosCountVec childDest; + CanStoreItem_InInventorySlots(CHILD_EQUIPMENT_SLOT_START, CHILD_EQUIPMENT_SLOT_END, childDest, childTemplate, count, false, nullptr, NULL_BAG, NULL_SLOT); + if (Item* childItem = StoreNewItem(childDest, childTemplate->GetId(), update, {}, {}, context, {}, addToCollection)) + { + childItem->SetCreator(item->GetGUID()); + childItem->SetItemFlag(ITEM_FIELD_FLAG_CHILD); + item->SetChildItem(childItem->GetGUID()); + } + } + } + if (item->GetTemplate()->GetInventoryType() != INVTYPE_NON_EQUIP) UpdateAverageItemLevelTotal(); } @@ -11391,6 +11607,23 @@ void Player::EquipChildItem(uint8 parentBag, uint8 parentSlot, Item* parentItem) void Player::AutoUnequipChildItem(Item* parentItem) { + if (sDB2Manager.GetItemChildEquipment(parentItem->GetEntry())) + { + if (Item* childItem = GetChildItemByGuid(parentItem->GetChildItem())) + { + if (IsChildEquipmentPos(childItem->GetPos())) + return; + + ItemPosCountVec dest; + uint32 count = childItem->GetCount(); + InventoryResult result = CanStoreItem_InInventorySlots(CHILD_EQUIPMENT_SLOT_START, CHILD_EQUIPMENT_SLOT_END, dest, childItem->GetTemplate(), count, false, childItem, NULL_BAG, NULL_SLOT); + if (result != EQUIP_ERR_OK) + return; + + RemoveItem(childItem->GetBagSlot(), childItem->GetSlot(), true); + StoreItem(dest, childItem, true); + } + } } void Player::QuickEquipItem(uint16 pos, Item* pItem) @@ -11739,6 +11972,34 @@ uint32 Player::DestroyItemCount(uint32 itemEntry, uint32 count, bool update, boo } } + for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) + { + if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + { + if (item->GetEntry() == itemEntry && !item->IsInTrade()) + { + if (item->GetCount() + remcount <= count) + { + // all keys can be unequipped + remcount += item->GetCount(); + DestroyItem(INVENTORY_SLOT_BAG_0, i, update); + + if (remcount >= count) + return remcount; + } + else + { + item->SetCount(item->GetCount() - count + remcount); + ItemRemovedQuestCheck(item->GetEntry(), count - remcount); + if (IsInWorld() && update) + item->SendUpdateToPlayer(this); + item->SetState(ITEM_CHANGED, this); + return count; + } + } + } + } + // in inventory bags for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { @@ -11897,6 +12158,33 @@ uint32 Player::DestroyItemCount(uint32 itemEntry, uint32 count, bool update, boo } } + 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() == itemEntry && !item->IsInTrade()) + { + if (item->GetCount() + remcount <= count) + { + // all keys can be unequipped + remcount += item->GetCount(); + DestroyItem(INVENTORY_SLOT_BAG_0, i, update); + + if (remcount >= count) + return remcount; + } + else + { + item->SetCount(item->GetCount() - count + remcount); + ItemRemovedQuestCheck(item->GetEntry(), count - remcount); + if (IsInWorld() && update) + item->SendUpdateToPlayer(this); + item->SetState(ITEM_CHANGED, this); + return count; + } + } + } + } return remcount; } @@ -11912,6 +12200,11 @@ void Player::DestroyZoneLimitedItem(bool update, uint32 new_zone) if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(), new_zone)) DestroyItem(INVENTORY_SLOT_BAG_0, i, update); + for (uint8 i = KEYRING_SLOT_START; i < KEYRING_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); + // in inventory bags for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* pBag = GetBagByPos(i)) @@ -11974,7 +12267,7 @@ Item* Player::GetItemByEntry(uint32 entry, ItemSearchLocation where /*= ItemSear std::vector<Item*> Player::GetItemListByEntry(uint32 entry, bool inBankAlso) const { - ItemSearchLocation location = ItemSearchLocation::Equipment | ItemSearchLocation::Inventory | ItemSearchLocation::KeyRing; + ItemSearchLocation location = ItemSearchLocation::Equipment | ItemSearchLocation::Inventory | ItemSearchLocation::ReagentBank; if (inBankAlso) location |= ItemSearchLocation::Bank; @@ -19163,7 +19456,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba ss.str(""); // cache equipment... - for (uint32 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint32 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { @@ -19300,7 +19593,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba ss.str(""); // cache equipment... - for (uint32 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + for (uint32 i = 0; i < REAGENT_BAG_SLOT_END; ++i) { if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 640e45b1483..f162a2c7de3 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -669,41 +669,47 @@ enum InventorySlots : uint8 // 4 slots INVENTORY_SLOT_BAG_END = 34 }; +enum ReagentBagSlots : uint8 // 1 slot +{ + REAGENT_BAG_SLOT_START = 34, + REAGENT_BAG_SLOT_END = 35 +}; + enum InventoryPackSlots : uint8 // 24 slots { - INVENTORY_SLOT_ITEM_START = 34, - INVENTORY_SLOT_ITEM_END = 58 + INVENTORY_SLOT_ITEM_START = 35, + INVENTORY_SLOT_ITEM_END = 59 }; enum BankItemSlots // 28 slots { - BANK_SLOT_ITEM_START = 58, - BANK_SLOT_ITEM_END = 86 + BANK_SLOT_ITEM_START = 59, + BANK_SLOT_ITEM_END = 87 }; enum BankBagSlots // 7 slots { - BANK_SLOT_BAG_START = 86, - BANK_SLOT_BAG_END = 93 + BANK_SLOT_BAG_START = 87, + BANK_SLOT_BAG_END = 94 }; enum BuyBackSlots // 12 slots { // stored in m_buybackitems - BUYBACK_SLOT_START = 93, - BUYBACK_SLOT_END = 105 + BUYBACK_SLOT_START = 94, + BUYBACK_SLOT_END = 106 }; -enum KeyRingSlots : uint8 // 32 slots +enum KeyRingSlots // 32 slots { - KEYRING_SLOT_START = 105, - KEYRING_SLOT_END = 137 + KEYRING_SLOT_START = 106, + KEYRING_SLOT_END = 138, }; enum ChildEquipmentSlots { - CHILD_EQUIPMENT_SLOT_START = 137, - CHILD_EQUIPMENT_SLOT_END = 141, + CHILD_EQUIPMENT_SLOT_START = 138, + CHILD_EQUIPMENT_SLOT_END = 141, }; // slots past 214 are guessed (unused in client) @@ -741,10 +747,10 @@ enum class ItemSearchLocation Equipment = 0x01, Inventory = 0x02, Bank = 0x04, - KeyRing = 0x08, + ReagentBank = 0x08, Default = Equipment | Inventory, - Everywhere = Equipment | Inventory | Bank | KeyRing + Everywhere = Equipment | Inventory | Bank | ReagentBank }; DEFINE_ENUM_FLAG(ItemSearchLocation); @@ -1279,6 +1285,16 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> if (callback(pItem) == ItemSearchCallbackResult::Stop) return false; + for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++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) @@ -1302,9 +1318,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> return false; } - if (flag.HasFlag(ItemSearchLocation::KeyRing)) + if (flag.HasFlag(ItemSearchLocation::ReagentBank)) { - for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) + for (uint8 i = REAGENT_BAG_SLOT_START; i < REAGENT_BAG_SLOT_END; ++i) if (Bag* bag = GetBagByPos(i)) for (uint32 j = 0; j < GetBagSize(bag); ++j) if (Item* pItem = GetItemInBag(bag, j)) @@ -1344,6 +1360,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> static bool IsBagPos(uint16 pos); static bool IsBankPos(uint16 pos) { return IsBankPos(pos >> 8, pos & 255); } static bool IsBankPos(uint8 bag, uint8 slot); + static bool IsChildEquipmentPos(uint16 pos) { return IsChildEquipmentPos(pos >> 8, pos & 255); } + static bool IsChildEquipmentPos(uint8 bag, uint8 slot); bool IsValidPos(uint16 pos, bool explicit_pos) const { return IsValidPos(pos >> 8, pos & 255, explicit_pos); } bool IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const; uint8 GetInventorySlotCount() const { return m_activePlayerData->NumBackpackSlots; } diff --git a/src/server/game/Handlers/BankHandler.cpp b/src/server/game/Handlers/BankHandler.cpp index b403c4bbfc1..065c8b0c72a 100644 --- a/src/server/game/Handlers/BankHandler.cpp +++ b/src/server/game/Handlers/BankHandler.cpp @@ -269,18 +269,16 @@ void WorldSession::HandleAutoStoreBankReagentOpcode(WorldPackets::Bank::AutoStor if (!pItem) return; + ItemPosCountVec dest; + InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, pItem, false, true); + if (msg != EQUIP_ERR_OK) { - ItemPosCountVec dest; - InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, pItem, false, true); - if (msg != EQUIP_ERR_OK) - { - _player->SendEquipError(msg, pItem, nullptr); - return; - } - - _player->RemoveItem(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot, true); - _player->BankItem(dest, pItem, true); + _player->SendEquipError(msg, pItem, nullptr); + return; } + + _player->RemoveItem(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot, true); + _player->BankItem(dest, pItem, true); } void WorldSession::SendShowBank(ObjectGuid guid) |
