Skip to content

Instantly share code, notes, and snippets.

@mindsear
Created February 12, 2019 23:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mindsear/32efc742bd341856deb6ad463c3b99c6 to your computer and use it in GitHub Desktop.
Save mindsear/32efc742bd341856deb6ad463c3b99c6 to your computer and use it in GitHub Desktop.
Modified TemplateNPC.cpp file to work without the .patch thingy || Also, added option to disable gear template as suggested by BarbzYHOOL (https://github.com/azerothcore/mod-npc-talent-template/issues/3)
#include "TemplateNPC.h"
#include "Item.h"
#include "DBCStores.h"
#include "Log.h"
#include "DatabaseEnv.h"
#include "Player.h"
#include "WorldSession.h"
#include "ScriptedGossip.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "GossipDef.h"
#include "Creature.h"
#include "ObjectMgr.h"
void sTemplateNPC::LearnPlateMailSpells(Player* player)
{
switch (player->getClass())
{
case CLASS_WARRIOR:
case CLASS_PALADIN:
case CLASS_DEATH_KNIGHT:
player->learnSpell(PLATE_MAIL);
break;
case CLASS_SHAMAN:
case CLASS_HUNTER:
player->learnSpell(MAIL);
break;
default:
break;
}
}
void sTemplateNPC::ApplyBonus(Player* player, Item* item, EnchantmentSlot slot, uint32 bonusEntry)
{
if (!item)
return;
if (!bonusEntry || bonusEntry == 0)
return;
player->ApplyEnchantment(item, slot, false);
item->SetEnchantment(slot, bonusEntry, 0, 0);
player->ApplyEnchantment(item, slot, true);
}
void sTemplateNPC::ApplyGlyph(Player* player, uint8 slot, uint32 glyphID)
{
if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphID))
{
if (uint32 oldGlyph = player->GetGlyph(slot))
{
player->RemoveAurasDueToSpell(sGlyphPropertiesStore.LookupEntry(oldGlyph)->SpellId);
player->SetGlyph(slot, 0, true);
}
player->CastSpell(player, gp->SpellId, true);
player->SetGlyph(slot, glyphID, true);
}
}
void sTemplateNPC::RemoveAllGlyphs(Player* player)
{
for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i)
{
if (uint32 glyph = player->GetGlyph(i))
{
if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyph))
{
if (GlyphSlotEntry const* gs = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(i)))
{
player->RemoveAurasDueToSpell(sGlyphPropertiesStore.LookupEntry(glyph)->SpellId);
player->SetGlyph(i, 0, true);
player->SendTalentsInfoData(false); // this is somewhat an in-game glyph realtime update (apply/remove)
}
}
}
}
}
void sTemplateNPC::LearnTemplateTalents(Player* player)
{
for (TalentContainer::const_iterator itr = m_TalentContainer.begin(); itr != m_TalentContainer.end(); ++itr)
{
if ((*itr)->playerClass == GetClassString(player).c_str() && (*itr)->playerSpec == sTalentsSpec)
{
player->learnSpell((*itr)->talentId);
player->addTalent((*itr)->talentId, player->GetActiveSpecMask(), true);
}
}
player->SetFreeTalentPoints(0);
player->SendTalentsInfoData(false);
}
void sTemplateNPC::LearnTemplateGlyphs(Player* player)
{
for (GlyphContainer::const_iterator itr = m_GlyphContainer.begin(); itr != m_GlyphContainer.end(); ++itr)
{
if ((*itr)->playerClass == GetClassString(player).c_str() && (*itr)->playerSpec == sTalentsSpec)
ApplyGlyph(player, (*itr)->slot, (*itr)->glyph);
}
player->SendTalentsInfoData(false);
}
void sTemplateNPC::EquipTemplateGear(Player* player)
{
if (player->getRace() == RACE_HUMAN)
{
for (HumanGearContainer::const_iterator itr = m_HumanGearContainer.begin(); itr != m_HumanGearContainer.end(); ++itr)
{
if ((*itr)->playerClass == GetClassString(player).c_str() && (*itr)->playerSpec == sTalentsSpec)
{
player->EquipNewItem((*itr)->pos, (*itr)->itemEntry, true); // Equip the item and apply enchants and gems
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), PERM_ENCHANTMENT_SLOT, (*itr)->enchant);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), SOCK_ENCHANTMENT_SLOT, (*itr)->socket1);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), SOCK_ENCHANTMENT_SLOT_2, (*itr)->socket2);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), SOCK_ENCHANTMENT_SLOT_3, (*itr)->socket3);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), BONUS_ENCHANTMENT_SLOT, (*itr)->bonusEnchant);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), PRISMATIC_ENCHANTMENT_SLOT, (*itr)->prismaticEnchant);
}
}
}
else if (player->GetTeamId() == TEAM_ALLIANCE && player->getRace() != RACE_HUMAN)
{
for (AllianceGearContainer::const_iterator itr = m_AllianceGearContainer.begin(); itr != m_AllianceGearContainer.end(); ++itr)
{
if ((*itr)->playerClass == GetClassString(player).c_str() && (*itr)->playerSpec == sTalentsSpec)
{
player->EquipNewItem((*itr)->pos, (*itr)->itemEntry, true); // Equip the item and apply enchants and gems
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), PERM_ENCHANTMENT_SLOT, (*itr)->enchant);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), SOCK_ENCHANTMENT_SLOT, (*itr)->socket1);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), SOCK_ENCHANTMENT_SLOT_2, (*itr)->socket2);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), SOCK_ENCHANTMENT_SLOT_3, (*itr)->socket3);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), BONUS_ENCHANTMENT_SLOT, (*itr)->bonusEnchant);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), PRISMATIC_ENCHANTMENT_SLOT, (*itr)->prismaticEnchant);
}
}
}
else if (player->GetTeamId() == TEAM_HORDE)
{
for (HordeGearContainer::const_iterator itr = m_HordeGearContainer.begin(); itr != m_HordeGearContainer.end(); ++itr)
{
if ((*itr)->playerClass == GetClassString(player).c_str() && (*itr)->playerSpec == sTalentsSpec)
{
player->EquipNewItem((*itr)->pos, (*itr)->itemEntry, true); // Equip the item and apply enchants and gems
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), PERM_ENCHANTMENT_SLOT, (*itr)->enchant);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), SOCK_ENCHANTMENT_SLOT, (*itr)->socket1);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), SOCK_ENCHANTMENT_SLOT_2, (*itr)->socket2);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), SOCK_ENCHANTMENT_SLOT_3, (*itr)->socket3);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), BONUS_ENCHANTMENT_SLOT, (*itr)->bonusEnchant);
ApplyBonus(player, player->GetItemByPos(INVENTORY_SLOT_BAG_0, (*itr)->pos), PRISMATIC_ENCHANTMENT_SLOT, (*itr)->prismaticEnchant);
}
}
}
}
void sTemplateNPC::LoadTalentsContainer()
{
for (TalentContainer::const_iterator itr = m_TalentContainer.begin(); itr != m_TalentContainer.end(); ++itr)
delete *itr;
m_TalentContainer.clear();
uint32 oldMSTime = getMSTime();
uint32 count = 0;
QueryResult result = CharacterDatabase.Query("SELECT playerClass, playerSpec, talentId FROM template_npc_talents;");
if (!result)
{
sLog->outString(">>TEMPLATE NPC: Loaded 0 talent templates. DB table `template_npc_talents` is empty!");
return;
}
do
{
Field* fields = result->Fetch();
TalentTemplate* pTalent = new TalentTemplate;
pTalent->playerClass = fields[0].GetString();
pTalent->playerSpec = fields[1].GetString();
pTalent->talentId = fields[2].GetUInt32();
m_TalentContainer.push_back(pTalent);
++count;
} while (result->NextRow());
sLog->outString(">>TEMPLATE NPC: Loaded %u talent templates in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void sTemplateNPC::LoadGlyphsContainer()
{
for (GlyphContainer::const_iterator itr = m_GlyphContainer.begin(); itr != m_GlyphContainer.end(); ++itr)
delete *itr;
m_GlyphContainer.clear();
QueryResult result = CharacterDatabase.Query("SELECT playerClass, playerSpec, slot, glyph FROM template_npc_glyphs;");
uint32 oldMSTime = getMSTime();
uint32 count = 0;
if (!result)
{
sLog->outString(">>TEMPLATE NPC: Loaded 0 glyph templates. DB table `template_npc_glyphs` is empty!");
return;
}
do
{
Field* fields = result->Fetch();
GlyphTemplate* pGlyph = new GlyphTemplate;
pGlyph->playerClass = fields[0].GetString();
pGlyph->playerSpec = fields[1].GetString();
pGlyph->slot = fields[2].GetUInt8();
pGlyph->glyph = fields[3].GetUInt32();
m_GlyphContainer.push_back(pGlyph);
++count;
} while (result->NextRow());
sLog->outString(">>TEMPLATE NPC: Loaded %u glyph templates in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void sTemplateNPC::LoadHumanGearContainer()
{
for (HumanGearContainer::const_iterator itr = m_HumanGearContainer.begin(); itr != m_HumanGearContainer.end(); ++itr)
delete *itr;
m_HumanGearContainer.clear();
QueryResult result = CharacterDatabase.Query("SELECT playerClass, playerSpec, pos, itemEntry, enchant, socket1, socket2, socket3, bonusEnchant, prismaticEnchant FROM template_npc_human;");
uint32 oldMSTime = getMSTime();
uint32 count = 0;
if (!result)
{
sLog->outString(">>TEMPLATE NPC: Loaded 0 'gear templates. DB table `template_npc_human` is empty!");
return;
}
do
{
Field* fields = result->Fetch();
HumanGearTemplate* pItem = new HumanGearTemplate;
pItem->playerClass = fields[0].GetString();
pItem->playerSpec = fields[1].GetString();
pItem->pos = fields[2].GetUInt8();
pItem->itemEntry = fields[3].GetUInt32();
pItem->enchant = fields[4].GetUInt32();
pItem->socket1 = fields[5].GetUInt32();
pItem->socket2 = fields[6].GetUInt32();
pItem->socket3 = fields[7].GetUInt32();
pItem->bonusEnchant = fields[8].GetUInt32();
pItem->prismaticEnchant = fields[9].GetUInt32();
m_HumanGearContainer.push_back(pItem);
++count;
} while (result->NextRow());
sLog->outString(">>TEMPLATE NPC: Loaded %u gear templates for Humans in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void sTemplateNPC::LoadAllianceGearContainer()
{
for (AllianceGearContainer::const_iterator itr = m_AllianceGearContainer.begin(); itr != m_AllianceGearContainer.end(); ++itr)
delete *itr;
m_AllianceGearContainer.clear();
QueryResult result = CharacterDatabase.Query("SELECT playerClass, playerSpec, pos, itemEntry, enchant, socket1, socket2, socket3, bonusEnchant, prismaticEnchant FROM template_npc_alliance;");
uint32 oldMSTime = getMSTime();
uint32 count = 0;
if (!result)
{
sLog->outString(">>TEMPLATE NPC: Loaded 0 'gear templates. DB table `template_npc_alliance` is empty!");
return;
}
do
{
Field* fields = result->Fetch();
AllianceGearTemplate* pItem = new AllianceGearTemplate;
pItem->playerClass = fields[0].GetString();
pItem->playerSpec = fields[1].GetString();
pItem->pos = fields[2].GetUInt8();
pItem->itemEntry = fields[3].GetUInt32();
pItem->enchant = fields[4].GetUInt32();
pItem->socket1 = fields[5].GetUInt32();
pItem->socket2 = fields[6].GetUInt32();
pItem->socket3 = fields[7].GetUInt32();
pItem->bonusEnchant = fields[8].GetUInt32();
pItem->prismaticEnchant = fields[9].GetUInt32();
m_AllianceGearContainer.push_back(pItem);
++count;
} while (result->NextRow());
sLog->outString(">>TEMPLATE NPC: Loaded %u gear templates for Alliances in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void sTemplateNPC::LoadHordeGearContainer()
{
for (HordeGearContainer::const_iterator itr = m_HordeGearContainer.begin(); itr != m_HordeGearContainer.end(); ++itr)
delete *itr;
m_HordeGearContainer.clear();
QueryResult result = CharacterDatabase.Query("SELECT playerClass, playerSpec, pos, itemEntry, enchant, socket1, socket2, socket3, bonusEnchant, prismaticEnchant FROM template_npc_horde;");
uint32 oldMSTime = getMSTime();
uint32 count = 0;
if (!result)
{
sLog->outString(">>TEMPLATE NPC: Loaded 0 'gear templates. DB table `template_npc_horde` is empty!");
return;
}
do
{
Field* fields = result->Fetch();
HordeGearTemplate* pItem = new HordeGearTemplate;
pItem->playerClass = fields[0].GetString();
pItem->playerSpec = fields[1].GetString();
pItem->pos = fields[2].GetUInt8();
pItem->itemEntry = fields[3].GetUInt32();
pItem->enchant = fields[4].GetUInt32();
pItem->socket1 = fields[5].GetUInt32();
pItem->socket2 = fields[6].GetUInt32();
pItem->socket3 = fields[7].GetUInt32();
pItem->bonusEnchant = fields[8].GetUInt32();
pItem->prismaticEnchant = fields[9].GetUInt32();
m_HordeGearContainer.push_back(pItem);
++count;
} while (result->NextRow());
sLog->outString(">>TEMPLATE NPC: Loaded %u gear templates for Hordes in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
std::string sTemplateNPC::GetClassString(Player* player)
{
switch (player->getClass())
{
case CLASS_PRIEST: return "Priest"; break;
case CLASS_PALADIN: return "Paladin"; break;
case CLASS_WARRIOR: return "Warrior"; break;
case CLASS_MAGE: return "Mage"; break;
case CLASS_WARLOCK: return "Warlock"; break;
case CLASS_SHAMAN: return "Shaman"; break;
case CLASS_DRUID: return "Druid"; break;
case CLASS_HUNTER: return "Hunter"; break;
case CLASS_ROGUE: return "Rogue"; break;
case CLASS_DEATH_KNIGHT: return "DeathKnight"; break;
default:
break;
}
return "Unknown"; // Fix warning, this should never happen
}
bool sTemplateNPC::OverwriteTemplate(Player* player, std::string& playerSpecStr)
{
// Delete old talent and glyph templates before extracting new ones
CharacterDatabase.PExecute("DELETE FROM template_npc_talents WHERE playerClass = '%s' AND playerSpec = '%s';", GetClassString(player).c_str(), playerSpecStr.c_str());
CharacterDatabase.PExecute("DELETE FROM template_npc_glyphs WHERE playerClass = '%s' AND playerSpec = '%s';", GetClassString(player).c_str(), playerSpecStr.c_str());
// Delete old gear templates before extracting new ones
if (player->getRace() == RACE_HUMAN)
{
CharacterDatabase.PExecute("DELETE FROM template_npc_human WHERE playerClass = '%s' AND playerSpec = '%s';", GetClassString(player).c_str(), playerSpecStr.c_str());
player->GetSession()->SendAreaTriggerMessage("Template successfuly created!");
return false;
}
else if (player->GetTeamId() == TEAM_ALLIANCE && player->getRace() != RACE_HUMAN)
{
CharacterDatabase.PExecute("DELETE FROM template_npc_alliance WHERE playerClass = '%s' AND playerSpec = '%s';", GetClassString(player).c_str(), playerSpecStr.c_str());
player->GetSession()->SendAreaTriggerMessage("Template successfuly created!");
return false;
}
else if (player->GetTeamId() == TEAM_HORDE)
{ // ????????????? sTemplateNpcMgr here??
CharacterDatabase.PExecute("DELETE FROM template_npc_horde WHERE playerClass = '%s' AND playerSpec = '%s';", GetClassString(player).c_str(), playerSpecStr.c_str());
player->GetSession()->SendAreaTriggerMessage("Template successfuly created!");
return false;
}
return true;
}
void sTemplateNPC::ExtractGearTemplateToDB(Player* player, std::string& playerSpecStr)
{
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
Item* equippedItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (equippedItem)
{
if (player->getRace() == RACE_HUMAN)
{
CharacterDatabase.PExecute("INSERT INTO template_npc_human (`playerClass`, `playerSpec`, `pos`, `itemEntry`, `enchant`, `socket1`, `socket2`, `socket3`, `bonusEnchant`, `prismaticEnchant`) VALUES ('%s', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u');"
, GetClassString(player).c_str(), playerSpecStr.c_str(), equippedItem->GetSlot(), equippedItem->GetEntry(), equippedItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT),
equippedItem->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT), equippedItem->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_2), equippedItem->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_3),
equippedItem->GetEnchantmentId(BONUS_ENCHANTMENT_SLOT), equippedItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT));
}
else if (player->GetTeamId() == TEAM_ALLIANCE && player->getRace() != RACE_HUMAN)
{
CharacterDatabase.PExecute("INSERT INTO template_npc_alliance (`playerClass`, `playerSpec`, `pos`, `itemEntry`, `enchant`, `socket1`, `socket2`, `socket3`, `bonusEnchant`, `prismaticEnchant`) VALUES ('%s', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u');"
, GetClassString(player).c_str(), playerSpecStr.c_str(), equippedItem->GetSlot(), equippedItem->GetEntry(), equippedItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT),
equippedItem->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT), equippedItem->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_2), equippedItem->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_3),
equippedItem->GetEnchantmentId(BONUS_ENCHANTMENT_SLOT), equippedItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT));
}
else if (player->GetTeamId() == TEAM_HORDE)
{
CharacterDatabase.PExecute("INSERT INTO template_npc_horde (`playerClass`, `playerSpec`, `pos`, `itemEntry`, `enchant`, `socket1`, `socket2`, `socket3`, `bonusEnchant`, `prismaticEnchant`) VALUES ('%s', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u');"
, GetClassString(player).c_str(), playerSpecStr.c_str(), equippedItem->GetSlot(), equippedItem->GetEntry(), equippedItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT),
equippedItem->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT), equippedItem->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_2), equippedItem->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_3),
equippedItem->GetEnchantmentId(BONUS_ENCHANTMENT_SLOT), equippedItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT));
}
}
}
}
void sTemplateNPC::ExtractTalentTemplateToDB(Player* player, std::string& playerSpecStr)
{
QueryResult result = CharacterDatabase.PQuery("SELECT spell FROM character_talent WHERE guid = '%u' "
"AND talentGroup = '%u';", player->GetGUID(), player->GetActiveSpec());
if (!result)
{
return;
}
else if (player->GetFreeTalentPoints() > 0)
{
player->GetSession()->SendAreaTriggerMessage("You have unspend talent points. Please spend all your talent points and re-extract the template.");
return;
}
else
{
do
{
Field* fields = result->Fetch();
uint32 spell = fields[0].GetUInt32();
CharacterDatabase.PExecute("INSERT INTO template_npc_talents (playerClass, playerSpec, talentId) "
"VALUES ('%s', '%s', '%u');", GetClassString(player).c_str(), playerSpecStr.c_str(), spell);
} while (result->NextRow());
}
}
void sTemplateNPC::ExtractGlyphsTemplateToDB(Player* player, std::string& playerSpecStr)
{
QueryResult result = CharacterDatabase.PQuery("SELECT glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 "
"FROM character_glyphs WHERE guid = '%u' AND talentGroup = '%u';", player->GetGUID(), player->GetActiveSpec());
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
{
if (!result)
{
player->GetSession()->SendAreaTriggerMessage("Get glyphs and re-extract the template!");
continue;
}
Field* fields = result->Fetch();
uint32 glyph1 = fields[0].GetUInt32();
uint32 glyph2 = fields[1].GetUInt32();
uint32 glyph3 = fields[2].GetUInt32();
uint32 glyph4 = fields[3].GetUInt32();
uint32 glyph5 = fields[4].GetUInt32();
uint32 glyph6 = fields[5].GetUInt32();
uint32 storedGlyph;
switch (slot)
{
case 0:
storedGlyph = glyph1;
break;
case 1:
storedGlyph = glyph2;
break;
case 2:
storedGlyph = glyph3;
break;
case 3:
storedGlyph = glyph4;
break;
case 4:
storedGlyph = glyph5;
break;
case 5:
storedGlyph = glyph6;
break;
default:
break;
}
CharacterDatabase.PExecute("INSERT INTO template_npc_glyphs (playerClass, playerSpec, slot, glyph) "
"VALUES ('%s', '%s', '%u', '%u');", GetClassString(player).c_str(), playerSpecStr.c_str(), slot, storedGlyph);
}
}
bool sTemplateNPC::CanEquipTemplate(Player* player, std::string& playerSpecStr)
{
if (player->getRace() == RACE_HUMAN)
{
QueryResult result = CharacterDatabase.PQuery("SELECT playerClass, playerSpec FROM template_npc_human "
"WHERE playerClass = '%s' AND playerSpec = '%s';", GetClassString(player).c_str(), playerSpecStr.c_str());
if (!result)
return false;
}
else if (player->GetTeamId() == TEAM_ALLIANCE && player->getRace() != RACE_HUMAN)
{
QueryResult result = CharacterDatabase.PQuery("SELECT playerClass, playerSpec FROM template_npc_alliance "
"WHERE playerClass = '%s' AND playerSpec = '%s';", GetClassString(player).c_str(), playerSpecStr.c_str());
if (!result)
return false;
}
else if (player->GetTeamId() == TEAM_HORDE)
{
QueryResult result = CharacterDatabase.PQuery("SELECT playerClass, playerSpec FROM template_npc_horde "
"WHERE playerClass = '%s' AND playerSpec = '%s';", GetClassString(player).c_str(), playerSpecStr.c_str());
if (!result)
return false;
}
return true;
}
class TemplateNPC : public CreatureScript
{
public:
TemplateNPC() : CreatureScript("TemplateNPC") { }
bool OnGossipHello(Player* player, Creature* creature) override
{
switch (player->getClass())
{
case CLASS_PRIEST:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_wordfortitude:30|t|r Use Discipline Spec", GOSSIP_SENDER_MAIN, 0);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_holybolt:30|t|r Use Holy Spec", GOSSIP_SENDER_MAIN, 1);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_shadow_shadowwordpain:30|t|r Use Shadow Spec", GOSSIP_SENDER_MAIN, 2);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_wordfortitude:30|t|r Use Discipline Spec (Talents Only)", GOSSIP_SENDER_MAIN, 100);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_holybolt:30|t|r Use Holy spec (Talents only)", GOSSIP_SENDER_MAIN, 101);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_shadow_shadowwordpain:30|t|r Use Shadow spec (Talents only)", GOSSIP_SENDER_MAIN, 102);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
case CLASS_PALADIN:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_holybolt:30|t|r Use Holy Spec", GOSSIP_SENDER_MAIN, 3);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_devotionaura:30|t|r Use Protection Spec", GOSSIP_SENDER_MAIN, 4);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_auraoflight:30|t|r Use Retribution Spec", GOSSIP_SENDER_MAIN, 5);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_holybolt:30|t|r Use Holy Spec (Talents Only)", GOSSIP_SENDER_MAIN, 103);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_devotionaura:30|t|r Use Protection Spec (Talents Only)", GOSSIP_SENDER_MAIN, 104);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_auraoflight:30|t|r Use Retribution Spec (Talents Only)", GOSSIP_SENDER_MAIN, 105);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
case CLASS_WARRIOR:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_warrior_innerrage:30|t|r Use Fury Spec", GOSSIP_SENDER_MAIN, 6);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_rogue_eviscerate:30|t|r Use Arms Spec", GOSSIP_SENDER_MAIN, 7);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_warrior_defensivestance:30|t|r Use Protection Spec", GOSSIP_SENDER_MAIN, 8);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_warrior_innerrage:30|t|r Use Fury Spec (Talents Only)", GOSSIP_SENDER_MAIN, 106);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_rogue_eviscerate:30|t|r Use Arms Spec (Talents Only)", GOSSIP_SENDER_MAIN, 107);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_warrior_defensivestance:30|t|r Use Protection Spec (Talents Only)", GOSSIP_SENDER_MAIN, 108);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
case CLASS_MAGE:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_magicalsentry:30|t|r Use Arcane Spec", GOSSIP_SENDER_MAIN, 9);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_fire_flamebolt:30|t|r Use Fire Spec", GOSSIP_SENDER_MAIN, 10);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_frost_frostbolt02:30|t|r Use Frost Spec", GOSSIP_SENDER_MAIN, 11);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_holy_magicalsentry:30|t|r Use Arcane Spec (Talents Only)", GOSSIP_SENDER_MAIN, 109);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_fire_flamebolt:30|t|r Use Fire Spec (Talents Only)", GOSSIP_SENDER_MAIN, 110);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_frost_frostbolt02:30|t|r Use Frost Spec (Talents Only)", GOSSIP_SENDER_MAIN, 111);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
case CLASS_WARLOCK:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_shadow_deathcoil:30|t|r Use Affliction Spec", GOSSIP_SENDER_MAIN, 12);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_shadow_metamorphosis:30|t|r Use Demonology Spec", GOSSIP_SENDER_MAIN, 13);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_shadow_rainoffire:30|t|r Use Destruction Spec", GOSSIP_SENDER_MAIN, 14);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_shadow_deathcoil:30|t|r Use Affliction Spec (Talents Only)", GOSSIP_SENDER_MAIN, 112);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_shadow_metamorphosis:30|t|r Use Demonology Spec (Talents Only)", GOSSIP_SENDER_MAIN, 113);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_shadow_rainoffire:30|t|r Use Destruction Spec (Talents Only)", GOSSIP_SENDER_MAIN, 114);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
case CLASS_SHAMAN:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_lightning:30|t|r Use Elemental Spec", GOSSIP_SENDER_MAIN, 15);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_lightningshield:30|t|r Use Enhancement Spec", GOSSIP_SENDER_MAIN, 16);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_magicimmunity:30|t|r Use Restoration Spec", GOSSIP_SENDER_MAIN, 17);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_lightning:30|t|r Use Elemental Spec (Talents Only)", GOSSIP_SENDER_MAIN, 115);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_lightningshield:30|t|r Use Enhancement Spec (Talents Only)", GOSSIP_SENDER_MAIN, 116);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_magicimmunity:30|t|r Use Restoration Spec (Talents Only)", GOSSIP_SENDER_MAIN, 117);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
case CLASS_DRUID:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_starfall:30|t|r Use Ballance Spec", GOSSIP_SENDER_MAIN, 18);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_racial_bearform:30|t|r Use Feral Spec", GOSSIP_SENDER_MAIN, 19);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_healingtouch:30|t|r Use Restoration Spec", GOSSIP_SENDER_MAIN, 20);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_starfall:30|t|r Use Ballance Spec (Talents Only)", GOSSIP_SENDER_MAIN, 118);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_racial_bearform:30|t|r Use Feral Spec (Talents Only)", GOSSIP_SENDER_MAIN, 119);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_nature_healingtouch:30|t|r Use Restoration Spec (Talents Only)", GOSSIP_SENDER_MAIN, 120);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
case CLASS_HUNTER:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_marksmanship:30|t|r Use Marksmanship Spec", GOSSIP_SENDER_MAIN, 21);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_hunter_beasttaming:30|t|r Use Beastmastery Spec", GOSSIP_SENDER_MAIN, 22);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_Hunter_swiftstrike:30|t|r Use Survival Spec", GOSSIP_SENDER_MAIN, 23);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_marksmanship:30|t|r Use Marksmanship Spec (Talents Only)", GOSSIP_SENDER_MAIN, 121);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_hunter_beasttaming:30|t|r Use Beastmastery Spec (Talents Only)", GOSSIP_SENDER_MAIN, 122);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_Hunter_swiftstrike:30|t|r Use Survival Spec (Talents Only)", GOSSIP_SENDER_MAIN, 123);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
case CLASS_ROGUE:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_rogue_eviscerate:30|t|r Use Assasination Spec", GOSSIP_SENDER_MAIN, 24);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_backstab:30|t|r Use Combat Spec", GOSSIP_SENDER_MAIN, 25);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_stealth:30|t|r Use Subtlety Spec", GOSSIP_SENDER_MAIN, 26);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_rogue_eviscerate:30|t|r Use Assasination Spec (Talents Only)", GOSSIP_SENDER_MAIN, 124);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_backstab:30|t|r Use Combat Spec (Talents Only)", GOSSIP_SENDER_MAIN, 125);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\ability_stealth:30|t|r Use Subtlety Spec (Talents Only)", GOSSIP_SENDER_MAIN, 126);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
case CLASS_DEATH_KNIGHT:
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_deathknight_bloodpresence:30|t|r Use Blood Spec", GOSSIP_SENDER_MAIN, 27);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_deathknight_frostpresence:30|t|r Use Frost Spec", GOSSIP_SENDER_MAIN, 28);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_deathknight_unholypresence:30|t|r Use Unholy Spec", GOSSIP_SENDER_MAIN, 29);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_deathknight_bloodpresence:30|t|r Use Blood Spec (Talents Only)", GOSSIP_SENDER_MAIN, 127);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_deathknight_frostpresence:30|t|r Use Frost Spec (Talents Only)", GOSSIP_SENDER_MAIN, 128);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\spell_deathknight_unholypresence:30|t|r Use Unholy Spec (Talents Only)", GOSSIP_SENDER_MAIN, 129);
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "----------------------------------------------", GOSSIP_SENDER_MAIN, 5000);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Trade_Engineering:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);*/
break;
}
/*AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Spell_ChargeNegative:30|t|r Remove all glyphs", GOSSIP_SENDER_MAIN, 30);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Spell_ChargeNegative:30|t|r Reset Talents", GOSSIP_SENDER_MAIN, 31);
AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "|cff00ff00|TInterface\\icons\\Spell_ChargeNegative:30|t|r Destroy my equipped gear", GOSSIP_SENDER_MAIN, 32);*/
SendGossipMenuFor(player, 55002, creature->GetGUID());
return true;
}
static void EquipFullTemplateGear(Player* player, std::string& playerSpecStr) // Merge
{
if (sTemplateNpcMgr->CanEquipTemplate(player, playerSpecStr) == false)
{
player->GetSession()->SendAreaTriggerMessage("There's no templates for %s specialization yet.", playerSpecStr.c_str());
return;
}
// Don't let players to use Template feature while wearing some gear
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
if (Item* haveItemEquipped = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
if (haveItemEquipped)
{
player->GetSession()->SendAreaTriggerMessage("You need to remove all your equipped items in order to use this feature!");
CloseGossipMenuFor(player);
return;
}
}
}
// Don't let players to use Template feature after spending some talent points
if (player->GetFreeTalentPoints() < 71)
{
player->GetSession()->SendAreaTriggerMessage("You have already spent some talent points. You need to reset your talents first!");
CloseGossipMenuFor(player);
return;
}
sTemplateNpcMgr->LearnTemplateTalents(player);
sTemplateNpcMgr->LearnTemplateGlyphs(player);
sTemplateNpcMgr->EquipTemplateGear(player);
sTemplateNpcMgr->LearnPlateMailSpells(player);
LearnWeaponSkills(player);
player->GetSession()->SendAreaTriggerMessage("Successfuly equipped %s %s template!", playerSpecStr.c_str(), sTemplateNpcMgr->GetClassString(player).c_str());
if (player->getPowerType() == POWER_MANA)
player->SetMaxPower(POWER_MANA, 100);
player->SetFullHealth();
// Learn Riding/Flying
if (player->HasSpell(SPELL_Artisan_Riding) ||
player->HasSpell(SPELL_Cold_Weather_Flying) ||
player->HasSpell(SPELL_Amani_War_Bear) ||
player->HasSpell(SPELL_Teach_Learn_Talent_Specialization_Switches)
|| player->HasSpell(SPELL_Learn_a_Second_Talent_Specialization)
)
return;
// Cast spells that teach dual spec
// Both are also ImplicitTarget self and must be cast by player
player->CastSpell(player, SPELL_Teach_Learn_Talent_Specialization_Switches, player->GetGUID());
player->CastSpell(player, SPELL_Learn_a_Second_Talent_Specialization, player->GetGUID());
player->learnSpell(SPELL_Artisan_Riding);
player->learnSpell(SPELL_Cold_Weather_Flying);
player->learnSpell(SPELL_Amani_War_Bear);
}
static void LearnOnlyTalentsAndGlyphs(Player* player, std::string& playerSpecStr) // Merge
{
if (sTemplateNpcMgr->CanEquipTemplate(player, playerSpecStr) == false)
{
player->GetSession()->SendAreaTriggerMessage("There's no templates for %s specialization yet.", playerSpecStr.c_str());
return;
}
// Don't let players to use Template feature after spending some talent points
if (player->GetFreeTalentPoints() < 71)
{
player->GetSession()->SendAreaTriggerMessage("You have already spent some talent points. You need to reset your talents first!");
CloseGossipMenuFor(player);
return;
}
sTemplateNpcMgr->LearnTemplateTalents(player);
sTemplateNpcMgr->LearnTemplateGlyphs(player);
//sTemplateNpcMgr->EquipTemplateGear(player);
sTemplateNpcMgr->LearnPlateMailSpells(player);
LearnWeaponSkills(player);
player->GetSession()->SendAreaTriggerMessage("Successfuly learned talent spec %s!", playerSpecStr.c_str());
// Learn Riding/Flying
if (player->HasSpell(SPELL_Artisan_Riding) ||
player->HasSpell(SPELL_Cold_Weather_Flying) ||
player->HasSpell(SPELL_Amani_War_Bear) ||
player->HasSpell(SPELL_Teach_Learn_Talent_Specialization_Switches)
|| player->HasSpell(SPELL_Learn_a_Second_Talent_Specialization)
)
return;
// Cast spells that teach dual spec
// Both are also ImplicitTarget self and must be cast by player
player->CastSpell(player, SPELL_Teach_Learn_Talent_Specialization_Switches, player->GetGUID());
player->CastSpell(player, SPELL_Learn_a_Second_Talent_Specialization, player->GetGUID());
player->learnSpell(SPELL_Artisan_Riding);
player->learnSpell(SPELL_Cold_Weather_Flying);
player->learnSpell(SPELL_Amani_War_Bear);
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction) override
{
ClearGossipMenuFor(player);
if (!player || !creature)
return false;
switch (uiAction)
{
case 0: // Use Discipline Priest Spec
sTemplateNpcMgr->sTalentsSpec = "Discipline";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 1: // Use Holy Priest Spec
sTemplateNpcMgr->sTalentsSpec = "Holy";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 2: // Use Shadow Priest Spec
sTemplateNpcMgr->sTalentsSpec = "Shadow";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 3: // Use Holy Paladin Spec
sTemplateNpcMgr->sTalentsSpec = "Holy";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 4: // Use Protection Paladin Spec
sTemplateNpcMgr->sTalentsSpec = "Protection";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 5: // Use Retribution Paladin Spec
sTemplateNpcMgr->sTalentsSpec = "Retribution";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 6: // Use Fury Warrior Spec
sTemplateNpcMgr->sTalentsSpec = "Fury";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 7: // Use Arms Warrior Spec
sTemplateNpcMgr->sTalentsSpec = "Arms";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 8: // Use Protection Warrior Spec
sTemplateNpcMgr->sTalentsSpec = "Protection";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 9: // Use Arcane Mage Spec
sTemplateNpcMgr->sTalentsSpec = "Arcane";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 10: // Use Fire Mage Spec
sTemplateNpcMgr->sTalentsSpec = "Fire";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 11: // Use Frost Mage Spec
sTemplateNpcMgr->sTalentsSpec = "Frost";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 12: // Use Affliction Warlock Spec
sTemplateNpcMgr->sTalentsSpec = "Affliction";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 13: // Use Demonology Warlock Spec
sTemplateNpcMgr->sTalentsSpec = "Demonology";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 14: // Use Destruction Warlock Spec
sTemplateNpcMgr->sTalentsSpec = "Destruction";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 15: // Use Elemental Shaman Spec
sTemplateNpcMgr->sTalentsSpec = "Elemental";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 16: // Use Enhancement Shaman Spec
sTemplateNpcMgr->sTalentsSpec = "Enhancement";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 17: // Use Restoration Shaman Spec
sTemplateNpcMgr->sTalentsSpec = "Restoration";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 18: // Use Ballance Druid Spec
sTemplateNpcMgr->sTalentsSpec = "Ballance";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 19: // Use Feral Druid Spec
sTemplateNpcMgr->sTalentsSpec = "Feral";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 20: // Use Restoration Druid Spec
sTemplateNpcMgr->sTalentsSpec = "Restoration";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 21: // Use Marksmanship Hunter Spec
sTemplateNpcMgr->sTalentsSpec = "Marksmanship";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 22: // Use Beastmastery Hunter Spec
sTemplateNpcMgr->sTalentsSpec = "Beastmastery";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 23: // Use Survival Hunter Spec
sTemplateNpcMgr->sTalentsSpec = "Survival";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 24: // Use Assassination Rogue Spec
sTemplateNpcMgr->sTalentsSpec = "Assassination";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 25: // Use Combat Rogue Spec
sTemplateNpcMgr->sTalentsSpec = "Combat";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 26: // Use Subtlety Rogue Spec
sTemplateNpcMgr->sTalentsSpec = "Subtlety";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 27: // Use Blood DK Spec
sTemplateNpcMgr->sTalentsSpec = "Blood";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 28: // Use Frost DK Spec
sTemplateNpcMgr->sTalentsSpec = "Frost";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 29: // Use Unholy DK Spec
sTemplateNpcMgr->sTalentsSpec = "Unholy";
EquipFullTemplateGear(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 30:
sTemplateNpcMgr->RemoveAllGlyphs(player);
player->GetSession()->SendAreaTriggerMessage("Your glyphs have been removed.");
//GossipHello(player);
CloseGossipMenuFor(player);
break;
case 31:
player->resetTalents(true);
player->SendTalentsInfoData(false);
player->GetSession()->SendAreaTriggerMessage("Your talents have been reset.");
CloseGossipMenuFor(player);
break;
case 32:
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
if (Item* haveItemEquipped = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
if (haveItemEquipped)
{
player->DestroyItemCount(haveItemEquipped->GetEntry(), 1, true, true);
if (haveItemEquipped->IsInWorld())
{
haveItemEquipped->RemoveFromWorld();
haveItemEquipped->DestroyForPlayer(player);
}
haveItemEquipped->SetUInt64Value(ITEM_FIELD_CONTAINED, NULL);
haveItemEquipped->SetSlot(NULL_SLOT);
haveItemEquipped->SetState(ITEM_REMOVED, player);
}
}
}
player->GetSession()->SendAreaTriggerMessage("Your equipped gear has been destroyed.");
CloseGossipMenuFor(player);
break;
//Priest
case 100:
sTemplateNpcMgr->sTalentsSpec = "Discipline";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 101:
sTemplateNpcMgr->sTalentsSpec = "Holy";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 102:
sTemplateNpcMgr->sTalentsSpec = "Shadow";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
//Paladin
case 103:
sTemplateNpcMgr->sTalentsSpec = "Holy";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 104:
sTemplateNpcMgr->sTalentsSpec = "Protection";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 105:
sTemplateNpcMgr->sTalentsSpec = "Retribution";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
//Warrior
case 106:
sTemplateNpcMgr->sTalentsSpec = "Fury";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 107:
sTemplateNpcMgr->sTalentsSpec = "Arms";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 108:
sTemplateNpcMgr->sTalentsSpec = "Protection";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
//Mage
case 109:
sTemplateNpcMgr->sTalentsSpec = "Arcane";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 110:
sTemplateNpcMgr->sTalentsSpec = "Fire";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 111:
sTemplateNpcMgr->sTalentsSpec = "Frost";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
//Warlock
case 112:
sTemplateNpcMgr->sTalentsSpec = "Affliction";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 113:
sTemplateNpcMgr->sTalentsSpec = "Demonology";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 114:
sTemplateNpcMgr->sTalentsSpec = "Destruction";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
//Shaman
case 115:
sTemplateNpcMgr->sTalentsSpec = "Elemental";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 116:
sTemplateNpcMgr->sTalentsSpec = "Enhancement";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 117:
sTemplateNpcMgr->sTalentsSpec = "Restoration";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
//Druid
case 118:
sTemplateNpcMgr->sTalentsSpec = "Ballance";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 119:
sTemplateNpcMgr->sTalentsSpec = "Feral";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 120:
sTemplateNpcMgr->sTalentsSpec = "Restoration";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
//Hunter
case 121:
sTemplateNpcMgr->sTalentsSpec = "Marksmanship";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 122:
sTemplateNpcMgr->sTalentsSpec = "Beastmastery";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 123:
sTemplateNpcMgr->sTalentsSpec = "Survival";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
//Rogue
case 124:
sTemplateNpcMgr->sTalentsSpec = "Assasination";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 125:
sTemplateNpcMgr->sTalentsSpec = "Combat";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 126:
sTemplateNpcMgr->sTalentsSpec = "Subtlety";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
//DK
case 127:
sTemplateNpcMgr->sTalentsSpec = "Blood";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 128:
sTemplateNpcMgr->sTalentsSpec = "Frost";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 129:
sTemplateNpcMgr->sTalentsSpec = "Unholy";
LearnOnlyTalentsAndGlyphs(player, sTemplateNpcMgr->sTalentsSpec);
CloseGossipMenuFor(player);
break;
case 5000:
// return to OnGossipHello menu, otherwise it will freeze every menu
OnGossipHello(player, creature);
break;
default: // Just in case
player->GetSession()->SendAreaTriggerMessage("Something went wrong in the code. Please contact the administrator.");
break;
}
player->UpdateSkillsForLevel();
return true;
}
};
class TemplateNPC_command : public CommandScript
{
public:
TemplateNPC_command() : CommandScript("TemplateNPC_command") { }
std::vector<ChatCommand> GetCommands() const override
{
static std::vector<ChatCommand> TemplateNPCTable =
{
{ "reload", SEC_ADMINISTRATOR, true , &HandleReloadTemplateNPCCommand, "" }
};
static std::vector<ChatCommand> commandTable =
{
{ "templatenpc", SEC_ADMINISTRATOR, true, nullptr , "", TemplateNPCTable }
};
return commandTable;
}
static bool HandleReloadTemplateNPCCommand(ChatHandler* handler, const char* /*args*/)
{
sLog->outString("misc", "Reloading templates for Template NPC table...");
sTemplateNpcMgr->LoadTalentsContainer();
sTemplateNpcMgr->LoadGlyphsContainer();
sTemplateNpcMgr->LoadHumanGearContainer();
sTemplateNpcMgr->LoadAllianceGearContainer();
sTemplateNpcMgr->LoadHordeGearContainer();
handler->SendGlobalGMSysMessage("Template NPC templates reloaded.");
return true;
}
};
class TemplateNPC_World : public WorldScript
{
public:
TemplateNPC_World() : WorldScript("TemplateNPC_World") { }
void OnStartup() override
{
// Load templates for Template NPC #1
sLog->outString("== TEMPLATE NPC ===========================================================================");
sLog->outString("Loading Template Talents...");
sTemplateNpcMgr->LoadTalentsContainer();
// Load templates for Template NPC #2
sLog->outString("Loading Template Glyphs...");
sTemplateNpcMgr->LoadGlyphsContainer();
// Load templates for Template NPC #3
sLog->outString("Loading Template Gear for Humans...");
sTemplateNpcMgr->LoadHumanGearContainer();
// Load templates for Template NPC #4
sLog->outString("Loading Template Gear for Alliances...");
sTemplateNpcMgr->LoadAllianceGearContainer();
// Load templates for Template NPC #5
sLog->outString("Loading Template Gear for Hordes...");
sTemplateNpcMgr->LoadHordeGearContainer();
sLog->outString("== END TEMPLATE NPC ===========================================================================");
}
};
void AddSC_TemplateNPC()
{
new TemplateNPC();
new TemplateNPC_command();
new TemplateNPC_World();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment