aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp351
-rw-r--r--src/server/game/Entities/Player/Player.h52
-rw-r--r--src/server/game/Handlers/BankHandler.cpp18
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)