void SetAfterTeleport() { me->InterruptNonMeleeSpells(false); DoStopAttack(); ResetThreatList(); DoCast(me, SPELL_TWIN_TELEPORT_VISUAL); me->AddUnitState(UNIT_STATE_STUNNED); AfterTeleport = true; AfterTeleportTimer = 2000; tspellcast = false; }
void UpdateAI(uint32 diff) override { //Return since we have no target if (!UpdateVictim()) return; //Fear_Timer if (Fear_Timer <= diff) { DoCastVictim(SPELL_FEAR); ResetThreatList(); Fear_Timer = 20000; } else Fear_Timer -= diff; //Casting Heal to other twins or herself. if (Heal_Timer <= diff) { switch (urand(0, 2)) { case 0: if (Creature* kri = instance->GetCreature(DATA_KRI)) DoCast(kri, SPELL_HEAL); break; case 1: if (Creature* vem = instance->GetCreature(DATA_VEM)) DoCast(vem, SPELL_HEAL); break; case 2: DoCast(me, SPELL_HEAL); break; } Heal_Timer = 15000 + rand32() % 15000; } else Heal_Timer -= diff; //Checking if Vem is dead. If yes we will enrage. if (Check_Timer <= diff) { if (!VemDead) { if (instance->GetData(DATA_VEMISDEAD)) { DoCast(me, SPELL_ENRAGE); VemDead = true; } } Check_Timer = 2000; } else Check_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_ARCANE_EXPLOSION: DoCastAOE(SPELL_ARCANE_EXPLOSION, true); events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(8000, 18000)); break; case EVENT_FULLFILMENT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 45.0f, true)) DoCast(target, SPELL_TRUE_FULFILLMENT); events.ScheduleEvent(EVENT_FULLFILMENT, urand(20000, 30000)); break; case EVENT_BLINK: DoCast(me, BlinkSpells[urand(0, 2)]); ResetThreatList(); me->SetVisible(true); events.ScheduleEvent(EVENT_BLINK, urand(10000, 30000)); break; case EVENT_EARTH_SHOCK: DoCastVictim(SPELL_EARTH_SHOCK); events.ScheduleEvent(EVENT_EARTH_SHOCK, 2000); break; } } if (!me->IsSummon() && me->GetHealthPct() < _hpct) { DoCast(me, SPELL_SUMMON_IMAGES); Talk(SAY_SPLIT); _hpct -= 25.0f; me->SetVisible(false); events.RescheduleEvent(EVENT_BLINK, 2000); } if (me->IsWithinMeleeRange(me->GetVictim())) { events.RescheduleEvent(EVENT_EARTH_SHOCK, 2000); DoMeleeAttackIfReady(); } }
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override { if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(50)) { me->RemoveAurasDueToSpell(SPELL_BAT_FORM); me->SetCanFly(false); ResetThreatList(); events.SetPhase(PHASE_TWO); events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 6s, 0, PHASE_TWO); events.ScheduleEvent(EVENT_MIND_FLAY, 11s, 0, PHASE_TWO); events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, 26s, 0, PHASE_TWO); events.ScheduleEvent(EVENT_GREATER_HEAL, 50s, 0, PHASE_TWO); events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, 10s, 0, PHASE_TWO); return; } }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_PARTING_SORROW: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) DoCast(target, SPELL_PARTING_SORROW); events.ScheduleEvent(EVENT_PARTING_SORROW, 30s, 40s); break; case EVENT_STORM_OF_GRIEF: DoCastVictim(SPELL_STORM_OF_GRIEF, true); events.ScheduleEvent(EVENT_STORM_OF_GRIEF, 15s, 20s); break; case EVENT_SHOCK_OF_SORROW: ResetThreatList(); Talk(SAY_STUN); DoCastAOE(SPELL_SHOCK_OF_SORROW); events.ScheduleEvent(EVENT_SHOCK_OF_SORROW, 20s, 30s); break; case EVENT_PILLAR_OF_WOE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) DoCast(target, SPELL_PILLAR_OF_WOE); else DoCastVictim(SPELL_PILLAR_OF_WOE); events.ScheduleEvent(EVENT_PILLAR_OF_WOE, 5s, 25s); break; default: break; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; } DoMeleeAttackIfReady(); }
void ChaseNewVictim() { if (_phase != PHASE_EGG) return; me->RemoveAurasDueToSpell(SPELL_FULL_SPEED); me->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED); events.ScheduleEvent(EVENT_GATHERING_SPEED, 9s); events.ScheduleEvent(EVENT_FULL_SPEED, 1min); if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { ResetThreatList(); AttackStart(victim); Talk(EMOTE_TARGET, victim); } }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; if (_phase == PHASE_GLOB && summons.empty()) { ResetThreatList(); me->NearTeleportTo(ViscidusCoord.GetPositionX(), ViscidusCoord.GetPositionY(), ViscidusCoord.GetPositionZ(), ViscidusCoord.GetOrientation()); _hitcounter = 0; _phase = PHASE_FROST; InitSpells(); me->SetVisible(true); } events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_POISONBOLT_VOLLEY: DoCast(me, SPELL_POISONBOLT_VOLLEY); events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, 10s, 15s); break; case EVENT_POISON_SHOCK: DoCast(me, SPELL_POISON_SHOCK); events.ScheduleEvent(EVENT_POISON_SHOCK, 7s, 12s); break; case EVENT_RESET_PHASE: _hitcounter = 0; _phase = PHASE_FROST; break; default: break; } } if (_phase != PHASE_GLOB) DoMeleeAttackIfReady(); }
void SelectNewTarget() { if (Creature* teron = _instance->GetCreature(DATA_TERON_GOREFIEND)) { Unit* target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true, true, -SPELL_SPIRITUAL_VENGEANCE); // He should target Vengeful Spirits only if has no other player available if (!target) target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0); if (target) { ResetThreatList(); AttackStart(target); AddThreat(target, 1000000.0f); targetGUID = target->GetGUID(); } } }
void UpdateAI(uint32 diff) override { if (!beam) { SummonBeams(); beam = true; } //Return since we have no target if (!UpdateVictim()) return; // corrupted form if (CorruptedForm) { //MarkOfCorruption_Timer if (MarkOfCorruption_Timer <= diff) { if (MarkOfCorruption_Count <= 5) { uint32 mark_spell = 0; switch (MarkOfCorruption_Count) { case 0: mark_spell = SPELL_MARK_OF_CORRUPTION1; break; case 1: mark_spell = SPELL_MARK_OF_CORRUPTION2; break; case 2: mark_spell = SPELL_MARK_OF_CORRUPTION3; break; case 3: mark_spell = SPELL_MARK_OF_CORRUPTION4; break; case 4: mark_spell = SPELL_MARK_OF_CORRUPTION5; break; case 5: mark_spell = SPELL_MARK_OF_CORRUPTION6; break; } DoCastVictim(mark_spell); if (MarkOfCorruption_Count < 5) ++MarkOfCorruption_Count; } MarkOfCorruption_Timer = 15000; } else MarkOfCorruption_Timer -= diff; //VileSludge_Timer if (VileSludge_Timer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_VILE_SLUDGE); VileSludge_Timer = 15000; } else VileSludge_Timer -= diff; //PosCheck_Timer if (PosCheck_Timer <= diff) { 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, 0); DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 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 { //MarkOfHydross_Timer if (MarkOfHydross_Timer <= diff) { 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; case 2: mark_spell = SPELL_MARK_OF_HYDROSS3; break; case 3: mark_spell = SPELL_MARK_OF_HYDROSS4; break; case 4: mark_spell = SPELL_MARK_OF_HYDROSS5; break; case 5: mark_spell = SPELL_MARK_OF_HYDROSS6; break; } DoCastVictim(mark_spell); if (MarkOfHydross_Count < 5) ++MarkOfHydross_Count; } MarkOfHydross_Timer = 15000; } else MarkOfHydross_Timer -= diff; //WaterTomb_Timer if (WaterTomb_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (target) DoCast(target, SPELL_WATER_TOMB); WaterTomb_Timer = 7000; } else WaterTomb_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, 0); DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 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); } PosCheck_Timer = 2500; } else PosCheck_Timer -=diff; } //EnrageTimer if (EnrageTimer <= diff) { DoCast(me, SPELL_ENRAGE); EnrageTimer = 60000; } else EnrageTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { if (_introState != 2) { if (!_introState) { me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); events.ScheduleEvent(EVENT_INTRO_1, 4000); events.ScheduleEvent(EVENT_INTRO_2, 23000); events.ScheduleEvent(EVENT_INTRO_3, 42000); events.ScheduleEvent(EVENT_INTRO_4, 43000); events.ScheduleEvent(EVENT_INTRO_5, 53000); _introState = 1; } events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_INTRO_1: Talk(SAY_ARRIVAL1_RAG); break; case EVENT_INTRO_2: Talk(SAY_ARRIVAL3_RAG); break; case EVENT_INTRO_3: me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H); break; case EVENT_INTRO_4: Talk(SAY_ARRIVAL5_RAG); if (Creature* executus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MAJORDOMO_EXECUTUS))) Unit::Kill(me, executus); break; case EVENT_INTRO_5: me->SetReactState(REACT_AGGRESSIVE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetImmuneToPC(false); _introState = 2; break; default: break; } } } else { if (_isBanished && ((_emergeTimer <= diff) || (instance->GetData(DATA_RAGNAROS_ADDS)) > 8)) { //Become unbanished again me->SetReactState(REACT_AGGRESSIVE); me->SetFaction(FACTION_MONSTER); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) AttackStart(target); instance->SetData(DATA_RAGNAROS_ADDS, 0); //DoCast(me, SPELL_RAGEMERGE); //"phase spells" didnt worked correctly so Ive commented them and wrote solution witch doesnt need core support _isBanished = false; } else if (_isBanished) { _emergeTimer -= diff; //Do nothing while banished return; } //Return since we have no target if (!UpdateVictim()) return; events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_ERUPTION: DoCastVictim(SPELL_ERRUPTION); events.ScheduleEvent(EVENT_ERUPTION, urand(20000, 45000)); break; case EVENT_WRATH_OF_RAGNAROS: DoCastVictim(SPELL_WRATH_OF_RAGNAROS); if (urand(0, 1)) Talk(SAY_WRATH); events.ScheduleEvent(EVENT_WRATH_OF_RAGNAROS, 25000); break; case EVENT_HAND_OF_RAGNAROS: DoCast(me, SPELL_HAND_OF_RAGNAROS); if (urand(0, 1)) Talk(SAY_HAND); events.ScheduleEvent(EVENT_HAND_OF_RAGNAROS, 20000); break; case EVENT_LAVA_BURST: DoCastVictim(SPELL_LAVA_BURST); events.ScheduleEvent(EVENT_LAVA_BURST, 10000); break; case EVENT_ELEMENTAL_FIRE: DoCastVictim(SPELL_ELEMENTAL_FIRE); events.ScheduleEvent(EVENT_ELEMENTAL_FIRE, urand(10000, 14000)); break; case EVENT_MAGMA_BLAST: if (!me->IsWithinMeleeRange(me->GetVictim())) { DoCastVictim(SPELL_MAGMA_BLAST); if (!_hasYelledMagmaBurst) { //Say our dialog Talk(SAY_MAGMABURST); _hasYelledMagmaBurst = true; } } events.ScheduleEvent(EVENT_MAGMA_BLAST, 2500); break; case EVENT_SUBMERGE: { if (!_isBanished) { //Creature spawning and ragnaros becomming unattackable //is not very well supported in the core //no it really isnt //so added normaly spawning and banish workaround and attack again after 90 secs. me->AttackStop(); ResetThreatList(); me->SetReactState(REACT_PASSIVE); me->InterruptNonMeleeSpells(false); //Root self //DoCast(me, 23973); me->SetFaction(FACTION_FRIENDLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE); instance->SetData(DATA_RAGNAROS_ADDS, 0); if (!_hasSubmergedOnce) { Talk(SAY_REINFORCEMENTS1); // summon 8 elementals for (uint8 i = 0; i < 8; ++i) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) if (Creature* summoned = me->SummonCreature(12143, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 900000)) summoned->AI()->AttackStart(target); _hasSubmergedOnce = true; _isBanished = true; //DoCast(me, SPELL_RAGSUBMERGE); _emergeTimer = 90000; } else { Talk(SAY_REINFORCEMENTS2); for (uint8 i = 0; i < 8; ++i) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) if (Creature* summoned = me->SummonCreature(12143, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 900000)) summoned->AI()->AttackStart(target); _isBanished = true; //DoCast(me, SPELL_RAGSUBMERGE); _emergeTimer = 90000; } } events.ScheduleEvent(EVENT_SUBMERGE, 180000); break; } default: break; } } DoMeleeAttackIfReady(); } }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_MORTALCLEAVE: DoCastVictim(SPELL_MORTALCLEAVE, true); events.ScheduleEvent(EVENT_MORTALCLEAVE, urand(15000, 20000), 0, PHASE_ONE); break; case EVENT_SILENCE: DoCastVictim(SPELL_SILENCE, true); events.ScheduleEvent(EVENT_SILENCE, urand(20000, 25000), 0, PHASE_ONE); break; case EVENT_RESURRECT_TIMER: //Thekal will transform to Tiger if he died and was not resurrected after 10 seconds. if (WasDead) { DoCast(me, SPELL_TIGER_FORM); // SPELL_AURA_TRANSFORM me->SetObjectScale(2.00f); me->SetStandState(UNIT_STAND_STATE_STAND); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); /* CreatureTemplate const* cinfo = me->GetCreatureTemplate(); me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40))); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40))); me->UpdateDamagePhysical(BASE_ATTACK); */ me->ApplyStatPctModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, DamageIncrease); // hack ResetThreatList(); events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); // Phase 2 events.ScheduleEvent(EVENT_FORCEPUNCH, 4000, 0, PHASE_TWO); // Phase 2 events.ScheduleEvent(EVENT_SPELL_CHARGE, 12000, 0, PHASE_TWO); // Phase 2 events.ScheduleEvent(EVENT_ENRAGE, 32000, 0, PHASE_TWO); // Phase 2 events.ScheduleEvent(EVENT_SUMMONTIGERS, 25000, 0, PHASE_TWO); // Phase 2 events.SetPhase(PHASE_TWO); } events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE); break; case EVENT_CHECK_TIMER: //Check_Timer for the death of LorKhan and Zath. if (!WasDead) { if (instance->GetBossState(DATA_LORKHAN) == SPECIAL) { //Resurrect LorKhan if (Unit* pLorKhan = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LORKHAN))) { pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pLorKhan->SetFaction(FACTION_MONSTER); pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pLorKhan->SetFullHealth(); instance->SetData(DATA_LORKHAN, DONE); } } if (instance->GetBossState(DATA_ZATH) == SPECIAL) { //Resurrect Zath if (Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_ZATH))) { pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pZath->SetFaction(FACTION_MONSTER); pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pZath->SetFullHealth(); instance->SetBossState(DATA_ZATH, DONE); } } } events.ScheduleEvent(EVENT_CHECK_TIMER, 5000, 0, PHASE_ONE); break; case EVENT_FRENZY: DoCast(me, SPELL_FRENZY); events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); break; case EVENT_FORCEPUNCH: DoCastVictim(SPELL_FORCEPUNCH, true); events.ScheduleEvent(EVENT_FORCEPUNCH, urand(16000, 21000), 0, PHASE_TWO); break; case EVENT_CHARGE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_CHARGE); ResetThreatList(); AttackStart(target); } events.ScheduleEvent(EVENT_CHARGE, urand(15000, 22000), 0, PHASE_TWO); break; case EVENT_ENRAGE: if (HealthBelowPct(11) && !Enraged) { DoCast(me, SPELL_ENRAGE); Enraged = true; } events.ScheduleEvent(EVENT_ENRAGE, 30000); break; case EVENT_SUMMONTIGERS: DoCastVictim(SPELL_SUMMONTIGERS, true); events.ScheduleEvent(EVENT_SUMMONTIGERS, urand(10000, 14000), 0, PHASE_TWO); break; default: break; } if (me->IsFullHealth() && WasDead) WasDead = false; if ((events.IsInPhase(PHASE_ONE)) && !WasDead && !HealthAbovePct(5)) { me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE); me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetStandState(UNIT_STAND_STATE_SLEEP); me->AttackStop(); instance->SetBossState(DATA_THEKAL, SPECIAL); WasDead = true; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); if (_phase == PHASE_AIR && me->GetHealthPct() < 70.0f) { _phase = PHASE_GROUND; SetCombatMovement(true); me->SetCanFly(false); if (me->GetVictim()) { Position VictimPos = me->EnsureVictim()->GetPosition(); me->GetMotionMaster()->MovePoint(POINT_GROUND, VictimPos); } ResetThreatList(); events.ScheduleEvent(EVENT_LASH, urand(5000, 8000)); events.ScheduleEvent(EVENT_TRASH, urand(3000, 6000)); events.CancelEvent(EVENT_POISON_STINGER); } else { DoMeleeAttackIfReady(); } if (!_enraged && me->GetHealthPct() < 20.0f) { DoCast(me, SPELL_FRENZY); Talk(EMOTE_FRENZY); _enraged = true; } while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_STINGER_SPRAY: DoCast(me, SPELL_STINGER_SPRAY); events.ScheduleEvent(EVENT_STINGER_SPRAY, urand(15000, 20000)); break; case EVENT_POISON_STINGER: DoCastVictim(SPELL_POISON_STINGER); events.ScheduleEvent(EVENT_POISON_STINGER, urand(2000, 3000)); break; case EVENT_PARALYZE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true)) { DoCast(target, SPELL_PARALYZE); instance->SetGuidData(DATA_PARALYZED, target->GetGUID()); uint8 Index = urand(0, 1); me->SummonCreature(NPC_LARVA, LarvaPos[Index], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); } events.ScheduleEvent(EVENT_PARALYZE, 15000); break; case EVENT_SWARMER_ATTACK: for (GuidList::iterator i = _swarmers.begin(); i != _swarmers.end(); ++i) if (Creature* swarmer = ObjectAccessor::GetCreature(*me, *i)) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) swarmer->AI()->AttackStart(target); _swarmers.clear(); events.ScheduleEvent(EVENT_SWARMER_ATTACK, 60000); break; case EVENT_SUMMON_SWARMER: { Position Pos = me->GetRandomPoint(SwarmerPos, 80.0f); me->SummonCreature(NPC_SWARMER, Pos); events.ScheduleEvent(EVENT_SUMMON_SWARMER, 5000); break; } case EVENT_TRASH: DoCastVictim(SPELL_TRASH); events.ScheduleEvent(EVENT_TRASH, urand(5000, 7000)); break; case EVENT_LASH: DoCastVictim(SPELL_LASH); events.ScheduleEvent(EVENT_LASH, urand(8000, 15000)); break; } } }