aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp886
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp499
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp1089
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp1084
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp594
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp399
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp96
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h53
8 files changed, 2190 insertions, 2510 deletions
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
index f7d921875f9..72623c68ace 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
@@ -98,618 +98,562 @@ enum FathomlordKarathress
#define MAX_ADVISORS 3
//Fathom-Lord Karathress AI
-class boss_fathomlord_karathress : public CreatureScript
+struct boss_fathomlord_karathress : public BossAI
{
-public:
- boss_fathomlord_karathress() : CreatureScript("boss_fathomlord_karathress") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ boss_fathomlord_karathress(Creature* creature) : BossAI(creature, BOSS_FATHOM_LORD_KARATHRESS)
{
- return GetSerpentshrineCavernAI<boss_fathomlord_karathressAI>(creature);
+ Initialize();
}
- struct boss_fathomlord_karathressAI : public ScriptedAI
+ void Initialize()
{
- boss_fathomlord_karathressAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- CataclysmicBolt_Timer = 10000;
- Enrage_Timer = 600000; //10 minutes
- SearNova_Timer = 20000 + rand32() % 40000; // 20 - 60 seconds
-
- BlessingOfTides = false;
- }
-
- InstanceScript* instance;
+ CataclysmicBolt_Timer = 10000;
+ Enrage_Timer = 600000; //10 minutes
+ SearNova_Timer = 20000 + rand32() % 40000; // 20 - 60 seconds
- uint32 CataclysmicBolt_Timer;
- uint32 Enrage_Timer;
- uint32 SearNova_Timer;
+ BlessingOfTides = false;
+ }
- bool BlessingOfTides;
+ uint32 CataclysmicBolt_Timer;
+ uint32 Enrage_Timer;
+ uint32 SearNova_Timer;
- ObjectGuid Advisors[MAX_ADVISORS];
+ bool BlessingOfTides;
- void Reset() override
- {
- Initialize();
+ ObjectGuid Advisors[MAX_ADVISORS];
- ObjectGuid RAdvisors[MAX_ADVISORS];
- RAdvisors[0] = instance->GetGuidData(DATA_SHARKKIS);
- RAdvisors[1] = instance->GetGuidData(DATA_TIDALVESS);
- RAdvisors[2] = instance->GetGuidData(DATA_CARIBDIS);
- // Respawn of the 3 Advisors
- for (uint8 i = 0; i < MAX_ADVISORS; ++i)
+ void Reset() override
+ {
+ Initialize();
+
+ ObjectGuid RAdvisors[MAX_ADVISORS];
+ RAdvisors[0] = instance->GetGuidData(DATA_SHARKKIS);
+ RAdvisors[1] = instance->GetGuidData(DATA_TIDALVESS);
+ RAdvisors[2] = instance->GetGuidData(DATA_CARIBDIS);
+ // Respawn of the 3 Advisors
+ for (uint8 i = 0; i < MAX_ADVISORS; ++i)
+ if (!RAdvisors[i].IsEmpty())
{
- if (!RAdvisors[i].IsEmpty())
+ Creature* advisor = ObjectAccessor::GetCreature(*me, RAdvisors[i]);
+ if (advisor && !advisor->IsAlive())
{
- Creature* advisor = ObjectAccessor::GetCreature(*me, RAdvisors[i]);
- if (advisor && !advisor->IsAlive())
- {
- advisor->Respawn();
- advisor->AI()->EnterEvadeMode();
- advisor->GetMotionMaster()->MoveTargetedHome();
- }
+ advisor->Respawn();
+ advisor->AI()->EnterEvadeMode();
+ advisor->GetMotionMaster()->MoveTargetedHome();
}
}
- instance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
- }
+ _Reset();
+ }
- void EventSharkkisDeath()
- {
- Talk(SAY_GAIN_ABILITY1);
- DoCast(me, SPELL_POWER_OF_SHARKKIS);
- }
+ void EventSharkkisDeath()
+ {
+ Talk(SAY_GAIN_ABILITY1);
+ DoCast(me, SPELL_POWER_OF_SHARKKIS);
+ }
- void EventTidalvessDeath()
- {
- Talk(SAY_GAIN_ABILITY2);
- DoCast(me, SPELL_POWER_OF_TIDALVESS);
- }
+ void EventTidalvessDeath()
+ {
+ Talk(SAY_GAIN_ABILITY2);
+ DoCast(me, SPELL_POWER_OF_TIDALVESS);
+ }
- void EventCaribdisDeath()
- {
- Talk(SAY_GAIN_ABILITY3);
- DoCast(me, SPELL_POWER_OF_CARIBDIS);
- }
+ void EventCaribdisDeath()
+ {
+ Talk(SAY_GAIN_ABILITY3);
+ DoCast(me, SPELL_POWER_OF_CARIBDIS);
+ }
- void GetAdvisors()
- {
- Advisors[0] = instance->GetGuidData(DATA_SHARKKIS);
- Advisors[1] = instance->GetGuidData(DATA_TIDALVESS);
- Advisors[2] = instance->GetGuidData(DATA_CARIBDIS);
- }
+ void GetAdvisors()
+ {
+ Advisors[0] = instance->GetGuidData(DATA_SHARKKIS);
+ Advisors[1] = instance->GetGuidData(DATA_TIDALVESS);
+ Advisors[2] = instance->GetGuidData(DATA_CARIBDIS);
+ }
- void StartEvent(Unit* who)
- {
- GetAdvisors();
+ void StartEvent(Unit* who)
+ {
+ GetAdvisors();
- Talk(SAY_AGGRO);
- DoZoneInCombat();
+ Talk(SAY_AGGRO);
- instance->SetGuidData(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
- instance->SetData(DATA_KARATHRESSEVENT, IN_PROGRESS);
- }
+ instance->SetGuidData(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
+ }
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(SAY_SLAY);
- }
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ Talk(SAY_SLAY);
+ }
- void JustDied(Unit* /*killer*/) override
- {
- Talk(SAY_DEATH);
+ void JustDied(Unit* /*killer*/) override
+ {
+ Talk(SAY_DEATH);
- instance->SetData(DATA_FATHOMLORDKARATHRESSEVENT, DONE);
+ instance->SetData(DATA_FATHOMLORDKARATHRESSEVENT, DONE);
- //support for quest 10944
- me->SummonCreature(SEER_OLUM, OLUM_X, OLUM_Y, OLUM_Z, OLUM_O, TEMPSUMMON_TIMED_DESPAWN, 1h);
- }
+ //support for quest 10944
+ me->SummonCreature(SEER_OLUM, OLUM_X, OLUM_Y, OLUM_Z, OLUM_O, TEMPSUMMON_TIMED_DESPAWN, 1h);
+ }
- void JustEngagedWith(Unit* who) override
- {
- StartEvent(who);
- }
+ void JustEngagedWith(Unit* who) override
+ {
+ _JustEngagedWith(who);
+ StartEvent(who);
+ }
- void UpdateAI(uint32 diff) override
+ void UpdateAI(uint32 diff) override
+ {
+ //Only if not incombat check if the event is started
+ if (!me->IsInCombat() && instance->GetBossState(BOSS_FATHOM_LORD_KARATHRESS) == IN_PROGRESS)
{
- //Only if not incombat check if the event is started
- if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
+ if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
{
- if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
- {
- AttackStart(target);
- GetAdvisors();
- }
+ AttackStart(target);
+ GetAdvisors();
}
+ }
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
- //someone evaded!
- if (!instance->GetData(DATA_KARATHRESSEVENT))
- {
- EnterEvadeMode();
- return;
- }
+ //someone evaded!
+ if (instance->GetBossState(BOSS_FATHOM_LORD_KARATHRESS) == NOT_STARTED)
+ {
+ EnterEvadeMode();
+ return;
+ }
- //CataclysmicBolt_Timer
- if (CataclysmicBolt_Timer <= diff)
- {
- //select a random unit other than the main tank
- Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
+ //CataclysmicBolt_Timer
+ if (CataclysmicBolt_Timer <= diff)
+ {
+ //select a random unit other than the main tank
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
- //if there aren't other units, cast on the tank
- if (!target)
- target = me->GetVictim();
+ //if there aren't other units, cast on the tank
+ if (!target)
+ target = me->GetVictim();
- if (target)
- DoCast(target, SPELL_CATACLYSMIC_BOLT);
- CataclysmicBolt_Timer = 10000;
- } else CataclysmicBolt_Timer -= diff;
+ if (target)
+ DoCast(target, SPELL_CATACLYSMIC_BOLT);
+ CataclysmicBolt_Timer = 10000;
+ } else CataclysmicBolt_Timer -= diff;
- //SearNova_Timer
- if (SearNova_Timer <= diff)
- {
- DoCastVictim(SPELL_SEAR_NOVA);
- SearNova_Timer = 20000 + rand32() % 40000;
- } else SearNova_Timer -= diff;
+ //SearNova_Timer
+ if (SearNova_Timer <= diff)
+ {
+ DoCastVictim(SPELL_SEAR_NOVA);
+ SearNova_Timer = 20000 + rand32() % 40000;
+ } else SearNova_Timer -= diff;
- //Enrage_Timer
- if (Enrage_Timer <= diff)
- {
- DoCast(me, SPELL_ENRAGE);
- Enrage_Timer = 90000;
- } else Enrage_Timer -= diff;
+ //Enrage_Timer
+ if (Enrage_Timer <= diff)
+ {
+ DoCast(me, SPELL_ENRAGE);
+ Enrage_Timer = 90000;
+ } else Enrage_Timer -= diff;
- //Blessing of Tides Trigger
- if (!HealthAbovePct(75) && !BlessingOfTides)
- {
- BlessingOfTides = true;
- bool continueTriggering = false;
- for (uint8 i = 0; i < MAX_ADVISORS; ++i)
+ //Blessing of Tides Trigger
+ if (!HealthAbovePct(75) && !BlessingOfTides)
+ {
+ BlessingOfTides = true;
+ bool continueTriggering = false;
+ for (uint8 i = 0; i < MAX_ADVISORS; ++i)
+ if (!Advisors[i].IsEmpty())
{
- if (!Advisors[i].IsEmpty())
+ Creature* advisor = ObjectAccessor::GetCreature(*me, Advisors[i]);
+ if (advisor && advisor->IsAlive())
{
- Creature* advisor = ObjectAccessor::GetCreature(*me, Advisors[i]);
- if (advisor && advisor->IsAlive())
- {
- continueTriggering = true;
- break;
- }
+ continueTriggering = true;
+ break;
}
}
-
- if (continueTriggering)
- {
- DoCast(me, SPELL_BLESSING_OF_THE_TIDES);
- Talk(SAY_GAIN_BLESSING);
- }
+ if (continueTriggering)
+ {
+ DoCast(me, SPELL_BLESSING_OF_THE_TIDES);
+ Talk(SAY_GAIN_BLESSING);
}
-
- DoMeleeAttackIfReady();
}
- };
+ DoMeleeAttackIfReady();
+ }
};
//Fathom-Guard Sharkkis AI
-class boss_fathomguard_sharkkis : public CreatureScript
+struct boss_fathomguard_sharkkis : public ScriptedAI
{
-public:
- boss_fathomguard_sharkkis() : CreatureScript("boss_fathomguard_sharkkis") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ boss_fathomguard_sharkkis(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<boss_fathomguard_sharkkisAI>(creature);
+ Initialize();
+ instance = creature->GetInstanceScript();
}
- struct boss_fathomguard_sharkkisAI : public ScriptedAI
+ void Initialize()
{
- boss_fathomguard_sharkkisAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ LeechingThrow_Timer = 20000;
+ TheBeastWithin_Timer = 30000;
+ Multishot_Timer = 15000;
+ Pet_Timer = 10000;
- void Initialize()
- {
- LeechingThrow_Timer = 20000;
- TheBeastWithin_Timer = 30000;
- Multishot_Timer = 15000;
- Pet_Timer = 10000;
+ pet = false;
+ }
- pet = false;
- }
+ InstanceScript* instance;
- InstanceScript* instance;
+ uint32 LeechingThrow_Timer;
+ uint32 TheBeastWithin_Timer;
+ uint32 Multishot_Timer;
+ uint32 Pet_Timer;
- uint32 LeechingThrow_Timer;
- uint32 TheBeastWithin_Timer;
- uint32 Multishot_Timer;
- uint32 Pet_Timer;
+ bool pet;
- bool pet;
+ ObjectGuid SummonedPet;
- ObjectGuid SummonedPet;
+ void Reset() override
+ {
+ Initialize();
- void Reset() override
- {
- Initialize();
+ Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet);
+ if (Pet && Pet->IsAlive())
+ Pet->KillSelf();
- Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet);
- if (Pet && Pet->IsAlive())
- Pet->KillSelf();
+ SummonedPet.Clear();
- SummonedPet.Clear();
+ instance->SetBossState(BOSS_FATHOM_LORD_KARATHRESS, NOT_STARTED);
+ }
- instance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KARATHRESS)))
+ ENSURE_AI(boss_fathomlord_karathress, Karathress->AI())->EventSharkkisDeath();
+ }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ instance->SetGuidData(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
+ instance->SetBossState(BOSS_FATHOM_LORD_KARATHRESS, IN_PROGRESS);
+ }
- void JustDied(Unit* /*killer*/) override
+ void UpdateAI(uint32 diff) override
+ {
+ //Only if not incombat check if the event is started
+ if (!me->IsInCombat() && instance->GetBossState(BOSS_FATHOM_LORD_KARATHRESS) == IN_PROGRESS)
{
- if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KARATHRESS)))
- ENSURE_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventSharkkisDeath();
+ if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
+ AttackStart(target);
}
- void JustEngagedWith(Unit* who) override
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ //someone evaded!
+ if (instance->GetBossState(BOSS_FATHOM_LORD_KARATHRESS) == NOT_STARTED)
{
- instance->SetGuidData(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
- instance->SetData(DATA_KARATHRESSEVENT, IN_PROGRESS);
+ EnterEvadeMode();
+ return;
}
- void UpdateAI(uint32 diff) override
+ //LeechingThrow_Timer
+ if (LeechingThrow_Timer <= diff)
{
- //Only if not incombat check if the event is started
- if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
- {
- if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
- AttackStart(target);
- }
+ DoCastVictim(SPELL_LEECHING_THROW);
+ LeechingThrow_Timer = 20000;
+ } else LeechingThrow_Timer -= diff;
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ //Multishot_Timer
+ if (Multishot_Timer <= diff)
+ {
+ DoCastVictim(SPELL_MULTISHOT);
+ Multishot_Timer = 20000;
+ } else Multishot_Timer -= diff;
- //someone evaded!
- if (!instance->GetData(DATA_KARATHRESSEVENT))
- {
- EnterEvadeMode();
- return;
- }
+ //TheBeastWithin_Timer
+ if (TheBeastWithin_Timer <= diff)
+ {
+ DoCast(me, SPELL_THE_BEAST_WITHIN);
- //LeechingThrow_Timer
- if (LeechingThrow_Timer <= diff)
- {
- DoCastVictim(SPELL_LEECHING_THROW);
- LeechingThrow_Timer = 20000;
- } else LeechingThrow_Timer -= diff;
+ Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet);
+ if (Pet && Pet->IsAlive())
+ Pet->CastSpell(Pet, SPELL_PET_ENRAGE, true);
- //Multishot_Timer
- if (Multishot_Timer <= diff)
- {
- DoCastVictim(SPELL_MULTISHOT);
- Multishot_Timer = 20000;
- } else Multishot_Timer -= diff;
+ TheBeastWithin_Timer = 30000;
+ } else TheBeastWithin_Timer -= diff;
- //TheBeastWithin_Timer
- if (TheBeastWithin_Timer <= diff)
+ //Pet_Timer
+ if (Pet_Timer < diff && pet == false)
+ {
+ pet = true;
+ //uint32 spell_id;
+ uint32 pet_id;
+ if (!urand(0, 1))
{
- DoCast(me, SPELL_THE_BEAST_WITHIN);
-
- Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet);
- if (Pet && Pet->IsAlive())
- Pet->CastSpell(Pet, SPELL_PET_ENRAGE, true);
-
- TheBeastWithin_Timer = 30000;
- } else TheBeastWithin_Timer -= diff;
-
- //Pet_Timer
- if (Pet_Timer < diff && pet == false)
+ //spell_id = SPELL_SUMMON_FATHOM_LURKER;
+ pet_id = CREATURE_FATHOM_LURKER;
+ }
+ else
{
- pet = true;
- //uint32 spell_id;
- uint32 pet_id;
- if (!urand(0, 1))
- {
- //spell_id = SPELL_SUMMON_FATHOM_LURKER;
- pet_id = CREATURE_FATHOM_LURKER;
- }
- else
- {
- //spell_id = SPELL_SUMMON_FATHOM_SPOREBAT;
- pet_id = CREATURE_FATHOM_SPOREBAT;
- }
- //DoCast(me, spell_id, true);
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ //spell_id = SPELL_SUMMON_FATHOM_SPOREBAT;
+ pet_id = CREATURE_FATHOM_SPOREBAT;
+ }
+ //DoCast(me, spell_id, true);
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ {
+ if (Creature* Pet = DoSpawnCreature(pet_id, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s))
{
- if (Creature* Pet = DoSpawnCreature(pet_id, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s))
- {
- Pet->AI()->AttackStart(target);
- SummonedPet = Pet->GetGUID();
- }
+ Pet->AI()->AttackStart(target);
+ SummonedPet = Pet->GetGUID();
}
- } else Pet_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
+ }
+ } else Pet_Timer -= diff;
+ DoMeleeAttackIfReady();
+ }
};
//Fathom-Guard Tidalvess AI
-class boss_fathomguard_tidalvess : public CreatureScript
+struct boss_fathomguard_tidalvess : public ScriptedAI
{
-public:
- boss_fathomguard_tidalvess() : CreatureScript("boss_fathomguard_tidalvess") { }
+ boss_fathomguard_tidalvess(Creature* creature) : ScriptedAI(creature)
+ {
+ Initialize();
+ instance = creature->GetInstanceScript();
+ }
- CreatureAI* GetAI(Creature* creature) const override
+ void Initialize()
{
- return GetSerpentshrineCavernAI<boss_fathomguard_tidalvessAI>(creature);
+ FrostShock_Timer = 25000;
+ Spitfire_Timer = 60000;
+ PoisonCleansing_Timer = 30000;
+ Earthbind_Timer = 45000;
}
- struct boss_fathomguard_tidalvessAI : public ScriptedAI
+ InstanceScript* instance;
+
+ uint32 FrostShock_Timer;
+ uint32 Spitfire_Timer;
+ uint32 PoisonCleansing_Timer;
+ uint32 Earthbind_Timer;
+
+ void Reset() override
{
- boss_fathomguard_tidalvessAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ Initialize();
- void Initialize()
- {
- FrostShock_Timer = 25000;
- Spitfire_Timer = 60000;
- PoisonCleansing_Timer = 30000;
- Earthbind_Timer = 45000;
- }
+ instance->SetBossState(BOSS_FATHOM_LORD_KARATHRESS, NOT_STARTED);
+ }
- InstanceScript* instance;
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KARATHRESS)))
+ ENSURE_AI(boss_fathomlord_karathress, Karathress->AI())->EventTidalvessDeath();
+ }
- uint32 FrostShock_Timer;
- uint32 Spitfire_Timer;
- uint32 PoisonCleansing_Timer;
- uint32 Earthbind_Timer;
+ void JustEngagedWith(Unit* who) override
+ {
+ instance->SetGuidData(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
+ instance->SetBossState(BOSS_FATHOM_LORD_KARATHRESS, IN_PROGRESS);
+ DoCast(me, SPELL_WINDFURY_WEAPON);
+ }
- void Reset() override
+ void UpdateAI(uint32 diff) override
+ {
+ //Only if not incombat check if the event is started
+ if (!me->IsInCombat() && instance->GetBossState(BOSS_FATHOM_LORD_KARATHRESS) == IN_PROGRESS)
{
- Initialize();
-
- instance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
+ if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
+ AttackStart(target);
}
- void JustDied(Unit* /*killer*/) override
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ //someone evaded!
+ if (instance->GetBossState(BOSS_FATHOM_LORD_KARATHRESS) == NOT_STARTED)
{
- if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KARATHRESS)))
- ENSURE_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventTidalvessDeath();
+ EnterEvadeMode();
+ return;
}
- void JustEngagedWith(Unit* who) override
+ if (!me->HasAura(SPELL_WINDFURY_WEAPON))
{
- instance->SetGuidData(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
- instance->SetData(DATA_KARATHRESSEVENT, IN_PROGRESS);
DoCast(me, SPELL_WINDFURY_WEAPON);
}
- void UpdateAI(uint32 diff) override
+ //FrostShock_Timer
+ if (FrostShock_Timer <= diff)
{
- //Only if not incombat check if the event is started
- if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
- {
- if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
- AttackStart(target);
- }
-
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- //someone evaded!
- if (!instance->GetData(DATA_KARATHRESSEVENT))
- {
- EnterEvadeMode();
- return;
- }
-
- if (!me->HasAura(SPELL_WINDFURY_WEAPON))
- {
- DoCast(me, SPELL_WINDFURY_WEAPON);
- }
-
- //FrostShock_Timer
- if (FrostShock_Timer <= diff)
- {
- DoCastVictim(SPELL_FROST_SHOCK);
- FrostShock_Timer = 25000 + rand32() % 5000;
- } else FrostShock_Timer -= diff;
-
- //Spitfire_Timer
- if (Spitfire_Timer <= diff)
- {
- DoCast(me, SPELL_SPITFIRE_TOTEM);
- if (Unit* SpitfireTotem = me->FindNearestCreature(CREATURE_SPITFIRE_TOTEM, 100.0f))
- SpitfireTotem->ToCreature()->AI()->AttackStart(me->GetVictim());
+ DoCastVictim(SPELL_FROST_SHOCK);
+ FrostShock_Timer = 25000 + rand32() % 5000;
+ } else FrostShock_Timer -= diff;
- Spitfire_Timer = 60000;
- }
- else
- Spitfire_Timer -= diff;
+ //Spitfire_Timer
+ if (Spitfire_Timer <= diff)
+ {
+ DoCast(me, SPELL_SPITFIRE_TOTEM);
+ if (Unit* SpitfireTotem = me->FindNearestCreature(CREATURE_SPITFIRE_TOTEM, 100.0f))
+ SpitfireTotem->ToCreature()->AI()->AttackStart(me->GetVictim());
- //PoisonCleansing_Timer
- if (PoisonCleansing_Timer <= diff)
- {
- DoCast(me, SPELL_POISON_CLEANSING_TOTEM);
- PoisonCleansing_Timer = 30000;
- }
- else
- PoisonCleansing_Timer -= diff;
+ Spitfire_Timer = 60000;
+ }
+ else
+ Spitfire_Timer -= diff;
- //Earthbind_Timer
- if (Earthbind_Timer <= diff)
- {
- DoCast(me, SPELL_EARTHBIND_TOTEM);
- Earthbind_Timer = 45000;
- }
- else
- Earthbind_Timer -= diff;
+ //PoisonCleansing_Timer
+ if (PoisonCleansing_Timer <= diff)
+ {
+ DoCast(me, SPELL_POISON_CLEANSING_TOTEM);
+ PoisonCleansing_Timer = 30000;
+ }
+ else
+ PoisonCleansing_Timer -= diff;
- DoMeleeAttackIfReady();
+ //Earthbind_Timer
+ if (Earthbind_Timer <= diff)
+ {
+ DoCast(me, SPELL_EARTHBIND_TOTEM);
+ Earthbind_Timer = 45000;
}
- };
+ else
+ Earthbind_Timer -= diff;
+ DoMeleeAttackIfReady();
+ }
};
//Fathom-Guard Caribdis AI
-class boss_fathomguard_caribdis : public CreatureScript
+struct boss_fathomguard_caribdis : public ScriptedAI
{
-public:
- boss_fathomguard_caribdis() : CreatureScript("boss_fathomguard_caribdis") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ boss_fathomguard_caribdis(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<boss_fathomguard_caribdisAI>(creature);
+ Initialize();
+ instance = creature->GetInstanceScript();
}
- struct boss_fathomguard_caribdisAI : public ScriptedAI
+ void Initialize()
{
- boss_fathomguard_caribdisAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ WaterBoltVolley_Timer = 35000;
+ TidalSurge_Timer = 15000 + rand32() % 5000;
+ Heal_Timer = 55000;
+ Cyclone_Timer = 30000 + rand32() % 10000;
+ }
- void Initialize()
- {
- WaterBoltVolley_Timer = 35000;
- TidalSurge_Timer = 15000 + rand32() % 5000;
- Heal_Timer = 55000;
- Cyclone_Timer = 30000 + rand32() % 10000;
- }
+ InstanceScript* instance;
- InstanceScript* instance;
+ uint32 WaterBoltVolley_Timer;
+ uint32 TidalSurge_Timer;
+ uint32 Heal_Timer;
+ uint32 Cyclone_Timer;
- uint32 WaterBoltVolley_Timer;
- uint32 TidalSurge_Timer;
- uint32 Heal_Timer;
- uint32 Cyclone_Timer;
+ void Reset() override
+ {
+ Initialize();
- void Reset() override
- {
- Initialize();
+ instance->SetBossState(BOSS_FATHOM_LORD_KARATHRESS, NOT_STARTED);
+ }
- instance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KARATHRESS)))
+ ENSURE_AI(boss_fathomlord_karathress, Karathress->AI())->EventCaribdisDeath();
+ }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ instance->SetGuidData(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
+ instance->SetBossState(BOSS_FATHOM_LORD_KARATHRESS, IN_PROGRESS);
+ }
- void JustDied(Unit* /*killer*/) override
+ void UpdateAI(uint32 diff) override
+ {
+ //Only if not incombat check if the event is started
+ if (!me->IsInCombat() && instance->GetBossState(BOSS_FATHOM_LORD_KARATHRESS) == IN_PROGRESS)
{
- if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KARATHRESS)))
- ENSURE_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventCaribdisDeath();
+ if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
+ AttackStart(target);
}
- void JustEngagedWith(Unit* who) override
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ //someone evaded!
+ if (instance->GetBossState(BOSS_FATHOM_LORD_KARATHRESS) == NOT_STARTED)
{
- instance->SetGuidData(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
- instance->SetData(DATA_KARATHRESSEVENT, IN_PROGRESS);
+ EnterEvadeMode();
+ return;
}
- void UpdateAI(uint32 diff) override
+ //WaterBoltVolley_Timer
+ if (WaterBoltVolley_Timer <= diff)
{
- //Only if not incombat check if the event is started
- if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
- {
- if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
- AttackStart(target);
- }
-
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ DoCastVictim(SPELL_WATER_BOLT_VOLLEY);
+ WaterBoltVolley_Timer = 30000;
+ } else WaterBoltVolley_Timer -= diff;
- //someone evaded!
- if (!instance->GetData(DATA_KARATHRESSEVENT))
- {
- EnterEvadeMode();
- return;
- }
-
- //WaterBoltVolley_Timer
- if (WaterBoltVolley_Timer <= diff)
- {
- DoCastVictim(SPELL_WATER_BOLT_VOLLEY);
- WaterBoltVolley_Timer = 30000;
- } else WaterBoltVolley_Timer -= diff;
+ //TidalSurge_Timer
+ if (TidalSurge_Timer <= diff)
+ {
+ DoCastSelf(SPELL_TIDAL_SURGE);
+ TidalSurge_Timer = 15000 + rand32() % 5000;
+ } else TidalSurge_Timer -= diff;
- //TidalSurge_Timer
- if (TidalSurge_Timer <= diff)
- {
- DoCastSelf(SPELL_TIDAL_SURGE);
- TidalSurge_Timer = 15000 + rand32() % 5000;
- } else TidalSurge_Timer -= diff;
+ //Cyclone_Timer
+ if (Cyclone_Timer <= diff)
+ {
+ //DoCast(me, SPELL_SUMMON_CYCLONE); // Doesn't work
+ Cyclone_Timer = 30000 + rand32() % 10000;
- //Cyclone_Timer
- if (Cyclone_Timer <= diff)
+ if (Creature* Cyclone = me->SummonCreature(CREATURE_CYCLONE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), float(rand32() % 5), TEMPSUMMON_TIMED_DESPAWN, 15s))
{
- //DoCast(me, SPELL_SUMMON_CYCLONE); // Doesn't work
- Cyclone_Timer = 30000 + rand32() % 10000;
-
- if (Creature* Cyclone = me->SummonCreature(CREATURE_CYCLONE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), float(rand32() % 5), TEMPSUMMON_TIMED_DESPAWN, 15s))
- {
- Cyclone->SetObjectScale(3.0f);
- Cyclone->SetFaction(me->GetFaction());
- Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true);
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- Cyclone->AI()->AttackStart(target);
- }
+ Cyclone->SetObjectScale(3.0f);
+ Cyclone->SetFaction(me->GetFaction());
+ Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true);
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ Cyclone->AI()->AttackStart(target);
}
- else
- Cyclone_Timer -= diff;
-
- //Heal_Timer
- if (Heal_Timer <= diff)
- {
- // It can be cast on any of the mobs
- Unit* unit = nullptr;
+ }
+ else
+ Cyclone_Timer -= diff;
- while (unit == nullptr || !unit->IsAlive())
- unit = selectAdvisorUnit();
+ //Heal_Timer
+ if (Heal_Timer <= diff)
+ {
+ // It can be cast on any of the mobs
+ Unit* unit = nullptr;
- DoCast(unit, SPELL_HEAL);
- Heal_Timer = 60000;
- }
- else
- Heal_Timer -= diff;
+ while (unit == nullptr || !unit->IsAlive())
+ unit = selectAdvisorUnit();
- DoMeleeAttackIfReady();
+ DoCast(unit, SPELL_HEAL);
+ Heal_Timer = 60000;
}
+ else
+ Heal_Timer -= diff;
- Unit* selectAdvisorUnit()
+ DoMeleeAttackIfReady();
+ }
+
+ Unit* selectAdvisorUnit()
+ {
+ Unit* unit = nullptr;
+ switch (rand32() % 4)
{
- Unit* unit = nullptr;
- switch (rand32() % 4)
- {
- case 0:
- unit = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESS));
- break;
- case 1:
- unit = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_SHARKKIS));
- break;
- case 2:
- unit = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_TIDALVESS));
- break;
- case 3:
- unit = me;
- break;
- }
- return unit;
+ case 0:
+ unit = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESS));
+ break;
+ case 1:
+ unit = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_SHARKKIS));
+ break;
+ case 2:
+ unit = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_TIDALVESS));
+ break;
+ case 3:
+ unit = me;
+ break;
}
- };
+ return unit;
+ }
};
// 38358 - Tidal Surge
@@ -735,9 +679,9 @@ class spell_fathomlord_karathress_tidal_surge : public SpellScript
void AddSC_boss_fathomlord_karathress()
{
- new boss_fathomlord_karathress();
- new boss_fathomguard_sharkkis();
- new boss_fathomguard_tidalvess();
- new boss_fathomguard_caribdis();
+ RegisterSerpentshrineCavernCreatureAI(boss_fathomlord_karathress);
+ RegisterSerpentshrineCavernCreatureAI(boss_fathomguard_sharkkis);
+ RegisterSerpentshrineCavernCreatureAI(boss_fathomguard_tidalvess);
+ RegisterSerpentshrineCavernCreatureAI(boss_fathomguard_caribdis);
RegisterSpellScript(spell_fathomlord_karathress_tidal_surge);
}
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp
index 19fb7ef0cdd..f22d7fe791a 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp
@@ -80,329 +80,304 @@ enum HydrossTheUnstable
#define SPAWN_X_DIFF4 12.577011f
#define SPAWN_Y_DIFF4 4.72702f
-class boss_hydross_the_unstable : public CreatureScript
+struct boss_hydross_the_unstable : public BossAI
{
-public:
- boss_hydross_the_unstable() : CreatureScript("boss_hydross_the_unstable") { }
+ boss_hydross_the_unstable(Creature* creature) : BossAI(creature, BOSS_HYDROSS_THE_UNSTABLE)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ beams[0].Clear();
+ beams[1].Clear();
+ PosCheck_Timer = 2500;
+ MarkOfHydross_Timer = 15000;
+ MarkOfCorruption_Timer = 15000;
+ WaterTomb_Timer = 7000;
+ VileSludge_Timer = 7000;
+ MarkOfHydross_Count = 0;
+ MarkOfCorruption_Count = 0;
+ EnrageTimer = 600000;
+
+ CorruptedForm = false;
+ beam = false;
+ }
- CreatureAI* GetAI(Creature* creature) const override
+ ObjectGuid beams[2];
+ uint32 PosCheck_Timer;
+ uint32 MarkOfHydross_Timer;
+ uint32 MarkOfCorruption_Timer;
+ uint32 WaterTomb_Timer;
+ uint32 VileSludge_Timer;
+ uint32 MarkOfHydross_Count;
+ uint32 MarkOfCorruption_Count;
+ uint32 EnrageTimer;
+ bool CorruptedForm;
+ bool beam;
+
+ void Reset() override
{
- return GetSerpentshrineCavernAI<boss_hydross_the_unstableAI>(creature);
+ DeSummonBeams();
+ Initialize();
+
+ me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST);
+ me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
+ me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false);
+
+ me->SetDisplayId(MODEL_CLEAN);
+
+ _Reset();
}
- struct boss_hydross_the_unstableAI : public ScriptedAI
+ void SummonBeams()
{
- boss_hydross_the_unstableAI(Creature* creature) : ScriptedAI(creature), Summons(me)
+ Creature* beamer = me->SummonCreature(ENTRY_BEAM_DUMMY, -258.333f, -356.34f, 22.0499f, 5.90835f, TEMPSUMMON_CORPSE_DESPAWN);
+ if (beamer)
{
- Initialize();
- instance = creature->GetInstanceScript();
+ beamer->CastSpell(me, SPELL_BLUE_BEAM, true);
+ beamer->SetDisplayId(11686); //invisible
+ beams[0] = beamer->GetGUID();
}
-
- void Initialize()
+ beamer = me->SummonCreature(ENTRY_BEAM_DUMMY, -219.918f, -371.308f, 22.0042f, 2.73072f, TEMPSUMMON_CORPSE_DESPAWN);
+ if (beamer)
{
- beams[0].Clear();
- beams[1].Clear();
- PosCheck_Timer = 2500;
- MarkOfHydross_Timer = 15000;
- MarkOfCorruption_Timer = 15000;
- WaterTomb_Timer = 7000;
- VileSludge_Timer = 7000;
- MarkOfHydross_Count = 0;
- MarkOfCorruption_Count = 0;
- EnrageTimer = 600000;
-
- CorruptedForm = false;
- beam = false;
+ beamer->CastSpell(me, SPELL_BLUE_BEAM, true);
+ beamer->SetDisplayId(11686); //invisible
+ beams[1] = beamer->GetGUID();
}
+ }
- InstanceScript* instance;
-
- ObjectGuid beams[2];
- uint32 PosCheck_Timer;
- uint32 MarkOfHydross_Timer;
- uint32 MarkOfCorruption_Timer;
- uint32 WaterTomb_Timer;
- uint32 VileSludge_Timer;
- uint32 MarkOfHydross_Count;
- uint32 MarkOfCorruption_Count;
- uint32 EnrageTimer;
- bool CorruptedForm;
- bool beam;
- SummonList Summons;
-
- void Reset() override
+ void DeSummonBeams()
+ {
+ for (uint8 i = 0; i < 2; ++i)
{
- DeSummonBeams();
- Initialize();
+ if (Creature* mob = ObjectAccessor::GetCreature(*me, beams[i]))
+ mob->DespawnOrUnsummon();
+ }
+ }
- me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST);
- me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
- me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false);
+ void JustEngagedWith(Unit* who) override
+ {
+ Talk(SAY_AGGRO);
- me->SetDisplayId(MODEL_CLEAN);
+ _JustEngagedWith(who);
+ }
- instance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED);
- Summons.DespawnAll();
- }
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ Talk(CorruptedForm ? SAY_CORRUPT_SLAY : SAY_CLEAN_SLAY);
+ }
- void SummonBeams()
- {
- Creature* beamer = me->SummonCreature(ENTRY_BEAM_DUMMY, -258.333f, -356.34f, 22.0499f, 5.90835f, TEMPSUMMON_CORPSE_DESPAWN);
- if (beamer)
- {
- beamer->CastSpell(me, SPELL_BLUE_BEAM, true);
- beamer->SetDisplayId(11686); //invisible
- beams[0] = beamer->GetGUID();
- }
- beamer = me->SummonCreature(ENTRY_BEAM_DUMMY, -219.918f, -371.308f, 22.0042f, 2.73072f, TEMPSUMMON_CORPSE_DESPAWN);
- if (beamer)
- {
- beamer->CastSpell(me, SPELL_BLUE_BEAM, true);
- beamer->SetDisplayId(11686); //invisible
- beams[1] = beamer->GetGUID();
- }
- }
- void DeSummonBeams()
- {
- for (uint8 i = 0; i < 2; ++i)
- {
- if (Creature* mob = ObjectAccessor::GetCreature(*me, beams[i]))
- {
- mob->DespawnOrUnsummon();
- }
- }
- }
- void JustEngagedWith(Unit* /*who*/) override
- {
- Talk(SAY_AGGRO);
+ void JustSummoned(Creature* summoned) override
+ {
+ if (summoned->GetEntry() == ENTRY_PURE_SPAWN)
+ summoned->CastSpell(summoned, SPELL_ELEMENTAL_SPAWNIN, true);
- instance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, IN_PROGRESS);
- }
+ if (summoned->GetEntry() == ENTRY_TAINTED_SPAWN)
+ summoned->CastSpell(summoned, SPELL_ELEMENTAL_SPAWNIN, true);
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(CorruptedForm ? SAY_CORRUPT_SLAY : SAY_CLEAN_SLAY);
- }
+ BossAI::JustSummoned(summoned);
+ }
- void JustSummoned(Creature* summoned) override
- {
- if (summoned->GetEntry() == ENTRY_PURE_SPAWN)
- {
- summoned->CastSpell(summoned, SPELL_ELEMENTAL_SPAWNIN, true);
- Summons.Summon(summoned);
- }
- if (summoned->GetEntry() == ENTRY_TAINTED_SPAWN)
- {
- summoned->CastSpell(summoned, SPELL_ELEMENTAL_SPAWNIN, true);
- Summons.Summon(summoned);
- }
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ Talk(CorruptedForm ? SAY_CORRUPT_DEATH : SAY_CLEAN_DEATH);
- void SummonedCreatureDespawn(Creature* summon) override
- {
- Summons.Despawn(summon);
- }
+ _JustDied();
+ }
- void JustDied(Unit* /*killer*/) override
+ void UpdateAI(uint32 diff) override
+ {
+ if (!beam)
{
- Talk(CorruptedForm ? SAY_CORRUPT_DEATH : SAY_CLEAN_DEATH);
-
- instance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, DONE);
- Summons.DespawnAll();
+ SummonBeams();
+ beam = true;
}
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
- void UpdateAI(uint32 diff) override
+ // corrupted form
+ if (CorruptedForm)
{
- if (!beam)
- {
- SummonBeams();
- beam = true;
- }
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- // corrupted form
- if (CorruptedForm)
+ //MarkOfCorruption_Timer
+ if (MarkOfCorruption_Timer <= diff)
{
- //MarkOfCorruption_Timer
- if (MarkOfCorruption_Timer <= diff)
+ if (MarkOfCorruption_Count <= 5)
{
- if (MarkOfCorruption_Count <= 5)
- {
- uint32 mark_spell = 0;
+ uint32 mark_spell = 0;
- switch (MarkOfCorruption_Count)
- {
- case 0:
- mark_spell = SPELL_MARK_OF_CORRUPTION1;
- break;
+ switch (MarkOfCorruption_Count)
+ {
+ case 0:
+ mark_spell = SPELL_MARK_OF_CORRUPTION1;
+ break;
- case 1:
- mark_spell = SPELL_MARK_OF_CORRUPTION2;
- break;
+ case 1:
+ mark_spell = SPELL_MARK_OF_CORRUPTION2;
+ break;
- case 2:
- mark_spell = SPELL_MARK_OF_CORRUPTION3;
- break;
+ case 2:
+ mark_spell = SPELL_MARK_OF_CORRUPTION3;
+ break;
- case 3:
- mark_spell = SPELL_MARK_OF_CORRUPTION4;
- break;
+ case 3:
+ mark_spell = SPELL_MARK_OF_CORRUPTION4;
+ break;
- case 4:
- mark_spell = SPELL_MARK_OF_CORRUPTION5;
- break;
+ case 4:
+ mark_spell = SPELL_MARK_OF_CORRUPTION5;
+ break;
- case 5:
- mark_spell = SPELL_MARK_OF_CORRUPTION6;
- break;
- }
+ case 5:
+ mark_spell = SPELL_MARK_OF_CORRUPTION6;
+ break;
+ }
- DoCastVictim(mark_spell);
+ DoCastVictim(mark_spell);
- if (MarkOfCorruption_Count < 5)
- ++MarkOfCorruption_Count;
- }
+ if (MarkOfCorruption_Count < 5)
+ ++MarkOfCorruption_Count;
+ }
- MarkOfCorruption_Timer = 15000;
- } else MarkOfCorruption_Timer -= diff;
+ MarkOfCorruption_Timer = 15000;
+ } else MarkOfCorruption_Timer -= diff;
- //VileSludge_Timer
- if (VileSludge_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- DoCast(target, SPELL_VILE_SLUDGE);
+ //VileSludge_Timer
+ if (VileSludge_Timer <= diff)
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ DoCast(target, SPELL_VILE_SLUDGE);
- VileSludge_Timer = 15000;
- } else VileSludge_Timer -= diff;
+ VileSludge_Timer = 15000;
+ } else VileSludge_Timer -= diff;
- //PosCheck_Timer
- if (PosCheck_Timer <= diff)
+ //PosCheck_Timer
+ if (PosCheck_Timer <= diff)
+ {
+ if (me->IsWithinDist2d(HYDROSS_X, HYDROSS_Y, SWITCH_RADIUS))
{
- if (me->IsWithinDist2d(HYDROSS_X, HYDROSS_Y, SWITCH_RADIUS))
- {
- // switch to clean form
- me->SetDisplayId(MODEL_CLEAN);
- CorruptedForm = false;
- MarkOfHydross_Count = 0;
-
- Talk(SAY_SWITCH_TO_CLEAN);
- ResetThreatList();
- SummonBeams();
-
- // spawn 4 adds
- DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
- DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
- DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
- DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
-
- me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST);
- me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
- me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false);
- }
+ // switch to clean form
+ me->SetDisplayId(MODEL_CLEAN);
+ CorruptedForm = false;
+ MarkOfHydross_Count = 0;
+
+ Talk(SAY_SWITCH_TO_CLEAN);
+ ResetThreatList();
+ SummonBeams();
+
+ // spawn 4 adds
+ DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
+ DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
+ DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
+ DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
+
+ me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST);
+ me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
+ me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false);
+ }
- PosCheck_Timer = 2500;
- } else PosCheck_Timer -=diff;
- }
- // clean form
- else
+ PosCheck_Timer = 2500;
+ } else PosCheck_Timer -=diff;
+ }
+ // clean form
+ else
+ {
+ //MarkOfHydross_Timer
+ if (MarkOfHydross_Timer <= diff)
{
- //MarkOfHydross_Timer
- if (MarkOfHydross_Timer <= diff)
+ if (MarkOfHydross_Count <= 5)
{
- if (MarkOfHydross_Count <= 5)
- {
- uint32 mark_spell = 0;
-
- switch (MarkOfHydross_Count)
- {
- case 0:
- mark_spell = SPELL_MARK_OF_HYDROSS1;
- break;
-
- case 1:
- mark_spell = SPELL_MARK_OF_HYDROSS2;
- break;
+ uint32 mark_spell = 0;
- case 2:
- mark_spell = SPELL_MARK_OF_HYDROSS3;
- break;
+ switch (MarkOfHydross_Count)
+ {
+ case 0:
+ mark_spell = SPELL_MARK_OF_HYDROSS1;
+ break;
- case 3:
- mark_spell = SPELL_MARK_OF_HYDROSS4;
- break;
+ case 1:
+ mark_spell = SPELL_MARK_OF_HYDROSS2;
+ break;
- case 4:
- mark_spell = SPELL_MARK_OF_HYDROSS5;
- break;
+ case 2:
+ mark_spell = SPELL_MARK_OF_HYDROSS3;
+ break;
- case 5:
- mark_spell = SPELL_MARK_OF_HYDROSS6;
- break;
- }
+ case 3:
+ mark_spell = SPELL_MARK_OF_HYDROSS4;
+ break;
- DoCastVictim(mark_spell);
+ case 4:
+ mark_spell = SPELL_MARK_OF_HYDROSS5;
+ break;
- if (MarkOfHydross_Count < 5)
- ++MarkOfHydross_Count;
+ case 5:
+ mark_spell = SPELL_MARK_OF_HYDROSS6;
+ break;
}
- MarkOfHydross_Timer = 15000;
- } else MarkOfHydross_Timer -= diff;
+ DoCastVictim(mark_spell);
- //WaterTomb_Timer
- if (WaterTomb_Timer <= diff)
- {
- Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true);
- if (target)
- DoCast(target, SPELL_WATER_TOMB);
+ if (MarkOfHydross_Count < 5)
+ ++MarkOfHydross_Count;
+ }
- WaterTomb_Timer = 7000;
- } else WaterTomb_Timer -= diff;
+ MarkOfHydross_Timer = 15000;
+ } else MarkOfHydross_Timer -= diff;
- //PosCheck_Timer
- if (PosCheck_Timer <= diff)
- {
- if (!me->IsWithinDist2d(HYDROSS_X, HYDROSS_Y, SWITCH_RADIUS))
- {
- // switch to corrupted form
- me->SetDisplayId(MODEL_CORRUPT);
- MarkOfCorruption_Count = 0;
- CorruptedForm = true;
-
- Talk(SAY_SWITCH_TO_CORRUPT);
- ResetThreatList();
- DeSummonBeams();
-
- // spawn 4 adds
- DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
- DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
- DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
- DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
-
- me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE);
- me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
- me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, false);
- }
+ //WaterTomb_Timer
+ if (WaterTomb_Timer <= diff)
+ {
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true);
+ if (target)
+ DoCast(target, SPELL_WATER_TOMB);
- PosCheck_Timer = 2500;
- } else PosCheck_Timer -=diff;
- }
+ WaterTomb_Timer = 7000;
+ } else WaterTomb_Timer -= diff;
- //EnrageTimer
- if (EnrageTimer <= diff)
+ //PosCheck_Timer
+ if (PosCheck_Timer <= diff)
{
- DoCast(me, SPELL_ENRAGE);
- EnrageTimer = 60000;
- } else EnrageTimer -= diff;
+ if (!me->IsWithinDist2d(HYDROSS_X, HYDROSS_Y, SWITCH_RADIUS))
+ {
+ // switch to corrupted form
+ me->SetDisplayId(MODEL_CORRUPT);
+ MarkOfCorruption_Count = 0;
+ CorruptedForm = true;
+
+ Talk(SAY_SWITCH_TO_CORRUPT);
+ ResetThreatList();
+ DeSummonBeams();
+
+ // spawn 4 adds
+ DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
+ DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
+ DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
+ DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0s);
+
+ me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE);
+ me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
+ me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, false);
+ }
- DoMeleeAttackIfReady();
+ PosCheck_Timer = 2500;
+ } else PosCheck_Timer -=diff;
}
- };
+
+ //EnrageTimer
+ if (EnrageTimer <= diff)
+ {
+ DoCast(me, SPELL_ENRAGE);
+ EnrageTimer = 60000;
+ } else EnrageTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
};
void AddSC_boss_hydross_the_unstable()
{
- new boss_hydross_the_unstable();
+ RegisterSerpentshrineCavernCreatureAI(boss_hydross_the_unstable);
}
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
index cccd2184da3..6cec120340f 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
@@ -131,745 +131,684 @@ float ShieldGeneratorChannelPos[4][4] =
{49.3126f, -943.398f, 42.5501f, 2.40174f}
};
-class boss_lady_vashj : public CreatureScript
+struct boss_lady_vashj : public BossAI
{
-public:
- boss_lady_vashj() : CreatureScript("boss_lady_vashj") { }
+ boss_lady_vashj(Creature* creature) : BossAI(creature, BOSS_LADY_VASHJ)
+ {
+ Initialize();
+ instance = creature->GetInstanceScript();
+ Intro = false;
+ JustCreated = true;
+ CanAttack = false;
+ creature->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); // set it only once on Creature create (no need do intro if wiped)
+ }
- CreatureAI* GetAI(Creature* creature) const override
+ void Initialize()
{
- return GetSerpentshrineCavernAI<boss_lady_vashjAI>(creature);
+ AggroTimer = 19000;
+ ShockBlastTimer = 1 + rand32() % 60000;
+ EntangleTimer = 30000;
+ StaticChargeTimer = 10000 + rand32() % 15000;
+ ForkedLightningTimer = 2000;
+ CheckTimer = 15000;
+ EnchantedElementalTimer = 5000;
+ TaintedElementalTimer = 50000;
+ CoilfangEliteTimer = 45000 + rand32() % 5000;
+ CoilfangStriderTimer = 60000 + rand32() % 10000;
+ SummonSporebatTimer = 10000;
+ SummonSporebatStaticTimer = 30000;
+ EnchantedElementalPos = 0;
+ Phase = 0;
+
+ Entangle = false;
}
- struct boss_lady_vashjAI : public ScriptedAI
+ InstanceScript* instance;
+
+ ObjectGuid ShieldGeneratorChannel[4];
+
+ uint32 AggroTimer;
+ uint32 ShockBlastTimer;
+ uint32 EntangleTimer;
+ uint32 StaticChargeTimer;
+ uint32 ForkedLightningTimer;
+ uint32 CheckTimer;
+ uint32 EnchantedElementalTimer;
+ uint32 TaintedElementalTimer;
+ uint32 CoilfangEliteTimer;
+ uint32 CoilfangStriderTimer;
+ uint32 SummonSporebatTimer;
+ uint32 SummonSporebatStaticTimer;
+ uint8 EnchantedElementalPos;
+ uint8 Phase;
+
+ bool Entangle;
+ bool Intro;
+ bool CanAttack;
+ bool JustCreated;
+
+ void Reset() override
{
- boss_lady_vashjAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- Intro = false;
- JustCreated = true;
- CanAttack = false;
- creature->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); // set it only once on Creature create (no need do intro if wiped)
- }
+ Initialize();
- void Initialize()
+ if (JustCreated)
{
- AggroTimer = 19000;
- ShockBlastTimer = 1 + rand32() % 60000;
- EntangleTimer = 30000;
- StaticChargeTimer = 10000 + rand32() % 15000;
- ForkedLightningTimer = 2000;
- CheckTimer = 15000;
- EnchantedElementalTimer = 5000;
- TaintedElementalTimer = 50000;
- CoilfangEliteTimer = 45000 + rand32() % 5000;
- CoilfangStriderTimer = 60000 + rand32() % 10000;
- SummonSporebatTimer = 10000;
- SummonSporebatStaticTimer = 30000;
- EnchantedElementalPos = 0;
- Phase = 0;
-
- Entangle = false;
- }
+ CanAttack = false;
+ JustCreated = false;
+ } else CanAttack = true;
- InstanceScript* instance;
-
- ObjectGuid ShieldGeneratorChannel[4];
-
- uint32 AggroTimer;
- uint32 ShockBlastTimer;
- uint32 EntangleTimer;
- uint32 StaticChargeTimer;
- uint32 ForkedLightningTimer;
- uint32 CheckTimer;
- uint32 EnchantedElementalTimer;
- uint32 TaintedElementalTimer;
- uint32 CoilfangEliteTimer;
- uint32 CoilfangStriderTimer;
- uint32 SummonSporebatTimer;
- uint32 SummonSporebatStaticTimer;
- uint8 EnchantedElementalPos;
- uint8 Phase;
-
- bool Entangle;
- bool Intro;
- bool CanAttack;
- bool JustCreated;
-
- void Reset() override
+ for (uint8 i = 0; i < 4; ++i)
{
- Initialize();
-
- if (JustCreated)
- {
- CanAttack = false;
- JustCreated = false;
- } else CanAttack = true;
-
- for (uint8 i = 0; i < 4; ++i)
+ if (!ShieldGeneratorChannel[i].IsEmpty())
{
- if (!ShieldGeneratorChannel[i].IsEmpty())
+ if (Unit* remo = ObjectAccessor::GetUnit(*me, ShieldGeneratorChannel[i]))
{
- if (Unit* remo = ObjectAccessor::GetUnit(*me, ShieldGeneratorChannel[i]))
- {
- remo->setDeathState(JUST_DIED);
- ShieldGeneratorChannel[i].Clear();
- }
+ remo->setDeathState(JUST_DIED);
+ ShieldGeneratorChannel[i].Clear();
}
}
+ }
- instance->SetData(DATA_LADYVASHJEVENT, NOT_STARTED);
+ _Reset();
- me->SetCorpseDelay(1000*60*60);
- }
+ me->SetCorpseDelay(1000*60*60);
+ }
- // Called when a tainted elemental dies
- void EventTaintedElementalDeath()
- {
- // the next will spawn 50 seconds after the previous one's death
- if (TaintedElementalTimer > 50000)
- TaintedElementalTimer = 50000;
- }
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(SAY_SLAY);
- }
+ // Called when a tainted elemental dies
+ void EventTaintedElementalDeath()
+ {
+ // the next will spawn 50 seconds after the previous one's death
+ if (TaintedElementalTimer > 50000)
+ TaintedElementalTimer = 50000;
+ }
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ Talk(SAY_SLAY);
+ }
- void JustDied(Unit* /*killer*/) override
- {
- Talk(SAY_DEATH);
+ void JustDied(Unit* /*killer*/) override
+ {
+ Talk(SAY_DEATH);
- instance->SetData(DATA_LADYVASHJEVENT, DONE);
- }
+ _JustDied();
+ }
- void StartEvent()
- {
- Talk(SAY_AGGRO);
+ void StartEvent(Unit* who)
+ {
+ Talk(SAY_AGGRO);
- Phase = 1;
+ Phase = 1;
- instance->SetData(DATA_LADYVASHJEVENT, IN_PROGRESS);
- }
+ _JustEngagedWith(who);
+ }
- void JustEngagedWith(Unit* who) override
- {
- // remove old tainted cores to prevent cheating in phase 2
- Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
- if (Player* player = itr->GetSource())
- player->DestroyItemCount(31088, 1, true);
- StartEvent(); // this is JustEngagedWith(), so were are 100% in combat, start the event
-
- if (Phase != 2)
- AttackStart(who);
- }
+ void JustEngagedWith(Unit* who) override
+ {
+ // remove old tainted cores to prevent cheating in phase 2
+ Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
+ if (Player* player = itr->GetSource())
+ player->DestroyItemCount(31088, 1, true);
+ StartEvent(who); // this is JustEngagedWith(), so were are 100% in combat, start the event
- void MoveInLineOfSight(Unit* who) override
+ if (Phase != 2)
+ AttackStart(who);
+ }
+
+ void MoveInLineOfSight(Unit* who) override
+ {
+ if (!Intro)
{
- if (!Intro)
- {
- Intro = true;
- Talk(SAY_INTRO);
- }
- if (!CanAttack)
- return;
- if (!who || me->GetVictim())
- return;
+ Intro = true;
+ Talk(SAY_INTRO);
+ }
+ if (!CanAttack)
+ return;
+ if (!who || me->GetVictim())
+ return;
- if (me->CanCreatureAttack(who))
+ if (me->CanCreatureAttack(who))
+ {
+ float attackRadius = me->GetAttackDistance(who);
+ if (me->IsWithinDistInMap(who, attackRadius) && me->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && me->IsWithinLOSInMap(who))
{
- float attackRadius = me->GetAttackDistance(who);
- if (me->IsWithinDistInMap(who, attackRadius) && me->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && me->IsWithinLOSInMap(who))
- {
- if (!me->IsInCombat()) // AttackStart() sets UNIT_FLAG_IN_COMBAT, so this msut be before attacking
- StartEvent();
+ if (!me->IsInCombat()) // AttackStart() sets UNIT_FLAG_IN_COMBAT, so this msut be before attacking
+ StartEvent(who);
- if (Phase != 2)
- AttackStart(who);
- }
+ if (Phase != 2)
+ AttackStart(who);
}
}
+ }
- void CastShootOrMultishot()
+ void CastShootOrMultishot()
+ {
+ switch (urand(0, 1))
{
- switch (urand(0, 1))
- {
- case 0:
- // Shoot
- // Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits her target for 4097-5543 Physical damage.
- DoCastVictim(SPELL_SHOOT);
- break;
- case 1:
- // Multishot
- // Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits 1 person and 4 people around him for 6475-7525 physical damage.
- DoCastVictim(SPELL_MULTI_SHOT);
- break;
- }
- if (rand32() % 3)
- {
- Talk(SAY_BOWSHOT);
- }
+ case 0:
+ // Shoot
+ // Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits her target for 4097-5543 Physical damage.
+ DoCastVictim(SPELL_SHOOT);
+ break;
+ case 1:
+ // Multishot
+ // Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits 1 person and 4 people around him for 6475-7525 physical damage.
+ DoCastVictim(SPELL_MULTI_SHOT);
+ break;
+ }
+ if (rand32() % 3)
+ {
+ Talk(SAY_BOWSHOT);
}
+ }
- void UpdateAI(uint32 diff) override
+ void UpdateAI(uint32 diff) override
+ {
+ if (!CanAttack && Intro)
{
- if (!CanAttack && Intro)
+ if (AggroTimer <= diff)
{
- if (AggroTimer <= diff)
- {
- CanAttack = true;
- me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- AggroTimer=19000;
- }
- else
- {
- AggroTimer -= diff;
- return;
- }
+ CanAttack = true;
+ me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
+ AggroTimer=19000;
}
- // to prevent abuses during phase 2
- if (Phase == 2 && !me->GetVictim() && me->IsInCombat())
+ else
{
- EnterEvadeMode();
+ AggroTimer -= diff;
return;
}
- // Return since we have no target
- if (!UpdateVictim())
- return;
+ }
+ // to prevent abuses during phase 2
+ if (Phase == 2 && !me->GetVictim() && me->IsInCombat())
+ {
+ EnterEvadeMode();
+ return;
+ }
+ // Return since we have no target
+ if (!UpdateVictim())
+ return;
- if (Phase == 1 || Phase == 3)
+ if (Phase == 1 || Phase == 3)
+ {
+ // ShockBlastTimer
+ if (ShockBlastTimer <= diff)
{
- // ShockBlastTimer
- if (ShockBlastTimer <= diff)
- {
- // Shock Burst
- // Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list.
- DoCastVictim(SPELL_SHOCK_BLAST);
+ // Shock Burst
+ // Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list.
+ DoCastVictim(SPELL_SHOCK_BLAST);
- ShockBlastTimer = 1000 + rand32() % 14000; // random cooldown
- } else ShockBlastTimer -= diff;
+ ShockBlastTimer = 1000 + rand32() % 14000; // random cooldown
+ } else ShockBlastTimer -= diff;
- // StaticChargeTimer
- if (StaticChargeTimer <= diff)
- {
- // Static Charge
- // Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic.
- Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 200, true);
- if (target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER))
- DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); // cast Static Charge every 2 seconds for 20 seconds
+ // StaticChargeTimer
+ if (StaticChargeTimer <= diff)
+ {
+ // Static Charge
+ // Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic.
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 200, true);
+ if (target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER))
+ DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); // cast Static Charge every 2 seconds for 20 seconds
- StaticChargeTimer = 10000 + rand32() % 20000;
- } else StaticChargeTimer -= diff;
+ StaticChargeTimer = 10000 + rand32() % 20000;
+ } else StaticChargeTimer -= diff;
- // EntangleTimer
- if (EntangleTimer <= diff)
+ // EntangleTimer
+ if (EntangleTimer <= diff)
+ {
+ if (!Entangle)
{
- if (!Entangle)
- {
- // Entangle
- // Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom.
- DoCastVictim(SPELL_ENTANGLE);
- Entangle = true;
- EntangleTimer = 10000;
- }
- else
- {
- CastShootOrMultishot();
- Entangle = false;
- EntangleTimer = 20000 + rand32() % 5000;
- }
- } else EntangleTimer -= diff;
+ // Entangle
+ // Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom.
+ DoCastVictim(SPELL_ENTANGLE);
+ Entangle = true;
+ EntangleTimer = 10000;
+ }
+ else
+ {
+ CastShootOrMultishot();
+ Entangle = false;
+ EntangleTimer = 20000 + rand32() % 5000;
+ }
+ } else EntangleTimer -= diff;
- // Phase 1
- if (Phase == 1)
+ // Phase 1
+ if (Phase == 1)
+ {
+ // Start phase 2
+ if (HealthBelowPct(70))
{
- // Start phase 2
- if (HealthBelowPct(70))
- {
- // Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable.
- Phase = 2;
+ // Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable.
+ Phase = 2;
- me->GetMotionMaster()->Clear();
- DoTeleportTo(MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
+ me->GetMotionMaster()->Clear();
+ DoTeleportTo(MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
- for (uint8 i = 0; i < 4; ++i)
- if (Creature* creature = me->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0], ShieldGeneratorChannelPos[i][1], ShieldGeneratorChannelPos[i][2], ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN))
- ShieldGeneratorChannel[i] = creature->GetGUID();
+ for (uint8 i = 0; i < 4; ++i)
+ if (Creature* creature = me->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0], ShieldGeneratorChannelPos[i][1], ShieldGeneratorChannelPos[i][2], ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN))
+ ShieldGeneratorChannel[i] = creature->GetGUID();
- Talk(SAY_PHASE2);
- }
+ Talk(SAY_PHASE2);
}
- // Phase 3
- else
+ }
+ // Phase 3
+ else
+ {
+ // SummonSporebatTimer
+ if (SummonSporebatTimer <= diff)
{
- // SummonSporebatTimer
- if (SummonSporebatTimer <= diff)
- {
- if (Creature* sporebat = me->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN))
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- sporebat->AI()->AttackStart(target);
+ if (Creature* sporebat = me->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN))
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ sporebat->AI()->AttackStart(target);
- // summon sporebats faster and faster
- if (SummonSporebatStaticTimer > 1000)
- SummonSporebatStaticTimer -= 1000;
+ // summon sporebats faster and faster
+ if (SummonSporebatStaticTimer > 1000)
+ SummonSporebatStaticTimer -= 1000;
- SummonSporebatTimer = SummonSporebatStaticTimer;
+ SummonSporebatTimer = SummonSporebatStaticTimer;
- if (SummonSporebatTimer < 5000)
- SummonSporebatTimer = 5000;
+ if (SummonSporebatTimer < 5000)
+ SummonSporebatTimer = 5000;
- } else SummonSporebatTimer -= diff;
- }
+ } else SummonSporebatTimer -= diff;
+ }
- // Melee attack
- DoMeleeAttackIfReady();
+ // Melee attack
+ DoMeleeAttackIfReady();
- // CheckTimer - used to check if somebody is in melee range
- if (CheckTimer <= diff)
+ // CheckTimer - used to check if somebody is in melee range
+ if (CheckTimer <= diff)
+ {
+ bool inMeleeRange = false;
+ for (auto* ref : me->GetThreatManager().GetUnsortedThreatList())
{
- bool inMeleeRange = false;
- for (auto* ref : me->GetThreatManager().GetUnsortedThreatList())
+ Unit* target = ref->GetVictim();
+ if (target->IsWithinMeleeRange(me)) // if in melee range
{
- Unit* target = ref->GetVictim();
- if (target->IsWithinMeleeRange(me)) // if in melee range
- {
- inMeleeRange = true;
- break;
- }
+ inMeleeRange = true;
+ break;
}
+ }
- // if nobody is in melee range
- if (!inMeleeRange)
- CastShootOrMultishot();
+ // if nobody is in melee range
+ if (!inMeleeRange)
+ CastShootOrMultishot();
- CheckTimer = 5000;
- } else CheckTimer -= diff;
- }
- // Phase 2
- else
+ CheckTimer = 5000;
+ } else CheckTimer -= diff;
+ }
+ // Phase 2
+ else
+ {
+ // ForkedLightningTimer
+ if (ForkedLightningTimer <= diff)
{
- // ForkedLightningTimer
- if (ForkedLightningTimer <= diff)
- {
- // Forked Lightning
- // Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage.
- Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
+ // Forked Lightning
+ // Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage.
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
- if (!target)
- target = me->GetVictim();
+ if (!target)
+ target = me->GetVictim();
- DoCast(target, SPELL_FORKED_LIGHTNING);
+ DoCast(target, SPELL_FORKED_LIGHTNING);
- ForkedLightningTimer = 2000 + rand32() % 6000;
- } else ForkedLightningTimer -= diff;
+ ForkedLightningTimer = 2000 + rand32() % 6000;
+ } else ForkedLightningTimer -= diff;
- // EnchantedElementalTimer
- if (EnchantedElementalTimer <= diff)
- {
- me->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElementalPos][0], ElementPos[EnchantedElementalPos][1], ElementPos[EnchantedElementalPos][2], ElementPos[EnchantedElementalPos][3], TEMPSUMMON_CORPSE_DESPAWN);
+ // EnchantedElementalTimer
+ if (EnchantedElementalTimer <= diff)
+ {
+ me->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElementalPos][0], ElementPos[EnchantedElementalPos][1], ElementPos[EnchantedElementalPos][2], ElementPos[EnchantedElementalPos][3], TEMPSUMMON_CORPSE_DESPAWN);
- if (EnchantedElementalPos == 7)
- EnchantedElementalPos = 0;
- else
- ++EnchantedElementalPos;
+ if (EnchantedElementalPos == 7)
+ EnchantedElementalPos = 0;
+ else
+ ++EnchantedElementalPos;
- EnchantedElementalTimer = 10000 + rand32() % 5000;
- } else EnchantedElementalTimer -= diff;
+ EnchantedElementalTimer = 10000 + rand32() % 5000;
+ } else EnchantedElementalTimer -= diff;
- // TaintedElementalTimer
- if (TaintedElementalTimer <= diff)
- {
- uint32 pos = rand32() % 8;
- me->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN);
+ // TaintedElementalTimer
+ if (TaintedElementalTimer <= diff)
+ {
+ uint32 pos = rand32() % 8;
+ me->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN);
- TaintedElementalTimer = 120000;
- } else TaintedElementalTimer -= diff;
+ TaintedElementalTimer = 120000;
+ } else TaintedElementalTimer -= diff;
- // CoilfangEliteTimer
- if (CoilfangEliteTimer <= diff)
+ // CoilfangEliteTimer
+ if (CoilfangEliteTimer <= diff)
+ {
+ uint32 pos = rand32() % 3;
+ Creature* coilfangElite = me->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
+ if (coilfangElite)
{
- uint32 pos = rand32() % 3;
- Creature* coilfangElite = me->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
- if (coilfangElite)
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- coilfangElite->AI()->AttackStart(target);
- else if (me->GetVictim())
- coilfangElite->AI()->AttackStart(me->GetVictim());
- }
- CoilfangEliteTimer = 45000 + rand32() % 5000;
- } else CoilfangEliteTimer -= diff;
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ coilfangElite->AI()->AttackStart(target);
+ else if (me->GetVictim())
+ coilfangElite->AI()->AttackStart(me->GetVictim());
+ }
+ CoilfangEliteTimer = 45000 + rand32() % 5000;
+ } else CoilfangEliteTimer -= diff;
- // CoilfangStriderTimer
- if (CoilfangStriderTimer <= diff)
+ // CoilfangStriderTimer
+ if (CoilfangStriderTimer <= diff)
+ {
+ uint32 pos = rand32() % 3;
+ if (Creature* CoilfangStrider = me->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s))
{
- uint32 pos = rand32() % 3;
- if (Creature* CoilfangStrider = me->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s))
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- CoilfangStrider->AI()->AttackStart(target);
- else if (me->GetVictim())
- CoilfangStrider->AI()->AttackStart(me->GetVictim());
- }
- CoilfangStriderTimer = 60000 + rand32() % 10000;
- } else CoilfangStriderTimer -= diff;
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ CoilfangStrider->AI()->AttackStart(target);
+ else if (me->GetVictim())
+ CoilfangStrider->AI()->AttackStart(me->GetVictim());
+ }
+ CoilfangStriderTimer = 60000 + rand32() % 10000;
+ } else CoilfangStriderTimer -= diff;
- // CheckTimer
- if (CheckTimer <= diff)
+ // CheckTimer
+ if (CheckTimer <= diff)
+ {
+ // Start Phase 3
+ if (instance->GetData(DATA_CANSTARTPHASE3))
{
- // Start Phase 3
- if (instance->GetData(DATA_CANSTARTPHASE3))
- {
- // set life 50%
- me->SetHealth(me->CountPctFromMaxHealth(50));
+ // set life 50%
+ me->SetHealth(me->CountPctFromMaxHealth(50));
- me->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER);
+ me->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER);
- Talk(SAY_PHASE3);
+ Talk(SAY_PHASE3);
- Phase = 3;
+ Phase = 3;
- // return to the tank
- me->GetMotionMaster()->MoveChase(me->GetVictim());
- }
- CheckTimer = 1000;
- } else CheckTimer -= diff;
- }
+ // return to the tank
+ me->GetMotionMaster()->MoveChase(me->GetVictim());
+ }
+ CheckTimer = 1000;
+ } else CheckTimer -= diff;
}
- };
-
+ }
};
// Enchanted Elemental
// If one of them reaches Vashj he will increase her damage done by 5%.
-class npc_enchanted_elemental : public CreatureScript
+struct npc_enchanted_elemental : public ScriptedAI
{
-public:
- npc_enchanted_elemental() : CreatureScript("npc_enchanted_elemental") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_enchanted_elemental(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<npc_enchanted_elementalAI>(creature);
+ Initialize();
+ instance = creature->GetInstanceScript();
}
- struct npc_enchanted_elementalAI : public ScriptedAI
+ void Initialize()
{
- npc_enchanted_elementalAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ Move = 0;
+ Phase = 1;
- void Initialize()
- {
- Move = 0;
- Phase = 1;
+ X = ElementWPPos[0][0];
+ Y = ElementWPPos[0][1];
+ Z = ElementWPPos[0][2];
+ }
- X = ElementWPPos[0][0];
- Y = ElementWPPos[0][1];
- Z = ElementWPPos[0][2];
- }
+ InstanceScript* instance;
+ uint32 Move;
+ uint32 Phase;
+ float X, Y, Z;
- InstanceScript* instance;
- uint32 Move;
- uint32 Phase;
- float X, Y, Z;
+ ObjectGuid VashjGUID;
- ObjectGuid VashjGUID;
+ void Reset() override
+ {
+ me->SetSpeedRate(MOVE_WALK, 0.6f); // walk
+ me->SetSpeedRate(MOVE_RUN, 0.6f); // run
+ Initialize();
- void Reset() override
+ //search for nearest waypoint (up on stairs)
+ for (uint32 i = 1; i < 8; ++i)
{
- me->SetSpeedRate(MOVE_WALK, 0.6f); // walk
- me->SetSpeedRate(MOVE_RUN, 0.6f); // run
- Initialize();
-
- //search for nearest waypoint (up on stairs)
- for (uint32 i = 1; i < 8; ++i)
+ if (me->GetDistance(ElementWPPos[i][0], ElementWPPos[i][1], ElementWPPos[i][2]) < me->GetDistance(X, Y, Z))
{
- if (me->GetDistance(ElementWPPos[i][0], ElementWPPos[i][1], ElementWPPos[i][2]) < me->GetDistance(X, Y, Z))
- {
- X = ElementWPPos[i][0];
- Y = ElementWPPos[i][1];
- Z = ElementWPPos[i][2];
- }
+ X = ElementWPPos[i][0];
+ Y = ElementWPPos[i][1];
+ Z = ElementWPPos[i][2];
}
-
- VashjGUID = instance->GetGuidData(DATA_LADYVASHJ);
}
- void JustEngagedWith(Unit* /*who*/) override { }
+ VashjGUID = instance->GetGuidData(DATA_LADYVASHJ);
+ }
- void MoveInLineOfSight(Unit* /*who*/) override { }
+ void JustEngagedWith(Unit* /*who*/) override { }
- void UpdateAI(uint32 diff) override
- {
- if (!VashjGUID)
- return;
+ void MoveInLineOfSight(Unit* /*who*/) override { }
- if (Move <= diff)
- {
- me->SetWalk(true);
- if (Phase == 1)
- me->GetMotionMaster()->MovePoint(0, X, Y, Z);
- if (Phase == 1 && me->IsWithinDist3d(X, Y, Z, 0.1f))
- Phase = 2;
- if (Phase == 2)
- {
- me->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
- Phase = 3;
- }
- if (Phase == 3)
- {
- me->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
- if (me->IsWithinDist3d(MIDDLE_X, MIDDLE_Y, MIDDLE_Z, 3))
- DoCast(me, SPELL_SURGE);
- }
- if (Creature* vashj = ObjectAccessor::GetCreature(*me, VashjGUID))
- if (!vashj->IsInCombat() || ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->Phase != 2 || vashj->isDead())
- me->KillSelf();
- Move = 1000;
- } else Move -= diff;
- }
- };
+ void UpdateAI(uint32 diff) override
+ {
+ if (!VashjGUID)
+ return;
+ if (Move <= diff)
+ {
+ me->SetWalk(true);
+ if (Phase == 1)
+ me->GetMotionMaster()->MovePoint(0, X, Y, Z);
+ if (Phase == 1 && me->IsWithinDist3d(X, Y, Z, 0.1f))
+ Phase = 2;
+ if (Phase == 2)
+ {
+ me->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
+ Phase = 3;
+ }
+ if (Phase == 3)
+ {
+ me->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
+ if (me->IsWithinDist3d(MIDDLE_X, MIDDLE_Y, MIDDLE_Z, 3))
+ DoCast(me, SPELL_SURGE);
+ }
+ if (Creature* vashj = ObjectAccessor::GetCreature(*me, VashjGUID))
+ if (!vashj->IsInCombat() || ENSURE_AI(boss_lady_vashj, vashj->AI())->Phase != 2 || vashj->isDead())
+ me->KillSelf();
+ Move = 1000;
+ } else Move -= diff;
+ }
};
// Tainted Elemental
// This mob has 7, 900 life, doesn't move, and shoots Poison Bolts at one person anywhere in the area, doing 3, 000 nature damage and placing a posion doing 2, 000 damage every 2 seconds. He will switch targets often, or sometimes just hang on a single player, but there is nothing you can do about it except heal the damage and kill the Tainted Elemental
-class npc_tainted_elemental : public CreatureScript
+struct npc_tainted_elemental : public ScriptedAI
{
-public:
- npc_tainted_elemental() : CreatureScript("npc_tainted_elemental") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_tainted_elemental(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<npc_tainted_elementalAI>(creature);
+ Initialize();
+ instance = creature->GetInstanceScript();
}
- struct npc_tainted_elementalAI : public ScriptedAI
+ void Initialize()
{
- npc_tainted_elementalAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- PoisonBoltTimer = 5000 + rand32() % 5000;
- DespawnTimer = 30000;
- }
+ PoisonBoltTimer = 5000 + rand32() % 5000;
+ DespawnTimer = 30000;
+ }
- InstanceScript* instance;
+ InstanceScript* instance;
- uint32 PoisonBoltTimer;
- uint32 DespawnTimer;
+ uint32 PoisonBoltTimer;
+ uint32 DespawnTimer;
- void Reset() override
- {
- Initialize();
- }
+ void Reset() override
+ {
+ Initialize();
+ }
- void JustDied(Unit* /*killer*/) override
- {
- if (Creature* vashj = ObjectAccessor::GetCreature((*me), instance->GetGuidData(DATA_LADYVASHJ)))
- ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->EventTaintedElementalDeath();
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (Creature* vashj = ObjectAccessor::GetCreature((*me), instance->GetGuidData(DATA_LADYVASHJ)))
+ ENSURE_AI(boss_lady_vashj, vashj->AI())->EventTaintedElementalDeath();
+ }
- void JustEngagedWith(Unit* who) override
- {
- AddThreat(who, 0.1f);
- }
+ void JustEngagedWith(Unit* who) override
+ {
+ AddThreat(who, 0.1f);
+ }
- void UpdateAI(uint32 diff) override
+ void UpdateAI(uint32 diff) override
+ {
+ // PoisonBoltTimer
+ if (PoisonBoltTimer <= diff)
{
- // PoisonBoltTimer
- if (PoisonBoltTimer <= diff)
- {
- Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
-
- if (target && target->IsWithinDistInMap(me, 30))
- DoCast(target, SPELL_POISON_BOLT);
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
- PoisonBoltTimer = 5000 + rand32() % 5000;
- } else PoisonBoltTimer -= diff;
+ if (target && target->IsWithinDistInMap(me, 30))
+ DoCast(target, SPELL_POISON_BOLT);
- // DespawnTimer
- if (DespawnTimer <= diff)
- {
- // call Unsummon()
- me->setDeathState(DEAD);
+ PoisonBoltTimer = 5000 + rand32() % 5000;
+ } else PoisonBoltTimer -= diff;
- // to prevent crashes
- DespawnTimer = 1000;
- } else DespawnTimer -= diff;
- }
- };
+ // DespawnTimer
+ if (DespawnTimer <= diff)
+ {
+ // call Unsummon()
+ me->setDeathState(DEAD);
+ // to prevent crashes
+ DespawnTimer = 1000;
+ } else DespawnTimer -= diff;
+ }
};
//Toxic Sporebat
//Toxic Spores: Used in Phase 3 by the Spore Bats, it creates a contaminated green patch of ground, dealing about 2775-3225 nature damage every second to anyone who stands in it.
-class npc_toxic_sporebat : public CreatureScript
+struct npc_toxic_sporebat : public ScriptedAI
{
-public:
- npc_toxic_sporebat() : CreatureScript("npc_toxic_sporebat") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_toxic_sporebat(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<npc_toxic_sporebatAI>(creature);
+ Initialize();
+ instance = creature->GetInstanceScript();
+ EnterEvadeMode();
}
- struct npc_toxic_sporebatAI : public ScriptedAI
+ void Initialize()
{
- npc_toxic_sporebatAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- EnterEvadeMode();
- }
+ MovementTimer = 0;
+ ToxicSporeTimer = 5000;
+ BoltTimer = 5500;
+ CheckTimer = 1000;
+ }
- void Initialize()
- {
- MovementTimer = 0;
- ToxicSporeTimer = 5000;
- BoltTimer = 5500;
- CheckTimer = 1000;
- }
+ InstanceScript* instance;
- InstanceScript* instance;
+ uint32 MovementTimer;
+ uint32 ToxicSporeTimer;
+ uint32 BoltTimer;
+ uint32 CheckTimer;
- uint32 MovementTimer;
- uint32 ToxicSporeTimer;
- uint32 BoltTimer;
- uint32 CheckTimer;
+ void Reset() override
+ {
+ me->SetDisableGravity(true);
+ me->SetFaction(FACTION_MONSTER);
+ Initialize();
+ }
- void Reset() override
- {
- me->SetDisableGravity(true);
- me->SetFaction(FACTION_MONSTER);
- Initialize();
- }
+ void MoveInLineOfSight(Unit* /*who*/) override
+ {
+ }
- void MoveInLineOfSight(Unit* /*who*/) override
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
- {
- }
+ if (id == 1)
+ MovementTimer = 0;
+ }
- void MovementInform(uint32 type, uint32 id) override
+ void UpdateAI(uint32 diff) override
+ {
+ // Random movement
+ if (MovementTimer <= diff)
{
- if (type != POINT_MOTION_TYPE)
- return;
-
- if (id == 1)
- MovementTimer = 0;
- }
+ uint32 rndpos = rand32() % 8;
+ me->GetMotionMaster()->MovePoint(1, SporebatWPPos[rndpos][0], SporebatWPPos[rndpos][1], SporebatWPPos[rndpos][2]);
+ MovementTimer = 6000;
+ } else MovementTimer -= diff;
- void UpdateAI(uint32 diff) override
+ // toxic spores
+ if (BoltTimer <= diff)
{
- // Random movement
- if (MovementTimer <= diff)
- {
- uint32 rndpos = rand32() % 8;
- me->GetMotionMaster()->MovePoint(1, SporebatWPPos[rndpos][0], SporebatWPPos[rndpos][1], SporebatWPPos[rndpos][2]);
- MovementTimer = 6000;
- } else MovementTimer -= diff;
-
- // toxic spores
- if (BoltTimer <= diff)
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ if (Creature* trig = me->SummonCreature(TOXIC_SPORES_TRIGGER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30s))
{
- if (Creature* trig = me->SummonCreature(TOXIC_SPORES_TRIGGER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30s))
- {
- trig->SetFaction(FACTION_MONSTER);
- trig->CastSpell(trig, SPELL_TOXIC_SPORES, true);
- }
+ trig->SetFaction(FACTION_MONSTER);
+ trig->CastSpell(trig, SPELL_TOXIC_SPORES, true);
}
- BoltTimer = 10000 + rand32() % 5000;
}
- else BoltTimer -= diff;
+ BoltTimer = 10000 + rand32() % 5000;
+ }
+ else BoltTimer -= diff;
- // CheckTimer
- if (CheckTimer <= diff)
+ // CheckTimer
+ if (CheckTimer <= diff)
+ {
+ // check if vashj is death
+ Unit* Vashj = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LADYVASHJ));
+ if (!Vashj || !Vashj->IsAlive() || ENSURE_AI(boss_lady_vashj, Vashj->ToCreature()->AI())->Phase != 3)
{
- // check if vashj is death
- Unit* Vashj = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LADYVASHJ));
- if (!Vashj || !Vashj->IsAlive() || ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, Vashj->ToCreature()->AI())->Phase != 3)
- {
- // remove
- me->SetFaction(FACTION_FRIENDLY);
- me->DespawnOrUnsummon();
- return;
- }
-
- CheckTimer = 1000;
+ // remove
+ me->SetFaction(FACTION_FRIENDLY);
+ me->DespawnOrUnsummon();
+ return;
}
- else
- CheckTimer -= diff;
- }
- };
+ CheckTimer = 1000;
+ }
+ else
+ CheckTimer -= diff;
+ }
};
-class npc_shield_generator_channel : public CreatureScript
+struct npc_shield_generator_channel : public ScriptedAI
{
-public:
- npc_shield_generator_channel() : CreatureScript("npc_shield_generator_channel") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_shield_generator_channel(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<npc_shield_generator_channelAI>(creature);
+ Initialize();
+ instance = creature->GetInstanceScript();
}
- struct npc_shield_generator_channelAI : public ScriptedAI
+ void Initialize()
{
- npc_shield_generator_channelAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- CheckTimer = 0;
- Cast = false;
- }
+ CheckTimer = 0;
+ Cast = false;
+ }
- InstanceScript* instance;
- uint32 CheckTimer;
- bool Cast;
+ InstanceScript* instance;
+ uint32 CheckTimer;
+ bool Cast;
- void Reset() override
- {
- Initialize();
- me->SetDisplayId(11686); // invisible
- }
+ void Reset() override
+ {
+ Initialize();
+ me->SetDisplayId(11686); // invisible
+ }
- void MoveInLineOfSight(Unit* /*who*/) override { }
+ void MoveInLineOfSight(Unit* /*who*/) override { }
- void UpdateAI(uint32 diff) override
+ void UpdateAI(uint32 diff) override
+ {
+ if (CheckTimer <= diff)
{
- if (CheckTimer <= diff)
- {
- Unit* vashj = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LADYVASHJ));
+ Unit* vashj = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LADYVASHJ));
- if (vashj && vashj->IsAlive())
+ if (vashj && vashj->IsAlive())
+ {
+ // start visual channel
+ if (!Cast || !vashj->HasAura(SPELL_MAGIC_BARRIER))
{
- // start visual channel
- if (!Cast || !vashj->HasAura(SPELL_MAGIC_BARRIER))
- {
- DoCast(vashj, SPELL_MAGIC_BARRIER, true);
- Cast = true;
- }
+ DoCast(vashj, SPELL_MAGIC_BARRIER, true);
+ Cast = true;
}
- CheckTimer = 1000;
- } else CheckTimer -= diff;
- }
- };
-
+ }
+ CheckTimer = 1000;
+ } else CheckTimer -= diff;
+ }
};
class item_tainted_core : public ItemScript
@@ -884,7 +823,7 @@ public:
return true;
Creature* vashj = ObjectAccessor::GetCreature((*player), instance->GetGuidData(DATA_LADYVASHJ));
- if (vashj && (ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->Phase == 2))
+ if (vashj && (ENSURE_AI(boss_lady_vashj, vashj->AI())->Phase == 2))
{
if (GameObject* gObj = targets.GetGOTarget())
{
@@ -916,7 +855,7 @@ public:
return true;
// get and remove channel
- if (Unit* channel = ObjectAccessor::GetCreature(*vashj, ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->ShieldGeneratorChannel[channelIdentifier]))
+ if (Unit* channel = ObjectAccessor::GetCreature(*vashj, ENSURE_AI(boss_lady_vashj, vashj->AI())->ShieldGeneratorChannel[channelIdentifier]))
channel->setDeathState(JUST_DIED); // call Unsummon()
instance->SetData(identifier, 1);
@@ -941,10 +880,10 @@ public:
void AddSC_boss_lady_vashj()
{
- new boss_lady_vashj();
- new npc_enchanted_elemental();
- new npc_tainted_elemental();
- new npc_toxic_sporebat();
- new npc_shield_generator_channel();
+ RegisterSerpentshrineCavernCreatureAI(boss_lady_vashj);
+ RegisterSerpentshrineCavernCreatureAI(npc_enchanted_elemental);
+ RegisterSerpentshrineCavernCreatureAI(npc_tainted_elemental);
+ RegisterSerpentshrineCavernCreatureAI(npc_toxic_sporebat);
+ RegisterSerpentshrineCavernCreatureAI(npc_shield_generator_channel);
new item_tainted_core();
}
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
index 7293fc9f6ee..10bdf3bc631 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
@@ -73,746 +73,698 @@ enum LeotherasTheBlind
SAY_DEATH = 7
};
-class npc_inner_demon : public CreatureScript
+struct npc_inner_demon : public ScriptedAI
{
-public:
- npc_inner_demon() : CreatureScript("npc_inner_demon") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_inner_demon(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<npc_inner_demonAI>(creature);
+ Initialize();
}
- struct npc_inner_demonAI : public ScriptedAI
+ void Initialize()
{
- npc_inner_demonAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- }
+ ShadowBolt_Timer = 10000;
+ Link_Timer = 1000;
+ }
- void Initialize()
- {
- ShadowBolt_Timer = 10000;
- Link_Timer = 1000;
- }
+ uint32 ShadowBolt_Timer;
- uint32 ShadowBolt_Timer;
+ uint32 Link_Timer;
+ ObjectGuid victimGUID;
- uint32 Link_Timer;
- ObjectGuid victimGUID;
+ void Reset() override
+ {
+ Initialize();
+ }
- void Reset() override
- {
- Initialize();
- }
+ void SetGUID(ObjectGuid const& guid, int32 id) override
+ {
+ if (id == INNER_DEMON_VICTIM)
+ victimGUID = guid;
+ }
- void SetGUID(ObjectGuid const& guid, int32 id) override
- {
- if (id == INNER_DEMON_VICTIM)
- victimGUID = guid;
- }
+ ObjectGuid GetGUID(int32 id/* = 0 */) const override
+ {
+ if (id == INNER_DEMON_VICTIM)
+ return victimGUID;
+ return ObjectGuid::Empty;
+ }
- ObjectGuid GetGUID(int32 id/* = 0 */) const override
- {
- if (id == INNER_DEMON_VICTIM)
- return victimGUID;
- return ObjectGuid::Empty;
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ Unit* unit = ObjectAccessor::GetUnit(*me, victimGUID);
+ if (unit && unit->HasAura(SPELL_INSIDIOUS_WHISPER))
+ unit->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER);
+ }
- void JustDied(Unit* /*killer*/) override
+ void DamageTaken(Unit* done_by, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (!done_by || (done_by->GetGUID() != victimGUID && done_by->GetGUID() != me->GetGUID()))
{
- Unit* unit = ObjectAccessor::GetUnit(*me, victimGUID);
- if (unit && unit->HasAura(SPELL_INSIDIOUS_WHISPER))
- unit->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER);
+ damage = 0;
+ ModifyThreatByPercent(done_by, -100);
}
+ }
- void DamageTaken(Unit* done_by, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
- {
- if (!done_by || (done_by->GetGUID() != victimGUID && done_by->GetGUID() != me->GetGUID()))
- {
- damage = 0;
- ModifyThreatByPercent(done_by, -100);
- }
- }
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ if (!victimGUID)
+ return;
+ }
- void JustEngagedWith(Unit* /*who*/) override
- {
- if (!victimGUID)
- return;
- }
+ void UpdateAI(uint32 diff) override
+ {
+ //Return since we have no target
+ if (!UpdateVictim() || !me->GetVictim())
+ return;
- void UpdateAI(uint32 diff) override
+ if (me->EnsureVictim()->GetGUID() != victimGUID)
{
- //Return since we have no target
- if (!UpdateVictim() || !me->GetVictim())
- return;
-
- if (me->EnsureVictim()->GetGUID() != victimGUID)
+ ModifyThreatByPercent(me->GetVictim(), -100);
+ Unit* owner = ObjectAccessor::GetUnit(*me, victimGUID);
+ if (owner && owner->IsAlive())
{
- ModifyThreatByPercent(me->GetVictim(), -100);
- Unit* owner = ObjectAccessor::GetUnit(*me, victimGUID);
- if (owner && owner->IsAlive())
- {
- AddThreat(owner, 999999);
- AttackStart(owner);
- } else if (owner && owner->isDead())
- {
- me->KillSelf();
- return;
- }
+ AddThreat(owner, 999999);
+ AttackStart(owner);
+ } else if (owner && owner->isDead())
+ {
+ me->KillSelf();
+ return;
}
+ }
- if (Link_Timer <= diff)
- {
- DoCastVictim(SPELL_SOUL_LINK, true);
- Link_Timer = 1000;
- } else Link_Timer -= diff;
+ if (Link_Timer <= diff)
+ {
+ DoCastVictim(SPELL_SOUL_LINK, true);
+ Link_Timer = 1000;
+ } else Link_Timer -= diff;
- if (!me->HasAura(AURA_DEMONIC_ALIGNMENT))
- DoCast(me, AURA_DEMONIC_ALIGNMENT, true);
+ if (!me->HasAura(AURA_DEMONIC_ALIGNMENT))
+ DoCast(me, AURA_DEMONIC_ALIGNMENT, true);
- if (ShadowBolt_Timer <= diff)
- {
- DoCastVictim(SPELL_SHADOWBOLT, false);
- ShadowBolt_Timer = 10000;
- } else ShadowBolt_Timer -= diff;
+ if (ShadowBolt_Timer <= diff)
+ {
+ DoCastVictim(SPELL_SHADOWBOLT, false);
+ ShadowBolt_Timer = 10000;
+ } else ShadowBolt_Timer -= diff;
- DoMeleeAttackIfReady();
- }
- };
+ DoMeleeAttackIfReady();
+ }
};
//Original Leotheras the Blind AI
-class boss_leotheras_the_blind : public CreatureScript
+struct boss_leotheras_the_blind : public BossAI
{
-public:
- boss_leotheras_the_blind() : CreatureScript("boss_leotheras_the_blind") { }
+ boss_leotheras_the_blind(Creature* creature) : BossAI(creature, BOSS_LEOTHERAS_THE_BLIND)
+ {
+ Initialize();
+ creature->GetPosition(x, y, z);
+ }
- CreatureAI* GetAI(Creature* creature) const override
+ void Initialize()
{
- return GetSerpentshrineCavernAI<boss_leotheras_the_blindAI>(creature);
+ BanishTimer = 1000;
+ Whirlwind_Timer = 15000;
+ ChaosBlast_Timer = 1000;
+ SwitchToDemon_Timer = 45000;
+ SwitchToHuman_Timer = 60000;
+ Berserk_Timer = 600000;
+ InnerDemons_Timer = 30000;
+
+ DealDamage = true;
+ DemonForm = false;
+ IsFinalForm = false;
+ NeedThreatReset = false;
+ EnrageUsed = false;
+ for (ObjectGuid& guid : InnderDemon)
+ guid.Clear();
+ InnerDemon_Count = 0;
}
- struct boss_leotheras_the_blindAI : public ScriptedAI
+ uint32 Whirlwind_Timer;
+ uint32 ChaosBlast_Timer;
+ uint32 SwitchToDemon_Timer;
+ uint32 SwitchToHuman_Timer;
+ uint32 Berserk_Timer;
+ uint32 InnerDemons_Timer;
+ uint32 BanishTimer;
+
+ bool DealDamage;
+ bool NeedThreatReset;
+ bool DemonForm;
+ bool IsFinalForm;
+ bool EnrageUsed;
+ float x, y, z;
+
+ ObjectGuid InnderDemon[5];
+ uint32 InnerDemon_Count;
+ ObjectGuid Demon;
+ ObjectGuid SpellBinderGUID[3];
+
+ void Reset() override
{
- boss_leotheras_the_blindAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- creature->GetPosition(x, y, z);
- instance = creature->GetInstanceScript();
- }
+ CheckChannelers();
+ Initialize();
+ me->SetCanDualWield(true);
+ me->SetSpeedRate(MOVE_RUN, 2.0f);
+ me->SetDisplayId(MODEL_NIGHTELF);
+ me->SetVirtualItem(0, 0);
+ me->SetVirtualItem(1, 0);
+ DoCast(me, SPELL_DUAL_WIELD, true);
+ me->SetCorpseDelay(1000*60*60);
+ _Reset();
+ }
- void Initialize()
+ void CheckChannelers(/*bool DoEvade = true*/)
+ {
+ for (uint8 i = 0; i < 3; ++i)
{
- BanishTimer = 1000;
- Whirlwind_Timer = 15000;
- ChaosBlast_Timer = 1000;
- SwitchToDemon_Timer = 45000;
- SwitchToHuman_Timer = 60000;
- Berserk_Timer = 600000;
- InnerDemons_Timer = 30000;
-
- DealDamage = true;
- DemonForm = false;
- IsFinalForm = false;
- NeedThreatReset = false;
- EnrageUsed = false;
- for (ObjectGuid& guid : InnderDemon)
- guid.Clear();
- InnerDemon_Count = 0;
- }
+ if (Creature* add = ObjectAccessor::GetCreature(*me, SpellBinderGUID[i]))
+ add->DisappearAndDie();
- InstanceScript* instance;
-
- uint32 Whirlwind_Timer;
- uint32 ChaosBlast_Timer;
- uint32 SwitchToDemon_Timer;
- uint32 SwitchToHuman_Timer;
- uint32 Berserk_Timer;
- uint32 InnerDemons_Timer;
- uint32 BanishTimer;
-
- bool DealDamage;
- bool NeedThreatReset;
- bool DemonForm;
- bool IsFinalForm;
- bool EnrageUsed;
- float x, y, z;
-
- ObjectGuid InnderDemon[5];
- uint32 InnerDemon_Count;
- ObjectGuid Demon;
- ObjectGuid SpellBinderGUID[3];
-
- void Reset() override
- {
- CheckChannelers();
- Initialize();
- me->SetCanDualWield(true);
- me->SetSpeedRate(MOVE_RUN, 2.0f);
- me->SetDisplayId(MODEL_NIGHTELF);
- me->SetVirtualItem(0, 0);
- me->SetVirtualItem(1, 0);
- DoCast(me, SPELL_DUAL_WIELD, true);
- me->SetCorpseDelay(1000*60*60);
- instance->SetData(DATA_LEOTHERASTHEBLINDEVENT, NOT_STARTED);
+ float nx = x;
+ float ny = y;
+ float o = 2.4f;
+ if (i == 0) {nx += 10; ny -= 5; o=2.5f;}
+ if (i == 1) {nx -= 8; ny -= 7; o=0.9f;}
+ if (i == 2) {nx -= 3; ny += 9; o=5.0f;}
+ Creature* binder = me->SummonCreature(NPC_SPELLBINDER, nx, ny, z, o, TEMPSUMMON_DEAD_DESPAWN);
+ if (binder)
+ SpellBinderGUID[i] = binder->GetGUID();
}
+ }
+ void MoveInLineOfSight(Unit* who) override
- void CheckChannelers(/*bool DoEvade = true*/)
- {
- for (uint8 i = 0; i < 3; ++i)
- {
- if (Creature* add = ObjectAccessor::GetCreature(*me, SpellBinderGUID[i]))
- add->DisappearAndDie();
-
- float nx = x;
- float ny = y;
- float o = 2.4f;
- if (i == 0) {nx += 10; ny -= 5; o=2.5f;}
- if (i == 1) {nx -= 8; ny -= 7; o=0.9f;}
- if (i == 2) {nx -= 3; ny += 9; o=5.0f;}
- Creature* binder = me->SummonCreature(NPC_SPELLBINDER, nx, ny, z, o, TEMPSUMMON_DEAD_DESPAWN);
- if (binder)
- SpellBinderGUID[i] = binder->GetGUID();
- }
- }
- void MoveInLineOfSight(Unit* who) override
+ {
+ if (me->HasAura(AURA_BANISH))
+ return;
+ if (!me->GetVictim() && me->CanCreatureAttack(who))
{
- if (me->HasAura(AURA_BANISH))
+ if (me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
- if (!me->GetVictim() && me->CanCreatureAttack(who))
+ float attackRadius = me->GetAttackDistance(who);
+ if (me->IsWithinDistInMap(who, attackRadius))
{
- if (me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
- return;
-
- float attackRadius = me->GetAttackDistance(who);
- if (me->IsWithinDistInMap(who, attackRadius))
+ // Check first that object is in an angle in front of this one before LoS check
+ if (me->HasInArc(float(M_PI) / 2.0f, who) && me->IsWithinLOSInMap(who))
{
- // Check first that object is in an angle in front of this one before LoS check
- if (me->HasInArc(float(M_PI) / 2.0f, who) && me->IsWithinLOSInMap(who))
- {
- AttackStart(who);
- }
+ AttackStart(who);
}
}
}
+ }
- void StartEvent()
+ void StartEvent()
+ {
+ Talk(SAY_AGGRO);
+ instance->SetBossState(BOSS_LEOTHERAS_THE_BLIND, IN_PROGRESS);
+ }
+
+ void CheckBanish()
+ {
+ uint8 AliveChannelers = 0;
+ for (uint8 i = 0; i < 3; ++i)
{
- Talk(SAY_AGGRO);
- instance->SetData(DATA_LEOTHERASTHEBLINDEVENT, IN_PROGRESS);
+ Unit* add = ObjectAccessor::GetUnit(*me, SpellBinderGUID[i]);
+ if (add && add->IsAlive())
+ ++AliveChannelers;
}
- void CheckBanish()
+ // channelers == 0 remove banish aura
+ if (AliveChannelers == 0 && me->HasAura(AURA_BANISH))
{
- uint8 AliveChannelers = 0;
- for (uint8 i = 0; i < 3; ++i)
- {
- Unit* add = ObjectAccessor::GetUnit(*me, SpellBinderGUID[i]);
- if (add && add->IsAlive())
- ++AliveChannelers;
- }
+ // removing banish aura
+ me->RemoveAurasDueToSpell(AURA_BANISH);
- // channelers == 0 remove banish aura
- if (AliveChannelers == 0 && me->HasAura(AURA_BANISH))
- {
- // removing banish aura
- me->RemoveAurasDueToSpell(AURA_BANISH);
+ // Leotheras is getting immune again
+ me->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);
- // Leotheras is getting immune again
- me->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);
-
- // changing model to bloodelf
- me->SetDisplayId(MODEL_NIGHTELF);
+ // changing model to bloodelf
+ me->SetDisplayId(MODEL_NIGHTELF);
- // and reseting equipment
- me->LoadEquipment();
+ // and reseting equipment
+ me->LoadEquipment();
- if (!instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER).IsEmpty())
- {
- if (Unit* victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER)))
- AddThreat(victim, 1);
- StartEvent();
- }
- }
- else if (AliveChannelers != 0 && !me->HasAura(AURA_BANISH))
+ if (!instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER).IsEmpty())
{
- // channelers != 0 apply banish aura
- // removing Leotheras banish immune to apply AURA_BANISH
- me->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, false);
- DoCast(me, AURA_BANISH);
+ if (Unit* victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER)))
+ AddThreat(victim, 1);
+ StartEvent();
+ }
+ }
+ else if (AliveChannelers != 0 && !me->HasAura(AURA_BANISH))
+ {
+ // channelers != 0 apply banish aura
+ // removing Leotheras banish immune to apply AURA_BANISH
+ me->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, false);
+ DoCast(me, AURA_BANISH);
- // changing model
- me->SetDisplayId(MODEL_DEMON);
+ // changing model
+ me->SetDisplayId(MODEL_DEMON);
- // and removing weapons
- me->SetVirtualItem(0, 0);
- me->SetVirtualItem(1, 0);
- }
+ // and removing weapons
+ me->SetVirtualItem(0, 0);
+ me->SetVirtualItem(1, 0);
}
+ }
- //Despawn all Inner Demon summoned
- void DespawnDemon()
+ //Despawn all Inner Demon summoned
+ void DespawnDemon()
+ {
+ for (uint8 i=0; i<5; ++i)
{
- for (uint8 i = 0; i < 5; ++i)
+ if (!InnderDemon[i].IsEmpty())
{
- if (!InnderDemon[i].IsEmpty())
- {
- //delete creature
- Creature* creature = ObjectAccessor::GetCreature((*me), InnderDemon[i]);
- if (creature && creature->IsAlive())
- creature->DespawnOrUnsummon();
+ //delete creature
+ Creature* creature = ObjectAccessor::GetCreature((*me), InnderDemon[i]);
+ if (creature && creature->IsAlive())
+ creature->DespawnOrUnsummon();
- InnderDemon[i].Clear();
- }
+ InnderDemon[i].Clear();
}
-
- InnerDemon_Count = 0;
}
- void CastConsumingMadness() //remove this once SPELL_INSIDIOUS_WHISPER is supported by core
+ InnerDemon_Count = 0;
+ }
+
+ void CastConsumingMadness() //remove this once SPELL_INSIDIOUS_WHISPER is supported by core
+ {
+ for (uint8 i = 0; i < 5; ++i)
{
- for (uint8 i = 0; i < 5; ++i)
+ if (!InnderDemon[i].IsEmpty())
{
- if (!InnderDemon[i].IsEmpty())
+ Creature* unit = ObjectAccessor::GetCreature((*me), InnderDemon[i]);
+ if (unit && unit->IsAlive())
{
- Creature* unit = ObjectAccessor::GetCreature((*me), InnderDemon[i]);
- if (unit && unit->IsAlive())
+ Unit* unit_target = ObjectAccessor::GetUnit(*unit, unit->AI()->GetGUID(INNER_DEMON_VICTIM));
+ if (unit_target && unit_target->IsAlive())
{
- Unit* unit_target = ObjectAccessor::GetUnit(*unit, unit->AI()->GetGUID(INNER_DEMON_VICTIM));
- if (unit_target && unit_target->IsAlive())
- {
- unit->CastSpell(unit_target, SPELL_CONSUMING_MADNESS, true);
- ModifyThreatByPercent(unit_target, -100);
- }
+ unit->CastSpell(unit_target, SPELL_CONSUMING_MADNESS, true);
+ ModifyThreatByPercent(unit_target, -100);
}
}
}
}
+ }
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() != TYPEID_PLAYER)
- return;
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() != TYPEID_PLAYER)
+ return;
- Talk(DemonForm ? SAY_DEMON_SLAY : SAY_NIGHTELF_SLAY);
- }
+ Talk(DemonForm ? SAY_DEMON_SLAY : SAY_NIGHTELF_SLAY);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ Talk(SAY_DEATH);
- void JustDied(Unit* /*killer*/) override
+ //despawn copy
+ if (!Demon.IsEmpty())
{
- Talk(SAY_DEATH);
+ if (Creature* pDemon = ObjectAccessor::GetCreature(*me, Demon))
+ pDemon->DespawnOrUnsummon();
+ }
+ _JustDied();
+ }
- //despawn copy
- if (!Demon.IsEmpty())
- if (Creature* pDemon = ObjectAccessor::GetCreature(*me, Demon))
- pDemon->DespawnOrUnsummon();
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ if (me->HasAura(AURA_BANISH))
+ return;
- instance->SetData(DATA_LEOTHERASTHEBLINDEVENT, DONE);
- }
+ me->LoadEquipment();
+ }
- void JustEngagedWith(Unit* /*who*/) override
+ void UpdateAI(uint32 diff) override
+ {
+ //Return since we have no target
+ if (me->HasAura(AURA_BANISH) || !UpdateVictim())
{
- if (me->HasAura(AURA_BANISH))
+ if (BanishTimer <= diff)
+ {
+ CheckBanish();//no need to check every update tick
+ BanishTimer = 1000;
+ } else BanishTimer -= diff;
return;
-
- me->LoadEquipment();
}
-
- void UpdateAI(uint32 diff) override
+ if (me->HasAura(SPELL_WHIRLWIND))
{
- //Return since we have no target
- if (me->HasAura(AURA_BANISH) || !UpdateVictim())
+ if (Whirlwind_Timer <= diff)
{
- if (BanishTimer <= diff)
+ Unit* newTarget = SelectTarget(SelectTargetMethod::Random, 0);
+ if (newTarget)
{
- CheckBanish();//no need to check every update tick
- BanishTimer = 1000;
- } else BanishTimer -= diff;
- return;
- }
- if (me->HasAura(SPELL_WHIRLWIND))
+ ResetThreatList();
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MovePoint(0, newTarget->GetPositionX(), newTarget->GetPositionY(), newTarget->GetPositionZ());
+ }
+ Whirlwind_Timer = 2000;
+ } else Whirlwind_Timer -= diff;
+ }
+
+ // reseting after changing forms and after ending whirlwind
+ if (NeedThreatReset && !me->HasAura(SPELL_WHIRLWIND))
+ {
+ // when changing forms seting timers (or when ending whirlwind - to avoid adding new variable i use Whirlwind_Timer to countdown 2s while whirlwinding)
+ if (DemonForm)
+ InnerDemons_Timer = 30000;
+ else
+ Whirlwind_Timer = 15000;
+
+ NeedThreatReset = false;
+ ResetThreatList();
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveChase(me->GetVictim());
+ }
+
+ //Enrage_Timer (10 min)
+ if (Berserk_Timer < diff && !EnrageUsed)
+ {
+ me->InterruptNonMeleeSpells(false);
+ DoCast(me, SPELL_BERSERK);
+ EnrageUsed = true;
+ } else Berserk_Timer -= diff;
+
+ if (!DemonForm)
+ {
+ //Whirldind Timer
+ if (!me->HasAura(SPELL_WHIRLWIND))
{
if (Whirlwind_Timer <= diff)
{
- Unit* newTarget = SelectTarget(SelectTargetMethod::Random, 0);
- if (newTarget)
- {
- ResetThreatList();
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MovePoint(0, newTarget->GetPositionX(), newTarget->GetPositionY(), newTarget->GetPositionZ());
- }
+ DoCast(me, SPELL_WHIRLWIND);
+ // while whirlwinding this variable is used to countdown target's change
Whirlwind_Timer = 2000;
+ NeedThreatReset = true;
} else Whirlwind_Timer -= diff;
}
+ //Switch_Timer
- // reseting after changing forms and after ending whirlwind
- if (NeedThreatReset && !me->HasAura(SPELL_WHIRLWIND))
+ if (!IsFinalForm)
{
- // when changing forms seting timers (or when ending whirlwind - to avoid adding new variable i use Whirlwind_Timer to countdown 2s while whirlwinding)
- if (DemonForm)
- InnerDemons_Timer = 30000;
- else
- Whirlwind_Timer = 15000;
-
- NeedThreatReset = false;
- ResetThreatList();
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveChase(me->GetVictim());
+ if (SwitchToDemon_Timer <= diff)
+ {
+ //switch to demon form
+ me->RemoveAurasDueToSpell(SPELL_WHIRLWIND);
+ me->SetDisplayId(MODEL_DEMON);
+ Talk(SAY_SWITCH_TO_DEMON);
+ me->SetVirtualItem(0, 0);
+ me->SetVirtualItem(1, 0);
+ DemonForm = true;
+ NeedThreatReset = true;
+ SwitchToDemon_Timer = 45000;
+ } else SwitchToDemon_Timer -= diff;
}
-
- //Enrage_Timer (10 min)
- if (Berserk_Timer < diff && !EnrageUsed)
- {
- me->InterruptNonMeleeSpells(false);
- DoCast(me, SPELL_BERSERK);
- EnrageUsed = true;
- } else Berserk_Timer -= diff;
-
- if (!DemonForm)
+ DoMeleeAttackIfReady();
+ }
+ else
+ {
+ //ChaosBlast_Timer
+ if (!me->GetVictim())
+ return;
+ if (me->IsWithinDist(me->GetVictim(), 30))
+ me->StopMoving();
+ if (ChaosBlast_Timer <= diff)
{
- //Whirldind Timer
- if (!me->HasAura(SPELL_WHIRLWIND))
- {
- if (Whirlwind_Timer <= diff)
- {
- DoCast(me, SPELL_WHIRLWIND);
- // while whirlwinding this variable is used to countdown target's change
- Whirlwind_Timer = 2000;
- NeedThreatReset = true;
- } else Whirlwind_Timer -= diff;
- }
- //Switch_Timer
-
- if (!IsFinalForm)
+ // will cast only when in range of spell
+ if (me->IsWithinDist(me->GetVictim(), 30))
{
- if (SwitchToDemon_Timer <= diff)
- {
- //switch to demon form
- me->RemoveAurasDueToSpell(SPELL_WHIRLWIND);
- me->SetDisplayId(MODEL_DEMON);
- Talk(SAY_SWITCH_TO_DEMON);
- me->SetVirtualItem(0, 0);
- me->SetVirtualItem(1, 0);
- DemonForm = true;
- NeedThreatReset = true;
- SwitchToDemon_Timer = 45000;
- } else SwitchToDemon_Timer -= diff;
+ //DoCastVictim(SPELL_CHAOS_BLAST, true);
+ me->CastSpell(me->GetVictim(), SPELL_CHAOS_BLAST, CastSpellExtraArgs().SetOriginalCaster(me->GetGUID()).AddSpellBP0(100));
}
- DoMeleeAttackIfReady();
- }
- else
+ ChaosBlast_Timer = 3000;
+ } else ChaosBlast_Timer -= diff;
+ //Summon Inner Demon
+ if (InnerDemons_Timer <= diff)
{
- //ChaosBlast_Timer
- if (!me->GetVictim())
- return;
- if (me->IsWithinDist(me->GetVictim(), 30))
- me->StopMoving();
- if (ChaosBlast_Timer <= diff)
+ ThreatManager const& mgr = me->GetThreatManager();
+ std::list<Unit*> TargetList;
+ Unit* currentVictim = mgr.GetLastVictim();
+ for (ThreatReference const* ref : mgr.GetSortedThreatList())
{
- // will cast only when in range of spell
- if (me->IsWithinDist(me->GetVictim(), 30))
- {
- //DoCastVictim(SPELL_CHAOS_BLAST, true);
- me->CastSpell(me->GetVictim(), SPELL_CHAOS_BLAST, CastSpellExtraArgs().SetOriginalCaster(me->GetGUID()).AddSpellBP0(100));
- }
- ChaosBlast_Timer = 3000;
- } else ChaosBlast_Timer -= diff;
- //Summon Inner Demon
- if (InnerDemons_Timer <= diff)
+ if (Player* tempTarget = ref->GetVictim()->ToPlayer())
+ if (tempTarget != currentVictim && TargetList.size()<5)
+ TargetList.push_back(tempTarget);
+ }
+ //SpellInfo* spell = GET_SPELL(SPELL_INSIDIOUS_WHISPER);
+ for (auto itr = TargetList.begin(), end = TargetList.end(); itr != end; ++itr)
{
- ThreatManager const& mgr = me->GetThreatManager();
- std::list<Unit*> TargetList;
- Unit* currentVictim = mgr.GetLastVictim();
- for (ThreatReference const* ref : mgr.GetSortedThreatList())
+ if ((*itr) && (*itr)->IsAlive())
{
- if (Player* tempTarget = ref->GetVictim()->ToPlayer())
- if (tempTarget != currentVictim && TargetList.size()<5)
- TargetList.push_back(tempTarget);
- }
- //SpellInfo* spell = GET_SPELL(SPELL_INSIDIOUS_WHISPER);
- for (auto itr = TargetList.begin(), end = TargetList.end(); itr != end; ++itr)
- {
- if ((*itr) && (*itr)->IsAlive())
+ Creature* demon = me->SummonCreature(INNER_DEMON_ID, (*itr)->GetPositionX()+10, (*itr)->GetPositionY()+10, (*itr)->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
+ if (demon)
{
- Creature* demon = me->SummonCreature(INNER_DEMON_ID, (*itr)->GetPositionX()+10, (*itr)->GetPositionY()+10, (*itr)->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
- if (demon)
- {
- demon->AI()->AttackStart((*itr));
- demon->AI()->SetGUID((*itr)->GetGUID(), INNER_DEMON_VICTIM);
+ demon->AI()->AttackStart((*itr));
+ demon->AI()->SetGUID((*itr)->GetGUID(), INNER_DEMON_VICTIM);
- (*itr)->AddAura(SPELL_INSIDIOUS_WHISPER, *itr);
+ (*itr)->AddAura(SPELL_INSIDIOUS_WHISPER, *itr);
- if (InnerDemon_Count > 4)
- InnerDemon_Count = 0;
+ if (InnerDemon_Count > 4)
+ InnerDemon_Count = 0;
- //Safe storing of creatures
- InnderDemon[InnerDemon_Count] = demon->GetGUID();
+ //Safe storing of creatures
+ InnderDemon[InnerDemon_Count] = demon->GetGUID();
- //Update demon count
- ++InnerDemon_Count;
- }
+ //Update demon count
+ ++InnerDemon_Count;
}
}
- Talk(SAY_INNER_DEMONS);
-
- InnerDemons_Timer = 999999;
- } else InnerDemons_Timer -= diff;
-
- //Switch_Timer
- if (SwitchToHuman_Timer <= diff)
- {
- //switch to nightelf form
- me->SetDisplayId(MODEL_NIGHTELF);
- me->LoadEquipment();
-
- CastConsumingMadness();
- DespawnDemon();
-
- DemonForm = false;
- NeedThreatReset = true;
+ }
+ Talk(SAY_INNER_DEMONS);
- SwitchToHuman_Timer = 60000;
- } else SwitchToHuman_Timer -= diff;
- }
+ InnerDemons_Timer = 999999;
+ } else InnerDemons_Timer -= diff;
- if (!IsFinalForm && HealthBelowPct(15))
+ //Switch_Timer
+ if (SwitchToHuman_Timer <= diff)
{
- //at this point he divides himself in two parts
+ //switch to nightelf form
+ me->SetDisplayId(MODEL_NIGHTELF);
+ me->LoadEquipment();
+
CastConsumingMadness();
DespawnDemon();
- if (Creature* Copy = DoSpawnCreature(DEMON_FORM, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 6s))
- {
- Demon = Copy->GetGUID();
- if (me->GetVictim())
- Copy->AI()->AttackStart(me->GetVictim());
- }
- //set nightelf final form
- IsFinalForm = true;
+
DemonForm = false;
+ NeedThreatReset = true;
- Talk(SAY_FINAL_FORM);
- me->SetDisplayId(MODEL_NIGHTELF);
- me->LoadEquipment();
+ SwitchToHuman_Timer = 60000;
+ } else SwitchToHuman_Timer -= diff;
+ }
+
+ if (!IsFinalForm && HealthBelowPct(15))
+ {
+ //at this point he divides himself in two parts
+ CastConsumingMadness();
+ DespawnDemon();
+ if (Creature* Copy = DoSpawnCreature(DEMON_FORM, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 6s))
+ {
+ Demon = Copy->GetGUID();
+ if (me->GetVictim())
+ Copy->AI()->AttackStart(me->GetVictim());
}
+ //set nightelf final form
+ IsFinalForm = true;
+ DemonForm = false;
+
+ Talk(SAY_FINAL_FORM);
+ me->SetDisplayId(MODEL_NIGHTELF);
+ me->LoadEquipment();
}
- };
+ }
};
//Leotheras the Blind Demon Form AI
-class boss_leotheras_the_blind_demonform : public CreatureScript
+struct boss_leotheras_the_blind_demonform : public ScriptedAI
{
-public:
- boss_leotheras_the_blind_demonform() : CreatureScript("boss_leotheras_the_blind_demonform") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ boss_leotheras_the_blind_demonform(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<boss_leotheras_the_blind_demonformAI>(creature);
+ Initialize();
}
- struct boss_leotheras_the_blind_demonformAI : public ScriptedAI
+ void Initialize()
{
- boss_leotheras_the_blind_demonformAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- }
+ ChaosBlast_Timer = 1000;
+ DealDamage = true;
+ }
- void Initialize()
- {
- ChaosBlast_Timer = 1000;
- DealDamage = true;
- }
+ uint32 ChaosBlast_Timer;
+ bool DealDamage;
- uint32 ChaosBlast_Timer;
- bool DealDamage;
+ void Reset() override
+ {
+ Initialize();
+ }
- void Reset() override
- {
- Initialize();
- }
+ void StartEvent()
+ {
+ Talk(SAY_FREE);
+ }
- void StartEvent()
- {
- Talk(SAY_FREE);
- }
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() != TYPEID_PLAYER)
+ return;
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() != TYPEID_PLAYER)
- return;
+ Talk(SAY_DEMON_SLAY);
+ }
- Talk(SAY_DEMON_SLAY);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ //invisibility (blizzlike, at the end of the fight he doesn't die, he disappears)
+ DoCast(me, 8149, true);
+ }
- void JustDied(Unit* /*killer*/) override
- {
- //invisibility (blizzlike, at the end of the fight he doesn't die, he disappears)
- DoCast(me, 8149, true);
- }
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ StartEvent();
+ }
- void JustEngagedWith(Unit* /*who*/) override
- {
- StartEvent();
- }
+ void UpdateAI(uint32 diff) override
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+ //ChaosBlast_Timer
+ if (me->IsWithinDist(me->GetVictim(), 30))
+ me->StopMoving();
- void UpdateAI(uint32 diff) override
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
- //ChaosBlast_Timer
+ if (ChaosBlast_Timer <= diff)
+ {
+ // will cast only when in range od spell
if (me->IsWithinDist(me->GetVictim(), 30))
- me->StopMoving();
-
- if (ChaosBlast_Timer <= diff)
- {
- // will cast only when in range od spell
- if (me->IsWithinDist(me->GetVictim(), 30))
- {
- //DoCastVictim(SPELL_CHAOS_BLAST, true);
- me->CastSpell(me->GetVictim(), SPELL_CHAOS_BLAST, CastSpellExtraArgs().SetOriginalCaster(me->GetGUID()).AddSpellBP0(100));
- ChaosBlast_Timer = 3000;
- }
- } else ChaosBlast_Timer -= diff;
+ {
+ //DoCastVictim(SPELL_CHAOS_BLAST, true);
+ me->CastSpell(me->GetVictim(), SPELL_CHAOS_BLAST, CastSpellExtraArgs().SetOriginalCaster(me->GetGUID()).AddSpellBP0(100));
+ ChaosBlast_Timer = 3000;
+ }
+ } else ChaosBlast_Timer -= diff;
- //Do NOT deal any melee damage to the target.
- }
- };
+ //Do NOT deal any melee damage to the target.
+ }
};
-class npc_greyheart_spellbinder : public CreatureScript
+struct npc_greyheart_spellbinder : public ScriptedAI
{
-public:
- npc_greyheart_spellbinder() : CreatureScript("npc_greyheart_spellbinder") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_greyheart_spellbinder(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<npc_greyheart_spellbinderAI>(creature);
+ Initialize();
+ instance = creature->GetInstanceScript();
+ AddedBanish = false;
}
- struct npc_greyheart_spellbinderAI : public ScriptedAI
+ void Initialize()
{
- npc_greyheart_spellbinderAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- AddedBanish = false;
- }
+ Mindblast_Timer = urand(3000, 8000);
+ Earthshock_Timer = urand(5000, 10000);
+ }
- void Initialize()
- {
- Mindblast_Timer = urand(3000, 8000);
- Earthshock_Timer = urand(5000, 10000);
- }
+ InstanceScript* instance;
+
+ ObjectGuid leotherasGUID;
- InstanceScript* instance;
+ uint32 Mindblast_Timer;
+ uint32 Earthshock_Timer;
- ObjectGuid leotherasGUID;
+ bool AddedBanish;
- uint32 Mindblast_Timer;
- uint32 Earthshock_Timer;
+ void Reset() override
+ {
+ Initialize();
- bool AddedBanish;
+ instance->SetGuidData(DATA_LEOTHERAS_EVENT_STARTER, ObjectGuid::Empty);
+ Creature* leotheras = ObjectAccessor::GetCreature(*me, leotherasGUID);
+ if (leotheras && leotheras->IsAlive())
+ ENSURE_AI(boss_leotheras_the_blind, leotheras->AI())->CheckChannelers(/*false*/);
+ }
- void Reset() override
- {
- Initialize();
+ void JustEngagedWith(Unit* who) override
+ {
+ me->InterruptNonMeleeSpells(false);
+ instance->SetGuidData(DATA_LEOTHERAS_EVENT_STARTER, who->GetGUID());
+ }
- instance->SetGuidData(DATA_LEOTHERAS_EVENT_STARTER, ObjectGuid::Empty);
- Creature* leotheras = ObjectAccessor::GetCreature(*me, leotherasGUID);
- if (leotheras && leotheras->IsAlive())
- ENSURE_AI(boss_leotheras_the_blind::boss_leotheras_the_blindAI, leotheras->AI())->CheckChannelers(/*false*/);
- }
+ void JustAppeared() override
+ {
+ AddedBanish = false;
+ Reset();
+ }
- void JustEngagedWith(Unit* who) override
+ void CastChanneling()
+ {
+ if (!me->IsInCombat() && !me->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
{
- me->InterruptNonMeleeSpells(false);
- instance->SetGuidData(DATA_LEOTHERAS_EVENT_STARTER, who->GetGUID());
+ if (!leotherasGUID.IsEmpty())
+ {
+ Creature* leotheras = ObjectAccessor::GetCreature(*me, leotherasGUID);
+ if (leotheras && leotheras->IsAlive())
+ DoCast(leotheras, BANISH_BEAM);
+ }
}
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!leotherasGUID)
+ leotherasGUID = instance->GetGuidData(DATA_LEOTHERAS);
- void JustAppeared() override
+ if (!me->IsInCombat() && !instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER).IsEmpty())
{
- AddedBanish = false;
- Reset();
+ if (Unit* victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER)))
+ AttackStart(victim);
}
- void CastChanneling()
+ if (!UpdateVictim())
{
- if (!me->IsInCombat() && !me->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
- {
- if (!leotherasGUID.IsEmpty())
- {
- Creature* leotheras = ObjectAccessor::GetCreature(*me, leotherasGUID);
- if (leotheras && leotheras->IsAlive())
- DoCast(leotheras, BANISH_BEAM);
- }
- }
+ CastChanneling();
+ return;
}
- void UpdateAI(uint32 diff) override
+ if (!instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER))
{
- if (!leotherasGUID)
- leotherasGUID = instance->GetGuidData(DATA_LEOTHERAS);
-
- if (!me->IsInCombat() && !instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER).IsEmpty())
- {
- if (Unit* victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER)))
- AttackStart(victim);
- }
-
- if (!UpdateVictim())
- {
- CastChanneling();
- return;
- }
-
- if (!instance->GetGuidData(DATA_LEOTHERAS_EVENT_STARTER))
- {
- EnterEvadeMode();
- return;
- }
+ EnterEvadeMode();
+ return;
+ }
- if (Mindblast_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- DoCast(target, SPELL_MINDBLAST);
+ if (Mindblast_Timer <= diff)
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ DoCast(target, SPELL_MINDBLAST);
- Mindblast_Timer = urand(10000, 15000);
- } else Mindblast_Timer -= diff;
+ Mindblast_Timer = urand(10000, 15000);
+ } else Mindblast_Timer -= diff;
- if (Earthshock_Timer <= diff)
+ if (Earthshock_Timer <= diff)
+ {
+ Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
{
- Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
+ if (Player* i_pl = itr->GetSource())
{
- if (Player* i_pl = itr->GetSource())
- {
- bool isCasting = false;
- for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
- if (i_pl->GetCurrentSpell(i))
- isCasting = true;
+ bool isCasting = false;
+ for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
+ if (i_pl->GetCurrentSpell(i))
+ isCasting = true;
- if (isCasting)
- {
- DoCast(i_pl, SPELL_EARTHSHOCK);
- break;
- }
+ if (isCasting)
+ {
+ DoCast(i_pl, SPELL_EARTHSHOCK);
+ break;
}
}
- Earthshock_Timer = urand(8000, 15000);
- } else Earthshock_Timer -= diff;
- DoMeleeAttackIfReady();
- }
-
- void JustDied(Unit* /*killer*/) override { }
- };
+ }
+ Earthshock_Timer = urand(8000, 15000);
+ } else Earthshock_Timer -= diff;
+ DoMeleeAttackIfReady();
+ }
};
void AddSC_boss_leotheras_the_blind()
{
- new boss_leotheras_the_blind();
- new boss_leotheras_the_blind_demonform();
- new npc_greyheart_spellbinder();
- new npc_inner_demon();
+ RegisterSerpentshrineCavernCreatureAI(boss_leotheras_the_blind);
+ RegisterSerpentshrineCavernCreatureAI(boss_leotheras_the_blind_demonform);
+ RegisterSerpentshrineCavernCreatureAI(npc_greyheart_spellbinder);
+ RegisterSerpentshrineCavernCreatureAI(npc_inner_demon);
}
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
index 5afdb989f40..a3e16887b68 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
@@ -79,408 +79,360 @@ float AddPos[9][3] =
{42.471519f, -445.115295f, -19.769423f}
};
-class boss_the_lurker_below : public CreatureScript
+struct boss_the_lurker_below : public BossAI
{
-public:
- boss_the_lurker_below() : CreatureScript("boss_the_lurker_below") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ boss_the_lurker_below(Creature* creature) : BossAI(creature, BOSS_THE_LURKER_BELOW)
{
- return GetSerpentshrineCavernAI<boss_the_lurker_belowAI>(creature);
+ Initialize();
+ SetCombatMovement(false);
}
- struct boss_the_lurker_belowAI : public ScriptedAI
+ void Initialize()
{
- boss_the_lurker_belowAI(Creature* creature) : ScriptedAI(creature), Summons(me)
- {
- Initialize();
- SetCombatMovement(false);
- instance = creature->GetInstanceScript();
- }
+ SpoutAnimTimer = 1000;
+ RotTimer = 0;
+ WaterboltTimer = 15000; // give time to get in range when fight starts
+ SpoutTimer = 45000;
+ WhirlTimer = 18000; // after avery spout
+ PhaseTimer = 120000;
+ GeyserTimer = rand32() % 5000 + 15000;
+ CheckTimer = 15000; // give time to get in range when fight starts
+ WaitTimer = 60000; // never reached
+ WaitTimer2 = 60000; // never reached
+
+ Submerged = true; // will be false at combat start
+ Spawned = false;
+ InRange = false;
+ CanStartEvent = false;
+ }
- void Initialize()
- {
- SpoutAnimTimer = 1000;
- RotTimer = 0;
- WaterboltTimer = 15000; // give time to get in range when fight starts
- SpoutTimer = 45000;
- WhirlTimer = 18000; // after avery spout
- PhaseTimer = 120000;
- GeyserTimer = rand32() % 5000 + 15000;
- CheckTimer = 15000; // give time to get in range when fight starts
- WaitTimer = 60000; // never reached
- WaitTimer2 = 60000; // never reached
-
- Submerged = true; // will be false at combat start
- Spawned = false;
- InRange = false;
- CanStartEvent = false;
- }
+ bool Spawned;
+ bool Submerged;
+ bool InRange;
+ bool CanStartEvent;
+ uint32 RotTimer;
+ uint32 SpoutAnimTimer;
+ uint32 WaterboltTimer;
+ uint32 SpoutTimer;
+ uint32 WhirlTimer;
+ uint32 PhaseTimer;
+ uint32 GeyserTimer;
+ uint32 CheckTimer;
+ uint32 WaitTimer;
+ uint32 WaitTimer2;
+
+ bool CheckCanStart()//check if players fished
+ {
+ if (instance->GetData(DATA_STRANGE_POOL) == NOT_STARTED)
+ return false;
+ return true;
+ }
- InstanceScript* instance;
- SummonList Summons;
-
- bool Spawned;
- bool Submerged;
- bool InRange;
- bool CanStartEvent;
- uint32 RotTimer;
- uint32 SpoutAnimTimer;
- uint32 WaterboltTimer;
- uint32 SpoutTimer;
- uint32 WhirlTimer;
- uint32 PhaseTimer;
- uint32 GeyserTimer;
- uint32 CheckTimer;
- uint32 WaitTimer;
- uint32 WaitTimer2;
-
- bool CheckCanStart()//check if players fished
- {
- if (instance->GetData(DATA_STRANGE_POOL) == NOT_STARTED)
- return false;
- return true;
- }
+ void Reset() override
+ {
+ me->SetSwim(true);
+ me->SetDisableGravity(true);
+ Initialize();
+
+ _Reset();
+ instance->SetData(DATA_STRANGE_POOL, NOT_STARTED);
+ DoCast(me, SPELL_SUBMERGE); // submerge anim
+ me->SetVisible(false); // we start invis under water, submerged
+ me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+ me->SetImmuneToPC(true);
+ }
- void Reset() override
- {
- me->SetSwim(true);
- me->SetDisableGravity(true);
- Initialize();
-
- Summons.DespawnAll();
-
- instance->SetData(DATA_THELURKERBELOWEVENT, NOT_STARTED);
- instance->SetData(DATA_STRANGE_POOL, NOT_STARTED);
- DoCast(me, SPELL_SUBMERGE); // submerge anim
- me->SetVisible(false); // we start invis under water, submerged
- me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
- me->SetImmuneToPC(true);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ instance->SetData(DATA_STRANGE_POOL, IN_PROGRESS);
+ }
- void JustDied(Unit* /*killer*/) override
+ void MoveInLineOfSight(Unit* who) override
+ {
+ if (!CanStartEvent) // boss is invisible, don't attack
+ return;
+ if (!me->GetVictim() && who->IsValidAttackTarget(me))
{
- instance->SetData(DATA_THELURKERBELOWEVENT, DONE);
- instance->SetData(DATA_STRANGE_POOL, IN_PROGRESS);
-
- Summons.DespawnAll();
+ float attackRadius = me->GetAttackDistance(who);
+ if (me->IsWithinDistInMap(who, attackRadius))
+ AttackStart(who);
}
+ }
- void JustEngagedWith(Unit* /*who*/) override
- {
- instance->SetData(DATA_THELURKERBELOWEVENT, IN_PROGRESS);
- }
+ void MovementInform(uint32 type, uint32 /*id*/) override
+ {
+ if (type == ROTATE_MOTION_TYPE)
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
- void MoveInLineOfSight(Unit* who) override
+ void UpdateAI(uint32 diff) override
+ {
+ if (!CanStartEvent) // boss is invisible, don't attack
{
- if (!CanStartEvent) // boss is invisible, don't attack
- return;
- if (!me->GetVictim() && who->IsValidAttackTarget(me))
+ if (CheckCanStart())
{
- float attackRadius = me->GetAttackDistance(who);
- if (me->IsWithinDistInMap(who, attackRadius))
- AttackStart(who);
+ if (Submerged)
+ {
+ me->SetVisible(true);
+ Submerged = false;
+ WaitTimer2 = 500;
+ }
+ else if (WaitTimer2 <= diff) // wait 500ms before emerge anim
+ {
+ me->RemoveAllAuras();
+ me->SetEmoteState(EMOTE_ONESHOT_NONE);
+ DoCast(me, SPELL_EMERGE, false);
+ WaitTimer2 = 60000; // never reached
+ WaitTimer = 3000;
+ }
+ else
+ WaitTimer2 -= diff;
+
+ if (WaitTimer <= diff) // wait 3secs for emerge anim, then attack
+ {
+ WaitTimer = 3000;
+ CanStartEvent = true; // fresh fished from pool
+ me->SetImmuneToPC(false);
+ me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+ }
+ else
+ WaitTimer -= diff;
}
+ return;
}
- void MovementInform(uint32 type, uint32 /*id*/) override
+ if (!me->IsThreatened()) // check if should evade
{
- if (type == ROTATE_MOTION_TYPE)
- me->SetReactState(REACT_AGGRESSIVE);
+ if (me->IsEngaged())
+ EnterEvadeMode();
+ return;
}
-
- void UpdateAI(uint32 diff) override
+ if (!Submerged)
{
- if (!CanStartEvent) // boss is invisible, don't attack
+ if (PhaseTimer <= diff)
{
- if (CheckCanStart())
- {
- if (Submerged)
- {
- me->SetVisible(true);
- Submerged = false;
- WaitTimer2 = 500;
- }
- else if (WaitTimer2 <= diff) // wait 500ms before emerge anim
- {
- me->RemoveAllAuras();
- me->SetEmoteState(EMOTE_ONESHOT_NONE);
- DoCast(me, SPELL_EMERGE, false);
- WaitTimer2 = 60000; // never reached
- WaitTimer = 3000;
- }
- else
- WaitTimer2 -= diff;
+ me->InterruptNonMeleeSpells(false);
+ DoCast(me, SPELL_SUBMERGE);
+ PhaseTimer = 60000; // 60secs submerged
+ Submerged = true;
+ }
+ else
+ PhaseTimer -= diff;
- if (WaitTimer <= diff) // wait 3secs for emerge anim, then attack
- {
- WaitTimer = 3000;
- CanStartEvent = true; // fresh fished from pool
- me->SetImmuneToPC(false);
- me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
- }
- else
- WaitTimer -= diff;
- }
+ if (SpoutTimer <= diff)
+ {
+ Talk(EMOTE_SPOUT);
+ me->SetReactState(REACT_PASSIVE);
+ me->GetMotionMaster()->MoveRotate(0, 20000, urand(0, 1) ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT);
+ SpoutTimer = 45000;
+ WhirlTimer = 20000; // whirl directly after spout
+ RotTimer = 20000;
return;
}
+ else
+ SpoutTimer -= diff;
- if (!me->IsThreatened()) // check if should evade
+ // Whirl directly after a Spout and at random times
+ if (WhirlTimer <= diff)
{
- if (me->IsEngaged())
- EnterEvadeMode();
- return;
+ WhirlTimer = 18000;
+ DoCast(me, SPELL_WHIRL);
}
- if (!Submerged)
+ else
+ WhirlTimer -= diff;
+
+ if (CheckTimer <= diff) // check if there are players in melee range
{
- if (PhaseTimer <= diff)
+ InRange = false;
+ Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
+ if (!PlayerList.isEmpty())
{
- me->InterruptNonMeleeSpells(false);
- DoCast(me, SPELL_SUBMERGE);
- PhaseTimer = 60000; // 60secs submerged
- Submerged = true;
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (me->IsWithinMeleeRange(i->GetSource()))
+ InRange = true;
+ }
}
- else
- PhaseTimer -= diff;
+ CheckTimer = 2000;
+ }
+ else
+ CheckTimer -= diff;
- if (SpoutTimer <= diff)
+ if (RotTimer)
+ {
+ instance->instance->DoOnPlayers([&](Player* player)
{
- Talk(EMOTE_SPOUT);
- me->SetReactState(REACT_PASSIVE);
- me->GetMotionMaster()->MoveRotate(0, 20000, urand(0, 1) ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT);
- SpoutTimer = 45000;
- WhirlTimer = 20000; // whirl directly after spout
- RotTimer = 20000;
- return;
- }
- else
- SpoutTimer -= diff;
+ if (player->IsAlive() && me->HasInArc(diff/20000.f*float(M_PI)*2.f, player) && me->IsWithinDist(player, SPOUT_DIST) && !player->IsInWater())
+ DoCast(player, SPELL_SPOUT, true); // only knock back players in arc, in 100yards, not in water
+ });
- // Whirl directly after a Spout and at random times
- if (WhirlTimer <= diff)
+ if (SpoutAnimTimer <= diff)
{
- WhirlTimer = 18000;
- DoCast(me, SPELL_WHIRL);
- }
- else
- WhirlTimer -= diff;
+ DoCast(me, SPELL_SPOUT_ANIM, true);
+ SpoutAnimTimer = 1000;
+ } else SpoutAnimTimer -= diff;
- if (CheckTimer <= diff) // check if there are players in melee range
+ if (RotTimer <= diff)
{
- InRange = false;
- Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
- if (!PlayerList.isEmpty())
- {
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- {
- if (me->IsWithinMeleeRange(i->GetSource()))
- InRange = true;
- }
- }
- CheckTimer = 2000;
+ RotTimer = 0;
}
else
- CheckTimer -= diff;
-
- if (RotTimer)
- {
- instance->instance->DoOnPlayers([this, diff](Player* player)
- {
- if (player->IsAlive() && me->HasInArc(diff / 20000.f * float(M_PI) * 2.f, player) && me->IsWithinDist(player, SPOUT_DIST) && !player->IsInWater())
- DoCast(player, SPELL_SPOUT, true); // only knock back players in arc, in 100yards, not in water
- });
-
- if (SpoutAnimTimer <= diff)
- {
- DoCast(me, SPELL_SPOUT_ANIM, true);
- SpoutAnimTimer = 1000;
- } else SpoutAnimTimer -= diff;
+ RotTimer -= diff;
+ return;
+ }
- if (RotTimer <= diff)
- {
- RotTimer = 0;
- }
- else
- RotTimer -= diff;
- return;
- }
+ if (GeyserTimer <= diff)
+ {
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
+ if (!target && me->GetVictim())
+ target = me->GetVictim();
+ if (target)
+ DoCast(target, SPELL_GEYSER, true);
+ GeyserTimer = rand32() % 5000 + 15000;
+ }
+ else
+ GeyserTimer -= diff;
- if (GeyserTimer <= diff)
+ if (!InRange) // if on players in melee range cast Waterbolt
+ {
+ if (WaterboltTimer <= diff)
{
- Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
if (!target && me->GetVictim())
target = me->GetVictim();
if (target)
- DoCast(target, SPELL_GEYSER, true);
- GeyserTimer = rand32() % 5000 + 15000;
+ DoCast(target, SPELL_WATERBOLT, true);
+ WaterboltTimer = 3000;
}
else
- GeyserTimer -= diff;
-
- if (!InRange) // if on players in melee range cast Waterbolt
- {
- if (WaterboltTimer <= diff)
- {
- Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
- if (!target && me->GetVictim())
- target = me->GetVictim();
- if (target)
- DoCast(target, SPELL_WATERBOLT, true);
- WaterboltTimer = 3000;
- }
- else
- WaterboltTimer -= diff;
- }
+ WaterboltTimer -= diff;
+ }
- if (!UpdateVictim())
- return;
+ if (!UpdateVictim())
+ return;
- DoMeleeAttackIfReady();
+ DoMeleeAttackIfReady();
- }
- else // submerged
+ }
+ else // submerged
+ {
+ if (PhaseTimer <= diff)
{
- if (PhaseTimer <= diff)
- {
- Submerged = false;
- me->InterruptNonMeleeSpells(false); // shouldn't be any
- me->RemoveAllAuras();
- me->SetImmuneToPC(false);
- me->SetEmoteState(EMOTE_ONESHOT_NONE);
- DoCast(me, SPELL_EMERGE, true);
- Spawned = false;
- SpoutTimer = 3000; // directly cast Spout after emerging!
- PhaseTimer = 120000;
- return;
- }
- else
- PhaseTimer -= diff;
+ Submerged = false;
+ me->InterruptNonMeleeSpells(false); // shouldn't be any
+ me->RemoveAllAuras();
+ me->SetImmuneToPC(false);
+ me->SetEmoteState(EMOTE_ONESHOT_NONE);
+ DoCast(me, SPELL_EMERGE, true);
+ Spawned = false;
+ SpoutTimer = 3000; // directly cast Spout after emerging!
+ PhaseTimer = 120000;
+ return;
+ }
+ else
+ PhaseTimer -= diff;
- if (!me->IsThreatened()) // check if should evade
- {
- EnterEvadeMode();
- return;
- }
+ if (!me->IsThreatened()) // check if should evade
+ {
+ EnterEvadeMode();
+ return;
+ }
- if (!me->IsInCombat())
- DoZoneInCombat();
+ if (!me->IsInCombat())
+ DoZoneInCombat();
- if (!Spawned)
- {
- me->ReplaceAllUnitFlags(UNIT_FLAG_IMMUNE_TO_PC);
- // spawn adds
- for (uint8 i = 0; i < 9; ++i)
- if (Creature* summoned = me->SummonCreature(i < 6 ? NPC_COILFANG_AMBUSHER : NPC_COILFANG_GUARDIAN, AddPos[i][0], AddPos[i][1], AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN))
- Summons.Summon(summoned);
- Spawned = true;
- }
+ if (!Spawned)
+ {
+ me->ReplaceAllUnitFlags(UNIT_FLAG_IMMUNE_TO_PC);
+ // spawn adds
+ for (uint8 i = 0; i < 9; ++i)
+ me->SummonCreature(i < 6 ? NPC_COILFANG_AMBUSHER : NPC_COILFANG_GUARDIAN, AddPos[i][0], AddPos[i][1], AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN);
+ Spawned = true;
}
}
- };
-};
+ }
+ };
-class npc_coilfang_ambusher : public CreatureScript
+struct npc_coilfang_ambusher : public ScriptedAI
{
-public:
- npc_coilfang_ambusher() : CreatureScript("npc_coilfang_ambusher") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_coilfang_ambusher(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<npc_coilfang_ambusherAI>(creature);
+ Initialize();
+ SetCombatMovement(false);
}
- struct npc_coilfang_ambusherAI : public ScriptedAI
+ void Initialize()
{
- npc_coilfang_ambusherAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- SetCombatMovement(false);
- }
-
- void Initialize()
- {
- MultiShotTimer = 10000;
- ShootBowTimer = 4000;
- }
+ MultiShotTimer = 10000;
+ ShootBowTimer = 4000;
+ }
- uint32 MultiShotTimer;
- uint32 ShootBowTimer;
+ uint32 MultiShotTimer;
+ uint32 ShootBowTimer;
- void Reset() override
- {
- Initialize();
- }
+ void Reset() override
+ {
+ Initialize();
+ }
- void MoveInLineOfSight(Unit* who) override
+ void MoveInLineOfSight(Unit* who) override
- {
- if (!who || me->GetVictim())
- return;
+ {
+ if (!who || me->GetVictim())
+ return;
- if (who->isInAccessiblePlaceFor(me) && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 45))
- AttackStart(who);
- }
+ if (who->isInAccessiblePlaceFor(me) && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 45))
+ AttackStart(who);
+ }
- void UpdateAI(uint32 diff) override
+ void UpdateAI(uint32 diff) override
+ {
+ if (MultiShotTimer <= diff)
{
- if (MultiShotTimer <= diff)
- {
- if (me->GetVictim())
- DoCastVictim(SPELL_SPREAD_SHOT, true);
+ if (me->GetVictim())
+ DoCastVictim(SPELL_SPREAD_SHOT, true);
- MultiShotTimer = 10000 + rand32() % 10000;
- ShootBowTimer += 1500; // add global cooldown
- } else MultiShotTimer -= diff;
-
- if (ShootBowTimer <= diff)
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- me->CastSpell(target, SPELL_SHOOT, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellBP0(1100));
- ShootBowTimer = 4000 + rand32() % 5000;
- MultiShotTimer += 1500; // add global cooldown
- } else ShootBowTimer -= diff;
- }
- };
+ MultiShotTimer = 10000 + rand32() % 10000;
+ ShootBowTimer += 1500; // add global cooldown
+ } else MultiShotTimer -= diff;
+ if (ShootBowTimer <= diff)
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ me->CastSpell(target, SPELL_SHOOT, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellBP0(1100));
+ ShootBowTimer = 4000 + rand32() % 5000;
+ MultiShotTimer += 1500; // add global cooldown
+ } else ShootBowTimer -= diff;
+ }
};
-class go_strange_pool : public GameObjectScript
+struct go_strange_pool : public GameObjectAI
{
- public:
- go_strange_pool() : GameObjectScript("go_strange_pool") { }
-
- struct go_strange_poolAI : public GameObjectAI
- {
- go_strange_poolAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
+ go_strange_pool(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
- InstanceScript* instance;
+ InstanceScript* instance;
- bool OnGossipHello(Player* player) override
+ bool OnGossipHello(Player* player) override
+ {
+ // 25%
+ if (!urand(0, 3))
+ {
+ if (instance->GetData(DATA_STRANGE_POOL) == NOT_STARTED)
{
- // 25%
- if (!urand(0, 3))
- {
- if (instance->GetData(DATA_STRANGE_POOL) == NOT_STARTED)
- {
- me->CastSpell(player, 54587);
- instance->SetData(DATA_STRANGE_POOL, IN_PROGRESS);
- }
- return true;
- }
-
- return false;
+ me->CastSpell(player, 54587);
+ instance->SetData(DATA_STRANGE_POOL, IN_PROGRESS);
}
- };
-
- GameObjectAI* GetAI(GameObject* go) const override
- {
- return GetSerpentshrineCavernAI<go_strange_poolAI>(go);
+ return true;
}
+
+ return false;
+ }
};
void AddSC_boss_the_lurker_below()
{
- new boss_the_lurker_below();
- new npc_coilfang_ambusher();
- new go_strange_pool();
+ RegisterSerpentshrineCavernCreatureAI(boss_the_lurker_below);
+ RegisterSerpentshrineCavernCreatureAI(npc_coilfang_ambusher);
+ RegisterSerpentshrineCavernGameObjectAI(go_strange_pool);
}
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
index a752c81adaa..f3273232950 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
@@ -86,286 +86,253 @@ float MurlocCords[10][4] =
};
//Morogrim Tidewalker AI
-class boss_morogrim_tidewalker : public CreatureScript
+struct boss_morogrim_tidewalker : public BossAI
{
-public:
- boss_morogrim_tidewalker() : CreatureScript("boss_morogrim_tidewalker") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ boss_morogrim_tidewalker(Creature* creature) : BossAI(creature, BOSS_MOROGRIM_TIDEWALKER)
{
- return GetSerpentshrineCavernAI<boss_morogrim_tidewalkerAI>(creature);
+ Initialize();
+ Playercount = 0;
+ counter = 0;
}
- struct boss_morogrim_tidewalkerAI : public ScriptedAI
+ void Initialize()
{
- boss_morogrim_tidewalkerAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- Playercount = 0;
- counter = 0;
- }
+ TidalWave_Timer = 10000;
+ WateryGrave_Timer = 30000;
+ Earthquake_Timer = 40000;
+ WateryGlobules_Timer = 0;
+ globulespell[0] = SPELL_SUMMON_WATER_GLOBULE_1;
+ globulespell[1] = SPELL_SUMMON_WATER_GLOBULE_2;
+ globulespell[2] = SPELL_SUMMON_WATER_GLOBULE_3;
+ globulespell[3] = SPELL_SUMMON_WATER_GLOBULE_4;
+
+ Earthquake = false;
+ Phase2 = false;
+ }
- void Initialize()
- {
- TidalWave_Timer = 10000;
- WateryGrave_Timer = 30000;
- Earthquake_Timer = 40000;
- WateryGlobules_Timer = 0;
- globulespell[0] = SPELL_SUMMON_WATER_GLOBULE_1;
- globulespell[1] = SPELL_SUMMON_WATER_GLOBULE_2;
- globulespell[2] = SPELL_SUMMON_WATER_GLOBULE_3;
- globulespell[3] = SPELL_SUMMON_WATER_GLOBULE_4;
-
- Earthquake = false;
- Phase2 = false;
- }
+ uint32 TidalWave_Timer;
+ uint32 WateryGrave_Timer;
+ uint32 Earthquake_Timer;
+ uint32 WateryGlobules_Timer;
+ uint32 globulespell[4];
+ int8 Playercount;
+ int8 counter;
- InstanceScript* instance;
+ bool Earthquake;
+ bool Phase2;
- uint32 TidalWave_Timer;
- uint32 WateryGrave_Timer;
- uint32 Earthquake_Timer;
- uint32 WateryGlobules_Timer;
- uint32 globulespell[4];
- int8 Playercount;
- int8 counter;
+ void Reset() override
+ {
+ Initialize();
- bool Earthquake;
- bool Phase2;
+ _Reset();
+ }
- void Reset() override
- {
- Initialize();
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ Talk(SAY_SLAY);
+ }
- instance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, NOT_STARTED);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ Talk(SAY_DEATH);
- void StartEvent()
- {
- Talk(SAY_AGGRO);
+ _JustDied();
+ }
- instance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, IN_PROGRESS);
- }
+ void JustEngagedWith(Unit* who) override
+ {
+ Playercount = me->GetMap()->GetPlayers().getSize();
+ Talk(SAY_AGGRO);
+ _JustEngagedWith(who);
+ }
- void KilledUnit(Unit* /*victim*/) override
+ void ApplyWateryGrave(Unit* player, uint8 i)
+ {
+ switch (i)
{
- Talk(SAY_SLAY);
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- Talk(SAY_DEATH);
-
- instance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, DONE);
+ case 0: player->CastSpell(player, SPELL_WATERY_GRAVE_1, true); break;
+ case 1: player->CastSpell(player, SPELL_WATERY_GRAVE_2, true); break;
+ case 2: player->CastSpell(player, SPELL_WATERY_GRAVE_3, true); break;
+ case 3: player->CastSpell(player, SPELL_WATERY_GRAVE_4, true); break;
}
+ }
- void JustEngagedWith(Unit* /*who*/) override
- {
- Playercount = me->GetMap()->GetPlayers().getSize();
- StartEvent();
- }
+ void UpdateAI(uint32 diff) override
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
- void ApplyWateryGrave(Unit* player, uint8 i)
+ //Earthquake_Timer
+ if (Earthquake_Timer <= diff)
{
- switch (i)
+ if (!Earthquake)
{
- case 0: player->CastSpell(player, SPELL_WATERY_GRAVE_1, true); break;
- case 1: player->CastSpell(player, SPELL_WATERY_GRAVE_2, true); break;
- case 2: player->CastSpell(player, SPELL_WATERY_GRAVE_3, true); break;
- case 3: player->CastSpell(player, SPELL_WATERY_GRAVE_4, true); break;
+ DoCastVictim(SPELL_EARTHQUAKE);
+ Earthquake = true;
+ Earthquake_Timer = 10000;
}
- }
-
- void UpdateAI(uint32 diff) override
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- //Earthquake_Timer
- if (Earthquake_Timer <= diff)
+ else
{
- if (!Earthquake)
- {
- DoCastVictim(SPELL_EARTHQUAKE);
- Earthquake = true;
- Earthquake_Timer = 10000;
- }
- else
- {
- Talk(SAY_SUMMON);
+ Talk(SAY_SUMMON);
- for (uint8 i = 0; i < 10; ++i)
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- if (Creature* Murloc = me->SummonCreature(NPC_TIDEWALKER_LURKER, MurlocCords[i][0], MurlocCords[i][1], MurlocCords[i][2], MurlocCords[i][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10s))
- Murloc->AI()->AttackStart(target);
- }
- Talk(EMOTE_EARTHQUAKE);
- Earthquake = false;
- Earthquake_Timer = 40000 + rand32() % 5000;
+ for (uint8 i = 0; i < 10; ++i)
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ if (Creature* Murloc = me->SummonCreature(NPC_TIDEWALKER_LURKER, MurlocCords[i][0], MurlocCords[i][1], MurlocCords[i][2], MurlocCords[i][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10s))
+ Murloc->AI()->AttackStart(target);
}
- } else Earthquake_Timer -= diff;
+ Talk(EMOTE_EARTHQUAKE);
+ Earthquake = false;
+ Earthquake_Timer = 40000 + rand32() % 5000;
+ }
+ } else Earthquake_Timer -= diff;
- //TidalWave_Timer
- if (TidalWave_Timer <= diff)
- {
- DoCastVictim(SPELL_TIDAL_WAVE);
- TidalWave_Timer = 20000;
- } else TidalWave_Timer -= diff;
+ //TidalWave_Timer
+ if (TidalWave_Timer <= diff)
+ {
+ DoCastVictim(SPELL_TIDAL_WAVE);
+ TidalWave_Timer = 20000;
+ } else TidalWave_Timer -= diff;
- if (!Phase2)
+ if (!Phase2)
+ {
+ //WateryGrave_Timer
+ if (WateryGrave_Timer <= diff)
{
- //WateryGrave_Timer
- if (WateryGrave_Timer <= diff)
+ //Teleport 4 players under the waterfalls
+ GuidSet targets;
+ GuidSet::const_iterator itr = targets.begin();
+ for (uint8 i = 0; i < 4; ++i)
{
- //Teleport 4 players under the waterfalls
- GuidSet targets;
- GuidSet::const_iterator itr = targets.begin();
- for (uint8 i = 0; i < 4; ++i)
+ counter = 0;
+ Unit* target;
+ do
{
- counter = 0;
- Unit* target;
- do
- {
- target = SelectTarget(SelectTargetMethod::Random, 1, 50, true); //target players only
- if (counter < Playercount)
- break;
- if (target)
- itr = targets.find(target->GetGUID());
- ++counter;
- } while (itr != targets.end());
-
+ target = SelectTarget(SelectTargetMethod::Random, 1, 50, true); //target players only
+ if (counter < Playercount)
+ break;
if (target)
- {
- targets.insert(target->GetGUID());
- ApplyWateryGrave(target, i);
- }
+ itr = targets.find(target->GetGUID());
+ ++counter;
+ } while (itr != targets.end());
+
+ if (target)
+ {
+ targets.insert(target->GetGUID());
+ ApplyWateryGrave(target, i);
}
+ }
- Talk(SAY_SUMMON_BUBL);
+ Talk(SAY_SUMMON_BUBL);
- Talk(EMOTE_WATERY_GRAVE);
- WateryGrave_Timer = 30000;
- } else WateryGrave_Timer -= diff;
+ Talk(EMOTE_WATERY_GRAVE);
+ WateryGrave_Timer = 30000;
+ } else WateryGrave_Timer -= diff;
- //Start Phase2
- if (HealthBelowPct(25))
- Phase2 = true;
- }
- else
+ //Start Phase2
+ if (HealthBelowPct(25))
+ Phase2 = true;
+ }
+ else
+ {
+ //WateryGlobules_Timer
+ if (WateryGlobules_Timer <= diff)
{
- //WateryGlobules_Timer
- if (WateryGlobules_Timer <= diff)
+ GuidSet globules;
+ GuidSet::const_iterator itr = globules.begin();
+ for (uint8 g = 0; g < 4; g++) //one unit can't cast more than one spell per update, so some players have to cast for us XD
{
- GuidSet globules;
- GuidSet::const_iterator itr = globules.begin();
- for (uint8 g = 0; g < 4; g++) //one unit can't cast more than one spell per update, so some players have to cast for us XD
+ counter = 0;
+ Unit* pGlobuleTarget;
+ do
{
- counter = 0;
- Unit* pGlobuleTarget;
- do
- {
- pGlobuleTarget = SelectTarget(SelectTargetMethod::Random, 0, 50, true);
- if (pGlobuleTarget)
- itr = globules.find(pGlobuleTarget->GetGUID());
- if (counter > Playercount)
- break;
- ++counter;
- } while (itr != globules.end());
-
+ pGlobuleTarget = SelectTarget(SelectTargetMethod::Random, 0, 50, true);
if (pGlobuleTarget)
- {
- globules.insert(pGlobuleTarget->GetGUID());
- pGlobuleTarget->CastSpell(pGlobuleTarget, globulespell[g], true);
- }
- }
- Talk(EMOTE_WATERY_GLOBULES);
- WateryGlobules_Timer = 25000;
- } else WateryGlobules_Timer -= diff;
- }
+ itr = globules.find(pGlobuleTarget->GetGUID());
+ if (counter > Playercount)
+ break;
+ ++counter;
+ } while (itr != globules.end());
- DoMeleeAttackIfReady();
+ if (pGlobuleTarget)
+ {
+ globules.insert(pGlobuleTarget->GetGUID());
+ pGlobuleTarget->CastSpell(pGlobuleTarget, globulespell[g], true);
+ }
+ }
+ Talk(EMOTE_WATERY_GLOBULES);
+ WateryGlobules_Timer = 25000;
+ } else WateryGlobules_Timer -= diff;
}
- };
+ DoMeleeAttackIfReady();
+ }
};
-class npc_water_globule : public CreatureScript
+struct npc_water_globule : public ScriptedAI
{
-public:
- npc_water_globule() : CreatureScript("npc_water_globule") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_water_globule(Creature* creature) : ScriptedAI(creature)
{
- return GetSerpentshrineCavernAI<npc_water_globuleAI>(creature);
+ Initialize();
}
- struct npc_water_globuleAI : public ScriptedAI
+ void Initialize()
{
- npc_water_globuleAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- }
+ Check_Timer = 1000;
+ }
- void Initialize()
- {
- Check_Timer = 1000;
- }
+ uint32 Check_Timer;
- uint32 Check_Timer;
+ void Reset() override
+ {
+ Initialize();
- void Reset() override
- {
- Initialize();
+ me->SetFaction(FACTION_MONSTER);
+ }
- me->SetFaction(FACTION_MONSTER);
- }
+ void JustEngagedWith(Unit* /*who*/) override { }
- void JustEngagedWith(Unit* /*who*/) override { }
+ void MoveInLineOfSight(Unit* who) override
- void MoveInLineOfSight(Unit* who) override
+ {
+ if (!who || me->GetVictim())
+ return;
+ if (me->CanCreatureAttack(who))
{
- if (!who || me->GetVictim())
- return;
-
- if (me->CanCreatureAttack(who))
- {
- //no attack radius check - it attacks the first target that moves in his los
- //who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- AttackStart(who);
- }
+ //no attack radius check - it attacks the first target that moves in his los
+ //who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ AttackStart(who);
}
+ }
- void UpdateAI(uint32 diff) override
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
- if (Check_Timer <= diff)
+ if (Check_Timer <= diff)
+ {
+ if (me->IsWithinDistInMap(me->GetVictim(), 5))
{
- if (me->IsWithinDistInMap(me->GetVictim(), 5))
- {
- DoCastVictim(SPELL_GLOBULE_EXPLOSION);
-
- //despawn
- me->DespawnOrUnsummon();
- return;
- }
- Check_Timer = 500;
- } else Check_Timer -= diff;
+ DoCastVictim(SPELL_GLOBULE_EXPLOSION);
- //do NOT deal any melee damage to the target.
- }
- };
+ //despawn
+ me->DespawnOrUnsummon();
+ return;
+ }
+ Check_Timer = 500;
+ } else Check_Timer -= diff;
+ //do NOT deal any melee damage to the target.
+ }
};
void AddSC_boss_morogrim_tidewalker()
{
- new boss_morogrim_tidewalker();
- new npc_water_globule();
+ RegisterSerpentshrineCavernCreatureAI(boss_morogrim_tidewalker);
+ RegisterSerpentshrineCavernCreatureAI(npc_water_globule);
}
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
index ab2586716e2..ebde8fa0ccc 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
@@ -97,7 +97,7 @@ class instance_serpent_shrine : public InstanceMapScript
instance_serpentshrine_cavern_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ SetBossNumber(MAX_ENCOUNTER);
StrangePool = 0;
Water = WATERSTATE_FRENZY;
@@ -113,15 +113,6 @@ class instance_serpent_shrine : public InstanceMapScript
TrashCount = 0;
}
- bool IsEncounterInProgress() const override
- {
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS)
- return true;
-
- return false;
- }
-
void Update(uint32 diff) override
{
//Water checks
@@ -299,32 +290,6 @@ class instance_serpent_shrine : public InstanceMapScript
case DATA_WATER:
Water = data;
break;
- case DATA_HYDROSSTHEUNSTABLEEVENT:
- m_auiEncounter[0] = data;
- break;
- case DATA_LEOTHERASTHEBLINDEVENT:
- m_auiEncounter[1] = data;
- break;
- case DATA_THELURKERBELOWEVENT:
- m_auiEncounter[2] = data;
- break;
- case DATA_KARATHRESSEVENT:
- m_auiEncounter[3] = data;
- break;
- case DATA_MOROGRIMTIDEWALKEREVENT:
- m_auiEncounter[4] = data;
- break;
- //Lady Vashj
- case DATA_LADYVASHJEVENT:
- if (data == NOT_STARTED)
- {
- ShieldGeneratorDeactivated[0] = false;
- ShieldGeneratorDeactivated[1] = false;
- ShieldGeneratorDeactivated[2] = false;
- ShieldGeneratorDeactivated[3] = false;
- }
- m_auiEncounter[5] = data;
- break;
case DATA_SHIELDGENERATOR1:
ShieldGeneratorDeactivated[0] = data != 0;
break;
@@ -340,28 +305,28 @@ class instance_serpent_shrine : public InstanceMapScript
default:
break;
}
+ }
+
+ bool SetBossState(uint32 id, EncounterState state) override
+ {
+ if (!InstanceScript::SetBossState(id, state))
+ return false;
+
+ if (id == BOSS_LADY_VASHJ && state == NOT_STARTED)
+ {
+ ShieldGeneratorDeactivated[0] = false;
+ ShieldGeneratorDeactivated[1] = false;
+ ShieldGeneratorDeactivated[2] = false;
+ ShieldGeneratorDeactivated[3] = false;
+ }
- if (data == DONE)
- SaveToDB();
+ return true;
}
uint32 GetData(uint32 type) const override
{
switch (type)
{
- case DATA_HYDROSSTHEUNSTABLEEVENT:
- return m_auiEncounter[0];
- case DATA_LEOTHERASTHEBLINDEVENT:
- return m_auiEncounter[1];
- case DATA_THELURKERBELOWEVENT:
- return m_auiEncounter[2];
- case DATA_KARATHRESSEVENT:
- return m_auiEncounter[3];
- case DATA_MOROGRIMTIDEWALKEREVENT:
- return m_auiEncounter[4];
- //Lady Vashj
- case DATA_LADYVASHJEVENT:
- return m_auiEncounter[5];
case DATA_SHIELDGENERATOR1:
return ShieldGeneratorDeactivated[0];
case DATA_SHIELDGENERATOR2:
@@ -385,34 +350,14 @@ class instance_serpent_shrine : public InstanceMapScript
return 0;
}
- std::string GetSaveData() override
+ void WriteSaveDataMore(std::ostringstream& stream) override
{
- OUT_SAVE_INST_DATA;
- std::ostringstream stream;
- stream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' '
- << m_auiEncounter[3] << ' ' << m_auiEncounter[4] << ' ' << m_auiEncounter[5] << ' ' << TrashCount;
- OUT_SAVE_INST_DATA_COMPLETE;
- return stream.str();
+ stream << TrashCount;
}
- void Load(char const* in) override
+ void ReadSaveDataMore(std::istringstream& stream) override
{
- if (!in)
- {
- OUT_LOAD_INST_DATA_FAIL;
- return;
- }
-
- OUT_LOAD_INST_DATA(in);
- std::istringstream stream(in);
- stream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
- >> m_auiEncounter[4] >> m_auiEncounter[5] >> TrashCount;
-
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead.
- m_auiEncounter[i] = NOT_STARTED;
-
- OUT_LOAD_INST_DATA_COMPLETE;
+ stream >> TrashCount;
}
private:
@@ -436,7 +381,6 @@ class instance_serpent_shrine : public InstanceMapScript
uint32 TrashCount;
bool ShieldGeneratorDeactivated[4];
- uint32 m_auiEncounter[MAX_ENCOUNTER];
bool DoSpawnFrenzy;
};
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h
index b7ad1f73512..2228a36d8c8 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h
@@ -30,33 +30,37 @@ enum SSWaterEventState
WATERSTATE_SCALDING = 2
};
+enum SSBosses
+{
+ BOSS_HYDROSS_THE_UNSTABLE = 0,
+ BOSS_THE_LURKER_BELOW = 1,
+ BOSS_LEOTHERAS_THE_BLIND = 2,
+ BOSS_FATHOM_LORD_KARATHRESS = 3,
+ BOSS_MOROGRIM_TIDEWALKER = 4,
+ BOSS_LADY_VASHJ = 5
+};
+
enum SSDataTypes
{
DATA_CANSTARTPHASE3 = 1,
DATA_CARIBDIS = 2,
- DATA_HYDROSSTHEUNSTABLEEVENT = 3,
- DATA_KARATHRESS = 4,
- DATA_KARATHRESSEVENT = 5,
- DATA_KARATHRESSEVENT_STARTER = 6,
- DATA_LADYVASHJ = 7,
- DATA_LADYVASHJEVENT = 8,
- DATA_LEOTHERASTHEBLINDEVENT = 9,
- DATA_MOROGRIMTIDEWALKEREVENT = 10,
- DATA_SHARKKIS = 11,
- DATA_SHIELDGENERATOR1 = 12,
- DATA_SHIELDGENERATOR2 = 13,
- DATA_SHIELDGENERATOR3 = 14,
- DATA_SHIELDGENERATOR4 = 15,
- DATA_THELURKERBELOW = 16,
- DATA_THELURKERBELOWEVENT = 17,
- DATA_TIDALVESS = 18,
- DATA_FATHOMLORDKARATHRESSEVENT = 19,
- DATA_LEOTHERAS = 20,
- DATA_LEOTHERAS_EVENT_STARTER = 21,
- DATA_CONTROL_CONSOLE = 22,
- DATA_STRANGE_POOL = 23,
- DATA_WATER = 24,
- DATA_TRASH = 25,
+ DATA_KARATHRESS = 3,
+ DATA_KARATHRESSEVENT_STARTER = 4,
+ DATA_LADYVASHJ = 5,
+ DATA_SHARKKIS = 6,
+ DATA_SHIELDGENERATOR1 = 7,
+ DATA_SHIELDGENERATOR2 = 8,
+ DATA_SHIELDGENERATOR3 = 9,
+ DATA_SHIELDGENERATOR4 = 10,
+ DATA_THELURKERBELOW = 11,
+ DATA_TIDALVESS = 12,
+ DATA_FATHOMLORDKARATHRESSEVENT = 13,
+ DATA_LEOTHERAS = 14,
+ DATA_LEOTHERAS_EVENT_STARTER = 15,
+ DATA_CONTROL_CONSOLE = 16,
+ DATA_STRANGE_POOL = 17,
+ DATA_WATER = 18,
+ DATA_TRASH = 19,
};
template <class AI, class T>
@@ -65,4 +69,7 @@ inline AI* GetSerpentshrineCavernAI(T* obj)
return GetInstanceAI<AI>(obj, SSCScriptName);
}
+#define RegisterSerpentshrineCavernCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetSerpentshrineCavernAI)
+#define RegisterSerpentshrineCavernGameObjectAI(ai_name) RegisterGameObjectAIWithFactory(ai_name, GetSerpentshrineCavernAI)
+
#endif