TrinityCore
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
cs_learn.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* ScriptData
19Name: learn_commandscript
20%Complete: 100
21Comment: All learn related commands
22Category: commandscripts
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "Chat.h"
27#include "DBCStores.h"
28#include "Language.h"
29#include "ObjectMgr.h"
30#include "Pet.h"
31#include "Player.h"
32#include "RBAC.h"
33#include "SpellInfo.h"
34#include "SpellMgr.h"
35#include "WorldSession.h"
36
37using namespace Trinity::ChatCommands;
39{
40public:
41 learn_commandscript() : CommandScript("learn_commandscript") { }
42
44 {
45 static ChatCommandTable learnAllCommandTable =
46 {
55 };
56
57 static ChatCommandTable learnMyCommandTable =
58 {
61 };
62
63 static ChatCommandTable learnCommandTable =
64 {
66 { "all", learnAllCommandTable },
67 { "my", learnMyCommandTable }
68 };
69
70 static ChatCommandTable commandTable =
71 {
72 { "learn", learnCommandTable },
74 };
75 return commandTable;
76 }
77
78 static bool HandleLearnCommand(ChatHandler* handler, SpellInfo const* spell, Optional<EXACT_SEQUENCE("all")> allRanks)
79 {
80 Player* targetPlayer = handler->getSelectedPlayerOrSelf();
81
82 if (!targetPlayer)
83 {
85 handler->SetSentErrorMessage(true);
86 return false;
87 }
88
89 if (!SpellMgr::IsSpellValid(spell, handler->GetSession()->GetPlayer()))
90 {
92 handler->SetSentErrorMessage(true);
93 return false;
94 }
95
96 if (!allRanks && targetPlayer->HasSpell(spell->Id))
97 {
98 if (targetPlayer == handler->GetPlayer())
100 else
101 handler->PSendSysMessage(LANG_TARGET_KNOWN_SPELL, handler->GetNameLink(targetPlayer).c_str());
102 handler->SetSentErrorMessage(true);
103 return false;
104 }
105
106 targetPlayer->LearnSpell(spell->Id, false);
107 if (allRanks)
108 {
109 uint32 spellId = spell->Id;
110 while ((spellId = sSpellMgr->GetNextSpellInChain(spellId)))
111 targetPlayer->LearnSpell(spellId, false);
112 }
113
115 targetPlayer->SendTalentsInfoData(false);
116
117 return true;
118 }
119
121 {
122 for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
123 {
124 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i);
125 if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false))
126 continue;
127
128 if (!spellInfo->IsAbilityOfSkillType(SKILL_INTERNAL))
129 continue;
130
131 handler->GetSession()->GetPlayer()->LearnSpell(i, false);
132 }
133
135 return true;
136 }
137
139 {
140 Player* player = handler->GetPlayer();
141 for (auto const& [id, quest] : sObjectMgr->GetQuestTemplates())
142 {
143 if (quest->GetRequiredClasses() && player->SatisfyQuestClass(quest.get(), false))
144 player->LearnQuestRewardedSpells(quest.get());
145 }
146 return true;
147 }
148
150 {
151 ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(handler->GetPlayer()->GetClass());
152 if (!classEntry)
153 return true;
154
155 Player* player = handler->GetPlayer();
156 std::vector<Trainer::Trainer const*> const& trainers = sObjectMgr->GetClassTrainers(player->GetClass());
157
158 bool hadNew;
159 do
160 {
161 hadNew = false;
162 for (Trainer::Trainer const* trainer : trainers)
163 {
164 if (!trainer->IsTrainerValidForPlayer(player))
165 continue;
166 for (Trainer::Spell const& trainerSpell : trainer->GetSpells())
167 {
168 if (!trainer->CanTeachSpell(player, &trainerSpell))
169 continue;
170
171 if (trainerSpell.IsCastable())
172 player->CastSpell(player, trainerSpell.SpellId, true);
173 else
174 player->LearnSpell(trainerSpell.SpellId, false);
175
176 hadNew = true;
177 }
178 }
179 } while (hadNew);
180
182 return true;
183 }
184
186 {
187 Player* player = handler->GetSession()->GetPlayer();
188 uint32 classMask = player->GetClassMask();
189
190 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
191 {
192 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
193 if (!talentInfo)
194 continue;
195
196 TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TabID);
197 if (!talentTabInfo)
198 continue;
199
200 if ((classMask & talentTabInfo->ClassMask) == 0)
201 continue;
202
203 // search highest talent rank
204 uint32 spellId = 0;
205 for (int8 rank = MAX_TALENT_RANK - 1; rank >= 0; --rank)
206 {
207 if (talentInfo->SpellRank[rank] != 0)
208 {
209 spellId = talentInfo->SpellRank[rank];
210 break;
211 }
212 }
213
214 if (!spellId) // ??? none spells in talent
215 continue;
216
217 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
218 if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false))
219 continue;
220
221 player->LearnSpell(spellId, false);
222 player->AddTalent(spellId, player->GetActiveSpec(), true);
223 }
224
225 player->SetFreeTalentPoints(0);
226 player->SendTalentsInfoData(false);
227
229 return true;
230 }
231
233 {
234 Player* player = handler->GetSession()->GetPlayer();
235
236 Pet* pet = player->GetPet();
237 if (!pet)
238 {
240 handler->SetSentErrorMessage(true);
241 return false;
242 }
243
244 CreatureTemplate const* creatureInfo = pet->GetCreatureTemplate();
245 if (!creatureInfo)
246 {
248 handler->SetSentErrorMessage(true);
249 return false;
250 }
251
252 CreatureFamilyEntry const* petFamily = sCreatureFamilyStore.LookupEntry(creatureInfo->family);
253 if (!petFamily)
254 {
256 handler->SetSentErrorMessage(true);
257 return false;
258 }
259
260 if (petFamily->PetTalentType < 0) // not hunter pet
261 {
263 handler->SetSentErrorMessage(true);
264 return false;
265 }
266
267 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
268 {
269 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
270 if (!talentInfo)
271 continue;
272
273 TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TabID);
274 if (!talentTabInfo)
275 continue;
276
277 // prevent learn talent for different family (cheating)
278 if (((1 << petFamily->PetTalentType) & talentTabInfo->PetTalentMask) == 0)
279 continue;
280
281 // search highest talent rank
282 uint32 spellId = 0;
283
284 for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
285 {
286 if (talentInfo->SpellRank[rank] != 0)
287 {
288 spellId = talentInfo->SpellRank[rank];
289 break;
290 }
291 }
292
293 if (!spellId) // ??? none spells in talent
294 continue;
295
296 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
297 if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false))
298 continue;
299
300 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
301 pet->learnSpellHighRank(spellId);
302 }
303
304 pet->SetFreeTalentPoints(0);
305
307 return true;
308 }
309
311 {
312 for (LanguageDesc const& langDesc : lang_description)
313 if (uint32 langSpellId = langDesc.spell_id)
314 handler->GetPlayer()->LearnSpell(langSpellId, false);
315
317 return true;
318 }
319
321 {
322 Player* const player = handler->GetPlayer();
323 player->LearnSpell(63364, false); /* 63364 - Saronite Barrier (reduces damage taken by 99%) */
324 player->LearnSpell(1908, false); /* 1908 - Uber Heal Over Time (heals target to full constantly) */
325 player->LearnSpell(27680, false); /* 27680 - Berserk (+500% damage, +150% speed, 10m duration) */
326 player->LearnSpell(62555, false); /* 62555 - Berserk (+500% damage, +150% melee haste, 10m duration) */
327 player->LearnSpell(64238, false); /* 64238 - Berserk (+900% damage, +150% melee haste, 30m duration) */
328 player->LearnSpell(72525, false); /* 72525 - Berserk (+240% damage, +160% haste, infinite duration) */
329 player->LearnSpell(66776, false); /* 66776 - Rage (+300% damage, -95% damage taken, +100% speed, infinite duration) */
330 return true;
331 }
332
334 {
335 if (!player)
336 player = PlayerIdentifier::FromTargetOrSelf(handler);
337 if (!player || !player->IsConnected())
338 return false;
339
340 Player* target = player->GetConnectedPlayer();
341 target->LearnDefaultSkills();
342 target->LearnCustomSpells();
343 target->LearnQuestRewardedSpells();
344
345 handler->PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST, handler->GetNameLink(target).c_str());
346 return true;
347 }
348
350 {
351 if (!player)
352 player = PlayerIdentifier::FromTargetOrSelf(handler);
353 if (!player || !player->IsConnected())
354 return false;
355
356 Player* target = player->GetConnectedPlayer();
357 for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
358 {
359 SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(i);
360 if (!skillInfo)
361 continue;
362
363 if ((skillInfo->CategoryID == SKILL_CATEGORY_PROFESSION || skillInfo->CategoryID == SKILL_CATEGORY_SECONDARY) &&
364 skillInfo->CanLink) // only prof. with recipes have
365 {
366 HandleLearnSkillRecipesHelper(target, skillInfo->ID);
367 }
368 }
369
371 return true;
372 }
373
374 static bool HandleLearnAllRecipesCommand(ChatHandler* handler, WTail namePart)
375 {
376 // Learns all recipes of specified profession and sets skill to max
377 // Example: .learn all_recipes enchanting
378
379 Player* target = handler->getSelectedPlayer();
380 if (!target)
381 {
383 return false;
384 }
385
386 if (namePart.empty())
387 return false;
388
389 // converting string that we try to find to lower case
390 wstrToLower(namePart);
391
392 SkillLineEntry const* targetSkillInfo = nullptr;
393 char const* name = nullptr;
394 for (uint32 i = 1; i < sSkillLineStore.GetNumRows(); ++i)
395 {
396 SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(i);
397 if (!skillInfo)
398 continue;
399
400 if ((skillInfo->CategoryID != SKILL_CATEGORY_PROFESSION &&
401 skillInfo->CategoryID != SKILL_CATEGORY_SECONDARY) ||
402 !skillInfo->CanLink) // only prof with recipes have set
403 continue;
404
405 uint8 locale = 0;
406 for (; locale < TOTAL_LOCALES; ++locale)
407 {
408 name = skillInfo->DisplayName[locale];
409 if (!name || !*name)
410 continue;
411
412 if (Utf8FitTo(name, namePart))
413 break;
414 }
415
416 if (locale < TOTAL_LOCALES)
417 {
418 targetSkillInfo = skillInfo;
419 break;
420 }
421 }
422
423 if (!(name && targetSkillInfo))
424 return false;
425
426 HandleLearnSkillRecipesHelper(target, targetSkillInfo->ID);
427
428 uint16 maxLevel = target->GetPureMaxSkillValue(targetSkillInfo->ID);
429 target->SetSkill(targetSkillInfo->ID, target->GetSkillStep(targetSkillInfo->ID), maxLevel, maxLevel);
431 return true;
432 }
433
434 static void HandleLearnSkillRecipesHelper(Player* player, uint32 skillId)
435 {
436 uint32 classmask = player->GetClassMask();
437
438 std::vector<SkillLineAbilityEntry const*> const* skillLineAbilities = GetSkillLineAbilitiesBySkill(skillId);
439 if (!skillLineAbilities)
440 return;
441
442 for (SkillLineAbilityEntry const* skillLine : *skillLineAbilities)
443 {
444 // not high rank
445 if (skillLine->SupercededBySpell)
446 continue;
447
448 // skip racial skills
449 if (skillLine->RaceMask != 0)
450 continue;
451
452 // skip wrong class skills
453 if (skillLine->ClassMask && (skillLine->ClassMask & classmask) == 0)
454 continue;
455
456 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(skillLine->Spell);
457 if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, player, false))
458 continue;
459
460 player->LearnSpell(skillLine->Spell, false);
461 }
462 }
463
464 static bool HandleUnLearnCommand(ChatHandler* handler, SpellInfo const* spell, Optional<EXACT_SEQUENCE("all")> allRanks)
465 {
466 Player* target = handler->getSelectedPlayer();
467
468 if (!target)
469 {
471 handler->SetSentErrorMessage(true);
472 return false;
473 }
474
475 uint32 spellId = spell->Id;
476 if (allRanks)
477 spellId = sSpellMgr->GetFirstSpellInChain(spellId);
478
479 if (target->HasSpell(spellId))
480 target->RemoveSpell(spellId, false, !allRanks);
481 else
483
484 if (GetTalentSpellCost(spellId))
485 target->SendTalentsInfoData(false);
486
487 return true;
488 }
489};
490
492{
494}
#define EXACT_SEQUENCE(str)
@ TOTAL_LOCALES
Definition: Common.h:59
#define MAX_TALENT_RANK
Definition: DBCEnums.h:432
DBCStorage< TalentTabEntry > sTalentTabStore(TalentTabEntryfmt)
std::vector< SkillLineAbilityEntry const * > const * GetSkillLineAbilitiesBySkill(uint32 skillLine)
Definition: DBCStores.cpp:946
uint32 GetTalentSpellCost(uint32 spellId)
Definition: DBCStores.cpp:704
DBCStorage< SkillLineEntry > sSkillLineStore(SkillLinefmt)
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
DBCStorage< ChrClassesEntry > sChrClassesStore(ChrClassesEntryfmt)
uint8_t uint8
Definition: Define.h:135
int8_t int8
Definition: Define.h:131
uint16_t uint16
Definition: Define.h:134
uint32_t uint32
Definition: Define.h:133
@ LANG_COMMAND_LEARN_ALL_RECIPES
Definition: Language.h:682
@ LANG_YOU_KNOWN_SPELL
Definition: Language.h:558
@ LANG_COMMAND_LEARN_ALL_DEBUG_HELP
Definition: Language.h:443
@ LANG_FORGET_SPELL
Definition: Language.h:561
@ LANG_COMMAND_LEARN_ALL_PETTALENT_HELP
Definition: Language.h:449
@ LANG_COMMAND_LEARN_ALL_CRAFT
Definition: Language.h:496
@ LANG_LEARNING_GM_SKILLS
Definition: Language.h:557
@ LANG_WRONG_PET_TYPE
Definition: Language.h:900
@ LANG_COMMAND_LEARN_ALL_LANGUAGES_HELP
Definition: Language.h:446
@ LANG_COMMAND_LEARN_MY_TRAINER_HELP
Definition: Language.h:441
@ LANG_COMMAND_LEARN_CLASS_TALENTS
Definition: Language.h:494
@ LANG_COMMAND_LEARN_ALL_BLIZZARD_HELP
Definition: Language.h:442
@ LANG_COMMAND_LEARN_CLASS_SPELLS
Definition: Language.h:493
@ LANG_COMMAND_LEARN_ALL_LANG
Definition: Language.h:495
@ LANG_COMMAND_LEARN_ALL_CRAFTS_HELP
Definition: Language.h:444
@ LANG_COMMAND_LEARN_ALL_DEFAULT_HELP
Definition: Language.h:445
@ LANG_COMMAND_LEARN_ALL_RECIPES_HELP
Definition: Language.h:447
@ LANG_COMMAND_UNLEARN_HELP
Definition: Language.h:439
@ LANG_COMMAND_LEARN_PET_TALENTS
Definition: Language.h:901
@ LANG_NO_CHAR_SELECTED
Definition: Language.h:150
@ LANG_PLAYER_NOT_FOUND
Definition: Language.h:570
@ LANG_NO_PET_FOUND
Definition: Language.h:899
@ LANG_COMMAND_LEARN_ALL_TALENTS_HELP
Definition: Language.h:448
@ LANG_COMMAND_SPELL_BROKEN
Definition: Language.h:551
@ LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST
Definition: Language.h:667
@ LANG_COMMAND_LEARN_MY_QUESTS_HELP
Definition: Language.h:440
@ LANG_TARGET_KNOWN_SPELL
Definition: Language.h:559
@ LANG_COMMAND_LEARN_HELP
Definition: Language.h:438
LanguageDesc lang_description[LANGUAGES_COUNT]
Definition: ObjectMgr.cpp:161
#define sObjectMgr
Definition: ObjectMgr.h:1723
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
Role Based Access Control related classes definition.
@ SKILL_CATEGORY_SECONDARY
@ SKILL_CATEGORY_PROFESSION
@ SKILL_INTERNAL
#define sSpellMgr
Definition: SpellMgr.h:738
void wstrToLower(std::wstring &str)
Definition: Util.cpp:480
bool Utf8FitTo(std::string_view str, std::wstring_view search)
Definition: Util.cpp:565
Player * getSelectedPlayerOrSelf()
Definition: Chat.cpp:341
Player * getSelectedPlayer()
Definition: Chat.cpp:297
WorldSession * GetSession()
Definition: Chat.h:46
virtual std::string GetNameLink() const
Definition: Chat.cpp:46
void PSendSysMessage(const char *fmt, Args &&... args)
Definition: Chat.h:69
void SetSentErrorMessage(bool val)
Definition: Chat.h:126
Player * GetPlayer() const
Definition: Chat.cpp:34
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition: Chat.cpp:101
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:194
Definition: Pet.h:40
void learnSpellHighRank(uint32 spellid)
Definition: Pet.cpp:1973
void SetFreeTalentPoints(uint8 points)
Definition: Pet.h:139
Definition: Player.h:915
void LearnSpell(uint32 spell_id, bool dependent, uint32 fromSkill=0)
Definition: Player.cpp:3421
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:25548
void LearnQuestRewardedSpells()
Definition: Player.cpp:23023
void LearnCustomSpells()
Definition: Player.cpp:22884
void SetSkill(uint32 id, uint16 step, uint16 newVal, uint16 maxVal)
Definition: Player.cpp:5843
Pet * GetPet() const
Definition: Player.cpp:20442
uint16 GetPureMaxSkillValue(uint32 skill) const
Definition: Player.cpp:6002
bool SatisfyQuestClass(Quest const *qInfo, bool msg) const
Definition: Player.cpp:15439
void RemoveSpell(uint32 spell_id, bool disabled=false, bool learn_low_rank=true)
Definition: Player.cpp:3459
uint16 GetSkillStep(uint32 skill) const
Definition: Player.cpp:5956
void SetFreeTalentPoints(uint32 points)
Definition: Player.cpp:3844
uint8 GetActiveSpec() const
Definition: Player.h:1489
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3921
bool AddTalent(uint32 spellId, uint8 spec, bool learning)
Definition: Player.cpp:2930
void LearnDefaultSkills()
Definition: Player.cpp:22904
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:3332
uint32 Id
Definition: SpellInfo.h:293
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:1035
static bool IsSpellValid(SpellInfo const *spellInfo, Player *player=nullptr, bool msg=true)
Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book,...
Definition: SpellMgr.cpp:71
uint8 GetClass() const
Definition: Unit.h:893
uint32 GetClassMask() const
Definition: Unit.h:895
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2831
Player * GetPlayer() const
Definition: WorldSession.h:500
static bool HandleLearnMySpellsCommand(ChatHandler *handler)
Definition: cs_learn.cpp:149
static bool HandleLearnDebugSpellsCommand(ChatHandler *handler)
Definition: cs_learn.cpp:320
static bool HandleUnLearnCommand(ChatHandler *handler, SpellInfo const *spell, Optional< EXACT_SEQUENCE("all")> allRanks)
Definition: cs_learn.cpp:464
static bool HandleLearnAllRecipesCommand(ChatHandler *handler, WTail namePart)
Definition: cs_learn.cpp:374
static bool HandleLearnAllTalentsCommand(ChatHandler *handler)
Definition: cs_learn.cpp:185
static bool HandleLearnMyQuestsCommand(ChatHandler *handler)
Definition: cs_learn.cpp:138
static bool HandleLearnAllCraftsCommand(ChatHandler *handler, Optional< PlayerIdentifier > player)
Definition: cs_learn.cpp:349
static bool HandleLearnAllGMCommand(ChatHandler *handler)
Definition: cs_learn.cpp:120
ChatCommandTable GetCommands() const override
Definition: cs_learn.cpp:43
static bool HandleLearnAllPetTalentsCommand(ChatHandler *handler)
Definition: cs_learn.cpp:232
static bool HandleLearnAllDefaultCommand(ChatHandler *handler, Optional< PlayerIdentifier > player)
Definition: cs_learn.cpp:333
static bool HandleLearnAllLangCommand(ChatHandler *handler)
Definition: cs_learn.cpp:310
static bool HandleLearnCommand(ChatHandler *handler, SpellInfo const *spell, Optional< EXACT_SEQUENCE("all")> allRanks)
Definition: cs_learn.cpp:78
static void HandleLearnSkillRecipesHelper(Player *player, uint32 skillId)
Definition: cs_learn.cpp:434
void AddSC_learn_commandscript()
Definition: cs_learn.cpp:491
std::vector< ChatCommandBuilder > ChatCommandTable
Definition: ChatCommand.h:50
@ RBAC_PERM_COMMAND_UNLEARN
Definition: RBAC.h:299
@ RBAC_PERM_COMMAND_LEARN_ALL_LANG
Definition: RBAC.h:297
@ RBAC_PERM_COMMAND_LEARN_ALL_CRAFTS
Definition: RBAC.h:295
@ RBAC_PERM_COMMAND_LEARN_ALL_RECIPES
Definition: RBAC.h:298
@ RBAC_PERM_COMMAND_LEARN_ALL_TALENTS
Definition: RBAC.h:293
@ RBAC_PERM_COMMAND_LEARN
Definition: RBAC.h:287
@ RBAC_PERM_COMMAND_LEARN_ALL_MY_SPELLS
Definition: RBAC.h:292
@ RBAC_PERM_COMMAND_LEARN_ALL_GM
Definition: RBAC.h:294
@ RBAC_PERM_COMMAND_LEARN_ALL_DEFAULT
Definition: RBAC.h:296
@ RBAC_PERM_COMMAND_LEARN_MY_PETTALENTS
Definition: RBAC.h:291
CreatureFamily family
Definition: CreatureData.h:324
char const * DisplayName[16]
std::array< uint32, MAX_TALENT_RANK > SpellRank
uint32 PetTalentMask