Merge pull request #15495 from Treeston/3.3.5-gemperfection

Core/Spell: Implement "Gem Perfection" (and framework for similar spells in the future)
This commit is contained in:
Shauren
2015-10-11 11:40:05 +02:00
7 changed files with 340 additions and 54 deletions

View File

@@ -0,0 +1,96 @@
DROP TABLE IF EXISTS `skill_perfect_item_template`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
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';
/*!40101 SET character_set_client = @saved_cs_client */;
LOCK TABLES `skill_perfect_item_template` WRITE;
/*!40000 ALTER TABLE `skill_perfect_item_template` DISABLE KEYS */;
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
/*!40000 ALTER TABLE `skill_perfect_item_template` ENABLE KEYS */;
UNLOCK TABLES;

View File

@@ -20,11 +20,98 @@
#include "DatabaseEnv.h"
#include "Log.h"
#include "Player.h"
#include "ObjectMgr.h"
#include <map>
// some type definitions
// no use putting them in the header file, they're only used in this .cpp
// struct to store information about perfection procs
// one entry per spell
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<uint32, SkillPerfectItemEntry> 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)
{
TC_LOG_ERROR("server.loading", ">> Loaded 0 spell perfection definitions. DB table `skill_perfect_item_template` is empty.");
return;
}
uint32 count = 0;
do /* fetch data and run sanity checks */
{
Field* fields = result->Fetch();
uint32 spellId = fields[0].GetUInt32();
if (!sSpellMgr->GetSpellInfo(spellId))
{
TC_LOG_ERROR("sql.sql", "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))
{
TC_LOG_ERROR("sql.sql", "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)
{
TC_LOG_ERROR("sql.sql", "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))
{
TC_LOG_ERROR("sql.sql", "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());
TC_LOG_INFO("server.loading", ">> Loaded %u spell perfection definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
// struct to store information about extra item creation
// one entry for every spell that is able to create an extra item
struct SkillExtraItemEntry
@@ -112,6 +199,30 @@ void LoadSkillExtraItemTable()
TC_LOG_INFO("server.loading", ">> Loaded %u spell specialization definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
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, uint8 &additionalMax)
{
// get the info for the specified spell

View File

@@ -23,6 +23,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, uint8 &additionalMax);
// function to load the extra item creation info from DB

View File

@@ -1571,6 +1571,22 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
if (num_to_add > pProto->GetMaxStackSize())
num_to_add = pProto->GetMaxStackSize();
/* == gem perfection handling == */
// the chance of getting a perfect result
float perfectCreateChance = 0.0f;
// the resulting perfect item if successful
uint32 perfectItemType = itemtype;
// 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
int items_count=1;
// the chance to create additional items
@@ -1579,15 +1595,16 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
uint8 additionalMaxNum=0;
// get the chance and maximum number for creating extra items
if (CanCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
{
// roll with this chance till we roll not to create or we create the max num
while (roll_chance_f(additionalCreateChance) && items_count <= additionalMaxNum)
++items_count;
}
// really will be created more items
num_to_add *= items_count;
/* == profession specialization handling over == */
// can the player store the new item?
ItemPosCountVec dest;
uint32 no_space = 0;

View File

@@ -1644,6 +1644,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Skill Extra Item Table...");
LoadSkillExtraItemTable();
TC_LOG_INFO("server.loading", "Loading Skill Perfection Data Table...");
LoadSkillPerfectItemTable();
TC_LOG_INFO("server.loading", "Loading Skill Fishing base level requirements...");
sObjectMgr->LoadFishingBaseSkillLevel();

View File

@@ -749,12 +749,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)
TC_LOG_INFO("misc", "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)
{
TC_LOG_INFO("misc", "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*/)

View File

@@ -178,6 +178,52 @@ 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
###*/
@@ -395,23 +441,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))
@@ -464,17 +510,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());
@@ -489,17 +535,17 @@ public:
{
switch (creature->GetEntry())
{
case 22427: //Zarevhi
case N_TRAINER_TRANSMUTE:
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:
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:
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());
@@ -564,20 +610,20 @@ public:
{
switch (creatureId)
{
case 11145: //Myolor Sunderfury
case 11176: //Krathok Moltenfist
case N_TRAINER_SMITHOMNI1:
case N_TRAINER_SMITHOMNI2:
if (!player->HasSpell(S_ARMOR) && !player->HasSpell(S_WEAPON) && player->GetReputationRank(REP_ARMOR) >= REP_FRIENDLY)
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->GetReputationRank(REP_WEAPON) >= REP_FRIENDLY)
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:
case N_TRAINER_WEAPON2:
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:
case N_TRAINER_ARMOR2:
if (player->HasSpell(S_ARMOR))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARMOR_UNLEARN, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4);
break;
@@ -588,19 +634,19 @@ public:
{
switch (creatureId)
{
case 11191: //Lilith the Lithe
case N_TRAINER_HAMMER:
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:
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:
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))
@@ -685,17 +731,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());
@@ -710,26 +756,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:
case N_TRAINER_WEAPON2:
case N_TRAINER_ARMOR1:
case N_TRAINER_ARMOR2:
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());
@@ -901,18 +947,18 @@ public:
{
switch (creature->GetEntry())
{
case 7866: //Peter Galen
case 7867: //Thorkaf Dragoneye
case N_TRAINER_DRAGON1:
case N_TRAINER_DRAGON2:
if (player->HasSpell(S_DRAGON))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_DRAGON, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 1);
break;
case 7868: //Sarah Tanner
case 7869: //Brumn Winterhoof
case N_TRAINER_ELEMENTAL1:
case N_TRAINER_ELEMENTAL2:
if (player->HasSpell(S_ELEMENTAL))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_ELEMENTAL, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 2);
break;
case 7870: //Caryssia Moonhunter
case 7871: //Se'Jib
case N_TRAINER_TRIBAL1:
case N_TRAINER_TRIBAL2:
if (player->HasSpell(S_TRIBAL))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_TRIBAL, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 3);
break;
@@ -952,20 +998,20 @@ public:
{
switch (creature->GetEntry())
{
case 7866: //Peter Galen
case 7867: //Thorkaf Dragoneye
case N_TRAINER_DRAGON1:
case N_TRAINER_DRAGON2:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_DRAGON, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_LEATHER_SPEC, DoMedUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
case 7868: //Sarah Tanner
case 7869: //Brumn Winterhoof
case N_TRAINER_ELEMENTAL1:
case N_TRAINER_ELEMENTAL2:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_ELEMENTAL, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_LEATHER_SPEC, DoMedUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
case 7870: //Caryssia Moonhunter
case 7871: //Se'Jib
case N_TRAINER_TRIBAL1:
case N_TRAINER_TRIBAL2:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_TRIBAL, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_LEATHER_SPEC, DoMedUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
@@ -1027,19 +1073,19 @@ public:
{
switch (creature->GetEntry())
{
case 22213: //Gidge Spellweaver
case N_TRAINER_SPELLFIRE:
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:
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:
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))
@@ -1092,17 +1138,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());
@@ -1117,17 +1163,17 @@ public:
{
switch (creature->GetEntry())
{
case 22213: //Gidge Spellweaver
case N_TRAINER_SPELLFIRE:
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:
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:
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());