fix(Scripts/Ulduar): overhaul Auriaya's Feral Defender (#26762)

Co-authored-by: Keader <keader.android@gmail.com>
This commit is contained in:
Andrew
2026-07-23 21:39:39 -03:00
committed by GitHub
parent 44df0285ce
commit c9317a7940
3 changed files with 189 additions and 53 deletions

View File

@@ -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');

View File

@@ -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();

View File

@@ -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);