aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp590
1 files changed, 277 insertions, 313 deletions
diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
index 9868bdea0d4..336e7f30dd3 100644
--- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
+++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
@@ -82,407 +82,371 @@ enum ElementalEvents
EVENT_SURGE = 1
};
-class boss_drakkari_colossus : public CreatureScript
+struct boss_drakkari_colossus : public BossAI
{
- public:
- boss_drakkari_colossus() : CreatureScript("boss_drakkari_colossus") { }
+ boss_drakkari_colossus(Creature* creature) : BossAI(creature, DATA_DRAKKARI_COLOSSUS)
+ {
+ Initialize();
+ me->SetReactState(REACT_PASSIVE);
+ introDone = false;
+ }
- struct boss_drakkari_colossusAI : public BossAI
- {
- boss_drakkari_colossusAI(Creature* creature) : BossAI(creature, DATA_DRAKKARI_COLOSSUS)
- {
- Initialize();
- me->SetReactState(REACT_PASSIVE);
- introDone = false;
- }
+ void Initialize()
+ {
+ phase = COLOSSUS_PHASE_NORMAL;
+ }
- void Initialize()
- {
- phase = COLOSSUS_PHASE_NORMAL;
- }
+ void Reset() override
+ {
+ _Reset();
- void Reset() override
- {
- _Reset();
+ if (GetData(DATA_INTRO_DONE))
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetImmuneToPC(false);
+ me->RemoveAura(SPELL_FREEZE_ANIM);
+ }
- if (GetData(DATA_INTRO_DONE))
- {
- me->SetReactState(REACT_AGGRESSIVE);
- me->SetImmuneToPC(false);
- me->RemoveAura(SPELL_FREEZE_ANIM);
- }
+ events.ScheduleEvent(EVENT_MIGHTY_BLOW, 10s, 30s);
- events.ScheduleEvent(EVENT_MIGHTY_BLOW, 10s, 30s);
+ Initialize();
+ }
- Initialize();
- }
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
+ me->RemoveAura(SPELL_FREEZE_ANIM);
+ }
- void JustEngagedWith(Unit* who) override
- {
- BossAI::JustEngagedWith(who);
- me->RemoveAura(SPELL_FREEZE_ANIM);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ }
- void JustDied(Unit* /*killer*/) override
- {
- _JustDied();
- }
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_SUMMON_ELEMENTAL:
+ DoCast(SPELL_EMERGE);
+ break;
+ case ACTION_FREEZE_COLOSSUS:
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveIdle();
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_SUMMON_ELEMENTAL:
- DoCast(SPELL_EMERGE);
- break;
- case ACTION_FREEZE_COLOSSUS:
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveIdle();
-
- me->SetReactState(REACT_PASSIVE);
- me->SetImmuneToPC(true);
- DoCast(me, SPELL_FREEZE_ANIM);
- break;
- case ACTION_UNFREEZE_COLOSSUS:
-
- if (me->GetReactState() == REACT_AGGRESSIVE)
- return;
+ me->SetReactState(REACT_PASSIVE);
+ me->SetImmuneToPC(true);
+ DoCast(me, SPELL_FREEZE_ANIM);
+ break;
+ case ACTION_UNFREEZE_COLOSSUS:
- me->SetImmuneToPC(false);
- me->SetReactState(REACT_AGGRESSIVE);
- me->RemoveAura(SPELL_FREEZE_ANIM);
+ if (me->GetReactState() == REACT_AGGRESSIVE)
+ return;
- DoZoneInCombat();
+ me->SetImmuneToPC(false);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveAura(SPELL_FREEZE_ANIM);
- break;
- }
- }
+ DoZoneInCombat();
- void DamageTaken(Unit* /*attacker*/, uint32& damage) override
- {
- if (me->IsImmuneToPC())
- damage = 0;
+ break;
+ }
+ }
- if (phase == COLOSSUS_PHASE_NORMAL ||
- phase == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON)
- {
- if (HealthBelowPct(phase == COLOSSUS_PHASE_NORMAL ? 50 : 5))
- {
- damage = 0;
- phase = (phase == COLOSSUS_PHASE_NORMAL ? COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON : COLOSSUS_PHASE_SECOND_ELEMENTAL_SUMMON);
- DoAction(ACTION_FREEZE_COLOSSUS);
- DoAction(ACTION_SUMMON_ELEMENTAL);
- }
- }
- }
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (me->IsImmuneToPC())
+ damage = 0;
- uint32 GetData(uint32 data) const override
+ if (phase == COLOSSUS_PHASE_NORMAL ||
+ phase == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON)
+ {
+ if (HealthBelowPct(phase == COLOSSUS_PHASE_NORMAL ? 50 : 5))
{
- if (data == DATA_COLOSSUS_PHASE)
- return phase;
- else if (data == DATA_INTRO_DONE)
- return introDone;
-
- return 0;
+ damage = 0;
+ phase = (phase == COLOSSUS_PHASE_NORMAL ? COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON : COLOSSUS_PHASE_SECOND_ELEMENTAL_SUMMON);
+ DoAction(ACTION_FREEZE_COLOSSUS);
+ DoAction(ACTION_SUMMON_ELEMENTAL);
}
+ }
+ }
- void SetData(uint32 type, uint32 data) override
- {
- if (type == DATA_INTRO_DONE)
- introDone = data != 0;
- }
+ uint32 GetData(uint32 data) const override
+ {
+ if (data == DATA_COLOSSUS_PHASE)
+ return phase;
+ else if (data == DATA_INTRO_DONE)
+ return introDone;
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ return 0;
+ }
- events.Update(diff);
+ void SetData(uint32 type, uint32 data) override
+ {
+ if (type == DATA_INTRO_DONE)
+ introDone = data != 0;
+ }
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_MIGHTY_BLOW:
- DoCastVictim(SPELL_MIGHTY_BLOW);
- events.ScheduleEvent(EVENT_MIGHTY_BLOW, 5s, 15s);
- break;
- }
+ events.Update(diff);
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (me->GetReactState() == REACT_AGGRESSIVE)
- DoMeleeAttackIfReady();
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_MIGHTY_BLOW:
+ DoCastVictim(SPELL_MIGHTY_BLOW);
+ events.ScheduleEvent(EVENT_MIGHTY_BLOW, 5s, 15s);
+ break;
}
- void JustSummoned(Creature* summon) override
- {
- DoZoneInCombat(summon);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
- if (phase == COLOSSUS_PHASE_SECOND_ELEMENTAL_SUMMON)
- summon->SetHealth(summon->GetMaxHealth() / 2);
- }
+ if (me->GetReactState() == REACT_AGGRESSIVE)
+ DoMeleeAttackIfReady();
+ }
- private:
- uint8 phase;
- bool introDone;
- };
+ void JustSummoned(Creature* summon) override
+ {
+ DoZoneInCombat(summon);
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetGundrakAI<boss_drakkari_colossusAI>(creature);
- }
+ if (phase == COLOSSUS_PHASE_SECOND_ELEMENTAL_SUMMON)
+ summon->SetHealth(summon->GetMaxHealth() / 2);
+ }
+
+private:
+ uint8 phase;
+ bool introDone;
};
-class boss_drakkari_elemental : public CreatureScript
+struct boss_drakkari_elemental : public ScriptedAI
{
- public:
- boss_drakkari_elemental() : CreatureScript("boss_drakkari_elemental") { }
+ boss_drakkari_elemental(Creature* creature) : ScriptedAI(creature)
+ {
+ DoCast(me, SPELL_ELEMENTAL_SPAWN_EFFECT);
+ instance = creature->GetInstanceScript();
+ }
- struct boss_drakkari_elementalAI : public ScriptedAI
- {
- boss_drakkari_elementalAI(Creature* creature) : ScriptedAI(creature)
- {
- DoCast(me, SPELL_ELEMENTAL_SPAWN_EFFECT);
- instance = creature->GetInstanceScript();
- }
+ void Reset() override
+ {
+ events.Reset();
+ events.ScheduleEvent(EVENT_SURGE, 5s, 15s);
- void Reset() override
- {
- events.Reset();
- events.ScheduleEvent(EVENT_SURGE, 5s, 15s);
+ me->AddAura(SPELL_MOJO_VOLLEY, me);
+ }
- me->AddAura(SPELL_MOJO_VOLLEY, me);
- }
+ void JustDied(Unit* killer) override
+ {
+ Talk(EMOTE_ACTIVATE_ALTAR);
- void JustDied(Unit* killer) override
- {
- Talk(EMOTE_ACTIVATE_ALTAR);
+ if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
+ Unit::Kill(killer, colossus);
+ }
- if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
- Unit::Kill(killer, colossus);
- }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ events.Update(diff);
- events.Update(diff);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SURGE:
+ DoCast(SPELL_SURGE_VISUAL);
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
+ DoCast(target, SPELL_SURGE);
+ events.ScheduleEvent(EVENT_SURGE, 5s, 15s);
+ break;
+ }
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_SURGE:
- DoCast(SPELL_SURGE_VISUAL);
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
- DoCast(target, SPELL_SURGE);
- events.ScheduleEvent(EVENT_SURGE, 5s, 15s);
- break;
- }
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
- DoMeleeAttackIfReady();
- }
+ DoMeleeAttackIfReady();
+ }
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_RETURN_TO_COLOSSUS:
- Talk(EMOTE_MOJO);
- DoCast(SPELL_SURGE_VISUAL);
- if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
- // what if the elemental is more than 80 yards from drakkari colossus ?
- DoCast(colossus, SPELL_MERGE, true);
- break;
- }
- }
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_RETURN_TO_COLOSSUS:
+ Talk(EMOTE_MOJO);
+ DoCast(SPELL_SURGE_VISUAL);
+ if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
+ // what if the elemental is more than 80 yards from drakkari colossus ?
+ DoCast(colossus, SPELL_MERGE, true);
+ break;
+ }
+ }
- void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (HealthBelowPct(50))
+ {
+ if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
{
- if (HealthBelowPct(50))
+ if (colossus->AI()->GetData(DATA_COLOSSUS_PHASE) == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON)
{
- if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
- {
- if (colossus->AI()->GetData(DATA_COLOSSUS_PHASE) == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON)
- {
- damage = 0;
-
- // to prevent spell spaming
- if (me->HasUnitState(UNIT_STATE_CHARGING))
- return;
-
- // not sure about this, the idea of this code is to prevent bug the elemental
- // if it is not in a acceptable distance to cast the charge spell.
- /*if (me->GetDistance(colossus) > 80.0f)
- {
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
- return;
-
- me->GetMotionMaster()->MovePoint(0, colossus->GetPositionX(), colossus->GetPositionY(), colossus->GetPositionZ());
- return;
- }*/
- DoAction(ACTION_RETURN_TO_COLOSSUS);
- }
- }
- }
- }
+ damage = 0;
- void EnterEvadeMode(EvadeReason /*why*/) override
- {
- me->DespawnOrUnsummon();
- }
+ // to prevent spell spaming
+ if (me->HasUnitState(UNIT_STATE_CHARGING))
+ return;
- void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
- {
- if (spellInfo->Id == SPELL_MERGE)
- {
- if (Creature* colossus = target->ToCreature())
+ // not sure about this, the idea of this code is to prevent bug the elemental
+ // if it is not in a acceptable distance to cast the charge spell.
+ /*if (me->GetDistance(colossus) > 80.0f)
{
- colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
- me->DespawnOrUnsummon();
- }
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
+ return;
+
+ me->GetMotionMaster()->MovePoint(0, colossus->GetPositionX(), colossus->GetPositionY(), colossus->GetPositionZ());
+ return;
+ }*/
+ DoAction(ACTION_RETURN_TO_COLOSSUS);
}
}
+ }
+ }
- private:
- EventMap events;
- InstanceScript* instance;
- };
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ me->DespawnOrUnsummon();
+ }
- CreatureAI* GetAI(Creature* creature) const override
+ void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_MERGE)
{
- return GetGundrakAI<boss_drakkari_elementalAI>(creature);
+ if (Creature* colossus = target->ToCreature())
+ {
+ colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
+ me->DespawnOrUnsummon();
+ }
}
+ }
+
+private:
+ EventMap events;
+ InstanceScript* instance;
};
-class npc_living_mojo : public CreatureScript
+struct npc_living_mojo : public ScriptedAI
{
-public:
- npc_living_mojo() : CreatureScript("npc_living_mojo") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_living_mojo(Creature* creature) : ScriptedAI(creature)
{
- return GetGundrakAI<npc_living_mojoAI>(creature);
+ instance = creature->GetInstanceScript();
}
- struct npc_living_mojoAI : public ScriptedAI
+ void Reset() override
{
- npc_living_mojoAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ _scheduler.CancelAll();
+ }
- void Initialize()
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ _scheduler.Schedule(2s, [this](TaskContext task)
{
- mojoWaveTimer = 2 * IN_MILLISECONDS;
- mojoPuddleTimer = 7 * IN_MILLISECONDS;
- }
-
- void Reset() override
+ DoCastVictim(SPELL_MOJO_WAVE);
+ task.Repeat(15s);
+ })
+ .Schedule(7s, [this](TaskContext task)
{
- Initialize();
- }
+ DoCastVictim(SPELL_MOJO_PUDDLE);
+ task.Repeat(18s);
+ });
+ }
- void MoveMojos(Creature* boss)
+ void MoveMojos(Creature* boss)
+ {
+ std::list<Creature*> mojosList;
+ boss->GetCreatureListWithEntryInGrid(mojosList, me->GetEntry(), 12.0f);
+ if (!mojosList.empty())
{
- std::list<Creature*> mojosList;
- boss->GetCreatureListWithEntryInGrid(mojosList, me->GetEntry(), 12.0f);
- if (!mojosList.empty())
+ for (std::list<Creature*>::const_iterator itr = mojosList.begin(); itr != mojosList.end(); ++itr)
{
- for (std::list<Creature*>::const_iterator itr = mojosList.begin(); itr != mojosList.end(); ++itr)
- {
- if (Creature* mojo = *itr)
- mojo->GetMotionMaster()->MovePoint(1, boss->GetHomePosition().GetPositionX(), boss->GetHomePosition().GetPositionY(), boss->GetHomePosition().GetPositionZ());
- }
+ if (Creature* mojo = *itr)
+ mojo->GetMotionMaster()->MovePoint(1, boss->GetHomePosition().GetPositionX(), boss->GetHomePosition().GetPositionY(), boss->GetHomePosition().GetPositionZ());
}
}
+ }
- void MovementInform(uint32 type, uint32 id) override
- {
- if (type != POINT_MOTION_TYPE)
- return;
-
- if (id == 1)
- {
- if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
- {
- colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
- if (!colossus->AI()->GetData(DATA_INTRO_DONE))
- colossus->AI()->SetData(DATA_INTRO_DONE, true);
- DoZoneInCombat(colossus);
- me->DespawnOrUnsummon();
- }
- }
- }
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
- void AttackStart(Unit* attacker) override
+ if (id == 1)
{
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
- return;
-
- // we do this checks to see if the creature is one of the creatures that sorround the boss
if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
{
- Position homePosition = me->GetHomePosition();
-
- float distance = homePosition.GetExactDist(&colossus->GetHomePosition());
-
- if (distance < 12.0f)
- {
- MoveMojos(colossus);
- me->SetReactState(REACT_PASSIVE);
- }
- else
- ScriptedAI::AttackStart(attacker);
+ colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
+ if (!colossus->AI()->GetData(DATA_INTRO_DONE))
+ colossus->AI()->SetData(DATA_INTRO_DONE, true);
+ DoZoneInCombat(colossus);
+ me->DespawnOrUnsummon();
}
}
+ }
+
+ void AttackStart(Unit* attacker) override
+ {
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
+ return;
- void UpdateAI(uint32 diff) override
+ // we do this checks to see if the creature is one of the creatures that sorround the boss
+ if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ Position homePosition = me->GetHomePosition();
- if (mojoWaveTimer <= diff)
- {
- DoCastVictim(SPELL_MOJO_WAVE);
- mojoWaveTimer = 15*IN_MILLISECONDS;
- } else mojoWaveTimer -= diff;
+ float distance = homePosition.GetExactDist(&colossus->GetHomePosition());
- if (mojoPuddleTimer <= diff)
+ if (distance < 12.0f)
{
- DoCastVictim(SPELL_MOJO_PUDDLE);
- mojoPuddleTimer = 18*IN_MILLISECONDS;
- } else mojoPuddleTimer -= diff;
+ MoveMojos(colossus);
+ me->SetReactState(REACT_PASSIVE);
+ }
+ else
+ ScriptedAI::AttackStart(attacker);
+ }
+ }
+ void UpdateAI(uint32 diff) override
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ _scheduler.Update(diff, [this]
+ {
DoMeleeAttackIfReady();
- }
+ });
+ }
- private:
- InstanceScript* instance;
- uint32 mojoWaveTimer;
- uint32 mojoPuddleTimer;
- };
+private:
+ InstanceScript* instance;
+ TaskScheduler _scheduler;
};
void AddSC_boss_drakkari_colossus()
{
- new boss_drakkari_colossus();
- new boss_drakkari_elemental();
- new npc_living_mojo();
+ RegisterCreatureAIWithFactory(boss_drakkari_colossus, GetGundrakAI);
+ RegisterCreatureAIWithFactory(boss_drakkari_elemental, GetGundrakAI);
+ RegisterCreatureAIWithFactory(npc_living_mojo, GetGundrakAI);
}