From 28833e12dccbcf122d00bfb98a647f36cdff1720 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 28 Mar 2026 19:12:55 -0300 Subject: [PATCH] fix(Scripts/HoR): fix HoR escape event outro and refactor tracking (#25287) Co-authored-by: Claude Opus 4.6 --- .../HallsOfReflection/halls_of_reflection.cpp | 70 +++++++------------ .../HallsOfReflection/halls_of_reflection.h | 19 ++--- .../instance_halls_of_reflection.cpp | 5 +- 3 files changed, 40 insertions(+), 54 deletions(-) diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 95b2c4f5c..c6fbed94b 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -1499,7 +1499,6 @@ enum eFightEvents EVENT_LK_SUMMON_LA, EVENT_LK_SUMMON_NEXT_ICE_WALL, EVENT_SAY_OPENING, - EVENT_DECREASE_REQ_COUNT_BY_100, }; struct npc_hor_lich_king : public NullCreatureAI @@ -1515,13 +1514,14 @@ struct npc_hor_lich_king : public NullCreatureAI EventMap events; SummonList summons; uint8 currentWall; - uint8 reqKillCount; + uint8 summonsCount; uint8 div2; void Reset() override { currentWall = 0; - reqKillCount = 0; + summonsCount = 0; + div2 = 0; events.Reset(); events.RescheduleEvent(EVENT_LK_CHECK_COMBAT, 1s); } @@ -1529,24 +1529,21 @@ struct npc_hor_lich_king : public NullCreatureAI { if (action == ACTION_START_LK_FIGHT_REAL) events.ScheduleEvent(EVENT_LK_START_FOLLOWING, 1500ms); - else if ((action == ACTION_INFORM_TRASH_DIED && reqKillCount) || action == ACTION_CHECK_TRASH_DIED) + } + + void WallCompleted() + { + ++currentWall; + instance->SetData(ACTION_DELETE_ICE_WALL, 1); + if (currentWall <= 3) { - if ((action == ACTION_CHECK_TRASH_DIED && reqKillCount == 0) || (action == ACTION_INFORM_TRASH_DIED && (--reqKillCount) == 0)) - { - events.CancelEvent(EVENT_DECREASE_REQ_COUNT_BY_100); // just in case, magic happens sometimes - ++currentWall; - instance->SetData(ACTION_DELETE_ICE_WALL, 1); - if (currentWall <= 3) - { - events.ScheduleEvent(EVENT_LK_SUMMON_NEXT_ICE_WALL, 1s); - events.ScheduleEvent(EVENT_LK_SUMMON, currentWall == 3 ? 11s : 7500ms); - } - else - me->RemoveAura(SPELL_REMORSELESS_WINTER); - if (Creature* c = instance->GetCreature(NPC_SYLVANAS_PART2)) - c->AI()->DoAction(ACTION_INFORM_WALL_DESTROYED); - } + events.ScheduleEvent(EVENT_LK_SUMMON_NEXT_ICE_WALL, 1s); + events.ScheduleEvent(EVENT_LK_SUMMON, currentWall == 3 ? 11s : 7500ms); } + else + me->RemoveAura(SPELL_REMORSELESS_WINTER); + if (Creature* c = instance->GetCreature(NPC_SYLVANAS_PART2)) + c->AI()->DoAction(ACTION_INFORM_WALL_DESTROYED); } void MovementInform(uint32 type, uint32 /*id*/) override @@ -1569,17 +1566,14 @@ struct npc_hor_lich_king : public NullCreatureAI else if (currentWall == 4) { Talk(SAY_LK_NOWHERE_TO_RUN); - instance->SetData(DATA_LICH_KING, DONE); + instance->SetBossState(DATA_LICH_KING, DONE); } } } void JustSummoned(Creature* s) override { - - ++reqKillCount; - if (events.HasTimeUntilEvent(EVENT_DECREASE_REQ_COUNT_BY_100)) - events.RescheduleEvent(EVENT_DECREASE_REQ_COUNT_BY_100, 10s); + ++summonsCount; summons.Summon(s); s->SetHomePosition(PathWaypoints[WP_STOP[currentWall + 1]]); s->GetMotionMaster()->MovePoint(0, PathWaypoints[WP_STOP[currentWall + 1]]); @@ -1592,6 +1586,14 @@ struct npc_hor_lich_king : public NullCreatureAI s->SetHomePosition(PathWaypoints[WP_STOP[currentWall + 1]]); } + void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override + { + if (!summonsCount) + return; + if (--summonsCount == 0) + WallCompleted(); + } + void SummonedCreatureDespawn(Creature* s) override { summons.Despawn(s); @@ -1623,7 +1625,7 @@ struct npc_hor_lich_king : public NullCreatureAI { me->GetMotionMaster()->MovementExpired(); me->StopMoving(); - reqKillCount = 255; + summonsCount = 255; leader->InterruptNonMeleeSpells(true); me->CastSpell(leader, SPELL_HARVEST_SOUL); events.ScheduleEvent(EVENT_LK_KILL_LEADER, 3s); @@ -1720,15 +1722,6 @@ struct npc_hor_lich_king : public NullCreatureAI events.ScheduleEvent(EVENT_LK_SUMMON_LA, 17s + 700ms); break; } - if (currentWall <= 3) - { - reqKillCount = 100; - events.RescheduleEvent(EVENT_DECREASE_REQ_COUNT_BY_100, 10s); - } - break; - case EVENT_DECREASE_REQ_COUNT_BY_100: - reqKillCount = (reqKillCount <= 100 ? 0 : reqKillCount - 100); - DoAction(ACTION_CHECK_TRASH_DIED); break; case EVENT_LK_SUMMON_GHOULS: DoCastAOE(SPELL_SUMMON_RAGING_GHOULS); @@ -2003,9 +1996,6 @@ struct npc_hor_raging_ghoul : public ScriptedAI void JustDied(Unit* /*killer*/) override { me->SetCorpseDelay(10); - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* lichKing = instance->GetCreature(NPC_LICH_KING_BOSS)) - lichKing->AI()->DoAction(ACTION_INFORM_TRASH_DIED); } }; @@ -2059,9 +2049,6 @@ struct npc_hor_risen_witch_doctor : public ScriptedAI void JustDied(Unit* /*killer*/) override { me->SetCorpseDelay(10); - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* lichKing = instance->GetCreature(NPC_LICH_KING_BOSS)) - lichKing->AI()->DoAction(ACTION_INFORM_TRASH_DIED); } }; @@ -2110,9 +2097,6 @@ struct npc_hor_lumbering_abomination : public ScriptedAI void JustDied(Unit* /*killer*/) override { me->SetCorpseDelay(10); - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* lichKing = instance->GetCreature(NPC_LICH_KING_BOSS)) - lichKing->AI()->DoAction(ACTION_INFORM_TRASH_DIED); } }; diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h index dfd4c93c5..363d1d17e 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h @@ -27,14 +27,22 @@ enum Data { - DATA_INTRO, + // Boss encounters (indices for SetBossState) DATA_FALRIC, DATA_MARWYN, + DATA_LICH_KING, + MAX_ENCOUNTER, + + // Non-boss data (SetData/GetData only) + DATA_INTRO, DATA_FROSTSWORN_GENERAL, DATA_LK_INTRO, - DATA_LICH_KING, DATA_BATTERED_HILT, - MAX_ENCOUNTER, + DATA_WAVE_NUMBER, + DATA_LK_BATTLE, + DATA_SHIP_CAPTAIN, + + // Actions ACTION_SHOW_TRASH, ACTION_SPIRITUAL_REFLECTIONS_COPY, ACTION_SPIRITUAL_REFLECTIONS_ACTIVATE, @@ -42,9 +50,6 @@ enum Data ACTION_START_LK_FIGHT, ACTION_STOP_LK_FIGHT, ACTION_DELETE_ICE_WALL, - DATA_WAVE_NUMBER, - DATA_LK_BATTLE,// in progress - DATA_SHIP_CAPTAIN, }; enum Creatures @@ -249,8 +254,6 @@ enum hMisc ACTION_START_INTRO, ACTION_SKIP_INTRO, ACTION_START_LK_FIGHT_REAL, - ACTION_INFORM_TRASH_DIED, - ACTION_CHECK_TRASH_DIED, ACTION_INFORM_WALL_DESTROYED, QUEST_DELIVRANCE_FROM_THE_PIT_A2 = 24710, diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp index a1bd4554e..9d235c7b9 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp @@ -468,6 +468,7 @@ public: leader->AI()->DoAction(ACTION_START_INTRO); break; case ACTION_START_LK_FIGHT: + SetBossState(DATA_LICH_KING, IN_PROGRESS); _isLichKingFightActive = true; DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_RETREATING_TIMED_EVENT); DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_RETREATING_TIMED_EVENT); @@ -516,15 +517,13 @@ public: lichKing->SetSpeed(MOVE_RUN, lichKing->GetCreatureTemplate()->speed_run); } _isLichKingFightActive = false; + SetBossState(DATA_LICH_KING, FAIL); _outroTimer = 0; _outroStep = 0; [[fallthrough]]; case ACTION_DELETE_ICE_WALL: HandleGameObject(GO_ICE_WALL, true); break; - case DATA_LICH_KING: - SetBossState(DATA_LICH_KING, static_cast(data)); - break; case DATA_BATTERED_HILT: { if (GetPersistentData(PERSISTENT_DATA_BATTERED_HILT))