mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 01:37:37 +01:00
Core/Player: Fix Inventory
This commit is contained in:
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user