From 85b0251bc192d34656ff22145e43c469196acc04 Mon Sep 17 00:00:00 2001 From: SylvaniaCore deploy Date: Thu, 27 Aug 2026 11:46:52 +0200 Subject: [PATCH] =?UTF-8?q?Scenarios=20:=20le=20premier=20critere=20achev?= =?UTF-8?q?=C3=A9=20cloturait=20toute=20l=20etape?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signale en jeu, capture a l appui : a la Brasserie brune d Orage, la liste des trois boss disparaissait entierement des qu Ook-Ook tombait, au lieu de cocher 1/1 et de conserver les deux autres. Le scenario 537 n a qu UNE etape (972), dont l arbre de criteres 36317 porte trois feuilles : 36318 Ook-Ook, 36319 Hoptallus, 36320 Yan-Zhu. CriteriaMgr::LoadCriteriaList attribue l etape via GetEntry, qui REMONTE la chaine des parents jusqu a trouver une correspondance -- chaque feuille herite donc de l etape 972. Et le moteur n evalue que les feuilles : GetCriteriaTreesByCriteria ne renvoie que les arbres portant directement le critere, jamais la racine. Resultat : la premiere feuille achevee marquait l ETAPE ENTIERE terminee. CompleteStep ne trouvait alors aucune etape suivante, IsComplete() repondait oui, et le scenario etait cloture des le premier boss. On verifie desormais l arbre RACINE de l etape avant de conclure. Un garde naif sur « tree doit etre la racine » ne conviendrait pas : la racine n etant jamais transmise ici, l etape ne s acheverait alors JAMAIS. CheckCompletedCriteriaTree pouvant rappeler cette fonction avec la racine, on relit l etat de l etape ensuite -- sans quoi CompleteStep serait execute deux fois et la quete de recompense octroyee en double. Correctif dans le moteur partage : il vaut pour tous les scenarios dont une etape porte plusieurs criteres. Co-Authored-By: Claude Opus 5 --- src/server/game/Scenarios/Scenario.cpp | 49 +++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/server/game/Scenarios/Scenario.cpp b/src/server/game/Scenarios/Scenario.cpp index 3b4df00..8302253 100644 --- a/src/server/game/Scenarios/Scenario.cpp +++ b/src/server/game/Scenarios/Scenario.cpp @@ -192,7 +192,7 @@ bool Scenario::CanCompleteCriteriaTree(CriteriaTree const* tree) return true; } -void Scenario::CompletedCriteriaTree(CriteriaTree const* tree, Player* /*referencePlayer*/) +void Scenario::CompletedCriteriaTree(CriteriaTree const* tree, Player* referencePlayer) { ScenarioStepEntry const* step = tree->ScenarioStep; if (!step) @@ -204,6 +204,53 @@ void Scenario::CompletedCriteriaTree(CriteriaTree const* tree, Player* /*referen if (GetStepState(step) == SCENARIO_STEP_DONE) return; + // ================================================================= + // SylvaniaCore - une etape ne s'acheve que si TOUS ses criteres le + // sont. + // + // SIGNALE EN JEU : a la Brasserie brune d'Orage, la liste des boss + // disparaissait entierement des qu'Ook-Ook tombait, au lieu de + // cocher « 1/1 » et de conserver les deux autres. + // + // POURQUOI. Le scenario 537 n'a qu'UNE etape (972), dont l'arbre de + // criteres 36317 porte trois feuilles : + // 36318 Ook-Ook, 36319 Hoptallus, 36320 Yan-Zhu. + // + // Or `CriteriaMgr::LoadCriteriaList` attribue l'etape via une aide + // qui REMONTE la chaine des parents jusqu'a trouver une + // correspondance. Chaque feuille herite donc de l'etape 972. Et le + // moteur n'evalue que les feuilles : `GetCriteriaTreesByCriteria` + // ne renvoie que les arbres portant directement le critere, jamais + // la racine. + // + // Resultat : la premiere feuille achevee marquait l'ETAPE ENTIERE + // terminee. `CompleteStep` ne trouvait alors aucune etape suivante, + // `IsComplete()` repondait oui, et le scenario etait cloture des le + // premier boss. + // + // On verifie donc l'arbre RACINE de l'etape avant de conclure. Un + // garde naif sur « tree doit etre la racine » ne conviendrait pas : + // la racine n'etant jamais transmise ici, l'etape ne s'acheverait + // alors JAMAIS. + // + // `CheckCompletedCriteriaTree` peut, en cas de succes, rappeler + // cette fonction avec la racine : on relit donc l'etat de l'etape + // ensuite, faute de quoi `CompleteStep` serait execute deux fois et + // la quete de recompense octroyee en double. + // ================================================================= + if (step->Criteriatreeid && step->Criteriatreeid != tree->Entry->ID) + { + CriteriaTree const* racine = sCriteriaMgr->GetCriteriaTree(step->Criteriatreeid); + if (!racine) + return; + + if (!CheckCompletedCriteriaTree(racine, referencePlayer)) + return; + + if (GetStepState(step) == SCENARIO_STEP_DONE) + return; + } + SetStepState(step, SCENARIO_STEP_DONE); CompleteStep(step); }