diff --git a/chantiers/reference_legion/rivage_1460_deroule.md b/chantiers/reference_legion/rivage_1460_deroule.md new file mode 100644 index 0000000..a18a02e --- /dev/null +++ b/chantiers/reference_legion/rivage_1460_deroule.md @@ -0,0 +1,114 @@ +# La bataille du Rivage brisé — déroulé de référence (carte 1460, scénario 786) + +Ce document croise trois sources, et dit toujours laquelle parle : + +- **la vidéo** fournie par l'exploitant (40 min, écran partagé Alliance/Horde), + qui donne l'ordre réel des événements, le minutage et les compteurs affichés ; +- **les DB2 du build 7.3.5.26972** (`ScenarioStep`, `CriteriaTree`, `Criteria`), + qui donnent les critères chiffrés ; +- **[Warcraft Wiki](https://warcraft.wiki.gg/wiki/The_Battle_for_Broken_Shore_(quest))**, + qui donne les intitulés et les répliques. + +Ce que **notre base** contient est indiqué en regard, avec l'écart quand il y en a. + +--- + +## Les neuf étapes + +| # | Alliance | Horde | Critère officiel | +|---|---|---|---| +| 1 | The Broken Shore | idem | arbre 42768 — asset 44060 ×1 | +| 2 | Storm The Beach | idem | 44095 ×**33**, 52643 ×**3**, 44077 ×**3** | +| 3 | Defeat the Commander — **Arganoth** | Defeat the Commander — **Azgalor** | arbre 43554 — asset 45131 ×1 | +| 4 | **Find Varian** | **Find The Others** (Sylvanas *et* Baine) | arbre 43589 — asset 45228 ×1 | +| 5 | Destroy the Portal — **4 ancres blindées** | idem | arbre 43415 — asset 45288 ×**4** | +| 6 | Raze the Black City — barre 0→100 % | idem | arbre 42770 — 44384 ×1, 53062 ×2, 53063 ×5, 53064 ×10 | +| 7 | The Highlord — atteindre Tirion | idem | arbre 42772 | +| 8 | Krosus | idem | arbre 43765 | +| 9 | **Stop Gul'dan** | **Hold the Ridge** | arbre 47225 | + +--- + +## Trois erreurs que ce croisement a révélées + +**L'étape 5 comptait la mauvaise créature.** Notre script invoquait deux +« ancres dimensionnelles » (90637) de sa fabrication. Le jeu demande la +destruction de **quatre ancres blindées** (`101667`), dont la carte porte déjà +quinze exemplaires autour de `(1107, 2061)`. Corrigé. + +**L'étape 3 n'a pas le même adversaire selon la faction.** Alliance : *Dread +Commander Arganoth*. Horde : *Fel Commander Azgalor*. Notre script ne connaît +qu'Arganoth et l'invoque pour les deux camps. **Non corrigé.** + +**L'étape 4 non plus.** Alliance : trouver Varian. Horde : trouver **Sylvanas +et Baine**, deux personnages, pas Vol'jin. Notre script cherche Vol'jin côté +Horde. **Non corrigé.** + +Et l'étape 9 diverge aussi : l'Alliance arrête Gul'dan, la Horde tient la +crête pendant ce temps. + +--- + +## Nos dialogues sont inventés + +Toutes les répliques de `creature_text` pour ce scénario ont un +`BroadcastTextId` à **zéro** : elles ont été écrites à la main, elles ne +viennent pas du jeu. Elles sont plausibles mais fausses, et l'une d'elles a +directement produit un bug. + +| Entrée | Notre texte | Le jeu | +|---|---|---| +| 90714 Jaina | « Détruisez les ancres **dimensionnelles** » | *Those crystals appear to be anchoring the structures to our dimension. Take them out!* | +| 90713 Varian | « Soldats de l'Alliance ! La Légion s'abat… » | *Genn, Jaina, it's good to see you safe.* | +| 90717 Genn | — | *Just in time. We haven't been able to break their line. Now we may have a chance.* | +| 90708 Vol'jin | « Fils et filles de la Horde ! … » | *Dere's only one way offa dis beach, and it be t'rough alla dose demons ahead of us.* | +| 90413 Gul'dan | « Vous arrivez trop tard ! … » | *I have seen the end of your pitiful world, Wrynn. … The legion is ENDLESS.* | + +C'est la réplique de Jaina qui a fabriqué l'erreur de l'étape 5 : le script a +été écrit d'après elle. **La donnée fausse produit du code faux.** + +--- + +## Déroulé relevé sur la vidéo + +Minutage de la vidéo, pas du scénario — les premières minutes sont à Dalaran. + +| Temps | Événement | +|---|---| +| 06:02 | Jaina : « Attention, des infernaux ! » — début du combat de plage | +| 06:04 | Le commandant de l'effroi Arganoth parle | +| 06:54 | Genn Grisetête : « Celui-là est à moi ! » | +| 07:00 | Jaina : « Est-ce que tout le monde va bien ? » | +| 07:26 | Genn : « Les troupes de Varian ont dû arriver de l'autre côté de… » | +| 07:48 | Jaina : « Je n'avais jamais vu des démons progresser… » | +| 08:18 | Genn : « Quelque chose a changé. La Légion n'est… » | +| 08:38 | Jaina : « Oh, non… » | +| 08:46 | Varian : « Tenez bon, soldats de l'Alliance ! » | +| 09:12 | Varian : « Genn, Jaina, je suis heureux de voir que vous allez bien. » | +| 09:18 | Varian : « En formation, protecteurs de l'Alliance ! Repoussons-les ! » | +| 17:28 | Varian : « Vous avez une autre occasion de l'abattre, Sylvanas » | +| 17:32 | Sylvanas : « C'est comme si c'était fait, Wrynn. » | +| 17:54 | Varian : « Tout le monde, de l'autre côté du gouffre ! » | +| 18:08 | Sylvanas : « Nous allons prendre la crête et couvrir votre… » | +| 18:44 | Gul'dan : « M'échapper ? C'est plutôt vous qui n'échapperez pas à mon… » | +| ~08:20 vidéo | phase 5 : compteur **0/4 → 2/4 → 3/4 Ancres blindées détruites** | +| ~09:00 vidéo | phase 6 : barre **0 % → 2 % → 13 % → 37 % → 63 %** | + +Le texte ci-dessus vient de la reconnaissance optique sur une vidéo 720p en +écran partagé : **les fins de phrase sont tronquées** par la largeur de la +fenêtre de discussion, et certains caractères sont incertains. Il donne +l'ordre et l'orateur de façon fiable ; il ne fait pas autorité sur la +formulation exacte. Pour celle-ci, se référer au wiki. + +--- + +## Ce qui reste à faire + +1. **Le commandant Horde** : invoquer Azgalor et non Arganoth. +2. **L'étape 4 Horde** : deux cibles, Sylvanas et Baine. +3. **L'étape 9 Horde** : tenir la crête, pas arrêter Gul'dan. +4. **Les étapes 6 à 9** avancent encore par forçage, sans leurs critères. La + barre de 300 points de l'étape 6 est alimentée par quatre événements de + poids différents (1, 2, 5, 10) dont le sens reste à établir. +5. **Remplacer les dialogues inventés** par les vrais. Ils n'existent qu'en + anglais dans nos sources : traduire, ou assumer l'anglais. 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 f82e105..7db2f4a 100644 --- a/src/server/scripts/BrokenIsles/Scenario/scenario_broken_shore_intro.cpp +++ b/src/server/scripts/BrokenIsles/Scenario/scenario_broken_shore_intro.cpp @@ -105,9 +105,29 @@ enum BrokenShoreMisc GO_SPIRE_OF_WOE = 240194, DATA_SPIRE_USED = 9001, // signal envoye par le script d'objet + // ============================================================== + // Criteres officiels des etapes 2 a 4, releves dans ScenarioStep, + // CriteriaTree et Criteria du build 7.3.5.26972 : + // etape 2 arbre 43554 critere 30883 type 92 asset 45131 x1 + // etape 3 arbre 43589 critere 28017 type 92 asset 45228 x1 + // etape 4 arbre 43415 critere 27940 type 92 asset 45288 x4 + // + // L'ancre du portail a ete identifiee sur la VIDEO de la bataille + // fournie par l'exploitant, et non deduite : l'objectif y affiche + // « 0/4 Ancres blindees detruites », puis 2/4, puis 3/4. Il s'agit + // donc de 101667 « Shielded Anchor », dont la carte porte QUINZE + // exemplaires deja poses autour de (1107, 2061) -- et non des deux + // ancres dimensionnelles 90637 que le script invoquait lui-meme. + // ============================================================== + NPC_SHIELDED_ANCHOR = 101667, + + EVENT_COMMANDER_SLAIN = 45131, + EVENT_LEADER_FOUND = 45228, + EVENT_ANCHOR_DESTROYED = 45288, + KILLS_CITY = 10, KILLS_FINALE = 8, - ANCHORS_PORTAL = 2, + ANCHORS_PORTAL = 4, // etait 2, valeur inventee }; struct FactionAnchors @@ -213,6 +233,45 @@ struct scenario_broken_shore_intro : public InstanceScript scheduler.Update(diff); } + // ================================================================= + // SylvaniaCore : retenir le chef POSE SUR LA CARTE. + // + // SIGNALE EN JEU : « je suis en phase 4, je suis juste a cote de + // Varian et rien ne se valide ». + // + // La carte 1460 porte deja les vrais protagonistes -- Varian en + // (1120, 2484), Vol'jin en (568, 1887), Sylvanas et Jaina -- parmi + // les 757 creatures transposees. Or le script en invoquait une + // SECONDE copie sur la plage et ne surveillait que celle-la. Le + // joueur se tenait donc devant le vrai Varian pendant que l'etape + // guettait un sosie ailleurs, ou deja disparu. + // + // Le spawnId distingue les deux sans ambiguite : une creature issue + // de la base en porte un, une invocation non. + // ================================================================= + void OnCreatureCreate(Creature* creature) override + { + InstanceScript::OnCreatureCreate(creature); + + if (!creature || !creature->GetSpawnId()) + return; + + if (creature->GetEntry() == NPC_KING_VARIAN) + placedVarianGUID = creature->GetGUID(); + else if (creature->GetEntry() == NPC_VOLJIN) + placedVoljinGUID = creature->GetGUID(); + } + + // Le chef a rejoindre : celui de la carte s'il existe, sinon la + // copie invoquee par le script. + Creature* FindLeader() const + { + ObjectGuid const pose = (team == TEAM_HORDE) ? placedVoljinGUID : placedVarianGUID; + if (Creature* leader = instance->GetCreature(pose)) + return leader; + return instance->GetCreature(leaderGUID); + } + void CompleteStep() { if (Scenario* scenario = instance->GetInstanceScenario()) @@ -340,16 +399,21 @@ struct scenario_broken_shore_intro : public InstanceScript if (stage == STAGE_COMMANDER) { creature->AI()->Talk(1); + DoSendEventScenario(EVENT_COMMANDER_SLAIN); stage = STAGE_FIND_LEADER; - CompleteStep(); StartFindLeader(); } break; - case NPC_DIMENSIONAL_ANCHOR: - if (stage == STAGE_PORTAL && ++anchorsDown >= ANCHORS_PORTAL) + case NPC_SHIELDED_ANCHOR: + if (stage != STAGE_PORTAL) + break; + + // Une activation par ancre : le critere en exige quatre. + DoSendEventScenario(EVENT_ANCHOR_DESTROYED); + + if (++anchorsDown >= ANCHORS_PORTAL) { stage = STAGE_RAZE_CITY; - CompleteStep(); SummonWave(Anchors().city, 5); SummonWave(Anchors().city, 5); } @@ -411,8 +475,12 @@ struct scenario_broken_shore_intro : public InstanceScript if (beachKills < KILLS_BEACH || felLordKills < FEL_LORDS_BEACH || spiresDown < SPIRES_BEACH) return; + // Les trois criteres officiels ont ete alimentes a chaque mort : + // le moteur acheve l'etape de lui-meme. Un CompleteStep() ici + // ferait avancer une SECONDE fois -- c'est la cause du saut + // d'etapes signale en jeu (« j'ai passe ma phase 2 et ca m'a + // switche jusqu'a la 5 sans rien faire »). stage = STAGE_COMMANDER; - CompleteStep(); if (Creature* arganoth = Summon(NPC_ARGANOTH, Anchors().commander)) { @@ -451,9 +519,11 @@ struct scenario_broken_shore_intro : public InstanceScript { FactionAnchors const& a = Anchors(); - // le chef et son etat-major se replacent au point de ralliement (la Cite noire) - if (Creature* leader = instance->GetCreature(leaderGUID)) - leader->NearTeleportTo(a.city.GetPositionX(), a.city.GetPositionY(), a.city.GetPositionZ(), a.city.GetOrientation()); + // On ne DEPLACE plus le chef. L'etape s'intitule « Trouver + // Varian » : le joueur doit aller a lui, la ou la carte le pose. + // Le teleporter au point de ralliement revenait a le mettre + // sous les pieds du joueur, et la detection de proximite se + // declenchait alors dans la seconde. SummonAt(NPC_KHADGAR, a.city, 4.0f, 3.0f); for (uint8 i = 0; i < 3; ++i) SummonAt(TroopEntry(), a.city, -6.0f + i * 6.0f, -5.0f); @@ -464,7 +534,7 @@ struct scenario_broken_shore_intro : public InstanceScript if (stage != STAGE_FIND_LEADER) return; bool found = false; - Creature* leader = instance->GetCreature(leaderGUID); + Creature* leader = FindLeader(); if (leader) { DoOnPlayers([&found, leader](Player* player) @@ -475,8 +545,8 @@ struct scenario_broken_shore_intro : public InstanceScript } if (found) { + DoSendEventScenario(EVENT_LEADER_FOUND); stage = STAGE_PORTAL; - CompleteStep(); if (Creature* second = instance->GetCreature(team == TEAM_HORDE ? sylvanasGUID : jainaGUID)) second->AI()->Talk(0); StartPortal(); @@ -489,8 +559,10 @@ struct scenario_broken_shore_intro : public InstanceScript void StartPortal() { FactionAnchors const& a = Anchors(); - SummonAt(NPC_DIMENSIONAL_ANCHOR, a.portal, -8.0f, 0.0f); - SummonAt(NPC_DIMENSIONAL_ANCHOR, a.portal, 8.0f, 0.0f); + // Les ancres blindees (101667) sont DEJA posees sur la carte, + // quinze exemplaires autour de (1107, 2061). Rien a invoquer : + // le script en fabriquait deux fausses, d'une autre entree, que + // le critere officiel ne reconnaissait pas. SummonAt(NPC_EREDAR_SUMMONER, a.portal, 0.0f, 6.0f); SummonAt(NPC_CHAOS_MINION, a.portal, -5.0f, 8.0f); SummonAt(NPC_CHAOS_MINION, a.portal, 5.0f, 8.0f); @@ -578,6 +650,8 @@ private: ObjectGuid leaderGUID; ObjectGuid jainaGUID; ObjectGuid sylvanasGUID; + ObjectGuid placedVarianGUID; + ObjectGuid placedVoljinGUID; ObjectGuid guldanGUID; TaskScheduler scheduler; };