Core/Transmog: Support new transmog modifiers (secondary appearance)

This commit is contained in:
Shauren
2020-11-05 19:51:21 +01:00
parent b6cb916840
commit 78f77dbd41
3 changed files with 113 additions and 42 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -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);
if (!validateAndStoreTransmogItem(itemTransmogrified, transmogItem.ItemModifiedAppearanceID, false))
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.SecondaryItemModifiedAppearanceID, true))
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->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);
}