From 42427a8a728461eef9a59df3e7ed044bac2c2313 Mon Sep 17 00:00:00 2001 From: SylvaniaCore deploy Date: Fri, 28 Aug 2026 13:05:22 +0200 Subject: [PATCH] Rivage brise 1460 : rebrancher les vrais compteurs de l etape 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signale en jeu : « la phase 1 ou il fallait tuer 33 demons ainsi que d autres objectifs a ete skip et je suis passe en phase 3 direct », puis « les objectifs ne se remplissent jamais ». DEUX COMPTEURS VIVAIENT EN PARALLELE, et ne disaient pas la meme chose. Le client affichait les criteres officiels de l arbre 42935 (« Broken Shore - Stage 1 », operateur ALL) du build 7.3.5.26972 : 43010 Demons slain 33 critere 27653 46549 Fel Lords slain 3 critere 29377 46548 Spires of Woe destroyed 3 critere 27619 Tous trois de type CRITERIA_TYPE_SEND_EVENT_SCENARIO (92) : ils ne se remplissent PAS en tuant, mais quand le script emet l evenement correspondant. Le script ne l emettait jamais -- d ou le 0/33 fige. En parallele, il tenait sa propre comptabilite et cloturait l etape a KILLS_BEACH = 12, un chiffre invente. D ou l impression de saut : a 12 demons il invoquait Arganoth avec SetInCombatWithZone(), lequel mourait aussitot et faisait franchir une seconde etape. CORRECTIF -- on ne touche PAS aux objectifs, qui sont officiels et de toute facon dans les donnees du client. On supprime le seuil invente et on emet les vrais evenements : - chaque demon tue emet 44095 ; - chaque Seigneur gangrebois emet 52643 (les treize entrees placees sur la carte sont enumerees explicitement, le nom n etant pas une donnee stable) ; - chaque Fleche actionnee emet 44077 ; - l etape ne s acheve que si les TROIS seuils officiels sont atteints (33 / 3 / 3), conformement a l operateur ALL de l arbre. LES FLECHES sont des objets de type 10 : ACTIONNES, pas detruits. Ni OnGameObjectCreate ni OnGameObjectRemove ne rapportent cette utilisation. Le seul accrochage est GameObjectScript::OnGossipHello, que GameObject::Use appelle avant tout traitement specifique (GameObject.cpp:1379). D ou la classe go_spire_of_woe -- ET son rattachement en base, sans lequel elle n aurait jamais ete invoquee. Co-Authored-By: Claude Opus 5 --- sql/sylvania/rivage_fleche.sql | 24 ++++ .../Scenario/scenario_broken_shore_intro.cpp | 118 ++++++++++++++++-- 2 files changed, 131 insertions(+), 11 deletions(-) create mode 100644 sql/sylvania/rivage_fleche.sql diff --git a/sql/sylvania/rivage_fleche.sql b/sql/sylvania/rivage_fleche.sql new file mode 100644 index 0000000..ace3ec1 --- /dev/null +++ b/sql/sylvania/rivage_fleche.sql @@ -0,0 +1,24 @@ +-- ===================================================================== +-- Rivage brisé (carte 1460) — rattachement du script des Flèches +-- +-- L'étape 1 « Storm The Beach » exige trois Flèches de la Détresse +-- détruites (critère 27619, arbre 46548). Ce critère est de type +-- CRITERIA_TYPE_SEND_EVENT_SCENARIO : il ne se remplit que si le serveur +-- émet l'événement 44077. +-- +-- La Flèche est un objet de type 10, c'est-à-dire ACTIONNÉ et non +-- détruit. Aucun point d'entrée d'instance ne rapporte cette +-- utilisation : ni `OnGameObjectCreate` ni `OnGameObjectRemove` ne se +-- déclenchent. Le seul accrochage disponible est +-- `GameObjectScript::OnGossipHello`, que `GameObject::Use` appelle avant +-- tout traitement spécifique (GameObject.cpp:1379). +-- +-- Sans cette ligne, la classe `go_spire_of_woe` existerait dans le code +-- sans jamais être invoquée — un script non rattaché de plus. +-- +-- Rechargeable à chaud : reload gameobject_template +-- ===================================================================== + +UPDATE `gameobject_template` + SET `ScriptName` = 'go_spire_of_woe' + WHERE `entry` = 240194; diff --git a/src/server/scripts/BrokenIsles/Scenario/scenario_broken_shore_intro.cpp b/src/server/scripts/BrokenIsles/Scenario/scenario_broken_shore_intro.cpp index 4148d96..b7d796c 100644 --- a/src/server/scripts/BrokenIsles/Scenario/scenario_broken_shore_intro.cpp +++ b/src/server/scripts/BrokenIsles/Scenario/scenario_broken_shore_intro.cpp @@ -14,6 +14,7 @@ #include "TemporarySummon.h" #include "MotionMaster.h" #include "Player.h" +#include "GameObject.h" #include "ObjectMgr.h" #include "TaskScheduler.h" @@ -71,7 +72,39 @@ enum BrokenShoreCreatures enum BrokenShoreMisc { PHASE_NORMAL = 169, - KILLS_BEACH = 12, + + // ============================================================== + // SylvaniaCore - etape 1 « Storm The Beach » : seuils OFFICIELS. + // + // SIGNALE EN JEU : « la phase 1 ou il fallait tuer 33 demons ainsi + // que d'autres objectifs a ete skip et je suis passe en phase 3 + // direct », et « les objectifs ne se remplissent jamais ». + // + // Le script comptait ses propres demons et cloturait l'etape a 12, + // un chiffre invente qui ne correspondait a rien. Pendant ce temps + // le client affichait les vrais criteres, figes a zero. + // + // Les valeurs ci-dessous viennent de l'arbre de criteres 42935 + // (« Broken Shore - Stage 1 », operateur ALL) du build 7.3.5.26972 : + // 43010 Demons slain 33 critere 27653 + // 46549 Fel Lords slain 3 critere 29377 + // 46548 Spires of Woe destroyed 3 critere 27619 + // + // Les trois criteres sont de type CRITERIA_TYPE_SEND_EVENT_SCENARIO + // (92) : ils ne se remplissent PAS en tuant, mais quand le script + // emet l'evenement correspondant. C'est ce qui manquait. + // ============================================================== + KILLS_BEACH = 33, // etait 12, valeur inventee + FEL_LORDS_BEACH = 3, + SPIRES_BEACH = 3, + + EVENT_DEMONS_SLAIN = 44095, + EVENT_FEL_LORDS_SLAIN = 52643, + EVENT_SPIRES_DESTROYED = 44077, + + GO_SPIRE_OF_WOE = 240194, + DATA_SPIRE_USED = 9001, // signal envoye par le script d'objet + KILLS_CITY = 10, KILLS_FINALE = 8, ANCHORS_PORTAL = 2, @@ -121,6 +154,8 @@ struct scenario_broken_shore_intro : public InstanceScript stage = STAGE_INTRO; introDone = false; beachKills = 0; + felLordKills = 0; + spiresDown = 0; cityKills = 0; finaleKills = 0; anchorsDown = 0; @@ -261,6 +296,20 @@ struct scenario_broken_shore_intro : public InstanceScript case NPC_INFERNAL_DESTROYER: OnDemonDied(); break; + // Les treize Seigneurs gangrebois places sur la carte. L'etape + // en exige trois ; on les enumere explicitement plutot que de + // filtrer sur le nom, qui n'est pas une donnee stable. + case 91588: case 102703: case 102704: case 102705: + case 109586: case 109587: case 111156: case 113036: + case 113037: case 113038: case 113057: case 113058: + case 113059: + if (stage == STAGE_STORM_BEACH) + { + ++felLordKills; + DoSendEventScenario(EVENT_FEL_LORDS_SLAIN); + TryFinishBeach(); + } + break; case NPC_ARGANOTH: if (stage == STAGE_COMMANDER) { @@ -292,21 +341,47 @@ struct scenario_broken_shore_intro : public InstanceScript } } + // Le script d'objet des Fleches de la Detresse passe par ici : un + // objet de type 10 est ACTIONNE, pas detruit, et aucun point d'entree + // d'instance ne rapporte cette utilisation. + void SetData(uint32 type, uint32 /*data*/) override + { + if (type != DATA_SPIRE_USED || stage != STAGE_STORM_BEACH) + return; + + ++spiresDown; + DoSendEventScenario(EVENT_SPIRES_DESTROYED); + TryFinishBeach(); + } + + // L'etape ne s'acheve que si les TROIS criteres officiels sont + // remplis -- operateur ALL de l'arbre 42935. + void TryFinishBeach() + { + if (stage != STAGE_STORM_BEACH) + return; + + if (beachKills < KILLS_BEACH || felLordKills < FEL_LORDS_BEACH || spiresDown < SPIRES_BEACH) + return; + + stage = STAGE_COMMANDER; + CompleteStep(); + + if (Creature* arganoth = Summon(NPC_ARGANOTH, Anchors().commander)) + { + arganoth->AI()->Talk(0); + arganoth->SetInCombatWithZone(); + } + } + void OnDemonDied() { switch (stage) { case STAGE_STORM_BEACH: - if (++beachKills >= KILLS_BEACH) - { - stage = STAGE_COMMANDER; - CompleteStep(); - if (Creature* arganoth = Summon(NPC_ARGANOTH, Anchors().commander)) - { - arganoth->AI()->Talk(0); - arganoth->SetInCombatWithZone(); - } - } + ++beachKills; + DoSendEventScenario(EVENT_DEMONS_SLAIN); + TryFinishBeach(); break; case STAGE_RAZE_CITY: if (++cityKills >= KILLS_CITY) @@ -447,6 +522,8 @@ private: uint32 stage = STAGE_INTRO; bool introDone = false; uint8 beachKills = 0; + uint8 felLordKills = 0; + uint8 spiresDown = 0; uint8 cityKills = 0; uint8 finaleKills = 0; uint8 anchorsDown = 0; @@ -458,7 +535,26 @@ private: TaskScheduler scheduler; }; +// Fleche de la Detresse : objet de type 10 (actionnable). GameObject::Use +// appelle sScriptMgr->OnGossipHello avant tout traitement specifique, ce +// qui nous donne le seul point d'accroche disponible. On renvoie false +// pour laisser le comportement normal se poursuivre. +class go_spire_of_woe : public GameObjectScript +{ +public: + go_spire_of_woe() : GameObjectScript("go_spire_of_woe") { } + + bool OnGossipHello(Player* /*player*/, GameObject* go) override + { + if (InstanceScript* instance = go->GetInstanceScript()) + instance->SetData(DATA_SPIRE_USED, 1); + + return false; + } +}; + void AddSC_scenario_broken_shore_intro() { RegisterInstanceScript(scenario_broken_shore_intro, 1460); + new go_spire_of_woe(); }