Core/Player: Fix Inventory

This commit is contained in:
funjoker
2023-11-16 23:22:55 +01:00
parent bbc5539928
commit f54b0aad52
3 changed files with 365 additions and 56 deletions

View File

@@ -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))
{

View File

@@ -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; }

View File

@@ -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)