void UpdateAI(const uint32 diff) { if (!me->isInCombat()) { if (pInstance) { // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished. if ((pInstance->GetData(DATA_AZGALOREVENT) < DONE) && (me->IsVisible() || (me->getFaction() != 35))) { me->SetVisible(false); me->setFaction(35); } else if ((pInstance->GetData(DATA_AZGALOREVENT) >= DONE) && (!me->IsVisible() || (me->getFaction() == 35))) { me->setFaction(1720); me->SetVisible(true); } } if (DrainNordrassilTimer <= diff) { if (!IsChanneling) { Creature *temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000); if (temp) WorldTreeGUID = temp->GetGUID(); if (Unit *Nordrassil = Unit::GetUnit(*me, WorldTreeGUID)) { Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Nordrassil->SetDisplayId(11686); DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE); IsChanneling = true; } } if (Unit *Nordrassil = Unit::GetUnit(*me, WorldTreeGUID)) { Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true); DrainNordrassilTimer = 1000; } } else DrainNordrassilTimer -= diff; } if (!UpdateVictim()) return; if (me->HealthBelowPct(10) && !BelowTenPercent && !Enraged) BelowTenPercent = true; if (!Enraged) { if (EnrageTimer <= diff) { if (HealthAbovePct(10)) { me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); Enraged = true; DoScriptText(SAY_ENRAGE, me); } } else EnrageTimer -= diff; if (CheckDistanceTimer <= diff) { // To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000); if (Check) { Check->SetVisible(false); if (me->IsWithinDistInMap(Check, 75)) { me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); Enraged = true; DoScriptText(SAY_ENRAGE, me); } } CheckDistanceTimer = 5000; } else CheckDistanceTimer -= diff; } if (BelowTenPercent) { if (!HasProtected) { me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); //all members of raid must get this buff DoCast(me->getVictim(), SPELL_PROTECTION_OF_ELUNE); HasProtected = true; Enraged = true; } if (SummonWispTimer <= diff) { DoSpawnCreature(CREATURE_ANCIENT_WISP, float(rand()%40), float(rand()%40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); SummonWispTimer = 1500; ++WispCount; } else SummonWispTimer -= diff; if (WispCount >= 30) me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } if (Enraged) { if (HandOfDeathTimer <= diff) { DoCast(me->getVictim(), SPELL_HAND_OF_DEATH); HandOfDeathTimer = 2000; } else HandOfDeathTimer -= diff; return; // Don't do anything after this point. } if (SoulChargeCount) { if (SoulChargeTimer <= diff) UnleashSoulCharge(); else SoulChargeTimer -= diff; } if (GripOfTheLegionTimer <= diff) { DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION); GripOfTheLegionTimer = urand(5000,25000); } else GripOfTheLegionTimer -= diff; if (AirBurstTimer <= diff) { if (urand(0,1)) DoScriptText(SAY_AIR_BURST1, me); else DoScriptText(SAY_AIR_BURST2, me); DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank AirBurstTimer = urand(25000,40000); } else AirBurstTimer -= diff; if (FearTimer <= diff) { DoCast(me->getVictim(), SPELL_FEAR); FearTimer = 42000; } else FearTimer -= diff; if (DoomfireTimer <= diff) { if (urand(0,1)) DoScriptText(SAY_DOOMFIRE1, me); else DoScriptText(SAY_DOOMFIRE2, me); Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 1); if (!temp) temp = me->getVictim(); //replace with spell cast 31903 once implicitTarget 73 implemented SummonDoomfire(temp); //supposedly three doomfire can be up at the same time DoomfireTimer = 20000; } else DoomfireTimer -= diff; if (MeleeRangeCheckTimer <= diff) { if (CanUseFingerOfDeath()) { DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH); MeleeRangeCheckTimer = 1000; } MeleeRangeCheckTimer = 5000; } else MeleeRangeCheckTimer -= diff; DoMeleeAttackIfReady(); }
void ExecuteEvent(uint32 eventId) override { switch (eventId) { case EVENT_HAND_OF_DEATH: DoCastAOE(SPELL_HAND_OF_DEATH); events.ScheduleEvent(EVENT_HAND_OF_DEATH, 2000); break; case EVENT_UNLEASH_SOUL_CHARGE: _chargeSpell = 0; _unleashSpell = 0; me->InterruptNonMeleeSpells(false); switch (urand(0, 2)) { case 0: _chargeSpell = SPELL_SOUL_CHARGE_RED; _unleashSpell = SPELL_UNLEASH_SOUL_RED; break; case 1: _chargeSpell = SPELL_SOUL_CHARGE_YELLOW; _unleashSpell = SPELL_UNLEASH_SOUL_YELLOW; break; case 2: _chargeSpell = SPELL_SOUL_CHARGE_GREEN; _unleashSpell = SPELL_UNLEASH_SOUL_GREEN; break; } if (me->HasAura(_chargeSpell)) { me->RemoveAuraFromStack(_chargeSpell); DoCastVictim(_unleashSpell); SoulChargeCount--; events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000)); } break; case EVENT_FINGER_OF_DEATH: if (!SelectTarget(SELECT_TARGET_RANDOM, 0, 5.0f)) // Checks if there are no targets in melee range { DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH); events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 1000); } else events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 5000); break; case EVENT_GRIP_OF_THE_LEGION: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_GRIP_OF_THE_LEGION); events.ScheduleEvent(EVENT_GRIP_OF_THE_LEGION, urand(5000, 25000)); break; case EVENT_AIR_BURST: Talk(SAY_AIR_BURST); if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) DoCast(target, SPELL_AIR_BURST); //not on tank events.ScheduleEvent(EVENT_AIR_BURST, urand(25000, 40000)); break; case EVENT_FEAR: DoCastAOE(SPELL_FEAR); events.ScheduleEvent(EVENT_FEAR, 42000); break; case EVENT_DOOMFIRE: Talk(SAY_DOOMFIRE); if (Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1)) SummonDoomfire(temp); else SummonDoomfire(me->GetVictim()); events.ScheduleEvent(EVENT_DOOMFIRE, 20000); break; case EVENT_DISTANCE_CHECK: if (Creature* channelTrigger = instance->GetCreature(DATA_CHANNEL_TARGET)) if (me->IsWithinDistInMap(channelTrigger, 75.0f)) DoAction(ACTION_ENRAGE); events.ScheduleEvent(EVENT_DISTANCE_CHECK, 5000); break; case EVENT_SUMMON_WHISP: DoSpawnCreature(NPC_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); ++WispCount; if (WispCount >= 30) me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500); break; default: break; } }