diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 34 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.h | 1 | ||||
-rw-r--r-- | src/server/game/Handlers/TransmogrificationHandler.cpp | 120 |
3 files changed, 113 insertions, 42 deletions
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 337a0e85923..9accf6abf42 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -268,11 +268,11 @@ ItemModifier const AppearanceModifierSlotBySpec[MAX_SPECIALIZATIONS] = ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4 }; -static uint32 const AppearanceModifierMaskSpecSpecific = - (1 << ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1) | - (1 << ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2) | - (1 << ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3) | - (1 << ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4); +static uint64 constexpr AppearanceModifierMaskSpecSpecific = + (UI64LIT(1) << ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1) | + (UI64LIT(1) << ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2) | + (UI64LIT(1) << ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3) | + (UI64LIT(1) << ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4); ItemModifier const IllusionModifierSlotBySpec[MAX_SPECIALIZATIONS] = { @@ -282,11 +282,25 @@ ItemModifier const IllusionModifierSlotBySpec[MAX_SPECIALIZATIONS] = ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4 }; -static uint32 const IllusionModifierMaskSpecSpecific = - (1 << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1) | - (1 << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2) | - (1 << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3) | - (1 << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4); +static uint64 constexpr IllusionModifierMaskSpecSpecific = + (UI64LIT(1) << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1) | + (UI64LIT(1) << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2) | + (UI64LIT(1) << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3) | + (UI64LIT(1) << ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4); + +ItemModifier const SecondaryAppearanceModifierSlotBySpec[MAX_SPECIALIZATIONS] = +{ + ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1, + ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2, + ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3, + ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4 +}; + +static uint64 constexpr SecondaryAppearanceModifierMaskSpecSpecific = + (UI64LIT(1) << ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1) | + (UI64LIT(1) << ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2) | + (UI64LIT(1) << ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3) | + (UI64LIT(1) << ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4); void ItemAdditionalLoadInfo::Init(std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo>* loadInfo, PreparedQueryResult artifactResult, PreparedQueryResult azeriteItemResult, diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 7aa3e3327da..53744f5b1b5 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -62,6 +62,7 @@ enum ItemUpdateState bool ItemCanGoIntoBag(ItemTemplate const* proto, ItemTemplate const* pBagProto); extern ItemModifier const AppearanceModifierSlotBySpec[MAX_SPECIALIZATIONS]; extern ItemModifier const IllusionModifierSlotBySpec[MAX_SPECIALIZATIONS]; +extern ItemModifier const SecondaryAppearanceModifierSlotBySpec[MAX_SPECIALIZATIONS]; extern int32 const ItemTransmogrificationSlots[MAX_INVTYPE]; struct BonusData diff --git a/src/server/game/Handlers/TransmogrificationHandler.cpp b/src/server/game/Handlers/TransmogrificationHandler.cpp index 81a35329e20..37e3d3228de 100644 --- a/src/server/game/Handlers/TransmogrificationHandler.cpp +++ b/src/server/game/Handlers/TransmogrificationHandler.cpp @@ -35,13 +35,60 @@ void WorldSession::HandleTransmogrifyItems(WorldPackets::Transmogrification::Tra } int64 cost = 0; - std::unordered_map<Item*, uint32> transmogItems; + std::unordered_map<Item*, std::pair<uint32, uint32>> transmogItems; std::unordered_map<Item*, uint32> illusionItems; std::vector<Item*> resetAppearanceItems; std::vector<Item*> resetIllusionItems; std::vector<uint32> bindAppearances; + auto validateAndStoreTransmogItem = [&](Item* itemTransmogrified, uint32 itemModifiedAppearanceId, bool isSecondary) + { + ItemModifiedAppearanceEntry const* itemModifiedAppearance = sItemModifiedAppearanceStore.LookupEntry(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(), itemModifiedAppearanceId); + return false; + } + + if (isSecondary && itemTransmogrified->GetTemplate()->GetInventoryType() != INVTYPE_SHOULDERS) + { + TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify secondary appearance to non-shoulder item.", player->GetGUID().ToString().c_str(), player->GetName().c_str()); + return false; + } + + bool hasAppearance, isTemporary; + std::tie(hasAppearance, isTemporary) = GetCollectionMgr()->HasItemAppearance(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(), itemModifiedAppearanceId); + return false; + } + 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(), itemModifiedAppearanceId); + return false; + } + + // 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(), itemModifiedAppearanceId); + return false; + } + + if (!isSecondary) + transmogItems[itemTransmogrified].first = itemModifiedAppearanceId; + else + transmogItems[itemTransmogrified].second = itemModifiedAppearanceId; + + if (isTemporary) + bindAppearances.push_back(itemModifiedAppearanceId); + + return true; + }; + for (WorldPackets::Transmogrification::TransmogrifyItem const& transmogItem : transmogrifyItems.Items) { // slot of the transmogrified item @@ -59,39 +106,13 @@ void WorldSession::HandleTransmogrifyItems(WorldPackets::Transmogrification::Tra return; } - if (transmogItem.ItemModifiedAppearanceID) + if (transmogItem.ItemModifiedAppearanceID || transmogItem.SecondaryItemModifiedAppearanceID) { - 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); + if (!validateAndStoreTransmogItem(itemTransmogrified, transmogItem.ItemModifiedAppearanceID, false)) 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); + if (!validateAndStoreTransmogItem(itemTransmogrified, transmogItem.SecondaryItemModifiedAppearanceID, true)) return; - } - - transmogItems[itemTransmogrified] = transmogItem.ItemModifiedAppearanceID; - if (isTemporary) - bindAppearances.push_back(transmogItem.ItemModifiedAppearanceID); // add cost cost += itemTransmogrified->GetSellPrice(_player); @@ -156,11 +177,17 @@ void WorldSession::HandleTransmogrifyItems(WorldPackets::Transmogrification::Tra if (!transmogrifyItems.CurrentSpecOnly) { - transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, transmogPair.second); + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, transmogPair.second.first); 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); + + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS, transmogPair.second.second); + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1, 0); + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2, 0); + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3, 0); + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4, 0); } else { @@ -172,7 +199,18 @@ void WorldSession::HandleTransmogrifyItems(WorldPackets::Transmogrification::Tra 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); + + if (!transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1)) + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1, transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS)); + if (!transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2)) + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2, transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS)); + if (!transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3)) + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3, transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS)); + if (!transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4)) + transmogrified->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4, transmogrified->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS)); + + transmogrified->SetModifier(AppearanceModifierSlotBySpec[player->GetActiveTalentGroup()], transmogPair.second.first); + transmogrified->SetModifier(SecondaryAppearanceModifierSlotBySpec[player->GetActiveTalentGroup()], transmogPair.second.second); } player->SetVisibleItemSlot(transmogrified->GetSlot(), transmogrified); @@ -223,6 +261,12 @@ void WorldSession::HandleTransmogrifyItems(WorldPackets::Transmogrification::Tra 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); + + item->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS, 0); + item->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1, 0); + item->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2, 0); + item->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3, 0); + item->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4, 0); } else { @@ -234,7 +278,18 @@ void WorldSession::HandleTransmogrifyItems(WorldPackets::Transmogrification::Tra 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)); + + if (!item->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1)) + item->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1, item->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS)); + if (!item->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2)) + item->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2, item->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS)); + if (!item->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3)) + item->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3, item->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS)); + if (!item->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4)) + item->SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4, item->GetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS)); + item->SetModifier(AppearanceModifierSlotBySpec[player->GetActiveTalentGroup()], 0); + item->SetModifier(SecondaryAppearanceModifierSlotBySpec[player->GetActiveTalentGroup()], 0); item->SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS, 0); } @@ -262,6 +317,7 @@ void WorldSession::HandleTransmogrifyItems(WorldPackets::Transmogrification::Tra 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); } |