tmog part 1

This commit is contained in:
luis
2026-03-22 18:11:58 -03:00
parent 9ec349ebaf
commit aed90f22e5
22 changed files with 1501 additions and 395 deletions
@@ -99,7 +99,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
"health, power1, power2, power3, power4, power5, power6, power7, power8, power9, power10, instance_id, activeTalentGroup, lootSpecId, exploredZones, knownTitles, actionBars, "
"raidDifficulty, legacyRaidDifficulty, fishingSteps, honor, honorLevel, honorRestState, honorRestBonus, numRespecs, "
"personalTabardEmblemStyle, personalTabardEmblemColor, personalTabardBorderStyle, personalTabardBorderColor, personalTabardBackgroundColor, "
"personalTabardEmblemStyle, personalTabardEmblemColor, personalTabardBorderStyle, personalTabardBorderColor, personalTabardBackgroundColor, transmogOutfitEquippedId, transmogOutfitLocked ,"
"chromieTimeExpansionId "
"FROM characters c LEFT JOIN character_fishingsteps cfs ON c.guid = cfs.guid WHERE c.guid = ?", CONNECTION_ASYNC);
@@ -151,6 +151,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER_TRANSMOG_OUTFITS, "SELECT setguid, setindex, name, iconname, ignore_mask, appearance0, appearance1, appearance2, appearance3, appearance4, "
"appearance5, appearance6, appearance7, appearance8, appearance9, appearance10, appearance11, appearance12, appearance13, appearance14, appearance15, appearance16, "
"appearance17, appearance18, mainHandEnchant, offHandEnchant FROM character_transmog_outfits WHERE guid = ? ORDER BY setindex", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_TRANSMOG_OUTFIT, "SELECT transmogOutfitId, name, icon, situationsEnabled FROM character_transmog_outfit WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_TRANSMOG_OUTFIT_SITUATION, "SELECT transmogOutfitId, situationID, specID, loadoutID, equipmentSetID FROM character_transmog_outfit_situation WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_TRANSMOG_OUTFIT_SLOT, "SELECT transmogOutfitId, slot, slotOption, itemModifiedAppearanceID, appearanceDisplayType, spellItemEnchantmentID, illusionDisplayType, flags FROM character_transmog_outfit_slot WHERE guid = ? ORDER BY transmogOutfitId, slot, slotOption", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_BGDATA, "SELECT instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell, queueId FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT talentGroup, glyphId FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_TALENTS, "SELECT talentId, talentGroup FROM character_talent WHERE guid = ?", CONNECTION_ASYNC);
@@ -361,6 +364,12 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"appearance16, appearance17, appearance18, mainHandEnchant, offHandEnchant) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_TRANSMOG_OUTFIT, "DELETE FROM character_transmog_outfits WHERE setguid=?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_TRANSMOG_OUTFIT_2, "INSERT INTO character_transmog_outfit (guid, transmogOutfitId, name, icon, situationsEnabled) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_TRANSMOG_OUTFIT_2, "DELETE FROM character_transmog_outfit WHERE guid = ? AND transmogOutfitId = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_TRANSMOG_OUTFIT_SITUATION, "INSERT INTO character_transmog_outfit_situation (guid, transmogOutfitId, situationID, specID, loadoutID, equipmentSetID) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_TRANSMOG_OUTFIT_SITUATION, "DELETE FROM character_transmog_outfit_situation WHERE guid = ? AND transmogOutfitId = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_TRANSMOG_OUTFIT_SLOT, "INSERT INTO character_transmog_outfit_slot (guid, transmogOutfitId, slot, slotOption, itemModifiedAppearanceID, appearanceDisplayType, spellItemEnchantmentID, illusionDisplayType, flags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_TRANSMOG_OUTFIT_SLOT, "DELETE FROM character_transmog_outfit_slot WHERE guid = ? AND transmogOutfitId = ?", CONNECTION_ASYNC);
// Auras
PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, casterGuid, itemGuid, spell, effectMask, recalculateMask, difficulty, stackCount, maxDuration, remainTime, remainCharges, castItemId, castItemLevel) "
@@ -482,17 +491,19 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"taximask, createTime, createMode, cinematic, "
"totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, primarySpecialization, "
"extra_flags, summonedPetNumber, at_login, "
"death_expire_time, taxi_path, totalKills, "
"todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, "
"power4, power5, power6, power7, power8, power9, power10, latency, activeTalentGroup, lootSpecId, exploredZones, equipmentCache, knownTitles, actionBars, lastLoginBuild, chromieTimeExpansionId) VALUES "
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
"death_expire_time, taxi_path, totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, "
"power1, power2, power3, power4, power5, power6, power7, power8, power9, power10, "
"latency, activeTalentGroup, lootSpecId, exploredZones, equipmentCache, knownTitles, actionBars, lastLoginBuild, "
"personalTabardEmblemStyle, personalTabardEmblemColor, personalTabardBorderStyle, personalTabardBorderColor, personalTabardBackgroundColor, transmogOutfitEquippedId, transmogOutfitLocked, chromieTimeExpansionId) VALUES "
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,inventorySlots=?,inventoryBagFlags=?,bagSlotFlags1=?,bagSlotFlags2=?,bagSlotFlags3=?,bagSlotFlags4=?,bagSlotFlags5=?,"
"bankSlots=?,bankTabs=?,bankBagFlags=?,restState=?,playerFlags=?,playerFlagsEx=?,"
"map=?,instance_id=?,dungeonDifficulty=?,raidDifficulty=?,legacyRaidDifficulty=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?,"
"logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,numRespecs=?,primarySpecialization=?,extra_flags=?,summonedPetNumber=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?,"
"totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,"
"watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,power7=?,power8=?,power9=?,power10=?,latency=?,activeTalentGroup=?,lootSpecId=?,exploredZones=?,"
"equipmentCache=?,knownTitles=?,actionBars=?,online=?,honor=?,honorLevel=?,honorRestState=?,honorRestBonus=?,lastLoginBuild=?,chromieTimeExpansionId=? WHERE guid=?", CONNECTION_ASYNC);
"equipmentCache=?,knownTitles=?,actionBars=?,online=?,honor=?,honorLevel=?,honorRestState=?,honorRestBonus=?,lastLoginBuild=?,"
"personalTabardEmblemStyle=?,personalTabardEmblemColor=?,personalTabardBorderStyle=?,personalTabardBorderColor=?,personalTabardBackgroundColor=?,transmogOutfitEquippedId=?,transmogOutfitLocked=?, chromieTimeExpansionId=? WHERE guid=?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG, "UPDATE characters SET at_login = at_login | ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_REM_AT_LOGIN_FLAG, "UPDATE characters set at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
@@ -627,6 +638,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENTS, "DELETE FROM character_achievement WHERE guid = ? AND achievement NOT IN (456,457,458,459,460,461,462,463,464,465,466,467,1400,1402,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1463,3117,3259,4078,4576,4998,4999,5000,5001,5002,5003,5004,5005,5006,5007,5008,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,6433,6523,6524,6743,6744,6745,6746,6747,6748,6749,6750,6751,6752,6829,6859,6860,6861,6862,6863,6864,6865,6866,6867,6868,6869,6870,6871,6872,6873)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_EQUIPMENTSETS, "DELETE FROM character_equipmentsets WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_TRANSMOG_OUTFITS, "DELETE FROM character_transmog_outfits WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_TRANSMOG_OUTFIT_BY_CHAR, "DELETE FROM character_transmog_outfit WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_TRANSMOG_OUTFIT_SITUATION_BY_CHAR, "DELETE FROM character_transmog_outfit_slot WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_TRANSMOG_OUTFIT_SLOT_BY_CHAR, "DELETE FROM character_transmog_outfit_situation WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER, "DELETE FROM guild_eventlog WHERE PlayerGuid1 = ? OR PlayerGuid2 = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_BANK_EVENTLOG_BY_PLAYER, "DELETE FROM guild_bank_eventlog WHERE PlayerGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_GLYPHS, "DELETE FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
@@ -107,6 +107,9 @@ enum CharacterDatabaseStatements : uint32
CHAR_SEL_CHARACTER_CRITERIAPROGRESS,
CHAR_SEL_CHARACTER_EQUIPMENTSETS,
CHAR_SEL_CHARACTER_TRANSMOG_OUTFITS,
CHAR_SEL_CHARACTER_TRANSMOG_OUTFIT,
CHAR_SEL_CHARACTER_TRANSMOG_OUTFIT_SITUATION,
CHAR_SEL_CHARACTER_TRANSMOG_OUTFIT_SLOT,
CHAR_SEL_CHARACTER_BGDATA,
CHAR_SEL_CHARACTER_GLYPHS,
CHAR_SEL_CHARACTER_TALENTS,
@@ -270,6 +273,13 @@ enum CharacterDatabaseStatements : uint32
CHAR_INS_TRANSMOG_OUTFIT,
CHAR_DEL_TRANSMOG_OUTFIT,
CHAR_INS_TRANSMOG_OUTFIT_2,
CHAR_DEL_TRANSMOG_OUTFIT_2,
CHAR_INS_TRANSMOG_OUTFIT_SITUATION,
CHAR_DEL_TRANSMOG_OUTFIT_SITUATION,
CHAR_INS_TRANSMOG_OUTFIT_SLOT,
CHAR_DEL_TRANSMOG_OUTFIT_SLOT,
CHAR_INS_AURA,
CHAR_INS_AURA_EFFECT,
@@ -496,6 +506,9 @@ enum CharacterDatabaseStatements : uint32
CHAR_DEL_CHAR_ACHIEVEMENTS,
CHAR_DEL_CHAR_EQUIPMENTSETS,
CHAR_DEL_CHAR_TRANSMOG_OUTFITS,
CHAR_DEL_CHAR_TRANSMOG_OUTFIT_BY_CHAR,
CHAR_DEL_CHAR_TRANSMOG_OUTFIT_SITUATION_BY_CHAR,
CHAR_DEL_CHAR_TRANSMOG_OUTFIT_SLOT_BY_CHAR,
CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER,
CHAR_DEL_GUILD_BANK_EVENTLOG_BY_PLAYER,
CHAR_DEL_CHAR_GLYPHS,
@@ -1997,6 +1997,26 @@ void HotfixDatabaseConnection::DoPrepareStatements()
" WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_TRANSMOG_ILLUSION, "SELECT MAX(ID) + 1 FROM transmog_illusion", CONNECTION_SYNCH);
// TransmogOutfitEntry.db2
PrepareStatement(HOTFIX_SEL_TRANSMOG_OUTFIT_ENTRY, "SELECT Cost, Name, ID, OrderIndex, Source, Flags, SetType, OverrideCostModifier"
" FROM transmog_outfit_entry WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_TRANSMOG_OUTFIT_ENTRY, "SELECT MAX(ID) + 1 FROM transmog_outfit_entry", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_TRANSMOG_OUTFIT_ENTRY, "SELECT ID, Name_lang FROM transmog_outfit_entry_locale WHERE (`VerifiedBuild` > 0) = ?"
" AND locale = ?", CONNECTION_SYNCH);
// TransmogOutfitSlotInfo.db2
PrepareStatement(HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_INFO, "SELECT InventorySlotName, ID, TransmogOutfitSlotEnum, InventorySlotEnum, Flags, "
"Unused1200, TransmogCollectionType, SecondarySlotID, InventorySlotID, UnassignedAtlasID, UnassignedDisplayAtlasID, ItemCostMultiplier, "
"IllusionCostMultiplier FROM transmog_outfit_slot_info WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_INFO, "SELECT MAX(ID) + 1 FROM transmog_outfit_slot_info", CONNECTION_SYNCH);
// TransmogOutfitSlotOption.db2
PrepareStatement(HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_OPTION, "SELECT ID, Name, OptionEnum, TransmogOutfitSlotInfoID, Flags, SecondaryOptionID, "
"ItemCostMultiplier, IllusionCostMultiplier FROM transmog_outfit_slot_option WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_OPTION, "SELECT MAX(ID) + 1 FROM transmog_outfit_slot_option", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_OPTION, "SELECT ID, Name_lang FROM transmog_outfit_slot_option_locale"
" WHERE (`VerifiedBuild` > 0) = ? AND locale = ?", CONNECTION_SYNCH);
// TransmogSet.db2
PrepareStatement(HOTFIX_SEL_TRANSMOG_SET, "SELECT Name, ID, ClassMask, TrackingQuestID, Flags, TransmogSetGroupID, ItemNameDescriptionID, "
"ParentTransmogSetID, Unknown810, ExpansionID, PatchID, UiOrder, PlayerConditionID FROM transmog_set WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
@@ -2014,6 +2034,25 @@ void HotfixDatabaseConnection::DoPrepareStatements()
" WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_TRANSMOG_SET_ITEM, "SELECT MAX(ID) + 1 FROM transmog_set_item", CONNECTION_SYNCH);
// TransmogSituation.db2
PrepareStatement(HOTFIX_SEL_TRANSMOG_SITUATION, "SELECT Name, ID, SituationEnum, Flags, TransmogSituationGroupID, OrderIndex"
" FROM transmog_situation WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_TRANSMOG_SITUATION, "SELECT MAX(ID) + 1 FROM transmog_situation", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_TRANSMOG_SITUATION, "SELECT ID, Name_lang FROM transmog_situation_locale WHERE (`VerifiedBuild` > 0) = ?"
" AND locale = ?", CONNECTION_SYNCH);
// TransmogSituationGroup.db2
PrepareStatement(HOTFIX_SEL_TRANSMOG_SITUATION_GROUP, "SELECT ID, TransmogSituationTriggerID, OrderIndex, Flags FROM transmog_situation_group"
" WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_TRANSMOG_SITUATION_GROUP, "SELECT MAX(ID) + 1 FROM transmog_situation_group", CONNECTION_SYNCH);
// TransmogSituationTrigger.db2
PrepareStatement(HOTFIX_SEL_TRANSMOG_SITUATION_TRIGGER, "SELECT Name, Description, ID, TriggerEnum, Flags FROM transmog_situation_trigger"
" WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_TRANSMOG_SITUATION_TRIGGER, "SELECT MAX(ID) + 1 FROM transmog_situation_trigger", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_TRANSMOG_SITUATION_TRIGGER, "SELECT ID, Name_lang, Description_lang FROM transmog_situation_trigger_locale"
" WHERE (`VerifiedBuild` > 0) = ? AND locale = ?", CONNECTION_SYNCH);
// TransportAnimation.db2
PrepareStatement(HOTFIX_SEL_TRANSPORT_ANIMATION, "SELECT ID, PosX, PosY, PosZ, SequenceID, TimeIndex, TransportID FROM transport_animation"
" WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
@@ -1158,6 +1158,17 @@ enum HotfixDatabaseStatements : uint32
HOTFIX_SEL_TRANSMOG_ILLUSION,
HOTFIX_SEL_TRANSMOG_ILLUSION_MAX_ID,
HOTFIX_SEL_TRANSMOG_OUTFIT_ENTRY,
HOTFIX_SEL_TRANSMOG_OUTFIT_ENTRY_MAX_ID,
HOTFIX_SEL_TRANSMOG_OUTFIT_ENTRY_LOCALE,
HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_INFO,
HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_INFO_MAX_ID,
HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_OPTION,
HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_OPTION_MAX_ID,
HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_OPTION_LOCALE,
HOTFIX_SEL_TRANSMOG_SET,
HOTFIX_SEL_TRANSMOG_SET_MAX_ID,
HOTFIX_SEL_TRANSMOG_SET_LOCALE,
@@ -1169,6 +1180,17 @@ enum HotfixDatabaseStatements : uint32
HOTFIX_SEL_TRANSMOG_SET_ITEM,
HOTFIX_SEL_TRANSMOG_SET_ITEM_MAX_ID,
HOTFIX_SEL_TRANSMOG_SITUATION,
HOTFIX_SEL_TRANSMOG_SITUATION_MAX_ID,
HOTFIX_SEL_TRANSMOG_SITUATION_LOCALE,
HOTFIX_SEL_TRANSMOG_SITUATION_GROUP,
HOTFIX_SEL_TRANSMOG_SITUATION_GROUP_MAX_ID,
HOTFIX_SEL_TRANSMOG_SITUATION_TRIGGER,
HOTFIX_SEL_TRANSMOG_SITUATION_TRIGGER_MAX_ID,
HOTFIX_SEL_TRANSMOG_SITUATION_TRIGGER_LOCALE,
HOTFIX_SEL_TRANSPORT_ANIMATION,
HOTFIX_SEL_TRANSPORT_ANIMATION_MAX_ID,
@@ -191,6 +191,8 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_BNET_TRANSMOG_ILLUSIONS, "SELECT blobIndex, illusionMask FROM battlenet_account_transmog_illusions WHERE battlenetAccountId = ? ORDER BY blobIndex DESC", CONNECTION_ASYNC);
PrepareStatement(LOGIN_INS_BNET_TRANSMOG_ILLUSIONS, "INSERT INTO battlenet_account_transmog_illusions (battlenetAccountId, blobIndex, illusionMask) VALUES (?, ?, ?) "
"ON DUPLICATE KEY UPDATE illusionMask = illusionMask | VALUES(illusionMask)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_BNET_TRANSMOG_OUTFITS, "SELECT transmogOutfitId FROM battlenet_account_transmog_outfits WHERE battlenetAccountId = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_INS_BNET_TRANSMOG_OUTFITS, "INSERT IGNORE INTO battlenet_account_transmog_outfits (battlenetAccountId, transmogOutfitId) VALUES (?, ?)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_BNET_WARBAND_SCENES, "SELECT warbandSceneId, isFavorite, hasFanfare FROM battlenet_account_warband_scenes WHERE battlenetAccountId = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_INS_BNET_WARBAND_SCENE, "INSERT INTO battlenet_account_warband_scenes (battlenetAccountId, warbandSceneId, isFavorite, hasFanfare) VALUES (?, ?, ?, ?) "
"ON DUPLICATE KEY UPDATE isFavorite = VALUES(isFavorite)", CONNECTION_ASYNC);
@@ -176,6 +176,8 @@ enum LoginDatabaseStatements : uint32
LOGIN_DEL_BNET_ITEM_FAVORITE_APPEARANCE,
LOGIN_SEL_BNET_TRANSMOG_ILLUSIONS,
LOGIN_INS_BNET_TRANSMOG_ILLUSIONS,
LOGIN_SEL_BNET_TRANSMOG_OUTFITS,
LOGIN_INS_BNET_TRANSMOG_OUTFITS,
LOGIN_SEL_BNET_WARBAND_SCENES,
LOGIN_INS_BNET_WARBAND_SCENE,
LOGIN_UPD_BNET_WARBAND_SCENE,
@@ -3312,10 +3312,9 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
{
itemSubclass = itemTemplate->GetSubClass();
if (ItemModifiedAppearanceEntry const* itemModifiedAppearance = sDB2Manager.GetItemModifiedAppearance(visibleItem.ItemID, visibleItem.ItemAppearanceModID))
if (ItemModifiedAppearanceExtraEntry const* itemModifiedAppearaceExtra = sItemModifiedAppearanceExtraStore.LookupEntry(itemModifiedAppearance->ID))
if (itemModifiedAppearaceExtra->DisplayWeaponSubclassID > 0)
itemSubclass = itemModifiedAppearaceExtra->DisplayWeaponSubclassID;
if (ItemModifiedAppearanceExtraEntry const* itemModifiedAppearaceExtra = sItemModifiedAppearanceExtraStore.LookupEntry(visibleItem.ItemModifiedAppearanceID))
if (itemModifiedAppearaceExtra->DisplayWeaponSubclassID > 0)
itemSubclass = itemModifiedAppearaceExtra->DisplayWeaponSubclassID;
}
}
if (itemSubclass != reqValue)
@@ -3332,10 +3331,9 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
{
itemSubclass = itemTemplate->GetSubClass();
if (ItemModifiedAppearanceEntry const* itemModifiedAppearance = sDB2Manager.GetItemModifiedAppearance(visibleItem.ItemID, visibleItem.ItemAppearanceModID))
if (ItemModifiedAppearanceExtraEntry const* itemModifiedAppearaceExtra = sItemModifiedAppearanceExtraStore.LookupEntry(itemModifiedAppearance->ID))
if (itemModifiedAppearaceExtra->DisplayWeaponSubclassID > 0)
itemSubclass = itemModifiedAppearaceExtra->DisplayWeaponSubclassID;
if (ItemModifiedAppearanceExtraEntry const* itemModifiedAppearaceExtra = sItemModifiedAppearanceExtraStore.LookupEntry(visibleItem.ItemModifiedAppearanceID))
if (itemModifiedAppearaceExtra->DisplayWeaponSubclassID > 0)
itemSubclass = itemModifiedAppearaceExtra->DisplayWeaponSubclassID;
}
}
if (itemSubclass != reqValue)
+2 -1
View File
@@ -22,6 +22,7 @@
#include "ObjectMgr.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "TransmogMgr.h"
static constexpr char HYPERLINK_DATA_DELIMITER = ':';
@@ -527,7 +528,7 @@ bool Trinity::Hyperlinks::LinkTags::transmogillusion::StoreTo(SpellItemEnchantme
if (!t.TryConsumeTo(spellItemEnchantmentId))
return false;
return !!(val = sSpellItemEnchantmentStore.LookupEntry(spellItemEnchantmentId))
&& sDB2Manager.GetTransmogIllusionForEnchantment(spellItemEnchantmentId) && t.IsEmpty();
&& TransmogMgr::GetTransmogIllusionForSpellItemEnchantment(spellItemEnchantmentId) && t.IsEmpty();
}
bool Trinity::Hyperlinks::LinkTags::transmogset::StoreTo(TransmogSetEntry const*& val, std::string_view text)
+98
View File
@@ -6597,6 +6597,62 @@ struct TransmogIllusionLoadInfo
static constexpr DB2LoadInfo Instance{ Fields, 5, &TransmogIllusionMeta::Instance, HOTFIX_SEL_TRANSMOG_ILLUSION };
};
struct TransmogOutfitEntryLoadInfo
{
static constexpr DB2FieldMeta Fields[8] =
{
{.IsSigned = false, .Type = FT_LONG, .Name = "Cost" },
{.IsSigned = false, .Type = FT_STRING, .Name = "Name" },
{.IsSigned = false, .Type = FT_INT, .Name = "ID" },
{.IsSigned = true, .Type = FT_INT, .Name = "OrderIndex" },
{.IsSigned = false, .Type = FT_BYTE, .Name = "Source" },
{.IsSigned = true, .Type = FT_INT, .Name = "Flags" },
{.IsSigned = false, .Type = FT_BYTE, .Name = "SetType" },
{.IsSigned = false, .Type = FT_FLOAT, .Name = "OverrideCostModifier" },
};
static constexpr DB2LoadInfo Instance{ Fields, 8, &TransmogOutfitEntryMeta::Instance, HOTFIX_SEL_TRANSMOG_OUTFIT_ENTRY };
};
struct TransmogOutfitSlotInfoLoadInfo
{
static constexpr DB2FieldMeta Fields[13] =
{
{.IsSigned = false, .Type = FT_STRING_NOT_LOCALIZED, .Name = "InventorySlotName" },
{.IsSigned = false, .Type = FT_INT, .Name = "ID" },
{.IsSigned = true, .Type = FT_BYTE, .Name = "TransmogOutfitSlotEnum" },
{.IsSigned = true, .Type = FT_INT, .Name = "InventorySlotEnum" },
{.IsSigned = true, .Type = FT_INT, .Name = "Flags" },
{.IsSigned = false, .Type = FT_BYTE, .Name = "Unused1200" },
{.IsSigned = false, .Type = FT_BYTE, .Name = "TransmogCollectionType" },
{.IsSigned = true, .Type = FT_INT, .Name = "SecondarySlotID" },
{.IsSigned = true, .Type = FT_INT, .Name = "InventorySlotID" },
{.IsSigned = true, .Type = FT_INT, .Name = "UnassignedAtlasID" },
{.IsSigned = true, .Type = FT_INT, .Name = "UnassignedDisplayAtlasID" },
{.IsSigned = false, .Type = FT_FLOAT, .Name = "ItemCostMultiplier" },
{.IsSigned = false, .Type = FT_FLOAT, .Name = "IllusionCostMultiplier" },
};
static constexpr DB2LoadInfo Instance{ Fields, 13, &TransmogOutfitSlotInfoMeta::Instance, HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_INFO };
};
struct TransmogOutfitSlotOptionLoadInfo
{
static constexpr DB2FieldMeta Fields[8] =
{
{.IsSigned = false, .Type = FT_INT, .Name = "ID" },
{.IsSigned = false, .Type = FT_STRING, .Name = "Name" },
{.IsSigned = false, .Type = FT_BYTE, .Name = "OptionEnum" },
{.IsSigned = false, .Type = FT_INT, .Name = "TransmogOutfitSlotInfoID" },
{.IsSigned = true, .Type = FT_INT, .Name = "Flags" },
{.IsSigned = true, .Type = FT_INT, .Name = "SecondaryOptionID" },
{.IsSigned = false, .Type = FT_FLOAT, .Name = "ItemCostMultiplier" },
{.IsSigned = false, .Type = FT_FLOAT, .Name = "IllusionCostMultiplier" },
};
static constexpr DB2LoadInfo Instance{ Fields, 8, &TransmogOutfitSlotOptionMeta::Instance, HOTFIX_SEL_TRANSMOG_OUTFIT_SLOT_OPTION };
};
struct TransmogSetLoadInfo
{
static constexpr DB2FieldMeta Fields[13] =
@@ -6619,6 +6675,48 @@ struct TransmogSetLoadInfo
static constexpr DB2LoadInfo Instance{ Fields, 13, &TransmogSetMeta::Instance, HOTFIX_SEL_TRANSMOG_SET };
};
struct TransmogSituationLoadInfo
{
static constexpr DB2FieldMeta Fields[6] =
{
{.IsSigned = false, .Type = FT_STRING, .Name = "Name" },
{.IsSigned = false, .Type = FT_INT, .Name = "ID" },
{.IsSigned = true, .Type = FT_BYTE, .Name = "SituationEnum" },
{.IsSigned = true, .Type = FT_INT, .Name = "Flags" },
{.IsSigned = false, .Type = FT_INT, .Name = "TransmogSituationGroupID" },
{.IsSigned = true, .Type = FT_INT, .Name = "OrderIndex" },
};
static constexpr DB2LoadInfo Instance{ Fields, 6, &TransmogSituationMeta::Instance, HOTFIX_SEL_TRANSMOG_SITUATION };
};
struct TransmogSituationGroupLoadInfo
{
static constexpr DB2FieldMeta Fields[4] =
{
{.IsSigned = false, .Type = FT_INT, .Name = "ID" },
{.IsSigned = false, .Type = FT_INT, .Name = "TransmogSituationTriggerID" },
{.IsSigned = true, .Type = FT_INT, .Name = "OrderIndex" },
{.IsSigned = true, .Type = FT_INT, .Name = "Flags" },
};
static constexpr DB2LoadInfo Instance{ Fields, 4, &TransmogSituationGroupMeta::Instance, HOTFIX_SEL_TRANSMOG_SITUATION_GROUP };
};
struct TransmogSituationTriggerLoadInfo
{
static constexpr DB2FieldMeta Fields[5] =
{
{.IsSigned = false, .Type = FT_STRING, .Name = "Name" },
{.IsSigned = false, .Type = FT_STRING, .Name = "Description" },
{.IsSigned = false, .Type = FT_INT, .Name = "ID" },
{.IsSigned = false, .Type = FT_BYTE, .Name = "TriggerEnum" },
{.IsSigned = true, .Type = FT_INT, .Name = "Flags" },
};
static constexpr DB2LoadInfo Instance{ Fields, 5, &TransmogSituationTriggerMeta::Instance, HOTFIX_SEL_TRANSMOG_SITUATION_TRIGGER };
};
struct TransmogSetGroupLoadInfo
{
static constexpr DB2FieldMeta Fields[2] =
+12 -70
View File
@@ -383,6 +383,12 @@ DB2Storage<TraitTreeXTraitCostEntry> sTraitTreeXTraitCostStore("Trait
DB2Storage<TraitTreeXTraitCurrencyEntry> sTraitTreeXTraitCurrencyStore("TraitTreeXTraitCurrency.db2", &TraitTreeXTraitCurrencyLoadInfo::Instance);
DB2Storage<TransmogHolidayEntry> sTransmogHolidayStore("TransmogHoliday.db2", &TransmogHolidayLoadInfo::Instance);
DB2Storage<TransmogIllusionEntry> sTransmogIllusionStore("TransmogIllusion.db2", &TransmogIllusionLoadInfo::Instance);
DB2Storage<TransmogOutfitEntryEntry> sTransmogOutfitEntryStore("TransmogOutfitEntry.db2", &TransmogOutfitEntryLoadInfo::Instance);
DB2Storage<TransmogOutfitSlotInfoEntry> sTransmogOutfitSlotInfoStore("TransmogOutfitSlotInfo.db2", &TransmogOutfitSlotInfoLoadInfo::Instance);
DB2Storage<TransmogOutfitSlotOptionEntry> sTransmogOutfitSlotOptionInfoStore("TransmogOutfitSlotOption.db2", &TransmogOutfitSlotOptionLoadInfo::Instance);
DB2Storage<TransmogSituationEntry> sTransmogSituationStore("TransmogSituation.db2", &TransmogSituationLoadInfo::Instance);
DB2Storage<TransmogSituationGroupEntry> sTransmogSituationGroupStore("TransmogSituationGroup.db2", &TransmogSituationGroupLoadInfo::Instance);
DB2Storage<TransmogSituationTriggerEntry> sTransmogSituationTriggerStore("TransmogSituationTrigger.db2", &TransmogSituationTriggerLoadInfo::Instance);
DB2Storage<TransmogSetEntry> sTransmogSetStore("TransmogSet.db2", &TransmogSetLoadInfo::Instance);
DB2Storage<TransmogSetGroupEntry> sTransmogSetGroupStore("TransmogSetGroup.db2", &TransmogSetGroupLoadInfo::Instance);
DB2Storage<TransmogSetItemEntry> sTransmogSetItemStore("TransmogSetItem.db2", &TransmogSetItemLoadInfo::Instance);
@@ -526,7 +532,6 @@ typedef std::unordered_map<uint32 /*glyphPropertiesId*/, std::vector<ChrSpeciali
typedef std::unordered_map<uint32 /*itemId*/, ItemChildEquipmentEntry const*> ItemChildEquipmentContainer;
typedef std::array<ItemClassEntry const*, 21> ItemClassByOldEnumContainer;
typedef std::unordered_map<uint32, std::vector<ItemLimitCategoryConditionEntry const*>> ItemLimitCategoryConditionContainer;
typedef std::unordered_map<uint32 /*itemId | appearanceMod << 24*/, ItemModifiedAppearanceEntry const*> ItemModifiedAppearanceByItemContainer;
typedef std::unordered_map<uint32, std::vector<ItemSetSpellEntry const*>> ItemSetSpellContainer;
typedef std::unordered_map<uint32, std::vector<ItemSpecOverrideEntry const*>> ItemSpecOverridesContainer;
typedef std::unordered_map<uint32, std::unordered_map<uint32, MapDifficultyEntry const*>> MapDifficultyContainer;
@@ -606,7 +611,6 @@ namespace
ItemClassByOldEnumContainer _itemClassByOldEnum;
std::unordered_set<uint32> _itemsWithCurrencyCost;
ItemLimitCategoryConditionContainer _itemCategoryConditions;
ItemModifiedAppearanceByItemContainer _itemModifiedAppearancesByItem;
ItemSetSpellContainer _itemSetSpells;
ItemSpecOverridesContainer _itemSpecOverrides;
std::vector<JournalTierEntry const*> _journalTiersByIndex;
@@ -637,9 +641,6 @@ namespace
TalentsByPosition _talentsByPosition;
std::unordered_map<std::pair<uint32, uint32>, TaxiPathEntry const*> _taxiPaths;
ToyItemIdsContainer _toys;
std::unordered_map<uint32, TransmogIllusionEntry const*> _transmogIllusionsByEnchantmentId;
std::unordered_map<uint32, std::vector<TransmogSetEntry const*>> _transmogSetsByItemModifiedAppearance;
std::unordered_map<uint32, std::vector<TransmogSetItemEntry const*>> _transmogSetItemsByTransmogSet;
std::unordered_map<int32, UiMapBounds> _uiMapBounds;
std::unordered_multimap<int32, UiMapAssignmentEntry const*> _uiMapAssignmentByMap[MAX_UI_MAP_SYSTEM];
std::unordered_multimap<int32, UiMapAssignmentEntry const*> _uiMapAssignmentByArea[MAX_UI_MAP_SYSTEM];
@@ -1120,6 +1121,12 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
LOAD_DB2(sTraitTreeXTraitCurrencyStore);
LOAD_DB2(sTransmogHolidayStore);
LOAD_DB2(sTransmogIllusionStore);
LOAD_DB2(sTransmogOutfitEntryStore);
LOAD_DB2(sTransmogOutfitSlotInfoStore);
LOAD_DB2(sTransmogOutfitSlotOptionInfoStore);
LOAD_DB2(sTransmogSituationStore);
LOAD_DB2(sTransmogSituationGroupStore);
LOAD_DB2(sTransmogSituationTriggerStore);
LOAD_DB2(sTransmogSetStore);
LOAD_DB2(sTransmogSetGroupStore);
LOAD_DB2(sTransmogSetItemStore);
@@ -1565,12 +1572,6 @@ void DB2Manager::IndexLoadedStores()
for (ItemLimitCategoryConditionEntry const* condition : sItemLimitCategoryConditionStore)
_itemCategoryConditions[condition->ParentItemLimitCategoryID].push_back(condition);
for (ItemModifiedAppearanceEntry const* appearanceMod : sItemModifiedAppearanceStore)
{
ASSERT(appearanceMod->ItemID <= 0xFFFFFF);
_itemModifiedAppearancesByItem[appearanceMod->ItemID | (appearanceMod->ItemAppearanceModifierID << 24)] = appearanceMod;
}
for (ItemSetSpellEntry const* itemSetSpell : sItemSetSpellStore)
_itemSetSpells[itemSetSpell->ItemSetID].push_back(itemSetSpell);
@@ -1782,19 +1783,6 @@ void DB2Manager::IndexLoadedStores()
for (ToyEntry const* toy : sToyStore)
_toys.insert(toy->ItemID);
for (TransmogIllusionEntry const* transmogIllusion : sTransmogIllusionStore)
_transmogIllusionsByEnchantmentId[transmogIllusion->SpellItemEnchantmentID] = transmogIllusion;
for (TransmogSetItemEntry const* transmogSetItem : sTransmogSetItemStore)
{
TransmogSetEntry const* set = sTransmogSetStore.LookupEntry(transmogSetItem->TransmogSetID);
if (!set)
continue;
_transmogSetsByItemModifiedAppearance[transmogSetItem->ItemModifiedAppearanceID].push_back(set);
_transmogSetItemsByTransmogSet[transmogSetItem->TransmogSetID].push_back(transmogSetItem);
}
//WowCommunity
for (UiChromieTimeExpansionInfoEntry const* uiChromieTimeExpansion : sUiChromieTimeExpansionInfoStore)
_chromieTimeExpansionInfo.emplace(uiChromieTimeExpansion->ID, uiChromieTimeExpansion);
@@ -2864,37 +2852,6 @@ std::vector<ItemLimitCategoryConditionEntry const*> const* DB2Manager::GetItemLi
return Trinity::Containers::MapGetValuePtr(_itemCategoryConditions, categoryId);
}
uint32 DB2Manager::GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const
{
if (ItemModifiedAppearanceEntry const* modifiedAppearance = GetItemModifiedAppearance(itemId, appearanceModId))
if (ItemAppearanceEntry const* itemAppearance = sItemAppearanceStore.LookupEntry(modifiedAppearance->ItemAppearanceID))
return itemAppearance->ItemDisplayInfoID;
return 0;
}
ItemModifiedAppearanceEntry const* DB2Manager::GetItemModifiedAppearance(uint32 itemId, uint32 appearanceModId) const
{
auto itr = _itemModifiedAppearancesByItem.find(itemId | (appearanceModId << 24));
if (itr != _itemModifiedAppearancesByItem.end())
return itr->second;
// Fall back to unmodified appearance
if (appearanceModId)
{
itr = _itemModifiedAppearancesByItem.find(itemId);
if (itr != _itemModifiedAppearancesByItem.end())
return itr->second;
}
return nullptr;
}
ItemModifiedAppearanceEntry const* DB2Manager::GetDefaultItemModifiedAppearance(uint32 itemId) const
{
return Trinity::Containers::MapGetValuePtr(_itemModifiedAppearancesByItem, itemId);
}
std::vector<ItemSetSpellEntry const*> const* DB2Manager::GetItemSetSpells(uint32 itemSetId) const
{
return Trinity::Containers::MapGetValuePtr(_itemSetSpells, itemSetId);
@@ -3331,21 +3288,6 @@ bool DB2Manager::IsToyItem(uint32 toy) const
return _toys.count(toy) > 0;
}
TransmogIllusionEntry const* DB2Manager::GetTransmogIllusionForEnchantment(uint32 spellItemEnchantmentId) const
{
return Trinity::Containers::MapGetValuePtr(_transmogIllusionsByEnchantmentId, spellItemEnchantmentId);
}
std::vector<TransmogSetEntry const*> const* DB2Manager::GetTransmogSetsForItemModifiedAppearance(uint32 itemModifiedAppearanceId) const
{
return Trinity::Containers::MapGetValuePtr(_transmogSetsByItemModifiedAppearance, itemModifiedAppearanceId);
}
std::vector<TransmogSetItemEntry const*> const* DB2Manager::GetTransmogSetItems(uint32 transmogSetId) const
{
return Trinity::Containers::MapGetValuePtr(_transmogSetItemsByTransmogSet, transmogSetId);
}
struct UiMapAssignmentStatus
{
UiMapAssignmentEntry const* UiMapAssignment = nullptr;
+6 -6
View File
@@ -307,6 +307,12 @@ TC_GAME_API extern DB2Storage<TraitTreeXTraitCostEntry> sTraitTreeXT
TC_GAME_API extern DB2Storage<TraitTreeXTraitCurrencyEntry> sTraitTreeXTraitCurrencyStore;
TC_GAME_API extern DB2Storage<TransmogHolidayEntry> sTransmogHolidayStore;
TC_GAME_API extern DB2Storage<TransmogIllusionEntry> sTransmogIllusionStore;
TC_GAME_API extern DB2Storage<TransmogOutfitEntryEntry> sTransmogOutfitEntryStore;
TC_GAME_API extern DB2Storage<TransmogOutfitSlotInfoEntry> sTransmogOutfitSlotInfoStore;
TC_GAME_API extern DB2Storage<TransmogOutfitSlotOptionEntry> sTransmogOutfitSlotOptionInfoStore;
TC_GAME_API extern DB2Storage<TransmogSituationEntry> sTransmogSituationStore;
TC_GAME_API extern DB2Storage<TransmogSituationGroupEntry> sTransmogSituationGroupStore;
TC_GAME_API extern DB2Storage<TransmogSituationTriggerEntry> sTransmogSituationTriggerStore;
TC_GAME_API extern DB2Storage<TransmogSetEntry> sTransmogSetStore;
TC_GAME_API extern DB2Storage<TransmogSetGroupEntry> sTransmogSetGroupStore;
TC_GAME_API extern DB2Storage<TransmogSetItemEntry> sTransmogSetItemStore;
@@ -601,9 +607,6 @@ public:
ItemClassEntry const* GetItemClassByOldEnum(uint32 itemClass) const;
bool HasItemCurrencyCost(uint32 itemId) const;
std::vector<ItemLimitCategoryConditionEntry const*> const* GetItemLimitCategoryConditions(uint32 categoryId) const;
uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const;
ItemModifiedAppearanceEntry const* GetItemModifiedAppearance(uint32 itemId, uint32 appearanceModId) const;
ItemModifiedAppearanceEntry const* GetDefaultItemModifiedAppearance(uint32 itemId) const;
std::vector<ItemSetSpellEntry const*> const* GetItemSetSpells(uint32 itemSetId) const;
std::vector<ItemSpecOverrideEntry const*> const* GetItemSpecOverrides(uint32 itemId) const;
JournalTierEntry const* GetJournalTier(uint32 index) const;
@@ -650,9 +653,6 @@ public:
TaxiPathEntry const* GetTaxiPath(uint32 from, uint32 to) const;
static bool IsTotemCategoryCompatibleWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId, bool requireAllTotems = true);
bool IsToyItem(uint32 toy) const;
TransmogIllusionEntry const* GetTransmogIllusionForEnchantment(uint32 spellItemEnchantmentId) const;
std::vector<TransmogSetEntry const*> const* GetTransmogSetsForItemModifiedAppearance(uint32 itemModifiedAppearanceId) const;
std::vector<TransmogSetItemEntry const*> const* GetTransmogSetItems(uint32 transmogSetId) const;
static bool GetUiMapPosition(float x, float y, float z, int32 mapId, int32 areaId, int32 wmoDoodadPlacementId, int32 wmoGroupId, UiMapSystem system, bool local,
uint32* uiMapId = nullptr, DBCPosition2D* newPos = nullptr);
bool Zone2MapCoordinates(uint32 areaId, float& x, float& y) const;
+84
View File
@@ -4721,6 +4721,57 @@ struct TransmogIllusionEntry
EnumFlag<TransmogIllusionFlags> GetFlags() const { return static_cast<TransmogIllusionFlags>(Flags); }
};
struct TransmogOutfitEntryEntry
{
uint64 Cost;
LocalizedString Name;
uint32 ID;
int32 OrderIndex;
uint8 Source;
int32 Flags;
uint8 SetType;
float OverrideCostModifier;
TransmogOutfitEntrySource GetSource() const { return static_cast<TransmogOutfitEntrySource>(Source); }
bool HasFlag(TransmogOutfitEntryFlags flag) const { return EnumFlag(static_cast<TransmogOutfitEntryFlags>(Flags)).HasFlag(flag); }
TransmogOutfitSetType GetSetType() const { return static_cast<TransmogOutfitSetType>(SetType); }
};
struct TransmogOutfitSlotInfoEntry
{
char const* InventorySlotName;
uint32 ID;
int8 TransmogOutfitSlotEnum;
int32 InventorySlotEnum;
int32 Flags;
uint8 Unused1200;
uint8 TransmogCollectionType;
int32 SecondarySlotID;
int32 InventorySlotID;
int32 UnassignedAtlasID;
int32 UnassignedDisplayAtlasID;
float ItemCostMultiplier;
float IllusionCostMultiplier;
TransmogOutfitSlot GetSlot() const { return static_cast<TransmogOutfitSlot>(TransmogOutfitSlotEnum); }
bool HasFlag(TransmogOutfitSlotFlags flag) const { return EnumFlag(static_cast<TransmogOutfitSlotFlags>(Flags)).HasFlag(flag); }
};
struct TransmogOutfitSlotOptionEntry
{
uint32 ID;
LocalizedString Name;
uint8 OptionEnum;
uint32 TransmogOutfitSlotInfoID;
int32 Flags;
int32 SecondaryOptionID;
float ItemCostMultiplier;
float IllusionCostMultiplier;
TransmogOutfitSlotOption GetOption() const { return static_cast<TransmogOutfitSlotOption>(OptionEnum); }
bool HasFlag(TransmogOutfitSlotOptionFlags flag) const { return EnumFlag(static_cast<TransmogOutfitSlotOptionFlags>(Flags)).HasFlag(flag); }
};
struct TransmogSetEntry
{
LocalizedString Name;
@@ -4752,6 +4803,39 @@ struct TransmogSetItemEntry
int32 Flags;
};
struct TransmogSituationEntry
{
LocalizedString Name;
uint32 ID;
int8 SituationEnum;
int32 Flags;
uint32 TransmogSituationGroupID;
int32 OrderIndex;
TransmogSituation GetSituation() const { return static_cast<TransmogSituation>(SituationEnum); }
bool HasFlag(TransmogSituationFlags flag) const { return EnumFlag(static_cast<TransmogSituationFlags>(Flags)).HasFlag(flag); }
};
struct TransmogSituationGroupEntry
{
uint32 ID;
uint32 TransmogSituationTriggerID;
int32 OrderIndex;
int32 Flags;
};
struct TransmogSituationTriggerEntry
{
LocalizedString Name;
LocalizedString Description;
uint32 ID;
uint8 TriggerEnum;
int32 Flags;
TransmogSituationTrigger GetTrigger() const { return static_cast<TransmogSituationTrigger>(TriggerEnum); }
bool HasFlag(TransmogSituationTriggerFlags flag) const { return EnumFlag(static_cast<TransmogSituationTriggerFlags>(Flags)).HasFlag(flag); }
};
struct TransportAnimationEntry
{
uint32 ID;
+174
View File
@@ -2520,6 +2520,180 @@ enum class TransmogIllusionFlags : int32
DEFINE_ENUM_FLAG(TransmogIllusionFlags);
enum class TransmogOutfitDisplayType : uint8
{
Unassigned = 0,
Assigned = 1,
Equipped = 2,
Hidden = 3,
Disabled = 4,
Max
};
enum class TransmogOutfitEquipAction : uint8
{
Equip = 0,
EquipAndLock = 1,
Remove = 2,
RemoveAndLock = 3,
Unlock = 4,
Lock = 5,
};
enum class TransmogOutfitEntryFlags : int32
{
AutomaticallyAwardedOnLogin = 0x01,
UseOverrideName = 0x02,
OnlyAvailableDuringEvent = 0x04,
SortedToTopOfList = 0x08,
UseOverrideCostModifier = 0x10,
IsDefaultEquipped = 0x20
};
DEFINE_ENUM_FLAG(TransmogOutfitEntryFlags);
enum class TransmogOutfitEntrySource : uint8
{
StampedSource = 0,
AutomaticallyAwarded = 1,
PlayerPurchased = 2,
Max
};
enum class TransmogOutfitSetType : uint8
{
Equipped = 0,
Outfit = 1,
CustomSet = 2
};
enum class TransmogOutfitSlot : int8
{
Head = 0,
ShoulderRight = 1,
ShoulderLeft = 2,
Back = 3,
Chest = 4,
Tabard = 5,
Body = 6,
Wrist = 7,
Hand = 8,
Waist = 9,
Legs = 10,
Feet = 11,
WeaponMainHand = 12,
WeaponOffHand = 13,
WeaponRanged = 14,
Max
};
enum class TransmogOutfitSlotFlags : int32
{
CannotBeHidden = 0x01,
CanHaveIllusions = 0x02,
IsSecondarySlot = 0x04
};
DEFINE_ENUM_FLAG(TransmogOutfitSlotFlags);
enum class TransmogOutfitSlotOption : uint8
{
None = 0,
OneHandedWeapon = 1,
TwoHandedWeapon = 2,
RangedWeapon = 3,
OffHand = 4,
Shield = 5,
DeprecatedReuseMe = 6,
FuryTwoHandedWeapon = 7,
ArtifactSpecOne = 8,
ArtifactSpecTwo = 9,
ArtifactSpecThree = 10,
ArtifactSpecFour = 11,
Max
};
enum class TransmogOutfitSlotOptionFlags : int32
{
IllusionNotAllowed = 0x01,
DynamicOptionName = 0x02,
DisablesOffhandSlot = 0x04
};
DEFINE_ENUM_FLAG(TransmogOutfitSlotOptionFlags);
enum class TransmogSituation : int8
{
AllSpecs = 0,
Spec = 1,
AllLocations = 2,
LocationRested = 3,
LocationHouse = 4,
LocationCharacterSelect = 5,
LocationWorld = 6,
LocationDelves = 7,
LocationDungeons = 8,
LocationRaids = 9,
LocationArenas = 10,
LocationBattlegrounds = 11,
AllMovement = 12,
MovementUnmounted = 13,
MovementSwimming = 14,
MovementGroundMount = 15,
MovementFlyingMount = 16,
AllEquipmentSets = 17,
EquipmentSets = 18,
AllRacialForms = 19,
FormNative = 20,
FormNonNative = 21,
Max
};
enum class TransmogSituationFlags : int32
{
IsPlayerFacing = 0x01,
SpecUseTalentLoadout = 0x02,
AllSituation = 0x04,
DefaultsToOn = 0x08,
DynamicallyNamed = 0x10,
NoneSituation = 0x20,
DisabledSituation = 0x40
};
DEFINE_ENUM_FLAG(TransmogSituationFlags);
enum class TransmogSituationTrigger : uint8
{
None = 0,
Manual = 1,
TransmogUpdate = 2,
Location = 3,
Movement = 4,
Specialization = 5,
EquipmentSet = 6,
Forms = 7,
EventOutfit = 8,
Max
};
enum class TransmogSituationTriggerFlags : int32
{
CanLockOutfit = 0x01,
CanChangeLockedOutfit = 0x02,
IsPlayerFacing = 0x04,
SituationsAreExclusive = 0x08,
DisabledTrigger = 0x10
};
DEFINE_ENUM_FLAG(TransmogSituationTriggerFlags);
// SummonProperties.dbc, col 1
enum SummonPropGroup
{
+10 -51
View File
@@ -46,6 +46,7 @@
#include "SpellMgr.h"
#include "StringConvert.h"
#include "TradeData.h"
#include "TransmogMgr.h"
#include "UpdateData.h"
#include "World.h"
#ifdef ELUNA
@@ -2012,52 +2013,6 @@ bool Item::IsValidTransmogrificationTarget() const
return true;
}
enum class ItemTransmogrificationWeaponCategory : uint8
{
// Two-handed
MELEE_2H,
RANGED,
// One-handed
AXE_MACE_SWORD_1H,
DAGGER,
INVALID
};
static ItemTransmogrificationWeaponCategory GetTransmogrificationWeaponCategory(ItemTemplate const* proto)
{
if (proto->GetClass() == ITEM_CLASS_WEAPON)
{
switch (proto->GetSubClass())
{
case ITEM_SUBCLASS_WEAPON_AXE2:
case ITEM_SUBCLASS_WEAPON_MACE2:
case ITEM_SUBCLASS_WEAPON_SWORD2:
case ITEM_SUBCLASS_WEAPON_STAFF:
case ITEM_SUBCLASS_WEAPON_POLEARM:
return ItemTransmogrificationWeaponCategory::MELEE_2H;
case ITEM_SUBCLASS_WEAPON_BOW:
case ITEM_SUBCLASS_WEAPON_GUN:
case ITEM_SUBCLASS_WEAPON_CROSSBOW:
return ItemTransmogrificationWeaponCategory::RANGED;
case ITEM_SUBCLASS_WEAPON_AXE:
case ITEM_SUBCLASS_WEAPON_MACE:
case ITEM_SUBCLASS_WEAPON_SWORD:
case ITEM_SUBCLASS_WEAPON_WARGLAIVES:
case ITEM_SUBCLASS_WEAPON_FIST_WEAPON:
return ItemTransmogrificationWeaponCategory::AXE_MACE_SWORD_1H;
case ITEM_SUBCLASS_WEAPON_DAGGER:
return ItemTransmogrificationWeaponCategory::DAGGER;
default:
break;
}
}
return ItemTransmogrificationWeaponCategory::INVALID;
}
int32 const ItemTransmogrificationSlots[MAX_INVTYPE] =
{
-1, // INVTYPE_NON_EQUIP
@@ -2127,7 +2082,7 @@ bool Item::CanTransmogrifyItemWithItem(Item const* item, ItemModifiedAppearanceE
switch (source->GetClass())
{
case ITEM_CLASS_WEAPON:
if (GetTransmogrificationWeaponCategory(source) != GetTransmogrificationWeaponCategory(target))
if (source->GetWeaponTransmogOutfitSlotOption() != target->GetWeaponTransmogOutfitSlotOption())
return false;
break;
case ITEM_CLASS_ARMOR:
@@ -2496,16 +2451,20 @@ uint32 Item::GetDisplayId(Player const* owner) const
if (!itemModifiedAppearanceId)
itemModifiedAppearanceId = GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS);
if (ItemModifiedAppearanceEntry const* transmog = sItemModifiedAppearanceStore.LookupEntry(itemModifiedAppearanceId))
if (ItemAppearanceEntry const* itemAppearance = sItemAppearanceStore.LookupEntry(transmog->ItemAppearanceID))
ItemModifiedAppearanceEntry const* itemModifiedAppearance = sItemModifiedAppearanceStore.LookupEntry(itemModifiedAppearanceId);
if (!itemModifiedAppearance)
itemModifiedAppearance = GetItemModifiedAppearance();
if (itemModifiedAppearance)
if (ItemAppearanceEntry const* itemAppearance = sItemAppearanceStore.LookupEntry(itemModifiedAppearance->ItemAppearanceID))
return itemAppearance->ItemDisplayInfoID;
return sDB2Manager.GetItemDisplayId(GetEntry(), GetAppearanceModId());
return 0;
}
ItemModifiedAppearanceEntry const* Item::GetItemModifiedAppearance() const
{
return sDB2Manager.GetItemModifiedAppearance(GetEntry(), _bonusData.AppearanceModID);
return TransmogMgr::GetItemModifiedAppearance(GetEntry(), _bonusData.AppearanceModID);
}
uint32 Item::GetModifier(ItemModifier modifier) const
@@ -297,3 +297,50 @@ std::size_t ItemTemplate::CalculateItemSpecBit(ChrSpecializationEntry const* spe
{
return (spec->ClassID - 1) * MAX_SPECIALIZATIONS + spec->OrderIndex;
}
TransmogOutfitSlotOption ItemTemplate::GetWeaponTransmogOutfitSlotOption() const
{
switch (GetClass())
{
case ITEM_CLASS_WEAPON:
switch (GetSubClass())
{
case ITEM_SUBCLASS_WEAPON_AXE2:
case ITEM_SUBCLASS_WEAPON_MACE2:
case ITEM_SUBCLASS_WEAPON_SWORD2:
case ITEM_SUBCLASS_WEAPON_STAFF:
case ITEM_SUBCLASS_WEAPON_POLEARM:
return TransmogOutfitSlotOption::TwoHandedWeapon;
case ITEM_SUBCLASS_WEAPON_BOW:
case ITEM_SUBCLASS_WEAPON_GUN:
case ITEM_SUBCLASS_WEAPON_CROSSBOW:
return TransmogOutfitSlotOption::RangedWeapon;
case ITEM_SUBCLASS_WEAPON_AXE:
case ITEM_SUBCLASS_WEAPON_MACE:
case ITEM_SUBCLASS_WEAPON_SWORD:
case ITEM_SUBCLASS_WEAPON_WARGLAIVES:
case ITEM_SUBCLASS_WEAPON_FIST_WEAPON:
case ITEM_SUBCLASS_WEAPON_DAGGER:
return TransmogOutfitSlotOption::OneHandedWeapon;
default:
break;
}
break;
case ITEM_CLASS_ARMOR:
switch (GetInventoryType())
{
case INVTYPE_SHIELD:
return TransmogOutfitSlotOption::Shield;
case INVTYPE_HOLDABLE:
return TransmogOutfitSlotOption::OffHand;
default:
break;
}
break;
default:
break;
}
return TransmogOutfitSlotOption::None;
}
@@ -967,6 +967,7 @@ struct TC_GAME_API ItemTemplate
void GetDamage(uint32 itemLevel, float& minDamage, float& maxDamage) const;
bool IsUsableByLootSpecialization(Player const* player, bool alwaysAllowBoundToAccount) const;
static std::size_t CalculateItemSpecBit(ChrSpecializationEntry const* spec);
TransmogOutfitSlotOption GetWeaponTransmogOutfitSlotOption() const;
};
#endif
@@ -882,7 +882,7 @@ namespace UF
data << uint16(ItemAppearanceModID);
data << uint16(ItemVisual);
data << uint32(ItemModifiedAppearanceID);
data << uint8(Field_18);
data << uint8(TransmogSlotOption);
data.WriteBit(HasTransmog);
data.WriteBit(HasIllusion);
data.FlushBits();
@@ -936,7 +936,7 @@ namespace UF
}
if (changesMask[9])
{
data << uint8(Field_18);
data << uint8(TransmogSlotOption);
}
}
data.FlushBits();
@@ -952,7 +952,7 @@ namespace UF
Base::ClearChangesMask(ItemAppearanceModID);
Base::ClearChangesMask(ItemVisual);
Base::ClearChangesMask(ItemModifiedAppearanceID);
Base::ClearChangesMask(Field_18);
Base::ClearChangesMask(TransmogSlotOption);
_changesMask.ResetAll();
}
@@ -5444,7 +5444,7 @@ namespace UF
data << uint32(HouseThemes.size());
data << uint32(HouseRoomComponentTextures.size());
data << uint32(HouseTypes.size());
data << uint32(Field_1980.size());
data << uint32(UnlockedTransmogOutfits.size());
data << uint32(CharacterRestrictions.size());
data << uint32(SpellPctModByLabel.size());
data << uint32(SpellFlatModByLabel.size());
@@ -5563,9 +5563,9 @@ namespace UF
{
data << uint32(HouseTypes[i]);
}
for (uint32 i = 0; i < Field_1980.size(); ++i)
for (uint32 i = 0; i < UnlockedTransmogOutfits.size(); ++i)
{
data << int32(Field_1980[i]);
data << int32(UnlockedTransmogOutfits[i]);
}
for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i)
{
@@ -5979,9 +5979,9 @@ namespace UF
if (changesMask[29])
{
if (!ignoreNestedChangesMask)
Field_1980.WriteUpdateMask(data);
UnlockedTransmogOutfits.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(Field_1980.size(), data);
WriteCompleteDynamicFieldUpdateMask(UnlockedTransmogOutfits.size(), data);
}
if (changesMask[30])
{
@@ -6321,11 +6321,11 @@ namespace UF
}
if (changesMask[29])
{
for (uint32 i = 0; i < Field_1980.size(); ++i)
for (uint32 i = 0; i < UnlockedTransmogOutfits.size(); ++i)
{
if (Field_1980.HasChanged(i) || ignoreNestedChangesMask)
if (UnlockedTransmogOutfits.HasChanged(i) || ignoreNestedChangesMask)
{
data << int32(Field_1980[i]);
data << int32(UnlockedTransmogOutfits[i]);
}
}
}
@@ -7158,7 +7158,7 @@ namespace UF
Base::ClearChangesMask(HouseThemes);
Base::ClearChangesMask(HouseRoomComponentTextures);
Base::ClearChangesMask(HouseTypes);
Base::ClearChangesMask(Field_1980);
Base::ClearChangesMask(UnlockedTransmogOutfits);
Base::ClearChangesMask(SpellPctModByLabel);
Base::ClearChangesMask(SpellFlatModByLabel);
Base::ClearChangesMask(SpellPctModPVPByLabel);
@@ -262,7 +262,7 @@ struct VisibleItem : public IsUpdateFieldStructureTag, public HasChangesMask<10>
UpdateField<uint16, 0, 6> ItemAppearanceModID;
UpdateField<uint16, 0, 7> ItemVisual;
UpdateField<uint32, 0, 8> ItemModifiedAppearanceID;
UpdateField<uint8, 0, 9> Field_18;
UpdateField<uint8, 0, 9> TransmogSlotOption;
using OwnerObject = Unit;
void WriteCreate(ByteBuffer& data, Player const* receiver, Unit const* owner) const;
@@ -1311,7 +1311,7 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas
DynamicUpdateField<uint32, 0, 26> HouseThemes;
DynamicUpdateField<uint32, 0, 27> HouseRoomComponentTextures;
DynamicUpdateField<uint32, 0, 28> HouseTypes;
DynamicUpdateField<int32, 0, 29> Field_1980;
DynamicUpdateField<int32, 0, 29> UnlockedTransmogOutfits;
DynamicUpdateField<UF::SpellPctModByLabel, 0, 31> SpellPctModByLabel;
DynamicUpdateField<UF::SpellFlatModByLabel, 32, 33> SpellFlatModByLabel;
DynamicUpdateField<UF::SpellPctPVPModByLabel, 32, 34> SpellPctModPVPByLabel;
+198 -132
View File
@@ -26,6 +26,7 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "Timer.h"
#include "TransmogMgr.h"
#include "TransmogrificationPackets.h"
#include "WorldSession.h"
#include <boost/dynamic_bitset.hpp>
@@ -95,12 +96,36 @@ namespace
}
}
CollectionMgr::CollectionMgr(WorldSession* owner) : _owner(owner), _appearances(std::make_unique<boost::dynamic_bitset<uint32>>()), _transmogIllusions(std::make_unique<boost::dynamic_bitset<uint32>>())
CollectionMgr::CollectionMgr(WorldSession* owner) : _owner(owner),
_appearances(std::make_unique<boost::dynamic_bitset<uint32>>()),
_transmogIllusions(std::make_unique<boost::dynamic_bitset<uint32>>())
{
}
CollectionMgr::~CollectionMgr() = default;
void CollectionMgr::LoadCharacterData()
{
LoadToys();
LoadHeirlooms();
LoadMounts();
LoadItemAppearances();
LoadTransmogIllusions();
LoadTransmogOutfits();
LoadWarbandScenes();
}
void CollectionMgr::SaveToDB(LoginDatabaseTransaction trans)
{
SaveAccountToys(trans);
SaveAccountHeirlooms(trans);
SaveAccountMounts(trans);
SaveAccountItemAppearances(trans);
SaveAccountTransmogIllusions(trans);
SaveAccountTransmogOutfits(trans);
SaveAccountWarbandScenes(trans);
}
void CollectionMgr::LoadToys()
{
for (auto const& [itemId, flags] : _toys)
@@ -168,7 +193,7 @@ void CollectionMgr::ToyClearFanfare(uint32 itemId)
if (itr == _toys.end())
return;
itr->second &= ~ ToyFlags::HasFanfare;
itr->second &= ~ToyFlags::HasFanfare;
}
void CollectionMgr::OnItemAdded(Item* item)
@@ -456,7 +481,7 @@ struct DynamicBitsetBlockOutputIterator
using pointer = void;
using reference = void;
explicit DynamicBitsetBlockOutputIterator(OutputAction const& action) : _action(&action) { }
explicit DynamicBitsetBlockOutputIterator(OutputAction const& action) : _action(&action) {}
DynamicBitsetBlockOutputIterator& operator=(uint32 value)
{
@@ -476,9 +501,9 @@ void CollectionMgr::LoadItemAppearances()
{
Player* owner = _owner->GetPlayer();
boost::to_block_range(*_appearances, DynamicBitsetBlockOutputIterator([owner](uint32 blockValue)
{
owner->AddTransmogBlock(blockValue);
}));
{
owner->AddTransmogBlock(blockValue);
}));
for (auto const& [itemModifiedAppearanceId, _] : _temporaryAppearances)
owner->AddConditionalTransmog(itemModifiedAppearanceId);
@@ -529,7 +554,7 @@ void CollectionMgr::LoadAccountItemAppearances(PreparedQueryResult knownAppearan
for (uint32 hiddenItem : hiddenAppearanceItems)
{
ItemModifiedAppearanceEntry const* hiddenAppearance = sDB2Manager.GetItemModifiedAppearance(hiddenItem, 0);
ItemModifiedAppearanceEntry const* hiddenAppearance = TransmogMgr::GetDefaultItemModifiedAppearance(hiddenItem);
ASSERT(hiddenAppearance);
if (_appearances->size() <= hiddenAppearance->ID)
_appearances->resize(hiddenAppearance->ID + 1);
@@ -542,43 +567,43 @@ void CollectionMgr::SaveAccountItemAppearances(LoginDatabaseTransaction trans)
{
uint16 blockIndex = 0;
boost::to_block_range(*_appearances, DynamicBitsetBlockOutputIterator([this, &blockIndex, trans = trans.get()](uint32 blockValue)
{
if (blockValue) // this table is only appended/bits are set (never cleared) so don't save empty blocks
{
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ITEM_APPEARANCES);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt16(1, blockIndex);
stmt->setUInt32(2, blockValue);
trans->Append(stmt);
}
if (blockValue) // this table is only appended/bits are set (never cleared) so don't save empty blocks
{
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ITEM_APPEARANCES);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt16(1, blockIndex);
stmt->setUInt32(2, blockValue);
trans->Append(stmt);
}
++blockIndex;
}));
++blockIndex;
}));
LoginDatabasePreparedStatement* stmt;
for (auto itr = _favoriteAppearances.begin(); itr != _favoriteAppearances.end();)
{
switch (itr->second)
{
case CollectionItemState::New:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ITEM_FAVORITE_APPEARANCE);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt32(1, itr->first);
trans->Append(stmt);
itr->second = CollectionItemState::Unchanged;
++itr;
break;
case CollectionItemState::Removed:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_ITEM_FAVORITE_APPEARANCE);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt32(1, itr->first);
trans->Append(stmt);
itr = _favoriteAppearances.erase(itr);
break;
case CollectionItemState::Unchanged:
case CollectionItemState::Changed:
++itr;
break;
case CollectionItemState::New:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ITEM_FAVORITE_APPEARANCE);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt32(1, itr->first);
trans->Append(stmt);
itr->second = CollectionItemState::Unchanged;
++itr;
break;
case CollectionItemState::Removed:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_ITEM_FAVORITE_APPEARANCE);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt32(1, itr->first);
trans->Append(stmt);
itr = _favoriteAppearances.erase(itr);
break;
case CollectionItemState::Unchanged:
case CollectionItemState::Changed:
++itr;
break;
}
}
}
@@ -603,7 +628,7 @@ void CollectionMgr::AddItemAppearance(Item* item)
void CollectionMgr::AddItemAppearance(uint32 itemId, uint32 appearanceModId /*= 0*/)
{
ItemModifiedAppearanceEntry const* itemModifiedAppearance = sDB2Manager.GetItemModifiedAppearance(itemId, appearanceModId);
ItemModifiedAppearanceEntry const* itemModifiedAppearance = TransmogMgr::GetItemModifiedAppearance(itemId, appearanceModId);
if (!CanAddAppearance(itemModifiedAppearance))
return;
@@ -612,11 +637,7 @@ void CollectionMgr::AddItemAppearance(uint32 itemId, uint32 appearanceModId /*=
void CollectionMgr::AddTransmogSet(uint32 transmogSetId)
{
std::vector<TransmogSetItemEntry const*> const* items = sDB2Manager.GetTransmogSetItems(transmogSetId);
if (!items)
return;
for (TransmogSetItemEntry const* item : *items)
for (TransmogSetItemEntry const* item : TransmogMgr::GetTransmogSetItems(transmogSetId))
{
ItemModifiedAppearanceEntry const* itemModifiedAppearance = sItemModifiedAppearanceStore.LookupEntry(item->ItemModifiedAppearanceID);
if (!itemModifiedAppearance)
@@ -628,13 +649,13 @@ void CollectionMgr::AddTransmogSet(uint32 transmogSetId)
bool CollectionMgr::IsSetCompleted(uint32 transmogSetId) const
{
std::vector<TransmogSetItemEntry const*> const* transmogSetItems = sDB2Manager.GetTransmogSetItems(transmogSetId);
if (!transmogSetItems)
std::span<TransmogSetItemEntry const* const> transmogSetItems = TransmogMgr::GetTransmogSetItems(transmogSetId);
if (transmogSetItems.empty())
return false;
std::array<int8, EQUIPMENT_SLOT_END> knownPieces;
knownPieces.fill(-1);
for (TransmogSetItemEntry const* transmogSetItem : *transmogSetItems)
for (TransmogSetItemEntry const* transmogSetItem : transmogSetItems)
{
ItemModifiedAppearanceEntry const* itemModifiedAppearance = sItemModifiedAppearanceStore.LookupEntry(transmogSetItem->ItemModifiedAppearanceID);
if (!itemModifiedAppearance)
@@ -676,46 +697,46 @@ bool CollectionMgr::CanAddAppearance(ItemModifiedAppearanceEntry const* itemModi
switch (itemTemplate->GetClass())
{
case ITEM_CLASS_WEAPON:
case ITEM_CLASS_WEAPON:
{
if (itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_EXOTIC ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_EXOTIC2 ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_MISCELLANEOUS ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_THROWN ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_SPEAR ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_FISHING_POLE)
return false;
break;
}
case ITEM_CLASS_ARMOR:
{
switch (itemTemplate->GetInventoryType())
{
if (itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_EXOTIC ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_EXOTIC2 ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_MISCELLANEOUS ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_THROWN ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_SPEAR ||
itemTemplate->GetSubClass() == ITEM_SUBCLASS_WEAPON_FISHING_POLE)
case INVTYPE_BODY:
case INVTYPE_SHIELD:
case INVTYPE_CLOAK:
case INVTYPE_TABARD:
case INVTYPE_HOLDABLE:
break;
case INVTYPE_HEAD:
case INVTYPE_SHOULDERS:
case INVTYPE_CHEST:
case INVTYPE_WAIST:
case INVTYPE_LEGS:
case INVTYPE_FEET:
case INVTYPE_WRISTS:
case INVTYPE_HANDS:
case INVTYPE_ROBE:
if (itemTemplate->GetSubClass() == ITEM_SUBCLASS_ARMOR_MISCELLANEOUS)
return false;
break;
}
case ITEM_CLASS_ARMOR:
{
switch (itemTemplate->GetInventoryType())
{
case INVTYPE_BODY:
case INVTYPE_SHIELD:
case INVTYPE_CLOAK:
case INVTYPE_TABARD:
case INVTYPE_HOLDABLE:
break;
case INVTYPE_HEAD:
case INVTYPE_SHOULDERS:
case INVTYPE_CHEST:
case INVTYPE_WAIST:
case INVTYPE_LEGS:
case INVTYPE_FEET:
case INVTYPE_WRISTS:
case INVTYPE_HANDS:
case INVTYPE_ROBE:
if (itemTemplate->GetSubClass() == ITEM_SUBCLASS_ARMOR_MISCELLANEOUS)
return false;
break;
default:
return false;
}
break;
}
default:
return false;
}
break;
}
default:
return false;
}
if (itemModifiedAppearance->ID < _appearances->size() && _appearances->test(itemModifiedAppearance->ID))
@@ -756,18 +777,14 @@ void CollectionMgr::AddItemAppearance(ItemModifiedAppearanceEntry const* itemMod
owner->UpdateCriteria(CriteriaType::LearnAnyTransmogInSlot, transmogSlot, itemModifiedAppearance->ID);
}
if (std::vector<TransmogSetEntry const*> const* sets = sDB2Manager.GetTransmogSetsForItemModifiedAppearance(itemModifiedAppearance->ID))
for (TransmogSetEntry const* set : TransmogMgr::GetTransmogSetsForItemModifiedAppearance(itemModifiedAppearance->ID))
{
for (TransmogSetEntry const* set : *sets)
if (IsSetCompleted(set->ID))
{
if (IsSetCompleted(set->ID))
{
if (Quest const* quest = sObjectMgr->GetQuestTemplate(set->TrackingQuestID))
owner->RewardQuest(quest, LootItemType::Item, 0, owner, false);
if (Quest const* quest = sObjectMgr->GetQuestTemplate(set->TrackingQuestID))
owner->RewardQuest(quest, LootItemType::Item, 0, owner, false);
owner->UpdateCriteria(CriteriaType::CollectTransmogSetFromGroup, set->TransmogSetGroupID);
}
owner->UpdateCriteria(CriteriaType::CollectTransmogSetFromGroup, set->TransmogSetGroupID);
}
}
}
@@ -878,9 +895,9 @@ void CollectionMgr::LoadTransmogIllusions()
{
Player* owner = _owner->GetPlayer();
boost::to_block_range(*_transmogIllusions, DynamicBitsetBlockOutputIterator([owner](uint32 blockValue)
{
owner->AddIllusionBlock(blockValue);
}));
{
owner->AddIllusionBlock(blockValue);
}));
}
void CollectionMgr::LoadAccountTransmogIllusions(PreparedQueryResult knownTransmogIllusions)
@@ -929,17 +946,17 @@ void CollectionMgr::SaveAccountTransmogIllusions(LoginDatabaseTransaction trans)
uint16 blockIndex = 0;
boost::to_block_range(*_transmogIllusions, DynamicBitsetBlockOutputIterator([this, &blockIndex, trans = trans.get()](uint32 blockValue)
{
if (blockValue) // this table is only appended/bits are set (never cleared) so don't save empty blocks
{
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_TRANSMOG_ILLUSIONS);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt16(1, blockIndex);
stmt->setUInt32(2, blockValue);
trans->Append(stmt);
}
++blockIndex;
}));
if (blockValue) // this table is only appended/bits are set (never cleared) so don't save empty blocks
{
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_TRANSMOG_ILLUSIONS);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt16(1, blockIndex);
stmt->setUInt32(2, blockValue);
trans->Append(stmt);
}
++blockIndex;
}));
}
void CollectionMgr::AddTransmogIllusion(uint32 transmogIllusionId)
@@ -966,6 +983,55 @@ bool CollectionMgr::HasTransmogIllusion(uint32 transmogIllusionId) const
return transmogIllusionId < _transmogIllusions->size() && _transmogIllusions->test(transmogIllusionId);
}
void CollectionMgr::LoadTransmogOutfits()
{
_owner->GetPlayer()->AddUnlockedTransmogOutfits(_transmogOutfits);
}
void CollectionMgr::LoadAccountTransmogOutfits(PreparedQueryResult unlockedTransmogOutfits)
{
if (unlockedTransmogOutfits)
{
do
{
Field* fields = unlockedTransmogOutfits->Fetch();
int32 transmogOutfitId = fields[0].GetInt32();
if (!sTransmogOutfitEntryStore.HasRecord(transmogOutfitId))
continue;
_transmogOutfits.insert(transmogOutfitId);
} while (unlockedTransmogOutfits->NextRow());
}
for (TransmogOutfitEntryEntry const* transmogOutfitEntry : TransmogMgr::GetAutomaticallyUnlockedOutfits())
_transmogOutfits.insert(transmogOutfitEntry->ID);
}
void CollectionMgr::SaveAccountTransmogOutfits(LoginDatabaseTransaction trans)
{
for (int32 transmogOutfitId : _transmogOutfits)
{
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_TRANSMOG_OUTFITS);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setInt32(1, transmogOutfitId);
trans->Append(stmt);
}
}
void CollectionMgr::AddTransmogOutfit(int32 transmogOutfitId)
{
if (_transmogOutfits.insert(transmogOutfitId).second)
_owner->GetPlayer()->AddUnlockedTransmogOutfit(transmogOutfitId);
}
bool CollectionMgr::HasTransmogOutfit(int32 transmogOutfitId) const
{
return _transmogOutfits.contains(transmogOutfitId);
}
void CollectionMgr::LoadWarbandScenes()
{
Player* owner = _owner->GetPlayer();
@@ -1013,36 +1079,36 @@ void CollectionMgr::SaveAccountWarbandScenes(LoginDatabaseTransaction trans)
auto& [warbandSceneId, data] = *itr;
switch (data.State)
{
case CollectionItemState::New:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_WARBAND_SCENE);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt32(1, warbandSceneId);
stmt->setBool(2, data.Flags.HasFlag(WarbandSceneCollectionFlags::Favorite));
stmt->setBool(3, data.Flags.HasFlag(WarbandSceneCollectionFlags::HasFanfare));
trans->Append(stmt);
data.State = CollectionItemState::Unchanged;
++itr;
break;
case CollectionItemState::Changed:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_WARBAND_SCENE);
stmt->setBool(0, data.Flags.HasFlag(WarbandSceneCollectionFlags::Favorite));
stmt->setBool(1, data.Flags.HasFlag(WarbandSceneCollectionFlags::HasFanfare));
stmt->setUInt32(2, _owner->GetBattlenetAccountId());
stmt->setUInt32(3, warbandSceneId);
trans->Append(stmt);
data.State = CollectionItemState::Unchanged;
++itr;
break;
case CollectionItemState::Removed:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_WARBAND_SCENE);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt32(1, warbandSceneId);
trans->Append(stmt);
itr = _warbandScenes.erase(itr);
break;
default:
++itr;
break;
case CollectionItemState::New:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_WARBAND_SCENE);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt32(1, warbandSceneId);
stmt->setBool(2, data.Flags.HasFlag(WarbandSceneCollectionFlags::Favorite));
stmt->setBool(3, data.Flags.HasFlag(WarbandSceneCollectionFlags::HasFanfare));
trans->Append(stmt);
data.State = CollectionItemState::Unchanged;
++itr;
break;
case CollectionItemState::Changed:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_WARBAND_SCENE);
stmt->setBool(0, data.Flags.HasFlag(WarbandSceneCollectionFlags::Favorite));
stmt->setBool(1, data.Flags.HasFlag(WarbandSceneCollectionFlags::HasFanfare));
stmt->setUInt32(2, _owner->GetBattlenetAccountId());
stmt->setUInt32(3, warbandSceneId);
trans->Append(stmt);
data.State = CollectionItemState::Unchanged;
++itr;
break;
case CollectionItemState::Removed:
stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_WARBAND_SCENE);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt32(1, warbandSceneId);
trans->Append(stmt);
itr = _warbandScenes.erase(itr);
break;
default:
++itr;
break;
}
}
}
+29 -18
View File
@@ -21,6 +21,7 @@
#include "Define.h"
#include "DatabaseEnvFwd.h"
#include "EnumFlag.h"
#include "FlatSet.h"
#include "ObjectGuid.h"
#include <boost/dynamic_bitset_fwd.hpp>
#include <map>
@@ -41,25 +42,25 @@ enum class CollectionItemState : uint8
enum HeirloomPlayerFlags
{
HEIRLOOM_FLAG_NONE = 0x00,
HEIRLOOM_FLAG_UPGRADE_LEVEL_1 = 0x01,
HEIRLOOM_FLAG_UPGRADE_LEVEL_2 = 0x02,
HEIRLOOM_FLAG_UPGRADE_LEVEL_3 = 0x04,
HEIRLOOM_FLAG_UPGRADE_LEVEL_4 = 0x08,
HEIRLOOM_FLAG_UPGRADE_LEVEL_5 = 0x10,
HEIRLOOM_FLAG_UPGRADE_LEVEL_6 = 0x20,
HEIRLOOM_FLAG_NONE = 0x00,
HEIRLOOM_FLAG_UPGRADE_LEVEL_1 = 0x01,
HEIRLOOM_FLAG_UPGRADE_LEVEL_2 = 0x02,
HEIRLOOM_FLAG_UPGRADE_LEVEL_3 = 0x04,
HEIRLOOM_FLAG_UPGRADE_LEVEL_4 = 0x08,
HEIRLOOM_FLAG_UPGRADE_LEVEL_5 = 0x10,
HEIRLOOM_FLAG_UPGRADE_LEVEL_6 = 0x20,
};
enum HeirloomItemFlags
{
HEIRLOOM_ITEM_FLAG_NONE = 0x00,
HEIRLOOM_ITEM_FLAG_NONE = 0x00,
HEIRLOOM_ITEM_FLAG_SHOW_ONLY_IF_KNOWN = 0x01,
HEIRLOOM_ITEM_FLAG_PVP = 0x02
HEIRLOOM_ITEM_FLAG_PVP = 0x02
};
struct HeirloomData
{
HeirloomData(uint32 _flags = 0, uint32 _bonusId = 0) : flags(_flags), bonusId(_bonusId) { }
HeirloomData(uint32 _flags = 0, uint32 _bonusId = 0) : flags(_flags), bonusId(_bonusId) {}
uint32 flags;
uint32 bonusId;
@@ -67,9 +68,9 @@ struct HeirloomData
enum class ToyFlags : uint32
{
None = 0,
Favorite = 0x01,
HasFanfare = 0x02
None = 0,
Favorite = 0x01,
HasFanfare = 0x02
};
DEFINE_ENUM_FLAG(ToyFlags);
@@ -79,9 +80,9 @@ typedef std::map<uint32, HeirloomData> HeirloomContainer;
enum MountStatusFlags : uint8
{
MOUNT_STATUS_NONE = 0x00,
MOUNT_STATUS_NONE = 0x00,
MOUNT_NEEDS_FANFARE = 0x01,
MOUNT_IS_FAVORITE = 0x02
MOUNT_IS_FAVORITE = 0x02
};
typedef std::map<uint32, MountStatusFlags> MountContainer;
@@ -89,9 +90,9 @@ typedef std::unordered_map<uint32, uint32> MountDefinitionMap;
enum class WarbandSceneCollectionFlags : uint8
{
None = 0x00,
Favorite = 0x01,
HasFanfare = 0x02
None = 0x00,
Favorite = 0x01,
HasFanfare = 0x02
};
DEFINE_ENUM_FLAG(WarbandSceneCollectionFlags);
@@ -117,6 +118,9 @@ public:
static void LoadMountDefinitions();
static void LoadWarbandSceneDefinitions();
void LoadCharacterData();
void SaveToDB(LoginDatabaseTransaction trans);
// Account-wide toys
void LoadToys();
void LoadAccountToys(PreparedQueryResult result);
@@ -179,6 +183,12 @@ public:
void AddTransmogIllusion(uint32 transmogIllusionId);
bool HasTransmogIllusion(uint32 transmogIllusionId) const;
void LoadTransmogOutfits();
void LoadAccountTransmogOutfits(PreparedQueryResult unlockedTransmogOutfits);
void SaveAccountTransmogOutfits(LoginDatabaseTransaction trans);
void AddTransmogOutfit(int32 transmogOutfitId);
bool HasTransmogOutfit(int32 transmogOutfitId) const;
// Warband Scenes
void LoadWarbandScenes();
void LoadAccountWarbandScenes(PreparedQueryResult knownWarbandScenes);
@@ -204,6 +214,7 @@ private:
std::unordered_map<uint32, std::unordered_set<ObjectGuid>> _temporaryAppearances;
std::unordered_map<uint32, CollectionItemState> _favoriteAppearances;
std::unique_ptr<boost::dynamic_bitset<uint32>> _transmogIllusions;
Trinity::Containers::FlatSet<int32> _transmogOutfits;
WarbandSceneCollectionContainer _warbandScenes;
};
+686 -85
View File
@@ -131,6 +131,8 @@
#include "TradeData.h"
#include "TraitMgr.h"
#include "TraitPacketsCommon.h"
#include "TransmogMgr.h"
#include "TransmogrificationPackets.h"
#include "Transport.h"
#include "UpdateData.h"
#include "Util.h"
@@ -577,6 +579,8 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac
GetThreatManager().Initialize();
EquipTransmogOutfit(0, TransmogSituationTrigger::Manual, false);
return true;
}
@@ -4242,6 +4246,18 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt64(0, guid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_TRANSMOG_OUTFIT_SITUATION_BY_CHAR);
stmt->setUInt64(0, guid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_TRANSMOG_OUTFIT_SLOT_BY_CHAR);
stmt->setUInt64(0, guid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_TRANSMOG_OUTFIT_BY_CHAR);
stmt->setUInt64(0, guid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER);
stmt->setUInt64(0, guid);
stmt->setUInt64(1, guid);
@@ -4631,19 +4647,10 @@ Corpse* Player::CreateCorpse()
corpse->SetFactionTemplate(sChrRacesStore.AssertEntry(GetRace())->FactionID);
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
{
if (m_items[i])
{
uint32 itemDisplayId = m_items[i]->GetDisplayId(this);
uint32 itemInventoryType;
if (ItemEntry const* itemEntry = sItemStore.LookupEntry(m_items[i]->GetVisibleEntry(this)))
itemInventoryType = itemEntry->InventoryType;
else
itemInventoryType = m_items[i]->GetTemplate()->GetInventoryType();
corpse->SetItem(i, itemDisplayId | (itemInventoryType << 24));
}
}
if (ItemModifiedAppearanceEntry const* itemModifiedAppearance = sItemModifiedAppearanceStore.LookupEntry(m_playerData->VisibleItems[i].ItemModifiedAppearanceID))
if (ItemAppearanceEntry const* itemAppearance = sItemAppearanceStore.LookupEntry(itemModifiedAppearance->ItemAppearanceID))
if (ItemEntry const* item = sItemStore.LookupEntry(itemModifiedAppearance->ItemID))
corpse->SetItem(i, itemAppearance->ItemDisplayInfoID | int32(item->InventoryType) << 24);
// register for player, but not show
GetMap()->AddCorpse(corpse);
@@ -6286,6 +6293,7 @@ bool Player::IsActionButtonDataValid(uint8 button, uint64 action, uint8 type) co
case ACTION_BUTTON_MACRO:
case ACTION_BUTTON_EQSET:
case ACTION_BUTTON_DROPDOWN:
case ACTION_BUTTON_OUTFIT:
break;
default:
TC_LOG_ERROR("entities.player", "Player::IsActionButtonDataValid: Unknown action type {}", type);
@@ -12077,25 +12085,124 @@ void Player::QuickEquipItem(uint16 pos, Item* pItem)
}
}
void Player::SetVisibleItemSlot(uint8 slot, Item* pItem)
void Player::SetVisibleItemSlot(uint8 slot, Item const* item)
{
auto itemField = m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::VisibleItems, slot);
if (pItem)
auto setVisibleItemSlot = [this](uint32 slot, int32 itemId, int32 secondaryItemModifiedAppearanceId, int32 conditionalItemAppearanceId,
uint16 itemAppearanceModId, uint16 itemVisual, uint32 itemModifiedAppearanceId, TransmogOutfitSlotOption transmogSlotOption,
bool hasTransmog, bool hasIllusion)
{
auto itemField = m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::VisibleItems, slot);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemID), itemId);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::SecondaryItemModifiedAppearanceID), secondaryItemModifiedAppearanceId);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ConditionalItemAppearanceID), conditionalItemAppearanceId);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemAppearanceModID), itemAppearanceModId);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemVisual), itemVisual);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemModifiedAppearanceID), itemModifiedAppearanceId);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::TransmogSlotOption), AsUnderlyingType(transmogSlotOption));
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::HasTransmog), hasTransmog);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::HasIllusion), hasIllusion);
auto transmogMetadata = m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::TransmogMetadata);
if (slot == EQUIPMENT_SLOT_MAINHAND)
SetUpdateFieldValue(transmogMetadata.ModifyValue(&UF::TransmogOutfitMetadata::StampedOptionMainHand), AsUnderlyingType(transmogSlotOption));
else if (slot == EQUIPMENT_SLOT_OFFHAND)
SetUpdateFieldValue(transmogMetadata.ModifyValue(&UF::TransmogOutfitMetadata::StampedOptionOffHand), AsUnderlyingType(transmogSlotOption));
};
if (item)
{
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemID), pItem->GetVisibleEntry(this));
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::SecondaryItemModifiedAppearanceID), pItem->GetVisibleSecondaryModifiedAppearanceId(this));
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemAppearanceModID), pItem->GetVisibleAppearanceModId(this));
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemVisual), pItem->GetVisibleItemVisual(this));
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemModifiedAppearanceID), pItem->GetVisibleModifiedAppearanceId(this));
TransmogOutfitSlotOption transmogSlotOption = item->GetTemplate()->GetWeaponTransmogOutfitSlotOption();
if (transmogSlotOption == TransmogOutfitSlotOption::TwoHandedWeapon && CanTitanGrip())
transmogSlotOption = TransmogOutfitSlotOption::FuryTwoHandedWeapon;
int32 itemId = item->GetVisibleEntry(this);
int32 secondaryItemModifiedAppearanceId = item->GetVisibleSecondaryModifiedAppearanceId(this);
int32 conditionalItemAppearanceId = 0;
uint16 itemAppearanceModId = item->GetVisibleAppearanceModId(this);
uint16 itemVisual = item->GetVisibleItemVisual(this);
uint32 itemModifiedAppearanceId = item->GetVisibleModifiedAppearanceId(this);
bool hasTransmog = false;
bool hasIllusion = false;
if (!m_activePlayerData->ViewedOutfit->Slots.empty())
{
TransmogMgr::TransmogOutfitSlotAndOptionInfo const* slotInfo = TransmogMgr::GetSlotAndOption(EquipmentSlots(slot), transmogSlotOption);
if (transmogSlotOption != TransmogOutfitSlotOption::None)
{
// check if artifact override is active
TransmogOutfitSlotOption artifactOption = static_cast<TransmogOutfitSlotOption>(AsUnderlyingType(TransmogOutfitSlotOption::ArtifactSpecOne) + GetPrimarySpecializationEntry()->OrderIndex);
TransmogMgr::TransmogOutfitSlotAndOptionInfo const* artifactSlotInfo = TransmogMgr::GetSlotAndOption(EquipmentSlots(slot), artifactOption);
if (artifactSlotInfo && static_cast<TransmogOutfitDisplayType>(*m_activePlayerData->ViewedOutfit->Slots[artifactSlotInfo->SlotIndex].AppearanceDisplayType) == TransmogOutfitDisplayType::Assigned)
{
transmogSlotOption = artifactOption;
slotInfo = artifactSlotInfo;
}
}
if (slotInfo)
{
auto isTransmogDisplayed = [](TransmogOutfitDisplayType displayType)
{
return displayType == TransmogOutfitDisplayType::Assigned || displayType == TransmogOutfitDisplayType::Hidden;
};
UF::TransmogOutfitSlotData const& transmogOutfitItem = m_activePlayerData->ViewedOutfit->Slots[slotInfo->SlotIndex];
if (isTransmogDisplayed(static_cast<TransmogOutfitDisplayType>(*transmogOutfitItem.AppearanceDisplayType)))
{
if (ItemModifiedAppearanceEntry const* itemModifiedAppearance = sItemModifiedAppearanceStore.LookupEntry(transmogOutfitItem.ItemModifiedAppearanceID))
{
itemId = itemModifiedAppearance->ItemID;
itemAppearanceModId = itemModifiedAppearance->ItemAppearanceModifierID;
itemModifiedAppearanceId = itemModifiedAppearance->ID;
}
hasTransmog = true;
}
if (TransmogOutfitSlotInfoEntry const* secondarySlot = sTransmogOutfitSlotInfoStore.LookupEntry(slotInfo->Slot->SecondarySlotID))
{
if (TransmogMgr::TransmogOutfitSlotAndOptionInfo const* secondarySlotInfo = TransmogMgr::GetSlotAndOption(secondarySlot->GetSlot(), transmogSlotOption))
{
UF::TransmogOutfitSlotData const& secondaryTransmogOutfitItem = m_activePlayerData->ViewedOutfit->Slots[secondarySlotInfo->SlotIndex];
if (isTransmogDisplayed(static_cast<TransmogOutfitDisplayType>(*secondaryTransmogOutfitItem.AppearanceDisplayType))
|| static_cast<TransmogOutfitDisplayType>(*secondaryTransmogOutfitItem.AppearanceDisplayType) == TransmogOutfitDisplayType::Equipped)
{
secondaryItemModifiedAppearanceId = secondaryTransmogOutfitItem.ItemModifiedAppearanceID;
hasTransmog = true;
}
}
}
if (TransmogOutfitSlotOptionEntry const* secondarySlotOption = sTransmogOutfitSlotOptionInfoStore.LookupEntry(slotInfo->SlotOption ? slotInfo->SlotOption->SecondaryOptionID : 0))
{
if (TransmogMgr::TransmogOutfitSlotAndOptionInfo const* secondarySlotInfo = TransmogMgr::GetSlotAndOption(slotInfo->Slot->GetSlot(), secondarySlotOption->GetOption()))
{
UF::TransmogOutfitSlotData const& secondaryTransmogOutfitItem = m_activePlayerData->ViewedOutfit->Slots[secondarySlotInfo->SlotIndex];
if (isTransmogDisplayed(static_cast<TransmogOutfitDisplayType>(*secondaryTransmogOutfitItem.AppearanceDisplayType))
|| static_cast<TransmogOutfitDisplayType>(*secondaryTransmogOutfitItem.AppearanceDisplayType) == TransmogOutfitDisplayType::Equipped)
{
secondaryItemModifiedAppearanceId = secondaryTransmogOutfitItem.ItemModifiedAppearanceID;
hasTransmog = true;
}
}
}
if (isTransmogDisplayed(static_cast<TransmogOutfitDisplayType>(*transmogOutfitItem.IllusionDisplayType)))
{
if (SpellItemEnchantmentEntry const* spellItemEnchantment = sSpellItemEnchantmentStore.LookupEntry(transmogOutfitItem.SpellItemEnchantmentID))
itemVisual = spellItemEnchantment->ItemVisual;
hasIllusion = true;
}
}
}
setVisibleItemSlot(slot, itemId, secondaryItemModifiedAppearanceId, conditionalItemAppearanceId, itemAppearanceModId,
itemVisual, itemModifiedAppearanceId, transmogSlotOption, hasTransmog, hasIllusion);
}
else
{
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemID), 0);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::SecondaryItemModifiedAppearanceID), 0);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemAppearanceModID), 0);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemVisual), 0);
SetUpdateFieldValue(itemField.ModifyValue(&UF::VisibleItem::ItemModifiedAppearanceID), 0);
}
setVisibleItemSlot(slot, 0, 0, 0, 0, 0, 0, TransmogOutfitSlotOption::None, false, false);
}
void Player::VisualizeItem(uint8 slot, Item* pItem)
@@ -17884,7 +17991,7 @@ void Player::_LoadEquipmentSets(PreparedQueryResult result)
} while (result->NextRow());
}
void Player::_LoadTransmogOutfits(PreparedQueryResult result)
void Player::_LoadTransmogCustomSets(PreparedQueryResult result)
{
// 0 1 2 3 4 5 6 7 8 9
//SELECT setguid, setindex, name, iconname, ignore_mask, appearance0, appearance1, appearance2, appearance3, appearance4,
@@ -17921,6 +18028,155 @@ void Player::_LoadTransmogOutfits(PreparedQueryResult result)
} while (result->NextRow());
}
void Player::_LoadTransmogOutfits(PreparedQueryResult setsResult, PreparedQueryResult situationsResult, PreparedQueryResult slotsResult,
int32 equippedTransmogOutfitId, bool locked)
{
struct SetData
{
std::vector<WorldPackets::Transmogrification::TransmogOutfitSituationInfo> situations;
std::vector<WorldPackets::Transmogrification::TransmogOutfitSlotData> slots;
};
std::unordered_map<uint32, SetData> sets;
// SELECT transmogOutfitId, situationID, specID, loadoutID, equipmentSetID FROM character_transmog_outfit_situation WHERE guid = ?
if (situationsResult)
{
do
{
DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(PreparedResultSet, (transmogOutfitId)(situationID)(specID)(loadoutID)(equipmentSetID)) fields { *situationsResult };
uint32 transmogOutfitId = fields.transmogOutfitId().GetUInt32();
WorldPackets::Transmogrification::TransmogOutfitSituationInfo& situation = sets[transmogOutfitId].situations.emplace_back();
situation.SituationID = fields.situationID().GetUInt32();
situation.SpecID = fields.specID().GetUInt32();
situation.LoadoutID = fields.loadoutID().GetUInt32();
situation.EquipmentSetID = fields.equipmentSetID().GetUInt32();
} while (situationsResult->NextRow());
}
// SELECT transmogOutfitId, slot, slotOption, itemModifiedAppearanceID, appearanceDisplayType, spellItemEnchantmentID, illusionDisplayType, flags FROM character_transmog_outfit_slot guid = ?
if (slotsResult)
{
do
{
DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(PreparedResultSet, (transmogOutfitId)(slot)(slotOption)(itemModifiedAppearanceID)(appearanceDisplayType)
(spellItemEnchantmentID)(illusionDisplayType)(flags)) fields {
*slotsResult
};
uint32 transmogOutfitId = fields.transmogOutfitId().GetUInt32();
WorldPackets::Transmogrification::TransmogOutfitSlotData& slot = sets[transmogOutfitId].slots.emplace_back();
slot.Slot = static_cast<TransmogOutfitSlot>(fields.slot().GetInt8());
slot.SlotOption = static_cast<TransmogOutfitSlotOption>(fields.slotOption().GetUInt8());
slot.ItemModifiedAppearanceID = fields.itemModifiedAppearanceID().GetUInt32();
slot.AppearanceDisplayType = static_cast<TransmogOutfitDisplayType>(fields.appearanceDisplayType().GetUInt8());
slot.SpellItemEnchantmentID = fields.spellItemEnchantmentID().GetUInt32();
slot.IllusionDisplayType = static_cast<TransmogOutfitDisplayType>(fields.illusionDisplayType().GetUInt8());
slot.Flags = fields.flags().GetUInt32();
} while (slotsResult->NextRow());
}
auto activePlayerData = m_values.ModifyValue(&Player::m_activePlayerData);
// SELECT transmogOutfitId, name, icon, situationsEnabled FROM character_transmog_outfit WHERE guid = ?
if (setsResult)
{
do
{
DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(PreparedResultSet, (transmogOutfitId)(name)(icon)(situationsEnabled)) fields { *setsResult };
uint32 transmogOutfitId = fields.transmogOutfitId().GetUInt32();
TransmogOutfitEntryEntry const* transmogOutfitEntry = sTransmogOutfitEntryStore.LookupEntry(transmogOutfitId);
if (!transmogOutfitEntry || transmogOutfitEntry->GetSetType() == TransmogOutfitSetType::CustomSet)
continue;
if (transmogOutfitEntry->HasFlag(TransmogOutfitEntryFlags::OnlyAvailableDuringEvent) && !IsHolidayActive(HOLIDAY_TRIAL_OF_STYLE))
continue;
WorldPackets::Transmogrification::TransmogOutfitDataInfo outfitInfo;
outfitInfo.SetType = transmogOutfitEntry->GetSetType();
outfitInfo.Name = fields.name().GetString();
outfitInfo.Icon = fields.icon().GetUInt32();
outfitInfo.SituationsEnabled = fields.situationsEnabled().GetBool();
auto transmogOutfit = activePlayerData.ModifyValue(&UF::ActivePlayerData::TransmogOutfits, transmogOutfitId);
InitializeNewTransmogOutfit(transmogOutfit, transmogOutfitId, outfitInfo);
auto setData = sets.extract(transmogOutfitId);
if (!setData)
continue;
auto situations = transmogOutfit.ModifyValue(&UF::TransmogOutfitData::Situations);
ClearDynamicUpdateFieldValues(situations);
for (WorldPackets::Transmogrification::TransmogOutfitSituationInfo const& situationInfo : setData.mapped().situations)
{
auto situation = AddDynamicUpdateFieldValue(situations);
situation.ModifyValue(&UF::TransmogOutfitSituationInfo::SituationID).SetValue(situationInfo.SituationID);
situation.ModifyValue(&UF::TransmogOutfitSituationInfo::SpecID).SetValue(situationInfo.SpecID);
situation.ModifyValue(&UF::TransmogOutfitSituationInfo::LoadoutID).SetValue(situationInfo.LoadoutID);
situation.ModifyValue(&UF::TransmogOutfitSituationInfo::EquipmentSetID).SetValue(situationInfo.EquipmentSetID);
}
for (WorldPackets::Transmogrification::TransmogOutfitSlotData const& slotData : setData.mapped().slots)
{
TransmogMgr::TransmogOutfitSlotAndOptionInfo const* slotInfo = TransmogMgr::GetSlotAndOption(slotData.Slot, slotData.SlotOption);
if (!slotInfo)
continue;
auto slot = transmogOutfit.ModifyValue(&UF::TransmogOutfitData::Slots, slotInfo->SlotIndex);
SetUpdateFieldValue(slot.ModifyValue(&UF::TransmogOutfitSlotData::Slot), AsUnderlyingType(slotData.Slot));
SetUpdateFieldValue(slot.ModifyValue(&UF::TransmogOutfitSlotData::SlotOption), AsUnderlyingType(slotData.SlotOption));
SetUpdateFieldValue(slot.ModifyValue(&UF::TransmogOutfitSlotData::ItemModifiedAppearanceID), slotData.ItemModifiedAppearanceID);
SetUpdateFieldValue(slot.ModifyValue(&UF::TransmogOutfitSlotData::AppearanceDisplayType), AsUnderlyingType(slotData.AppearanceDisplayType));
SetUpdateFieldValue(slot.ModifyValue(&UF::TransmogOutfitSlotData::SpellItemEnchantmentID), slotData.SpellItemEnchantmentID);
SetUpdateFieldValue(slot.ModifyValue(&UF::TransmogOutfitSlotData::IllusionDisplayType), AsUnderlyingType(slotData.IllusionDisplayType));
SetUpdateFieldValue(slot.ModifyValue(&UF::TransmogOutfitSlotData::Flags), slotData.Flags);
}
} while (setsResult->NextRow());
}
for (int32 transmogOutfitId : m_activePlayerData->UnlockedTransmogOutfits)
{
TransmogOutfitEntryEntry const* transmogOutfitEntry = sTransmogOutfitEntryStore.AssertEntry(transmogOutfitId);
if (transmogOutfitEntry->HasFlag(TransmogOutfitEntryFlags::OnlyAvailableDuringEvent) && !IsHolidayActive(HOLIDAY_TRIAL_OF_STYLE))
continue;
WorldPackets::Transmogrification::TransmogOutfitDataInfo outfitData;
outfitData.SetType = transmogOutfitEntry->GetSetType();
outfitData.SituationsEnabled = false;
outfitData.Icon = TransmogMgr::DefaultOutfitIcon;
outfitData.Name = TransmogMgr::DefaultOutfitName[GetSession()->GetSessionDbcLocale()];
if (transmogOutfitEntry->Name.Str[GetSession()->GetSessionDbcLocale()][0])
outfitData.Name = transmogOutfitEntry->Name.Str[GetSession()->GetSessionDbcLocale()];
switch (transmogOutfitEntry->GetSetType())
{
case TransmogOutfitSetType::Equipped:
{
outfitData.SituationsEnabled = true;
auto equippedOutfit = activePlayerData.ModifyValue(&UF::ActivePlayerData::ViewedOutfit);
InitializeNewTransmogOutfit(equippedOutfit, transmogOutfitId, outfitData);
break;
}
case TransmogOutfitSetType::Outfit:
if (!m_activePlayerData->TransmogOutfits.Get(transmogOutfitId))
CreateTransmogOutfit(transmogOutfitId, outfitData);
break;
case TransmogOutfitSetType::CustomSet:
default:
break;
}
}
EquipTransmogOutfit(equippedTransmogOutfitId, TransmogSituationTrigger::Manual, locked);
}
void Player::_LoadBGData(PreparedQueryResult result)
{
if (!result)
@@ -18022,7 +18278,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
// "totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
// "health, power1, power2, power3, power4, power5, power6, power7, power8, power9, power10, instance_id, activeTalentGroup, lootSpecId, exploredZones, knownTitles, actionBars, "
// "raidDifficulty, legacyRaidDifficulty, fishingSteps, honor, honorLevel, honorRestState, honorRestBonus, numRespecs, "
// "personalTabardEmblemStyle, personalTabardEmblemColor, personalTabardBorderStyle, personalTabardBorderColor, personalTabardBackgroundColor, "
// "personalTabardEmblemStyle, personalTabardEmblemColor, personalTabardBorderStyle, personalTabardBorderColor, personalTabardBackgroundColor, transmogOutfitEquippedId, transmogOutfitLocked, "
// "chromieTimeExpansionId "
// "FROM characters c LEFT JOIN character_fishingsteps cfs ON c.guid = cfs.guid WHERE c.guid = ?", CONNECTION_ASYNC);
@@ -18102,6 +18358,8 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
int32 personalTabardBorderStyle;
int32 personalTabardBorderColor;
int32 personalTabardBackgroundColor;
int32 transmogOutfitEquippedId;
bool transmogOutfitLocked;
uint8 chromieTimeExpansionId;
explicit PlayerLoadData(Field const* fields)
@@ -18184,6 +18442,8 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
personalTabardBorderStyle = fields[i++].GetInt32();
personalTabardBorderColor = fields[i++].GetInt32();
personalTabardBackgroundColor = fields[i++].GetInt32();
transmogOutfitEquippedId = fields[i++].GetInt32();
transmogOutfitLocked = fields[i++].GetBool();
chromieTimeExpansionId = fields[i++].GetUInt8();
}
@@ -18716,12 +18976,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
_LoadTalents(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS));
_LoadPvpTalents(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_PVP_TALENTS));
_LoadSpells(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_FAVORITES));
GetSession()->GetCollectionMgr()->LoadToys();
GetSession()->GetCollectionMgr()->LoadHeirlooms();
GetSession()->GetCollectionMgr()->LoadMounts();
GetSession()->GetCollectionMgr()->LoadItemAppearances();
GetSession()->GetCollectionMgr()->LoadTransmogIllusions();
GetSession()->GetCollectionMgr()->LoadWarbandScenes();
GetSession()->GetCollectionMgr()->LoadCharacterData();
LearnSpecializationSpells();
@@ -18907,6 +19162,9 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
}
}
if (extraflags & PLAYER_EXTRA_FLAG_FREE_TRANSMOG_CLAIMED)
SetPlayerLocalFlag(PLAYER_LOCAL_FLAG_FREE_TRANSMOG_CLAIMED);
InitPvP();
// RaF stuff.
@@ -18916,7 +19174,11 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
_LoadDeclinedNames(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES));
_LoadEquipmentSets(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS));
_LoadTransmogOutfits(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFITS));
_LoadTransmogCustomSets(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFITS));
_LoadTransmogOutfits(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFIT),
holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFIT_SITUATION),
holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFIT_SLOT),
fields.transmogOutfitEquippedId, fields.transmogOutfitLocked);
_LoadCUFProfiles(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES));
@@ -21109,27 +21371,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
}
stmt->setString(index++, ss.str());
ss.str("");
// cache equipment...
for (uint32 i = 0; i < REAGENT_BAG_SLOT_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
ss << uint32(item->GetTemplate()->GetInventoryType()) << ' ' << item->GetDisplayId(this) << ' ';
if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetVisibleEnchantmentId(this)))
ss << enchant->ItemVisual;
else
ss << '0';
ss << ' '
<< uint32(sItemStore.AssertEntry(item->GetVisibleEntry(this))->SubclassID) << ' '
<< uint32(item->GetVisibleSecondaryModifiedAppearanceId(this)) << ' ';
}
else
ss << "0 0 0 0 0 ";
}
stmt->setString(index++, ss.str());
stmt->setString(index++, GetCharacterSelectOutfit());
ss.str("");
for (uint32 i = 0; i < m_activePlayerData->KnownTitles.size(); ++i)
@@ -21144,6 +21386,14 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
stmt->setUInt32(index++, ClientBuild::GetMinorMajorBugfixVersionForBuild(currentRealm->Build));
else
stmt->setUInt32(index++, 0);
stmt->setInt32(index++, m_playerData->PersonalTabard->EmblemStyle);
stmt->setInt32(index++, m_playerData->PersonalTabard->EmblemColor);
stmt->setInt32(index++, m_playerData->PersonalTabard->BorderStyle);
stmt->setInt32(index++, m_playerData->PersonalTabard->BorderColor);
stmt->setInt32(index++, m_playerData->PersonalTabard->BackgroundColor);
stmt->setInt32(index++, m_activePlayerData->TransmogMetadata->TransmogOutfitID);
stmt->setBool(index++, m_activePlayerData->TransmogMetadata->Locked);
stmt->setUInt8(index++, uint8(m_activePlayerData->UiChromieTimeExpansionID));
}
else
@@ -21269,27 +21519,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
}
stmt->setString(index++, ss.str());
ss.str("");
// cache equipment...
for (uint32 i = 0; i < REAGENT_BAG_SLOT_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
ss << uint32(item->GetTemplate()->GetInventoryType()) << ' ' << item->GetDisplayId(this) << ' ';
if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetVisibleEnchantmentId(this)))
ss << enchant->ItemVisual;
else
ss << '0';
ss << ' '
<< uint32(sItemStore.AssertEntry(item->GetVisibleEntry(this))->SubclassID) << ' '
<< uint32(item->GetVisibleSecondaryModifiedAppearanceId(this)) << ' ';
}
else
ss << "0 0 0 0 0 ";
}
stmt->setString(index++, ss.str());
stmt->setString(index++, GetCharacterSelectOutfit());
ss.str("");
for (uint32 i = 0; i < m_activePlayerData->KnownTitles.size(); ++i)
@@ -21312,6 +21542,14 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
stmt->setUInt32(index++, 0);
stmt->setUInt8(index++, uint8(m_activePlayerData->UiChromieTimeExpansionID));
stmt->setInt32(index++, m_playerData->PersonalTabard->EmblemStyle);
stmt->setInt32(index++, m_playerData->PersonalTabard->EmblemColor);
stmt->setInt32(index++, m_playerData->PersonalTabard->BorderStyle);
stmt->setInt32(index++, m_playerData->PersonalTabard->BorderColor);
stmt->setInt32(index++, m_playerData->PersonalTabard->BackgroundColor);
stmt->setInt32(index++, m_activePlayerData->TransmogMetadata->TransmogOutfitID);
stmt->setBool(index++, m_activePlayerData->TransmogMetadata->Locked);
// Index
stmt->setUInt64(index, GetGUID().GetCounter());
}
@@ -21354,6 +21592,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
m_reputationMgr->SaveAccountWideToDB(trans);
m_questObjectiveCriteriaMgr->SaveToDB(trans);
_SaveEquipmentSets(trans);
_SaveTransmogOutfits(trans);
GetSession()->SaveTutorialsData(trans); // changed only while character in game
_SaveInstanceTimeRestrictions(trans);
_SaveCurrency(trans);
@@ -21384,13 +21623,8 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
_SaveStats(trans);
// TODO: Move this out
GetSession()->GetCollectionMgr()->SaveAccountToys(loginTransaction);
GetSession()->GetCollectionMgr()->SaveToDB(loginTransaction);
GetSession()->GetBattlePetMgr()->SaveToDB(loginTransaction);
GetSession()->GetCollectionMgr()->SaveAccountHeirlooms(loginTransaction);
GetSession()->GetCollectionMgr()->SaveAccountMounts(loginTransaction);
GetSession()->GetCollectionMgr()->SaveAccountItemAppearances(loginTransaction);
GetSession()->GetCollectionMgr()->SaveAccountTransmogIllusions(loginTransaction);
GetSession()->GetCollectionMgr()->SaveAccountWarbandScenes(loginTransaction);
GetSession()->SavePlayerDataAccount(loginTransaction);
Battlenet::RealmHandle currentRealmId = sRealmList->GetCurrentRealmId();
@@ -29210,6 +29444,71 @@ void Player::_SaveEquipmentSets(CharacterDatabaseTransaction trans)
}
}
void Player::_SaveTransmogOutfits(CharacterDatabaseTransaction trans)
{
CharacterDatabasePreparedStatement* stmt = nullptr;
ObjectGuid::LowType guid = GetGUID().GetCounter();
for (uint32 transmogOutfitId : m_changedTransmogOutfits)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TRANSMOG_OUTFIT_SLOT);
stmt->setUInt64(0, guid);
stmt->setUInt32(1, transmogOutfitId);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TRANSMOG_OUTFIT_SITUATION);
stmt->setUInt64(0, guid);
stmt->setUInt32(1, transmogOutfitId);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TRANSMOG_OUTFIT_2);
stmt->setUInt64(0, guid);
stmt->setUInt32(1, transmogOutfitId);
trans->Append(stmt);
UF::TransmogOutfitData const* transmogOutfit = m_activePlayerData->TransmogOutfits.Get(transmogOutfitId);
if (!transmogOutfit)
continue;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_TRANSMOG_OUTFIT_2);
stmt->setUInt64(0, guid);
stmt->setUInt32(1, transmogOutfitId);
stmt->setString(2, *transmogOutfit->OutfitInfo->Name);
stmt->setUInt32(3, *transmogOutfit->OutfitInfo->Icon);
stmt->setBool(4, *transmogOutfit->OutfitInfo->SituationsEnabled);
trans->Append(stmt);
for (UF::TransmogOutfitSituationInfo const& situation : transmogOutfit->Situations)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_TRANSMOG_OUTFIT_SITUATION);
stmt->setUInt64(0, guid);
stmt->setUInt32(1, transmogOutfitId);
stmt->setUInt32(2, *situation.SituationID);
stmt->setUInt32(3, *situation.SpecID);
stmt->setUInt32(4, *situation.LoadoutID);
stmt->setUInt32(5, *situation.EquipmentSetID);
trans->Append(stmt);
}
for (UF::TransmogOutfitSlotData const& slot : transmogOutfit->Slots)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_TRANSMOG_OUTFIT_SLOT);
stmt->setUInt64(0, guid);
stmt->setUInt32(1, transmogOutfitId);
stmt->setInt8(2, *slot.Slot);
stmt->setUInt8(3, *slot.SlotOption);
stmt->setUInt32(4, *slot.ItemModifiedAppearanceID);
stmt->setUInt8(5, *slot.AppearanceDisplayType);
stmt->setUInt32(6, *slot.SpellItemEnchantmentID);
stmt->setUInt8(7, *slot.IllusionDisplayType);
stmt->setUInt32(8, *slot.Flags);
trans->Append(stmt);
}
}
m_changedTransmogOutfits.clear();
}
void Player::_SaveBGData(CharacterDatabaseTransaction trans)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_BGDATA);
@@ -32064,6 +32363,308 @@ void Player::UpdateWarModeAuras()
}
}
void Player::AddUnlockedTransmogOutfits(std::span<int32 const> transmogOutfitIds)
{
auto unlockedTransmogOutfits = m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::UnlockedTransmogOutfits);
for (int32 transmogOutfitId : transmogOutfitIds)
AddDynamicUpdateFieldValue(unlockedTransmogOutfits) = transmogOutfitId;
}
void Player::CreateTransmogOutfit(uint32 id, WorldPackets::Transmogrification::TransmogOutfitDataInfo const& outfitData)
{
auto outfit = m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::TransmogOutfits, id);
InitializeNewTransmogOutfit(outfit, id, outfitData);
m_changedTransmogOutfits.insert(id);
}
void Player::InitializeNewTransmogOutfit(UF::MutableFieldReference<UF::TransmogOutfitData, false> outfit,
uint32 id, WorldPackets::Transmogrification::TransmogOutfitDataInfo const& outfitData)
{
SetUpdateFieldValue(outfit.ModifyValue(&UF::TransmogOutfitData::Id), id);
auto outfitInfo = outfit.ModifyValue(&UF::TransmogOutfitData::OutfitInfo);
SetUpdateFieldValue(outfitInfo.ModifyValue(&UF::TransmogOutfitDataInfo::SetType), AsUnderlyingType(outfitData.SetType));
SetUpdateFieldValue(outfitInfo.ModifyValue(&UF::TransmogOutfitDataInfo::SituationsEnabled), outfitData.SituationsEnabled);
SetUpdateFieldValue(outfitInfo.ModifyValue(&UF::TransmogOutfitDataInfo::Icon), outfitData.Icon);
SetUpdateFieldValue(outfitInfo.ModifyValue(&UF::TransmogOutfitDataInfo::Name), std::string(outfitData.Name));
auto situations = outfit.ModifyValue(&UF::TransmogOutfitData::Situations);
for (TransmogSituationEntry const* defaultSituation : TransmogMgr::GetDefaultSituations())
{
auto situation = AddDynamicUpdateFieldValue(situations);
situation.ModifyValue(&UF::TransmogOutfitSituationInfo::SituationID).SetValue(defaultSituation->ID);
}
auto slots = outfit.ModifyValue(&UF::TransmogOutfitData::Slots);
for (TransmogMgr::TransmogOutfitSlotAndOptionInfo const& slotInfo : TransmogMgr::GetAllSlots())
{
auto slot = AddDynamicUpdateFieldValue(slots);
slot.ModifyValue(&UF::TransmogOutfitSlotData::Slot).SetValue(AsUnderlyingType(slotInfo.Slot->GetSlot()));
if (slotInfo.SlotOption)
{
slot.ModifyValue(&UF::TransmogOutfitSlotData::SlotOption).SetValue(AsUnderlyingType(slotInfo.SlotOption->GetOption()));
switch (slotInfo.SlotOption->GetOption())
{
case TransmogOutfitSlotOption::ArtifactSpecOne:
case TransmogOutfitSlotOption::ArtifactSpecTwo:
case TransmogOutfitSlotOption::ArtifactSpecThree:
case TransmogOutfitSlotOption::ArtifactSpecFour:
// artifacts are disabled by default
slot.ModifyValue(&UF::TransmogOutfitSlotData::AppearanceDisplayType).SetValue(AsUnderlyingType(TransmogOutfitDisplayType::Disabled));
slot.ModifyValue(&UF::TransmogOutfitSlotData::IllusionDisplayType).SetValue(AsUnderlyingType(TransmogOutfitDisplayType::Disabled));
break;
default:
break;
}
}
}
}
bool Player::UpdateTransmogOutfit(uint32 id, WorldPackets::Transmogrification::TransmogOutfitDataInfo const& outfitData)
{
if (!m_activePlayerData->TransmogOutfits.Get(id))
return false;
auto outfitInfo = m_values.ModifyValue(&Player::m_activePlayerData)
.ModifyValue(&UF::ActivePlayerData::TransmogOutfits, id)
.ModifyValue(&UF::TransmogOutfitData::OutfitInfo);
SetUpdateFieldValue(outfitInfo.ModifyValue(&UF::TransmogOutfitDataInfo::SetType), AsUnderlyingType(outfitData.SetType));
SetUpdateFieldValue(outfitInfo.ModifyValue(&UF::TransmogOutfitDataInfo::SituationsEnabled), outfitData.SituationsEnabled);
SetUpdateFieldValue(outfitInfo.ModifyValue(&UF::TransmogOutfitDataInfo::Icon), outfitData.Icon);
SetUpdateFieldValue(outfitInfo.ModifyValue(&UF::TransmogOutfitDataInfo::Name), std::string(outfitData.Name));
m_changedTransmogOutfits.insert(id);
return true;
}
void Player::UpdateTransmogOutfitSituations(uint32 id, bool situationsEnabled, std::span<WorldPackets::Transmogrification::TransmogOutfitSituationInfo const> situations)
{
auto outfit = m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::TransmogOutfits, id);
SetUpdateFieldValue(outfit.ModifyValue(&UF::TransmogOutfitData::OutfitInfo).ModifyValue(&UF::TransmogOutfitDataInfo::SituationsEnabled), situationsEnabled);
auto outfitSituations = outfit.ModifyValue(&UF::TransmogOutfitData::Situations);
ClearDynamicUpdateFieldValues(outfitSituations);
for (WorldPackets::Transmogrification::TransmogOutfitSituationInfo const& situation : situations)
{
auto outfitSituation = AddDynamicUpdateFieldValue(outfitSituations);
outfitSituation.ModifyValue(&UF::TransmogOutfitSituationInfo::SituationID).SetValue(situation.SituationID);
outfitSituation.ModifyValue(&UF::TransmogOutfitSituationInfo::SpecID).SetValue(situation.SpecID);
outfitSituation.ModifyValue(&UF::TransmogOutfitSituationInfo::LoadoutID).SetValue(situation.LoadoutID);
outfitSituation.ModifyValue(&UF::TransmogOutfitSituationInfo::EquipmentSetID).SetValue(situation.EquipmentSetID);
}
m_changedTransmogOutfits.insert(id);
}
void Player::UpdateTransmogOutfitSlots(uint32 id, std::span<WorldPackets::Transmogrification::TransmogOutfitSlotData const> slots)
{
UF::TransmogOutfitData const* transmogOutfit = m_activePlayerData->TransmogOutfits.Get(id);
if (!transmogOutfit)
return;
auto outfit = m_values.ModifyValue(&Player::m_activePlayerData)
.ModifyValue(&UF::ActivePlayerData::TransmogOutfits, id);
uint32 outfitSlotIndex = 0;
for (WorldPackets::Transmogrification::TransmogOutfitSlotData const& slot : slots)
{
while (std::pair(*transmogOutfit->Slots[outfitSlotIndex].Slot, *transmogOutfit->Slots[outfitSlotIndex].SlotOption) < std::pair(AsUnderlyingType(slot.Slot), AsUnderlyingType(slot.SlotOption)))
if (++outfitSlotIndex >= transmogOutfit->Slots.size())
return;
auto viewedOutfitSlot = outfit.ModifyValue(&UF::TransmogOutfitData::Slots, outfitSlotIndex);
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::Slot), AsUnderlyingType(slot.Slot));
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::SlotOption), AsUnderlyingType(slot.SlotOption));
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::ItemModifiedAppearanceID), slot.ItemModifiedAppearanceID);
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::AppearanceDisplayType), AsUnderlyingType(slot.AppearanceDisplayType));
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::SpellItemEnchantmentID), slot.SpellItemEnchantmentID);
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::IllusionDisplayType), AsUnderlyingType(slot.IllusionDisplayType));
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::Flags), slot.Flags);
}
m_changedTransmogOutfits.insert(id);
}
void Player::EquipTransmogOutfit(uint32 id, TransmogSituationTrigger trigger, Optional<bool> locked)
{
auto activePlayerData = m_values.ModifyValue(&Player::m_activePlayerData);
auto transmogMetadata = activePlayerData.ModifyValue(&UF::ActivePlayerData::TransmogMetadata);
SetUpdateFieldValue(transmogMetadata.ModifyValue(&UF::TransmogOutfitMetadata::TransmogOutfitID), id);
SetUpdateFieldValue(transmogMetadata.ModifyValue(&UF::TransmogOutfitMetadata::SituationTrigger), AsUnderlyingType(trigger));
if (locked.has_value())
SetUpdateFieldValue(transmogMetadata.ModifyValue(&UF::TransmogOutfitMetadata::Locked), *locked);
auto viewedOutfit = activePlayerData.ModifyValue(&UF::ActivePlayerData::ViewedOutfit);
if (UF::TransmogOutfitData const* transmogOutfit = m_activePlayerData->TransmogOutfits.Get(id))
{
for (UF::TransmogOutfitSlotData const& slot : transmogOutfit->Slots)
{
uint32 slotIndex = TransmogMgr::GetSlotAndOption(static_cast<TransmogOutfitSlot>(*slot.Slot), static_cast<TransmogOutfitSlotOption>(*slot.SlotOption))->SlotIndex;
auto viewedOutfitSlot = viewedOutfit.ModifyValue(&UF::TransmogOutfitData::Slots, slotIndex);
if (static_cast<TransmogOutfitDisplayType>(*slot.AppearanceDisplayType) != TransmogOutfitDisplayType::Unassigned)
{
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::ItemModifiedAppearanceID), slot.ItemModifiedAppearanceID);
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::AppearanceDisplayType), slot.AppearanceDisplayType);
}
if (static_cast<TransmogOutfitDisplayType>(*slot.IllusionDisplayType) != TransmogOutfitDisplayType::Unassigned)
{
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::SpellItemEnchantmentID), slot.SpellItemEnchantmentID);
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::IllusionDisplayType), slot.IllusionDisplayType);
}
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::Flags), slot.Flags);
}
}
else
{
for (TransmogMgr::TransmogOutfitSlotAndOptionInfo const& slotInfo : TransmogMgr::GetAllSlots())
{
auto viewedOutfitSlot = viewedOutfit.ModifyValue(&UF::TransmogOutfitData::Slots, slotInfo.SlotIndex);
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::Slot), AsUnderlyingType(slotInfo.Slot->GetSlot()));
TransmogOutfitSlotOption slotOption = slotInfo.SlotOption ? slotInfo.SlotOption->GetOption() : TransmogOutfitSlotOption::None;
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::SlotOption), AsUnderlyingType(slotOption));
if (Item const* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slotInfo.Slot->InventorySlotEnum))
{
if (item->GetTemplate()->GetWeaponTransmogOutfitSlotOption() == slotOption)
{
if (ItemModifiedAppearanceEntry const* itemModifiedAppearance = item->GetItemModifiedAppearance())
{
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::ItemModifiedAppearanceID), itemModifiedAppearance->ID);
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::AppearanceDisplayType), AsUnderlyingType(TransmogOutfitDisplayType::Equipped));
}
}
}
switch (slotOption)
{
case TransmogOutfitSlotOption::ArtifactSpecOne:
case TransmogOutfitSlotOption::ArtifactSpecTwo:
case TransmogOutfitSlotOption::ArtifactSpecThree:
case TransmogOutfitSlotOption::ArtifactSpecFour:
// artifacts are disabled by default
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::AppearanceDisplayType), AsUnderlyingType(TransmogOutfitDisplayType::Disabled));
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::IllusionDisplayType), AsUnderlyingType(TransmogOutfitDisplayType::Disabled));
break;
case TransmogOutfitSlotOption::None:
break;
default:
SetUpdateFieldValue(viewedOutfitSlot.ModifyValue(&UF::TransmogOutfitSlotData::IllusionDisplayType), AsUnderlyingType(TransmogOutfitDisplayType::Equipped));
break;
}
}
}
for (uint8 equipSlot = EQUIPMENT_SLOT_START; equipSlot < EQUIPMENT_SLOT_END; ++equipSlot)
SetVisibleItemSlot(equipSlot, GetItemByPos(INVENTORY_SLOT_BAG_0, equipSlot));
}
std::string Player::GetCharacterSelectOutfit() const
{
std::vector<UF::TransmogOutfitData const*> outfits;
for (auto const& [_, transmogOutfit] : m_activePlayerData->TransmogOutfits)
{
if (!transmogOutfit.value.OutfitInfo->SituationsEnabled)
continue;
bool isCharacterSelect = transmogOutfit.value.Situations.FindIndexIf([](UF::TransmogOutfitSituationInfo const& situation)
{
return sTransmogSituationStore.AssertEntry(situation.SituationID)->GetSituation() == TransmogSituation::LocationCharacterSelect;
}) >= 0;
if (!isCharacterSelect)
continue;
outfits.push_back(&transmogOutfit.value);
}
UF::TransmogOutfitData const* outfit = &*m_activePlayerData->ViewedOutfit;
if (!outfits.empty())
outfit = Trinity::Containers::SelectRandomContainerElement(outfits);
auto isTransmogDisplayed = [](TransmogOutfitDisplayType displayType)
{
return displayType == TransmogOutfitDisplayType::Assigned || displayType == TransmogOutfitDisplayType::Hidden;
};
std::string result;
for (EquipmentSlots i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i = EquipmentSlots(i + 1))
{
TransmogOutfitSlotOption transmogSlotOption = TransmogOutfitSlotOption::None;
switch (i)
{
case EQUIPMENT_SLOT_MAINHAND:
transmogSlotOption = static_cast<TransmogOutfitSlotOption>(m_activePlayerData->TransmogMetadata->StampedOptionMainHand);
break;
case EQUIPMENT_SLOT_OFFHAND:
transmogSlotOption = static_cast<TransmogOutfitSlotOption>(m_activePlayerData->TransmogMetadata->StampedOptionOffHand);
break;
default:
break;
}
if (TransmogMgr::TransmogOutfitSlotAndOptionInfo const* slotInfo = TransmogMgr::GetSlotAndOption(i, transmogSlotOption))
{
UF::TransmogOutfitSlotData const& transmogOutfitSlot = outfit->Slots[slotInfo->SlotIndex];
uint32 itemModifiedAppearanceId = transmogOutfitSlot.ItemModifiedAppearanceID;
if (!isTransmogDisplayed(static_cast<TransmogOutfitDisplayType>(*transmogOutfitSlot.AppearanceDisplayType)))
itemModifiedAppearanceId = m_activePlayerData->ViewedOutfit->Slots[slotInfo->SlotIndex].ItemModifiedAppearanceID;
uint32 spellItemEnchantmentId = transmogOutfitSlot.SpellItemEnchantmentID;
if (!isTransmogDisplayed(static_cast<TransmogOutfitDisplayType>(*transmogOutfitSlot.IllusionDisplayType)))
spellItemEnchantmentId = m_activePlayerData->ViewedOutfit->Slots[slotInfo->SlotIndex].SpellItemEnchantmentID;
InventoryType inventoryType = INVTYPE_NON_EQUIP;
int32 displayId = 0;
uint16 itemVisual = 0;
uint8 subClass = 0;
uint32 secondaryItemModifiedAppearanceId = 0;
if (ItemModifiedAppearanceEntry const* itemModifiedAppearance = sItemModifiedAppearanceStore.LookupEntry(itemModifiedAppearanceId))
{
if (ItemEntry const* item = sItemStore.LookupEntry(itemModifiedAppearance->ItemID))
{
subClass = item->SubclassID;
inventoryType = static_cast<InventoryType>(item->InventoryType);
}
if (ItemAppearanceEntry const* itemAppearance = sItemAppearanceStore.LookupEntry(itemModifiedAppearance->ItemAppearanceID))
displayId = itemAppearance->ItemDisplayInfoID;
}
if (SpellItemEnchantmentEntry const* spellItemEnchantment = sSpellItemEnchantmentStore.LookupEntry(spellItemEnchantmentId))
itemVisual = spellItemEnchantment->ItemVisual;
if (TransmogOutfitSlotInfoEntry const* secondarySlot = sTransmogOutfitSlotInfoStore.LookupEntry(slotInfo->Slot->SecondarySlotID))
{
if (TransmogMgr::TransmogOutfitSlotAndOptionInfo const* secondarySlotInfo = TransmogMgr::GetSlotAndOption(secondarySlot->GetSlot(), transmogSlotOption))
{
UF::TransmogOutfitSlotData const& secondaryTransmogOutfitSlot = outfit->Slots[secondarySlotInfo->SlotIndex];
secondaryItemModifiedAppearanceId = secondaryTransmogOutfitSlot.ItemModifiedAppearanceID;
if (!isTransmogDisplayed(static_cast<TransmogOutfitDisplayType>(*secondaryTransmogOutfitSlot.AppearanceDisplayType)))
secondaryItemModifiedAppearanceId = m_activePlayerData->ViewedOutfit->Slots[secondarySlotInfo->SlotIndex].ItemModifiedAppearanceID;
}
}
Trinity::StringFormatTo(std::back_inserter(result), "{} {} {} {} {} ", inventoryType, displayId, itemVisual, subClass, secondaryItemModifiedAppearanceId);
}
else
result += "0 0 0 0 0 "sv;
}
for (uint32 i = EQUIPMENT_SLOT_END; i < REAGENT_BAG_SLOT_END; ++i)
result += "0 0 0 0 0 "sv;
return result;
}
void Player::OnPhaseChange()
{
Unit::OnPhaseChange();
+36 -4
View File
@@ -138,6 +138,13 @@ namespace WorldPackets
struct TraitConfig;
struct TraitEntry;
}
namespace Transmogrification
{
struct TransmogOutfitDataInfo;
struct TransmogOutfitSituationInfo;
struct TransmogOutfitSlotData;
}
}
TC_GAME_API uint32 GetBagSize(Bag const* bag);
@@ -337,7 +344,8 @@ enum ActionButtonType
ACTION_BUTTON_CMACRO = ACTION_BUTTON_C | ACTION_BUTTON_MACRO,
ACTION_BUTTON_COMPANION = 0x50,
ACTION_BUTTON_MOUNT = 0x60,
ACTION_BUTTON_ITEM = 0x80
ACTION_BUTTON_ITEM = 0x80,
ACTION_BUTTON_OUTFIT = 0x90
};
enum class HonorGainSource : uint8
@@ -558,6 +566,7 @@ enum PlayerLocalFlags
PLAYER_LOCAL_FLAG_CHARACTER_BANK_DISABLED = 0x00080000,
PLAYER_LOCAL_FLAG_CHARACTER_BANK_CONVERSION_FAILED = 0x00100000,
PLAYER_LOCAL_FLAG_ACCOUNT_BANK_DISABLED = 0x00200000,
PLAYER_LOCAL_FLAG_FREE_TRANSMOG_CLAIMED = 0x00400000,
};
DEFINE_ENUM_FLAG(PlayerLocalFlags);
@@ -596,6 +605,8 @@ enum PlayerExtraFlags
PLAYER_EXTRA_HAS_RACE_CHANGED = 0x0200,
PLAYER_EXTRA_GRANTED_LEVELS_FROM_RAF = 0x0400,
PLAYER_EXTRA_LEVEL_BOOSTED = 0x0800,
PLAYER_EXTRA_FLAG_FREE_TRANSMOG_CLAIMED = 0x1000,
};
// 2^n values
@@ -947,6 +958,9 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS,
PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS,
PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS,
PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFIT,
PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFIT_SITUATION,
PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFIT_SLOT,
PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFITS,
PLAYER_LOGIN_QUERY_LOAD_BG_DATA,
PLAYER_LOGIN_QUERY_LOAD_GLYPHS,
@@ -1292,6 +1306,8 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void SetBeenGrantedLevelsFromRaF() { m_ExtraFlags |= PLAYER_EXTRA_GRANTED_LEVELS_FROM_RAF; }
bool HasLevelBoosted() const { return (m_ExtraFlags & PLAYER_EXTRA_LEVEL_BOOSTED) != 0; }
void SetHasLevelBoosted() { m_ExtraFlags |= PLAYER_EXTRA_LEVEL_BOOSTED; }
bool HasClaimedFreeTransmog() const { return (m_ExtraFlags & PLAYER_EXTRA_FLAG_FREE_TRANSMOG_CLAIMED) != 0; }
void SetHasClaimedFreeTransmog() { m_ExtraFlags |= PLAYER_EXTRA_FLAG_FREE_TRANSMOG_CLAIMED; }
uint32 GetXP() const { return m_activePlayerData->XP; }
uint32 GetXPForNextLevel() const { return m_activePlayerData->NextLevelXP; }
@@ -1594,7 +1610,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void ApplyEquipCooldown(Item* pItem);
void QuickEquipItem(uint16 pos, Item* pItem);
void VisualizeItem(uint8 slot, Item* pItem);
void SetVisibleItemSlot(uint8 slot, Item* pItem);
void SetVisibleItemSlot(uint8 slot, Item const* item);
Item* BankItem(ItemPosCountVec const& dest, Item* pItem, bool update);
void RemoveItem(uint8 bag, uint8 slot, bool update);
void MoveItemFromInventory(uint8 bag, uint8 slot, bool update);
@@ -3057,6 +3073,19 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
bool CanEnableWarModeInArea() const;
void UpdateWarModeAuras();
void AddUnlockedTransmogOutfits(std::span<int32 const> transmogOutfitIds);
void AddUnlockedTransmogOutfit(int32 transmogOutfitIds) { AddUnlockedTransmogOutfits(std::span(&transmogOutfitIds, 1)); }
void CreateTransmogOutfit(uint32 id, WorldPackets::Transmogrification::TransmogOutfitDataInfo const& outfitData);
void InitializeNewTransmogOutfit(UF::MutableFieldReference<UF::TransmogOutfitData, false> outfit,
uint32 id, WorldPackets::Transmogrification::TransmogOutfitDataInfo const& outfitData);
bool UpdateTransmogOutfit(uint32 id, WorldPackets::Transmogrification::TransmogOutfitDataInfo const& outfitData);
void UpdateTransmogOutfitSituations(uint32 id, bool situationsEnabled, std::span<WorldPackets::Transmogrification::TransmogOutfitSituationInfo const> situations);
void UpdateTransmogOutfitSlots(uint32 id, std::span<WorldPackets::Transmogrification::TransmogOutfitSlotData const> slots);
void EquipTransmogOutfit(uint32 id, TransmogSituationTrigger trigger, Optional<bool> locked);
std::string GetCharacterSelectOutfit() const;
std::string GetDebugInfo() const override;
UF::UpdateField<UF::PlayerData, int32(WowCS::EntityFragment::CGObject), TYPEID_PLAYER> m_playerData;
@@ -3150,7 +3179,9 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void _LoadDeclinedNames(PreparedQueryResult result);
void _LoadArenaTeamInfo(PreparedQueryResult result);
void _LoadEquipmentSets(PreparedQueryResult result);
void _LoadTransmogOutfits(PreparedQueryResult result);
void _LoadTransmogCustomSets(PreparedQueryResult result);
void _LoadTransmogOutfits(PreparedQueryResult setsResult, PreparedQueryResult situationsResult, PreparedQueryResult slotsResult,
int32 equippedTransmogOutfitId, bool locked);
void _LoadBGData(PreparedQueryResult result);
void _LoadGlyphs(PreparedQueryResult result);
void _LoadTalents(PreparedQueryResult result);
@@ -3182,7 +3213,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void _SaveSkills(CharacterDatabaseTransaction trans);
void _SaveSpells(CharacterDatabaseTransaction trans);
void _SaveStoredAuraTeleportLocations(CharacterDatabaseTransaction trans);
void _SaveEquipmentSets(CharacterDatabaseTransaction trans);
void _SaveTransmogOutfits(CharacterDatabaseTransaction trans);
void _SaveBGData(CharacterDatabaseTransaction trans);
void _SaveGlyphs(CharacterDatabaseTransaction trans) const;
void _SaveTalents(CharacterDatabaseTransaction trans);
@@ -3333,6 +3364,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
std::unique_ptr<Runes> m_runes;
EquipmentSetContainer _equipmentSets;
std::set<uint32> m_changedTransmogOutfits;
bool CanNeverSee(WorldObject const* obj, bool ignorePhaseShift = false) const override;
bool CanAlwaysSee(WorldObject const* obj) const override;