mirror of
https://gitcode.com/GitHub_Trending/az/azerothcore-wotlk.git
synced 2026-10-10 07:06:38 +08:00
fix(Core/Scripting): ask OnPlayerCanLearnSpell before a trainer casts an entry (#27707)
Co-authored-by: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
70865b66c7
commit
fd43d2b5ad
@@ -111,11 +111,13 @@ namespace Trainer
|
||||
npc->SendPlaySpellVisual(179); // 53 SpellCastDirected
|
||||
npc->SendPlaySpellImpact(player->GetGUID(), 362); // 113 EmoteSalute
|
||||
|
||||
// learn explicitly or cast explicitly
|
||||
if (trainerSpell->IsCastable())
|
||||
player->CastSpell(player, trainerSpell->SpellId, true);
|
||||
else
|
||||
// learn explicitly or cast explicitly. A cast puts each wrapped spell through learnSpell and
|
||||
// its hook, but also runs whatever else the entry does (a class mount steps the Riding skill),
|
||||
// so the entry itself is put to the hook first and a refusal skips the cast as a whole
|
||||
if (!trainerSpell->IsCastable())
|
||||
player->learnSpell(trainerSpell->SpellId, false);
|
||||
else if (sScriptMgr->OnPlayerCanLearnSpell(player, trainerSpell->SpellId))
|
||||
player->CastSpell(player, trainerSpell->SpellId, true);
|
||||
|
||||
SendTeachSucceeded(npc, player, spellId);
|
||||
|
||||
|
||||
@@ -891,18 +891,21 @@ public:
|
||||
* did. A trainer has taken the money and still reports success, and Player::LearnTalent spends
|
||||
* the point and records the talent anyway -- use OnPlayerCanLearnTalent to stop a talent.
|
||||
*
|
||||
* Only Player::learnSpell reaches it; spells written through addSpell do not. Those bypasses
|
||||
* include character loading (_LoadSpells, and the initial class and skill-rewarded spells,
|
||||
* which run on every login) and talent spells from _addTalentAurasAndSpells, reapplied on
|
||||
* every dual-spec switch -- so a refusal in world is undone the next time one of them runs.
|
||||
* Player::learnSpell reaches it, and so does a trainer about to cast a wrapper entry (below);
|
||||
* spells written through addSpell do not. Those bypasses include character loading
|
||||
* (_LoadSpells, and the initial class and skill-rewarded spells, which run on every login) and
|
||||
* talent spells from _addTalentAurasAndSpells, reapplied on every dual-spec switch -- so a
|
||||
* refusal in world is undone the next time one of them runs.
|
||||
*
|
||||
* What it sees can be indirect: a trainer entry that wraps other spells (a paladin's Summon
|
||||
* Warhorse) is cast, so the hook sees the wrapped spells instead. A talent rank arrives only
|
||||
* when it lands in the spell book, which most do not -- but a learn-spell talent still
|
||||
* delivers its additional talent spells.
|
||||
* Warhorse) is cast, so the hook sees the entry first and then each wrapped spell as the cast
|
||||
* teaches it. Refusing the entry skips the cast as a whole, and with it whatever else the entry
|
||||
* does: a class mount also steps the Riding skill, which refusing the wrapped spells alone does
|
||||
* not stop. A talent rank arrives only when it lands in the spell book, which most do not -- but
|
||||
* a learn-spell talent still delivers its additional talent spells.
|
||||
*
|
||||
* @param player Contains information about the Player
|
||||
* @param spellId The id of the spell about to be learned
|
||||
* @param spellId The id of the spell about to be learned, or of the trainer entry about to be cast
|
||||
*
|
||||
* @return true if the player is allowed to learn the spell
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user