diff --git a/data/sql/updates/pending_db_world/rev_1785678970043008400.sql b/data/sql/updates/pending_db_world/rev_1785678970043008400.sql new file mode 100644 index 0000000000..4733706dfd --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1785678970043008400.sql @@ -0,0 +1,3 @@ +-- +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_hodir_shatter_chest', 'spell_hodir_shatter_chest_timer_aura'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (65272, 'spell_hodir_shatter_chest_timer_aura'); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index 71ccf0fbc8..201d2cd0a3 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -46,6 +46,7 @@ enum HodirSpellData SPELL_SAFE_AREA = 65705, SPELL_SAFE_AREA_TRIGGERED = 62464, SPELL_SHATTER_CHEST = 62501, + SPELL_SHATTER_CHEST_TIMER = 65272, SPELL_ICICLE_BOSS_AURA = 62227, SPELL_ICICLE_TBBA = 63545, @@ -123,8 +124,6 @@ enum HodirEvents EVENT_FREEZE = 4, EVENT_SMALL_ICICLES_ENABLE = 5, EVENT_HARD_MODE_MISSED = 6, - EVENT_DESPAWN_CHEST = 7, - EVENT_FAIL_HM = 8, EVENT_TRY_FREE_HELPER = 10, EVENT_PRIEST_DISPELL_MAGIC = 11, @@ -258,12 +257,13 @@ struct boss_hodir : public BossAI void JustEngagedWith(Unit* /*who*/) override { me->CastSpell(me, SPELL_BITING_COLD_BOSS_AURA, true); + // Hard mode timer: periodic dummy aura whose tick shatters the Rare Cache (sniffed on retail) + me->CastSpell(me, SPELL_SHATTER_CHEST_TIMER, true); SmallIcicles(true); events.Reset(); events.ScheduleEvent(EVENT_FLASH_FREEZE, 48s, 49s); events.ScheduleEvent(EVENT_FREEZE, 17s, 20s); events.ScheduleEvent(EVENT_BERSERK, 8min); - events.ScheduleEvent(EVENT_HARD_MODE_MISSED, 3min); Talk(TEXT_AGGRO); // Helpers spawn IMMUNE_TO_NPC so idle bosses (e.g. Freya's Ground Tremor, #26330) can't tag @@ -289,14 +289,13 @@ struct boss_hodir : public BossAI { switch (action) { - case EVENT_FAIL_HM: + case EVENT_HARD_MODE_MISSED: + Talk(TEXT_HM_MISS); + bAchievCacheRare = false; if (instance) { if (GameObject* go = GetHardmodeChest()) - { - go->SetGoState(GO_STATE_ACTIVE); - events.ScheduleEvent(EVENT_DESPAWN_CHEST, 3s); - } + me->CastSpell(go, SPELL_SHATTER_CHEST, false); } break; } @@ -409,21 +408,6 @@ struct boss_hodir : public BossAI Talk(TEXT_BERSERK); } break; - case EVENT_HARD_MODE_MISSED: - { - Talk(TEXT_HM_MISS); - bAchievCacheRare = false; - if (instance) - { - if (GameObject* go = GetHardmodeChest()) - me->CastSpell(go, SPELL_SHATTER_CHEST, false); - } - } - break; - case EVENT_DESPAWN_CHEST: - if (instance && instance->GetBossState(BOSS_HODIR) != DONE) - instance->SetData(TYPE_HODIR_HM_FAIL, 0); - break; case EVENT_FLASH_FREEZE: { std::list targets; @@ -1225,22 +1209,25 @@ struct npc_ulduar_hodir_mage : public ScriptedAI } }; -class spell_hodir_shatter_chest : public SpellScript +class spell_hodir_shatter_chest_timer_aura : public AuraScript { - PrepareSpellScript(spell_hodir_shatter_chest); + PrepareAuraScript(spell_hodir_shatter_chest_timer_aura); - void DestroyWinterCache(SpellEffIndex effIndex) + bool Validate(SpellInfo const* /*spellInfo*/) override { - PreventHitDefaultEffect(effIndex); + return ValidateSpellInfo({ SPELL_SHATTER_CHEST }); + } - if (Unit* hodir = GetCaster()) - hodir->GetAI()->DoAction(EVENT_FAIL_HM); + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + if (Unit* hodir = GetTarget()) + hodir->GetAI()->DoAction(EVENT_HARD_MODE_MISSED); } void Register() override { - OnEffectHit += SpellEffectFn(spell_hodir_shatter_chest::DestroyWinterCache, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE); - }; + OnEffectPeriodic += AuraEffectPeriodicFn(spell_hodir_shatter_chest_timer_aura::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } }; class spell_hodir_biting_cold_main_aura : public AuraScript @@ -1599,7 +1586,7 @@ void AddSC_boss_hodir() RegisterUlduarCreatureAI(npc_ulduar_hodir_shaman); RegisterUlduarCreatureAI(npc_ulduar_hodir_mage); - RegisterSpellScript(spell_hodir_shatter_chest); + RegisterSpellScript(spell_hodir_shatter_chest_timer_aura); RegisterSpellScript(spell_hodir_biting_cold_main_aura); RegisterSpellScript(spell_hodir_biting_cold_player_aura); RegisterSpellScript(spell_hodir_periodic_icicle); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index c4afe6229e..949ee3242b 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -326,6 +326,18 @@ public: // destory towers if (eventId >= EVENT_TOWER_OF_LIFE_DESTROYED && eventId <= EVENT_TOWER_OF_FLAMES_DESTROYED) SetData(eventId, 0); + else if (eventId == EVENT_HODIR_SHATTER_CHEST) + { + if (GameObject* go = GetHodirChest(true)) + { + go->SetGoState(GO_STATE_ACTIVE); + scheduler.Schedule(3s, [this](TaskContext /*context*/) + { + if (GetBossState(BOSS_HODIR) != DONE) + SetData(TYPE_HODIR_HM_FAIL, 0); + }); + } + } } bool SetBossState(uint32 type, EncounterState state) override diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index f2f294542a..769bb24b54 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -356,6 +356,9 @@ enum UlduarMisc EVENT_TOWER_OF_FLAMES_DESTROYED = 21033, EVENT_TOWER_OF_LIFE_DESTROYED = 21030, + // Sent by Shatter Chest (62502), triggered by Hodir's hard mode timer missile (62501) + EVENT_HODIR_SHATTER_CHEST = 20907, + ACTION_LEVIATHAN_REFRESH_TOWERS = -1, ACTION_TOWER_OF_STORM_DESTROYED = 1, ACTION_TOWER_OF_FROST_DESTROYED = 2,