Skip to content

Instantly share code, notes, and snippets.

@SymbolixDEV
Created May 16, 2013 17:52
Show Gist options
  • Save SymbolixDEV/5593639 to your computer and use it in GitHub Desktop.
Save SymbolixDEV/5593639 to your computer and use it in GitHub Desktop.
Transmogrification
diff --git a/sql/Transmogrification/characters.sql b/sql/Transmogrification/characters.sql
new file mode 100644
index 0000000..b575605
--- /dev/null
+++ b/sql/Transmogrification/characters.sql
@@ -0,0 +1,9 @@
+CREATE TABLE `custom_transmogrification` (
+ `GUID` INT(10) UNSIGNED NOT NULL COMMENT 'Item guidLow',
+ `FakeEntry` INT(10) UNSIGNED NOT NULL COMMENT 'Item entry',
+ `Owner` INT(10) UNSIGNED NOT NULL COMMENT 'Player guidLow',
+ PRIMARY KEY (`GUID`)
+)
+COMMENT='version 4.0'
+COLLATE='latin1_swedish_ci'
+ENGINE=InnoDB;
diff --git a/sql/Transmogrification/updates/characters_update_2_1_to_2_2.sql b/sql/Transmogrification/updates/characters_update_2_1_to_2_2.sql
new file mode 100644
index 0000000..ee57844
--- /dev/null
+++ b/sql/Transmogrification/updates/characters_update_2_1_to_2_2.sql
@@ -0,0 +1,12 @@
+CREATE TABLE IF NOT EXISTS `custom_transmogrification` (
+ `GUID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `FakeOwner` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `FakeEntry` INT(10) UNSIGNED NOT NULL DEFAULT '0'
+)
+COLLATE='latin1_swedish_ci'
+ENGINE=InnoDB;
+
+REPLACE INTO custom_transmogrification (GUID, FakeOwner, FakeEntry) SELECT guid, FakeOwner, FakeEntry FROM item_instance WHERE FakeOwner != 0 AND FakeEntry != 0;
+ALTER TABLE `item_instance`
+ DROP COLUMN `FakeEntry`,
+ DROP COLUMN `FakeOwner`;
diff --git a/sql/Transmogrification/updates/characters_update_2_2_to_3_0.sql b/sql/Transmogrification/updates/characters_update_2_2_to_3_0.sql
new file mode 100644
index 0000000..63059ee
--- /dev/null
+++ b/sql/Transmogrification/updates/characters_update_2_2_to_3_0.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `custom_transmogrification`
+ DROP COLUMN `FakeOwner`;
diff --git a/sql/Transmogrification/updates/world_update_3_5_to_3_6.sql b/sql/Transmogrification/updates/world_update_3_5_to_3_6.sql
new file mode 100644
index 0000000..03cc6d2
--- /dev/null
+++ b/sql/Transmogrification/updates/world_update_3_5_to_3_6.sql
@@ -0,0 +1 @@
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11129, 'You don\'t have enough %ss', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
diff --git a/sql/Transmogrification/world_NPC.sql b/sql/Transmogrification/world_NPC.sql
new file mode 100644
index 0000000..81879da
--- /dev/null
+++ b/sql/Transmogrification/world_NPC.sql
@@ -0,0 +1,6 @@
+SET
+@Entry = 190010,
+@Name = "Warpweaver";
+
+INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction_A`, `faction_H`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `Health_mod`, `Mana_mod`, `Armor_mod`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `WDBVerified`) VALUES
+(@Entry, 0, 0, 0, 0, 0, 19646, 0, 0, 0, @Name, 'Transmogrifier', NULL, 0, 80, 80, 2, 35, 35, 1, 1, 1.14286, 1, 0, 500, 500, 0, 350, 1, 2000, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 'NPC_Transmogrify', 0);
diff --git a/sql/Transmogrification/world_texts.sql b/sql/Transmogrification/world_texts.sql
new file mode 100644
index 0000000..f55fb68
--- /dev/null
+++ b/sql/Transmogrification/world_texts.sql
@@ -0,0 +1,30 @@
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11100, 'Transmogrifications removed from equipped items', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11101, 'You have no transmogrified items equipped', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11102, '%s transmogrification removed', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11103, 'No transmogrification on %s slot', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11104, '%s transmogrified', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11105, 'Selected items are not suitable', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11106, 'Selected item does not exist', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11107, 'Equipment slot is empty', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11108, 'Head', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11109, 'Shoulders', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11110, 'Shirt', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11111, 'Chest', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11112, 'Waist', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11113, 'Legs', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11114, 'Feet', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11115, 'Wrists', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11116, 'Hands', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11117, 'Back', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11118, 'Main hand', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11119, 'Off hand', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11120, 'Ranged', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11121, 'Tabard', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11122, 'Back..', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11123, 'Remove all transmogrifications', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11124, 'Remove transmogrifications from all equipped items?', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11125, 'Update menu', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11126, 'Remove transmogrification', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11127, 'Remove transmogrification from %s?', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11128, 'Using this item for transmogrify will bind it to you and make it non-refundable and non-tradeable.\r\nDo you wish to continue?\r\n\r\n', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+REPLACE INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (11129, 'You don\'t have enough %ss', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 5dd7260..d04d0b1 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -16,6 +16,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "../../../scripts/Custom/Transmogrification.h"
#include "Common.h"
#include "Item.h"
#include "ObjectMgr.h"
@@ -479,6 +480,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entr
/*static*/
void Item::DeleteFromDB(SQLTransaction& trans, uint32 itemGuid)
{
+ Transmogrification::DeleteFakeFromDB(itemGuid); // custom
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
stmt->setUInt32(0, itemGuid);
trans->Append(stmt);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 59f9e1e..09d6591 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -16,6 +16,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "../../../scripts/Custom/Transmogrification.h"
#include "Player.h"
#include "AccountMgr.h"
#include "AchievementMgr.h"
@@ -12392,7 +12393,11 @@ void Player::SetVisibleItemSlot(uint8 slot, Item* pItem)
{
if (pItem)
{
- SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetEntry());
+ // custom
+ if (Transmogrification::GetFakeEntry(pItem))
+ SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), Transmogrification::GetFakeEntry(pItem));
+ else
+ SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetEntry());
SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 0, pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 1, pItem->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT));
}
@@ -12513,6 +12518,7 @@ void Player::MoveItemFromInventory(uint8 bag, uint8 slot, bool update)
{
if (Item* it = GetItemByPos(bag, slot))
{
+ Transmogrification::DeleteFakeFromDB(it->GetGUIDLow()); // custom
ItemRemovedQuestCheck(it->GetEntry(), it->GetCount());
RemoveItem(bag, slot, update);
it->SetNotRefundable(this, false);
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index efd4518..918fc8f 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -1287,6 +1287,7 @@ void AddBattlegroundScripts()
#ifdef SCRIPTS
/* This is where custom scripts' loading functions should be declared. */
+void AddSC_NPC_Transmogrify();
#endif
void AddCustomScripts()
@@ -1294,5 +1295,6 @@ void AddCustomScripts()
#ifdef SCRIPTS
/* This is where custom scripts should be added. */
+ AddSC_NPC_Transmogrify();
#endif
}
diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt
index 99cf026..9873d62 100644
--- a/src/server/scripts/Custom/CMakeLists.txt
+++ b/src/server/scripts/Custom/CMakeLists.txt
@@ -10,6 +10,8 @@
set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
+ Custom/Transmogrification.h
+ Custom/Transmogrification.cpp
)
message(" -> Prepared: Custom")
diff --git a/src/server/scripts/Custom/Transmogrification.cpp b/src/server/scripts/Custom/Transmogrification.cpp
new file mode 100644
index 0000000..0ca03df
--- /dev/null
+++ b/src/server/scripts/Custom/Transmogrification.cpp
@@ -0,0 +1,421 @@
+/*
+4.0
+Transmogrification 3.3.5a - Gossip Menu
+By Rochet2
+
+ScriptName for NPC:
+NPC_Transmogrify
+
+
+TODO:
+Make DB saving even better (Deleting)? What about coding?
+
+Fix the cost formula
+
+TODO in the distant future:
+
+Are the qualities right? Blizzard might have changed the quality requirements.
+What can and cant be used as source or target..?
+
+Cant transmogrify:
+rediculus _items // Foereaper: would be fun to stab people with a fish
+-- Cant think of any good way to handle this easily
+
+Cataclysm:
+Test on cata -> implement UI xD?
+Item link icon to Are You sure text
+*/
+
+#include "ScriptPCH.h"
+#include "Transmogrification.h"
+
+typedef UNORDERED_MAP<uint32, uint32> transmogData;
+typedef UNORDERED_MAP<uint32, transmogData> transmogMap;
+transmogMap entryMap; // entryMap[pGUID][iGUID] = entry
+transmogData dataMap; // dataMap[iGUID] = pGUID
+
+uint32 Transmogrification::GetFakeEntry(Item* item)
+{
+ transmogData::iterator itr = dataMap.find(item->GetGUIDLow());
+ if (itr == dataMap.end()) return 0;
+ transmogMap::iterator itr2 = entryMap.find(itr->second);
+ if (itr2 == entryMap.end()) return 0;
+ transmogData::iterator itr3 = itr2->second.find(item->GetGUIDLow());
+ if (itr3 == itr2->second.end()) return 0;
+ return itr3->second;
+}
+void Transmogrification::DeleteFakeFromDB(uint32 itemGUID)
+{
+ if (dataMap.find(itemGUID) != dataMap.end())
+ {
+ entryMap.erase(dataMap[itemGUID]);
+ dataMap.erase(itemGUID);
+ }
+ CharacterDatabase.PExecute("DELETE FROM custom_transmogrification WHERE GUID = %u", itemGUID);
+}
+bool Transmogrification::DeleteFakeEntry(Item* item)
+{
+ if (!GetFakeEntry(item))
+ return false;
+ item->GetOwner()->UpdateUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (item->GetSlot() * 2), item->GetEntry());
+ DeleteFakeFromDB(item->GetGUIDLow());
+ return true;
+}
+void Transmogrification::SetFakeEntry(Item* item, uint32 entry)
+{
+ if(Player* player = item->GetOwner())
+ {
+ uint32 pGUID = player->GetGUIDLow();
+ uint32 iGUID = item->GetGUIDLow();
+ player->UpdateUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (item->GetSlot() * 2), entry);
+ entryMap[pGUID][iGUID] = entry;
+ dataMap[iGUID] = pGUID;
+ CharacterDatabase.PExecute("REPLACE INTO custom_transmogrification (GUID, FakeEntry, Owner) VALUES (%u, %u, %u)", iGUID, entry, pGUID);
+ }
+}
+uint32 Transmogrification::SuitableForTransmogrification(Player* player, Item* oldItem, Item* newItem)
+{
+ // not possibly the best structure here, but atleast I got my head around this
+ if (!sTransmogrification->AllowedQuality(newItem->GetTemplate()->Quality))
+ return ERR_FAKE_NEW_BAD_QUALITY;
+ if (!sTransmogrification->AllowedQuality(oldItem->GetTemplate()->Quality))
+ return ERR_FAKE_OLD_BAD_QUALITY;
+
+ if (oldItem->GetTemplate()->DisplayInfoID == newItem->GetTemplate()->DisplayInfoID)
+ return ERR_FAKE_SAME_DISPLAY;
+ if (GetFakeEntry(oldItem))
+ if (const ItemTemplate* fakeItemTemplate = sObjectMgr->GetItemTemplate(GetFakeEntry(oldItem)))
+ if (fakeItemTemplate->DisplayInfoID == newItem->GetTemplate()->DisplayInfoID)
+ return ERR_FAKE_SAME_DISPLAY_FAKE;
+ if (player->CanUseItem(newItem, false) != EQUIP_ERR_OK)
+ return ERR_FAKE_CANT_USE;
+ uint32 newClass = newItem->GetTemplate()->Class;
+ uint32 oldClass = oldItem->GetTemplate()->Class;
+ uint32 newSubClass = newItem->GetTemplate()->SubClass;
+ uint32 oldSubClass = oldItem->GetTemplate()->SubClass;
+ uint32 newInventorytype = newItem->GetTemplate()->InventoryType;
+ uint32 oldInventorytype = oldItem->GetTemplate()->InventoryType;
+ if (newClass != oldClass)
+ return ERR_FAKE_NOT_SAME_CLASS;
+ if (newClass == ITEM_CLASS_WEAPON && newSubClass != ITEM_SUBCLASS_WEAPON_FISHING_POLE && oldSubClass != ITEM_SUBCLASS_WEAPON_FISHING_POLE)
+ {
+ if (newSubClass == oldSubClass || ((newSubClass == ITEM_SUBCLASS_WEAPON_BOW || newSubClass == ITEM_SUBCLASS_WEAPON_GUN || newSubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW) && (oldSubClass == ITEM_SUBCLASS_WEAPON_BOW || oldSubClass == ITEM_SUBCLASS_WEAPON_GUN || oldSubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW)))
+ if (newInventorytype == oldInventorytype || (newInventorytype == INVTYPE_WEAPON && (oldInventorytype == INVTYPE_WEAPONMAINHAND || oldInventorytype == INVTYPE_WEAPONOFFHAND)))
+ return ERR_FAKE_OK;
+ else
+ return ERR_FAKE_BAD_INVENTORYTYPE;
+ else
+ return ERR_FAKE_BAD_SUBLCASS;
+ }
+ else if (newClass == ITEM_CLASS_ARMOR)
+ if (newSubClass == oldSubClass)
+ if (newInventorytype == oldInventorytype || (newInventorytype == INVTYPE_CHEST && oldInventorytype == INVTYPE_ROBE) || (newInventorytype == INVTYPE_ROBE && oldInventorytype == INVTYPE_CHEST))
+ return ERR_FAKE_OK;
+ else
+ return ERR_FAKE_BAD_INVENTORYTYPE;
+ else
+ return ERR_FAKE_BAD_SUBLCASS;
+ return ERR_FAKE_BAD_CLASS;
+}
+
+class NPC_Transmogrify : public CreatureScript
+{
+public:
+ NPC_Transmogrify() : CreatureScript("NPC_Transmogrify") { }
+
+ bool OnGossipHello(Player* player, Creature* creature)
+ {
+ WorldSession* session = player->GetSession();
+ for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_TABARD; slot++) // EQUIPMENT_SLOT_END
+ {
+ if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
+ {
+ if (sTransmogrification->AllowedQuality(newItem->GetTemplate()->Quality))
+ {
+ if (const char* slotName = GetSlotName(slot, session))
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, slotName, EQUIPMENT_SLOT_END, slot);
+ }
+ }
+ }
+ player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, session->GetTrinityString(LANG_OPTION_REMOVE_ALL), EQUIPMENT_SLOT_END+2, 0, session->GetTrinityString(LANG_POPUP_REMOVE_ALL), 0, false);
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, session->GetTrinityString(LANG_OPTION_UPDATE_MENU), EQUIPMENT_SLOT_END+1, 0);
+ player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
+ return true;
+ }
+
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 uiAction)
+ {
+ WorldSession* session = player->GetSession();
+ player->PlayerTalkClass->ClearMenus();
+ switch(sender)
+ {
+ case EQUIPMENT_SLOT_END: // Show items you can use
+ {
+ if (Item* oldItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, uiAction))
+ {
+ uint32 lowGUID = player->GetGUIDLow();
+ _items[lowGUID].clear();
+ uint32 limit = 0;
+ uint32 price = 0;
+ switch (sTransmogrification->GetRequireGold())
+ {
+ case 1: { price = (unsigned int)(GetFakePrice(oldItem)*sTransmogrification->GetGoldModifier()); } break;
+ case 2: { price = (unsigned int)sTransmogrification->GetGoldCost(); } break;
+ }
+ char tokenCost[250] = "\n";
+ if(sTransmogrification->GetRequireToken())
+ snprintf(tokenCost, 250, "\n\n%u x %s", sTransmogrification->GetTokenAmount(), GetItemName(sObjectMgr->GetItemTemplate(sTransmogrification->GetTokenEntry()), session).c_str());
+
+ for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
+ {
+ if (limit > 30)
+ break;
+ if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ {
+ uint32 display = newItem->GetTemplate()->DisplayInfoID;
+ if (Transmogrification::SuitableForTransmogrification(player, oldItem, newItem) == ERR_FAKE_OK)
+ {
+ if (_items[lowGUID].find(display) == _items[lowGUID].end())
+ {
+ limit++;
+ _items[lowGUID][display] = newItem;
+ player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, GetItemName(newItem->GetTemplate(), session), uiAction, display, session->GetTrinityString(LANG_POPUP_TRANSMOGRIFY)+GetItemName(newItem->GetTemplate(), session)+tokenCost, price, false);
+ }
+ }
+ }
+ }
+
+ for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
+ {
+ if (Bag* bag = player->GetBagByPos(i))
+ {
+ for (uint32 j = 0; j < bag->GetBagSize(); j++)
+ {
+ if (limit > 30)
+ break;
+ if (Item* newItem = player->GetItemByPos(i, j))
+ {
+ uint32 display = newItem->GetTemplate()->DisplayInfoID;
+ if (Transmogrification::SuitableForTransmogrification(player, oldItem, newItem) == ERR_FAKE_OK)
+ {
+ if (_items[lowGUID].find(display) == _items[lowGUID].end())
+ {
+ limit++;
+ _items[lowGUID][display] = newItem;
+ player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, GetItemName(newItem->GetTemplate(), session), uiAction, display, session->GetTrinityString(LANG_POPUP_TRANSMOGRIFY)+GetItemName(newItem->GetTemplate(), session)+tokenCost, price, false);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ char removeOnePopup[250];
+ snprintf(removeOnePopup, 250, session->GetTrinityString(LANG_POPUP_REMOVE_ONE), GetSlotName(uiAction, session));
+ player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, session->GetTrinityString(LANG_OPTION_REMOVE_ONE), EQUIPMENT_SLOT_END+3, uiAction, removeOnePopup, 0, false);
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, session->GetTrinityString(LANG_OPTION_BACK), EQUIPMENT_SLOT_END+1, 0);
+ player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
+ }
+ else
+ OnGossipHello(player, creature);
+ } break;
+ case EQUIPMENT_SLOT_END+1: // Back
+ {
+ OnGossipHello(player, creature);
+ } break;
+ case EQUIPMENT_SLOT_END+2: // Remove Transmogrifications
+ {
+ bool removed = false;
+ for (uint8 Slot = EQUIPMENT_SLOT_START; Slot < EQUIPMENT_SLOT_END; Slot++)
+ {
+ if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, Slot))
+ {
+ if (Transmogrification::DeleteFakeEntry(newItem) && !removed)
+ removed = true;
+ }
+ }
+ if (removed)
+ {
+ session->SendAreaTriggerMessage(session->GetTrinityString(LANG_REM_TRANSMOGRIFICATIONS_ITEMS));
+ player->PlayDirectSound(3337);
+ }
+ else
+ session->SendNotification(session->GetTrinityString(LANG_ERR_NO_TRANSMOGRIFICATIONS));
+ OnGossipHello(player, creature);
+ } break;
+ case EQUIPMENT_SLOT_END+3: // Remove Transmogrification from single item
+ {
+ if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, uiAction))
+ {
+ if (Transmogrification::DeleteFakeEntry(newItem))
+ {
+ session->SendAreaTriggerMessage(session->GetTrinityString(LANG_REM_TRANSMOGRIFICATION_ITEM), GetSlotName(uiAction, session));
+ player->PlayDirectSound(3337);
+ }
+ else
+ session->SendNotification(session->GetTrinityString(LANG_ERR_NO_TRANSMOGRIFICATION), GetSlotName(uiAction, session));
+ }
+ OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, uiAction);
+ } break;
+ default: // Transmogrify
+ {
+ uint32 lowGUID = player->GetGUIDLow();
+ if(!sTransmogrification->GetRequireToken() || player->GetItemCount(sTransmogrification->GetTokenEntry()) >= sTransmogrification->GetTokenAmount())
+ {
+ if (Item* oldItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, sender))
+ {
+ if (_items[lowGUID].find(uiAction) != _items[lowGUID].end() && _items[lowGUID][uiAction]->IsInWorld())
+ {
+ Item* newItem = _items[lowGUID][uiAction];
+ if (newItem->GetOwnerGUID() == player->GetGUIDLow() && (newItem->IsInBag() || newItem->GetBagSlot() == INVENTORY_SLOT_BAG_0) && Transmogrification::SuitableForTransmogrification(player, oldItem, newItem) == ERR_FAKE_OK)
+ {
+ switch(sTransmogrification->GetRequireGold())
+ {
+ case 1: { player->ModifyMoney(-1*(uint32)(GetFakePrice(oldItem)*sTransmogrification->GetGoldModifier())); } break;
+ case 2: { player->ModifyMoney(-1*(unsigned int)sTransmogrification->GetGoldCost()); } break;
+ }
+ if(sTransmogrification->GetRequireToken())
+ player->DestroyItemCount(sTransmogrification->GetTokenEntry(), sTransmogrification->GetTokenAmount(), true);
+ Transmogrification::SetFakeEntry(oldItem, newItem->GetEntry());
+ newItem->SetNotRefundable(player);
+ newItem->SetBinding(true);
+ player->PlayDirectSound(3337);
+ session->SendAreaTriggerMessage(session->GetTrinityString(LANG_ITEM_TRANSMOGRIFIED), GetSlotName(sender, session));
+ }
+ else
+ session->SendNotification(session->GetTrinityString(LANG_ERR_NO_ITEM_SUITABLE));
+ }
+ else
+ session->SendNotification(session->GetTrinityString(LANG_ERR_NO_ITEM_EXISTS));
+ }
+ else
+ session->SendNotification(session->GetTrinityString(LANG_ERR_EQUIP_SLOT_EMPTY));
+ }
+ else
+ session->SendNotification(session->GetTrinityString(LANG_ERR_NO_TOKEN), GetItemName(sObjectMgr->GetItemTemplate(sTransmogrification->GetTokenEntry()), session).c_str());
+ _items[lowGUID].clear();
+ OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, sender);
+ } break;
+ }
+ return true;
+ }
+
+private:
+ std::map<uint64, std::map<uint32, Item*> > _items; // _items[lowGUID][DISPLAY] = item
+
+ const char * GetSlotName(uint8 slot, WorldSession* session)
+ {
+ switch (slot)
+ {
+ case EQUIPMENT_SLOT_HEAD : return session->GetTrinityString(LANG_SLOT_NAME_HEAD);
+ case EQUIPMENT_SLOT_SHOULDERS : return session->GetTrinityString(LANG_SLOT_NAME_SHOULDERS);
+ case EQUIPMENT_SLOT_BODY : return session->GetTrinityString(LANG_SLOT_NAME_BODY);
+ case EQUIPMENT_SLOT_CHEST : return session->GetTrinityString(LANG_SLOT_NAME_CHEST);
+ case EQUIPMENT_SLOT_WAIST : return session->GetTrinityString(LANG_SLOT_NAME_WAIST);
+ case EQUIPMENT_SLOT_LEGS : return session->GetTrinityString(LANG_SLOT_NAME_LEGS);
+ case EQUIPMENT_SLOT_FEET : return session->GetTrinityString(LANG_SLOT_NAME_FEET);
+ case EQUIPMENT_SLOT_WRISTS : return session->GetTrinityString(LANG_SLOT_NAME_WRISTS);
+ case EQUIPMENT_SLOT_HANDS : return session->GetTrinityString(LANG_SLOT_NAME_HANDS);
+ case EQUIPMENT_SLOT_BACK : return session->GetTrinityString(LANG_SLOT_NAME_BACK);
+ case EQUIPMENT_SLOT_MAINHAND : return session->GetTrinityString(LANG_SLOT_NAME_MAINHAND);
+ case EQUIPMENT_SLOT_OFFHAND : return session->GetTrinityString(LANG_SLOT_NAME_OFFHAND);
+ case EQUIPMENT_SLOT_RANGED : return session->GetTrinityString(LANG_SLOT_NAME_RANGED);
+ case EQUIPMENT_SLOT_TABARD : return session->GetTrinityString(LANG_SLOT_NAME_TABARD);
+ default: return NULL;
+ }
+ }
+
+ std::string GetItemName(const ItemTemplate* itemTemplate, WorldSession* session)
+ {
+ std::string name = itemTemplate->Name1;
+ int loc_idx = session->GetSessionDbLocaleIndex();
+ if (loc_idx >= 0)
+ if (ItemLocale const* il = sObjectMgr->GetItemLocale(itemTemplate->ItemId))
+ sObjectMgr->GetLocaleString(il->Name, loc_idx, name);
+ return name;
+ }
+
+ uint32 GetFakePrice(Item* item)
+ {
+ uint32 sellPrice = item->GetTemplate()->SellPrice;
+ uint32 minPrice = item->GetTemplate()->RequiredLevel * 1176;
+ if (sellPrice < minPrice)
+ sellPrice = minPrice;
+ return sellPrice;
+ }
+};
+
+class Player_Transmogrify : public PlayerScript
+{
+public:
+ Player_Transmogrify() : PlayerScript("Player_Transmogrify") { }
+
+ void OnLogin(Player* player)
+ {
+ uint32 playerGUID = player->GetGUIDLow();
+ entryMap.erase(playerGUID);
+ QueryResult result = CharacterDatabase.PQuery("SELECT GUID, FakeEntry FROM custom_transmogrification WHERE Owner = %u", playerGUID);
+ if (result)
+ {
+ do
+ {
+ uint32 itemGUID = (*result)[0].GetUInt32();
+ uint32 fakeEntry = (*result)[1].GetUInt32();
+ if (sObjectMgr->GetItemTemplate(fakeEntry))
+ {
+ dataMap[itemGUID] = playerGUID;
+ entryMap[playerGUID][itemGUID] = fakeEntry;
+ }
+ else
+ {
+ sLog->outError(LOG_FILTER_SQL, "Item entry (Entry: %u, itemGUID: %u, playerGUID: %u) does not exist, deleting.", fakeEntry, itemGUID, playerGUID);
+ Transmogrification::DeleteFakeFromDB(itemGUID);
+ }
+ } while (result->NextRow());
+
+ for (uint8 Slot = EQUIPMENT_SLOT_START; Slot < EQUIPMENT_SLOT_END; Slot++)
+ {
+ if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, Slot))
+ if(entryMap.find(playerGUID) != entryMap.end())
+ if(entryMap[playerGUID].find(item->GetGUIDLow()) != entryMap[playerGUID].end())
+ player->UpdateUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (item->GetSlot() * 2), entryMap[playerGUID][item->GetGUIDLow()]);
+ }
+ }
+ }
+
+ void OnLogout(Player* player)
+ {
+ uint32 pGUID = player->GetGUIDLow();
+ if(entryMap.find(pGUID) == entryMap.end())
+ return;
+ for(transmogData::iterator it = entryMap[pGUID].begin(); it != entryMap[pGUID].end(); ++it)
+ {
+ dataMap.erase(it->first);
+ }
+ entryMap.erase(pGUID);
+ }
+};
+
+class Config_Transmogrify : public WorldScript
+{
+public:
+ Config_Transmogrify() : WorldScript("Config_Transmogrify") { }
+
+ void OnConfigLoad(bool reload)
+ {
+ sTransmogrification->LoadConfig();
+ }
+
+ void OnStartup()
+ {
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Deleting non-existing transmogrification entries...");
+ CharacterDatabase.Execute("DELETE FROM custom_transmogrification WHERE NOT EXISTS (SELECT 1 FROM item_instance WHERE item_instance.guid = custom_transmogrification.GUID)");
+ }
+};
+
+void AddSC_NPC_Transmogrify()
+{
+ new NPC_Transmogrify();
+ new Player_Transmogrify();
+ new Config_Transmogrify();
+}
diff --git a/src/server/scripts/Custom/Transmogrification.h b/src/server/scripts/Custom/Transmogrification.h
new file mode 100644
index 0000000..a4bcb14
--- /dev/null
+++ b/src/server/scripts/Custom/Transmogrification.h
@@ -0,0 +1,140 @@
+#ifndef DEF_TRANSMOGRIFICATION_H
+#define DEF_TRANSMOGRIFICATION_H
+
+#include "Config.h"
+
+enum TransmogTrinityStrings
+{
+ LANG_REM_TRANSMOGRIFICATIONS_ITEMS = 11100,
+ LANG_ERR_NO_TRANSMOGRIFICATIONS = 11101,
+ LANG_REM_TRANSMOGRIFICATION_ITEM = 11102,
+ LANG_ERR_NO_TRANSMOGRIFICATION = 11103,
+ LANG_ITEM_TRANSMOGRIFIED = 11104,
+ LANG_ERR_NO_ITEM_SUITABLE = 11105,
+ LANG_ERR_NO_ITEM_EXISTS = 11106,
+ LANG_ERR_EQUIP_SLOT_EMPTY = 11107,
+
+ LANG_SLOT_NAME_HEAD = 11108,
+ LANG_SLOT_NAME_SHOULDERS = 11109,
+ LANG_SLOT_NAME_BODY = 11110,
+ LANG_SLOT_NAME_CHEST = 11111,
+ LANG_SLOT_NAME_WAIST = 11112,
+ LANG_SLOT_NAME_LEGS = 11113,
+ LANG_SLOT_NAME_FEET = 11114,
+ LANG_SLOT_NAME_WRISTS = 11115,
+ LANG_SLOT_NAME_HANDS = 11116,
+ LANG_SLOT_NAME_BACK = 11117,
+ LANG_SLOT_NAME_MAINHAND = 11118,
+ LANG_SLOT_NAME_OFFHAND = 11119,
+ LANG_SLOT_NAME_RANGED = 11120,
+ LANG_SLOT_NAME_TABARD = 11121,
+
+ LANG_OPTION_BACK = 11122,
+ LANG_OPTION_REMOVE_ALL = 11123,
+ LANG_POPUP_REMOVE_ALL = 11124,
+ LANG_OPTION_UPDATE_MENU = 11125,
+ LANG_OPTION_REMOVE_ONE = 11126,
+ LANG_POPUP_REMOVE_ONE = 11127,
+ LANG_POPUP_TRANSMOGRIFY = 11128,
+
+ LANG_ERR_NO_TOKEN = 11129
+};
+
+enum TransmogrificationResult // custom
+{
+ ERR_FAKE_NEW_BAD_QUALITY,
+ ERR_FAKE_OLD_BAD_QUALITY,
+ ERR_FAKE_SAME_DISPLAY,
+ ERR_FAKE_SAME_DISPLAY_FAKE,
+ ERR_FAKE_CANT_USE,
+ ERR_FAKE_NOT_SAME_CLASS,
+ ERR_FAKE_BAD_CLASS,
+ ERR_FAKE_BAD_SUBLCASS,
+ ERR_FAKE_BAD_INVENTORYTYPE,
+ ERR_FAKE_OK
+};
+
+class Transmogrification
+{
+public:
+ Transmogrification() { };
+ ~Transmogrification() { };
+
+ uint32 GetRequireGold() { return RequireGold; }
+ float GetGoldModifier() { return GoldModifier; }
+ uint32 GetGoldCost() { return GoldCost; }
+
+ bool GetRequireToken() { return RequireToken; }
+ uint32 GetTokenEntry() { return TokenEntry; }
+ uint32 GetTokenAmount() { return TokenAmount; }
+
+ static uint32 GetFakeEntry(Item* item);
+ static void DeleteFakeFromDB(uint32 lowGUID);
+ static bool DeleteFakeEntry(Item* item);
+ static void SetFakeEntry(Item* item, uint32 entry);
+ static uint32 SuitableForTransmogrification(Player* player, Item* oldItem, Item* newItem);
+
+ bool AllowedQuality(uint32 quality) // Only thing used elsewhere (Player.cpp)
+ {
+ switch(quality)
+ {
+ case ITEM_QUALITY_POOR: return AllowPoor;
+ case ITEM_QUALITY_NORMAL: return AllowCommon;
+ case ITEM_QUALITY_UNCOMMON: return AllowUncommon;
+ case ITEM_QUALITY_RARE: return AllowRare;
+ case ITEM_QUALITY_EPIC: return AllowEpic;
+ case ITEM_QUALITY_LEGENDARY: return AllowLegendary;
+ case ITEM_QUALITY_ARTIFACT: return AllowArtifact;
+ case ITEM_QUALITY_HEIRLOOM: return AllowHeirloom;
+ default: return false;
+ }
+ }
+
+ void LoadConfig()
+ {
+ RequireGold = (uint32)ConfigMgr::GetIntDefault("Transmogrification.RequireGold", 1);
+ GoldModifier = ConfigMgr::GetFloatDefault("Transmogrification.GoldModifier", 1.0f);
+ GoldCost = (uint32)ConfigMgr::GetIntDefault("Transmogrification.GoldCost", 100000);
+
+ RequireToken = ConfigMgr::GetBoolDefault("Transmogrification.RequireToken", false);
+ TokenEntry = (uint32)ConfigMgr::GetIntDefault("Transmogrification.TokenEntry", 49426);
+ TokenAmount = (uint32)ConfigMgr::GetIntDefault("Transmogrification.TokenAmount", 1);
+
+ AllowPoor = ConfigMgr::GetBoolDefault("Transmogrification.AllowPoor", false);
+ AllowCommon = ConfigMgr::GetBoolDefault("Transmogrification.AllowCommon", false);
+ AllowUncommon = ConfigMgr::GetBoolDefault("Transmogrification.AllowUncommon", true);
+ AllowRare = ConfigMgr::GetBoolDefault("Transmogrification.AllowRare", true);
+ AllowEpic = ConfigMgr::GetBoolDefault("Transmogrification.AllowEpic", true);
+ AllowLegendary = ConfigMgr::GetBoolDefault("Transmogrification.AllowLegendary", false);
+ AllowArtifact = ConfigMgr::GetBoolDefault("Transmogrification.AllowArtifact", false);
+ AllowHeirloom = ConfigMgr::GetBoolDefault("Transmogrification.AllowHeirloom", true);
+
+ if(!sObjectMgr->GetItemTemplate(TokenEntry))
+ {
+ sLog->outError(LOG_FILTER_SERVER_LOADING, "Transmogrification.TokenEntry (%u) does not exist. Using default.", TokenEntry);
+ TokenEntry = 49426;
+ }
+ }
+
+private:
+
+ uint32 RequireGold;
+ float GoldModifier;
+ uint32 GoldCost;
+
+ bool RequireToken;
+ uint32 TokenEntry;
+ uint32 TokenAmount;
+
+ bool AllowPoor;
+ bool AllowCommon;
+ bool AllowUncommon;
+ bool AllowRare;
+ bool AllowEpic;
+ bool AllowLegendary;
+ bool AllowArtifact;
+ bool AllowHeirloom;
+};
+#define sTransmogrification ACE_Singleton<Transmogrification, ACE_Null_Mutex>::instance()
+
+#endif
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 641fe1e..3682332 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2848,3 +2848,91 @@ Log.Async.Enable = 0
#
###################################################################################################
+
+###################################################################################################
+# Transmogrification config
+###################################################################################################
+#
+# GOLD COST
+#
+# Transmogrification.RequireGold
+# Description: 0 No gold cost, 1 scaling gold cost, 2 custom gold cost
+# Default: 1
+#
+# Transmogrification.GoldModifier
+# Description: A multiplier for the default gold cost (Transmogrification.RequireGold is 1)
+# Default: 1.0
+#
+# Transmogrification.GoldCost
+# Description: Cost of transmogrification in copper for custom gold cost (Transmogrification.RequireGold is 2)
+# Default: 100000
+
+Transmogrification.RequireGold = 1
+Transmogrification.GoldModifier = 1.0
+Transmogrification.GoldCost = 100000
+
+#
+# TOKEN COST
+#
+# Transmogrification.RequireToken
+# Description: Adds/disables token cost
+# Default: 0
+#
+# Transmogrification.TokenEntry
+# Description: Entry of the token item
+# Default: 49426
+#
+# Transmogrification.TokenAmount
+# Description: Amount of tokens required
+# Default: 1
+
+Transmogrification.RequireToken = 0
+Transmogrification.TokenEntry = 49426
+Transmogrification.TokenAmount = 1
+
+#
+# QUALITIES
+#
+# Transmogrification.AllowPoor
+# Description: Allow poor quality items to be used as source and target items
+# Default: 0
+#
+# Transmogrification.AllowCommon
+# Description: Allow common quality items to be used as source and target items
+# Default: 0
+#
+# Transmogrification.AllowUncommon
+# Description: Allow uncommon quality items to be used as source and target items
+# Default: 1
+#
+# Transmogrification.AllowRare
+# Description: Allow rare quality items to be used as source and target items
+# Default: 1
+#
+# Transmogrification.AllowEpic
+# Description: Allow epic quality items to be used as source and target items
+# Default: 1
+#
+# Transmogrification.AllowLegendary
+# Description: Allow legendary quality items to be used as source and target items
+# Default: 0
+#
+# Transmogrification.AllowArtifact
+# Description: Allow artifact quality items to be used as source and target items
+# Default: 0
+#
+# Transmogrification.AllowHeirloom
+# Description: Allow heirloom quality items to be used as source and target items
+# Default: 1
+
+Transmogrification.AllowPoor = 1
+Transmogrification.AllowCommon = 1
+Transmogrification.AllowUncommon = 1
+Transmogrification.AllowRare = 1
+Transmogrification.AllowEpic = 1
+Transmogrification.AllowLegendary = 1
+Transmogrification.AllowArtifact = 1
+Transmogrification.AllowHeirloom = 1
+
+#
+###################################################################################################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment