Core/ Script HOI

This commit is contained in:
luis
2026-09-17 18:16:46 -03:00
parent f4afc16458
commit f19ee3937b
6 changed files with 649 additions and 125 deletions
@@ -31,6 +31,26 @@ enum HOINFUSIONCreatureIds
BOSS_GULPING_GOLIATH = 189722,
BOSS_KHAJIN_THE_UNYIELDING = 189727,
BOSS_PRIMAL_TSUNAMI = 189729,
NPC_CONTAINMENT_APPARATUS = 190342,
NPC_PRIMALIST_GEOMANCER = 190345,
NPC_PRIMALIST_RAVAGER = 190348,
NPC_SKULKING_ZEALOT = 190359,
NPC_DAZZLING_DRAGONFLY = 190362,
NPC_CURIOUS_SWOGLET = 190366,
NPC_FLAMECALLER_AYMI = 190368,
NPC_SQUALLBRINGER_CYRAZ = 190370,
NPC_PRIMALIST_EARTHSHAKER = 190371,
NPC_PRIMALIST_GALESINGER = 190373,
NPC_PRIMALIST_ICECALLER = 190377,
NPC_GLACIAL_PROTO_DRAGON = 190403,
NPC_INFUSER_SARIYA = 190405,
NPC_AQUA_RAGER = 190407,
NPC_REFTI_DEFENDER = 190340,
NPC_CURIOUS_SWOGLET_ALT = 195399,
NPC_PRIMALIST_INFUSER = 196043,
NPC_PRIMALIST_SHOCKTROOPER = 199037,
NPC_INFUSED_GLOBULE = 196008,
};
template <class AI, class T>
@@ -5,23 +5,535 @@
* and read our Terms
*/
#include "AreaTrigger.h"
#include "AreaTriggerAI.h"
#include "InstanceScript.h"
#include "Map.h"
#include "SpellAuras.h"
#include "SpellScript.h"
#include "ScriptMgr.h"
#include "Unit.h"
#include "HallsOfInfusion.h"
#include "InstanceScript.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
#include "SpellHistory.h"
#include "Spell.h"
#include "Player.h"
#include "MotionMaster.h"
#include "TemporarySummon.h"
//here to script trash and gobs
// Halls of Infusion trash (retail 12.1 sniff 69814)
enum NpcsSpells
enum TrashSpells
{
//Refti Defender 190340
SPELL_DEMORALIZING_SHOUT = 374339,
SPELL_SPEAR_FLURRY = 393432,
SPELL_GUSHING_WOUND = 393444,
//Primalist Geomancer 190345
SPELL_SEISMIC_SLAM = 374073,
SPELL_TAILWIND_GEOMANCER = 374154,
//Primalist Ravager 190348
SPELL_TAILWIND_RAVAGER = 374149,
//Skulking Zealot 190359
SPELL_STEALTH = 374612,
SPELL_CHEAP_SHOT = 374614,
SPELL_RISING_SQUALL = 374616,
//Dazzling Dragonfly 190362
SPELL_DAZZLE = 374563,
SPELL_EVASIVE_FLUTTER = 374578,
//Flamecaller Aymi 190368
SPELL_CAUTERIZE = 374699,
SPELL_PYRETIC_BURST = 374706,
SPELL_MOLTEN_SUBDUCTION = 374718,
SPELL_MAGMA_CRUSH = 374735,
//Squallbringer Cyraz 190370
SPELL_ZEPHYRS_CALL = 374823,
SPELL_GALE_FORCE_CHARGE = 374863,
SPELL_WHIRLING_FURY = 375079,
//Primalist Earthshaker 190371
SPELL_RUMBLING_EARTH = 375384,
//Primalist Galesinger 190373
SPELL_THUNDERSTRIKE = 437717,
//Primalist Icecaller 190377
SPELL_ICE_SHARD = 375950,
SPELL_REFRESHING_TIDES = 376171,
//Glacial Proto-Dragon 190403
SPELL_OCEANIC_BREATH = 375351,
SPELL_DEEP_CHILL = 391634,
//Infuser Sariya 190405
SPELL_AQUEOUS_BARRIER = 377402,
SPELL_INUNDATE = 388882,
SPELL_FLASH_FLOOD = 390290,
SPELL_WATER_MISSILE = 396783,
//Aqua Rager 190407
SPELL_TIDAL_DIVERGENCE = 377341,
SPELL_BOILING_RAGE = 377384,
//Primalist Infuser 196043
SPELL_INFUSE = 387618,
//Primalist Shocktrooper 199037
SPELL_LIGHTNING_BLAST = 395690,
SPELL_INFUSED_LIGHTNING = 395691,
SPELL_ELEMENTAL_FOCUS = 395694,
//Containment Apparatus 190342
SPELL_INVIS_DETECT = 18950,
SPELL_CONTAINMENT_BEAM = 374020,
SPELL_EXPULSE = 374045,
};
enum TrashEvents
{
EVENT_TH_A = 1,
EVENT_TH_B,
EVENT_TH_C,
};
// ---------- generic two-spell caster trash ----------
template<uint32 SpellA, uint32 CooldownA, uint32 SpellB, uint32 CooldownB>
struct npc_hoi_two_caster : public ScriptedAI
{
npc_hoi_two_caster(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_TH_A, 2s);
_events.ScheduleEvent(EVENT_TH_B, 6s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_TH_A:
DoCastVictim(SpellA);
_events.ScheduleEvent(EVENT_TH_A, Milliseconds(CooldownA));
break;
case EVENT_TH_B:
DoCastVictim(SpellB);
_events.ScheduleEvent(EVENT_TH_B, Milliseconds(CooldownB));
break;
default:
break;
}
}
me->DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
// ---------- generic single-spell trash ----------
template<uint32 SpellA, uint32 CooldownA>
struct npc_hoi_one_spell : public ScriptedAI
{
npc_hoi_one_spell(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_TH_A, 2s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
if (eventId == EVENT_TH_A)
{
DoCastVictim(SpellA);
_events.ScheduleEvent(EVENT_TH_A, Milliseconds(CooldownA));
}
}
me->DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
// ---------- named trash AI ----------
//Refti Defender 190340
struct npc_hoi_refti_defender : public ScriptedAI
{
npc_hoi_refti_defender(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_TH_A, 4s);
_events.ScheduleEvent(EVENT_TH_B, 8s);
_events.ScheduleEvent(EVENT_TH_C, 5s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_TH_A:
DoCastAOE(SPELL_DEMORALIZING_SHOUT);
_events.ScheduleEvent(EVENT_TH_A, 15s);
break;
case EVENT_TH_B:
DoCastAOE(SPELL_SPEAR_FLURRY);
_events.ScheduleEvent(EVENT_TH_B, 12s);
break;
case EVENT_TH_C:
DoCastVictim(SPELL_GUSHING_WOUND);
_events.ScheduleEvent(EVENT_TH_C, 6s);
break;
default:
break;
}
}
me->DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
//Skulking Zealot 190359 - stealth opener
struct npc_hoi_skulking_zealot : public ScriptedAI
{
npc_hoi_skulking_zealot(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
DoCastSelf(SPELL_STEALTH);
_events.ScheduleEvent(EVENT_TH_A, 5s);
_events.ScheduleEvent(EVENT_TH_B, 12s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_TH_A:
DoCastVictim(SPELL_CHEAP_SHOT);
_events.ScheduleEvent(EVENT_TH_A, 8s);
break;
case EVENT_TH_B:
DoCastAOE(SPELL_RISING_SQUALL);
_events.ScheduleEvent(EVENT_TH_B, 15s);
break;
default:
break;
}
}
me->DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
//Flamecaller Aymi 190368
struct npc_hoi_flamecaller_aymi : public ScriptedAI
{
npc_hoi_flamecaller_aymi(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_TH_A, 5s);
_events.ScheduleEvent(EVENT_TH_B, 10s);
_events.ScheduleEvent(EVENT_TH_C, 8s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_TH_A:
DoCastAOE(SPELL_PYRETIC_BURST);
_events.ScheduleEvent(EVENT_TH_A, 12s);
break;
case EVENT_TH_B:
DoCastAOE(SPELL_MOLTEN_SUBDUCTION);
_events.ScheduleEvent(EVENT_TH_B, 18s);
break;
case EVENT_TH_C:
if (HealthBelowPct(70))
DoCastSelf(SPELL_CAUTERIZE);
else
DoCastVictim(SPELL_MAGMA_CRUSH);
_events.ScheduleEvent(EVENT_TH_C, 14s);
break;
default:
break;
}
}
me->DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
//Squallbringer Cyraz 190370
struct npc_hoi_squallbringer_cyraz : public ScriptedAI
{
npc_hoi_squallbringer_cyraz(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_TH_A, 6s);
_events.ScheduleEvent(EVENT_TH_B, 12s);
_events.ScheduleEvent(EVENT_TH_C, 20s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_TH_A:
DoCastAOE(SPELL_ZEPHYRS_CALL);
_events.ScheduleEvent(EVENT_TH_A, 15s);
break;
case EVENT_TH_B:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true))
DoCast(target, SPELL_GALE_FORCE_CHARGE);
_events.ScheduleEvent(EVENT_TH_B, 20s);
break;
case EVENT_TH_C:
DoCastSelf(SPELL_WHIRLING_FURY);
_events.ScheduleEvent(EVENT_TH_C, 25s);
break;
default:
break;
}
}
me->DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
//Infuser Sariya 190405
struct npc_hoi_infuser_sariya : public ScriptedAI
{
npc_hoi_infuser_sariya(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
DoCastSelf(SPELL_AQUEOUS_BARRIER);
_events.ScheduleEvent(EVENT_TH_A, 3s);
_events.ScheduleEvent(EVENT_TH_B, 12s);
_events.ScheduleEvent(EVENT_TH_C, 25s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_TH_A:
DoCastVictim(SPELL_WATER_MISSILE);
_events.ScheduleEvent(EVENT_TH_A, 4s);
break;
case EVENT_TH_B:
DoCastAOE(SPELL_INUNDATE);
_events.ScheduleEvent(EVENT_TH_B, 15s);
break;
case EVENT_TH_C:
DoCastAOE(SPELL_FLASH_FLOOD);
_events.ScheduleEvent(EVENT_TH_C, 30s);
break;
default:
break;
}
}
me->DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
//Containment Apparatus 190342
struct npc_hoi_containment_apparatus : public ScriptedAI
{
npc_hoi_containment_apparatus(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_TH_A, 5s);
_events.ScheduleEvent(EVENT_TH_B, 20s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_TH_A:
DoCastAOE(SPELL_CONTAINMENT_BEAM);
_events.ScheduleEvent(EVENT_TH_A, 8s);
break;
case EVENT_TH_B:
DoCastSelf(SPELL_EXPULSE);
_events.ScheduleEvent(EVENT_TH_B, 20s);
break;
default:
break;
}
}
me->DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
//Primalist Infuser 196043 - buffs nearby allies
struct npc_hoi_primalist_infuser : public ScriptedAI
{
npc_hoi_primalist_infuser(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_TH_A, 4s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
if (eventId == EVENT_TH_A)
{
DoCastSelf(SPELL_INFUSE);
_events.ScheduleEvent(EVENT_TH_A, 15s);
}
}
me->DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
// ---------- bindings (AI name = ScriptName) ----------
typedef npc_hoi_one_spell<SPELL_TAILWIND_RAVAGER, 8000> npc_hoi_primalist_ravager;
typedef npc_hoi_one_spell<SPELL_ICE_SHARD, 4000> npc_hoi_primalist_icecaller;
typedef npc_hoi_one_spell<SPELL_THUNDERSTRIKE, 6000> npc_hoi_primalist_galesinger;
typedef npc_hoi_one_spell<SPELL_RUMBLING_EARTH, 9000> npc_hoi_primalist_earthshaker;
typedef npc_hoi_two_caster<SPELL_SEISMIC_SLAM, 10000, SPELL_TAILWIND_GEOMANCER, 15000> npc_hoi_primalist_geomancer;
typedef npc_hoi_two_caster<SPELL_DAZZLE, 8000, SPELL_EVASIVE_FLUTTER, 20000> npc_hoi_dazzling_dragonfly;
typedef npc_hoi_two_caster<SPELL_OCEANIC_BREATH, 12000, SPELL_DEEP_CHILL, 8000> npc_hoi_glacial_proto_dragon;
typedef npc_hoi_two_caster<SPELL_BOILING_RAGE, 8000, SPELL_TIDAL_DIVERGENCE, 12000> npc_hoi_aqua_rager;
typedef npc_hoi_two_caster<SPELL_LIGHTNING_BLAST, 6000, SPELL_INFUSED_LIGHTNING, 9000> npc_hoi_primalist_shocktrooper;
void AddSC_HallsOfInfusion()
{
RegisterCreatureAI(npc_hoi_refti_defender);
RegisterCreatureAI(npc_hoi_skulking_zealot);
RegisterCreatureAI(npc_hoi_flamecaller_aymi);
RegisterCreatureAI(npc_hoi_squallbringer_cyraz);
RegisterCreatureAI(npc_hoi_infuser_sariya);
RegisterCreatureAI(npc_hoi_containment_apparatus);
RegisterCreatureAI(npc_hoi_primalist_infuser);
RegisterCreatureAI(npc_hoi_primalist_ravager);
RegisterCreatureAI(npc_hoi_primalist_icecaller);
RegisterCreatureAI(npc_hoi_primalist_galesinger);
RegisterCreatureAI(npc_hoi_primalist_earthshaker);
RegisterCreatureAI(npc_hoi_primalist_geomancer);
RegisterCreatureAI(npc_hoi_dazzling_dragonfly);
RegisterCreatureAI(npc_hoi_glacial_proto_dragon);
RegisterCreatureAI(npc_hoi_aqua_rager);
RegisterCreatureAI(npc_hoi_primalist_shocktrooper);
}
@@ -24,9 +24,8 @@
enum GulpinggoliathSpells
{
SPELL_BELLY_SLAM = 385531,
SPELL_GULP = 385551, //385555,
SPELL_GULP_SWOG_TOXIN = 374389,
SPELL_HANGRY = 385743,
SPELL_BELLY_SLAM_FOLLOWUP = 385691,
SPELL_GULP = 385551,
SPELL_OVERPOWERING_CROAK = 385181,
SPELL_TOXIC_EFFLUVIA = 385442,
SPELL_PERIODIC_ENERGY_GAIN = 299956,
@@ -35,9 +34,8 @@ enum GulpinggoliathSpells
enum Gulpinggoliathevents
{
EVENT_BELLY_SLAM = 1,
EVENT_BELLY_SLAM_FOLLOWUP,
EVENT_GULP,
EVENT_GULP_SWOG_TOXIN,
EVENT_HANGRY,
EVENT_OVERPOWERING_CROAK,
EVENT_TOXIC_EFFLUVIA,
};
@@ -62,12 +60,10 @@ public:
BossAI::JustEngagedWith(who);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
DoCast(SPELL_PERIODIC_ENERGY_GAIN);
events.ScheduleEvent(EVENT_BELLY_SLAM, 24s);
events.ScheduleEvent(EVENT_GULP, 8s);
events.ScheduleEvent(EVENT_GULP_SWOG_TOXIN, 12s);
events.ScheduleEvent(EVENT_HANGRY, 14s);
events.ScheduleEvent(EVENT_OVERPOWERING_CROAK, 5s);
events.ScheduleEvent(EVENT_TOXIC_EFFLUVIA, 19s);
events.ScheduleEvent(EVENT_OVERPOWERING_CROAK, 4s);
events.ScheduleEvent(EVENT_GULP, 10s);
events.ScheduleEvent(EVENT_TOXIC_EFFLUVIA, 22s);
events.ScheduleEvent(EVENT_BELLY_SLAM, 30s);
}
void EnterEvadeMode(EvadeReason /*why*/) override
@@ -108,19 +104,15 @@ public:
{
case EVENT_BELLY_SLAM:
DoCastVictim(SPELL_BELLY_SLAM);
events.ScheduleEvent(EVENT_BELLY_SLAM, 20s);
events.ScheduleEvent(EVENT_BELLY_SLAM_FOLLOWUP, 4s);
events.ScheduleEvent(EVENT_BELLY_SLAM, 30s);
break;
case EVENT_BELLY_SLAM_FOLLOWUP:
DoCastSelf(SPELL_BELLY_SLAM_FOLLOWUP);
break;
case EVENT_GULP:
DoCast(SPELL_GULP);
events.ScheduleEvent(EVENT_GULP, 15s);
break;
case EVENT_GULP_SWOG_TOXIN:
DoCastVictim(SPELL_GULP_SWOG_TOXIN);
events.ScheduleEvent(EVENT_GULP_SWOG_TOXIN, 25s);
break;
case EVENT_HANGRY:
DoCastSelf(SPELL_HANGRY);
events.ScheduleEvent(EVENT_HANGRY, 33s);
events.ScheduleEvent(EVENT_GULP, 47s);
break;
case EVENT_OVERPOWERING_CROAK:
DoCastSelf(SPELL_OVERPOWERING_CROAK);
@@ -23,19 +23,19 @@
enum KhajintheunyieldingSpells
{
SPELL_FROST_CYCLONE = 390111,
SPELL_FROST_SHOCK = 385963,
SPELL_GLACIAL_SURGE = 386559,
SPELL_GLACIAL_SURGE_FOLLOW = 386562,
SPELL_HAILSTORM = 386757,
SPELL_POLAR_WINDS = 386743,
SPELL_PERIODIC_ENERGY_GAIN = 299956,
SPELL_POLAR_WINDS = 386741,
SPELL_POLAR_WINDS_FOLLOW = 386743,
};
enum Khajintheunyieldingevents
{
EVENT_FROST_CYCLONE = 1,
EVENT_FROST_SHOCK,
EVENT_FROST_SHOCK = 1,
EVENT_GLACIAL_SURGE,
EVENT_GLACIAL_SURGE_FOLLOW,
EVENT_HAILSTORM,
EVENT_POLAR_WINDS,
};
@@ -49,9 +49,6 @@ public:
void Reset() override
{
BossAI::Reset();
me->RemoveAura(SPELL_PERIODIC_ENERGY_GAIN);
me->SetPowerType(POWER_ENERGY);
me->SetPower(POWER_ENERGY, 0);
me->RemoveAllAreaTriggers();
}
@@ -59,12 +56,11 @@ public:
{
BossAI::JustEngagedWith(who);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
DoCast(SPELL_PERIODIC_ENERGY_GAIN);
events.ScheduleEvent(EVENT_FROST_CYCLONE, 24s);
events.ScheduleEvent(EVENT_FROST_SHOCK, 8s);
events.ScheduleEvent(EVENT_GLACIAL_SURGE, 12s);
events.ScheduleEvent(EVENT_HAILSTORM, 14s);
events.ScheduleEvent(EVENT_POLAR_WINDS, 17s);
DoCastSelf(SPELL_POLAR_WINDS);
events.ScheduleEvent(EVENT_POLAR_WINDS, 500ms);
events.ScheduleEvent(EVENT_FROST_SHOCK, 6s);
events.ScheduleEvent(EVENT_HAILSTORM, 10s);
events.ScheduleEvent(EVENT_GLACIAL_SURGE, 22s);
}
void EnterEvadeMode(EvadeReason /*why*/) override
@@ -91,37 +87,30 @@ public:
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (me->GetPowerPct(POWER_ENERGY) == 100)
{
me->ModifyPower(POWER_ENERGY, -100);
events.ScheduleEvent(EVENT_POLAR_WINDS, 2s);
}
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_FROST_CYCLONE:
DoCast(SPELL_FROST_CYCLONE);
events.ScheduleEvent(EVENT_FROST_CYCLONE, 20s);
case EVENT_POLAR_WINDS:
DoCastSelf(SPELL_POLAR_WINDS_FOLLOW);
break;
case EVENT_FROST_SHOCK:
DoCastVictim(SPELL_FROST_SHOCK);
events.ScheduleEvent(EVENT_FROST_SHOCK, 15s);
events.ScheduleEvent(EVENT_FROST_SHOCK, 12s);
break;
case EVENT_GLACIAL_SURGE:
DoCast(SPELL_GLACIAL_SURGE);
events.ScheduleEvent(EVENT_GLACIAL_SURGE, 12s);
DoCastSelf(SPELL_GLACIAL_SURGE);
events.ScheduleEvent(EVENT_GLACIAL_SURGE_FOLLOW, 4s);
events.ScheduleEvent(EVENT_GLACIAL_SURGE, 22s);
break;
case EVENT_GLACIAL_SURGE_FOLLOW:
DoCast(SPELL_GLACIAL_SURGE_FOLLOW);
break;
case EVENT_HAILSTORM:
DoCast(SPELL_HAILSTORM);
events.ScheduleEvent(EVENT_HAILSTORM, 33s);
break;
case EVENT_POLAR_WINDS:
DoCast(SPELL_POLAR_WINDS);
events.ScheduleEvent(EVENT_POLAR_WINDS, 37s);
events.ScheduleEvent(EVENT_HAILSTORM, 28s);
break;
default:
break;
@@ -23,58 +23,56 @@
enum PrimaltsunamiSpells
{
SPELL_FOCUSED_DELUGE = 387571,
SPELL_INFUSE = 387619,
SPELL_INFUSED_GLOBULES = 387559,
SPELL_ROGUE_WAVES = 388760,
SPELL_ROGUE_WAVES = 388788,
SPELL_SQUALL_BUFFET = 387504,
SPELL_SUBMERGE = 387585,
SPELL_TEMPESTS_FURY = 388424,
SPELL_UNDERTOW = 389872,
SPELL_UNDERTOW_DAMAGE = 389875,
SPELL_PERIODIC_ENERGY_GAIN = 299956,
SPELL_CRASHING_TSUNAMI = 388712,
SPELL_TELEPORT_CORPSES = 396893,
SPELL_PASSIVE_ENERGY_GAIN = 387593,
};
enum Primaltsunamievents
{
EVENT_FOCUSED_DELUGE = 1,
EVENT_INFUSE,
EVENT_INFUSED_GLOBULES,
EVENT_INFUSED_GLOBULES = 1,
EVENT_ROGUE_WAVES,
EVENT_SQUALL_BUFFET,
EVENT_SUBMERGE,
EVENT_TEMPESTS_FURY,
EVENT_UNDERTOW,
EVENT_CRASHING_TSUNAMI,
EVENT_RE_EMERGE,
};
//189729 Primal Tsunami
class boss_primal_tsunami : public BossAI
{
public:
boss_primal_tsunami(Creature* creature) : BossAI(creature, DATA_PRIMAL_TSUNAMI) {}
boss_primal_tsunami(Creature* creature) : BossAI(creature, DATA_PRIMAL_TSUNAMI), _submerged(false) {}
void Reset() override
{
BossAI::Reset();
me->RemoveAura(SPELL_PERIODIC_ENERGY_GAIN);
me->RemoveAura(SPELL_PASSIVE_ENERGY_GAIN);
me->SetPowerType(POWER_ENERGY);
me->SetPower(POWER_ENERGY, 0);
me->RemoveAllAreaTriggers();
me->SetReactState(REACT_AGGRESSIVE);
_submerged = false;
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
DoCast(SPELL_PERIODIC_ENERGY_GAIN);
events.ScheduleEvent(EVENT_FOCUSED_DELUGE, 24s);
events.ScheduleEvent(EVENT_INFUSE, 8s);
events.ScheduleEvent(EVENT_INFUSED_GLOBULES, 12s);
events.ScheduleEvent(EVENT_ROGUE_WAVES, 14s);
events.ScheduleEvent(EVENT_SQUALL_BUFFET, 22s);
events.ScheduleEvent(EVENT_SUBMERGE, 17s);
DoCastSelf(SPELL_PASSIVE_ENERGY_GAIN);
DoCastSelf(SPELL_UNDERTOW);
events.ScheduleEvent(EVENT_ROGUE_WAVES, 1s);
events.ScheduleEvent(EVENT_TEMPESTS_FURY, 5s);
events.ScheduleEvent(EVENT_UNDERTOW, 29s);
events.ScheduleEvent(EVENT_INFUSED_GLOBULES, 9s);
events.ScheduleEvent(EVENT_SQUALL_BUFFET, 17s);
}
void EnterEvadeMode(EvadeReason /*why*/) override
@@ -98,10 +96,7 @@ public:
if (!UpdateVictim())
return;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (me->GetPowerPct(POWER_ENERGY) == 100)
if (!_submerged && me->GetPowerPct(POWER_ENERGY) == 100)
{
me->ModifyPower(POWER_ENERGY, -100);
events.ScheduleEvent(EVENT_SUBMERGE, 2s);
@@ -113,37 +108,47 @@ public:
{
switch (eventId)
{
case EVENT_FOCUSED_DELUGE:
DoCastVictim(SPELL_FOCUSED_DELUGE);
events.ScheduleEvent(EVENT_FOCUSED_DELUGE, 20s);
break;
case EVENT_INFUSE:
DoCastSelf(SPELL_INFUSE);
me->RemoveAurasDueToSpell(SPELL_SUBMERGE);
events.ScheduleEvent(EVENT_INFUSE, 15s);
break;
case EVENT_INFUSED_GLOBULES:
DoCast(SPELL_INFUSED_GLOBULES);
events.ScheduleEvent(EVENT_INFUSED_GLOBULES, 12s);
break;
case EVENT_ROGUE_WAVES:
DoCast(SPELL_ROGUE_WAVES);
events.ScheduleEvent(EVENT_ROGUE_WAVES, 91s);
break;
case EVENT_SQUALL_BUFFET:
DoCastVictim(SPELL_SQUALL_BUFFET);
events.ScheduleEvent(EVENT_SQUALL_BUFFET, 37s);
break;
case EVENT_SUBMERGE:
DoCastSelf(SPELL_SUBMERGE);
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
_submerged = true;
events.ScheduleEvent(EVENT_CRASHING_TSUNAMI, 3s);
events.ScheduleEvent(EVENT_RE_EMERGE, 30s);
break;
case EVENT_CRASHING_TSUNAMI:
DoCastSelf(SPELL_CRASHING_TSUNAMI);
if (_submerged)
events.ScheduleEvent(EVENT_CRASHING_TSUNAMI, 7s);
break;
case EVENT_RE_EMERGE:
me->SetReactState(REACT_AGGRESSIVE);
DoCastSelf(SPELL_TELEPORT_CORPSES);
_submerged = false;
me->SetPower(POWER_ENERGY, 0);
events.ScheduleEvent(EVENT_TEMPESTS_FURY, 5s);
events.ScheduleEvent(EVENT_INFUSED_GLOBULES, 9s);
events.ScheduleEvent(EVENT_SQUALL_BUFFET, 17s);
events.ScheduleEvent(EVENT_ROGUE_WAVES, 25s);
break;
case EVENT_INFUSED_GLOBULES:
DoCastSelf(SPELL_INFUSED_GLOBULES);
events.ScheduleEvent(EVENT_INFUSED_GLOBULES, 17s);
break;
case EVENT_ROGUE_WAVES:
DoCastSelf(SPELL_ROGUE_WAVES);
events.ScheduleEvent(EVENT_ROGUE_WAVES, 20s);
break;
case EVENT_SQUALL_BUFFET:
DoCast(SPELL_SQUALL_BUFFET);
events.ScheduleEvent(EVENT_SQUALL_BUFFET, 37s);
break;
case EVENT_TEMPESTS_FURY:
DoCast(SPELL_TEMPESTS_FURY);
DoCastSelf(SPELL_TEMPESTS_FURY);
events.ScheduleEvent(EVENT_TEMPESTS_FURY, 44s);
break;
case EVENT_UNDERTOW:
DoCast(SPELL_UNDERTOW);
DoCast(SPELL_UNDERTOW_DAMAGE);
DoCastSelf(SPELL_UNDERTOW);
events.ScheduleEvent(EVENT_UNDERTOW, 25s);
break;
default:
@@ -151,7 +156,15 @@ public:
}
}
if (!_submerged && me->HasUnitState(UNIT_STATE_CASTING))
return;
if (!_submerged && me->GetVictim())
me->DoMeleeAttackIfReady();
}
private:
bool _submerged;
};
void AddSC_boss_primal_tsunami()
@@ -26,8 +26,8 @@ enum watcherirideusSpells
SPELL_ABLATIVE_BARRIER = 383840,
SPELL_POWER_FIELD = 389181,
SPELL_POWER_OVERLOAD = 389179,
SPELL_SIPHON_POWER = 389056, //389486,
SPELL_SPARK_VOLLEY = 383935, //384351,
SPELL_SIPHON_POWER = 389056,
SPELL_SPARK_VOLLEY = 384351,
SPELL_STATIC_SURGE = 384014,
SPELL_TITANIC_FIST = 384524,
SPELL_PERIODIC_ENERGY_GAIN = 299956,
@@ -65,13 +65,11 @@ public:
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
Talk(0);
DoCast(SPELL_PERIODIC_ENERGY_GAIN);
events.ScheduleEvent(EVENT_ABLATIVE_BARRIER, 24s);
events.ScheduleEvent(EVENT_POWER_FIELD, 8s);
events.ScheduleEvent(EVENT_POWER_OVERLOAD, 12s);
events.ScheduleEvent(EVENT_SIPHON_POWER, 14s);
events.ScheduleEvent(EVENT_SPARK_VOLLEY, 3s);
events.ScheduleEvent(EVENT_STATIC_SURGE, 17s);
events.ScheduleEvent(EVENT_TITANIC_FIST, 5s);
events.ScheduleEvent(EVENT_STATIC_SURGE, 10s);
events.ScheduleEvent(EVENT_POWER_OVERLOAD, 22s);
events.ScheduleEvent(EVENT_POWER_FIELD, 24s);
events.ScheduleEvent(EVENT_SPARK_VOLLEY, 26s);
}
void EnterEvadeMode(EvadeReason /*why*/) override
@@ -113,10 +111,11 @@ public:
{
case EVENT_ABLATIVE_BARRIER:
DoCastSelf(SPELL_ABLATIVE_BARRIER);
events.ScheduleEvent(EVENT_SIPHON_POWER, 2s);
break;
case EVENT_POWER_FIELD:
DoCastVictim(SPELL_POWER_FIELD);
events.ScheduleEvent(EVENT_POWER_FIELD, 20s);
DoCast(SPELL_POWER_FIELD);
events.ScheduleEvent(EVENT_POWER_FIELD, 25s);
break;
case EVENT_POWER_OVERLOAD:
DoCastSelf(SPELL_POWER_OVERLOAD);
@@ -124,19 +123,18 @@ public:
break;
case EVENT_SIPHON_POWER:
DoCastSelf(SPELL_SIPHON_POWER);
events.ScheduleEvent(EVENT_SIPHON_POWER, 12s);
break;
case EVENT_SPARK_VOLLEY:
DoCastVictim(SPELL_SPARK_VOLLEY);
events.ScheduleEvent(EVENT_SPARK_VOLLEY, 39s);
DoCastSelf(SPELL_SPARK_VOLLEY);
events.ScheduleEvent(EVENT_SPARK_VOLLEY, 30s);
break;
case EVENT_STATIC_SURGE:
DoCastSelf(SPELL_STATIC_SURGE);
events.ScheduleEvent(EVENT_STATIC_SURGE, 15s);
break;
case EVENT_TITANIC_FIST:
DoCast(SPELL_TITANIC_FIST);
events.ScheduleEvent(EVENT_TITANIC_FIST, 34s);
DoCastSelf(SPELL_TITANIC_FIST);
events.ScheduleEvent(EVENT_TITANIC_FIST, 30s);
break;
default:
break;