mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Items: Refactor loading additional item data (artifacts/azerite)
This commit is contained in:
@@ -28,7 +28,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
"iit.itemModifiedAppearanceAllSpecs, iit.itemModifiedAppearanceSpec1, iit.itemModifiedAppearanceSpec2, iit.itemModifiedAppearanceSpec3, iit.itemModifiedAppearanceSpec4, " \
|
||||
"iit.spellItemEnchantmentAllSpecs, iit.spellItemEnchantmentSpec1, iit.spellItemEnchantmentSpec2, iit.spellItemEnchantmentSpec3, iit.spellItemEnchantmentSpec4, " \
|
||||
"ig.gemItemId1, ig.gemBonuses1, ig.gemContext1, ig.gemScalingLevel1, ig.gemItemId2, ig.gemBonuses2, ig.gemContext2, ig.gemScalingLevel2, ig.gemItemId3, ig.gemBonuses3, ig.gemContext3, ig.gemScalingLevel3, " \
|
||||
"im.fixedScalingLevel, im.artifactKnowledgeLevel, iz.xp, iz.level, iz.knowledgeLevel"
|
||||
"im.fixedScalingLevel, im.artifactKnowledgeLevel"
|
||||
|
||||
PrepareStatement(CHAR_DEL_QUEST_POOL_SAVE, "DELETE FROM pool_quest_save WHERE pool_id = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_QUEST_POOL_SAVE, "INSERT INTO pool_quest_save (pool_id, quest_id) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
@@ -112,7 +112,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 LEFT JOIN item_instance_azerite iz ON ii.guid = iz.itemGuid WHERE ci.guid = ? ORDER BY (ii.flags & 0x80000) ASC, bag ASC, slot ASC", 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);
|
||||
@@ -144,8 +144,10 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES, "SELECT instanceId, releaseTime FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC);
|
||||
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC, "SELECT button, action, type FROM character_action WHERE guid = ? AND spec = ? ORDER BY button", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_MAILITEMS, "SELECT " SelectItemInstanceContent ", ii.owner_guid FROM mail_items mi JOIN item_instance ii ON mi.item_guid = 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 LEFT JOIN item_instance_azerite iz ON ii.guid = iz.itemGuid WHERE mail_id = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_AUCTION_ITEMS, "SELECT " SelectItemInstanceContent " FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = 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 LEFT JOIN item_instance_azerite iz ON ii.guid = iz.itemGuid", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_MAILITEMS, "SELECT " SelectItemInstanceContent ", ii.owner_guid, m.id FROM mail_items mi INNER JOIN mail m ON mi.mail_id = m.id LEFT JOIN item_instance ii ON mi.item_guid = 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 m.receiver = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_MAILITEMS_ARTIFACT, "SELECT a.itemGuid, a.xp, a.artifactAppearanceId, a.artifactTierId, ap.artifactPowerId, ap.purchasedRank FROM item_instance_artifact_powers ap LEFT JOIN item_instance_artifact a ON ap.itemGuid = a.itemGuid INNER JOIN mail_items mi ON a.itemGuid = mi.item_guid INNER JOIN mail m ON mi.mail_id = m.id WHERE m.receiver = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_MAILITEMS_AZERITE, "SELECT iz.itemGuid, iz.xp, iz.level, iz.knowledgeLevel FROM item_instance_azerite iz INNER JOIN mail_items mi ON iz.itemGuid = mi.item_guid INNER JOIN mail m ON mi.mail_id = m.id WHERE m.receiver = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_AUCTION_ITEMS, "SELECT " SelectItemInstanceContent " FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = 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", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, count, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_INS_AUCTION, "INSERT INTO auctionhouse (id, auctioneerguid, itemguid, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_AUCTION, "DELETE FROM auctionhouse WHERE id = ?", CONNECTION_ASYNC);
|
||||
@@ -189,6 +191,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_INS_ITEM_INSTANCE_MODIFIERS, "INSERT INTO item_instance_modifiers (itemGuid, fixedScalingLevel, artifactKnowledgeLevel) VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_MODIFIERS, "DELETE FROM item_instance_modifiers WHERE itemGuid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_MODIFIERS_BY_OWNER, "DELETE im FROM item_instance_modifiers im LEFT JOIN item_instance ii ON im.itemGuid = ii.guid WHERE ii.owner_guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_ITEM_INSTANCE_AZERITE, "SELECT iz.itemGuid, iz.xp, iz.level, iz.knowledgeLevel FROM item_instance_azerite iz INNER JOIN character_inventory ci ON iz.itemGuid = ci.item WHERE ci.guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_ITEM_INSTANCE_AZERITE, "INSERT INTO item_instance_azerite (itemGuid, xp, level, knowledgeLevel) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_ITEM_INSTANCE_AZERITE_ON_LOAD, "UPDATE item_instance_azerite SET xp = ?, knowledgeLevel = ? WHERE itemGuid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE, "DELETE FROM item_instance_azerite WHERE itemGuid = ?", CONNECTION_ASYNC);
|
||||
@@ -224,7 +227,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
// 0: uint32, 1: uint8, 2: uint8, 3: uint32, 4: uint32
|
||||
PrepareStatement(CHAR_INS_GUILD_BANK_ITEM, "INSERT INTO guild_bank_item (guildid, TabId, SlotId, item_guid) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_GUILD_BANK_ITEM, "DELETE FROM guild_bank_item WHERE guildid = ? AND TabId = ? AND SlotId = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8, 2: uint8
|
||||
PrepareStatement(CHAR_SEL_GUILD_BANK_ITEMS, "SELECT " SelectItemInstanceContent ", guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = 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 LEFT JOIN item_instance_azerite iz ON ii.guid = iz.itemGuid", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_GUILD_BANK_ITEMS, "SELECT " SelectItemInstanceContent ", guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = 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", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_DEL_GUILD_BANK_ITEMS, "DELETE FROM guild_bank_item WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32
|
||||
// 0: uint32, 1: uint8, 2: uint8, 3: uint8, 4: uint32
|
||||
PrepareStatement(CHAR_INS_GUILD_BANK_RIGHT, "INSERT INTO guild_bank_right (guildid, TabId, rid, gbright, SlotPerDay) VALUES (?, ?, ?, ?, ?) "
|
||||
@@ -506,7 +509,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_SEL_CHAR_COD_ITEM_MAIL, "SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver = ? AND has_items <> 0 AND cod <> 0", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_SOCIAL, "SELECT DISTINCT guid FROM character_social WHERE friend = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_OLD_CHARS, "SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE spell = 9454 AND guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_MAIL_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH);
|
||||
|
||||
@@ -116,6 +116,8 @@ enum CharacterDatabaseStatements : uint32
|
||||
CHAR_SEL_CHARACTER_QUESTSTATUSREW,
|
||||
CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES,
|
||||
CHAR_SEL_MAILITEMS,
|
||||
CHAR_SEL_MAILITEMS_ARTIFACT,
|
||||
CHAR_SEL_MAILITEMS_AZERITE,
|
||||
CHAR_SEL_AUCTION_ITEMS,
|
||||
CHAR_INS_AUCTION,
|
||||
CHAR_DEL_AUCTION,
|
||||
@@ -158,6 +160,7 @@ enum CharacterDatabaseStatements : uint32
|
||||
CHAR_INS_ITEM_INSTANCE_MODIFIERS,
|
||||
CHAR_DEL_ITEM_INSTANCE_MODIFIERS,
|
||||
CHAR_DEL_ITEM_INSTANCE_MODIFIERS_BY_OWNER,
|
||||
CHAR_SEL_ITEM_INSTANCE_AZERITE,
|
||||
CHAR_INS_ITEM_INSTANCE_AZERITE,
|
||||
CHAR_UPD_ITEM_INSTANCE_AZERITE_ON_LOAD,
|
||||
CHAR_DEL_ITEM_INSTANCE_AZERITE,
|
||||
|
||||
@@ -58,60 +58,51 @@ void AzeriteItem::SaveToDB(CharacterDatabaseTransaction& trans)
|
||||
trans->Append(stmt);
|
||||
}
|
||||
|
||||
bool AzeriteItem::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fields, uint32 entry)
|
||||
void AzeriteItem::LoadAzeriteItemData(AzeriteItemData& azeriteItemData)
|
||||
{
|
||||
if (!Item::LoadFromDB(guid, ownerGuid, fields, entry))
|
||||
return false;
|
||||
|
||||
bool needSave = false;
|
||||
|
||||
uint64 xp = fields[43].GetUInt64();
|
||||
uint32 level = fields[44].GetUInt32();
|
||||
uint32 knowledgeLevel = fields[45].GetUInt32();
|
||||
|
||||
if (!sAzeriteLevelInfoStore.LookupEntry(level))
|
||||
if (!sAzeriteLevelInfoStore.LookupEntry(azeriteItemData.Level))
|
||||
{
|
||||
xp = 0;
|
||||
level = 1;
|
||||
knowledgeLevel = GetCurrentKnowledgeLevel();
|
||||
azeriteItemData.Xp = 0;
|
||||
azeriteItemData.Level = 1;
|
||||
azeriteItemData.KnowledgeLevel = GetCurrentKnowledgeLevel();
|
||||
needSave = true;
|
||||
}
|
||||
else if (level > MAX_AZERITE_ITEM_LEVEL)
|
||||
else if (azeriteItemData.Level > MAX_AZERITE_ITEM_LEVEL)
|
||||
{
|
||||
xp = 0;
|
||||
level = MAX_AZERITE_ITEM_LEVEL;
|
||||
azeriteItemData.Xp = 0;
|
||||
azeriteItemData.Level = MAX_AZERITE_ITEM_LEVEL;
|
||||
needSave = true;
|
||||
}
|
||||
|
||||
if (knowledgeLevel != GetCurrentKnowledgeLevel())
|
||||
if (azeriteItemData.KnowledgeLevel != GetCurrentKnowledgeLevel())
|
||||
{
|
||||
// rescale XP to maintain same progress %
|
||||
uint64 oldMax = CalcTotalXPToNextLevel(level, knowledgeLevel);
|
||||
knowledgeLevel = GetCurrentKnowledgeLevel();
|
||||
uint64 newMax = CalcTotalXPToNextLevel(level, knowledgeLevel);
|
||||
xp = uint64(xp / double(oldMax) * newMax);
|
||||
uint64 oldMax = CalcTotalXPToNextLevel(azeriteItemData.Level, azeriteItemData.KnowledgeLevel);
|
||||
azeriteItemData.KnowledgeLevel = GetCurrentKnowledgeLevel();
|
||||
uint64 newMax = CalcTotalXPToNextLevel(azeriteItemData.Level, azeriteItemData.KnowledgeLevel);
|
||||
azeriteItemData.Xp = uint64(azeriteItemData.Xp / double(oldMax) * newMax);
|
||||
needSave = true;
|
||||
}
|
||||
else if (knowledgeLevel > MAX_AZERITE_ITEM_KNOWLEDGE_LEVEL)
|
||||
else if (azeriteItemData.KnowledgeLevel > MAX_AZERITE_ITEM_KNOWLEDGE_LEVEL)
|
||||
{
|
||||
knowledgeLevel = MAX_AZERITE_ITEM_KNOWLEDGE_LEVEL;
|
||||
azeriteItemData.KnowledgeLevel = MAX_AZERITE_ITEM_KNOWLEDGE_LEVEL;
|
||||
needSave = true;
|
||||
}
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(&AzeriteItem::m_azeriteItemData).ModifyValue(&UF::AzeriteItemData::Xp), xp);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(&AzeriteItem::m_azeriteItemData).ModifyValue(&UF::AzeriteItemData::Level), level);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(&AzeriteItem::m_azeriteItemData).ModifyValue(&UF::AzeriteItemData::KnowledgeLevel), knowledgeLevel);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(&AzeriteItem::m_azeriteItemData).ModifyValue(&UF::AzeriteItemData::Xp), azeriteItemData.Xp);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(&AzeriteItem::m_azeriteItemData).ModifyValue(&UF::AzeriteItemData::Level), azeriteItemData.Level);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(&AzeriteItem::m_azeriteItemData).ModifyValue(&UF::AzeriteItemData::KnowledgeLevel), azeriteItemData.KnowledgeLevel);
|
||||
|
||||
if (needSave)
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_INSTANCE_AZERITE_ON_LOAD);
|
||||
stmt->setUInt64(0, xp);
|
||||
stmt->setUInt32(1, knowledgeLevel);
|
||||
stmt->setUInt64(2, guid);
|
||||
stmt->setUInt64(0, azeriteItemData.Xp);
|
||||
stmt->setUInt32(1, azeriteItemData.KnowledgeLevel);
|
||||
stmt->setUInt64(2, GetGUID().GetCounter());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AzeriteItem::DeleteFromDB(CharacterDatabaseTransaction& trans)
|
||||
|
||||
@@ -32,11 +32,21 @@ public:
|
||||
bool Create(ObjectGuid::LowType guidlow, uint32 itemId, Player const* owner) override;
|
||||
|
||||
void SaveToDB(CharacterDatabaseTransaction& trans) override;
|
||||
bool LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fields, uint32 entry) override;
|
||||
void LoadAzeriteItemData(AzeriteItemData& azeriteItem);
|
||||
void DeleteFromDB(CharacterDatabaseTransaction& trans) override;
|
||||
|
||||
uint32 GetItemLevel(Player const* owner) const override;
|
||||
|
||||
uint32 GetLevel() const { return m_azeriteItemData->Level; }
|
||||
uint32 GetEffectiveLevel() const
|
||||
{
|
||||
uint32 level = m_azeriteItemData->AuraLevel;
|
||||
if (!level)
|
||||
level = m_azeriteItemData->Level;
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
static uint32 GetCurrentKnowledgeLevel();
|
||||
static uint64 CalcTotalXPToNextLevel(uint32 level, uint32 knowledgeLevel);
|
||||
void GiveXP(uint64 xp);
|
||||
|
||||
@@ -283,6 +283,61 @@ static uint32 const IllusionModifierMaskSpecSpecific =
|
||||
(1 << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3) |
|
||||
(1 << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4);
|
||||
|
||||
void ItemAdditionalLoadInfo::Init(std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo>* loadInfo,
|
||||
PreparedQueryResult artifactResult, PreparedQueryResult azeriteItemResult)
|
||||
{
|
||||
// 0 1 2 3 4 5
|
||||
// SELECT a.itemGuid, a.xp, a.artifactAppearanceId, a.artifactTierId, ap.artifactPowerId, ap.purchasedRank FROM item_instance_artifact_powers ap LEFT JOIN item_instance_artifact a ON ap.itemGuid = a.itemGuid ...
|
||||
if (artifactResult)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = artifactResult->Fetch();
|
||||
ItemAdditionalLoadInfo& info = (*loadInfo)[fields[0].GetUInt64()];
|
||||
if (!info.Artifact)
|
||||
info.Artifact = boost::in_place();
|
||||
info.Artifact->Xp = fields[1].GetUInt64();
|
||||
info.Artifact->ArtifactAppearanceId = fields[2].GetUInt32();
|
||||
info.Artifact->ArtifactTierId = fields[3].GetUInt32();
|
||||
ArtifactPowerData artifactPowerData;
|
||||
artifactPowerData.ArtifactPowerId = fields[4].GetUInt32();
|
||||
artifactPowerData.PurchasedRank = fields[5].GetUInt8();
|
||||
if (ArtifactPowerEntry const* artifactPower = sArtifactPowerStore.LookupEntry(artifactPowerData.ArtifactPowerId))
|
||||
{
|
||||
uint32 maxRank = artifactPower->MaxPurchasableRank;
|
||||
// allow ARTIFACT_POWER_FLAG_FINAL to overflow maxrank here - needs to be handled in Item::CheckArtifactUnlock (will refund artifact power)
|
||||
if (artifactPower->Flags & ARTIFACT_POWER_FLAG_MAX_RANK_WITH_TIER && artifactPower->Tier < info.Artifact->ArtifactTierId)
|
||||
maxRank += info.Artifact->ArtifactTierId - artifactPower->Tier;
|
||||
|
||||
if (artifactPowerData.PurchasedRank > maxRank)
|
||||
artifactPowerData.PurchasedRank = maxRank;
|
||||
|
||||
artifactPowerData.CurrentRankWithBonus = (artifactPower->Flags & ARTIFACT_POWER_FLAG_FIRST) == ARTIFACT_POWER_FLAG_FIRST ? 1 : 0;
|
||||
|
||||
info.Artifact->ArtifactPowers.push_back(artifactPowerData);
|
||||
}
|
||||
|
||||
} while (artifactResult->NextRow());
|
||||
}
|
||||
|
||||
// 0 1 2 3
|
||||
// SELECT iz.itemGuid, iz.xp, iz.level, iz.knowledgeLevel FROM item_instance_azerite iz INNER JOIN ...
|
||||
if (azeriteItemResult)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = azeriteItemResult->Fetch();
|
||||
ItemAdditionalLoadInfo& info = (*loadInfo)[fields[0].GetUInt64()];
|
||||
if (!info.AzeriteItem)
|
||||
info.AzeriteItem = boost::in_place();
|
||||
info.AzeriteItem->Xp = fields[1].GetUInt64();
|
||||
info.AzeriteItem->Level = fields[2].GetUInt32();
|
||||
info.AzeriteItem->KnowledgeLevel = fields[3].GetUInt32();
|
||||
|
||||
} while (azeriteItemResult->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
Item::Item()
|
||||
{
|
||||
m_objectType |= TYPEMASK_ITEM;
|
||||
@@ -640,8 +695,8 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
|
||||
// spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4,
|
||||
// 29 30 31 32 33 34 35 36 37 38 39 40
|
||||
// gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3
|
||||
// 41 42 43 44 45
|
||||
// fixedScalingLevel, artifactKnowledgeLevel, iz.xp, iz.level, iz.knowledgeLevel FROM item_instance
|
||||
// 41 42
|
||||
// fixedScalingLevel, artifactKnowledgeLevel FROM item_instance
|
||||
|
||||
// create item before any checks for store correct guid
|
||||
// and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB
|
||||
@@ -784,7 +839,7 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
|
||||
return true;
|
||||
}
|
||||
|
||||
void Item::LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerLoadInfo>& powers)
|
||||
void Item::LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerData>& powers)
|
||||
{
|
||||
for (uint8 i = 0; i <= artifactTier; ++i)
|
||||
InitArtifactPowers(GetTemplate()->GetArtifactID(), i);
|
||||
@@ -797,7 +852,7 @@ void Item::LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceI
|
||||
SetAppearanceModId(artifactAppearance->ItemAppearanceModifierID);
|
||||
|
||||
uint8 totalPurchasedRanks = 0;
|
||||
for (ArtifactPowerLoadInfo& power : powers)
|
||||
for (ArtifactPowerData& power : powers)
|
||||
{
|
||||
power.CurrentRankWithBonus += power.PurchasedRank;
|
||||
totalPurchasedRanks += power.PurchasedRank;
|
||||
@@ -841,7 +896,7 @@ void Item::LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceI
|
||||
SetArtifactPower(power.ArtifactPowerId, power.PurchasedRank, power.CurrentRankWithBonus);
|
||||
}
|
||||
|
||||
for (ArtifactPowerLoadInfo& power : powers)
|
||||
for (ArtifactPowerData& power : powers)
|
||||
{
|
||||
ArtifactPowerEntry const* scaledArtifactPowerEntry = sArtifactPowerStore.AssertEntry(power.ArtifactPowerId);
|
||||
if (!(scaledArtifactPowerEntry->Flags & ARTIFACT_POWER_FLAG_SCALES_WITH_NUM_POWERS))
|
||||
@@ -2381,7 +2436,7 @@ UF::ArtifactPower const* Item::GetArtifactPower(uint32 artifactPowerId) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Item::AddArtifactPower(ArtifactPowerLoadInfo const* artifactPower)
|
||||
void Item::AddArtifactPower(ArtifactPowerData const* artifactPower)
|
||||
{
|
||||
uint16 index = uint16(m_artifactPowerIdToIndex.size());
|
||||
m_artifactPowerIdToIndex[artifactPower->ArtifactPowerId] = index;
|
||||
@@ -2417,7 +2472,7 @@ void Item::InitArtifactPowers(uint8 artifactId, uint8 artifactTier)
|
||||
if (m_artifactPowerIdToIndex.find(artifactPower->ID) != m_artifactPowerIdToIndex.end())
|
||||
continue;
|
||||
|
||||
ArtifactPowerLoadInfo powerData;
|
||||
ArtifactPowerData powerData;
|
||||
memset(&powerData, 0, sizeof(powerData));
|
||||
powerData.ArtifactPowerId = artifactPower->ID;
|
||||
powerData.PurchasedRank = 0;
|
||||
|
||||
@@ -108,13 +108,36 @@ private:
|
||||
} _state;
|
||||
};
|
||||
|
||||
struct ArtifactPowerLoadInfo
|
||||
struct ArtifactPowerData
|
||||
{
|
||||
uint32 ArtifactPowerId;
|
||||
uint8 PurchasedRank;
|
||||
uint8 CurrentRankWithBonus;
|
||||
};
|
||||
|
||||
struct ArtifactData
|
||||
{
|
||||
uint64 Xp;
|
||||
uint32 ArtifactAppearanceId;
|
||||
uint32 ArtifactTierId;
|
||||
std::vector<ArtifactPowerData> ArtifactPowers;
|
||||
};
|
||||
|
||||
struct AzeriteItemData
|
||||
{
|
||||
uint64 Xp;
|
||||
uint32 Level;
|
||||
uint32 KnowledgeLevel;
|
||||
};
|
||||
|
||||
struct ItemAdditionalLoadInfo
|
||||
{
|
||||
static void Init(std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo>* loadInfo, PreparedQueryResult artifactResult, PreparedQueryResult azeriteItemResult);
|
||||
|
||||
Optional<ArtifactData> Artifact;
|
||||
Optional<AzeriteItemData> AzeriteItem;
|
||||
};
|
||||
|
||||
struct ItemDynamicFieldGems
|
||||
{
|
||||
uint32 ItemId;
|
||||
@@ -174,7 +197,7 @@ class TC_GAME_API Item : public Object
|
||||
bool IsBoundByEnchant() const;
|
||||
virtual void SaveToDB(CharacterDatabaseTransaction& trans);
|
||||
virtual bool LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fields, uint32 entry);
|
||||
void LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerLoadInfo>& powers); // must be called after LoadFromDB to have gems (relics) initialized
|
||||
void LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerData>& powers); // must be called after LoadFromDB to have gems (relics) initialized
|
||||
void CheckArtifactRelicSlotUnlock(Player const* owner);
|
||||
|
||||
void AddBonuses(uint32 bonusListID);
|
||||
@@ -355,7 +378,7 @@ class TC_GAME_API Item : public Object
|
||||
void SetChildItem(ObjectGuid childItem) { m_childItem = childItem; }
|
||||
|
||||
UF::ArtifactPower const* GetArtifactPower(uint32 artifactPowerId) const;
|
||||
void AddArtifactPower(ArtifactPowerLoadInfo const* artifactPower);
|
||||
void AddArtifactPower(ArtifactPowerData const* artifactPower);
|
||||
void SetArtifactPower(uint16 artifactPowerId, uint8 purchasedRank, uint8 currentRankWithBonus);
|
||||
|
||||
void InitArtifactPowers(uint8 artifactId, uint8 artifactTier);
|
||||
|
||||
@@ -18185,7 +18185,10 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
|
||||
// must be before inventory (some items required reputation check)
|
||||
m_reputationMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_REPUTATION));
|
||||
|
||||
_LoadInventory(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INVENTORY), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ARTIFACTS), time_diff);
|
||||
_LoadInventory(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INVENTORY),
|
||||
holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ARTIFACTS),
|
||||
holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AZERITE),
|
||||
time_diff);
|
||||
|
||||
if (IsVoidStorageUnlocked())
|
||||
_LoadVoidStorage(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE));
|
||||
@@ -18582,7 +18585,7 @@ void Player::LoadCorpse(PreparedQueryResult result)
|
||||
RemoveAtLoginFlag(AT_LOGIN_RESURRECT);
|
||||
}
|
||||
|
||||
void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult artifactsResult, uint32 timeDiff)
|
||||
void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult artifactsResult, PreparedQueryResult azeriteResult, uint32 timeDiff)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12
|
||||
// SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text,
|
||||
@@ -18594,9 +18597,9 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
|
||||
// spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4,
|
||||
// 29 30 31 32 33 34 35 36 37 38 39 40
|
||||
// gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3
|
||||
// 41 42 43 44 45
|
||||
// fixedScalingLevel, artifactKnowledgeLevel, iz.xp, iz.level, iz.knowledgeLevel FROM item_instance
|
||||
// 46 47
|
||||
// 41 42
|
||||
// fixedScalingLevel, artifactKnowledgeLevel FROM item_instance
|
||||
// 43 44
|
||||
// bag, slot
|
||||
// FROM character_inventory ci
|
||||
// JOIN item_instance ii ON ci.item = ii.guid
|
||||
@@ -18612,38 +18615,8 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
|
||||
//NOTE2: the "order by `slot`" is needed because mainhand weapons are (wrongly?)
|
||||
//expected to be equipped before offhand items (@todo fixme)
|
||||
|
||||
// 0 1 2 3 4 5
|
||||
// SELECT a.itemGuid, a.xp, a.artifactAppearanceId, a.artifactTierId, ap.artifactPowerId, ap.purchasedRank FROM item_instance_artifact_powers ap LEFT JOIN item_instance_artifact a ON ap.itemGuid = a.itemGuid INNER JOIN character_inventory ci ON ci.item = ap.guid WHERE ci.guid = ?
|
||||
std::unordered_map<ObjectGuid, std::tuple<uint64, uint32, uint32, std::vector<ArtifactPowerLoadInfo>>> artifactData;
|
||||
if (artifactsResult)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = artifactsResult->Fetch();
|
||||
auto& artifactDataEntry = artifactData[ObjectGuid::Create<HighGuid::Item>(fields[0].GetUInt64())];
|
||||
std::get<0>(artifactDataEntry) = fields[1].GetUInt64();
|
||||
std::get<1>(artifactDataEntry) = fields[2].GetUInt32();
|
||||
std::get<2>(artifactDataEntry) = fields[3].GetUInt32();
|
||||
ArtifactPowerLoadInfo artifactPowerData;
|
||||
artifactPowerData.ArtifactPowerId = fields[4].GetUInt32();
|
||||
artifactPowerData.PurchasedRank = fields[5].GetUInt8();
|
||||
if (ArtifactPowerEntry const* artifactPower = sArtifactPowerStore.LookupEntry(artifactPowerData.ArtifactPowerId))
|
||||
{
|
||||
uint32 maxRank = artifactPower->MaxPurchasableRank;
|
||||
// allow ARTIFACT_POWER_FLAG_FINAL to overflow maxrank here - needs to be handled in Item::CheckArtifactUnlock (will refund artifact power)
|
||||
if (artifactPower->Flags & ARTIFACT_POWER_FLAG_MAX_RANK_WITH_TIER && artifactPower->Tier < std::get<2>(artifactDataEntry))
|
||||
maxRank += std::get<2>(artifactDataEntry) - artifactPower->Tier;
|
||||
|
||||
if (artifactPowerData.PurchasedRank > maxRank)
|
||||
artifactPowerData.PurchasedRank = maxRank;
|
||||
|
||||
artifactPowerData.CurrentRankWithBonus = (artifactPower->Flags & ARTIFACT_POWER_FLAG_FIRST) == ARTIFACT_POWER_FLAG_FIRST ? 1 : 0;
|
||||
|
||||
std::get<3>(artifactDataEntry).push_back(artifactPowerData);
|
||||
}
|
||||
|
||||
} while (artifactsResult->NextRow());
|
||||
}
|
||||
std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo> additionalData;
|
||||
ItemAdditionalLoadInfo::Init(&additionalData, artifactsResult, azeriteResult);
|
||||
|
||||
if (result)
|
||||
{
|
||||
@@ -18661,12 +18634,19 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
|
||||
Field* fields = result->Fetch();
|
||||
if (Item* item = _LoadItem(trans, zoneId, timeDiff, fields))
|
||||
{
|
||||
auto artifactDataItr = artifactData.find(item->GetGUID());
|
||||
if (item->GetTemplate()->GetArtifactID() && artifactDataItr != artifactData.end())
|
||||
item->LoadArtifactData(this, std::get<0>(artifactDataItr->second), std::get<1>(artifactDataItr->second), std::get<2>(artifactDataItr->second), std::get<3>(artifactDataItr->second));
|
||||
if (ItemAdditionalLoadInfo* addionalDataPtr = Trinity::Containers::MapGetValuePtr(additionalData, fields[0].GetUInt64()))
|
||||
{
|
||||
if (item->GetTemplate()->GetArtifactID() && addionalDataPtr->Artifact)
|
||||
item->LoadArtifactData(this, addionalDataPtr->Artifact->Xp, addionalDataPtr->Artifact->ArtifactAppearanceId,
|
||||
addionalDataPtr->Artifact->ArtifactTierId, addionalDataPtr->Artifact->ArtifactPowers);
|
||||
|
||||
ObjectGuid bagGuid = fields[46].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[46].GetUInt64()) : ObjectGuid::Empty;
|
||||
uint8 slot = fields[47].GetUInt8();
|
||||
if (addionalDataPtr->AzeriteItem)
|
||||
if (AzeriteItem* azeriteItem = item->ToAzeriteItem())
|
||||
azeriteItem->LoadAzeriteItemData(*addionalDataPtr->AzeriteItem);
|
||||
}
|
||||
|
||||
ObjectGuid bagGuid = fields[43].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[43].GetUInt64()) : ObjectGuid::Empty;
|
||||
uint8 slot = fields[44].GetUInt8();
|
||||
|
||||
GetSession()->GetCollectionMgr()->CheckHeirloomUpgrades(item);
|
||||
GetSession()->GetCollectionMgr()->AddItemAppearance(item);
|
||||
@@ -18971,61 +18951,59 @@ Item* Player::_LoadItem(CharacterDatabaseTransaction& trans, uint32 zoneId, uint
|
||||
}
|
||||
|
||||
// load mailed item which should receive current player
|
||||
void Player::_LoadMailedItems(Mail* mail)
|
||||
void Player::_LoadMailedItem(Mail* mail, Field* fields, ItemAdditionalLoadInfo* addionalData)
|
||||
{
|
||||
// data needs to be at first place for Item::LoadFromDB
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS);
|
||||
stmt->setUInt32(0, mail->messageID);
|
||||
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
if (!result)
|
||||
return;
|
||||
ObjectGuid::LowType itemGuid = fields[0].GetUInt64();
|
||||
uint32 itemEntry = fields[1].GetUInt32();
|
||||
|
||||
do
|
||||
mail->AddItem(itemGuid, itemEntry);
|
||||
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemEntry);
|
||||
if (!proto)
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
TC_LOG_ERROR("entities.player", "Player '%s' (%s) has unknown item_template in mailed items (GUID: " UI64FMTD ", Entry: %u) in mail (%u), deleted.",
|
||||
GetName().c_str(), GetGUID().ToString().c_str(), itemGuid, itemEntry, mail->messageID);
|
||||
|
||||
ObjectGuid::LowType itemGuid = fields[0].GetUInt64();
|
||||
uint32 itemEntry = fields[1].GetUInt32();
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_MAIL_ITEM);
|
||||
stmt->setUInt64(0, itemGuid);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
mail->AddItem(itemGuid, itemEntry);
|
||||
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemEntry);
|
||||
if (!proto)
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Player '%s' (%s) has unknown item_template in mailed items (GUID: " UI64FMTD ", Entry: %u) in mail (%u), deleted.",
|
||||
GetName().c_str(), GetGUID().ToString().c_str(), itemGuid, itemEntry, mail->messageID);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_MAIL_ITEM);
|
||||
stmt->setUInt64(0, itemGuid);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
|
||||
stmt->setUInt64(0, itemGuid);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
continue;
|
||||
}
|
||||
|
||||
Item* item = NewItemOrBag(proto);
|
||||
|
||||
ObjectGuid ownerGuid = fields[46].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[46].GetUInt64()) : ObjectGuid::Empty;
|
||||
if (!item->LoadFromDB(itemGuid, ownerGuid, fields, itemEntry))
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems: Item (GUID: " UI64FMTD ") in mail (%u) doesn't exist, deleted from mail.", itemGuid, mail->messageID);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM);
|
||||
stmt->setUInt64(0, itemGuid);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
item->FSetState(ITEM_REMOVED);
|
||||
|
||||
CharacterDatabaseTransaction temp = CharacterDatabaseTransaction(nullptr);
|
||||
item->SaveToDB(temp); // it also deletes item object !
|
||||
continue;
|
||||
}
|
||||
|
||||
AddMItem(item);
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
|
||||
stmt->setUInt64(0, itemGuid);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
return;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
Item* item = NewItemOrBag(proto);
|
||||
|
||||
ObjectGuid ownerGuid = fields[43].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[43].GetUInt64()) : ObjectGuid::Empty;
|
||||
if (!item->LoadFromDB(itemGuid, ownerGuid, fields, itemEntry))
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems: Item (GUID: " UI64FMTD ") in mail (%u) doesn't exist, deleted from mail.", itemGuid, mail->messageID);
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM);
|
||||
stmt->setUInt64(0, itemGuid);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
item->FSetState(ITEM_REMOVED);
|
||||
|
||||
CharacterDatabaseTransaction temp = CharacterDatabaseTransaction(nullptr);
|
||||
item->SaveToDB(temp); // it also deletes item object !
|
||||
return;
|
||||
}
|
||||
|
||||
if (addionalData)
|
||||
{
|
||||
if (item->GetTemplate()->GetArtifactID() && addionalData->Artifact)
|
||||
item->LoadArtifactData(this, addionalData->Artifact->Xp, addionalData->Artifact->ArtifactAppearanceId,
|
||||
addionalData->Artifact->ArtifactTierId, addionalData->Artifact->ArtifactPowers);
|
||||
|
||||
if (addionalData->AzeriteItem)
|
||||
if (AzeriteItem* azeriteItem = item->ToAzeriteItem())
|
||||
azeriteItem->LoadAzeriteItemData(*addionalData->AzeriteItem);
|
||||
}
|
||||
|
||||
AddMItem(item);
|
||||
}
|
||||
|
||||
void Player::_LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult resultDelivery)
|
||||
@@ -19049,12 +19027,14 @@ void Player::_LoadMail()
|
||||
stmt->setUInt64(0, GetGUID().GetCounter());
|
||||
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
|
||||
std::unordered_map<uint32, Mail*> mailById;
|
||||
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
Mail* m = new Mail;
|
||||
Mail* m = new Mail();
|
||||
|
||||
m->messageID = fields[0].GetUInt32();
|
||||
m->messageType = fields[1].GetUInt8();
|
||||
@@ -19062,14 +19042,13 @@ void Player::_LoadMail()
|
||||
m->receiver = fields[3].GetUInt64();
|
||||
m->subject = fields[4].GetString();
|
||||
m->body = fields[5].GetString();
|
||||
bool has_items = fields[6].GetBool();
|
||||
m->expire_time = time_t(fields[7].GetUInt32());
|
||||
m->deliver_time = time_t(fields[8].GetUInt32());
|
||||
m->money = fields[9].GetUInt64();
|
||||
m->COD = fields[10].GetUInt64();
|
||||
m->checked = fields[11].GetUInt8();
|
||||
m->stationery = fields[12].GetUInt8();
|
||||
m->mailTemplateId = fields[13].GetInt16();
|
||||
m->expire_time = time_t(fields[6].GetUInt32());
|
||||
m->deliver_time = time_t(fields[7].GetUInt32());
|
||||
m->money = fields[8].GetUInt64();
|
||||
m->COD = fields[9].GetUInt64();
|
||||
m->checked = fields[10].GetUInt8();
|
||||
m->stationery = fields[11].GetUInt8();
|
||||
m->mailTemplateId = fields[12].GetInt16();
|
||||
|
||||
if (m->mailTemplateId && !sMailTemplateStore.LookupEntry(m->mailTemplateId))
|
||||
{
|
||||
@@ -19079,13 +19058,38 @@ void Player::_LoadMail()
|
||||
|
||||
m->state = MAIL_STATE_UNCHANGED;
|
||||
|
||||
if (has_items)
|
||||
_LoadMailedItems(m);
|
||||
|
||||
m_mail.push_back(m);
|
||||
mailById[m->messageID] = m;
|
||||
}
|
||||
while (result->NextRow());
|
||||
}
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS);
|
||||
stmt->setUInt64(0, GetGUID().GetCounter());
|
||||
result = CharacterDatabase.Query(stmt);
|
||||
|
||||
if (result)
|
||||
{
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_ARTIFACT);
|
||||
stmt->setUInt64(0, GetGUID().GetCounter());
|
||||
PreparedQueryResult artifactResult = CharacterDatabase.Query(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE);
|
||||
stmt->setUInt64(0, GetGUID().GetCounter());
|
||||
PreparedQueryResult azeriteResult = CharacterDatabase.Query(stmt);
|
||||
|
||||
std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo> additionalData;
|
||||
ItemAdditionalLoadInfo::Init(&additionalData, artifactResult, azeriteResult);
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 mailId = fields[44].GetUInt32();
|
||||
_LoadMailedItem(mailById[mailId], fields, Trinity::Containers::MapGetValuePtr(additionalData, fields[0].GetUInt64()));
|
||||
}
|
||||
while (result->NextRow());
|
||||
}
|
||||
|
||||
m_mailsLoaded = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ struct ChrSpecializationEntry;
|
||||
struct CreatureTemplate;
|
||||
struct CurrencyTypesEntry;
|
||||
struct FactionEntry;
|
||||
struct ItemAdditionalLoadInfo;
|
||||
struct ItemExtendedCostEntry;
|
||||
struct ItemLimitCategoryEntry;
|
||||
struct ItemSetEffect;
|
||||
@@ -749,6 +750,7 @@ enum PlayerLoginQueryIndex
|
||||
PLAYER_LOGIN_QUERY_LOAD_REPUTATION,
|
||||
PLAYER_LOGIN_QUERY_LOAD_INVENTORY,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ARTIFACTS,
|
||||
PLAYER_LOGIN_QUERY_LOAD_AZERITE,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ACTIONS,
|
||||
PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT,
|
||||
PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE,
|
||||
@@ -2487,11 +2489,11 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void _LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effectResult, uint32 timediff);
|
||||
void _LoadGlyphAuras();
|
||||
void _LoadBoundInstances(PreparedQueryResult result);
|
||||
void _LoadInventory(PreparedQueryResult result, PreparedQueryResult artifactsResult, uint32 timeDiff);
|
||||
void _LoadInventory(PreparedQueryResult result, PreparedQueryResult artifactsResult, PreparedQueryResult azeriteResult, uint32 timeDiff);
|
||||
void _LoadVoidStorage(PreparedQueryResult result);
|
||||
void _LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult resultDelivery);
|
||||
void _LoadMail();
|
||||
void _LoadMailedItems(Mail* mail);
|
||||
void _LoadMailedItem(Mail* mail, Field* fields, ItemAdditionalLoadInfo* addionalData);
|
||||
void _LoadQuestStatus(PreparedQueryResult result);
|
||||
void _LoadQuestStatusObjectives(PreparedQueryResult result);
|
||||
void _LoadQuestStatusRewarded(PreparedQueryResult result);
|
||||
|
||||
@@ -374,7 +374,7 @@ void Guild::BankTab::LoadFromDB(Field* fields)
|
||||
|
||||
bool Guild::BankTab::LoadItemFromDB(Field* fields)
|
||||
{
|
||||
uint8 slotId = fields[48].GetUInt8();
|
||||
uint8 slotId = fields[45].GetUInt8();
|
||||
ObjectGuid::LowType itemGuid = fields[0].GetUInt64();
|
||||
uint32 itemEntry = fields[1].GetUInt32();
|
||||
if (slotId >= GUILD_BANK_MAX_SLOTS)
|
||||
@@ -2498,7 +2498,7 @@ void Guild::LoadBankTabFromDB(Field* fields)
|
||||
|
||||
bool Guild::LoadBankItemFromDB(Field* fields)
|
||||
{
|
||||
uint8 tabId = fields[47].GetUInt8();
|
||||
uint8 tabId = fields[44].GetUInt8();
|
||||
if (tabId >= _GetPurchasedTabsSize())
|
||||
{
|
||||
TC_LOG_ERROR("guild", "Invalid tab for item (GUID: %u, id: #%u) in guild bank, skipped.",
|
||||
|
||||
@@ -418,9 +418,9 @@ void GuildMgr::LoadGuilds()
|
||||
// spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4,
|
||||
// 29 30 31 32 33 34 35 36 37 38 39 40
|
||||
// gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3
|
||||
// 41 42 43 44 45
|
||||
// fixedScalingLevel, artifactKnowledgeLevel, iz.xp, iz.level, iz.knowledgeLevel
|
||||
// 46 47 48
|
||||
// 41 42
|
||||
// fixedScalingLevel, artifactKnowledgeLevel
|
||||
// 43 44 45
|
||||
// guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid
|
||||
|
||||
PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEMS));
|
||||
@@ -434,7 +434,7 @@ void GuildMgr::LoadGuilds()
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint64 guildId = fields[46].GetUInt64();
|
||||
uint64 guildId = fields[43].GetUInt64();
|
||||
|
||||
if (Guild* guild = GetGuildById(guildId))
|
||||
guild->LoadBankItemFromDB(fields);
|
||||
|
||||
@@ -152,6 +152,10 @@ bool LoginQueryHolder::Initialize()
|
||||
stmt->setUInt64(0, lowGuid);
|
||||
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ARTIFACTS, stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ITEM_INSTANCE_AZERITE);
|
||||
stmt->setUInt64(0, lowGuid);
|
||||
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_AZERITE, stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_VOID_STORAGE);
|
||||
stmt->setUInt64(0, lowGuid);
|
||||
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE, stmt);
|
||||
|
||||
Reference in New Issue
Block a user