diff options
| author | Shauren <shauren.trinity@gmail.com> | 2016-07-05 22:07:35 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2016-07-05 22:07:35 +0200 |
| commit | f7883bd5251a759da1ca8be3ba6f6cead36723ec (patch) | |
| tree | affce8f9ad4b343ba936ad6effa2127ab7d831b1 /src/server/game/Handlers | |
| parent | bc81ae70bc350a3decead610f1b17452bd44eec4 (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.cpp | 39 | ||||
| -rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 158 | ||||
| -rw-r--r-- | src/server/game/Handlers/SpellHandler.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Handlers/TransmogrificationHandler.cpp | 293 | ||||
| -rw-r--r-- | src/server/game/Handlers/VoidStorageHandler.cpp | 2 |
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)); |
