void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (events.ExecuteEvent()) { case EVENT_SPELL_DRAIN_LIFE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) me->CastSpell(target, DUNGEON_MODE(SPELL_DRAIN_LIFE_N, SPELL_DRAIN_LIFE_H), false); events.ScheduleEvent(EVENT_SPELL_DRAIN_LIFE, 10000, 1); return; case EVENT_SPELL_DRAIN_MANA: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, PowerUsersSelector(me, POWER_MANA, 40.0f, false))) me->CastSpell(target, SPELL_DRAIN_MANA, false); events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, 10000, 1); return; case EVENT_SPELL_FEL_EXPLOSION: me->RemoveAuraFromStack(SPELL_MANA_RAGE_TRIGGER); me->CastSpell(me, SPELL_FEL_EXPLOSION, false); events.ScheduleEvent(EVENT_SPELL_FEL_EXPLOSION, 2000); break; case EVENT_DRAIN_CRYSTAL: events.DelayEvents(10001); events.ScheduleEvent(EVENT_EMPOWER, 10000); events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 30000); SelectNearestCrystal(); break; case EVENT_EMPOWER: if (me->GetPower(POWER_MANA) == me->GetMaxPower(POWER_MANA)) { Talk(SAY_EMPOWERED); if (Unit* crystal = ObjectAccessor::GetUnit(*me, CrystalGUID)) Unit::Kill(crystal, crystal); events.DelayEvents(10000, 1); events.ScheduleEvent(EVENT_RESTORE_COMBAT, 0); } else events.ScheduleEvent(EVENT_EMPOWER, 0, 0, 1); break; case EVENT_RESTORE_COMBAT: events.SetPhase(0); me->GetMotionMaster()->MoveChase(me->GetVictim()); break; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (!m_bDrainingCrystal) { uint32 uiMaxPowerMana = m_creature->GetMaxPower(POWER_MANA); if (uiMaxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / uiMaxPowerMana) < 10)) { if (m_uiDrainLifeTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_DRAIN_LIFE) == CAST_OK) m_uiDrainLifeTimer = 10000; } } else m_uiDrainLifeTimer -= uiDiff; // Heroic only if (!m_bIsRegularMode) { if (m_uiDrainManaTimer < uiDiff) { Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); if (!pTarget) pTarget = m_creature->getVictim(); if (DoCastSpellIfCan(pTarget, SPELL_DRAIN_MANA) == CAST_OK) m_uiDrainManaTimer = 10000; } else m_uiDrainManaTimer -= uiDiff; } } if (m_uiFelExplosionTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FEL_EXPLOSION) == CAST_OK) m_uiFelExplosionTimer = 2000; } else m_uiFelExplosionTimer -= uiDiff; // If below 10% mana, start recharging uiMaxPowerMana = m_creature->GetMaxPower(POWER_MANA); if (uiMaxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / uiMaxPowerMana) < 10)) { if (m_uiDrainCrystalTimer < uiDiff) { SelectNearestCrystal(); if (m_bIsRegularMode) m_uiDrainCrystalTimer = urand(20000, 25000); else m_uiDrainCrystalTimer = urand(10000, 15000); } else m_uiDrainCrystalTimer -= uiDiff; } DoMeleeAttackIfReady(); } else // if m_bDrainingCrystal { if (m_bIsDraining) { if (m_uiEmpowerTimer < uiDiff) { m_bIsDraining = false; m_bDrainingCrystal = false; DoScriptText(SAY_EMPOWERED, m_creature); Creature* CrystalChosen = m_creature->GetMap()->GetCreature(m_crystalGuid); if (CrystalChosen && CrystalChosen->isAlive()) // Use Deal Damage to kill it, not SetDeathState. CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); m_crystalGuid.Clear(); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } else m_uiEmpowerTimer -= uiDiff; } } }
void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (!DrainingCrystal) { uint32 maxPowerMana = m_creature->GetMaxPower(POWER_MANA); if (maxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / maxPowerMana) < 10)) { if (DrainLifeTimer < diff) { DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DRAIN_LIFE); DrainLifeTimer = 10000; }else DrainLifeTimer -= diff; // Heroic only if (!m_bIsRegularMode) { if (DrainManaTimer < diff) { DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_DRAIN_MANA); DrainManaTimer = 10000; }else DrainManaTimer -= diff; } } if (FelExplosionTimer < diff) { if (!m_creature->IsNonMeleeSpellCasted(false)) { DoCast(m_creature, SPELL_FEL_EXPLOSION); FelExplosionTimer = 2000; } }else FelExplosionTimer -= diff; // If below 10% mana, start recharging maxPowerMana = m_creature->GetMaxPower(POWER_MANA); if (maxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / maxPowerMana) < 10)) { if (DrainCrystalTimer < diff) { SelectNearestCrystal(); if (m_bIsRegularMode) DrainCrystalTimer = urand(20000, 25000); else DrainCrystalTimer = urand(10000, 15000); }else DrainCrystalTimer -= diff; } }else { if (IsDraining) { if (EmpowerTimer < diff) { IsDraining = false; DrainingCrystal = false; DoScriptText(SAY_EMPOWERED, m_creature); Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID); if (CrystalChosen && CrystalChosen->isAlive()) // Use Deal Damage to kill it, not setDeathState. CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); CrystalGUID = 0; m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); }else EmpowerTimer -= diff; } } DoMeleeAttackIfReady(); // No need to check if we are draining crystal here, as the spell has a stun. }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (!DrainingCrystal) { uint32 maxPowerMana = me->GetMaxPower(POWER_MANA); if (maxPowerMana && ((me->GetPower(POWER_MANA)*100 / maxPowerMana) < 10)) { if (DrainLifeTimer <= diff) { DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_DRAIN_LIFE); DrainLifeTimer = 10000; } else DrainLifeTimer -= diff; // Heroic only if (IsHeroic()) { if (DrainManaTimer <= diff) { DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_DRAIN_MANA); DrainManaTimer = 10000; } else DrainManaTimer -= diff; } } if (FelExplosionTimer <= diff) { if (!me->IsNonMeleeSpellCasted(false)) { DoCast(me, SPELL_FEL_EXPLOSION); FelExplosionTimer = 2000; } } else FelExplosionTimer -= diff; // If below 10% mana, start recharging maxPowerMana = me->GetMaxPower(POWER_MANA); if (maxPowerMana && ((me->GetPower(POWER_MANA)*100 / maxPowerMana) < 10)) { if (DrainCrystalTimer <= diff) { SelectNearestCrystal(); if (IsHeroic()) DrainCrystalTimer = 10000 + rand()%5000; else DrainCrystalTimer = 20000 + rand()%5000; } else DrainCrystalTimer -= diff; } }else { if (IsDraining) { if (EmpowerTimer <= diff) { IsDraining = false; DrainingCrystal = false; DoScriptText(SAY_EMPOWERED, me); Unit* CrystalChosen = Unit::GetUnit(*me, CrystalGUID); if (CrystalChosen && CrystalChosen->isAlive()) // Use Deal Damage to kill it, not setDeathState. CrystalChosen->Kill(CrystalChosen); CrystalGUID = 0; me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveChase(me->getVictim()); } else EmpowerTimer -= diff; } } DoMeleeAttackIfReady(); // No need to check if we are draining crystal here, as the spell has a stun. }
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_FEL_EXPLOSION: DoCastAOE(SPELL_FEL_EXPLOSION); events.ScheduleEvent(EVENT_FEL_EXPLOSION, 2000, 0, PHASE_NORMAL); break; case EVENT_DRAIN_CRYSTAL: SelectNearestCrystal(); _scheduledEvents = false; break; case EVENT_DRAIN_MANA: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true)) DoCast(target, SPELL_DRAIN_MANA); events.ScheduleEvent(EVENT_DRAIN_MANA, 10000, 0, PHASE_NORMAL); break; case EVENT_DRAIN_LIFE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20.0f, true)) DoCast(target, SPELL_DRAIN_LIFE); events.ScheduleEvent(EVENT_DRAIN_LIFE, 10000, 0, PHASE_NORMAL); break; case EVENT_EMPOWER: { Talk(SAY_EMPOWERED); Creature* CrystalChosen = ObjectAccessor::GetCreature(*me, CrystalGUID); if (CrystalChosen && CrystalChosen->IsAlive()) CrystalChosen->KillSelf(); CrystalGUID.Clear(); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveChase(me->GetVictim()); break; } default: break; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; } if (me->GetPowerPct(POWER_MANA) < 10.f) { if (events.IsInPhase(PHASE_NORMAL) && !_scheduledEvents) { _scheduledEvents = true; uint32 timer = urand(3000, 7000); events.ScheduleEvent(EVENT_DRAIN_LIFE, timer, 0, PHASE_NORMAL); if (IsHeroic()) { events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, urand(10000, 15000), 0, PHASE_NORMAL); events.ScheduleEvent(EVENT_DRAIN_MANA, timer + 5000, 0, PHASE_NORMAL); } else events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, urand(20000, 25000), 0, PHASE_NORMAL); } } DoMeleeAttackIfReady(); }