From c53437bc759662f51230495e5cc069c1d280679b Mon Sep 17 00:00:00 2001 From: Ercules76 Date: Thu, 21 Mar 2019 19:38:40 +0100 Subject: [PATCH] Skill perfect item template (#1564) * Core/Misc Created handler for character creation * fix(Core/DB): Error message when the password is longer than 16 char when creating an account * Update rev_1551539925032805900.sql * Update AccountMgr.cpp * Milestone (DB/Core): Create new table for perfect item craft, create new command for reload capability to this new table, implements the table into core (killExtraItems.cpp, SkillExtraItems.h, SpellEffects.cpp), change some magic number with enum. Tnx to Treestone * clean old sql * Remove perfect item in skill extra item template table, now the perfect are in skill_perfect_item_template, sync column name skill_extra_item_template same as TC * Update rev_1552232377246845400.sql --- .../rev_1552232377246845400.sql | 107 ++++++++++++++ src/server/game/Skills/SkillExtraItems.cpp | 112 ++++++++++++++- src/server/game/Skills/SkillExtraItems.h | 4 + src/server/game/Spells/SpellEffects.cpp | 48 +++++-- src/server/game/World/World.cpp | 3 + src/server/scripts/Commands/cs_reload.cpp | 13 +- src/server/scripts/World/npc_professions.cpp | 136 ++++++++++++------ 7 files changed, 361 insertions(+), 62 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1552232377246845400.sql diff --git a/data/sql/updates/pending_db_world/rev_1552232377246845400.sql b/data/sql/updates/pending_db_world/rev_1552232377246845400.sql new file mode 100644 index 000000000..df66eb4c5 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1552232377246845400.sql @@ -0,0 +1,107 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1552232377246845400'); + +DELETE FROM `skill_extra_item_template` WHERE `spellId` IN +('53831', '53832', '53834', '53835', '53843', '53844', '53845', '53852', '53853', +'53854', '53855', '53856', '53857', '53859', '53860', '53861', '53862', '53863', +'53864', '53865', '53866', '53867', '53868', '53869', '53870', '53871', '53872', +'53873', '53874', '53875', '53876', '53877', '53878', '53879', '53880', '53881', +'53882', '53883', '53884', '53885', '53886', '53887', '53888', '53889', '53890', +'53891', '53892', '53893', '53894', '53916', '53917', '53918', '53919', '53920', +'53921', '53922', '53923', '53924', '53925', '53926', '53927', '53928', '53929', +'53930', '53931', '53932', '53933', '53934', '53940', '53941', '53943', '54017'); + +ALTER TABLE `skill_extra_item_template` CHANGE COLUMN `newMaxOrEntry` `additionalMaxNum` TINYINT(3) NOT NULL DEFAULT '0' ; + +DROP TABLE IF EXISTS `skill_perfect_item_template`; + +CREATE TABLE `skill_perfect_item_template` ( + `spellId` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'SpellId of the item creation spell', + `requiredSpecialization` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Specialization spell id', + `perfectCreateChance` float NOT NULL DEFAULT '0' COMMENT 'chance to create the perfect item instead', + `perfectItemType` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'perfect item type to create instead', + PRIMARY KEY (`spellId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Crafting Perfection System'; + +START TRANSACTION; + +INSERT INTO `skill_perfect_item_template` (`spellId`, `requiredSpecialization`, `perfectCreateChance`, `perfectItemType`) +VALUES +/* Bloodstone */ +(53831,55534,20,41432), -- Bold +(53835,55534,20,41433), -- Bright +(53832,55534,20,41434), -- Delicate +(53844,55534,20,41435), -- Flashing +(53845,55534,20,41436), -- Fractured +(54017,55534,20,41437), -- Precise +(53834,55534,20,41438), -- Runed +(53843,55534,20,41439), -- Subtle +/* Sun Crystal */ +(53852,55534,20,41444), -- Brilliant +(53857,55534,20,41445), -- Mystic +(53856,55534,20,41446), -- Quick +(53854,55534,20,41447), -- Rigid +(53853,55534,20,41448), -- Smooth +(53855,55534,20,41449), -- Thick +/* Chalcedony */ +(53941,55534,20,41440), -- Lustrous +(53934,55534,20,41441), -- Solid +(53940,55534,20,41442), -- Sparkling +(53943,55534,20,41443), -- Stormy +/* Dark Jade */ +(53926,55534,20,41463), -- Dazzling +(53918,55534,20,41464), -- Enduring +(53930,55534,20,41465), -- Energized +(53920,55534,20,41466), -- Forceful +(53925,55534,20,41467), -- Intricate +(53916,55534,20,41468), -- Jagged +(53928,55534,20,41469), -- Lambent +(53922,55534,20,41470), -- Misty +(53929,55534,20,41471), -- Opaque +(53931,55534,20,41472), -- Radiant +(53921,55534,20,41473), -- Seer's +(53933,55534,20,41474), -- Shattered +(53923,55534,20,41475), -- Shining +(53919,55534,20,41476), -- Steady +(53927,55534,20,41477), -- Sundered +(53932,55534,20,41478), -- Tense +(53894,55534,20,41479), -- Timeless +(53924,55534,20,41480), -- Turbid +(53917,55534,20,41481), -- Vivid +/* Huge Citrine */ +(53886,55534,20,41429), -- Wicked +(53892,55534,20,41482), -- Accurate +(53874,55534,20,41483), -- Champion's +(53877,55534,20,41484), -- Deadly +(53880,55534,20,41485), -- Deft +(53884,55534,20,41486), -- Durable +(53888,55534,20,41487), -- Empowered +(53873,55534,20,41488), -- Etched +(53876,55534,20,41489), -- Fierce +(53891,55534,20,41490), -- Glimmering +(53878,55534,20,41491), -- Glinting +(53872,55534,20,41492), -- Inscribed +(53879,55534,20,41493), -- Lucent +(53881,55534,20,41494), -- Luminous +(53882,55534,20,41495), -- Potent +(53887,55534,20,41496), -- Pristine +(53885,55534,20,41497), -- Reckless +(53893,55534,20,41498), -- Resolute +(53875,55534,20,41499), -- Resplendent +(53890,55534,20,41500), -- Stalwart +(53889,55534,20,41501), -- Stark +(53883,55534,20,41502), -- Veiled +/* Shadow Crystal */ +(53866,55534,20,41450), -- Balanced +(53869,55534,20,41451), -- Defender's +(53862,55534,20,41452), -- Glowing +(53871,55534,20,41453), -- Guardian's +(53867,55534,20,41454), -- Infused +(53865,55534,20,41455), -- Mysterious +(53870,55534,20,41456), -- Puissant +(53863,55534,20,41457), -- Purified +(53868,55534,20,41458), -- Regal +(53864,55534,20,41459), -- Royal +(53860,55534,20,41460), -- Shifting +(53859,55534,20,41461), -- Sovereign +(53861,55534,20,41462); -- Tenuous +COMMIT; diff --git a/src/server/game/Skills/SkillExtraItems.cpp b/src/server/game/Skills/SkillExtraItems.cpp index 647281fd3..c332c4d04 100644 --- a/src/server/game/Skills/SkillExtraItems.cpp +++ b/src/server/game/Skills/SkillExtraItems.cpp @@ -8,6 +8,7 @@ #include "DatabaseEnv.h" #include "Log.h" #include "Player.h" +#include "ObjectMgr.h" #include // some type definitions @@ -15,6 +16,91 @@ // struct to store information about extra item creation // one entry for every spell that is able to create an extra item +struct SkillPerfectItemEntry +{ + // the spell id of the spell required - it's named "specialization" to conform with SkillExtraItemEntry + uint32 requiredSpecialization; + // perfection proc chance + float perfectCreateChance; + // itemid of the resulting perfect item + uint32 perfectItemType; + + SkillPerfectItemEntry() + : requiredSpecialization(0), perfectCreateChance(0.0f), perfectItemType(0) { } + SkillPerfectItemEntry(uint32 rS, float pCC, uint32 pIT) + : requiredSpecialization(rS), perfectCreateChance(pCC), perfectItemType(pIT) { } +}; + +// map to store perfection info. key = spellId of the creation spell, value is the perfectitementry as specified above +typedef std::map SkillPerfectItemMap; + +SkillPerfectItemMap SkillPerfectItemStore; + +// loads the perfection proc info from DB +void LoadSkillPerfectItemTable() +{ + uint32 oldMSTime = getMSTime(); + + SkillPerfectItemStore.clear(); // reload capability + + // 0 1 2 3 + QueryResult result = WorldDatabase.Query("SELECT spellId, requiredSpecialization, perfectCreateChance, perfectItemType FROM skill_perfect_item_template"); + + if (!result) + { + sLog->outErrorDb(">> Loaded 0 spell perfection definitions. DB table `skill_perfect_item_template` is empty."); + sLog->outString(); + return; + } + + uint32 count = 0; + + do /* fetch data and run sanity checks */ + { + Field* fields = result->Fetch(); + + uint32 spellId = fields[0].GetUInt32(); + + if (!sSpellMgr->GetSpellInfo(spellId)) + { + sLog->outError("Skill perfection data for spell %u has non-existent spell id in `skill_perfect_item_template`!", spellId); + continue; + } + + uint32 requiredSpecialization = fields[1].GetUInt32(); + if (!sSpellMgr->GetSpellInfo(requiredSpecialization)) + { + sLog->outError("Skill perfection data for spell %u has non-existent required specialization spell id %u in `skill_perfect_item_template`!", spellId, requiredSpecialization); + continue; + } + + float perfectCreateChance = fields[2].GetFloat(); + if (perfectCreateChance <= 0.0f) + { + sLog->outError("Skill perfection data for spell %u has impossibly low proc chance in `skill_perfect_item_template`!", spellId); + continue; + } + + uint32 perfectItemType = fields[3].GetUInt32(); + if (!sObjectMgr->GetItemTemplate(perfectItemType)) + { + sLog->outError("Skill perfection data for spell %u references non-existent perfect item id %u in `skill_perfect_item_template`!", spellId, perfectItemType); + continue; + } + + SkillPerfectItemEntry& skillPerfectItemEntry = SkillPerfectItemStore[spellId]; + + skillPerfectItemEntry.requiredSpecialization = requiredSpecialization; + skillPerfectItemEntry.perfectCreateChance = perfectCreateChance; + skillPerfectItemEntry.perfectItemType = perfectItemType; + + ++count; + } while (result->NextRow()); + + sLog->outString(">> Loaded %u spell perfection definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + sLog->outString(); +} + struct SkillExtraItemEntry { // the spell id of the specialization required to create extra items @@ -44,7 +130,7 @@ void LoadSkillExtraItemTable() SkillExtraItemStore.clear(); // need for reload // 0 1 2 3 - QueryResult result = WorldDatabase.Query("SELECT spellId, requiredSpecialization, additionalCreateChance, newMaxOrEntry FROM skill_extra_item_template"); + QueryResult result = WorldDatabase.Query("SELECT spellId, requiredSpecialization, additionalCreateChance, additionalMaxNum FROM skill_extra_item_template"); if (!result) { @@ -102,6 +188,30 @@ void LoadSkillExtraItemTable() sLog->outString(); } +bool CanCreatePerfectItem(Player* player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType) +{ + SkillPerfectItemMap::const_iterator ret = SkillPerfectItemStore.find(spellId); + // no entry in DB means no perfection proc possible + if (ret == SkillPerfectItemStore.end()) + return false; + + SkillPerfectItemEntry const* thisEntry = &ret->second; + // lack of entry means no perfection proc possible + if (!thisEntry) + return false; + + // if you don't have the spell needed, then no procs for you + if (!player->HasSpell(thisEntry->requiredSpecialization)) + return false; + + // set values as appropriate + perfectCreateChance = thisEntry->perfectCreateChance; + perfectItemType = thisEntry->perfectItemType; + + // and tell the caller to start rolling the dice + return true; +} + bool canCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry) { // get the info for the specified spell diff --git a/src/server/game/Skills/SkillExtraItems.h b/src/server/game/Skills/SkillExtraItems.h index d677d8d02..0dace5a49 100644 --- a/src/server/game/Skills/SkillExtraItems.h +++ b/src/server/game/Skills/SkillExtraItems.h @@ -11,6 +11,10 @@ // predef classes used in functions class Player; +// returns true and sets the appropriate info if the player can create a perfect item with the given spellId +bool CanCreatePerfectItem(Player* player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType); +// load perfection proc info from DB +void LoadSkillPerfectItemTable(); // returns true and sets the appropriate info if the player can create extra items with the given spellId bool canCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry); // function to load the extra item creation info from DB diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index a75ee33e0..9e25358ae 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1666,7 +1666,9 @@ void Spell::DoCreateItem(uint8 /*effIndex*/, uint32 itemId) Player* player = unitTarget->ToPlayer(); - ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemId); + uint32 newitemid = itemId; + + ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid); if (!pProto) { player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); @@ -1703,30 +1705,46 @@ void Spell::DoCreateItem(uint8 /*effIndex*/, uint32 itemId) if (addNumber > pProto->GetMaxStackSize()) addNumber = pProto->GetMaxStackSize(); + /* == gem perfection handling == */ + + // the chance of getting a perfect result + float perfectCreateChance = 0.0f; + + // the resulting perfect item if successful + uint32 perfectItemType = itemId; + + // get perfection capability and chance + if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType)) + if (roll_chance_f(perfectCreateChance)) // if the roll succeeds... + newitemid = perfectItemType; // the perfect item replaces the regular one + + /* == gem perfection handling over == */ + + + /* == profession specialization handling == */ + + // init items_count to 1, since 1 item will be created regardless of specialization int32 itemsCount = 1; float additionalCreateChance = 0.0f; - int32 newMaxOrEntry = 0; + int32 additionalMaxNum = 0; // get the chance and maximum number for creating extra items - if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, newMaxOrEntry)) + if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum)) { - if (newMaxOrEntry > 0) - { - // roll with this chance till we roll not to create or we create the max num - while (roll_chance_f(additionalCreateChance) && itemsCount <= newMaxOrEntry) - ++itemsCount; - } - else if (roll_chance_f(additionalCreateChance)) // if the roll succeeds... - itemId = uint32(-newMaxOrEntry); // the perfect item replaces the regular one + // roll with this chance till we roll not to create or we create the max num + while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum) + ++itemsCount; } // really will be created more items addNumber *= itemsCount; + /* == profession specialization handling over == */ + // can the player store the new item? ItemPosCountVec dest; uint32 no_space = 0; - InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, addNumber, &no_space); + InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space); if (msg != EQUIP_ERR_OK) { // convert to possible store amount @@ -1735,7 +1753,7 @@ void Spell::DoCreateItem(uint8 /*effIndex*/, uint32 itemId) else { // if not created by another reason from full inventory or unique items amount limitation - player->SendEquipError(msg, NULL, NULL, itemId); + player->SendEquipError(msg, NULL, NULL, newitemid); return; } } @@ -1743,7 +1761,7 @@ void Spell::DoCreateItem(uint8 /*effIndex*/, uint32 itemId) if (addNumber) { // create the new item and store it - Item* pItem = player->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); + Item* pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid)); // was it successful? return error if not if (!pItem) @@ -1753,7 +1771,7 @@ void Spell::DoCreateItem(uint8 /*effIndex*/, uint32 itemId) } // set the "Crafted by ..." property of the item - if (pItem->GetTemplate()->Class != ITEM_CLASS_CONSUMABLE && pItem->GetTemplate()->Class != ITEM_CLASS_QUEST && itemId != 6265 && itemId != 6948) + if (pItem->GetTemplate()->Class != ITEM_CLASS_CONSUMABLE && pItem->GetTemplate()->Class != ITEM_CLASS_QUEST && newitemid != 6265 && newitemid != 6948) pItem->SetUInt32Value(ITEM_FIELD_CREATOR, player->GetGUIDLow()); // send info to the client diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 696be0fba..47ffd5d49 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1692,6 +1692,9 @@ void World::SetInitialWorldSettings() sLog->outString("Loading Skill Extra Item Table..."); LoadSkillExtraItemTable(); + sLog->outString("Loading Skill Perfection Data Table..."); + LoadSkillPerfectItemTable(); + sLog->outString("Loading Skill Fishing base level requirements..."); sObjectMgr->LoadFishingBaseSkillLevel(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 97ffcfe7c..22ffa93f0 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -813,12 +813,21 @@ public: return true; } - static bool HandleReloadSkillExtraItemTemplateCommand(ChatHandler* handler, const char* /*args*/) + static bool HandleReloadSkillPerfectItemTemplateCommand(ChatHandler* handler, const char* /*args*/) + { + // latched onto HandleReloadSkillExtraItemTemplateCommand as it's part of that table group (and i don't want to chance all the command IDs) + sLog->outString("Re-Loading Skill Perfection Data Table..."); + LoadSkillPerfectItemTable(); + handler->SendGlobalGMSysMessage("DB table `skill_perfect_item_template` (perfect item procs when crafting) reloaded."); + return true; + } + + static bool HandleReloadSkillExtraItemTemplateCommand(ChatHandler* handler, const char* args) { sLog->outString("Re-Loading Skill Extra Item Table..."); LoadSkillExtraItemTable(); handler->SendGlobalGMSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded."); - return true; + return HandleReloadSkillPerfectItemTemplateCommand(handler, args); } static bool HandleReloadSkillFishingBaseLevelCommand(ChatHandler* handler, const char* /*args*/) diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp index 050f55f63..abe433870 100644 --- a/src/server/scripts/World/npc_professions.cpp +++ b/src/server/scripts/World/npc_professions.cpp @@ -174,6 +174,54 @@ enum ProfessionSpells S_UNLEARN_POTION = 41563, }; +/*### +# specialization trainers +###*/ +enum SpecializationTrainers +{ + /* Alchemy */ + N_TRAINER_TRANSMUTE = 22427, // Zarevhi + N_TRAINER_ELIXIR = 19052, // Lorokeem + N_TRAINER_POTION = 17909, // Lauranna Thar'well + + /* Blacksmithing */ + N_TRAINER_SMITHOMNI1 = 11145, // Myolor Sunderfury + N_TRAINER_SMITHOMNI2 = 11176, // Krathok Moltenfist + N_TRAINER_WEAPON1 = 11146, // Ironus Coldsteel + N_TRAINER_WEAPON2 = 11178, // Borgosh Corebender + N_TRAINER_ARMOR1 = 5164, // Grumnus Steelshaper + N_TRAINER_ARMOR2 = 11177, // Okothos Ironrager + N_TRAINER_HAMMER = 11191, // Lilith the Lithe + N_TRAINER_AXE = 11192, // Kilram + N_TRAINER_SWORD = 11193, // Seril Scourgebane + + /* Leatherworking */ + N_TRAINER_DRAGON1 = 7866, // Peter Galen + N_TRAINER_DRAGON2 = 7867, // Thorkaf Dragoneye + N_TRAINER_ELEMENTAL1 = 7868, // Sarah Tanner + N_TRAINER_ELEMENTAL2 = 7869, // Brumn Winterhoof + N_TRAINER_TRIBAL1 = 7870, // Caryssia Moonhunter + N_TRAINER_TRIBAL2 = 7871, // Se'Jib + + /* Tailoring */ + N_TRAINER_SPELLFIRE = 22213, // Gidge Spellweaver + N_TRAINER_MOONCLOTH = 22208, // Nasmara Moonsong + N_TRAINER_SHADOWEAVE = 22212, // Andrion Darkspinner +}; + +/*### +# specialization quests +###*/ +enum SpecializationQuests +{ + /* Alchemy */ + Q_MASTER_TRANSMUTE = 10899, + Q_MASTER_ELIXIR = 10902, + Q_MASTER_POTION = 10897, +}; + + + /*### # formulas to calculate unlearning cost ###*/ @@ -399,23 +447,23 @@ public: if (player->HasSkill(SKILL_ALCHEMY) && player->GetBaseSkillValue(SKILL_ALCHEMY) >= 350 && player->getLevel() > 67) { - if (player->GetQuestRewardStatus(10899) || player->GetQuestRewardStatus(10902) || player->GetQuestRewardStatus(10897)) + if (player->GetQuestRewardStatus(Q_MASTER_TRANSMUTE) || player->GetQuestRewardStatus(Q_MASTER_ELIXIR) || player->GetQuestRewardStatus(Q_MASTER_POTION)) { switch (creature->GetEntry()) { - case 22427: //Zarevhi + case N_TRAINER_TRANSMUTE: //Zarevhi if (!HasAlchemySpell(player)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_TRANSMUTE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 1); if (player->HasSpell(S_TRANSMUTE)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_TRANSMUTE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4); break; - case 19052: //Lorokeem + case N_TRAINER_ELIXIR: //Lorokeem if (!HasAlchemySpell(player)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_ELIXIR, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 2); if (player->HasSpell(S_ELIXIR)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_ELIXIR, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 5); break; - case 17909: //Lauranna Thar'well + case N_TRAINER_POTION: //Lauranna Thar'well if (!HasAlchemySpell(player)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_POTION, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 3); if (player->HasSpell(S_POTION)) @@ -468,17 +516,17 @@ public: { switch (creature->GetEntry()) { - case 22427: + case N_TRAINER_TRANSMUTE: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_TRANSMUTE, GOSSIP_SENDER_CHECK, action); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 19052: + case N_TRAINER_ELIXIR: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_ELIXIR, GOSSIP_SENDER_CHECK, action); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 17909: + case N_TRAINER_POTION: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_POTION, GOSSIP_SENDER_CHECK, action); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); @@ -493,17 +541,17 @@ public: { switch (creature->GetEntry()) { - case 22427: //Zarevhi + case N_TRAINER_TRANSMUTE: //Zarevhi player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_TRANSMUTE, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(player), false); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 19052: //Lorokeem + case N_TRAINER_ELIXIR: //Lorokeem player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_ELIXIR, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(player), false); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 17909: //Lauranna Thar'well + case N_TRAINER_POTION: //Lauranna Thar'well player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_POTION, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(player), false); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); @@ -570,20 +618,20 @@ public: { switch (creatureId) { - case 11145: //Myolor Sunderfury - case 11176: //Krathok Moltenfist + case N_TRAINER_SMITHOMNI1: //Myolor Sunderfury + case N_TRAINER_SMITHOMNI2: //Krathok Moltenfist if (!player->HasSpell(S_ARMOR) && !player->HasSpell(S_WEAPON)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARMOR_LEARN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); if (!player->HasSpell(S_WEAPON) && !player->HasSpell(S_ARMOR)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WEAPON_LEARN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); break; - case 11146: //Ironus Coldsteel - case 11178: //Borgosh Corebender + case N_TRAINER_WEAPON1: //Ironus Coldsteel + case N_TRAINER_WEAPON2: //Borgosh Corebender if (player->HasSpell(S_WEAPON)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WEAPON_UNLEARN, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 3); break; - case 5164: //Grumnus Steelshaper - case 11177: //Okothos Ironrager + case N_TRAINER_ARMOR1: //Grumnus Steelshaper + case N_TRAINER_ARMOR2: //Okothos Ironrager if (player->HasSpell(S_ARMOR)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARMOR_UNLEARN, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4); break; @@ -595,19 +643,19 @@ public: { switch (creatureId) { - case 11191: //Lilith the Lithe + case N_TRAINER_HAMMER: //Lilith the Lithe if (!HasWeaponSub(player)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_HAMMER, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 5); if (player->HasSpell(S_HAMMER)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_HAMMER, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 8); break; - case 11192: //Kilram + case N_TRAINER_AXE: //Kilram if (!HasWeaponSub(player)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_AXE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 6); if (player->HasSpell(S_AXE)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_AXE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 9); break; - case 11193: //Seril Scourgebane + case N_TRAINER_SWORD: //Seril Scourgebane if (!HasWeaponSub(player)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SWORD, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 7); if (player->HasSpell(S_SWORD)) @@ -676,17 +724,17 @@ public: { switch (creature->GetEntry()) { - case 11191: + case N_TRAINER_HAMMER: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_HAMMER, GOSSIP_SENDER_CHECK, action); //unknown textID (TALK_HAMMER_LEARN) player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 11192: + case N_TRAINER_AXE: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_AXE, GOSSIP_SENDER_CHECK, action); //unknown textID (TALK_AXE_LEARN) player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 11193: + case N_TRAINER_SWORD: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SWORD, GOSSIP_SENDER_CHECK, action); //unknown textID (TALK_SWORD_LEARN) player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); @@ -701,26 +749,26 @@ public: { switch (creature->GetEntry()) { - case 11146: //Ironus Coldsteel - case 11178: //Borgosh Corebender - case 5164: //Grumnus Steelshaper - case 11177: //Okothos Ironrager + case N_TRAINER_WEAPON1: //Ironus Coldsteel + case N_TRAINER_WEAPON2: //Borgosh Corebender + case N_TRAINER_ARMOR1: //Grumnus Steelshaper + case N_TRAINER_ARMOR2: //Okothos Ironrager player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SMITH_SPEC, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ARMORORWEAPON, DoLowUnlearnCost(player), false); //unknown textID (TALK_UNLEARN_AXEORWEAPON) player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 11191: + case N_TRAINER_HAMMER: player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_HAMMER, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_WEAPON_SPEC, DoMedUnlearnCost(player), false); //unknown textID (TALK_HAMMER_UNLEARN) player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 11192: + case N_TRAINER_AXE: player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_AXE, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_WEAPON_SPEC, DoMedUnlearnCost(player), false); //unknown textID (TALK_AXE_UNLEARN) player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 11193: + case N_TRAINER_SWORD: player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SWORD, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_WEAPON_SPEC, DoMedUnlearnCost(player), false); //unknown textID (TALK_SWORD_UNLEARN) player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); @@ -900,18 +948,18 @@ public: { switch (creature->GetEntry()) { - case 7866: //Peter Galen - case 7867: //Thorkaf Dragoneye + case N_TRAINER_DRAGON1: //Peter Galen + case N_TRAINER_DRAGON2: //Thorkaf Dragoneye if (!HasLeatherSpecialty(player) && (player->GetQuestRewardStatus(5141) || player->GetQuestRewardStatus(5145))) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_DRAGON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); break; - case 7868: //Sarah Tanner - case 7869: //Brumn Winterhoof + case N_TRAINER_ELEMENTAL1: //Sarah Tanner + case N_TRAINER_ELEMENTAL2: //Brumn Winterhoof if (!HasLeatherSpecialty(player) && (player->GetQuestRewardStatus(5144) || player->GetQuestRewardStatus(5146))) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_ELEMENTAL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); break; - case 7870: //Caryssia Moonhunter - case 7871: //Se'Jib + case N_TRAINER_TRIBAL1: //Caryssia Moonhunter + case N_TRAINER_TRIBAL2: //Se'Jib if (!HasLeatherSpecialty(player) && (player->GetQuestRewardStatus(5143) || player->GetQuestRewardStatus(5148))) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_TRIBAL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); break; @@ -990,19 +1038,19 @@ public: { switch (creature->GetEntry()) { - case 22213: //Gidge Spellweaver + case N_TRAINER_SPELLFIRE: //Gidge Spellweaver if (!HasTailorSpell(player)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SPELLFIRE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 1); if (player->HasSpell(S_SPELLFIRE)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_SPELLFIRE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4); break; - case 22208: //Nasmara Moonsong + case N_TRAINER_MOONCLOTH: //Nasmara Moonsong if (!HasTailorSpell(player)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_MOONCLOTH, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 2); if (player->HasSpell(S_MOONCLOTH)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_MOONCLOTH, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 5); break; - case 22212: //Andrion Darkspinner + case N_TRAINER_SHADOWEAVE: //Andrion Darkspinner if (!HasTailorSpell(player)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SHADOWEAVE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 3); if (player->HasSpell(S_SHADOWEAVE)) @@ -1055,17 +1103,17 @@ public: { switch (creature->GetEntry()) { - case 22213: + case N_TRAINER_SPELLFIRE: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SPELLFIRE, GOSSIP_SENDER_CHECK, action); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 22208: + case N_TRAINER_MOONCLOTH: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_MOONCLOTH, GOSSIP_SENDER_CHECK, action); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 22212: + case N_TRAINER_SHADOWEAVE: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SHADOWEAVE, GOSSIP_SENDER_CHECK, action); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); @@ -1080,17 +1128,17 @@ public: { switch (creature->GetEntry()) { - case 22213: //Gidge Spellweaver + case N_TRAINER_SPELLFIRE: //Gidge Spellweaver player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SPELLFIRE, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_TAILOR_SPEC, DoHighUnlearnCost(player), false); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 22208: //Nasmara Moonsong + case N_TRAINER_MOONCLOTH: //Nasmara Moonsong player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_MOONCLOTH, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_TAILOR_SPEC, DoHighUnlearnCost(player), false); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); break; - case 22212: //Andrion Darkspinner + case N_TRAINER_SHADOWEAVE: //Andrion Darkspinner player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SHADOWEAVE, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_TAILOR_SPEC, DoHighUnlearnCost(player), false); //unknown textID () player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());