-
-
Save nzatsepilov/2897097 to your computer and use it in GitHub Desktop.
Transmogrification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 64c327d1393abaced5445b855cfb74ac639d32e3 Mon Sep 17 00:00:00 2001 | |
From: walkline <walkline.ua@gmail.com> | |
Date: Mon, 4 Jun 2012 19:49:20 +0300 | |
Subject: [PATCH] Imlemented Transmogrification. | |
diff --git a/sql/updates/fc_updates_characters/fake_items.sql b/sql/updates/fc_updates_characters/fake_items.sql | |
new file mode 100644 | |
index 0000000..3618ac1 | |
--- /dev/null | |
+++ b/sql/updates/fc_updates_characters/fake_items.sql | |
@@ -0,0 +1,11 @@ | |
+DROP TABLE IF EXISTS `fake_items`; | |
+CREATE TABLE `fake_items` ( | |
+ `guid` int(11) NOT NULL, | |
+ `fakeEntry` int(11) NOT NULL, | |
+ PRIMARY KEY (`guid`) | |
+); | |
+ | |
+INSERT INTO `gossip_menu` VALUES (51000, 51000); | |
+INSERT INTO npc_text (ID, text0_0, em0_1) VALUES | |
+(51000, 'Put in the first slot of bag item, that you want to transmogrify. In the second slot, put item with perfect display.', 0); | |
+ | |
diff --git a/sql/updates/fc_updates_world/fake_items.sql b/sql/updates/fc_updates_world/fake_items.sql | |
new file mode 100644 | |
index 0000000..7cfd4cc | |
--- /dev/null | |
+++ b/sql/updates/fc_updates_world/fake_items.sql | |
@@ -0,0 +1,3 @@ | |
+DELETE FROM creature_template WHERE entry = '190001'; | |
+INSERT INTO creature_template (entry, modelid1, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, Health_mod, Mana_mod, Armor_mod, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, dmg_multiplier, unit_class, unit_flags, type, type_flags, InhabitType, RegenHealth, flags_extra, ScriptName) VALUES | |
+('190001', '15998', "Transmogrify Master", "", 'Speak', '50000', 71, 71, 1.56, 1.56, 1.56, 35, 35, 3, 1, 1.14286, 1.25, 1, 1, 1, 2, 7, 138936390, 3, 1, 2, 'npc_transmogrify'); | |
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp | |
index 23a3f50..6521f93 100755 | |
--- a/src/server/game/Entities/Item/Item.cpp | |
+++ b/src/server/game/Entities/Item/Item.cpp | |
@@ -251,6 +251,8 @@ Item::Item() | |
m_refundRecipient = 0; | |
m_paidMoney = 0; | |
m_paidExtendedCost = 0; | |
+ | |
+ m_fakeDisplayEntry = 0; | |
} | |
bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner) | |
@@ -468,6 +470,9 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entr | |
SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, fields[9].GetUInt32()); | |
SetText(fields[10].GetString()); | |
+ if (QueryResult result = CharacterDatabase.PQuery("SELECT fakeEntry FROM fake_items WHERE guid = %u", guid)) | |
+ SetFakeDisplay((*result)[0].GetUInt32()); | |
+ | |
if (need_save) // normal item changed state set not work at loading | |
{ | |
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD); | |
@@ -491,6 +496,7 @@ void Item::DeleteFromDB(SQLTransaction& trans, uint32 itemGuid) | |
void Item::DeleteFromDB(SQLTransaction& trans) | |
{ | |
+ RemoveFakeDisplay(); | |
DeleteFromDB(trans, GetGUIDLow()); | |
} | |
@@ -1207,3 +1213,48 @@ bool Item::CheckSoulboundTradeExpire() | |
return false; | |
} | |
+ | |
+FakeResult Item::SetFakeDisplay(uint32 iEntry) | |
+{ | |
+ if (!iEntry) | |
+ { | |
+ RemoveFakeDisplay(); | |
+ return FAKE_ERR_OK; | |
+ } | |
+ | |
+ ItemTemplate const* myTmpl = GetTemplate(); | |
+ ItemTemplate const* otherTmpl = sObjectMgr->GetItemTemplate(iEntry); | |
+ | |
+ if (!otherTmpl) | |
+ return FAKE_ERR_CANT_FIND_ITEM; | |
+ | |
+ if (myTmpl->InventoryType != otherTmpl->InventoryType) | |
+ return FAKE_ERR_DIFF_SLOTS; | |
+ | |
+ if (myTmpl->AllowableClass != otherTmpl->AllowableClass) | |
+ return FAKE_ERR_DIFF_CLASS; | |
+ | |
+ if (myTmpl->AllowableRace != otherTmpl->AllowableRace) | |
+ return FAKE_ERR_DIFF_RACE; | |
+ | |
+ if (otherTmpl->Quality == ITEM_QUALITY_LEGENDARY || otherTmpl->Quality == ITEM_QUALITY_POOR) | |
+ return FAKE_ERR_WRONG_QUALITY; | |
+ | |
+ if (m_fakeDisplayEntry != iEntry) | |
+ { | |
+ (!m_fakeDisplayEntry) ? CharacterDatabase.PExecute("INSERT INTO fake_items VALUES (%u, %u)", GetGUIDLow(), iEntry) : | |
+ CharacterDatabase.PExecute("UPDATE fake_items SET fakeEntry = %u WHERE guid = %u", iEntry, GetGUIDLow()); | |
+ m_fakeDisplayEntry = iEntry; | |
+ } | |
+ | |
+ return FAKE_ERR_OK; | |
+} | |
+ | |
+void Item::RemoveFakeDisplay() | |
+{ | |
+ if (GetFakeDisplayEntry()) | |
+ { | |
+ m_fakeDisplayEntry = 0; | |
+ CharacterDatabase.PExecute("DELETE FROM fake_items WHERE guid = %u", GetGUIDLow()); | |
+ } | |
+} | |
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h | |
index 1d5fcae..32f1ef6 100755 | |
--- a/src/server/game/Entities/Item/Item.h | |
+++ b/src/server/game/Entities/Item/Item.h | |
@@ -152,6 +152,17 @@ enum SellResult | |
SELL_ERR_ONLY_EMPTY_BAG = 6 // can only do with empty bags | |
}; | |
+enum FakeResult | |
+{ | |
+ FAKE_ERR_CANT_FIND_OWNER, | |
+ FAKE_ERR_CANT_FIND_ITEM, | |
+ FAKE_ERR_WRONG_QUALITY, | |
+ FAKE_ERR_DIFF_SLOTS, | |
+ FAKE_ERR_DIFF_CLASS, | |
+ FAKE_ERR_DIFF_RACE, | |
+ FAKE_ERR_OK | |
+}; | |
+ | |
// -1 from client enchantment slot number | |
enum EnchantmentSlot | |
{ | |
@@ -340,6 +351,10 @@ class Item : public Object | |
void BuildUpdate(UpdateDataMapType&); | |
uint32 GetScriptId() const { return GetTemplate()->ScriptId; } | |
+ | |
+ FakeResult SetFakeDisplay(uint32 iEntry); | |
+ uint32 GetFakeDisplayEntry() { return m_fakeDisplayEntry; } | |
+ void RemoveFakeDisplay(); | |
private: | |
std::string m_text; | |
uint8 m_slot; | |
@@ -352,5 +367,7 @@ class Item : public Object | |
uint32 m_paidMoney; | |
uint32 m_paidExtendedCost; | |
AllowedLooterSet allowedGUIDs; | |
+ | |
+ uint32 m_fakeDisplayEntry; | |
}; | |
#endif | |
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp | |
index dd35dea..fc8e4d0 100755 | |
--- a/src/server/game/Entities/Player/Player.cpp | |
+++ b/src/server/game/Entities/Player/Player.cpp | |
@@ -12719,7 +12719,7 @@ void Player::SetVisibleItemSlot(uint8 slot, Item* pItem) | |
{ | |
if (pItem) | |
{ | |
- SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetEntry()); | |
+ SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), (pItem->GetFakeDisplayEntry()) ? pItem->GetFakeDisplayEntry() : 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)); | |
} | |
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp | |
index e5833c5..fa6a6c9 100755 | |
--- a/src/server/game/Scripting/ScriptLoader.cpp | |
+++ b/src/server/game/Scripting/ScriptLoader.cpp | |
@@ -38,6 +38,8 @@ void AddSC_ArgentTournament(); | |
void AddSC_dalaran_squirrel(); | |
// Arena Spectator | |
void AddSC_arena_spectator_script(); | |
+// Transmogrify | |
+void AddSC_transmogrify_script(); | |
// spells | |
void AddSC_deathknight_spell_scripts(); | |
@@ -1271,5 +1273,6 @@ void AddCustomScripts() | |
AddSC_ArgentTournament(); | |
AddSC_dalaran_squirrel(); | |
AddSC_arena_spectator_script(); | |
+ AddSC_transmogrify_script(); | |
#endif | |
} | |
diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt | |
index 24477b0..c5dde7b 100644 | |
--- a/src/server/scripts/Custom/CMakeLists.txt | |
+++ b/src/server/scripts/Custom/CMakeLists.txt | |
@@ -15,6 +15,7 @@ set(scripts_STAT_SRCS | |
Custom/argent_tournament.cpp | |
Custom/dalaran_squirrel.cpp | |
Custom/arena_spectator.cpp | |
+ Custom/npc_transmogrify.cpp | |
) | |
message(" -> Prepared: Custom") | |
diff --git a/src/server/scripts/Custom/npc_transmogrify.cpp b/src/server/scripts/Custom/npc_transmogrify.cpp | |
new file mode 100644 | |
index 0000000..94c98be | |
--- /dev/null | |
+++ b/src/server/scripts/Custom/npc_transmogrify.cpp | |
@@ -0,0 +1,134 @@ | |
+/* | |
+ * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> | |
+ * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, but WITHOUT | |
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
+ * more details. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program. If not, see <http://www.gnu.org/licenses/>. | |
+ */ | |
+ | |
+/* ScriptData | |
+Name: Transmogrify Npc | |
+%Complete: 100 | |
+Category: Custom Script | |
+EndScriptData */ | |
+ | |
+#include "ScriptPCH.h" | |
+ | |
+enum TransmogrifyActions { | |
+ ACTION_TRANSMOGRIFY_ADD_DISPLAY, | |
+ ACTION_TRANSMOGRIFY_REMOVE_DISPLAY | |
+}; | |
+ | |
+const uint16 PriceInGold = 1000; // 1k golds | |
+ | |
+class npc_transmogrify : public CreatureScript | |
+{ | |
+ public: | |
+ npc_transmogrify() : CreatureScript("npc_transmogrify") { } | |
+ | |
+ bool OnGossipHello(Player* pPlayer, Creature* pCreature) | |
+ { | |
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "Make exchange!", GOSSIP_SENDER_MAIN, ACTION_TRANSMOGRIFY_ADD_DISPLAY); | |
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "Make item clean.", GOSSIP_SENDER_MAIN, ACTION_TRANSMOGRIFY_REMOVE_DISPLAY); | |
+ pPlayer->SEND_GOSSIP_MENU(51000, pCreature->GetGUID()); | |
+ return true; | |
+ } | |
+ | |
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) | |
+ { | |
+ player->PlayerTalkClass->SendCloseGossip(); | |
+ switch (action) | |
+ { | |
+ case ACTION_TRANSMOGRIFY_ADD_DISPLAY: | |
+ TransmogrifyItem(player, creature); | |
+ break; | |
+ case ACTION_TRANSMOGRIFY_REMOVE_DISPLAY: | |
+ ClearItem(player, creature); | |
+ break; | |
+ } | |
+ return true; | |
+ } | |
+ | |
+ void TransmogrifyItem(Player* player, Creature* creature) | |
+ { | |
+ ChatHandler handler(player); | |
+ Item *trItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_ITEM_START); | |
+ Item *displayItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_ITEM_START + 1); | |
+ if (!trItem || !displayItem) | |
+ { | |
+ handler.PSendSysMessage("Put item in the first and second slot!"); | |
+ return; | |
+ } | |
+ | |
+ if (player->GetMoney() < PriceInGold * 100 * 100) | |
+ { | |
+ handler.PSendSysMessage("It costs %u gold!", PriceInGold); | |
+ return; | |
+ } | |
+ | |
+ uint8 result = trItem->SetFakeDisplay(displayItem->GetTemplate()->ItemId); | |
+ switch (result) | |
+ { | |
+ case FAKE_ERR_CANT_FIND_ITEM: | |
+ handler.PSendSysMessage("Cant find item!"); | |
+ break; | |
+ case FAKE_ERR_WRONG_QUALITY: | |
+ handler.PSendSysMessage("Item has wrong quality!"); | |
+ break; | |
+ case FAKE_ERR_DIFF_SLOTS: | |
+ handler.PSendSysMessage("Items has different types!"); | |
+ break; | |
+ case FAKE_ERR_DIFF_CLASS: | |
+ case FAKE_ERR_DIFF_RACE: | |
+ handler.PSendSysMessage("Items require different options!"); | |
+ break; | |
+ case FAKE_ERR_OK: | |
+ { | |
+ WorldPacket data; | |
+ data << uint8(INVENTORY_SLOT_BAG_0); | |
+ data << uint8(trItem->GetSlot()); | |
+ player->GetSession()->HandleAutoEquipItemOpcode(data); | |
+ | |
+ player->ModifyMoney(-1 * PriceInGold * 100 * 100); | |
+ creature->GetAI()->DoCast(63491); | |
+ | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ | |
+ void ClearItem(Player *player, Creature* creature) | |
+ { | |
+ ChatHandler handler(player); | |
+ Item *trItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_ITEM_START); | |
+ if (!trItem) | |
+ { | |
+ handler.PSendSysMessage("Put item in the first slot!"); | |
+ return; | |
+ } | |
+ | |
+ trItem->RemoveFakeDisplay(); | |
+ | |
+ WorldPacket data; | |
+ data << uint8(INVENTORY_SLOT_BAG_0); | |
+ data << uint8(trItem->GetSlot()); | |
+ player->GetSession()->HandleAutoEquipItemOpcode(data); | |
+ | |
+ creature->GetAI()->DoCast(63491); | |
+ } | |
+}; | |
+ | |
+void AddSC_transmogrify_script() | |
+{ | |
+ new npc_transmogrify; | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment