diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp | 429 |
1 files changed, 203 insertions, 226 deletions
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp index 6b61f95e446..ccec34c0cad 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp @@ -64,326 +64,303 @@ enum Misc ## Boss Ionar ######*/ -class boss_ionar : public CreatureScript +struct boss_ionar : public ScriptedAI { -public: - boss_ionar() : CreatureScript("boss_ionar") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_ionar(Creature* creature) : ScriptedAI(creature), lSparkList(creature) { - return GetHallsOfLightningAI<boss_ionarAI>(creature); + Initialize(); + instance = creature->GetInstanceScript(); } - struct boss_ionarAI : public ScriptedAI + void Initialize() { - boss_ionarAI(Creature* creature) : ScriptedAI(creature), lSparkList(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } + bIsSplitPhase = true; + bHasDispersed = false; - void Initialize() - { - bIsSplitPhase = true; - bHasDispersed = false; + uiSplitTimer = 25 * IN_MILLISECONDS; - uiSplitTimer = 25 * IN_MILLISECONDS; + uiStaticOverloadTimer = urand(5 * IN_MILLISECONDS, 6 * IN_MILLISECONDS); + uiBallLightningTimer = urand(10 * IN_MILLISECONDS, 11 * IN_MILLISECONDS); - uiStaticOverloadTimer = urand(5 * IN_MILLISECONDS, 6 * IN_MILLISECONDS); - uiBallLightningTimer = urand(10 * IN_MILLISECONDS, 11 * IN_MILLISECONDS); - - uiDisperseHealth = 45 + urand(0, 10); - } + uiDisperseHealth = 45 + urand(0, 10); + } - InstanceScript* instance; + InstanceScript* instance; - SummonList lSparkList; + SummonList lSparkList; - bool bIsSplitPhase; - bool bHasDispersed; + bool bIsSplitPhase; + bool bHasDispersed; - uint32 uiSplitTimer; + uint32 uiSplitTimer; - uint32 uiStaticOverloadTimer; - uint32 uiBallLightningTimer; + uint32 uiStaticOverloadTimer; + uint32 uiBallLightningTimer; - uint32 uiDisperseHealth; + uint32 uiDisperseHealth; - void Reset() override - { - lSparkList.DespawnAll(); + void Reset() override + { + lSparkList.DespawnAll(); - Initialize(); + Initialize(); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - me->SetControlled(false, UNIT_STATE_ROOT); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetControlled(false, UNIT_STATE_ROOT); - if (!me->IsVisible()) - me->SetVisible(true); + if (!me->IsVisible()) + me->SetVisible(true); - instance->SetBossState(DATA_IONAR, NOT_STARTED); - } + instance->SetBossState(DATA_IONAR, NOT_STARTED); + } - void JustEngagedWith(Unit* /*who*/) override - { - Talk(SAY_AGGRO); + void JustEngagedWith(Unit* /*who*/) override + { + Talk(SAY_AGGRO); - instance->SetBossState(DATA_IONAR, IN_PROGRESS); - } + instance->SetBossState(DATA_IONAR, IN_PROGRESS); + } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); - lSparkList.DespawnAll(); + lSparkList.DespawnAll(); - instance->SetBossState(DATA_IONAR, DONE); - } + instance->SetBossState(DATA_IONAR, DONE); + } - void KilledUnit(Unit* who) override - { - if (who->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } + void KilledUnit(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override + void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_DISPERSE) { - if (spellInfo->Id == SPELL_DISPERSE) - { - for (uint8 i = 0; i < DATA_MAX_SPARKS; ++i) - me->CastSpell(me, SPELL_SUMMON_SPARK, true); + for (uint8 i = 0; i < DATA_MAX_SPARKS; ++i) + me->CastSpell(me, SPELL_SUMMON_SPARK, true); - me->AttackStop(); - me->SetVisible(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - me->SetControlled(true, UNIT_STATE_ROOT); + me->AttackStop(); + me->SetVisible(false); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetControlled(true, UNIT_STATE_ROOT); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveIdle(); - } + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveIdle(); } + } - //make sparks come back - void CallBackSparks() - { - //should never be empty here, but check - if (lSparkList.empty()) - return; + //make sparks come back + void CallBackSparks() + { + //should never be empty here, but check + if (lSparkList.empty()) + return; - Position pos = me->GetPosition(); + Position pos = me->GetPosition(); - for (ObjectGuid guid : lSparkList) + for (ObjectGuid guid : lSparkList) + { + if (Creature* pSpark = ObjectAccessor::GetCreature(*me, guid)) { - if (Creature* pSpark = ObjectAccessor::GetCreature(*me, guid)) + if (pSpark->IsAlive()) { - if (pSpark->IsAlive()) - { - pSpark->SetSpeedRate(MOVE_RUN, 2.0f); - pSpark->GetMotionMaster()->Clear(); - pSpark->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); - } - else - pSpark->DespawnOrUnsummon(); + pSpark->SetSpeedRate(MOVE_RUN, 2.0f); + pSpark->GetMotionMaster()->Clear(); + pSpark->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } + else + pSpark->DespawnOrUnsummon(); } } + } - void DamageTaken(Unit* /*pDoneBy*/, uint32 &uiDamage) override - { - if (!me->IsVisible()) - uiDamage = 0; - } + void DamageTaken(Unit* /*pDoneBy*/, uint32 &uiDamage) override + { + if (!me->IsVisible()) + uiDamage = 0; + } - void JustSummoned(Creature* summoned) override + void JustSummoned(Creature* summoned) override + { + if (summoned->GetEntry() == NPC_SPARK_OF_IONAR) { - if (summoned->GetEntry() == NPC_SPARK_OF_IONAR) - { - lSparkList.Summon(summoned); + lSparkList.Summon(summoned); - summoned->CastSpell(summoned, SPELL_SPARK_VISUAL_TRIGGER, true); + summoned->CastSpell(summoned, SPELL_SPARK_VISUAL_TRIGGER, true); - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - { - summoned->SetInCombatWith(target); - summoned->GetMotionMaster()->Clear(); - summoned->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f); - } + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + { + summoned->SetInCombatWith(target); + summoned->GetMotionMaster()->Clear(); + summoned->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f); } } + } - void SummonedCreatureDespawn(Creature* summoned) override - { - if (summoned->GetEntry() == NPC_SPARK_OF_IONAR) - lSparkList.Despawn(summoned); - } + void SummonedCreatureDespawn(Creature* summoned) override + { + if (summoned->GetEntry() == NPC_SPARK_OF_IONAR) + lSparkList.Despawn(summoned); + } - void UpdateAI(uint32 uiDiff) override - { - //Return since we have no target - if (!UpdateVictim()) - return; + void UpdateAI(uint32 uiDiff) override + { + //Return since we have no target + if (!UpdateVictim()) + return; - // Splitted - if (!me->IsVisible()) + // Splitted + if (!me->IsVisible()) + { + if (uiSplitTimer <= uiDiff) { - if (uiSplitTimer <= uiDiff) + uiSplitTimer = 2500; + + // Return sparks to where Ionar splitted + if (bIsSplitPhase) { - uiSplitTimer = 2500; - - // Return sparks to where Ionar splitted - if (bIsSplitPhase) - { - CallBackSparks(); - bIsSplitPhase = false; - } - // Lightning effect and restore Ionar - else if (lSparkList.empty()) - { - me->SetVisible(true); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - me->SetControlled(false, UNIT_STATE_ROOT); - - DoCast(me, SPELL_SPARK_DESPAWN, false); - - uiSplitTimer = 25*IN_MILLISECONDS; - bIsSplitPhase = true; - - if (me->GetVictim()) - me->GetMotionMaster()->MoveChase(me->GetVictim()); - } + CallBackSparks(); + bIsSplitPhase = false; } - else - uiSplitTimer -= uiDiff; + // Lightning effect and restore Ionar + else if (lSparkList.empty()) + { + me->SetVisible(true); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetControlled(false, UNIT_STATE_ROOT); - return; - } + DoCast(me, SPELL_SPARK_DESPAWN, false); - if (uiStaticOverloadTimer <= uiDiff) - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - DoCast(target, SPELL_STATIC_OVERLOAD); + uiSplitTimer = 25*IN_MILLISECONDS; + bIsSplitPhase = true; - uiStaticOverloadTimer = urand(5*IN_MILLISECONDS, 6*IN_MILLISECONDS); + if (me->GetVictim()) + me->GetMotionMaster()->MoveChase(me->GetVictim()); + } } else - uiStaticOverloadTimer -= uiDiff; + uiSplitTimer -= uiDiff; - if (uiBallLightningTimer <= uiDiff) - { - DoCastVictim(SPELL_BALL_LIGHTNING); - uiBallLightningTimer = urand(10*IN_MILLISECONDS, 11*IN_MILLISECONDS); - } - else - uiBallLightningTimer -= uiDiff; + return; + } - // Health check - if (!bHasDispersed && HealthBelowPct(uiDisperseHealth)) - { - bHasDispersed = true; + if (uiStaticOverloadTimer <= uiDiff) + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + DoCast(target, SPELL_STATIC_OVERLOAD); - Talk(SAY_SPLIT); + uiStaticOverloadTimer = urand(5*IN_MILLISECONDS, 6*IN_MILLISECONDS); + } + else + uiStaticOverloadTimer -= uiDiff; - if (me->IsNonMeleeSpellCast(false)) - me->InterruptNonMeleeSpells(false); + if (uiBallLightningTimer <= uiDiff) + { + DoCastVictim(SPELL_BALL_LIGHTNING); + uiBallLightningTimer = urand(10*IN_MILLISECONDS, 11*IN_MILLISECONDS); + } + else + uiBallLightningTimer -= uiDiff; - DoCast(me, SPELL_DISPERSE, false); - } + // Health check + if (!bHasDispersed && HealthBelowPct(uiDisperseHealth)) + { + bHasDispersed = true; + + Talk(SAY_SPLIT); + + if (me->IsNonMeleeSpellCast(false)) + me->InterruptNonMeleeSpells(false); - DoMeleeAttackIfReady(); + DoCast(me, SPELL_DISPERSE, false); } - }; + DoMeleeAttackIfReady(); + } }; /*###### ## npc_spark_of_ionar ######*/ -class npc_spark_of_ionar : public CreatureScript +struct npc_spark_of_ionar : public ScriptedAI { -public: - npc_spark_of_ionar() : CreatureScript("npc_spark_of_ionar") { } + npc_spark_of_ionar(Creature* creature) : ScriptedAI(creature) + { + Initialize(); + instance = creature->GetInstanceScript(); + } - struct npc_spark_of_ionarAI : public ScriptedAI + void Initialize() { - npc_spark_of_ionarAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } + uiCheckTimer = 2 * IN_MILLISECONDS; + } - void Initialize() - { - uiCheckTimer = 2 * IN_MILLISECONDS; - } + InstanceScript* instance; - InstanceScript* instance; + uint32 uiCheckTimer; - uint32 uiCheckTimer; + void Reset() override + { + Initialize(); + me->SetReactState(REACT_PASSIVE); + } - void Reset() override - { - Initialize(); - me->SetReactState(REACT_PASSIVE); - } + void MovementInform(uint32 uiType, uint32 uiPointId) override + { + if (uiType != POINT_MOTION_TYPE || !instance) + return; - void MovementInform(uint32 uiType, uint32 uiPointId) override - { - if (uiType != POINT_MOTION_TYPE || !instance) - return; + if (uiPointId == DATA_POINT_CALLBACK) + me->DespawnOrUnsummon(); + } - if (uiPointId == DATA_POINT_CALLBACK) - me->DespawnOrUnsummon(); - } + void DamageTaken(Unit* /*pDoneBy*/, uint32 &uiDamage) override + { + uiDamage = 0; + } - void DamageTaken(Unit* /*pDoneBy*/, uint32 &uiDamage) override + void UpdateAI(uint32 uiDiff) override + { + // Despawn if the encounter is not running + if (instance->GetBossState(DATA_IONAR) != IN_PROGRESS) { - uiDamage = 0; + me->DespawnOrUnsummon(); + return; } - void UpdateAI(uint32 uiDiff) override + // Prevent them to follow players through the whole instance + if (uiCheckTimer <= uiDiff) { - // Despawn if the encounter is not running - if (instance->GetBossState(DATA_IONAR) != IN_PROGRESS) - { - me->DespawnOrUnsummon(); - return; - } - - // Prevent them to follow players through the whole instance - if (uiCheckTimer <= uiDiff) + Creature* ionar = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_IONAR)); + if (ionar && ionar->IsAlive()) { - Creature* ionar = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_IONAR)); - if (ionar && ionar->IsAlive()) + if (me->GetDistance(ionar) > DATA_MAX_SPARK_DISTANCE) { - if (me->GetDistance(ionar) > DATA_MAX_SPARK_DISTANCE) - { - Position pos = ionar->GetPosition(); - - me->SetSpeedRate(MOVE_RUN, 2.0f); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); - } + Position pos = ionar->GetPosition(); + + me->SetSpeedRate(MOVE_RUN, 2.0f); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } - else - me->DespawnOrUnsummon(); - uiCheckTimer = 2*IN_MILLISECONDS; } else - uiCheckTimer -= uiDiff; - - // No melee attack at all! + me->DespawnOrUnsummon(); + uiCheckTimer = 2*IN_MILLISECONDS; } - }; + else + uiCheckTimer -= uiDiff; - CreatureAI* GetAI(Creature* creature) const override - { - return GetHallsOfLightningAI<npc_spark_of_ionarAI>(creature); + // No melee attack at all! } }; void AddSC_boss_ionar() { - new boss_ionar(); - new npc_spark_of_ionar(); + RegisterHallsOfLightningCreatureAI(boss_ionar); + RegisterHallsOfLightningCreatureAI(npc_spark_of_ionar); } |