From fda4efbc5832879910f923d4967474ba041f1bbd Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 14 Mar 2026 13:54:32 -0300 Subject: [PATCH] fix(Scripts/EoE): fix Malygos Phase 3 Surge of Power warning (#25084) Co-authored-by: Trista Co-authored-by: Claude Opus 4.6 --- .../rev_1710432000000000000.sql | 5 + .../Nexus/EyeOfEternity/boss_malygos.cpp | 192 ++++++++++++++---- 2 files changed, 160 insertions(+), 37 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1710432000000000000.sql diff --git a/data/sql/updates/pending_db_world/rev_1710432000000000000.sql b/data/sql/updates/pending_db_world/rev_1710432000000000000.sql new file mode 100644 index 000000000..254e0b5d3 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1710432000000000000.sql @@ -0,0 +1,5 @@ +-- +DELETE FROM `spell_script_names` WHERE `spell_id` IN (60936, 60939); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(60936, 'spell_malygos_surge_of_power_25'), +(60939, 'spell_malygos_surge_of_power_warning_selector_25'); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 2f228e856..0829623ba 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -16,6 +16,7 @@ */ #include "CombatAI.h" +#include "Containers.h" #include "CreatureScript.h" #include "GameObjectAI.h" #include "GameObjectScript.h" @@ -72,7 +73,7 @@ enum MalygosSpells SPELL_ARCANE_OVERLOAD_SIZE = 56435, SPELL_ARCANE_OVERLOAD_PROTECTION = 56438, - SPELL_SURGE_OF_POWER = 56505, // no heroic version? + SPELL_SURGE_OF_POWER = 56505, SPELL_SURGE_OF_POWER_DMG = 56548, SPELL_DESTROY_PLATFORM_EFFECT = 59099, @@ -80,6 +81,10 @@ enum MalygosSpells SPELL_ARCANE_PULSE = 57432, SPELL_PH3_SURGE_OF_POWER = 57407, + SPELL_PH3_SURGE_OF_POWER_25 = 60936, + SPELL_SURGE_OF_POWER_WARN_SELECTOR_25 = 60939, + + SPELL_RIDE_RED_DRAGON_BUDDY = 56071, SPELL_STATIC_FIELD_MAIN = 57430, SPELL_STATIC_FIELD_SUMMON = 57431, @@ -168,6 +173,12 @@ enum Texts SAY_ALEXSTRASZA_FOUR = 3, }; +enum MalygosData +{ + DATA_FIRST_SURGE_TARGET_GUID = 14, + NUM_MAX_SURGE_TARGETS = 3, +}; + enum Phases { PHASE_NONE = 0, @@ -196,12 +207,7 @@ struct boss_malygos : public BossAI uint8 IntroCounter; bool bLockHealthCheck; bool _executingVortex; - - void InitializeAI() override - { - me->SetDisableGravity(true); - Reset(); - } + ObjectGuid _surgeTargetGUID[NUM_MAX_SURGE_TARGETS]; void Reset() override { @@ -212,17 +218,32 @@ struct boss_malygos : public BossAI IntroCounter = 0; bLockHealthCheck = false; _executingVortex = false; + for (uint8 i = 0; i < NUM_MAX_SURGE_TARGETS; ++i) + _surgeTargetGUID[i].Clear(); SetInvincibility(true); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE); - + me->SetDisableGravity(true); me->SetAnimTier(AnimTier::Fly); instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_YOU_DONT_HAVE_AN_ENTERNITY_EVENT); } + void SetGUID(ObjectGuid const& guid, int32 id) override + { + if (id >= DATA_FIRST_SURGE_TARGET_GUID && id < DATA_FIRST_SURGE_TARGET_GUID + NUM_MAX_SURGE_TARGETS) + _surgeTargetGUID[id - DATA_FIRST_SURGE_TARGET_GUID] = guid; + } + + ObjectGuid GetGUID(int32 id) const override + { + if (id >= DATA_FIRST_SURGE_TARGET_GUID && id < DATA_FIRST_SURGE_TARGET_GUID + NUM_MAX_SURGE_TARGETS) + return _surgeTargetGUID[id - DATA_FIRST_SURGE_TARGET_GUID]; + return ObjectGuid::Empty; + } + void MovementInform(uint32 type, uint32 id) override { if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) @@ -653,10 +674,37 @@ struct boss_malygos : public BossAI events.Repeat(12s); break; case EVENT_SPELL_PH3_SURGE_OF_POWER: - me->CastSpell((Unit*)nullptr, SPELL_PH3_SURGE_OF_POWER, false); + { + if (Is25ManRaid()) + { + for (uint8 i = 0; i < NUM_MAX_SURGE_TARGETS; ++i) + _surgeTargetGUID[i].Clear(); + me->CastSpell((Unit*)nullptr, SPELL_SURGE_OF_POWER_WARN_SELECTOR_25, true); + me->m_Events.AddEventAtOffset([this] + { + me->CastSpell((Unit*)nullptr, SPELL_PH3_SURGE_OF_POWER_25, true); + }, 3s); + } + else + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, false, true, SPELL_RIDE_RED_DRAGON_BUDDY)) + { + if (Vehicle* vehicle = target->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + if (Player* player = passenger->ToPlayer()) + Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, player); + ObjectGuid targetGuid = target->GetGUID(); + me->m_Events.AddEventAtOffset([this, targetGuid] + { + if (Unit* delayedTarget = ObjectAccessor::GetUnit(*me, targetGuid)) + me->CastSpell(delayedTarget, SPELL_PH3_SURGE_OF_POWER, true); + }, 3s); + } + } events.Repeat(7s); break; } + } DoMeleeAttackIfReady(); } @@ -1211,42 +1259,19 @@ class spell_malygos_vortex_visual : public AuraScript } }; +// 57407 - Surge of Power (Phase 3 - 10-man) class spell_eoe_ph3_surge_of_power : public SpellScript { PrepareSpellScript(spell_eoe_ph3_surge_of_power); - ObjectGuid DrakeGUID[3]; - - bool Load() override - { - if (Unit* caster = GetCaster()) - if (Creature* creature = caster->ToCreature()) - { - uint8 i = 0; - std::list drakes; - creature->AI()->SelectTargetList(drakes, (creature->GetMap()->GetSpawnMode() == 0 ? 1 : 3), SelectTargetMethod::Random, 0, 0.0f, false, true, 57403 /*only drakes have this aura*/); - for (std::list::iterator itr = drakes.begin(); itr != drakes.end() && i < 3; ++itr) - { - DrakeGUID[i++] = (*itr)->GetGUID(); - if (Vehicle* vehicle = (*itr)->GetVehicleKit()) - if (Unit* passenger = vehicle->GetPassenger(0)) - if (Player* player = passenger->ToPlayer()) - creature->AI()->Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, player); - } - } - - return true; - } - void FilterTargets(std::list& targets) { - if (Unit* caster = GetCaster()) + // Target selection and warning are handled in boss AI. + // Here we just restrict area targets to the explicit cast target. + if (Unit* explTarget = GetExplTargetUnit()) { targets.clear(); - for (uint8 i = 0; i < 3; ++i) - if (DrakeGUID[i]) - if (Unit* u = ObjectAccessor::GetUnit(*caster, DrakeGUID[i])) - targets.push_back(u); + targets.push_back(explTarget); } } @@ -1256,6 +1281,97 @@ class spell_eoe_ph3_surge_of_power : public SpellScript } }; +// 60939 - Surge of Power (Warning Selector - 25-man) +class spell_malygos_surge_of_power_warning_selector_25 : public SpellScript +{ + PrepareSpellScript(spell_malygos_surge_of_power_warning_selector_25); + + bool Load() override + { + return GetCaster()->IsCreature(); + } + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_PH3_SURGE_OF_POWER_25 }); + } + + void SendThreeTargets(std::list& targets) + { + Creature* caster = GetCaster()->ToCreature(); + + // Keep only creatures with vehicle kits (drakes) + targets.remove_if([](WorldObject* target) + { + Creature* creature = target->ToCreature(); + return !creature || !creature->GetVehicleKit(); + }); + + if (targets.empty()) + return; + + Acore::Containers::RandomResize(targets, NUM_MAX_SURGE_TARGETS); + + uint8 guidDataSlot = DATA_FIRST_SURGE_TARGET_GUID; + for (WorldObject* obj : targets) + { + Creature* target = obj->ToCreature(); + caster->AI()->SetGUID(target->GetGUID(), guidDataSlot++); + + if (Vehicle* vehicle = target->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + if (Player* player = passenger->ToPlayer()) + caster->AI()->Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, player); + } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_malygos_surge_of_power_warning_selector_25::SendThreeTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } +}; + +// 60936 - Surge of Power (Phase 3 - 25-man) +class spell_malygos_surge_of_power_25 : public SpellScript +{ + PrepareSpellScript(spell_malygos_surge_of_power_25); + + bool Load() override + { + return GetCaster()->IsCreature(); + } + + void FilterTargets(std::list& targets) + { + Creature* caster = GetCaster()->ToCreature(); + + for (auto itr = targets.begin(); itr != targets.end();) + { + bool found = false; + + for (uint8 i = DATA_FIRST_SURGE_TARGET_GUID; + i < DATA_FIRST_SURGE_TARGET_GUID + NUM_MAX_SURGE_TARGETS; ++i) + { + if ((*itr)->GetGUID() == caster->AI()->GetGUID(i)) + { + found = true; + break; + } + } + + if (!found) + targets.erase(itr++); + else + ++itr; + } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_malygos_surge_of_power_25::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } +}; + // 56070 - Summon Red Dragon Buddy class spell_wyrmrest_skytalon_summon_red_dragon_buddy : public SpellScript { @@ -1310,6 +1426,8 @@ void AddSC_boss_malygos() RegisterSpellScript(spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger); RegisterSpellScript(spell_eoe_ph3_surge_of_power); + RegisterSpellScript(spell_malygos_surge_of_power_warning_selector_25); + RegisterSpellScript(spell_malygos_surge_of_power_25); RegisterSpellScript(spell_malygos_vortex_dummy); RegisterSpellScript(spell_malygos_vortex_visual); }