aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/ItemHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/ItemHandler.cpp')
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp207
1 files changed, 84 insertions, 123 deletions
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 9c1afcc3785..b241dac38d0 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -1109,142 +1109,93 @@ void WorldSession::HandleItemRefund(WorldPacket &recvData)
GetPlayer()->RefundItem(item);
}
-void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData)
+void WorldSession::HandleTransmogrifyItems(WorldPackets::Item::TransmogrifyItems& transmogrifyItems)
{
Player* player = GetPlayer();
-
- // Read data
- uint32 count = recvData.ReadBits(22);
-
- if (count >= EQUIPMENT_SLOT_END)
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) sent a wrong count (%u) when transmogrifying items.", player->GetGUID().ToString().c_str(), player->GetName().c_str(), count);
- recvData.rfinish();
- return;
- }
-
- std::vector<ObjectGuid> itemGuids(count, ObjectGuid());
- std::vector<uint32> newEntries(count, 0);
- std::vector<uint32> slots(count, 0);
-
- for (uint8 i = 0; i < count; ++i)
- {
- itemGuids[i][0] = recvData.ReadBit();
- itemGuids[i][5] = recvData.ReadBit();
- itemGuids[i][6] = recvData.ReadBit();
- itemGuids[i][2] = recvData.ReadBit();
- itemGuids[i][3] = recvData.ReadBit();
- itemGuids[i][7] = recvData.ReadBit();
- itemGuids[i][4] = recvData.ReadBit();
- itemGuids[i][1] = recvData.ReadBit();
- }
-
- ObjectGuid npcGuid;
- npcGuid[7] = recvData.ReadBit();
- npcGuid[3] = recvData.ReadBit();
- npcGuid[5] = recvData.ReadBit();
- npcGuid[6] = recvData.ReadBit();
- npcGuid[1] = recvData.ReadBit();
- npcGuid[4] = recvData.ReadBit();
- npcGuid[0] = recvData.ReadBit();
- npcGuid[2] = recvData.ReadBit();
-
- recvData.FlushBits();
-
- for (uint32 i = 0; i < count; ++i)
- {
- recvData >> newEntries[i];
-
- recvData.ReadByteSeq(itemGuids[i][1]);
- recvData.ReadByteSeq(itemGuids[i][5]);
- recvData.ReadByteSeq(itemGuids[i][0]);
- recvData.ReadByteSeq(itemGuids[i][4]);
- recvData.ReadByteSeq(itemGuids[i][6]);
- recvData.ReadByteSeq(itemGuids[i][7]);
- recvData.ReadByteSeq(itemGuids[i][3]);
- recvData.ReadByteSeq(itemGuids[i][2]);
-
- recvData >> slots[i];
- }
-
- recvData.ReadByteSeq(npcGuid[7]);
- recvData.ReadByteSeq(npcGuid[2]);
- recvData.ReadByteSeq(npcGuid[5]);
- recvData.ReadByteSeq(npcGuid[4]);
- recvData.ReadByteSeq(npcGuid[3]);
- recvData.ReadByteSeq(npcGuid[1]);
- recvData.ReadByteSeq(npcGuid[6]);
- recvData.ReadByteSeq(npcGuid[0]);
-
// Validate
-
- if (!player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_TRANSMOGRIFIER))
+ 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.", npcGuid.ToString().c_str());
+ 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::vector<Item*> transmogrifier(count, NULL);
- std::vector<Item*> transmogrified(count, NULL);
+ std::unordered_map<Item*, Item*> transmogItems;
+ std::unordered_map<Item*, std::pair<VoidStorageItem*, BonusData>> transmogVoidItems;
+ std::vector<Item*> resetAppearanceItems;
- for (uint8 i = 0; i < count; ++i)
+ for (WorldPackets::Item::TransmogrifyItem const& transmogItem : transmogrifyItems.Items)
{
// slot of the transmogrified item
- if (slots[i] >= EQUIPMENT_SLOT_END)
+ if (transmogItem.Slot >= EQUIPMENT_SLOT_END)
{
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify %s with a wrong slot (%u) when transmogrifying items.", player->GetGUID().ToString().c_str(), player->GetName().c_str(), itemGuids[i].ToString().c_str(), slots[i]);
+ 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, slots[i]);
+ 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(), slots[i]);
+ 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 not resetting look
- Item* itemTransmogrifier = NULL;
- if (newEntries[i])
+ WorldPackets::Item::ItemInstance itemInstance;
+ BonusData const* bonus = nullptr;
+ if (transmogItem.SrcItemGUID)
{
- // entry of the transmogrifier item
- ItemTemplate const* proto = sObjectMgr->GetItemTemplate(newEntries[i]);
- if (!proto)
+ // 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 to an invalid item (entry: %u).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), newEntries[i]);
+ 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;
}
+ itemInstance.Initialize(itemTransmogrifier);
+ bonus = itemTransmogrifier->GetBonus();
+ transmogItems[itemTransmogrified] = itemTransmogrifier;
+ }
+ else if (transmogItem.SrcVoidItemGUID)
+ {
// guid of the transmogrifier item
- itemTransmogrifier = player->GetItemByGuid(itemGuids[i]);
+ 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 item (%s).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), itemGuids[i].ToString().c_str());
+ 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;
}
- // entry of transmogrifier and from packet
- if (itemTransmogrifier->GetEntry() != newEntries[i])
- {
- TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (%s, name: %s) tried to transmogrify with an invalid entry (entry: %u) for %s.", player->GetGUID().ToString().c_str(), player->GetName().c_str(), newEntries[i], itemGuids[i].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;
+ }
- // validity of the transmogrification items
- if (!Item::CanTransmogrifyItemWithItem(itemTransmogrified, itemTransmogrifier))
- {
- 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(), itemTransmogrifier->GetEntry());
- return;
- }
+ // 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.Item.ItemID, transmogItem.SrcItemGUID->ToString().c_str());
+ return;
+ }
- // add cost
- cost += itemTransmogrified->GetSpecialPrice();
+ // 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;
}
- transmogrifier[i] = itemTransmogrifier;
- transmogrified[i] = itemTransmogrified;
+ // add cost
+ cost += itemTransmogrified->GetSpecialPrice();
}
if (cost) // 0 cost if reverting look
@@ -1255,34 +1206,44 @@ void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData)
}
// Everything is fine, proceed
-
- for (uint8 i = 0; i < count; ++i)
+ for (auto& transmogPair : transmogItems)
{
- if (transmogrifier[i])
- {
- // Transmogrify
- transmogrified[i]->SetModifier(ITEM_MODIFIER_TRANSMOG_ITEM_ID, newEntries[i]);
- player->SetVisibleItemSlot(slots[i], transmogrified[i]);
+ Item* transmogrified = transmogPair.first;
+ Item* transmogrifier = transmogPair.second;
- transmogrified[i]->UpdatePlayedTime(player);
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_ITEM_ID, transmogrifier->GetEntry());
+ transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_MOD, transmogrifier->GetAppearanceModId());
+ player->SetVisibleItemSlot(transmogrified->GetSlot(), transmogrified);
- transmogrified[i]->SetOwnerGUID(player->GetGUID());
- transmogrified[i]->SetNotRefundable(player);
- transmogrified[i]->ClearSoulboundTradeable(player);
+ transmogrified->SetNotRefundable(player);
+ transmogrified->ClearSoulboundTradeable(player);
- if (transmogrifier[i]->GetTemplate()->GetBonding() == BIND_WHEN_EQUIPED || transmogrifier[i]->GetTemplate()->GetBonding() == BIND_WHEN_USE)
- transmogrifier[i]->SetBinding(true);
+ transmogrifier->SetNotRefundable(player);
+ transmogrifier->ClearSoulboundTradeable(player);
- transmogrifier[i]->SetOwnerGUID(player->GetGUID());
- transmogrifier[i]->SetNotRefundable(player);
- transmogrifier[i]->ClearSoulboundTradeable(player);
- }
- else
- {
- // Reset
- transmogrified[i]->SetModifier(ITEM_MODIFIER_TRANSMOG_ITEM_ID, 0);
- player->SetVisibleItemSlot(slots[i], transmogrified[i]);
- }
+ if (transmogrifier->GetTemplate()->GetBonding() == BIND_WHEN_EQUIPED || transmogrifier->GetTemplate()->GetBonding() == BIND_WHEN_USE)
+ transmogrifier->SetBinding(true);
+ }
+
+ 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);
+ }
+
+ for (Item* item : resetAppearanceItems)
+ {
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_ITEM_ID, 0);
+ item->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_MOD, 0);
+ player->SetVisibleItemSlot(item->GetSlot(), item);
}
}