From 8e9b65291f5ff35d376bc9bf23570156b3e04caf Mon Sep 17 00:00:00 2001 From: SylvaniaCore deploy Date: Tue, 25 Aug 2026 12:21:14 +0200 Subject: [PATCH] Brasserie : roulement des tonneaux, et sonde sur le reveil d Ook-Ook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signale en jeu : « les tonneaux sont completement bugges, ils se deplacent bizarrement ». Deux defauts certains dans npc_barrel : 1. Le trajet etait reinitialise en plein vol. Move() relancait un MovePoint vers un point a 5 m devant TOUTES LES 300 ms, alors que le tonneau avance a 0,85 de vitesse (environ 5,95 m/s) : parcourir ces 5 m lui demande 840 ms. Le trajet etait donc ecrase au tiers, quatre fois par segment. Cote client chaque reinitialisation est une rupture de trajectoire, d ou le roulement saccade. Le deplacement est desormais relance A L ARRIVEE via MovementInform, par segments de 20 m. 2. L orientation de depart n etait jamais fixee. Le tonneau est invoque par un sort a 5-10 m devant le Hurleur, mais rien ne lui donnait de cap propre. Il part maintenant dans la direction du lancer. Arbitrage assume : la generation de chemin de MovePoint est CONSERVEE. Un tonneau devrait rouler droit et la couper serait plus juste sur le papier, mais c est elle qui le maintient sur le sol praticable -- sans elle il traverserait les murs. Sur sol degage le chemin est de toute facon quasi rectiligne. Sonde OOKDBG ajoutee (4 points) : Ook-Ook se reveille avant le seuil de 40 hozens alors qu InitializeAI le pose en NON_ATTACKABLE et en reaction passive, et que le chemin scripte (SEUIL ATTEINT) n apparait jamais dans les traces. Pistes deja ecartees : les evenements 2 et 3 de l instance ne le concernent pas, et EVENT_INTROCHECK est programme mais traite nulle part -- evenement mort. Co-Authored-By: Claude Opus 5 --- .../StormstoutBrewery/boss_ook_ook.cpp | 84 +++++++++++++++++-- 1 file changed, 77 insertions(+), 7 deletions(-) diff --git a/src/server/scripts/Pandaria/StormstoutBrewery/boss_ook_ook.cpp b/src/server/scripts/Pandaria/StormstoutBrewery/boss_ook_ook.cpp index f3261b8..6d5936c 100644 --- a/src/server/scripts/Pandaria/StormstoutBrewery/boss_ook_ook.cpp +++ b/src/server/scripts/Pandaria/StormstoutBrewery/boss_ook_ook.cpp @@ -121,8 +121,19 @@ public: initializedBarrels = false; events.ScheduleEvent(EVENT_INTROCHECK, 3000); + // SONDE TEMPORAIRE + TC_LOG_ERROR("misc", + "OOKDBG InitializeAI : etatBoss=%u nonAttaquable=%u reactState=%u", + instance ? uint32(instance->GetBossState(DATA_OOK_OOK)) : 999, + uint32(me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE) ? 1 : 0), + uint32(me->GetReactState())); + if (instance && instance->GetBossState(DATA_OOK_OOK) == SPECIAL) + { + // SONDE TEMPORAIRE + TC_LOG_ERROR("misc", "OOKDBG etat SPECIAL persistant -> intro lancee des l initialisation"); me->AI()->DoAction(0); + } } void Reset() override @@ -146,6 +157,9 @@ public: void StartIntro() { + // SONDE TEMPORAIRE + TC_LOG_ERROR("misc", "OOKDBG StartIntro appelee (introDone valait %u)", uint32(introDone ? 1 : 0)); + introDone = true; events.CancelEvent(EVENT_INTROCHECK); @@ -160,8 +174,19 @@ public: me->SetHomePosition(ookJumpPos); } - void EnterCombat(Unit* /*who*/) override + void EnterCombat(Unit* who) override { + // SONDE TEMPORAIRE - c'est la question centrale : qui l'engage, + // et dans quel etat etait-il a ce moment-la ? + TC_LOG_ERROR("misc", + "OOKDBG EnterCombat par %s (type=%u entree=%u) | nonAttaquable=%u reactState=%u introDone=%u", + who ? who->GetName().c_str() : "INCONNU", + who ? uint32(who->GetTypeId()) : 999, + (who && who->GetTypeId() == TYPEID_UNIT) ? who->GetEntry() : 0, + uint32(me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE) ? 1 : 0), + uint32(me->GetReactState()), + uint32(introDone ? 1 : 0)); + _EnterCombat(); Talk(TALK_AGGRO); @@ -175,6 +200,9 @@ public: void DoAction(int32 actionId) override { + // SONDE TEMPORAIRE + TC_LOG_ERROR("misc", "OOKDBG DoAction(%d)", actionId); + if (actionId == 0) StartIntro(); else if (actionId == 1) @@ -301,6 +329,18 @@ public: { me->SetReactState(REACT_PASSIVE); me->AddAura(SPELL_ROLLING_BARREL_COSMETIC, me); + + // SylvaniaCore : le tonneau part desormais dans la direction du + // lancer. Il est invoque par un sort a 5-10 m devant le Hurleur + // (npc_hozen_hollerer::DoCastBarrel), mais son orientation + // propre n'etait jamais fixee : rien ne garantissait qu'il + // roule vers la salle plutot que dans n'importe quel sens. + if (summoner) + { + float const cap = summoner->GetOrientation(); + me->SetOrientation(cap); + me->SetFacingTo(cap, true); + } me->SetSpeed(MOVE_WALK, 0.85f); me->SetSpeed(MOVE_RUN, 0.85f); me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); @@ -317,14 +357,47 @@ public: me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); } + // SylvaniaCore - deplacement des tonneaux. + // + // SIGNALE EN JEU : « les tonneaux sont completement bugges, ils se + // deplacent bizarrement ». + // + // L'ancienne version relancait un MovePoint vers un point situe a + // 5 m devant, TOUTES LES 300 ms. Or le tonneau avance a 0,85 de + // vitesse, soit environ 5,95 m/s : parcourir ces 5 m lui demande + // 840 ms. Le trajet etait donc reinitialise alors qu'il n'en avait + // effectue qu'un tiers, et cela quatre fois de suite pour chaque + // segment. Cote client, chaque reinitialisation est une rupture de + // trajectoire : d'ou le roulement saccade. + // + // On ne relance donc plus au chronometre mais A L'ARRIVEE, via + // MovementInform. Le segment est aussi allonge : moins de coutures, + // donc un roulement continu. + static uint32 const POINT_ROULEMENT = 100; + void Move() { + // 20 m par segment : assez long pour que le roulement paraisse + // continu, assez court pour que le tonneau reste reactif. + float const DISTANCE_ROULEMENT = 20.0f; + float x = 0, y = 0; - GetPositionWithDistInOrientation(me, 5.0f, me->GetOrientation(), x, y); + GetPositionWithDistInOrientation(me, DISTANCE_ROULEMENT, me->GetOrientation(), x, y); - me->GetMotionMaster()->MovePoint(100, x, y, me->GetPositionZ()); + // On conserve volontairement la generation de chemin. Un tonneau + // devrait rouler en ligne droite, et la couper ferait mieux sur + // le papier -- mais elle est aussi ce qui garde le tonneau sur + // le sol praticable. Sans elle il traverserait les murs et + // sortirait de la salle, ce qui serait pire que le defaut + // corrige. Sur un sol degage, le chemin calcule est de toute + // facon quasi rectiligne. + me->GetMotionMaster()->MovePoint(POINT_ROULEMENT, x, y, me->GetPositionZ()); + } - events.ScheduleEvent(EVENT_MOVE, 300); + void MovementInform(uint32 type, uint32 id) override + { + if (type == POINT_MOTION_TYPE && id == POINT_ROULEMENT) + Move(); } void UpdateAI(uint32 diff) override @@ -338,9 +411,6 @@ public: { switch (eventId) { - case EVENT_MOVE: - Move(); - break; case EVENT_EXPLOSION_BREAK: initiate = true; break;