mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Transmog: Implemented transmog collection and updated transmog handling
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user