fix(Scripts/Ulduar): Algalon defeat, wipe recovery, and Brann's pathfinding to him (#26684)

Co-authored-by: Si1ker <61223313+Si1ker@users.noreply.github.com>
Co-authored-by: sogladev <sogladev@gmail.com>
This commit is contained in:
Xepic90
2026-07-25 16:41:21 -04:00
committed by GitHub
parent da5d724ff0
commit e462aef6b0
3 changed files with 134 additions and 69 deletions

View File

@@ -25,6 +25,7 @@
#include "PassiveAI.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "ulduar.h"
@@ -78,7 +79,7 @@ enum Actions
{
//ACTION_INIT_ALGALON = 1, defined in ulduar.h
//ACTION_DESPAWN_ALGALON = 2, defined in ulduar.h
ACTION_START_INTRO = 3,
//ACTION_START_INTRO = 3, defined in ulduar.h
ACTION_FINISH_INTRO = 4,
ACTION_ACTIVATE_STAR = 5,
ACTION_BIG_BANG = 6,
@@ -95,6 +96,7 @@ enum Misc
POINT_ALGALON_LAND = 1,
POINT_ALGALON_OUTRO = 2,
POINT_ALGALON_FLOAT = 3,
EVENT_ID_SUPERMASSIVE_START = 21697,
@@ -112,46 +114,51 @@ enum Events
EVENT_SUMMON_ALGALON = 3,
EVENT_BRANN_OUTRO_1 = 4,
EVENT_BRANN_OUTRO_2 = 5,
EVENT_BRANN_REACH_TALK_POINT = 6,
// Algalon the Observer
EVENT_INTRO_1 = 6,
EVENT_INTRO_2 = 7,
EVENT_INTRO_3 = 8,
EVENT_INTRO_FINISH = 9,
EVENT_SAY_ALGALON_AGGRO = 10,
EVENT_INTRO_TIMER_DONE = 11,
EVENT_QUANTUM_STRIKE = 12,
EVENT_PHASE_PUNCH = 13,
EVENT_SUMMON_COLLAPSING_STAR = 14,
EVENT_BIG_BANG = 15,
EVENT_RESUME_UPDATING = 16,
EVENT_ASCEND_TO_THE_HEAVENS = 17,
EVENT_EVADE = 18,
EVENT_COSMIC_SMASH = 19,
EVENT_UNLOCK_YELL = 20,
EVENT_OUTRO_START = 21,
EVENT_OUTRO_1 = 22,
EVENT_OUTRO_2 = 23,
EVENT_OUTRO_3 = 24,
EVENT_OUTRO_4 = 25,
EVENT_OUTRO_5 = 26,
EVENT_OUTRO_6 = 27,
EVENT_OUTRO_7 = 28,
EVENT_OUTRO_8 = 29,
EVENT_OUTRO_9 = 30,
EVENT_OUTRO_10 = 31,
EVENT_OUTRO_11 = 32,
EVENT_ACTIVATE_LIVING_CONSTELLATION = 33,
EVENT_CHECK_HERALD_ITEMS = 34,
EVENT_ALGALON_IN_PROGRESS = 35,
EVENT_DESPAWN_ALGALON_1 = 36,
EVENT_DESPAWN_ALGALON_2 = 37,
EVENT_DESPAWN_ALGALON_3 = 38,
EVENT_DESPAWN_ALGALON_4 = 39,
EVENT_DESPAWN_ALGALON_5 = 40,
EVENT_INTRO_1 = 7,
EVENT_INTRO_2 = 8,
EVENT_INTRO_3 = 9,
EVENT_INTRO_FINISH = 10,
EVENT_SAY_ALGALON_AGGRO = 11,
EVENT_INTRO_TIMER_DONE = 12,
EVENT_QUANTUM_STRIKE = 13,
EVENT_PHASE_PUNCH = 14,
EVENT_SUMMON_COLLAPSING_STAR = 15,
EVENT_BIG_BANG = 16,
EVENT_RESUME_UPDATING = 17,
EVENT_ASCEND_TO_THE_HEAVENS = 18,
EVENT_EVADE = 19,
EVENT_COSMIC_SMASH = 20,
EVENT_UNLOCK_YELL = 21,
EVENT_OUTRO_START = 22,
EVENT_OUTRO_1 = 23,
EVENT_OUTRO_2 = 24,
EVENT_OUTRO_3 = 25,
EVENT_OUTRO_4 = 26,
EVENT_OUTRO_5 = 27,
EVENT_OUTRO_6 = 28,
EVENT_OUTRO_7 = 29,
EVENT_OUTRO_8 = 30,
EVENT_OUTRO_9 = 31,
EVENT_OUTRO_10 = 32,
EVENT_OUTRO_11 = 33,
EVENT_ACTIVATE_LIVING_CONSTELLATION = 34,
EVENT_CHECK_HERALD_ITEMS = 35,
EVENT_ALGALON_IN_PROGRESS = 36,
EVENT_DESPAWN_ALGALON_1 = 37,
EVENT_DESPAWN_ALGALON_2 = 38,
EVENT_DESPAWN_ALGALON_3 = 39,
EVENT_DESPAWN_ALGALON_4 = 40,
EVENT_DESPAWN_ALGALON_5 = 41,
EVENT_INTRO_CHANNEL = 42,
EVENT_INTRO_SUMMON = 43,
EVENT_INTRO_DESCEND = 44,
// Living Constellation
EVENT_ARCANE_BARRAGE = 41,
EVENT_ARCANE_BARRAGE = 45,
};
enum EncounterPhases
@@ -204,7 +211,7 @@ Position const BrannIntroWaypoint[MAX_BRANN_WAYPOINTS_INTRO] =
{1632.676f, -190.5927f, 427.2631f, 0.0f},
{1631.497f, -214.2221f, 418.1152f, 0.0f},
{1636.455f, -263.6647f, 417.3213f, 0.0f},
{1629.586f, -267.9792f, 417.3219f, 0.0f},
{1624.1223f, -267.04172f, 417.3216f, 4.7690268f},
{1631.497f, -214.2221f, 418.1152f, 0.0f},
{1632.676f, -190.5927f, 425.8831f, 0.0f},
{1632.814f, -173.9334f, 427.2621f, 0.0f},
@@ -235,7 +242,8 @@ Position const CollapsingStarPos[COLLAPSING_STAR_COUNT] =
{1622.451f, -321.1563f, 417.6188f, 4.677482f},
{1615.060f, -291.6816f, 417.7796f, 3.490659f},
};
Position const AlgalonOutroPos = {1633.64f, -317.78f, 417.3211f, 0.0f};
Position const AlgalonOutroPos = {1633.64f, -317.78f, 417.3211f, 1.605703f};
Position const AlgalonFloatPos = {1632.668f, -302.7656f, 420.3211f, 1.530165f};
Position const BrannOutroPos[3] =
{
{1632.023f, -243.7434f, 417.9118f, 0.0f},
@@ -369,7 +377,14 @@ struct boss_algalon_the_observer : public ScriptedAI
if (_instance)
_instance->SetBossState(BOSS_ALGALON, FAIL);
ScriptedAI::EnterEvadeMode(why);
if (!_EnterEvadeMode(why))
return;
me->GetMotionMaster()->MoveTargetedHome();
Reset();
sScriptMgr->OnUnitEnterEvadeMode(me, why);
}
void Reset() override
@@ -392,6 +407,8 @@ struct boss_algalon_the_observer : public ScriptedAI
{
_firstPull = false;
_instance->StorePersistentData(PERSISTENT_DATA_ALGALON_FIRST_PULL, 1);
_instance->SetData(DATA_RESUMMON_ALGALON, 0);
me->DespawnOrUnsummon(1ms);
}
_instance->SetBossState(BOSS_ALGALON, NOT_STARTED);
}
@@ -416,15 +433,14 @@ struct boss_algalon_the_observer : public ScriptedAI
me->SetDisableGravity(true);
me->CastSpell(me, SPELL_ARRIVAL, true);
me->CastSpell(me, SPELL_RIDE_THE_LIGHTNING, true);
me->GetMotionMaster()->MovePoint(POINT_ALGALON_LAND, AlgalonLandPos);
me->GetMotionMaster()->MovePoint(POINT_ALGALON_FLOAT, AlgalonFloatPos);
me->SetHomePosition(AlgalonLandPos);
Movement::MoveSplineInit init(me);
init.MoveTo(AlgalonLandPos.GetPositionX(), AlgalonLandPos.GetPositionY(), AlgalonLandPos.GetPositionZ());
init.SetOrientationFixed(true);
init.Launch();
events.Reset();
events.SetPhase(PHASE_ROLE_PLAY);
events.ScheduleEvent(EVENT_INTRO_1, 5s, 0, PHASE_ROLE_PLAY);
events.ScheduleEvent(EVENT_INTRO_CHANNEL, 6s, 0, PHASE_ROLE_PLAY);
events.ScheduleEvent(EVENT_INTRO_SUMMON, 7s, 0, PHASE_ROLE_PLAY);
events.ScheduleEvent(EVENT_INTRO_DESCEND, 10s, 0, PHASE_ROLE_PLAY);
events.ScheduleEvent(EVENT_INTRO_2, 15s, 0, PHASE_ROLE_PLAY);
events.ScheduleEvent(EVENT_INTRO_3, 23s, 0, PHASE_ROLE_PLAY);
events.ScheduleEvent(EVENT_INTRO_FINISH, 36s, 0, PHASE_ROLE_PLAY);
@@ -525,18 +541,7 @@ struct boss_algalon_the_observer : public ScriptedAI
if (pointId == POINT_ALGALON_LAND)
me->SetDisableGravity(false);
else if (pointId == POINT_ALGALON_OUTRO)
{
me->SetFacingTo(1.605703f);
events.ScheduleEvent(EVENT_OUTRO_3, 1200ms);
events.ScheduleEvent(EVENT_OUTRO_4, 2400ms);
events.ScheduleEvent(EVENT_OUTRO_5, 8500ms);
events.ScheduleEvent(EVENT_OUTRO_6, 15s + 500ms);
events.ScheduleEvent(EVENT_OUTRO_7, 55s + 500ms);
events.ScheduleEvent(EVENT_OUTRO_8, 73s + 500ms);
events.ScheduleEvent(EVENT_OUTRO_9, 85s + 500ms);
events.ScheduleEvent(EVENT_OUTRO_10, 111s);
events.ScheduleEvent(EVENT_OUTRO_11, 117s + 500ms);
}
me->SetFacingTo(AlgalonOutroPos.GetOrientation());
}
void JustSummoned(Creature* summon) override
@@ -645,14 +650,26 @@ struct boss_algalon_the_observer : public ScriptedAI
{
case EVENT_INTRO_1:
me->RemoveAurasDueToSpell(SPELL_RIDE_THE_LIGHTNING);
Talk(SAY_ALGALON_INTRO_1);
if (_firstPull)
Talk(SAY_ALGALON_INTRO_1);
break;
case EVENT_INTRO_CHANNEL:
me->SetEmoteState(EMOTE_STATE_SPELL_CHANNEL_OMNI);
break;
case EVENT_INTRO_SUMMON:
me->CastSpell((Unit*)nullptr, SPELL_SUMMON_AZEROTH, true);
me->ClearEmoteState();
break;
case EVENT_INTRO_DESCEND:
me->GetMotionMaster()->MovePoint(POINT_ALGALON_LAND, AlgalonLandPos);
break;
case EVENT_INTRO_2:
me->CastSpell((Unit*)nullptr, SPELL_SUMMON_AZEROTH, true);
Talk(SAY_ALGALON_INTRO_2);
if (_firstPull)
Talk(SAY_ALGALON_INTRO_2);
break;
case EVENT_INTRO_3:
Talk(SAY_ALGALON_INTRO_3);
if (_firstPull)
Talk(SAY_ALGALON_INTRO_3);
break;
case EVENT_INTRO_FINISH:
events.Reset();
@@ -755,9 +772,20 @@ struct boss_algalon_the_observer : public ScriptedAI
{
Player* lootRecipent = me->GetLootRecipient();
_EnterEvadeMode();
me->ClearUnitState(UNIT_STATE_EVADE);
// LootRecipent is cleared in _EnterEvadeMode, restore it
me->SetLootRecipient(lootRecipent);
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MovePoint(POINT_ALGALON_OUTRO, AlgalonOutroPos);
events.ScheduleEvent(EVENT_OUTRO_3, 3200ms);
events.ScheduleEvent(EVENT_OUTRO_4, 4400ms);
events.ScheduleEvent(EVENT_OUTRO_5, 10500ms);
events.ScheduleEvent(EVENT_OUTRO_6, 17s + 500ms);
events.ScheduleEvent(EVENT_OUTRO_7, 57s + 500ms);
events.ScheduleEvent(EVENT_OUTRO_8, 75s + 500ms);
events.ScheduleEvent(EVENT_OUTRO_9, 87s + 500ms);
events.ScheduleEvent(EVENT_OUTRO_10, 113s);
events.ScheduleEvent(EVENT_OUTRO_11, 119s + 500ms);
break;
}
case EVENT_OUTRO_3:
@@ -869,16 +897,12 @@ struct npc_brann_bronzebeard_algalon : public CreatureAI
delay = 8s;
me->SetWalk(true);
break;
case 6:
me->SetFacingTo(4.6156f);
me->SetWalk(false);
Talk(SAY_BRANN_ALGALON_INTRO_1);
events.ScheduleEvent(EVENT_SUMMON_ALGALON, 7500ms);
return;
case 10:
me->DespawnOrUnsummon(1ms);
return;
case POINT_BRANN_OUTRO:
me->SetFacingTo(4.6528215f);
return;
case POINT_BRANN_OUTRO_END:
return;
}
@@ -895,7 +919,32 @@ struct npc_brann_bronzebeard_algalon : public CreatureAI
{
case EVENT_BRANN_MOVE_INTRO:
if (_currentPoint < MAX_BRANN_WAYPOINTS_INTRO)
me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]);
{
if (_currentPoint == 5 || _currentPoint == 6)
{
Position const& dest = BrannIntroWaypoint[_currentPoint];
Milliseconds travelTime = Milliseconds(uint32(me->GetExactDist2d(dest) / 2.5f * 1000)) + 500ms;
Movement::MoveSplineInit init(me);
init.MoveTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
init.Launch();
if (_currentPoint == 6)
events.ScheduleEvent(EVENT_BRANN_REACH_TALK_POINT, travelTime);
else
{
_currentPoint = 6;
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, travelTime);
}
}
else
me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]);
}
break;
case EVENT_BRANN_REACH_TALK_POINT:
_currentPoint = 7;
me->SetFacingTo(4.7760954f);
me->SetWalk(false);
Talk(SAY_BRANN_ALGALON_INTRO_1);
events.ScheduleEvent(EVENT_SUMMON_ALGALON, 7500ms);
break;
case EVENT_SUMMON_ALGALON:
if (me->GetInstanceScript() && !me->GetInstanceScript()->GetCreature(BOSS_ALGALON))

View File

@@ -219,6 +219,7 @@ public:
// Shared
EventMap _events;
bool _mimironTramUsed;
bool _algalonResummonPending;
void Initialize() override
{
@@ -234,6 +235,7 @@ public:
// Shared
_events.Reset();
_mimironTramUsed = false;
_algalonResummonPending = false;
}
void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& packet) override
@@ -279,7 +281,7 @@ public:
uint32 algalonTimer =
GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER);
if (!GetObjectGuid(BOSS_ALGALON) && algalonTimer
if (!GetObjectGuid(BOSS_ALGALON) && !_algalonResummonPending && algalonTimer
&& (algalonTimer <= 60
|| algalonTimer == TIMER_ALGALON_TO_SUMMON))
{
@@ -708,6 +710,10 @@ public:
StorePersistentData(PERSISTENT_DATA_ALGALON_TIMER, 60);
_events.RescheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 1min);
return;
case DATA_RESUMMON_ALGALON:
_algalonResummonPending = true;
_events.RescheduleEvent(EVENT_RESUMMON_ALGALON, 2s);
return;
case DATA_ALGALON_SUMMON_STATE:
case DATA_ALGALON_DEFEATED:
DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_TIMER_ENABLED, 0);
@@ -931,7 +937,14 @@ public:
SetData(DATA_ALGALON_DEFEATED, 1);
if (Creature* algalon = GetCreature(BOSS_ALGALON))
algalon->AI()->DoAction(ACTION_DESPAWN_ALGALON);
break;
}
case EVENT_RESUMMON_ALGALON:
_algalonResummonPending = false;
if (!GetCreature(BOSS_ALGALON))
if (Creature* algalon = instance->SummonCreature(NPC_ALGALON, AlgalonSummonPos))
algalon->AI()->DoAction(ACTION_START_INTRO);
break;
}
}

View File

@@ -111,6 +111,7 @@ enum UlduarData
DATA_UNIVERSE_GLOBE = 608,
DATA_ALGALON_TRAPDOOR = 609,
DATA_BRANN_BRONZEBEARD_ALG = 610,
DATA_RESUMMON_ALGALON = 611,
// Achievements
DATA_DWARFAGEDDON = 700,
@@ -362,9 +363,11 @@ enum UlduarMisc
ACTION_TOWER_OF_LIFE_DESTROYED = 4,
EVENT_UPDATE_ALGALON_TIMER = 1,
EVENT_RESUMMON_ALGALON = 2,
ACTION_FEEDS_ON_TEARS_FAILED = 0,
ACTION_INIT_ALGALON = 1,
ACTION_DESPAWN_ALGALON = 2,
ACTION_START_INTRO = 3,
TIMER_ALGALON_DEFEATED = 300,
TIMER_ALGALON_TO_SUMMON = 200,