AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Trainer::Trainer Class Reference

#include "Trainer.h"

Public Member Functions

 Trainer (uint32 trainerId, Type type, uint32 requirement, std::string greeting, std::vector< Spell > spells)
 
Spell const * GetSpell (uint32 spellId) const
 
std::vector< Spell > const & GetSpells () const
 
void SendSpells (Creature *npc, Player *player, LocaleConstant locale) const
 
bool CanTeachSpell (Player const *player, Spell const *trainerSpell)
 
void TeachSpell (Creature *npc, Player *player, uint32 spellId)
 
Type GetTrainerType () const
 
uint32 GetTrainerRequirement () const
 
bool IsTrainerValidForPlayer (Player const *player) const
 

Private Member Functions

SpellState GetSpellState (Player const *player, Spell const *trainerSpell) const
 
void SendTeachFailure (Creature const *npc, Player const *player, uint32 spellId, FailReason reason) const
 
void SendTeachSucceeded (Creature const *npc, Player const *player, uint32 spellId) const
 
std::string const & GetGreeting (LocaleConstant locale) const
 
void AddGreetingLocale (LocaleConstant locale, std::string greeting)
 

Private Attributes

friend ObjectMgr
 
uint32 _trainerId
 
Type _type
 
uint32 _requirement
 
std::vector< Spell_spells
 
std::array< std::string, TOTAL_LOCALES_greeting
 

Detailed Description

Constructor & Destructor Documentation

◆ Trainer()

Trainer::Trainer::Trainer ( uint32  trainerId,
Type  type,
uint32  requirement,
std::string  greeting,
std::vector< Spell spells 
)
32 : _trainerId(trainerId), _type(type), _requirement(requirement), _spells(std::move(spells))
33 {
34 _greeting[DEFAULT_LOCALE] = std::move(greeting);
35 }
#define DEFAULT_LOCALE
Definition Common.h:131
spells
Definition boss_krystallus.cpp:26
uint32 _trainerId
Definition Trainer.h:89
std::vector< Spell > _spells
Definition Trainer.h:92
Type _type
Definition Trainer.h:90
std::array< std::string, TOTAL_LOCALES > _greeting
Definition Trainer.h:93
uint32 _requirement
Definition Trainer.h:91

References DEFAULT_LOCALE.

Member Function Documentation

◆ AddGreetingLocale()

void Trainer::Trainer::AddGreetingLocale ( LocaleConstant  locale,
std::string  greeting 
)
private
259 {
260 _greeting[locale] = std::move(greeting);
261 }

◆ CanTeachSpell()

bool Trainer::Trainer::CanTeachSpell ( Player const *  player,
Spell const *  trainerSpell 
)
134 {
135 SpellState state = GetSpellState(player, trainerSpell);
136 if (state != SpellState::Available)
137 return false;
138
139 SpellInfo const* trainerSpellInfo = sSpellMgr->AssertSpellInfo(trainerSpell->SpellId);
140
141 for (SpellEffectInfo const& spellEffectInfo : trainerSpellInfo->GetEffects())
142 {
143 if (!spellEffectInfo.IsEffect(SPELL_EFFECT_LEARN_SPELL))
144 continue;
145
146 SpellInfo const* learnedSpellInfo = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell);
147 if (learnedSpellInfo && learnedSpellInfo->IsPrimaryProfessionFirstRank() && !player->GetFreePrimaryProfessionPoints())
148 return false;
149 }
150
151 return true;
152 }
@ SPELL_EFFECT_LEARN_SPELL
Definition SharedDefines.h:825
#define sSpellMgr
Definition SpellMgr.h:826
SpellState
Definition Spell.h:233
Definition SpellInfo.h:249
Definition SpellInfo.h:316
bool IsPrimaryProfessionFirstRank() const
Definition SpellInfo.cpp:983
SpellState GetSpellState(Player const *player, Spell const *trainerSpell) const
Definition Trainer.cpp:154

References Trainer::Available, SpellInfo::GetEffects(), Player::GetFreePrimaryProfessionPoints(), SpellInfo::IsPrimaryProfessionFirstRank(), SPELL_EFFECT_LEARN_SPELL, Trainer::Spell::SpellId, and sSpellMgr.

◆ GetGreeting()

std::string const & Trainer::Trainer::GetGreeting ( LocaleConstant  locale) const
private
251 {
252 if (_greeting[locale].empty())
254
255 return _greeting[locale];
256 }

References DEFAULT_LOCALE.

◆ GetSpell()

Spell const * Trainer::Trainer::GetSpell ( uint32  spellId) const
121 {
122 auto itr = std::find_if(_spells.begin(), _spells.end(), [spellId](Spell const& trainerSpell)
123 {
124 return trainerSpell.SpellId == spellId;
125 });
126
127 if (itr != _spells.end())
128 return &(*itr);
129
130 return nullptr;
131 }
Definition Spell.h:295

◆ GetSpells()

std::vector< Spell > const & Trainer::Trainer::GetSpells ( ) const
inline
71{ return _spells; }

◆ GetSpellState()

SpellState Trainer::Trainer::GetSpellState ( Player const *  player,
Spell const *  trainerSpell 
) const
private
155 {
156 if (player->HasSpell(trainerSpell->SpellId))
157 return SpellState::Known;
158
159 // check race/class requirement
160 if (!player->IsSpellFitByClassAndRace(trainerSpell->SpellId))
162
163 // check skill requirement
164 if (trainerSpell->ReqSkillLine && player->GetBaseSkillValue(trainerSpell->ReqSkillLine) < trainerSpell->ReqSkillRank)
166
167 for (int32 reqAbility : trainerSpell->ReqAbility)
168 if (reqAbility && !player->HasSpell(reqAbility))
169 return SpellState::Unavailable;
170
171 // check level requirement
172 if (player->GetLevel() < trainerSpell->ReqLevel)
174
175 // check ranks
176 bool hasLearnSpellEffect = false;
177 bool knowsAllLearnedSpells = true;
178 for (SpellEffectInfo const& spellEffectInfo : sSpellMgr->AssertSpellInfo(trainerSpell->SpellId)->GetEffects())
179 {
180 if (!spellEffectInfo.IsEffect(SPELL_EFFECT_LEARN_SPELL))
181 continue;
182
183 hasLearnSpellEffect = true;
184 if (!player->HasSpell(spellEffectInfo.TriggerSpell))
185 knowsAllLearnedSpells = false;
186
187 if (uint32 previousRankSpellId = sSpellMgr->GetPrevSpellInChain(spellEffectInfo.TriggerSpell))
188 if (!player->HasSpell(previousRankSpellId))
190 }
191
192 if (!hasLearnSpellEffect)
193 {
194 if (uint32 previousRankSpellId = sSpellMgr->GetPrevSpellInChain(trainerSpell->SpellId))
195 if (!player->HasSpell(previousRankSpellId))
197 }
198 else if (knowsAllLearnedSpells)
199 return SpellState::Known;
200
201 // check additional spell requirement
202 for (auto const& requirePair : sSpellMgr->GetSpellsRequiredForSpellBounds(trainerSpell->SpellId))
203 if (!player->HasSpell(requirePair.second))
204 return SpellState::Unavailable;
205
207 }
std::int32_t int32
Definition Define.h:103
std::uint32_t uint32
Definition Define.h:107

References Trainer::Available, Player::GetBaseSkillValue(), Unit::GetLevel(), Player::HasSpell(), Player::IsSpellFitByClassAndRace(), Trainer::Known, Trainer::Spell::ReqAbility, Trainer::Spell::ReqLevel, Trainer::Spell::ReqSkillLine, Trainer::Spell::ReqSkillRank, SPELL_EFFECT_LEARN_SPELL, Trainer::Spell::SpellId, sSpellMgr, and Trainer::Unavailable.

◆ GetTrainerRequirement()

uint32 Trainer::Trainer::GetTrainerRequirement ( ) const
inline
77{ return _requirement; }

◆ GetTrainerType()

Type Trainer::Trainer::GetTrainerType ( ) const
inline
76{ return _type; }

◆ IsTrainerValidForPlayer()

bool Trainer::Trainer::IsTrainerValidForPlayer ( Player const *  player) const
210 {
212 return true;
213
214 switch (GetTrainerType())
215 {
216 case Type::Class:
217 case Type::Pet:
218 // check class for class trainers
219 return player->getClass() == GetTrainerRequirement();
220 case Type::Mount:
221 // check race for mount trainers
222 return player->getRace() == GetTrainerRequirement();
223 case Type::Tradeskill:
224 // check spell for profession trainers
225 return player->HasSpell(GetTrainerRequirement());
226 default:
227 break;
228 }
229
230 return true;
231 }
uint32 GetTrainerRequirement() const
Definition Trainer.h:77
Type GetTrainerType() const
Definition Trainer.h:76

References Trainer::Class, Unit::getClass(), Unit::getRace(), Player::HasSpell(), Trainer::Mount, Trainer::Pet, and Trainer::Tradeskill.

Referenced by Creature::CanResetTalents(), Player::PrepareGossipMenu(), and WorldSession::SendTrainerList().

◆ SendSpells()

void Trainer::Trainer::SendSpells ( Creature npc,
Player player,
LocaleConstant  locale 
) const
38 {
39 float reputationDiscount = player->GetReputationPriceDiscount(npc);
40
42 trainerList.TrainerGUID = npc->GetGUID();
43 trainerList.TrainerType = AsUnderlyingType(_type);
44 trainerList.Greeting = GetGreeting(locale);
45 trainerList.Spells.reserve(_spells.size());
46 for (Spell const& trainerSpell : _spells)
47 {
48 if (!player->IsSpellFitByClassAndRace(trainerSpell.SpellId))
49 continue;
50
51 SpellInfo const* trainerSpellInfo = sSpellMgr->AssertSpellInfo(trainerSpell.SpellId);
52
53 bool primaryProfessionFirstRank = false;
54 for (SpellEffectInfo const& spellEffectInfo : trainerSpellInfo->GetEffects())
55 {
56 if (!spellEffectInfo.IsEffect(SPELL_EFFECT_LEARN_SPELL))
57 continue;
58
59 SpellInfo const* learnedSpellInfo = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell);
60 if (learnedSpellInfo && learnedSpellInfo->IsPrimaryProfessionFirstRank())
61 primaryProfessionFirstRank = true;
62 }
63
64 trainerList.Spells.emplace_back();
65 WorldPackets::NPC::TrainerListSpell& trainerListSpell = trainerList.Spells.back();
66 trainerListSpell.SpellID = trainerSpell.SpellId;
67 trainerListSpell.Usable = AsUnderlyingType(GetSpellState(player, &trainerSpell));
68 trainerListSpell.MoneyCost = int32(trainerSpell.MoneyCost * reputationDiscount);
69 trainerListSpell.PointCost[0] = 0; // spells don't cost talent points
70 trainerListSpell.PointCost[1] = (primaryProfessionFirstRank ? 1 : 0);
71 trainerListSpell.ReqLevel = trainerSpell.ReqLevel;
72 trainerListSpell.ReqSkillLine = trainerSpell.ReqSkillLine;
73 trainerListSpell.ReqSkillRank = trainerSpell.ReqSkillRank;
74 std::copy(trainerSpell.ReqAbility.begin(), trainerSpell.ReqAbility.end(), trainerListSpell.ReqAbility.begin());
75 }
76
77 player->SendDirectMessage(trainerList.Write());
78 }
npc
Definition BattlegroundSA.h:47
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:610
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5688
bool IsSpellFitByClassAndRace(uint32 spell_id) const
Definition Player.cpp:12321
float GetReputationPriceDiscount(Creature const *creature) const
Definition Player.cpp:12300
std::string const & GetGreeting(LocaleConstant locale) const
Definition Trainer.cpp:250
Definition NPCPackets.h:56
WorldPacket const * Write() override
Definition NPCPackets.cpp:25
int32 TrainerType
Definition NPCPackets.h:63
std::vector< TrainerListSpell > Spells
Definition NPCPackets.h:64
ObjectGuid TrainerGUID
Definition NPCPackets.h:62
std::string Greeting
Definition NPCPackets.h:65
Definition NPCPackets.h:44
uint8 Usable
Definition NPCPackets.h:46
int32 ReqSkillLine
Definition NPCPackets.h:50
int32 MoneyCost
Definition NPCPackets.h:47
uint8 ReqLevel
Definition NPCPackets.h:49
std::array< int32, 3 > ReqAbility
Definition NPCPackets.h:52
int32 SpellID
Definition NPCPackets.h:45
int32 ReqSkillRank
Definition NPCPackets.h:51
std::array< int32, 2 > PointCost
Definition NPCPackets.h:48

References AsUnderlyingType(), SpellInfo::GetEffects(), Player::GetReputationPriceDiscount(), WorldPackets::NPC::TrainerList::Greeting, SpellInfo::IsPrimaryProfessionFirstRank(), Player::IsSpellFitByClassAndRace(), WorldPackets::NPC::TrainerListSpell::MoneyCost, WorldPackets::NPC::TrainerListSpell::PointCost, WorldPackets::NPC::TrainerListSpell::ReqAbility, WorldPackets::NPC::TrainerListSpell::ReqLevel, WorldPackets::NPC::TrainerListSpell::ReqSkillLine, WorldPackets::NPC::TrainerListSpell::ReqSkillRank, Player::SendDirectMessage(), SPELL_EFFECT_LEARN_SPELL, WorldPackets::NPC::TrainerListSpell::SpellID, WorldPackets::NPC::TrainerList::Spells, sSpellMgr, WorldPackets::NPC::TrainerList::TrainerGUID, WorldPackets::NPC::TrainerList::TrainerType, WorldPackets::NPC::TrainerListSpell::Usable, and WorldPackets::NPC::TrainerList::Write().

Referenced by WorldSession::SendTrainerList().

◆ SendTeachFailure()

void Trainer::Trainer::SendTeachFailure ( Creature const *  npc,
Player const *  player,
uint32  spellId,
FailReason  reason 
) const
private
234 {
236 trainerBuyFailed.TrainerGUID = npc->GetGUID();
237 trainerBuyFailed.SpellID = spellId;
238 trainerBuyFailed.TrainerFailedReason = AsUnderlyingType(reason);
239 player->SendDirectMessage(trainerBuyFailed.Write());
240 }
Definition NPCPackets.h:80
int32 TrainerFailedReason
Definition NPCPackets.h:88
WorldPacket const * Write() override
Definition NPCPackets.cpp:54
int32 SpellID
Definition NPCPackets.h:87
ObjectGuid TrainerGUID
Definition NPCPackets.h:86

References AsUnderlyingType(), Player::SendDirectMessage(), WorldPackets::NPC::TrainerBuyFailed::SpellID, WorldPackets::NPC::TrainerBuyFailed::TrainerFailedReason, WorldPackets::NPC::TrainerBuyFailed::TrainerGUID, and WorldPackets::NPC::TrainerBuyFailed::Write().

◆ SendTeachSucceeded()

void Trainer::Trainer::SendTeachSucceeded ( Creature const *  npc,
Player const *  player,
uint32  spellId 
) const
private
243 {
244 WorldPackets::NPC::TrainerBuySucceeded trainerBuySucceeded;
245 trainerBuySucceeded.TrainerGUID = npc->GetGUID();
246 trainerBuySucceeded.SpellID = spellId;
247 player->SendDirectMessage(trainerBuySucceeded.Write());
248 }
Definition NPCPackets.h:92
ObjectGuid TrainerGUID
Definition NPCPackets.h:98
WorldPacket const * Write() override
Definition NPCPackets.cpp:63
int32 SpellID
Definition NPCPackets.h:99

References Player::SendDirectMessage(), WorldPackets::NPC::TrainerBuySucceeded::SpellID, WorldPackets::NPC::TrainerBuySucceeded::TrainerGUID, and WorldPackets::NPC::TrainerBuySucceeded::Write().

◆ TeachSpell()

void Trainer::Trainer::TeachSpell ( Creature npc,
Player player,
uint32  spellId 
)
81 {
82 if (!IsTrainerValidForPlayer(player))
83 return;
84
85 Spell const* trainerSpell = GetSpell(spellId);
86 if (!trainerSpell)
87 {
89 return;
90 }
91
92 if (!CanTeachSpell(player, trainerSpell))
93 {
95 return;
96 }
97
98 float reputationDiscount = player->GetReputationPriceDiscount(npc);
99 int32 moneyCost = int32(trainerSpell->MoneyCost * reputationDiscount);
100 if (!player->HasEnoughMoney(moneyCost))
101 {
103 return;
104 }
105
106 player->ModifyMoney(-moneyCost);
107
108 npc->SendPlaySpellVisual(179); // 53 SpellCastDirected
109 npc->SendPlaySpellImpact(player->GetGUID(), 362); // 113 EmoteSalute
110
111 // learn explicitly or cast explicitly
112 if (trainerSpell->IsCastable())
113 player->CastSpell(player, trainerSpell->SpellId, true);
114 else
115 player->learnSpell(trainerSpell->SpellId, false);
116
117 SendTeachSucceeded(npc, player, spellId);
118 }
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:113
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition Player.cpp:3292
bool ModifyMoney(int32 amount, bool sendError=true)
Definition Player.cpp:11448
bool HasEnoughMoney(uint32 amount) const
Definition Player.h:1597
bool IsTrainerValidForPlayer(Player const *player) const
Definition Trainer.cpp:209
Spell const * GetSpell(uint32 spellId) const
Definition Trainer.cpp:120
void SendTeachFailure(Creature const *npc, Player const *player, uint32 spellId, FailReason reason) const
Definition Trainer.cpp:233
bool CanTeachSpell(Player const *player, Spell const *trainerSpell)
Definition Trainer.cpp:133
void SendTeachSucceeded(Creature const *npc, Player const *player, uint32 spellId) const
Definition Trainer.cpp:242
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition Unit.cpp:1194

References Unit::CastSpell(), Object::GetGUID(), Player::GetReputationPriceDiscount(), Player::HasEnoughMoney(), Trainer::Spell::IsCastable(), Player::learnSpell(), Player::ModifyMoney(), Trainer::Spell::MoneyCost, Trainer::NotEnoughMoney, Trainer::NotEnoughSkill, Trainer::Spell::SpellId, and Trainer::Unavailable.

Referenced by WorldSession::HandleTrainerBuySpellOpcode().

Member Data Documentation

◆ _greeting

std::array<std::string, TOTAL_LOCALES> Trainer::Trainer::_greeting
private

◆ _requirement

uint32 Trainer::Trainer::_requirement
private

◆ _spells

std::vector<Spell> Trainer::Trainer::_spells
private

◆ _trainerId

uint32 Trainer::Trainer::_trainerId
private

◆ _type

Type Trainer::Trainer::_type
private

◆ ObjectMgr

friend Trainer::Trainer::ObjectMgr
private

The documentation for this class was generated from the following files: