Core/Items: Reworked loading child equipment from database, these items are now loaded last
Closes #18025
This commit is contained in:
@@ -113,7 +113,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT, "DELETE FROM character_queststatus_seasonal WHERE event = ?", CONNECTION_ASYNC);
|
||||
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_REPUTATION, "SELECT faction, standing, flags FROM character_reputation WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_INVENTORY, "SELECT " SelectItemInstanceContent ", bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid LEFT JOIN item_instance_transmog iit ON ii.guid = iit.itemGuid LEFT JOIN item_instance_modifiers im ON ii.guid = im.itemGuid WHERE ci.guid = ? ORDER BY bag, slot", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_INVENTORY, "SELECT " SelectItemInstanceContent ", bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid LEFT JOIN item_instance_transmog iit ON ii.guid = iit.itemGuid LEFT JOIN item_instance_modifiers im ON ii.guid = im.itemGuid WHERE ci.guid = ? ORDER BY (ii.flags & 0x80000) ASC, bag ASC, slot ASC", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS, "SELECT a.button, a.action, a.type FROM character_action as a, characters as c WHERE a.guid = c.guid AND a.spec = c.activeTalentGroup AND a.guid = ? ORDER BY button", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_MAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = ? AND (checked & 1) = 0 AND deliver_time <= ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_MAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = ? AND (checked & 1) = 0", CONNECTION_ASYNC);
|
||||
|
||||
@@ -17958,7 +17958,8 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
|
||||
// 24 25 26 27 28
|
||||
// spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4,
|
||||
// 29 30 31 32 33 34 35 36 37 40 41
|
||||
// gemItemId1, gemBonuses1, gemContext1, gemItemId2, gemBonuses2, gemContext2, gemItemId3, gemBonuses3, gemContext3, bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot
|
||||
// gemItemId1, gemBonuses1, gemContext1, gemItemId2, gemBonuses2, gemContext2, gemItemId3, gemBonuses3, gemContext3, bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY (ii.flags & 0x80000) ASC, bag ASC, slot ASC
|
||||
//NOTE: ORDER BY ii.flags & 0x80000 makes child items load last - they need their parents to be already loaded
|
||||
//NOTE: the "order by `bag`" is important because it makes sure
|
||||
//the bagMap is filled before items in the bags are loaded
|
||||
//NOTE2: the "order by `slot`" is needed because mainhand weapons are (wrongly?)
|
||||
@@ -17997,7 +17998,6 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
|
||||
|
||||
std::map<ObjectGuid, Bag*> bagMap; // fast guid lookup for bags
|
||||
std::map<ObjectGuid, Item*> invalidBagMap; // fast guid lookup for bags
|
||||
std::vector<Item*> childItems;
|
||||
std::list<Item*> problematicItems;
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
@@ -18019,6 +18019,17 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
|
||||
GetSession()->GetCollectionMgr()->AddItemAppearance(item);
|
||||
|
||||
InventoryResult err = EQUIP_ERR_OK;
|
||||
if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_CHILD))
|
||||
{
|
||||
if (Item* parent = GetItemByGuid(item->GetGuidValue(ITEM_FIELD_CREATOR)))
|
||||
{
|
||||
parent->SetChildItem(item->GetGUID());
|
||||
item->CopyArtifactDataFromParent(parent);
|
||||
}
|
||||
else
|
||||
err = EQUIP_ERR_WRONG_BAG_TYPE_3; // send by mail
|
||||
}
|
||||
|
||||
// Item is not in bag
|
||||
if (!bagGuid)
|
||||
{
|
||||
@@ -18085,16 +18096,11 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
|
||||
delete item;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Item's state may have changed after storing
|
||||
if (err == EQUIP_ERR_OK)
|
||||
{
|
||||
item->SetState(ITEM_UNCHANGED, this);
|
||||
if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_CHILD))
|
||||
childItems.push_back(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Player::_LoadInventory: Player '%s' (%s) has item (%s, entry: %u) which can't be loaded into inventory (Bag %s, slot: %u) by reason %u. Item will be sent by mail.",
|
||||
@@ -18121,19 +18127,6 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
|
||||
draft.SendMailTo(trans, this, MailSender(this, MAIL_STATIONERY_GM), MAIL_CHECK_MASK_COPIED);
|
||||
}
|
||||
|
||||
for (Item* childItem : childItems)
|
||||
{
|
||||
if (Item* parent = GetItemByGuid(childItem->GetGuidValue(ITEM_FIELD_CREATOR)))
|
||||
{
|
||||
parent->SetChildItem(childItem->GetGUID());
|
||||
childItem->CopyArtifactDataFromParent(parent);
|
||||
if (childItem->IsEquipped())
|
||||
SetVisibleItemSlot(childItem->GetSlot(), childItem);
|
||||
}
|
||||
else
|
||||
childItem->SetState(ITEM_REMOVED, this);
|
||||
}
|
||||
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
//if (IsAlive())
|
||||
|
||||
Reference in New Issue
Block a user