Merge pull request #72 from ZhengPeiRu21/appearanceCollection

Appearance Collection
This commit is contained in:
Stefano Borzì
2022-03-13 13:02:00 +01:00
committed by GitHub
5 changed files with 278 additions and 47 deletions

View File

@@ -12,6 +12,17 @@
# Players won't be able to see any transmogrified item while disabled, however, database data remains intact. # Players won't be able to see any transmogrified item while disabled, however, database data remains intact.
# Default: 1 # Default: 1
# #
# Transmogrification.UseCollectionSystem
# Description: Enables/Disables Legion-style appearance collection system.
# If enabled, players can use the appearance of any item equipped or rewarded from a completed quest.
# If disabled, players must have an item in their bags to use as a transmogrification appearance source.
# Default: 1
#
# Transmogrification.TrackUnusableItems
# Description: If enabled, appearances are collected even for items that are not suitable for transmogrification.
# This allows these appearances to be used later if the configuration is changed.
# Default: 1
#
# Transmogrification.EnableTransmogInfo # Transmogrification.EnableTransmogInfo
# Description: Enables / Disables the info button for transmogrification # Description: Enables / Disables the info button for transmogrification
# Default: 1 # Default: 1
@@ -31,6 +42,8 @@
# Default: "" # Default: ""
Transmogrification.Enable = 1 Transmogrification.Enable = 1
Transmogrification.UseCollectionSystem = 1
Transmogrification.TrackUnusableItems = 1
Transmogrification.EnableTransmogInfo = 1 Transmogrification.EnableTransmogInfo = 1
Transmogrification.TransmogNpcText = 601083 Transmogrification.TransmogNpcText = 601083

View File

@@ -18,3 +18,9 @@ CREATE TABLE IF NOT EXISTS `custom_transmogrification_sets` (
`SetData` text COMMENT 'Slot1 Entry1 Slot2 Entry2', `SetData` text COMMENT 'Slot1 Entry1 Slot2 Entry2',
PRIMARY KEY (`Owner`,`PresetID`) PRIMARY KEY (`Owner`,`PresetID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='6_1'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='6_1';
CREATE TABLE IF NOT EXISTS `custom_unlocked_appearances` (
`account_id` int(10) unsigned NOT NULL,
`item_template_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`account_id`, `item_template_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

View File

@@ -1,4 +1,5 @@
#include "Transmogrification.h" #include "Transmogrification.h"
#include "ItemTemplate.h"
Transmogrification* Transmogrification::instance() Transmogrification* Transmogrification::instance()
{ {
@@ -227,7 +228,8 @@ std::string Transmogrification::GetItemLink(Item* item, WorldSession* session) c
item->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_3) << ":" << item->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_3) << ":" <<
item->GetEnchantmentId(BONUS_ENCHANTMENT_SLOT) << ":" << item->GetEnchantmentId(BONUS_ENCHANTMENT_SLOT) << ":" <<
item->GetItemRandomPropertyId() << ":" << item->GetItemSuffixFactor() << ":" << item->GetItemRandomPropertyId() << ":" << item->GetItemSuffixFactor() << ":" <<
(uint32)item->GetOwner()->getLevel() << "|h[" << name << "]|h|r"; // (uint32)item->GetOwner()->getLevel() << "|h[" << name << "]|h|r";
(uint32)0 << "|h[" << name << "]|h|r";
return oss.str(); return oss.str();
} }
@@ -291,16 +293,12 @@ void Transmogrification::SetFakeEntry(Player* player, uint32 newEntry, uint8 /*s
UpdateItem(player, itemTransmogrified); UpdateItem(player, itemTransmogrified);
} }
TransmogAcoreStrings Transmogrification::Transmogrify(Player* player, ObjectGuid itemGUID, uint8 slot, /*uint32 newEntry, */bool no_cost) TransmogAcoreStrings Transmogrification::Transmogrify(Player* player, uint32 itemEntry, uint8 slot, /*uint32 newEntry, */bool no_cost) {
{ Item* itemTransmogrifier = Item::CreateItem(itemEntry, 1, 0);
int32 cost = 0; return Transmogrify(player, itemTransmogrifier, slot, no_cost);
// slot of the transmogrified item }
if (slot >= EQUIPMENT_SLOT_END)
{
// TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: {}, name: {}) tried to transmogrify an item (lowguid: {}) with a wrong slot ({}) when transmogrifying items.", player->GetGUIDLow(), player->GetName(), GUID_LOPART(itemGUID), slot);
return LANG_ERR_TRANSMOG_INVALID_SLOT;
}
TransmogAcoreStrings Transmogrification::Transmogrify(Player* player, ObjectGuid itemGUID, uint8 slot, /*uint32 newEntry, */bool no_cost) {
Item* itemTransmogrifier = NULL; Item* itemTransmogrifier = NULL;
// guid of the transmogrifier item, if it's not 0 // guid of the transmogrifier item, if it's not 0
if (itemGUID) if (itemGUID)
@@ -312,6 +310,18 @@ TransmogAcoreStrings Transmogrification::Transmogrify(Player* player, ObjectGuid
return LANG_ERR_TRANSMOG_MISSING_SRC_ITEM; return LANG_ERR_TRANSMOG_MISSING_SRC_ITEM;
} }
} }
return Transmogrify(player, itemTransmogrifier, slot, no_cost);
}
TransmogAcoreStrings Transmogrification::Transmogrify(Player* player, Item* itemTransmogrifier, uint8 slot, /*uint32 newEntry, */bool no_cost)
{
int32 cost = 0;
// slot of the transmogrified item
if (slot >= EQUIPMENT_SLOT_END)
{
// TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: {}, name: {}) tried to transmogrify an item (lowguid: {}) with a wrong slot ({}) when transmogrifying items.", player->GetGUIDLow(), player->GetName(), GUID_LOPART(itemGUID), slot);
return LANG_ERR_TRANSMOG_INVALID_SLOT;
}
// transmogrified item // transmogrified item
Item* itemTransmogrified = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); Item* itemTransmogrified = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
@@ -662,6 +672,8 @@ void Transmogrification::LoadConfig(bool reload)
IgnoreReqLevel = sConfigMgr->GetOption<bool>("Transmogrification.IgnoreReqLevel", false); IgnoreReqLevel = sConfigMgr->GetOption<bool>("Transmogrification.IgnoreReqLevel", false);
IgnoreReqEvent = sConfigMgr->GetOption<bool>("Transmogrification.IgnoreReqEvent", false); IgnoreReqEvent = sConfigMgr->GetOption<bool>("Transmogrification.IgnoreReqEvent", false);
IgnoreReqStats = sConfigMgr->GetOption<bool>("Transmogrification.IgnoreReqStats", false); IgnoreReqStats = sConfigMgr->GetOption<bool>("Transmogrification.IgnoreReqStats", false);
UseCollectionSystem = sConfigMgr->GetOption<bool>("Transmogrification.UseCollectionSystem", true);
TrackUnusableItems = sConfigMgr->GetOption<bool>("Transmogrification.TrackUnusableItems", true);
IsTransmogEnabled = sConfigMgr->GetOption<bool>("Transmogrification.Enable", true); IsTransmogEnabled = sConfigMgr->GetOption<bool>("Transmogrification.Enable", true);
@@ -731,6 +743,15 @@ bool Transmogrification::GetAllowMixedWeaponTypes() const
{ {
return AllowMixedWeaponTypes; return AllowMixedWeaponTypes;
}; };
bool Transmogrification::GetUseCollectionSystem() const
{
return UseCollectionSystem;
};
bool Transmogrification::GetTrackUnusableItems() const
{
return TrackUnusableItems;
}
bool Transmogrification::IsEnabled() const bool Transmogrification::IsEnabled() const
{ {

View File

@@ -6,6 +6,12 @@
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedGossip.h" #include "ScriptedGossip.h"
#include "GameEventMgr.h" #include "GameEventMgr.h"
#include "Item.h"
#include "ScriptMgr.h"
#include "Chat.h"
#include "ItemTemplate.h"
#include "QuestDef.h"
#include "ItemTemplate.h"
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@@ -118,6 +124,9 @@ public:
bool IgnoreReqEvent; bool IgnoreReqEvent;
bool IgnoreReqStats; bool IgnoreReqStats;
bool UseCollectionSystem;
bool TrackUnusableItems;
bool IsTransmogEnabled; bool IsTransmogEnabled;
bool IsAllowed(uint32 entry) const; bool IsAllowed(uint32 entry) const;
@@ -138,6 +147,8 @@ public:
void SetFakeEntry(Player* player, uint32 newEntry, uint8 slot, Item* itemTransmogrified); void SetFakeEntry(Player* player, uint32 newEntry, uint8 slot, Item* itemTransmogrified);
TransmogAcoreStrings Transmogrify(Player* player, ObjectGuid itemGUID, uint8 slot, /*uint32 newEntry, */bool no_cost = false); TransmogAcoreStrings Transmogrify(Player* player, ObjectGuid itemGUID, uint8 slot, /*uint32 newEntry, */bool no_cost = false);
TransmogAcoreStrings Transmogrify(Player* player, uint32 itemEntry, uint8 slot, /*uint32 newEntry, */bool no_cost = false);
TransmogAcoreStrings Transmogrify(Player* player, Item* itemTransmogrifier, uint8 slot, /*uint32 newEntry, */bool no_cost = false);
bool CanTransmogrifyItemWithItem(Player* player, ItemTemplate const* destination, ItemTemplate const* source) const; bool CanTransmogrifyItemWithItem(Player* player, ItemTemplate const* destination, ItemTemplate const* source) const;
bool SuitableForTransmogrification(Player* player, ItemTemplate const* proto) const; bool SuitableForTransmogrification(Player* player, ItemTemplate const* proto) const;
// bool CanBeTransmogrified(Item const* item); // bool CanBeTransmogrified(Item const* item);
@@ -161,6 +172,8 @@ public:
bool GetEnableSetInfo() const; bool GetEnableSetInfo() const;
uint32 GetSetNpcText() const; uint32 GetSetNpcText() const;
bool GetUseCollectionSystem() const;
bool GetTrackUnusableItems() const;
[[nodiscard]] bool IsEnabled() const; [[nodiscard]] bool IsEnabled() const;
}; };
#define sTransmogrification Transmogrification::instance() #define sTransmogrification Transmogrification::instance()

View File

@@ -76,10 +76,16 @@ public:
{ {
player->PlayerTalkClass->ClearMenus(); player->PlayerTalkClass->ClearMenus();
WorldSession* session = player->GetSession(); WorldSession* session = player->GetSession();
// Next page
if (sender > EQUIPMENT_SLOT_END + 10)
{
ShowTransmogItems(player, creature, action, sender);
return true;
}
switch (sender) switch (sender)
{ {
case EQUIPMENT_SLOT_END: // Show items you can use case EQUIPMENT_SLOT_END: // Show items you can use
ShowTransmogItems(player, creature, action); ShowTransmogItems(player, creature, action, sender);
break; break;
case EQUIPMENT_SLOT_END + 1: // Main menu case EQUIPMENT_SLOT_END + 1: // Main menu
OnGossipHello(player, creature); OnGossipHello(player, creature);
@@ -238,11 +244,22 @@ public:
return true; return true;
} }
// sender = slot, action = display // sender = slot, action = display
TransmogAcoreStrings res = sT->Transmogrify(player, ObjectGuid::Create<HighGuid::Item>(action), sender); if (sT->GetUseCollectionSystem())
if (res == LANG_ERR_TRANSMOG_OK) {
session->SendAreaTriggerMessage("%s",GTS(LANG_ERR_TRANSMOG_OK)); TransmogAcoreStrings res = sT->Transmogrify(player, action, sender);
if (res == LANG_ERR_TRANSMOG_OK)
session->SendAreaTriggerMessage("%s",GTS(LANG_ERR_TRANSMOG_OK));
else
session->SendNotification(res);
}
else else
session->SendNotification(res); {
TransmogAcoreStrings res = sT->Transmogrify(player, ObjectGuid::Create<HighGuid::Item>(action), sender);
if (res == LANG_ERR_TRANSMOG_OK)
session->SendAreaTriggerMessage("%s",GTS(LANG_ERR_TRANSMOG_OK));
else
session->SendNotification(res);
}
// OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, sender); // OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, sender);
// ShowTransmogItems(player, creature, sender); // ShowTransmogItems(player, creature, sender);
CloseGossipMenuFor(player); // Wait for SetMoney to get fixed, issue #10053 CloseGossipMenuFor(player); // Wait for SetMoney to get fixed, issue #10053
@@ -321,13 +338,13 @@ public:
} }
#endif #endif
void ShowTransmogItems(Player* player, Creature* creature, uint8 slot) // Only checks bags while can use an item from anywhere in inventory void ShowTransmogItems(Player* player, Creature* creature, uint8 slot, uint16 gossipPageNumber) // Only checks bags while can use an item from anywhere in inventory
{ {
WorldSession* session = player->GetSession(); WorldSession* session = player->GetSession();
Item* oldItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); Item* oldItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
bool sendGossip = true;
if (oldItem) if (oldItem)
{ {
uint32 limit = 0;
uint32 price = sT->GetSpecialPrice(oldItem->GetTemplate()); uint32 price = sT->GetSpecialPrice(oldItem->GetTemplate());
price *= sT->GetScaledCostModifier(); price *= sT->GetScaledCostModifier();
price += sT->GetCopperCost(); price += sT->GetCopperCost();
@@ -335,32 +352,85 @@ public:
ss << std::endl; ss << std::endl;
if (sT->GetRequireToken()) if (sT->GetRequireToken())
ss << std::endl << std::endl << sT->GetTokenAmount() << " x " << sT->GetItemLink(sT->GetTokenEntry(), session); ss << std::endl << std::endl << sT->GetTokenAmount() << " x " << sT->GetItemLink(sT->GetTokenEntry(), session);
std::string lineEnd = ss.str();
for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i) if (sT->GetUseCollectionSystem())
{ {
if (limit > MAX_OPTIONS) sendGossip = false;
break;
Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); std::string query = "SELECT item_template_id FROM custom_unlocked_appearances WHERE account_id = " + std::to_string(player->GetSession()->GetAccountId()) + " ORDER BY item_template_id";
if (!newItem) session->GetQueryProcessor().AddCallback(CharacterDatabase.AsyncQuery(query).WithCallback([=](QueryResult result)
continue; {
if (!sT->CanTransmogrifyItemWithItem(player, oldItem->GetTemplate(), newItem->GetTemplate())) uint16 pageNumber = 0;
continue; uint32 startValue = 0;
if (sT->GetFakeEntry(oldItem->GetGUID()) == newItem->GetEntry()) uint32 endValue = MAX_OPTIONS - 3;
continue; bool lastPage = false;
++limit; if (gossipPageNumber > EQUIPMENT_SLOT_END + 10)
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, sT->GetItemIcon(newItem->GetEntry(), 30, 30, -18, 0) + sT->GetItemLink(newItem, session), slot, newItem->GetGUID().GetCounter(), "Using this item for transmogrify will bind it to you and make it non-refundable and non-tradeable.\nDo you wish to continue?\n\n" + sT->GetItemIcon(newItem->GetEntry(), 40, 40, -15, -10) + sT->GetItemLink(newItem, session) + ss.str(), price, false); {
pageNumber = gossipPageNumber - EQUIPMENT_SLOT_END - 10;
startValue = (pageNumber * (MAX_OPTIONS - 2));
endValue = (pageNumber + 1) * (MAX_OPTIONS - 2) - 1;
}
if (result)
{
std::vector<Item*> allowedItems;
do {
uint32 newItemEntryId = (*result)[0].Get<uint32>();
Item* newItem = Item::CreateItem(newItemEntryId, 1, 0);
if (!newItem)
continue;
if (!sT->CanTransmogrifyItemWithItem(player, oldItem->GetTemplate(), newItem->GetTemplate()))
continue;
if (sT->GetFakeEntry(oldItem->GetGUID()) == newItem->GetEntry())
continue;
allowedItems.push_back(newItem);
} while (result->NextRow());
for (uint32 i = startValue; i <= endValue; i++)
{
if (allowedItems.empty() || i > allowedItems.size() - 1)
{
lastPage = true;
break;
}
Item* newItem = allowedItems.at(i);
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, sT->GetItemIcon(newItem->GetEntry(), 30, 30, -18, 0) + sT->GetItemLink(newItem, session), slot, newItem->GetEntry(), "Using this item for transmogrify will bind it to you and make it non-refundable and non-tradeable.\nDo you wish to continue?\n\n" + sT->GetItemIcon(newItem->GetEntry(), 40, 40, -15, -10) + sT->GetItemLink(newItem, session) + lineEnd, price, false);
}
}
if (gossipPageNumber == EQUIPMENT_SLOT_END + 11)
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Previous Page", EQUIPMENT_SLOT_END, slot);
if (!lastPage)
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Next Page", gossipPageNumber + 1, slot);
}
}
else if (gossipPageNumber > EQUIPMENT_SLOT_END + 11)
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Previous Page", gossipPageNumber - 1, slot);
if (!lastPage)
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Next Page", gossipPageNumber + 1, slot);
}
}
else if (!lastPage)
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Next Page", EQUIPMENT_SLOT_END + 11, slot);
}
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Enchant_Disenchant:30:30:-18:0|tRemove transmogrification", EQUIPMENT_SLOT_END + 3, slot, "Remove transmogrification from the slot?", 0, false);
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/PaperDollInfoFrame/UI-GearManager-Undo:30:30:-18:0|tUpdate menu", EQUIPMENT_SLOT_END, slot);
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack...", EQUIPMENT_SLOT_END + 1, 0);
SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
}));
} }
else
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
{ {
Bag* bag = player->GetBagByPos(i); uint32 limit = 0;
if (!bag) for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i)
continue;
for (uint32 j = 0; j < bag->GetBagSize(); ++j)
{ {
if (limit > MAX_OPTIONS) if (limit > MAX_OPTIONS)
break; break;
Item* newItem = player->GetItemByPos(i, j); Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (!newItem) if (!newItem)
continue; continue;
if (!sT->CanTransmogrifyItemWithItem(player, oldItem->GetTemplate(), newItem->GetTemplate())) if (!sT->CanTransmogrifyItemWithItem(player, oldItem->GetTemplate(), newItem->GetTemplate()))
@@ -368,24 +438,132 @@ public:
if (sT->GetFakeEntry(oldItem->GetGUID()) == newItem->GetEntry()) if (sT->GetFakeEntry(oldItem->GetGUID()) == newItem->GetEntry())
continue; continue;
++limit; ++limit;
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, sT->GetItemIcon(newItem->GetEntry(), 30, 30, -18, 0) + sT->GetItemLink(newItem, session), slot, newItem->GetGUID().GetCounter(), "Using this item for transmogrify will bind it to you and make it non-refundable and non-tradeable.\nDo you wish to continue?\n\n" + sT->GetItemIcon(newItem->GetEntry(), 40, 40, -15, -10) + sT->GetItemLink(newItem, session) + ss.str(), price, false); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, sT->GetItemIcon(newItem->GetEntry(), 30, 30, -18, 0) + sT->GetItemLink(newItem, session), slot, newItem->GetGUID().GetCounter(), "Using this item for transmogrify will bind it to you and make it non-refundable and non-tradeable.\nDo you wish to continue?\n\n" + sT->GetItemIcon(newItem->GetEntry(), 40, 40, -15, -10) + sT->GetItemLink(newItem, session) + lineEnd, price, false);
}
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
{
Bag* bag = player->GetBagByPos(i);
if (!bag)
continue;
for (uint32 j = 0; j < bag->GetBagSize(); ++j)
{
if (limit > MAX_OPTIONS)
break;
Item* newItem = player->GetItemByPos(i, j);
if (!newItem)
continue;
if (!sT->CanTransmogrifyItemWithItem(player, oldItem->GetTemplate(), newItem->GetTemplate()))
continue;
if (sT->GetFakeEntry(oldItem->GetGUID()) == newItem->GetEntry())
continue;
++limit;
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, sT->GetItemIcon(newItem->GetEntry(), 30, 30, -18, 0) + sT->GetItemLink(newItem, session), slot, newItem->GetGUID().GetCounter(), "Using this item for transmogrify will bind it to you and make it non-refundable and non-tradeable.\nDo you wish to continue?\n\n" + sT->GetItemIcon(newItem->GetEntry(), 40, 40, -15, -10) + sT->GetItemLink(newItem, session) + ss.str(), price, false);
}
} }
} }
} }
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Enchant_Disenchant:30:30:-18:0|tRemove transmogrification", EQUIPMENT_SLOT_END + 3, slot, "Remove transmogrification from the slot?", 0, false); if (sendGossip) {
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/PaperDollInfoFrame/UI-GearManager-Undo:30:30:-18:0|tUpdate menu", EQUIPMENT_SLOT_END, slot); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Enchant_Disenchant:30:30:-18:0|tRemove transmogrification", EQUIPMENT_SLOT_END + 3, slot, "Remove transmogrification from the slot?", 0, false);
AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack...", EQUIPMENT_SLOT_END + 1, 0); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/PaperDollInfoFrame/UI-GearManager-Undo:30:30:-18:0|tUpdate menu", EQUIPMENT_SLOT_END, slot);
SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack...", EQUIPMENT_SLOT_END + 1, 0);
SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
}
} }
}; };
class PS_Transmogrification : public PlayerScript class PS_Transmogrification : public PlayerScript
{ {
private:
void AddToDatabase(Player* player, ItemTemplate const* itemTemplate)
{
if (!sT->GetTrackUnusableItems() && !sT->SuitableForTransmogrification(player, itemTemplate))
return;
if (itemTemplate->Class != ITEM_CLASS_ARMOR && itemTemplate->Class != ITEM_CLASS_WEAPON)
return;
uint32 itemId = itemTemplate->ItemId;
uint32 accountId = player->GetSession()->GetAccountId();
std::string itemName = itemTemplate -> Name1;
std::stringstream tempStream;
tempStream << std::hex << ItemQualityColors[itemTemplate->Quality];
std::string itemQuality = tempStream.str();
bool showChatMessage = !(player->GetPlayerSetting("mod-transmog", SETTING_HIDE_TRANSMOG).value);
std::string query = "SELECT account_id, item_template_id FROM custom_unlocked_appearances WHERE account_id = " + std::to_string(accountId) + " AND item_template_id = " + std::to_string(itemId);
player->GetSession()->GetQueryProcessor().AddCallback(CharacterDatabase.AsyncQuery(query).WithCallback([=](QueryResult result)
{
if (!result)
{
if (showChatMessage)
ChatHandler(player->GetSession()).PSendSysMessage( R"(|c%s|Hitem:%u:0:0:0:0:0:0:0:0|h[%s]|h|r has been added to your appearance collection.)", itemQuality.c_str(), itemId, itemName.c_str());
CharacterDatabase.Execute( "INSERT INTO custom_unlocked_appearances (account_id, item_template_id) VALUES ({}, {})", accountId, itemId);
}
}));
}
public: public:
PS_Transmogrification() : PlayerScript("Player_Transmogrify") { } PS_Transmogrification() : PlayerScript("Player_Transmogrify") { }
void OnAfterSetVisibleItemSlot(Player* player, uint8 slot, Item *item) void OnEquip(Player* player, Item* it, uint8 /*bag*/, uint8 /*slot*/, bool /*update*/) override
{
if (!sT->GetUseCollectionSystem())
return;
ItemTemplate const* pProto = it->GetTemplate();
AddToDatabase(player, pProto);
}
void OnLootItem(Player* player, Item* item, uint32 /*count*/, ObjectGuid /*lootguid*/) override
{
if (!sT->GetUseCollectionSystem())
return;
if (item->GetTemplate()->Bonding == ItemBondingType::BIND_WHEN_PICKED_UP || item->IsSoulBound())
{
AddToDatabase(player, item->GetTemplate());
}
}
void OnCreateItem(Player* player, Item* item, uint32 /*count*/) override
{
if (!sT->GetUseCollectionSystem())
return;
if (item->GetTemplate()->Bonding == ItemBondingType::BIND_WHEN_PICKED_UP || item->IsSoulBound())
{
AddToDatabase(player, item->GetTemplate());
}
}
void OnAfterStoreOrEquipNewItem(Player* player, uint32 /*vendorslot*/, Item* item, uint8 /*count*/, uint8 /*bag*/, uint8 /*slot*/, ItemTemplate const* /*pProto*/, Creature* /*pVendor*/, VendorItem const* /*crItem*/, bool /*bStore*/) override
{
if (!sT->GetUseCollectionSystem())
return;
if (item->GetTemplate()->Bonding == ItemBondingType::BIND_WHEN_PICKED_UP || item->IsSoulBound())
{
AddToDatabase(player, item->GetTemplate());
}
}
void OnPlayerCompleteQuest(Player* player, Quest const* quest) override
{
if (!sT->GetUseCollectionSystem())
return;
for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
uint32 itemId = uint32(quest->RewardChoiceItemId[i]);
if (!itemId)
continue;
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
AddToDatabase(player, itemTemplate);
}
for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
{
uint32 itemId = uint32(quest->RewardItemId[i]);
if (!itemId)
continue;
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
AddToDatabase(player, itemTemplate);
}
}
void OnAfterSetVisibleItemSlot(Player* player, uint8 slot, Item *item) override
{ {
if (!item) if (!item)
return; return;
@@ -396,12 +574,12 @@ public:
} }
} }
void OnAfterMoveItemFromInventory(Player* /*player*/, Item* it, uint8 /*bag*/, uint8 /*slot*/, bool /*update*/) void OnAfterMoveItemFromInventory(Player* /*player*/, Item* it, uint8 /*bag*/, uint8 /*slot*/, bool /*update*/) override
{ {
sT->DeleteFakeFromDB(it->GetGUID().GetCounter()); sT->DeleteFakeFromDB(it->GetGUID().GetCounter());
} }
void OnLogin(Player* player) void OnLogin(Player* player) override
{ {
ObjectGuid playerGUID = player->GetGUID(); ObjectGuid playerGUID = player->GetGUID();
sT->entryMap.erase(playerGUID); sT->entryMap.erase(playerGUID);
@@ -437,7 +615,7 @@ public:
#endif #endif
} }
void OnLogout(Player* player) void OnLogout(Player* player) override
{ {
ObjectGuid pGUID = player->GetGUID(); ObjectGuid pGUID = player->GetGUID();
for (Transmogrification::transmog2Data::const_iterator it = sT->entryMap[pGUID].begin(); it != sT->entryMap[pGUID].end(); ++it) for (Transmogrification::transmog2Data::const_iterator it = sT->entryMap[pGUID].begin(); it != sT->entryMap[pGUID].end(); ++it)
@@ -480,12 +658,12 @@ class global_transmog_script : public GlobalScript
public: public:
global_transmog_script() : GlobalScript("global_transmog_script") { } global_transmog_script() : GlobalScript("global_transmog_script") { }
void OnItemDelFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid) void OnItemDelFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid) override
{ {
sT->DeleteFakeFromDB(itemGuid, &trans); sT->DeleteFakeFromDB(itemGuid, &trans);
} }
void OnMirrorImageDisplayItem(const Item *item, uint32 &display) void OnMirrorImageDisplayItem(const Item *item, uint32 &display) override
{ {
if (uint32 entry = sTransmogrification->GetFakeEntry(item->GetGUID())) if (uint32 entry = sTransmogrification->GetFakeEntry(item->GetGUID()))
display=uint32(sObjectMgr->GetItemTemplate(entry)->DisplayInfoID); display=uint32(sObjectMgr->GetItemTemplate(entry)->DisplayInfoID);