From c9317a79401f7e93fef2510e52d457ec2e99b2e1 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Thu, 23 Jul 2026 21:39:39 -0300 Subject: [PATCH] fix(Scripts/Ulduar): overhaul Auriaya's Feral Defender (#26762) Co-authored-by: Keader --- .../rev_1784846222197249400.sql | 7 + .../Northrend/Ulduar/Ulduar/boss_auriaya.cpp | 207 +++++++++++++----- .../Northrend/Ulduar/Ulduar/ulduar.cpp | 28 +++ 3 files changed, 189 insertions(+), 53 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1784846222197249400.sql diff --git a/data/sql/updates/pending_db_world/rev_1784846222197249400.sql b/data/sql/updates/pending_db_world/rev_1784846222197249400.sql new file mode 100644 index 000000000..b0244b5da --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1784846222197249400.sql @@ -0,0 +1,7 @@ +-- +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_ulduar_random_aggro_periodic', 'spell_auriaya_feral_essence_removal', 'spell_auriaya_feral_rush'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(61906, 'spell_ulduar_random_aggro_periodic'), +(64456, 'spell_auriaya_feral_essence_removal'), +(64496, 'spell_auriaya_feral_rush'), +(64674, 'spell_auriaya_feral_rush'); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp index 913e2c32d..e4ba147e7 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp @@ -42,9 +42,18 @@ enum AuriayaSpells // Feral Defender SPELL_FERAL_ESSENCE = 64455, + SPELL_FERAL_ESSENCE_REMOVAL = 64456, + SPELL_SUMMON_ESSENCE = 64457, SPELL_FERAL_POUNCE = 64478, SPELL_FERAL_RUSH = 64496, - //SPELL_SEEPING_FERAL_ESSENCE_SUMMON = 64457, + SPELL_FERAL_RUSH_2 = 64489, + SPELL_SHADOW_PAWS = 64479, + SPELL_REDUCE_CRIT_CHANCE = 64481, + SPELL_RANDOM_AGGRO_PERIODIC = 61906, + SPELL_PERMANENT_FEIGN_DEATH = 58951, + SPELL_CLEAR_ALL_DEBUFFS = 34098, + SPELL_DROWNED_STATE = 64462, + SPELL_FULL_HEAL = 64460, SPELL_SEEPING_FERAL_ESSENCE = 64458, }; @@ -64,7 +73,6 @@ enum AuriayaEvents EVENT_GUARDIAN_SWARM = 4, EVENT_SENTINEL_BLAST = 5, EVENT_REMOVE_IMMUNE = 6, - EVENT_RESPAWN_FERAL_DEFENDER = 7, // Sanctum Sentry EVENT_SAVAGE_POUNCE = 8, @@ -73,6 +81,9 @@ enum AuriayaEvents // Feral Defender EVENT_FERAL_RUSH = 10, EVENT_FERAL_POUNCE = 11, + EVENT_RESPAWN_DEFENDER = 12, + EVENT_RESPAWN_DEFENDER_2 = 13, + EVENT_RESPAWN_DEFENDER_3 = 14, }; enum Texts @@ -87,10 +98,8 @@ enum Texts enum Misc { - ACTION_FERAL_RESPAWN = 1, ACTION_FERAL_DEATH = 2, ACTION_DESPAWN_ADDS = 3, - ACTION_FERAL_DEATH_WITH_STACK = 4, ACTION_SENTRY_DEATH = 5, DATA_CRAZY_CAT = 10, @@ -178,9 +187,7 @@ struct boss_auriaya : public BossAI void DoAction(int32 param) override { - if (param == ACTION_FERAL_DEATH_WITH_STACK) - events.ScheduleEvent(EVENT_RESPAWN_FERAL_DEFENDER, 25s); - else if (param == ACTION_FERAL_DEATH) + if (param == ACTION_FERAL_DEATH) _nineLives = true; else if (param == ACTION_SENTRY_DEATH) _feralDied = true; @@ -217,12 +224,6 @@ struct boss_auriaya : public BossAI events.Repeat(35s); events.DelayEvents(5s, 0); break; - case EVENT_RESPAWN_FERAL_DEFENDER: - { - EntryCheckPredicate pred(NPC_FERAL_DEFENDER); - summons.DoAction(ACTION_FERAL_RESPAWN, pred); - break; - } } } }; @@ -288,21 +289,38 @@ struct npc_auriaya_sanctum_sentry : public ScriptedAI } }; +class CatsTargetSelector +{ +public: + CatsTargetSelector(Unit const* unit, float minDist, float maxDist) : _me(unit), _minDist(minDist), _maxDist(maxDist) { } + + bool operator()(Unit* unit) const + { + float dist = _me->GetDistance(unit); + return unit->IsPlayer() && dist >= _minDist && dist < _maxDist && _me->IsWithinLOSInMap(unit); + } + +private: + Unit const* _me; + float _minDist; + float _maxDist; +}; + struct npc_auriaya_feral_defender : public ScriptedAI { npc_auriaya_feral_defender(Creature* creature) : ScriptedAI(creature), _summons(creature) { } - uint8 _feralEssenceStack{8}; SummonList _summons; void Reset() override { events.Reset(); _summons.DespawnAll(); - _feralEssenceStack = 8; - if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me)) - aur->SetStackAmount(_feralEssenceStack); + DoCastSelf(SPELL_SHADOW_PAWS, true); + DoCastSelf(SPELL_REDUCE_CRIT_CHANCE, true); + me->SetAuraStack(SPELL_FERAL_ESSENCE, me, 8); + DoCastSelf(SPELL_RANDOM_AGGRO_PERIODIC, true); } void JustEngagedWith(Unit*) override @@ -311,43 +329,45 @@ struct npc_auriaya_feral_defender : public ScriptedAI events.ScheduleEvent(EVENT_FERAL_POUNCE, 6s); } + void JustSummoned(Creature* summon) override + { + _summons.Summon(summon); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth() && me->HasAura(SPELL_FERAL_ESSENCE)) + { + damage = 0; + if (!me->HasAura(SPELL_PERMANENT_FEIGN_DEATH)) + { + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->RemoveAurasDueToSpell(SPELL_RANDOM_AGGRO_PERIODIC); + DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH, true); + DoCastSelf(SPELL_FERAL_ESSENCE_REMOVAL, true); + DoCastSelf(SPELL_SUMMON_ESSENCE, true); + DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS, true); + DoResetThreatList(); + events.ScheduleEvent(EVENT_RESPAWN_DEFENDER, 30s); + events.CancelEvent(EVENT_FERAL_RUSH); + } + } + } + void JustDied(Unit*) override { + DoCastSelf(SPELL_SUMMON_ESSENCE, true); + if (InstanceScript* instance = me->GetInstanceScript()) if (Creature* cr = instance->GetCreature(BOSS_AURIAYA)) - cr->AI()->DoAction(_feralEssenceStack ? ACTION_FERAL_DEATH_WITH_STACK : ACTION_FERAL_DEATH); - - if (_feralEssenceStack) - { - if (Creature* cr = me->SummonCreature(NPC_SEEPING_FERAL_ESSENCE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f)) - _summons.Summon(cr); - - --_feralEssenceStack; - } + cr->AI()->DoAction(ACTION_FERAL_DEATH); } void DoAction(int32 param) override { - if (param == ACTION_FERAL_RESPAWN) - { - me->setDeathState(DeathState::JustRespawned); - - if (Player* target = SelectTargetFromPlayerList(200)) - AttackStart(target); - else - { - _summons.DespawnAll(); - me->DespawnOrUnsummon(1ms); - } - - if (_feralEssenceStack) - if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me)) - aur->SetStackAmount(_feralEssenceStack); - - events.ScheduleEvent(EVENT_FERAL_RUSH, 3s); - events.ScheduleEvent(EVENT_FERAL_POUNCE, 6s); - } - else if (param == ACTION_DESPAWN_ADDS) + if (param == ACTION_DESPAWN_ADDS) _summons.DespawnAll(); } @@ -364,15 +384,51 @@ struct npc_auriaya_feral_defender : public ScriptedAI switch (events.ExecuteEvent()) { case EVENT_FERAL_RUSH: - DoResetThreatList(); - if (!UpdateVictim()) - return; - DoCastVictim(SPELL_FERAL_RUSH, true); - events.Repeat(6s); + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, CatsTargetSelector(me, 10.0f, 11.0f))) + { + DoCast(target, SPELL_FERAL_RUSH, true); + events.Repeat(5s); + break; + } + events.Repeat(1s); break; case EVENT_FERAL_POUNCE: - DoCastVictim(SPELL_FERAL_POUNCE); - events.Repeat(6s); + { + Unit* victim = me->GetVictim(); + if (me->GetReactState() != REACT_PASSIVE && victim) + { + float distance = me->GetDistance2d(victim); + if (distance > 5.0f && distance <= 45.0f) + { + DoCastVictim(SPELL_FERAL_POUNCE); + events.Repeat(5s); + break; + } + } + events.Repeat(1s); + break; + } + case EVENT_RESPAWN_DEFENDER: + me->SetDisableGravity(true); + me->SetHover(true); + DoCastSelf(SPELL_DROWNED_STATE, true); + events.ScheduleEvent(EVENT_RESPAWN_DEFENDER_2, 3s); + events.ScheduleEvent(EVENT_RESPAWN_DEFENDER_3, 5s); + break; + case EVENT_RESPAWN_DEFENDER_2: + me->RemoveAurasDueToSpell(SPELL_DROWNED_STATE); + break; + case EVENT_RESPAWN_DEFENDER_3: + me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH); + DoCastSelf(SPELL_FULL_HEAL, true); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + me->SetDisableGravity(false); + me->SetHover(false); + DoCastSelf(SPELL_RANDOM_AGGRO_PERIODIC, true); + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true)) + AttackStart(target); + events.ScheduleEvent(EVENT_FERAL_RUSH, 1s); break; } @@ -395,6 +451,49 @@ class spell_auriaya_sentinel_blast : public SpellScript } }; +// 64456 - Feral Essence Application Removal +class spell_auriaya_feral_essence_removal : public SpellScript +{ + PrepareSpellScript(spell_auriaya_feral_essence_removal); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FERAL_ESSENCE }); + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Aura* essence = GetCaster()->GetAura(SPELL_FERAL_ESSENCE)) + essence->ModStackAmount(-1); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_auriaya_feral_essence_removal::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +// 64496, 64674 - Feral Rush +class spell_auriaya_feral_rush : public SpellScript +{ + PrepareSpellScript(spell_auriaya_feral_rush); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FERAL_RUSH_2 }); + } + + void HandleOnHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_FERAL_RUSH_2, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_auriaya_feral_rush::HandleOnHit, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); + } +}; + class achievement_auriaya_crazy_cat_lady : public AchievementCriteriaScript { public: @@ -434,6 +533,8 @@ void AddSC_boss_auriaya() RegisterUlduarCreatureAI(npc_auriaya_feral_defender); RegisterSpellScript(spell_auriaya_sentinel_blast); + RegisterSpellScript(spell_auriaya_feral_essence_removal); + RegisterSpellScript(spell_auriaya_feral_rush); new achievement_auriaya_crazy_cat_lady(); new achievement_auriaya_nine_lives(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp index 411e9ac10..406422e05 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp @@ -239,6 +239,33 @@ class spell_ulduar_energy_sap_aura : public AuraScript } }; +// 61906 - Random Aggro Periodic (5 sec) +class spell_ulduar_random_aggro_periodic : public AuraScript +{ + PrepareAuraScript(spell_ulduar_random_aggro_periodic); + + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + Unit* target = GetTarget(); + target->GetThreatMgr().ResetAllThreat(); + + Creature* creature = target->ToCreature(); + if (!creature || !creature->IsAIEnabled) + return; + + if (Unit* victim = creature->AI()->SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true)) + { + creature->AddThreat(victim, 3000000.0f); + creature->AI()->AttackStart(victim); + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_ulduar_random_aggro_periodic::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + struct npc_ulduar_snow_mound : public ScriptedAI { npc_ulduar_snow_mound(Creature* creature) : ScriptedAI(creature) @@ -590,6 +617,7 @@ void AddSC_ulduar() new npc_ulduar_keeper(); RegisterSpellScript(spell_ulduar_teleporter); RegisterSpellScript(spell_ulduar_energy_sap_aura); + RegisterSpellScript(spell_ulduar_random_aggro_periodic); RegisterUlduarCreatureAI(npc_ulduar_snow_mound); RegisterUlduarCreatureAI(npc_ulduar_storm_tempered_keeper); RegisterUlduarCreatureAI(npc_ulduar_arachnopod_destroyer);