Quatre hooks morts OnCompleteQuestChoice + quete 40373 injouable

Signale en jeu : choisir entre Kayn et Altruis ne declenche rien.

1) HOOK MORT, 4 occurrences. OnCompleteQuestChoice est declare dans
ScriptMgr mais appele DE NULLE PART ; le seul hook invoque a la reception
dun choix est OnPlayerChoiceResponse (QuestHandler.cpp). Corrige dans :
  zone_vault_of_wardens.cpp      choix Kayn / Altruis
  zone_legion_dalaran_legion.cpp Dalaran
  class_hall_dh.cpp              fief chasseur de demons
  class_hall_hunter.cpp          fief chasseur
Meme defaut que celui corrige a Mardum (commit 81b37487). Dautres fichiers
(class_hall_monk, class_hall_artifact_choices) utilisaient deja le bon nom,
ce qui confirme le diagnostic.

2) CREDIT MANQUANT. Le handler ne lancait quun sort : lobjectif 99278
(choisir entre Kayn et Altruis) de la quete 40373 netait accorde par rien.

3) QUETE SANS DONNEUR. 40373 a un recepteur et deux objectifs coherents
mais aucune ligne creature_queststarter. Attribuee a Korvas 97644 : elle en
est deja la receptrice, cest son propre script qui ouvre la fenetre de
choix, elle recoit aussi la quete precedente 39686, et elle porte npcflag=3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
SylvaniaCore deploy
2026-08-21 22:28:59 +02:00
parent e2300ba4a5
commit 69c9781828
5 changed files with 52 additions and 5 deletions
@@ -0,0 +1,23 @@
-- =====================================================================
-- Quête 40373 « Une nouvelle direction » — aucun donneur déclaré
--
-- La quête existe, a un récepteur (Kor'vas Bloodthorn 97644) et deux
-- objectifs cohérents (crédit 99278 « choisir entre Kayn et Altruis »,
-- crédit 100166 « Bassin du Jugement consulté »), mais AUCUNE ligne
-- creature_queststarter : personne ne pouvait la donner.
--
-- On l'attribue à Kor'vas 97644, et ce n'est pas un choix arbitraire :
-- * elle en est déjà la RÉCEPTRICE (creature_questender) ;
-- * c'est son propre script, npc_korvas_bloodthorn, qui déclenche la
-- fenêtre de choix Kayn/Altruis via OnGossipSelect ;
-- * elle est aussi réceptrice de la quête précédente, 39686
-- « Jusqu'au sommet », donc le joueur se trouve devant elle au bon
-- moment de la chaîne ;
-- * elle porte npcflag=3 (dialogue + donneur), elle est donc déjà
-- techniquement prête à donner une quête.
--
-- Rechargeable à chaud : reload creature_queststarter
-- =====================================================================
DELETE FROM `creature_queststarter` WHERE `id`=97644 AND `quest`=40373;
INSERT INTO `creature_queststarter` (`id`,`quest`) VALUES (97644,40373);
@@ -117,7 +117,11 @@ class PlayerScript_DH_artifact_choice : public PlayerScript
public: public:
PlayerScript_DH_artifact_choice() : PlayerScript("PlayerScript_DH_artifact_choice") {} PlayerScript_DH_artifact_choice() : PlayerScript("PlayerScript_DH_artifact_choice") {}
void OnCompleteQuestChoice(Player* player, uint32 choiceID, uint32 responseID) // Hook renomme : OnCompleteQuestChoice est declare dans ScriptMgr mais
// appele DE NULLE PART. Le seul hook que le core invoque a la reception
// dun choix est OnPlayerChoiceResponse (QuestHandler.cpp). Cette methode
// etait donc du code mort.
void OnPlayerChoiceResponse(Player* player, uint32 choiceID, uint32 responseID) override
{ {
if (choiceID != PLAYER_CHOICE_DH_ARTIFACT_SELECTION) if (choiceID != PLAYER_CHOICE_DH_ARTIFACT_SELECTION)
return; return;
@@ -138,7 +138,11 @@ class PlayerScript_hunter_artifact_choice : public PlayerScript
public: public:
PlayerScript_hunter_artifact_choice() : PlayerScript("PlayerScript_hunter_artifact_choice") {} PlayerScript_hunter_artifact_choice() : PlayerScript("PlayerScript_hunter_artifact_choice") {}
void OnCompleteQuestChoice(Player* player, uint32 choiceID, uint32 responseID) // Hook renomme : OnCompleteQuestChoice est declare dans ScriptMgr mais
// appele DE NULLE PART. Le seul hook que le core invoque a la reception
// dun choix est OnPlayerChoiceResponse (QuestHandler.cpp). Cette methode
// etait donc du code mort.
void OnPlayerChoiceResponse(Player* player, uint32 choiceID, uint32 responseID) override
{ {
if (choiceID != PLAYER_CHOICE_HUNTER_ARTIFACT_SELECTION) if (choiceID != PLAYER_CHOICE_HUNTER_ARTIFACT_SELECTION)
return; return;
@@ -1419,6 +1419,7 @@ enum eChoices
SPELL_NEW_DIRECTION_CHOICE_KAYN_OR_ALTRUIS = 196650, SPELL_NEW_DIRECTION_CHOICE_KAYN_OR_ALTRUIS = 196650,
SPELL_NEW_DIRECTION_CHOSE_ALTRUIS = 196662, SPELL_NEW_DIRECTION_CHOSE_ALTRUIS = 196662,
SPELL_NEW_DIRECTION_CHOSE_KAYN = 196661, SPELL_NEW_DIRECTION_CHOSE_KAYN = 196661,
NPC_CREDIT_FOLLOWER_CHOSEN = 99278,
}; };
class npc_korvas_bloodthorn : public CreatureScript class npc_korvas_bloodthorn : public CreatureScript
@@ -1438,7 +1439,11 @@ class PlayerScript_follower_choice : public PlayerScript
public: public:
PlayerScript_follower_choice() : PlayerScript("PlayerScript_follower_choice") {} PlayerScript_follower_choice() : PlayerScript("PlayerScript_follower_choice") {}
void OnCompleteQuestChoice(Player* player, uint32 choiceID, uint32 responseID) // Hook renomme : OnCompleteQuestChoice est declare dans ScriptMgr mais
// appele DE NULLE PART. Le seul hook que le core invoque a la reception
// dun choix est OnPlayerChoiceResponse (QuestHandler.cpp). Cette methode
// etait donc du code mort.
void OnPlayerChoiceResponse(Player* player, uint32 choiceID, uint32 responseID) override
{ {
if (choiceID != PLAYER_CHOICE_DH_FOLLOWER_SELECTION) if (choiceID != PLAYER_CHOICE_DH_FOLLOWER_SELECTION)
return; return;
@@ -1452,8 +1457,15 @@ public:
player->CastSpell(player, SPELL_NEW_DIRECTION_CHOSE_ALTRUIS, true); player->CastSpell(player, SPELL_NEW_DIRECTION_CHOSE_ALTRUIS, true);
break; break;
default: default:
break; return;
} }
// Objectif « Choose between Kayn and Altruis » de la quete 40373
// (Une nouvelle direction). Aucune source ne laccordait : ni ligne
// smart_scripts, ni code. La quete restait donc bloquee meme une fois
// le choix effectue.
if (player->GetQuestStatus(QUEST_A_NEW_DIRECTION) == QUEST_STATUS_INCOMPLETE)
player->KilledMonsterCredit(NPC_CREDIT_FOLLOWER_CHOSEN);
} }
}; };
@@ -342,7 +342,11 @@ class player_artifact_choice : public PlayerScript
public: public:
player_artifact_choice() : PlayerScript("player_artifact_choice") { } player_artifact_choice() : PlayerScript("player_artifact_choice") { }
void OnCompleteQuestChoice(Player* player, uint32 choiceId, uint32 /*responseId*/) // Hook renomme : OnCompleteQuestChoice est declare dans ScriptMgr mais
// appele DE NULLE PART. Le seul hook que le core invoque a la reception
// dun choix est OnPlayerChoiceResponse (QuestHandler.cpp). Cette methode
// etait donc du code mort.
void OnPlayerChoiceResponse(Player* player, uint32 choiceId, uint32 /*responseId*/) override
{ {
switch (choiceId) switch (choiceId)
{ {