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
This commit is contained in:
Ercules76
2019-03-21 19:38:40 +01:00
committed by Viste(Кирилл)
parent c4835d8099
commit c53437bc75
7 changed files with 361 additions and 62 deletions

View File

@@ -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;

View File

@@ -8,6 +8,7 @@
#include "DatabaseEnv.h"
#include "Log.h"
#include "Player.h"
#include "ObjectMgr.h"
#include <map>
// 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<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)
{
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

View File

@@ -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

View File

@@ -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

View File

@@ -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();

View File

@@ -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*/)

View File

@@ -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());