aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-07-05 22:07:35 +0200
committerShauren <shauren.trinity@gmail.com>2016-07-05 22:07:35 +0200
commitf7883bd5251a759da1ca8be3ba6f6cead36723ec (patch)
treeaffce8f9ad4b343ba936ad6effa2127ab7d831b1 /src/server/game/Handlers
parentbc81ae70bc350a3decead610f1b17452bd44eec4 (diff)
Core/Transmog: Implemented transmog collection and updated transmog handling
Diffstat (limited to 'src/server/game/Handlers')
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp39
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp158
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp4
-rw-r--r--src/server/game/Handlers/TransmogrificationHandler.cpp293
-rw-r--r--src/server/game/Handlers/VoidStorageHandler.cpp2
5 files changed, 334 insertions, 162 deletions
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 63a37b42efd..c3bea2abb34 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1653,10 +1653,16 @@ void WorldSession::HandleEquipmentSetSave(WorldPackets::EquipmentSet::SaveEquipm
else
{
saveEquipmentSet.Set.Pieces[i].Clear();
- if (saveEquipmentSet.Set.Appearances[i] && !sItemModifiedAppearanceStore.LookupEntry(saveEquipmentSet.Set.Appearances[i]))
- return;
+ if (saveEquipmentSet.Set.Appearances[i])
+ {
+ if (!sItemModifiedAppearanceStore.LookupEntry(saveEquipmentSet.Set.Appearances[i]))
+ return;
- // TODO: validata whether appearance is known
+ bool hasAppearance, isTemporary;
+ std::tie(hasAppearance, isTemporary) = GetCollectionMgr()->HasItemAppearance(saveEquipmentSet.Set.Appearances[i]);
+ if (!hasAppearance)
+ return;
+ }
}
}
else
@@ -1672,6 +1678,33 @@ void WorldSession::HandleEquipmentSetSave(WorldPackets::EquipmentSet::SaveEquipm
saveEquipmentSet.Set.Enchants[0] = 0;
saveEquipmentSet.Set.Enchants[1] = 0;
}
+ else
+ {
+ auto validateIllusion = [this](uint32 enchantId) -> bool
+ {
+ SpellItemEnchantmentEntry const* illusion = sSpellItemEnchantmentStore.LookupEntry(enchantId);
+ if (!illusion)
+ return false;
+
+ if (!illusion->ItemVisual || !(illusion->Flags & ENCHANTMENT_COLLECTABLE))
+ return false;
+
+ if (PlayerConditionEntry const* condition = sPlayerConditionStore.LookupEntry(illusion->PlayerConditionID))
+ if (!sConditionMgr->IsPlayerMeetingCondition(_player, condition))
+ return false;
+
+ if (illusion->ScalingClassRestricted > 0 && uint8(illusion->ScalingClassRestricted) != _player->getClass())
+ return false;
+
+ return true;
+ };
+
+ if (saveEquipmentSet.Set.Enchants[0] && !validateIllusion(saveEquipmentSet.Set.Enchants[0]))
+ return;
+
+ if (saveEquipmentSet.Set.Enchants[1] && !validateIllusion(saveEquipmentSet.Set.Enchants[1]))
+ return;
+ }
_player->SetEquipmentSet(saveEquipmentSet.Set);
}
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index b5c8e6bdc67..938523afb8a 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -1096,164 +1096,6 @@ void WorldSession::HandleItemRefund(WorldPackets::Item::ItemPurchaseRefund& pack
GetPlayer()->RefundItem(item);
}
-void WorldSession::HandleTransmogrifyItems(WorldPackets::Item::TransmogrifyItems& transmogrifyItems)
-{
- Player* player = GetPlayer();
- // Validate
- if (!player->GetNPCIfCanInteractWith(transmogrifyItems.Npc, UNIT_NPC_FLAG_TRANSMOGRIFIER))
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s not found or player can't interact with it.", transmogrifyItems.Npc.ToString().c_str());
- return;
- }
-
- int64 cost = 0;
- std::unordered_map<Item*, Item*> transmogItems;
- std::unordered_map<Item*, std::pair<VoidStorageItem*, BonusData>> transmogVoidItems;
- std::vector<Item*> resetAppearanceItems;
-
- for (WorldPackets::Item::TransmogrifyItem const& transmogItem : transmogrifyItems.Items)
- {
- // slot of the transmogrified item
- if (transmogItem.Slot >= EQUIPMENT_SLOT_END)
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify wrong slot (%u) when transmogrifying items.", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.Slot);
- return;
- }
-
- // transmogrified item
- Item* itemTransmogrified = player->GetItemByPos(INVENTORY_SLOT_BAG_0, transmogItem.Slot);
- if (!itemTransmogrified)
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify an invalid item in a valid slot (slot: %u).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.Slot);
- return;
- }
- if (player->CanUseItem(itemTransmogrified->GetTemplate()) != EQUIP_ERR_OK)
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify an unequippable item in a valid slot (slot: %u).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.Slot);
- return;
- }
-
- WorldPackets::Item::ItemInstance itemInstance;
- BonusData const* bonus = nullptr;
- if (transmogItem.SrcItemGUID)
- {
- // guid of the transmogrifier item
- Item* itemTransmogrifier = player->GetItemByGuid(*transmogItem.SrcItemGUID);
- if (!itemTransmogrifier)
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify with an invalid item (%s).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SrcItemGUID->ToString().c_str());
- return;
- }
- if (player->CanUseItem(itemTransmogrifier->GetTemplate()) != EQUIP_ERR_OK)
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify with an unequippable item (%s).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SrcItemGUID->ToString().c_str());
- return;
- }
-
- itemInstance.Initialize(itemTransmogrifier);
- bonus = itemTransmogrifier->GetBonus();
- transmogItems[itemTransmogrified] = itemTransmogrifier;
- }
- else if (transmogItem.SrcVoidItemGUID)
- {
- // guid of the transmogrifier item
- uint8 slot;
- VoidStorageItem* itemTransmogrifier = player->GetVoidStorageItem(transmogItem.SrcVoidItemGUID->GetCounter(), slot);
- if (!itemTransmogrifier)
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify with an invalid void storage item (%s).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SrcVoidItemGUID->ToString().c_str());
- return;
- }
- ItemTemplate const * transmogrifierTemplate = sObjectMgr->GetItemTemplate(itemTransmogrifier->ItemEntry);
- if (player->CanUseItem(transmogrifierTemplate) != EQUIP_ERR_OK)
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify with an unequippable void storage item (%s).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SrcVoidItemGUID->ToString().c_str());
- return;
- }
-
- itemInstance.Initialize(itemTransmogrifier);
- std::pair<VoidStorageItem*, BonusData>& transmogData = transmogVoidItems[itemTransmogrified];
- transmogData.first = itemTransmogrifier;
- transmogData.second.Initialize(itemInstance);
- bonus = &transmogData.second;
- }
- else
- {
- resetAppearanceItems.push_back(itemTransmogrified);
- continue;
- }
-
- // entry of transmogrifier and from packet
- if (itemInstance != transmogItem.Item)
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify with an invalid item instance data for %s.", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SrcItemGUID->ToString().c_str());
- return;
- }
-
- // validity of the transmogrification items
- if (!Item::CanTransmogrifyItemWithItem(itemTransmogrified, transmogItem.Item, bonus))
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) failed CanTransmogrifyItemWithItem (%u with %u).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), itemTransmogrified->GetEntry(), transmogItem.Item.ItemID);
- return;
- }
-
- // add cost
- cost += itemTransmogrified->GetSpecialPrice();
- }
-
- if (cost) // 0 cost if reverting look
- {
- if (!player->HasEnoughMoney(cost))
- return;
- player->ModifyMoney(-cost);
- }
-
- // Everything is fine, proceed
- for (auto& transmogPair : transmogItems)
- {
- Item* transmogrified = transmogPair.first;
- Item* transmogrifier = transmogPair.second;
-
- transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_ITEM_ID, transmogrifier->GetEntry());
- transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_MOD, transmogrifier->GetAppearanceModId());
- player->SetVisibleItemSlot(transmogrified->GetSlot(), transmogrified);
-
- transmogrified->SetNotRefundable(player);
- transmogrified->ClearSoulboundTradeable(player);
-
- transmogrifier->SetNotRefundable(player);
- transmogrifier->ClearSoulboundTradeable(player);
-
- if (transmogrifier->GetTemplate()->GetBonding() == BIND_WHEN_EQUIPED || transmogrifier->GetTemplate()->GetBonding() == BIND_WHEN_USE)
- transmogrifier->SetBinding(true);
-
- transmogrified->SetState(ITEM_CHANGED, player);
- }
-
- for (auto& transmogVoirPair : transmogVoidItems)
- {
- Item* transmogrified = transmogVoirPair.first;
- VoidStorageItem* transmogrifier = transmogVoirPair.second.first;
- BonusData& bonus = transmogVoirPair.second.second;
-
- transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_ITEM_ID, transmogrifier->ItemEntry);
- transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_MOD, bonus.AppearanceModID);
- player->SetVisibleItemSlot(transmogrified->GetSlot(), transmogrified);
-
- transmogrified->SetNotRefundable(player);
- transmogrified->ClearSoulboundTradeable(player);
- transmogrified->SetState(ITEM_CHANGED, player);
- }
-
- for (Item* item : resetAppearanceItems)
- {
- item->SetModifier(ITEM_MODIFIER_TRANSMOG_ITEM_ID, 0);
- item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_MOD, 0);
- item->SetState(ITEM_CHANGED, player);
- player->SetVisibleItemSlot(item->GetSlot(), item);
- }
-}
-
bool WorldSession::CanUseBank(ObjectGuid bankerGUID) const
{
// bankerGUID parameter is optional, set to 0 by default.
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 8ce4a88ef5a..4bfada8aab3 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -17,6 +17,7 @@
*/
#include "WorldSession.h"
+#include "CollectionMgr.h"
#include "Common.h"
#include "Config.h"
#include "GameObjectAI.h"
@@ -111,6 +112,7 @@ void WorldSession::HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet)
{
item->SetState(ITEM_CHANGED, user);
item->SetBinding(true);
+ GetCollectionMgr()->AddItemAppearance(item);
}
}
@@ -544,7 +546,7 @@ void WorldSession::HandleMirrorImageDataRequest(WorldPackets::Spells::GetMirrorI
(slot == EQUIPMENT_SLOT_BACK && player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK)))
itemDisplayId = 0;
else if (Item const* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
- itemDisplayId = item->GetDisplayId();
+ itemDisplayId = item->GetDisplayId(player);
else
itemDisplayId = 0;
diff --git a/src/server/game/Handlers/TransmogrificationHandler.cpp b/src/server/game/Handlers/TransmogrificationHandler.cpp
new file mode 100644
index 00000000000..0d8406beb45
--- /dev/null
+++ b/src/server/game/Handlers/TransmogrificationHandler.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "WorldSession.h"
+#include "CollectionMgr.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+#include "TransmogrificationPackets.h"
+
+void WorldSession::HandleTransmogrifyItems(WorldPackets::Transmogrification::TransmogrifyItems& transmogrifyItems)
+{
+ Player* player = GetPlayer();
+ // Validate
+ if (!player->GetNPCIfCanInteractWith(transmogrifyItems.Npc, UNIT_NPC_FLAG_TRANSMOGRIFIER))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s not found or player can't interact with it.", transmogrifyItems.Npc.ToString().c_str());
+ return;
+ }
+
+ int64 cost = 0;
+ std::unordered_map<Item*, uint32> transmogItems;
+ std::unordered_map<Item*, uint32> illusionItems;
+
+ std::vector<Item*> resetAppearanceItems;
+ std::vector<Item*> resetIllusionItems;
+ std::vector<uint32> bindAppearances;
+
+ for (WorldPackets::Transmogrification::TransmogrifyItem const& transmogItem : transmogrifyItems.Items)
+ {
+ // slot of the transmogrified item
+ if (transmogItem.Slot >= EQUIPMENT_SLOT_END)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify wrong slot (%u) when transmogrifying items.", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.Slot);
+ return;
+ }
+
+ // transmogrified item
+ Item* itemTransmogrified = player->GetItemByPos(INVENTORY_SLOT_BAG_0, transmogItem.Slot);
+ if (!itemTransmogrified)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify an invalid item in a valid slot (slot: %u).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.Slot);
+ return;
+ }
+
+ if (transmogItem.ItemModifiedAppearanceID)
+ {
+ ItemModifiedAppearanceEntry const* itemModifiedAppearance = sItemModifiedAppearanceStore.LookupEntry(transmogItem.ItemModifiedAppearanceID);
+ if (!itemModifiedAppearance)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify using invalid appearance (%d).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.ItemModifiedAppearanceID);
+ return;
+ }
+
+ bool hasAppearance, isTemporary;
+ std::tie(hasAppearance, isTemporary) = GetCollectionMgr()->HasItemAppearance(transmogItem.ItemModifiedAppearanceID);
+ if (!hasAppearance)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify using appearance he has not collected (%d).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.ItemModifiedAppearanceID);
+ return;
+ }
+ ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemModifiedAppearance->ItemID);
+ if (player->CanUseItem(itemTemplate) != EQUIP_ERR_OK)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify using appearance he can never use (%d).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.ItemModifiedAppearanceID);
+ return;
+ }
+
+ // validity of the transmogrification items
+ if (!Item::CanTransmogrifyItemWithItem(itemTransmogrified, itemModifiedAppearance))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s failed CanTransmogrifyItemWithItem (%u with appearance %d).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), itemTransmogrified->GetEntry(), transmogItem.ItemModifiedAppearanceID);
+ return;
+ }
+
+ transmogItems[itemTransmogrified] = transmogItem.ItemModifiedAppearanceID;
+ if (isTemporary)
+ bindAppearances.push_back(transmogItem.ItemModifiedAppearanceID);
+
+ // add cost
+ cost += itemTransmogrified->GetSpecialPrice();
+ }
+ else
+ resetAppearanceItems.push_back(itemTransmogrified);
+
+ if (transmogItem.SpellItemEnchantmentID)
+ {
+ if (transmogItem.Slot != EQUIPMENT_SLOT_MAINHAND && transmogItem.Slot != EQUIPMENT_SLOT_OFFHAND)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify illusion into non-weapon slot (%u).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.Slot);
+ return;
+ }
+
+ SpellItemEnchantmentEntry const* illusion = sSpellItemEnchantmentStore.LookupEntry(transmogItem.SpellItemEnchantmentID);
+ if (!illusion)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify illusion using invalid enchant (%d).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SpellItemEnchantmentID);
+ return;
+ }
+
+ if (!illusion->ItemVisual || !(illusion->Flags & ENCHANTMENT_COLLECTABLE))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify illusion using not allowed enchant (%d).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SpellItemEnchantmentID);
+ return;
+ }
+
+ if (PlayerConditionEntry const* condition = sPlayerConditionStore.LookupEntry(illusion->PlayerConditionID))
+ {
+ if (!sConditionMgr->IsPlayerMeetingCondition(player, condition))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify illusion using not collected enchant (%d).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SpellItemEnchantmentID);
+ return;
+ }
+ }
+
+ if (illusion->ScalingClassRestricted > 0 && uint8(illusion->ScalingClassRestricted) != player->getClass())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify illusion using not allowed class enchant (%d).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SpellItemEnchantmentID);
+ return;
+ }
+
+ illusionItems[itemTransmogrified] = transmogItem.SpellItemEnchantmentID;
+ cost += illusion->TransmogCost;
+ }
+ else
+ resetIllusionItems.push_back(itemTransmogrified);
+ }
+
+ if (cost) // 0 cost if reverting look
+ {
+ if (!player->HasEnoughMoney(cost))
+ return;
+ player->ModifyMoney(-cost);
+ }
+
+ // Everything is fine, proceed
+ for (auto& transmogPair : transmogItems)
+ {
+ Item* transmogrified = transmogPair.first;
+
+ if (!transmogrifyItems.CurrentSpecOnly)
+ {
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, transmogPair.second);
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1, 0);
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2, 0);
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3, 0);
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4, 0);
+ }
+ else
+ {
+ if (!transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1))
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1, transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS));
+ if (!transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2))
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2, transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS));
+ if (!transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3))
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3, transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS));
+ if (!transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4))
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4, transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS));
+ transmogrified->SetModifier(AppearanceModifierSlotBySpec[player->GetActiveTalentGroup()], transmogPair.second);
+ }
+
+ player->SetVisibleItemSlot(transmogrified->GetSlot(), transmogrified);
+
+ transmogrified->SetNotRefundable(player);
+ transmogrified->ClearSoulboundTradeable(player);
+ transmogrified->SetState(ITEM_CHANGED, player);
+ }
+
+ for (auto& illusionPair : illusionItems)
+ {
+ Item* transmogrified = illusionPair.first;
+
+ if (!transmogrifyItems.CurrentSpecOnly)
+ {
+ transmogrified->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS, illusionPair.second);
+ transmogrified->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1, 0);
+ transmogrified->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2, 0);
+ transmogrified->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3, 0);
+ transmogrified->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4, 0);
+ }
+ else
+ {
+ if (!transmogrified->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1))
+ transmogrified->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1, transmogrified->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS));
+ if (!transmogrified->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2))
+ transmogrified->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2, transmogrified->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS));
+ if (!transmogrified->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3))
+ transmogrified->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3, transmogrified->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS));
+ if (!transmogrified->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4))
+ transmogrified->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4, transmogrified->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS));
+ transmogrified->SetModifier(IllusionModifierSlotBySpec[player->GetActiveTalentGroup()], illusionPair.second);
+ }
+
+ player->SetVisibleItemSlot(transmogrified->GetSlot(), transmogrified);
+
+ transmogrified->SetNotRefundable(player);
+ transmogrified->ClearSoulboundTradeable(player);
+ transmogrified->SetState(ITEM_CHANGED, player);
+ }
+
+ for (Item* item : resetAppearanceItems)
+ {
+ if (!transmogrifyItems.CurrentSpecOnly)
+ {
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, 0);
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1, 0);
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2, 0);
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3, 0);
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4, 0);
+ }
+ else
+ {
+ if (!item->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1))
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1, item->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS));
+ if (!item->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2))
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2, item->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS));
+ if (!item->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3))
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3, item->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS));
+ if (!item->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4))
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4, item->GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS));
+ item->SetModifier(AppearanceModifierSlotBySpec[player->GetActiveTalentGroup()], 0);
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS, 0);
+ }
+
+ item->SetState(ITEM_CHANGED, player);
+ player->SetVisibleItemSlot(item->GetSlot(), item);
+ }
+
+ for (Item* item : resetIllusionItems)
+ {
+ if (!transmogrifyItems.CurrentSpecOnly)
+ {
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS, 0);
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1, 0);
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2, 0);
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3, 0);
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4, 0);
+ }
+ else
+ {
+ if (!item->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1))
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1, item->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS));
+ if (!item->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2))
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2, item->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS));
+ if (!item->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3))
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3, item->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS));
+ if (!item->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4))
+ item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4, item->GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS));
+ item->SetModifier(IllusionModifierSlotBySpec[player->GetActiveTalentGroup()], 0);
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, 0);
+ }
+
+ item->SetState(ITEM_CHANGED, player);
+ player->SetVisibleItemSlot(item->GetSlot(), item);
+ }
+
+ for (uint32 itemModifedAppearanceId : bindAppearances)
+ {
+ std::unordered_set<ObjectGuid> itemsProvidingAppearance = GetCollectionMgr()->GetItemsProvidingTemporaryAppearance(itemModifedAppearanceId);
+ for (ObjectGuid const& itemGuid : itemsProvidingAppearance)
+ {
+ if (Item* item = player->GetItemByGuid(itemGuid))
+ {
+ item->SetNotRefundable(player);
+ item->ClearSoulboundTradeable(player);
+ GetCollectionMgr()->AddItemAppearance(item);
+ }
+ }
+ }
+}
+
+void WorldSession::HandleTransmogAppearanceSetFavorite(WorldPackets::Transmogrification::TransmogAppearanceSetFavorite& transmogAppearanceSetFavorite)
+{
+ bool hasAppearance, isTemporary;
+ std::tie(hasAppearance, isTemporary) = GetCollectionMgr()->HasItemAppearance(transmogAppearanceSetFavorite.ItemModifiedAppearanceID);
+ if (!hasAppearance || isTemporary)
+ return;
+
+ GetCollectionMgr()->SetAppearanceIsFavorite(transmogAppearanceSetFavorite.ItemModifiedAppearanceID, transmogAppearanceSetFavorite.IsFavorite);
+}
diff --git a/src/server/game/Handlers/VoidStorageHandler.cpp b/src/server/game/Handlers/VoidStorageHandler.cpp
index 637566d894a..6575f7b045c 100644
--- a/src/server/game/Handlers/VoidStorageHandler.cpp
+++ b/src/server/game/Handlers/VoidStorageHandler.cpp
@@ -16,6 +16,7 @@
*/
#include "Common.h"
+#include "CollectionMgr.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "World.h"
@@ -196,6 +197,7 @@ void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStor
item->SetGuidValue(ITEM_FIELD_CREATOR, itemVS->CreatorGuid);
item->SetModifier(ITEM_MODIFIER_UPGRADE_ID, itemVS->ItemUpgradeId);
item->SetBinding(true);
+ GetCollectionMgr()->AddItemAppearance(item);
voidStorageTransferChanges.RemovedItems.push_back(ObjectGuid::Create<HighGuid::Item>(itemVS->ItemId));