diff --git a/data/sql/updates/pending_db_world/rev_1716230497379077638.sql b/data/sql/updates/pending_db_world/rev_1716230497379077638.sql new file mode 100644 index 000000000..f773a2a9c --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1716230497379077638.sql @@ -0,0 +1,20 @@ +-- +-- Remove encounter auras minus glow aura from Keepers, add glow aura to Gossip Keepers +UPDATE `creature_template_addon` SET `auras` = '62647' WHERE `entry` IN (33410,33411,33412,33413,33213,33241,33242,33244); + +DELETE FROM `spell_script_names` WHERE `spell_id` = 64170; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (64170, 'spell_keeper_freya_summon_sanity_well'); + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (62650,62670,62671,62702); +DELETE FROM `spell_script_names` WHERE `spell_id` = 64174 AND `ScriptName` = 'spell_gen_area_aura_select_players'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(62650, 'spell_gen_area_aura_select_players_and_caster'), +(62670, 'spell_gen_area_aura_select_players_and_caster'), +(62671, 'spell_gen_area_aura_select_players_and_caster'), +(62702, 'spell_gen_area_aura_select_players_and_caster'), +(64174, 'spell_gen_area_aura_select_players'); + +-- Keeper: handle spawns with script +DELETE FROM `creature` WHERE `id1` IN (33213,33241,33242,33244); +-- Keeper: remove not selectable, immune to pc, immune to player; civilian +UPDATE `creature_template` SET `unit_flags` = `unit_flags` & ~(256 | 512 | 33554432), `flags_extra` = `flags_extra` & ~2 WHERE `entry` IN (33410,33411,33412,33413); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 98b178480..27d64a306 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -46,7 +46,6 @@ enum Spells SPELL_COSMIC_SMASH_VISUAL_STATE = 62300, SPELL_SELF_STUN = 65256, SPELL_KILL_CREDIT = 65184, - SPELL_TELEPORT = 62940, SPELL_DUAL_WIELD = 42459, // Algalon Stalker diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 4d3610adb..80694a911 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -347,7 +347,6 @@ public: uint32 chestId = RAID_MODE(GO_FREYA_CHEST, GO_FREYA_CHEST_HERO); chestId -= 2 * _elderCount; // offset - me->DespawnOrUnsummon(5000); if (GameObject* go = me->SummonGameObject(chestId, 2345.61f, -71.20f, 425.104f, 3.0f, 0, 0, 0, 0, 0)) { go->ReplaceAllGameObjectFlags((GameObjectFlags)0); @@ -360,10 +359,24 @@ public: me->CastSpell(me, 65074, true); // credit m_pInstance->SetData(TYPE_FREYA, DONE); } + + scheduler.Schedule(14s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_TELEPORT); + }); } } } + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_TELEPORT) + { + me->DespawnOrUnsummon(); + m_pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE); + } + } + void JustSummoned(Creature* cr) override { if (cr->GetEntry() == NPC_FREYA_UNSTABLE_SUN_BEAM) @@ -547,6 +560,7 @@ public: void UpdateAI(uint32 diff) override { + scheduler.Update(diff); if (!UpdateVictim()) return; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index d3f8de2eb..972763b30 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -346,6 +346,7 @@ public: { pInstance->SetData(TYPE_HODIR, DONE); me->CastSpell(me, 64899, true); // credit + pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BITING_COLD_PLAYER_AURA); } me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); @@ -355,7 +356,6 @@ public: me->CombatStop(); me->InterruptNonMeleeSpells(true); me->RemoveAllAuras(); - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BITING_COLD_PLAYER_AURA); events.Reset(); summons.DespawnAll(); @@ -383,13 +383,17 @@ public: } Talk(TEXT_DEATH); - me->DespawnOrUnsummon(10000); + scheduler.Schedule(14s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_TELEPORT); + }); } } } void UpdateAI(uint32 diff) override { + scheduler.Update(diff); if (me->GetPositionY() <= ENTRANCE_DOOR.GetPositionY() || me->GetPositionY() >= EXIT_DOOR.GetPositionY()) { boss_hodirAI::EnterEvadeMode(); @@ -497,6 +501,15 @@ public: DoMeleeAttackIfReady(); } + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_TELEPORT) + { + me->DespawnOrUnsummon(); + pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE); + } + } + Creature* GetHelper(uint8 index) { return Helpers[index] ? ObjectAccessor::GetCreature(*me, Helpers[index]) : nullptr; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 00ba652b4..dfbc906e0 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -802,12 +802,21 @@ public: case EVENT_DISAPPEAR: if( pInstance ) pInstance->SetData(TYPE_MIMIRON, DONE); + DoCastSelf(SPELL_TELEPORT); summons.DespawnAll(); - me->DespawnOrUnsummon(); break; } } + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_TELEPORT) + { + me->DespawnOrUnsummon(); + pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE); + } + } + void MoveInLineOfSight(Unit* /*mover*/) override {} void EnterEvadeMode(EvadeReason why) override diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp index 5894409be..cf62d6241 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp @@ -197,6 +197,7 @@ enum ThorimEvents EVENT_THORIM_OUTRO1 = 13, EVENT_THORIM_OUTRO2 = 14, EVENT_THORIM_OUTRO3 = 15, + EVENT_THORIM_OUTRO4 = 16, EVENT_DR_ACOLYTE_GH = 20, EVENT_DR_ACOLYTE_HS = 21, @@ -630,6 +631,11 @@ public: me->CastSpell(me, SPELL_LIGHTNING_CHARGE_BUFF, true); events.RescheduleEvent(EVENT_THORIM_LIGHTNING_CHARGE, 10s, 0, EVENT_PHASE_RING); } + else if (spellInfo->Id == SPELL_TELEPORT) + { + me->DespawnOrUnsummon(); + m_pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE); + } } void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override @@ -773,12 +779,13 @@ public: { Talk(SAY_END_NORMAL_3); } - // Defeat credit if (m_pInstance) m_pInstance->SetData(TYPE_THORIM, DONE); - - me->DespawnOrUnsummon(8000); + events.ScheduleEvent(EVENT_THORIM_OUTRO4, 14s, 0, 3); + break; + case EVENT_THORIM_OUTRO4: + DoCastSelf(SPELL_TELEPORT); break; } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp index a064933e3..71e73971b 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp @@ -251,6 +251,8 @@ enum Misc ACTION_ILLUSION_ICECROWN = 2, ACTION_ILLUSION_STORMWIND = 3, + // ACTION_SARA_UPDATE_SUMMON_KEEPERS = 4, // defined in ulduar.h + EVENT_PHASE_ONE = 1, EVENT_PHASE_TWO = 2, EVENT_PHASE_THREE = 3, @@ -271,6 +273,26 @@ struct LocationsXY float x, y, z; }; +Position const GossipKeepersPos[4] = +{ + {1945.6823f, 33.342014f, 411.44083f, 5.270895f}, // Freya + {1945.7609f, -81.52171f, 411.4407f, 1.029744f}, // Hodir + {2028.7656f, 17.42014f, 411.44458f, 3.857178f}, // Mimiron + {2028.8219f, -65.73573f, 411.44257f, 2.460914f} // Thorim +}; + +const Position KeepersPos[4] = +{ + {1939.32f, 42.165f, 338.415f, 5.17955f}, // Freya + {1939.13f, -90.8332f, 338.415f, 1.00123f}, // Hodir + {2036.81f, 25.6646f, 338.415f, 3.74227f}, // Mimiron + {2036.59f, -73.8499f, 338.415f, 2.34819f} // Thorim +}; + +const uint32 TABLE_KEEPER_ENTRY[4] = {NPC_FREYA_KEEPER, NPC_HODIR_KEEPER, NPC_MIMIRON_KEEPER, NPC_THORIM_KEEPER}; +const uint32 TABLE_GOSSIP_ENTRY[4] = {NPC_FREYA_GOSSIP, NPC_HODIR_GOSSIP, NPC_MIMIRON_GOSSIP, NPC_THORIM_GOSSIP}; +const uint32 TABLE_KEEPER_TYPE[4] = {TYPE_FREYA, TYPE_HODIR, TYPE_MIMIRON, TYPE_THORIM}; + static LocationsXY yoggPortalLoc[] = { {1970.48f, -9.75f, 325.5f}, @@ -344,7 +366,6 @@ enum Texts SAY_LK_2 = 1, SAY_YOGG_5 = 3, SAY_YOGG_6 = 4, - }; const Position Middle = {1980.28f, -25.5868f, 329.397f, M_PI * 1.5f}; @@ -371,7 +392,6 @@ public: SummonList summons; uint32 _initFight; - ObjectGuid _keepersGUID[4]; uint8 _summonedGuardiansCount; uint32 _p2TalkTimer; bool _secondPhase; @@ -382,17 +402,9 @@ public: void AttackStart(Unit*) override { } void MoveInLineOfSight(Unit*) override { } - void JustSummoned(Creature* cr) override + void JustSummoned(Creature* summon) override { - summons.Summon(cr); - if (cr->GetEntry() >= NPC_FREYA_KEEPER && cr->GetEntry() <= NPC_THORIM_KEEPER) - { - if (cr->GetEntry() == NPC_FREYA_KEEPER) - cr->CastSpell(cr, SPELL_CONJURE_SANITY_WELL, false); - _keepersGUID[cr->GetEntry() - NPC_FREYA_KEEPER] = cr->GetGUID(); - } - else if (cr->GetEntry() == NPC_SANITY_WELL) - cr->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_SCALE, true); + summons.Summon(summon); } void SpawnClouds() @@ -407,15 +419,6 @@ public: } } - void SpawnWeels() - { - me->SummonCreature(NPC_SANITY_WELL, 2042.56f, -40.3667f, 329.274f, 0.0f); - me->SummonCreature(NPC_SANITY_WELL, 1975.89f, 40.0216f, 331.1f, 0.0f); - me->SummonCreature(NPC_SANITY_WELL, 1987.12f, -91.2702f, 330.186f, 0.0f); - me->SummonCreature(NPC_SANITY_WELL, 1900.48f, -51.2386f, 332.13f, 0.0f); - me->SummonCreature(NPC_SANITY_WELL, 1899.94f, 0.330621f, 332.296f, 0.0f); - } - void EnterEvadeMode(EvadeReason why) override { if (!_EnterEvadeMode(why)) @@ -469,9 +472,7 @@ public: _initFight = 1; - for (uint8 i = 0; i < 4; ++i) - _keepersGUID[i].Clear(); - + UpdateKeeperSpawns(); _summonedGuardiansCount = 0; _p2TalkTimer = 0; _secondPhase = false; @@ -503,9 +504,11 @@ public: me->SetInCombatWithZone(); AttackStart(target); - me->CastSpell(me, SPELL_SANITY_BASE, true); + DespawnGossipKeepers(); + // Engage Keepers + summons.DoZoneInCombat(); - SaveKeepers(); + me->CastSpell(me, SPELL_SANITY_BASE, true); events.ScheduleEvent(EVENT_SARA_P1_DOORS_CLOSE, 15s, 0, EVENT_PHASE_ONE); events.ScheduleEvent(EVENT_SARA_P1_BERSERK, 15min, 0, 0); @@ -516,26 +519,27 @@ public: me->setActive(true); } - void SaveKeepers() + void DespawnGossipKeepers() { - for (uint8 i = 0; i < 4; ++i) + for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++) + summons.DespawnEntry(TABLE_GOSSIP_ENTRY[i]); + } + + void UpdateKeeperSpawns() + { + for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++) + { if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i)) - switch (i) - { - case KEEPER_FREYA: - SpawnWeels(); - me->SummonCreature(NPC_FREYA_KEEPER, 1939.32f, 42.165f, 338.415f, 5.17955f); - break; - case KEEPER_HODIR: - me->SummonCreature(NPC_HODIR_KEEPER, 1939.13f, -90.8332f, 338.415f, 1.00123f); - break; - case KEEPER_MIMIRON: - me->SummonCreature(NPC_MIMIRON_KEEPER, 2036.81f, 25.6646f, 338.415f, 3.74227f); - break; - case KEEPER_THORIM: - me->SummonCreature(NPC_THORIM_KEEPER, 2036.59f, -73.8499f, 338.415f, 2.34819f); - break; - } + { + if (!summons.HasEntry(TABLE_KEEPER_ENTRY[i])) + me->SummonCreature(TABLE_KEEPER_ENTRY[i], KeepersPos[i]); + } + else if (m_pInstance->GetData(TABLE_KEEPER_TYPE[i]) == DONE) + { + if (!summons.HasEntry(TABLE_GOSSIP_ENTRY[i])) + me->SummonCreature(TABLE_GOSSIP_ENTRY[i], GossipKeepersPos[i]); + } + } } void InformCloud() @@ -625,9 +629,8 @@ public: { uint8 _count = 0; for (uint8 i = 0; i < 4; ++i) - if (_keepersGUID[i]) + if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i)) ++_count; - return _count; } else if (param == DATA_GET_SARA_PHASE) @@ -638,7 +641,11 @@ public: void DoAction(int32 param) override { - if (param == ACTION_BRAIN_DAMAGED) + if (param == ACTION_SARA_UPDATE_SUMMON_KEEPERS) + { + UpdateKeeperSpawns(); + } + else if (param == ACTION_BRAIN_DAMAGED) { summons.DoAction(ACTION_REMOVE_STUN); @@ -648,7 +655,7 @@ public: EntryCheckPredicate pred3(NPC_THORIM_KEEPER); summons.DoAction(ACTION_THORIM_START_STORM, pred3); - if (!(_keepersGUID[0] && _keepersGUID[1] && _keepersGUID[2] && _keepersGUID[3]) && me->GetMap()->Is25ManRaid()) + if (me->GetMap()->Is25ManRaid() && (GetData(DATA_GET_KEEPERS_COUNT) > 0)) summons.DoAction(ACTION_YOGG_SARON_HARD_MODE, pred2); summons.DespawnEntry(NPC_DEATH_ORB); @@ -660,8 +667,17 @@ public: } else if (param == ACTION_YOGG_SARON_DEATH) { + // Despawn everything but Yogg-Saron's corpse + summons.DoAction(ACTION_DESPAWN_ADDS); + summons.DespawnEntry(NPC_CRUSHER_TENTACLE); + summons.DespawnEntry(NPC_CONSTRICTOR_TENTACLE); + summons.DespawnEntry(NPC_CORRUPTOR_TENTACLE); summons.DespawnEntry(NPC_VOICE_OF_YOGG_SARON); summons.DespawnEntry(NPC_BRAIN_OF_YOGG_SARON); + summons.DespawnEntry(NPC_MIMIRON_GOSSIP); + summons.DespawnEntry(NPC_HODIR_GOSSIP); + summons.DespawnEntry(NPC_FREYA_GOSSIP); + summons.DespawnEntry(NPC_THORIM_GOSSIP); summons.DespawnEntry(NPC_MIMIRON_KEEPER); summons.DespawnEntry(NPC_HODIR_KEEPER); summons.DespawnEntry(NPC_FREYA_KEEPER); @@ -1709,52 +1725,56 @@ public: }; }; -class boss_yoggsaron_keeper : public CreatureScript +struct boss_yoggsaron_keeper : public NullCreatureAI { -public: - boss_yoggsaron_keeper() : CreatureScript("boss_yoggsaron_keeper") { } + boss_yoggsaron_keeper(Creature* creature) : NullCreatureAI(creature), _summons(creature) { } - CreatureAI* GetAI(Creature* pCreature) const override + void DoAction(int32 param) override { - return GetUlduarAI(pCreature); + if (me->GetEntry() == NPC_THORIM_KEEPER && param == ACTION_THORIM_START_STORM) + me->CastSpell(me, SPELL_TITANIC_STORM_PASSIVE, false); + else if (param == ACTION_DESPAWN_ADDS) + _summons.DespawnAll(); } - struct boss_yoggsaron_keeperAI : public NullCreatureAI + void JustSummoned(Creature* summon) override { - boss_yoggsaron_keeperAI(Creature* pCreature) : NullCreatureAI(pCreature) + _summons.Summon(summon); + } + + void JustEngagedWith(Unit* /*who*/) override + { + switch (me->GetEntry()) { - _checkTimer = 0; - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_SCALE, true); - } - - uint32 _checkTimer; - - void DoAction(int32 param) override - { - if (me->GetEntry() == NPC_THORIM_KEEPER && param == ACTION_THORIM_START_STORM) - me->CastSpell(me, SPELL_TITANIC_STORM_PASSIVE, false); - } - - void UpdateAI(uint32 diff) override - { - if (me->GetInstanceScript()) - if (me->GetInstanceScript()->GetData(TYPE_YOGGSARON) != IN_PROGRESS) - return; - - _checkTimer += diff; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - if (me->GetEntry() == NPC_MIMIRON_KEEPER) - { - if (_checkTimer >= 2000) + case NPC_FREYA_KEEPER: + me->AddAura(SPELL_FREYA_PASSIVE, me); + me->CastSpell(me, SPELL_CONJURE_SANITY_WELL, false); + break; + case NPC_HODIR_KEEPER: + me->AddAura(SPELL_HODIR_PASSIVE, me); + me->AddAura(SPELL_PROTECTIVE_GAZE, me); + break; + case NPC_MIMIRON_KEEPER: + me->AddAura(SPELL_MIMIRON_PASSIVE, me); + scheduler.Schedule(2s, [this](TaskContext context) { - me->CastSpell(me, SPELL_DESTABILIZATION_MATRIX, false); - _checkTimer = 0; - } - } + if (!me->HasUnitState(UNIT_STATE_CASTING)) + me->CastSpell(me, SPELL_DESTABILIZATION_MATRIX, false); + context.Repeat(2s); + }); + break; + case NPC_THORIM_KEEPER: + me->AddAura(SPELL_THORIM_PASSIVE, me); + break; } - }; + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + } +private: + SummonList _summons; }; class boss_yoggsaron_descend_portal : public CreatureScript @@ -2739,6 +2759,33 @@ public: } }; +const Position SanityWellsPos[5] = +{ + {2042.56f, -40.3667f, 329.274f, 0.0f}, + {1975.89f, 40.0216f, 331.1f, 0.0f}, + {1987.12f, -91.2702f, 330.186f, 0.0f}, + {1900.48f, -51.2386f, 332.13f, 0.0f}, + {1899.94f, 0.330621f, 332.296f, 0.0f} +}; + +// 64170 - Sanity Well +class spell_keeper_freya_summon_sanity_well : public SpellScript +{ + PrepareSpellScript(spell_keeper_freya_summon_sanity_well); + + void OnEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetCaster()) + for (int i = 0; i < 5; i++) + caster->SummonCreature(NPC_SANITY_WELL, SanityWellsPos[i]); + } + + void Register() override + { + OnEffectLaunch += SpellEffectFn(spell_keeper_freya_summon_sanity_well::OnEffect, EFFECT_0, SPELL_EFFECT_SEND_EVENT); + } +}; + /* 63881 - Malady of the Mind 63795 - Psychosis 63830 - Malady of the Mind @@ -3032,7 +3079,7 @@ void AddSC_boss_yoggsaron() new boss_yoggsaron_crusher_tentacle(); new boss_yoggsaron_corruptor_tentacle(); new boss_yoggsaron_constrictor_tentacle(); - new boss_yoggsaron_keeper(); + RegisterUlduarCreatureAI(boss_yoggsaron_keeper); new boss_yoggsaron_descend_portal(); new boss_yoggsaron_influence_tentacle(); new boss_yoggsaron_immortal_guardian(); @@ -3053,6 +3100,7 @@ void AddSC_boss_yoggsaron() new spell_yogg_saron_insane_periodic_trigger(); new spell_yogg_saron_insane(); new spell_yogg_saron_sanity_well(); + RegisterSpellScript(spell_keeper_freya_summon_sanity_well); new spell_yogg_saron_sanity_reduce(); new spell_yogg_saron_empowering_shadows(); new spell_yogg_saron_in_the_maws_of_the_old_god(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index eaa548f81..d4289a097 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -370,22 +370,6 @@ public: case NPC_MIMIRON_ACU: m_MimironACUguid = creature->GetGUID(); break; - case NPC_FREYA_GOSSIP: - m_keepersGossipGUID[TYPE_FREYA - TYPE_FREYA] = creature->GetGUID(); - ShowKeeperGossip(TYPE_FREYA, creature); - break; - case NPC_HODIR_GOSSIP: - m_keepersGossipGUID[TYPE_HODIR - TYPE_FREYA] = creature->GetGUID(); - ShowKeeperGossip(TYPE_HODIR, creature); - break; - case NPC_THORIM_GOSSIP: - m_keepersGossipGUID[TYPE_THORIM - TYPE_FREYA] = creature->GetGUID(); - ShowKeeperGossip(TYPE_THORIM, creature); - break; - case NPC_MIMIRON_GOSSIP: - m_keepersGossipGUID[TYPE_MIMIRON - TYPE_FREYA] = creature->GetGUID(); - ShowKeeperGossip(TYPE_MIMIRON, creature); - break; case NPC_ELDER_IRONBRANCH: case NPC_ELDER_STONEBARK: case NPC_ELDER_BRIGHTLEAF: @@ -433,19 +417,6 @@ public: go->SetGoState(state); } - void ShowKeeperGossip(uint8 type, Creature* cr, ObjectGuid guid = ObjectGuid::Empty) - { - if (!cr) - { - cr = instance->GetCreature(guid); - if (!cr) - return; - } - - bool on = (GetData(type) == DONE && !(GetData(TYPE_WATCHERS) & (1 << (type - TYPE_FREYA)))); - cr->SetVisible(on); - } - void OnGameObjectCreate(GameObject* gameObject) override { switch (gameObject->GetEntry()) @@ -695,7 +666,6 @@ public: case TYPE_THORIM: case TYPE_FREYA: m_auiEncounter[type] = data; - ShowKeeperGossip(type, nullptr, m_keepersGossipGUID[type - TYPE_FREYA]); if (GetData(TYPE_MIMIRON) == DONE && GetData(TYPE_FREYA) == DONE && GetData(TYPE_HODIR) == DONE && GetData(TYPE_THORIM) == DONE) { if (GameObject* go = instance->GetGameObject(m_keepersgateGUID)) @@ -716,8 +686,11 @@ public: break; case TYPE_WATCHERS: m_auiEncounter[type] |= 1 << data; + [[fallthrough]]; + case EVENT_KEEPER_TELEPORTED: + if (Creature* sara = instance->GetCreature(m_saraGUID)) + sara->AI()->DoAction(ACTION_SARA_UPDATE_SUMMON_KEEPERS); break; - case DATA_MAGE_BARRIER: m_mageBarrier = data; break; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp index 218bb84bf..e8b6042d8 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp @@ -21,6 +21,7 @@ #include "GameObjectScript.h" #include "Player.h" #include "ScriptedCreature.h" +#include "PassiveAI.h" #include "ScriptedGossip.h" #include "SpellAuraEffects.h" #include "SpellScript.h" @@ -51,7 +52,14 @@ enum Texts GOSSIP_MENU_CONFIRM = 10333, NPC_TEXT_CONFIRM = 14325, - SAY_KEEPER_SELECTED = 1, + // Chosen + SAY_KEEPER_CHOSEN_TO_PLAYER = 0, + SAY_KEEPER_CHOSEN_ANNOUNCE = 1, +}; + +enum UldActions +{ + ACTION_KEEPER_OUTRO = 0, }; enum UldNPCs @@ -69,6 +77,8 @@ enum UldGameObjects enum UldSpells { + SPELL_SIMPLE_TELEPORT = 12980, + SPELL_KEEPER_TELEPORT = 62940, SPELL_SNOW_MOUND_PARTICLES = 64615 }; @@ -77,6 +87,68 @@ class npc_ulduar_keeper : public CreatureScript public: npc_ulduar_keeper() : CreatureScript("npc_ulduar_keeper_gossip") { } + struct npc_ulduar_keeperAI : public NullCreatureAI + { + npc_ulduar_keeperAI(Creature* creature) : NullCreatureAI(creature) { } + + void Reset() override + { + scheduler.Schedule(250ms, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_SIMPLE_TELEPORT); + }); + } + + void DoAction(int32 param) override + { + if (param == ACTION_KEEPER_OUTRO) + { + switch (me->GetEntry()) + { + case NPC_FREYA_GOSSIP: + _keeper = KEEPER_FREYA; + break; + case NPC_HODIR_GOSSIP: + _keeper = KEEPER_HODIR; + break; + case NPC_MIMIRON_GOSSIP: + _keeper = KEEPER_MIMIRON; + break; + case NPC_THORIM_GOSSIP: + _keeper = KEEPER_THORIM; + break; + default: + return; + } + scheduler.Schedule(1s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_KEEPER_TELEPORT); + }); + } + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_TELEPORT) + { + me->DespawnOrUnsummon(); + me->GetInstanceScript()->SetData(TYPE_WATCHERS, _keeper); + } + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + } + private: + uint8 _keeper; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetUlduarAI(creature); + } + bool OnGossipHello(Player* player, Creature* creature) override { uint32 gossipMenuId = 0; @@ -109,7 +181,6 @@ public: bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override { ClearGossipMenuFor(player); - uint8 _keeper = 0; switch (action) { case GOSSIP_ACTION_INFO_DEF+1: @@ -118,34 +189,12 @@ public: break; case GOSSIP_ACTION_INFO_DEF+2: { - switch (creature->GetEntry()) - { - case NPC_FREYA_GOSSIP: - creature->AI()->Talk(SAY_KEEPER_SELECTED); - _keeper = KEEPER_FREYA; - break; - case NPC_HODIR_GOSSIP: - creature->AI()->Talk(SAY_KEEPER_SELECTED); - _keeper = KEEPER_HODIR; - break; - case NPC_MIMIRON_GOSSIP: - creature->AI()->Talk(SAY_KEEPER_SELECTED); - _keeper = KEEPER_MIMIRON; - break; - case NPC_THORIM_GOSSIP: - creature->AI()->Talk(SAY_KEEPER_SELECTED); - _keeper = KEEPER_THORIM; - break; - } - - creature->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE); + creature->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); CloseGossipMenuFor(player); - if (creature->GetInstanceScript()) - { - creature->GetInstanceScript()->SetData(TYPE_WATCHERS, _keeper); - creature->DespawnOrUnsummon(6000); - } + creature->AI()->Talk(SAY_KEEPER_CHOSEN_TO_PLAYER, player); + creature->AI()->Talk(SAY_KEEPER_CHOSEN_ANNOUNCE); + creature->AI()->DoAction(ACTION_KEEPER_OUTRO); } } return true; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index ac91d1488..288e87dcb 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -284,6 +284,14 @@ enum UlduarMisc TIMER_ALGALON_TO_SUMMON = 200, TIMER_ALGALON_SUMMONED = 100, + // Algalon the Observer, Freya, Hodir, Mimiron, Thorim, Gossip Keepers + SPELL_TELEPORT = 62940, + + // Freya, Hodir, Mimiron, Thorim + EVENT_KEEPER_TELEPORTED = 62941, + + // Yogg-Saron + ACTION_SARA_UPDATE_SUMMON_KEEPERS = 4, KEEPER_FREYA = 0, KEEPER_HODIR = 1, KEEPER_MIMIRON = 2, diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 0b0d81091..f1502d756 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -628,6 +628,7 @@ class spell_gen_black_magic_enchant : public AuraScript }; // 53642 - The Might of Mograine +// 64174 - Protective Gaze class spell_gen_area_aura_select_players : public AuraScript { PrepareAuraScript(spell_gen_area_aura_select_players); @@ -642,6 +643,24 @@ class spell_gen_area_aura_select_players : public AuraScript } }; +// 62650 - Fortitude of Frost +// 62670 - Resilience of Nature +// 62671 - Speed of Invention +// 62702 - Fury of the Storm +class spell_gen_area_aura_select_players_and_caster : public AuraScript +{ + PrepareAuraScript(spell_gen_area_aura_select_players_and_caster); + + bool CheckAreaTarget(Unit* target) + { + return target->GetTypeId() == TYPEID_PLAYER || target == GetCaster(); + } + void Register() override + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_gen_area_aura_select_players_and_caster::CheckAreaTarget); + } +}; + /* 29883 - Blink (spell_gen_select_target_count_15_1) 38573 - Spore Drop Effect (spell_gen_select_target_count_15_1) 38633 - Arcane Volley (spell_gen_select_target_count_15_1) @@ -5193,6 +5212,7 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_disabled_above_63); RegisterSpellScript(spell_gen_black_magic_enchant); RegisterSpellScript(spell_gen_area_aura_select_players); + RegisterSpellScript(spell_gen_area_aura_select_players_and_caster); RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_1", TARGET_UNIT_SRC_AREA_ENEMY, 1); RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_2", TARGET_UNIT_SRC_AREA_ENEMY, 2); RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_5", TARGET_UNIT_SRC_AREA_ENEMY, 5);