aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp500
1 files changed, 324 insertions, 176 deletions
diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
index 7458e86592e..193f8c6cb4c 100644
--- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
+++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
@@ -25,213 +25,336 @@
enum Spells
{
SPELL_EMERGE = 54850,
- SPELL_MIGHTY_BLOW = 54719,
+ SPELL_ELEMENTAL_SPAWN_EFEFCT = 54888,
+ SPELL_MOJO_VOLLEY = 54849,
+ SPELL_SURGE_VISUAL = 54827,
SPELL_MERGE = 54878,
+ SPELL_MIGHTY_BLOW = 54719,
SPELL_SURGE = 54801,
SPELL_FREEZE_ANIM = 16245,
SPELL_MOJO_PUDDLE = 55627,
- H_SPELL_MOJO_PUDDLE = 58994,
SPELL_MOJO_WAVE = 55626,
- H_SPELL_MOJO_WAVE = 58993
};
-class boss_drakkari_colossus : public CreatureScript
+enum ColossusEvents
{
-public:
- boss_drakkari_colossus() : CreatureScript("boss_drakkari_colossus") { }
+ EVENT_MIGHTY_BLOW = 1,
+};
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new boss_drakkari_colossusAI (pCreature);
- }
+enum ColossusActions
+{
+ ACTION_SUMMON_ELEMENTAL = 1,
+ ACTION_FREEZE_COLOSSUS = 2,
+ ACTION_UNFREEZE_COLOSSUS = 3,
+};
- struct boss_drakkari_colossusAI : public ScriptedAI
- {
- boss_drakkari_colossusAI(Creature* pCreature) : ScriptedAI(pCreature)
- {
- pInstance = pCreature->GetInstanceScript();
- }
+enum ColossusPhases
+{
+ COLOSSUS_PHASE_NORMAL = 1,
+ COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON = 2,
+ COLOSSUS_PHASE_SECOND_ELEMENTAL_SUMMON = 3
+};
- InstanceScript* pInstance;
+enum ColossusData
+{
+ DATA_COLOSSUS_PHASE = 1,
+ DATA_INTRO_DONE = 2
+};
- bool bHealth;
- bool bHealth1;
+enum ElementalActions
+{
+ ACTION_RETURN_TO_COLOSSUS = 1
+};
- uint32 MightyBlowTimer;
+enum ElementalEvents
+{
+ EVENT_SURGE = 1
+};
- void Reset()
- {
- if (pInstance)
- pInstance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, NOT_STARTED);
- if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->ClearUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
- me->SetReactState(REACT_PASSIVE);
- MightyBlowTimer = 10*IN_MILLISECONDS;
- bHealth = false;
- bHealth1 = false;
- }
+class boss_drakkari_colossus : public CreatureScript
+{
+ public:
+ boss_drakkari_colossus() : CreatureScript("boss_drakkari_colossus") { }
- void EnterCombat(Unit* /*who*/)
+ struct boss_drakkari_colossusAI : public BossAI
{
- if (pInstance)
- pInstance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, IN_PROGRESS);
- }
+ boss_drakkari_colossusAI(Creature* creature) : BossAI(creature, DATA_DRAKKARI_COLOSSUS_EVENT)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ introDone = false;
+ }
- void CreatureState(Creature* pWho, bool bRestore = false)
- {
- if (!pWho)
- return;
+ void InitializeAI()
+ {
+ if (!me->isDead())
+ Reset();
+ }
- if (bRestore)
+ void Reset()
{
- pWho->ClearUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
- pWho->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- if (pWho == me)
+ if (GetData(DATA_INTRO_DONE))
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_OOC_NOT_ATTACKABLE);
me->RemoveAura(SPELL_FREEZE_ANIM);
- }else
+ }
+
+ events.Reset();
+ events.ScheduleEvent(EVENT_MIGHTY_BLOW, urand(10000,30000));
+
+ phase = COLOSSUS_PHASE_NORMAL;
+
+ instance->SetBossState(DATA_DRAKKARI_COLOSSUS_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
{
- pWho->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- pWho->AddUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
- if (pWho == me)
- DoCast(me,SPELL_FREEZE_ANIM);
+ instance->SetBossState(DATA_DRAKKARI_COLOSSUS_EVENT, IN_PROGRESS);
+
+ me->RemoveAura(SPELL_FREEZE_ANIM);
}
- }
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void JustDied(Unit* /*killer*/)
+ {
+ instance->SetBossState(DATA_DRAKKARI_COLOSSUS_EVENT, DONE);
+ }
- if (!bHealth && HealthBelowPct(50) && !HealthBelowPct(5))
+ void JustReachedHome()
{
- CreatureState(me, false);
- DoCast(me,SPELL_FREEZE_ANIM);
- DoCast(me,SPELL_EMERGE);
- bHealth = true;
+ instance->SetBossState(DATA_DRAKKARI_COLOSSUS_EVENT, FAIL);
}
- if (!bHealth1 && HealthBelowPct(5))
+ void DoAction(const int32 action)
{
- DoCast(me,SPELL_EMERGE);
- CreatureState(me, false);
- bHealth1 = true;
- me->RemoveAllAuras();
+ switch (action)
+ {
+ case ACTION_SUMMON_ELEMENTAL:
+ DoCast(SPELL_EMERGE);
+ break;
+ case ACTION_FREEZE_COLOSSUS:
+ me->GetMotionMaster()->MoveIdle();
+
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ DoCast(me,SPELL_FREEZE_ANIM);
+ break;
+ case ACTION_UNFREEZE_COLOSSUS:
+
+ if (me->GetReactState() == REACT_AGGRESSIVE)
+ return;
+
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->RemoveAura(SPELL_FREEZE_ANIM);
+
+ me->SetInCombatWithZone();
+
+ if (me->getVictim())
+ me->GetMotionMaster()->MoveChase(me->getVictim(), 0,0);
+
+ break;
+ }
}
- if (MightyBlowTimer <= diff)
+ void DamageTaken(Unit* /*attacker*/, uint32& damage)
{
- DoCast(me->getVictim(), SPELL_MIGHTY_BLOW, true);
- MightyBlowTimer = 10*IN_MILLISECONDS;
- } else MightyBlowTimer -= diff;
+ if (me->HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_OOC_NOT_ATTACKABLE))
+ damage = 0;
- if (!me->HasUnitState(UNIT_STAT_STUNNED))
- DoMeleeAttackIfReady();
- }
+ 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 JustDied(Unit* /*killer*/)
- {
- if (pInstance)
- pInstance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, DONE);
- }
+ uint32 GetData(uint32 data)
+ {
+ if (data == DATA_COLOSSUS_PHASE)
+ return phase;
+ else if (data == DATA_INTRO_DONE)
+ return introDone;
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ if (type == DATA_INTRO_DONE)
+ introDone = data;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
- void JustSummoned(Creature* pSummon)
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_MIGHTY_BLOW:
+ DoCast(me->getVictim(),SPELL_MIGHTY_BLOW);
+ events.ScheduleEvent(EVENT_MIGHTY_BLOW, urand(5000,15000));
+ break;
+ }
+ }
+
+ if (me->GetReactState() == REACT_AGGRESSIVE)
+ DoMeleeAttackIfReady();
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ summon->SetInCombatWithZone();
+
+ if (phase == COLOSSUS_PHASE_SECOND_ELEMENTAL_SUMMON)
+ summon->SetHealth(summon->GetMaxHealth() / 2);
+ }
+
+ private:
+ uint8 phase;
+ bool introDone;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
{
- if (HealthBelowPct(5))
- pSummon->DealDamage(pSummon, uint32(pSummon->GetHealth() * 0.5), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- pSummon->AI()->AttackStart(me->getVictim());
+ return new boss_drakkari_colossusAI(creature);
}
- };
-
};
class boss_drakkari_elemental : public CreatureScript
{
-public:
- boss_drakkari_elemental() : CreatureScript("boss_drakkari_elemental") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new boss_drakkari_elementalAI (pCreature);
- }
+ public:
+ boss_drakkari_elemental() : CreatureScript("boss_drakkari_elemental") { }
- struct boss_drakkari_elementalAI : public ScriptedAI
- {
- boss_drakkari_elementalAI(Creature* pCreature) : ScriptedAI(pCreature)
+ struct boss_drakkari_elementalAI : public ScriptedAI
{
- pInstance = pCreature->GetInstanceScript();
- }
+ boss_drakkari_elementalAI(Creature* creature) : ScriptedAI(creature)
+ {
+ DoCast(me,SPELL_ELEMENTAL_SPAWN_EFEFCT);
- InstanceScript* pInstance;
+ instance = creature->GetInstanceScript();
+ }
- uint32 uiSurgeTimer;
+ void Reset()
+ {
+ events.Reset();
+ events.ScheduleEvent(EVENT_SURGE,urand(5000,15000));
- bool bGoToColossus;
+ me->AddAura(SPELL_MOJO_VOLLEY,me);
+ }
- void Reset()
- {
- if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
- CAST_AI(boss_drakkari_colossus::boss_drakkari_colossusAI, pColossus->AI())->CreatureState(me, true);
- uiSurgeTimer = 7*IN_MILLISECONDS;
- bGoToColossus = false;
- }
+ void JustDied(Unit* killer)
+ {
+ if (killer == me)
+ return;
- void EnterEvadeMode()
- {
- me->RemoveFromWorld();
- }
+ if (instance)
+ {
+ if (Creature* colossus = Unit::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS)))
+ killer->Kill(colossus);
+ }
+ }
- void MovementInform(uint32 uiType, uint32 /*uiId*/)
- {
- if (uiType != POINT_MOTION_TYPE)
- return;
- if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ void UpdateAI(const uint32 diff)
{
- CAST_AI(boss_drakkari_colossus::boss_drakkari_colossusAI, pColossus->AI())->CreatureState(pColossus, true);
- CAST_AI(boss_drakkari_colossus::boss_drakkari_colossusAI, pColossus->AI())->bHealth1 = false;
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SURGE:
+ DoCast(SPELL_SURGE_VISUAL);
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
+ DoCast(target,SPELL_SURGE);
+ events.ScheduleEvent(EVENT_SURGE,urand(5000,15000));
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
}
- me->RemoveFromWorld();
- }
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void DoAction(const int32 action)
+ {
+ switch (action)
+ {
+ case ACTION_RETURN_TO_COLOSSUS:
+ DoCast(SPELL_SURGE_VISUAL);
+ if (instance)
+ {
+ if (Creature* colossus = Unit::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS)))
+ DoCast(colossus,SPELL_MERGE);
+ }
+ break;
+ }
+ }
- if (!bGoToColossus && HealthBelowPct(50))
+ void DamageTaken(Unit* /*attacker*/, uint32& damage)
{
- if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ if (HealthBelowPct(50) && instance)
{
- if (!CAST_AI(boss_drakkari_colossus::boss_drakkari_colossusAI,pColossus->AI())->HealthBelowPct(6))
+ if (Creature* colossus = Unit::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS)))
{
- me->InterruptNonMeleeSpells(true);
- DoCast(pColossus, SPELL_MERGE);
- bGoToColossus = true;
+ if (colossus->AI()->GetData(DATA_COLOSSUS_PHASE) == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON)
+ {
+ DoAction(ACTION_RETURN_TO_COLOSSUS);
+ damage = 0;
+ }
}
}
}
- if (uiSurgeTimer <= diff)
+ void EnterEvadeMode()
{
- DoCast(me->getVictim(), SPELL_SURGE);
- uiSurgeTimer = 7*IN_MILLISECONDS;
- } else uiSurgeTimer -= diff;
+ me->DespawnOrUnsummon();
+ }
- DoMeleeAttackIfReady();
- }
+ void SpellHitTarget(Unit* target, SpellEntry const* spell)
+ {
+ if (spell->Id == SPELL_MERGE)
+ {
+ if (Creature* colossus = target->ToCreature())
+ {
+ colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
- void JustDied(Unit* /*killer*/)
+ me->DespawnOrUnsummon();
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ InstanceScript* instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
{
- if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
- pColossus->Kill(pColossus);
+ return new boss_drakkari_elementalAI(creature);
}
- };
-
};
+
class npc_living_mojo : public CreatureScript
{
public:
@@ -244,51 +367,73 @@ public:
struct npc_living_mojoAI : public ScriptedAI
{
- npc_living_mojoAI(Creature* pCreature) : ScriptedAI(pCreature)
+ npc_living_mojoAI(Creature* creature) : ScriptedAI(creature)
{
- pInstance = pCreature->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
- InstanceScript* pInstance;
-
- uint32 uiMojoWaveTimer;
- uint32 uiMojoPuddleTimer;
-
void Reset()
{
- uiMojoWaveTimer = 2*IN_MILLISECONDS;
- uiMojoPuddleTimer = 7*IN_MILLISECONDS;
+ mojoWaveTimer = 2*IN_MILLISECONDS;
+ mojoPuddleTimer = 7*IN_MILLISECONDS;
+ }
+
+ void MoveMojos(Creature* boss)
+ {
+ 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)
+ {
+ if (Creature* mojo = *itr)
+ mojo->GetMotionMaster()->MovePoint(1,boss->GetHomePosition().GetPositionX(),boss->GetHomePosition().GetPositionY(),boss->GetHomePosition().GetPositionZ());
+ }
+ }
}
- void EnterCombat(Unit* /*who*/)
+ void MovementInform(uint32 type, uint32 id)
{
+ if (type != POINT_MOTION_TYPE)
+ return;
- //Check if the npc is near of Drakkari Colossus.
- if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ if (id == 1)
{
- if (pColossus->isAlive() && me->IsInRange3d(pColossus->GetHomePosition().GetPositionX(),pColossus->GetHomePosition().GetPositionY(),pColossus->GetHomePosition().GetPositionZ(),0.0f,17.0f))
- me->SetReactState(REACT_PASSIVE);
- else
- me->SetReactState(REACT_AGGRESSIVE);
+ if (Creature* colossus = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ {
+ colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
+ if (!colossus->AI()->GetData(DATA_INTRO_DONE))
+ colossus->AI()->SetData(DATA_INTRO_DONE,true);
+ colossus->SetInCombatWithZone();
+ me->DespawnOrUnsummon();
+ }
}
}
- void DamageTaken(Unit* pDone_by, uint32& /*uiDamage*/)
+
+ void AttackStart(Unit* attacker)
{
- if (me->HasReactState(REACT_PASSIVE))
+ 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 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
{
- if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ Position homePosition;
+ me->GetHomePosition().GetPosition(&homePosition);
+
+ Position colossusHomePosition;
+ colossus->GetHomePosition().GetPosition(&colossusHomePosition);
+
+ float distance = homePosition.GetExactDist(colossusHomePosition.GetPositionX(),colossusHomePosition.GetPositionY(),colossusHomePosition.GetPositionZ());
+
+ if (distance < 12.0f)
{
- if (pColossus->isAlive() && !pColossus->isInCombat())
- {
- pColossus->RemoveAura(SPELL_FREEZE_ANIM);
- pColossus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
- pColossus->SetReactState(REACT_AGGRESSIVE);
- if (pDone_by && pDone_by->isAlive())
- pColossus->AI()->AttackStart(pDone_by);
- EnterEvadeMode();
- }
+ MoveMojos(colossus);
+ me->SetReactState(REACT_PASSIVE);
}
+ else
+ ScriptedAI::AttackStart(attacker);
}
}
@@ -298,22 +443,25 @@ public:
if (!UpdateVictim())
return;
- if (uiMojoWaveTimer <= diff)
+ if (mojoWaveTimer <= diff)
{
DoCast(me->getVictim(), SPELL_MOJO_WAVE);
- uiMojoWaveTimer = 15*IN_MILLISECONDS;
- } else uiMojoWaveTimer -= diff;
+ mojoWaveTimer = 15*IN_MILLISECONDS;
+ } else mojoWaveTimer -= diff;
- if (uiMojoPuddleTimer <= diff)
+ if (mojoPuddleTimer <= diff)
{
DoCast(me->getVictim(), SPELL_MOJO_PUDDLE);
- uiMojoPuddleTimer = 18*IN_MILLISECONDS;
- } else uiMojoPuddleTimer -= diff;
+ mojoPuddleTimer = 18*IN_MILLISECONDS;
+ } else mojoPuddleTimer -= diff;
DoMeleeAttackIfReady();
}
+ private:
+ InstanceScript* instance;
+ uint32 mojoWaveTimer;
+ uint32 mojoPuddleTimer;
};
-
};