|
|
|
@@ -10039,6 +10039,9 @@ uint8 Player::_CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemPosCountVe
|
|
|
|
|
|
|
|
|
|
uint32 need_space;
|
|
|
|
|
|
|
|
|
|
if (pSrcItem && pSrcItem->IsBag() && !((Bag*)pSrcItem)->IsEmpty() && !IsBagPos(uint16(bag) << 8 | slot))
|
|
|
|
|
return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
|
|
|
|
|
|
|
|
|
|
// empty specific slot - check item fit to slot
|
|
|
|
|
if (!pItem2 || swap)
|
|
|
|
|
{
|
|
|
|
@@ -10111,6 +10114,9 @@ uint8 Player::_CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, ItemPrototyp
|
|
|
|
|
if (!pBag || pBag == pSrcItem)
|
|
|
|
|
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
|
|
|
|
|
|
|
|
|
|
if (pSrcItem && pSrcItem->IsBag() && !((Bag*)pSrcItem)->IsEmpty())
|
|
|
|
|
return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
|
|
|
|
|
|
|
|
|
|
ItemPrototype const* pBagProto = pBag->GetProto();
|
|
|
|
|
if (!pBagProto)
|
|
|
|
|
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
|
|
|
|
@@ -10169,6 +10175,10 @@ uint8 Player::_CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, ItemPrototyp
|
|
|
|
|
|
|
|
|
|
uint8 Player::_CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 slot_end, ItemPosCountVec &dest, ItemPrototype const *pProto, uint32& count, bool merge, Item* pSrcItem, uint8 skip_bag, uint8 skip_slot) const
|
|
|
|
|
{
|
|
|
|
|
//this is never called for non-bag slots so we can do this
|
|
|
|
|
if (pSrcItem && pSrcItem->IsBag() && !((Bag*)pSrcItem)->IsEmpty())
|
|
|
|
|
return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
|
|
|
|
|
|
|
|
|
|
for (uint32 j = slot_begin; j < slot_end; j++)
|
|
|
|
|
{
|
|
|
|
|
// skip specific slot already processed in first called _CanStoreItem_InSpecificSlot
|
|
|
|
@@ -18056,52 +18066,52 @@ void Player::_SaveInventory(SQLTransaction& trans)
|
|
|
|
|
if (m_itemUpdateQueue.empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// do not save if the update queue is corrupt
|
|
|
|
|
bool error = false;
|
|
|
|
|
uint32 lowGuid = GetGUIDLow();
|
|
|
|
|
for (size_t i = 0; i < m_itemUpdateQueue.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
Item *item = m_itemUpdateQueue[i];
|
|
|
|
|
if (!item || item->GetState() == ITEM_REMOVED)
|
|
|
|
|
if (!item)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Item *test = GetItemByPos(item->GetBagSlot(), item->GetSlot());
|
|
|
|
|
|
|
|
|
|
if (test == NULL)
|
|
|
|
|
{
|
|
|
|
|
sLog.outCrash("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%d) and slot(%d) values for the item with guid %d (state %d) are incorrect, the player doesn't have an item at that position!", GetGUIDLow(), GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), (int32)item->GetState());
|
|
|
|
|
//error = true;
|
|
|
|
|
//Should the above line really be commented out?
|
|
|
|
|
}
|
|
|
|
|
else if (test != item)
|
|
|
|
|
{
|
|
|
|
|
sLog.outError("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the item with guid %d is there instead!", GetGUIDLow(), GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
|
|
|
|
|
error = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (error)
|
|
|
|
|
{
|
|
|
|
|
sLog.outError("Player::_SaveInventory - one or more errors occurred save aborted!");
|
|
|
|
|
ChatHandler(this).SendSysMessage(LANG_ITEM_SAVE_FAILED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < m_itemUpdateQueue.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
Item *item = m_itemUpdateQueue[i];
|
|
|
|
|
if (!item) continue;
|
|
|
|
|
|
|
|
|
|
Bag *container = item->GetContainer();
|
|
|
|
|
uint32 bag_guid = container ? container->GetGUIDLow() : 0;
|
|
|
|
|
|
|
|
|
|
if (item->GetState() != ITEM_REMOVED)
|
|
|
|
|
{
|
|
|
|
|
Item *test = GetItemByPos(item->GetBagSlot(), item->GetSlot());
|
|
|
|
|
if (test == NULL)
|
|
|
|
|
{
|
|
|
|
|
uint32 bagTestGUID = 0;
|
|
|
|
|
if (Item* test2 = GetItemByPos(INVENTORY_SLOT_BAG_0, item->GetBagSlot()))
|
|
|
|
|
bagTestGUID = test2->GetGUIDLow();
|
|
|
|
|
sLog.outError("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u (state %d) are incorrect, the player doesn't have an item at that position!", lowGuid, GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), (int32)item->GetState());
|
|
|
|
|
// according to the test that was just performed nothing should be in this slot, delete
|
|
|
|
|
trans->PAppend("DELETE FROM character_inventory WHERE bag=%u AND slot=%u", bagTestGUID, item->GetSlot());
|
|
|
|
|
// also THIS item should be somewhere else, cheat attempt
|
|
|
|
|
item->FSetState(ITEM_REMOVED); // we are IN updateQueue right now, can't use SetState which modifies the queue
|
|
|
|
|
DeleteRefundReference(item->GetGUIDLow());
|
|
|
|
|
// don't skip, let the switch delete it
|
|
|
|
|
//continue;
|
|
|
|
|
}
|
|
|
|
|
else if (test != item)
|
|
|
|
|
{
|
|
|
|
|
sLog.outError("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u are incorrect, the item with guid %u is there instead!", lowGuid, GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
|
|
|
|
|
// save all changes to the item...
|
|
|
|
|
if (item->GetState() != ITEM_NEW) // only for existing items, no dupes
|
|
|
|
|
item->SaveToDB(trans);
|
|
|
|
|
// ...but do not save position in invntory
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (item->GetState())
|
|
|
|
|
{
|
|
|
|
|
case ITEM_NEW:
|
|
|
|
|
trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
|
|
|
|
|
trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", lowGuid, bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
|
|
|
|
|
break;
|
|
|
|
|
case ITEM_CHANGED:
|
|
|
|
|
trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
|
|
|
|
|
trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
|
|
|
|
|
trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", lowGuid, bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
|
|
|
|
|
break;
|
|
|
|
|
case ITEM_REMOVED:
|
|
|
|
|
trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
|
|
|
|
|