void UpdateAI(uint32 diff) { events2.Update(diff); switch (events2.ExecuteEvent()) { case EVENT_SHADE_GATHER_NPCS: { std::list<Creature*> ChannelerList; me->GetCreaturesWithEntryInRange(ChannelerList, 100.0f, NPC_ASHTONGUE_CHANNELER); for (std::list<Creature*>::const_iterator itr = ChannelerList.begin(); itr != ChannelerList.end(); ++itr) summonsChanneler.Summon(*itr); std::list<Creature*> SpawnerList; me->GetCreaturesWithEntryInRange(SpawnerList, 100.0f, NPC_CREATURE_GENERATOR_AKAMA); for (std::list<Creature*>::const_iterator itr = SpawnerList.begin(); itr != SpawnerList.end(); ++itr) summonsGenerator.Summon(*itr); summonsChanneler.Respawn(); summonsGenerator.Respawn(); ChannelersAction(ACTION_CHANNELERS_START_CHANNEL); if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_AKAMA_SHADE))) akama->Respawn(true); break; } case EVENT_SHADE_RESET_ENCOUNTER: me->SetVisible(true); summonsGenerator.Respawn(); summonsChanneler.Respawn(); ChannelersAction(ACTION_CHANNELERS_START_CHANNEL); if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_AKAMA_SHADE))) akama->Respawn(true); break; } if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (events.ExecuteEvent()) { case EVENT_SHADE_CHECK_DISTANCE: if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) { int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED); if (slow > -100) { me->SetWalk(true); me->GetMotionMaster()->MovePoint(POINT_START, 510.0f, 400.7993f, 112.7837f); } } else { int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED); if (slow < -100) me->GetMotionMaster()->Clear(); else if (slow == 0) { summonsGenerator.DoAction(ACTION_NO_SORCERERS); me->SetWalk(false); } } if (me->IsWithinMeleeRange(me->GetVictim())) { me->SetReactState(REACT_AGGRESSIVE); DoResetThreat(); me->GetVictim()->InterruptNonMeleeSpells(false); me->AddThreat(me->GetVictim(), 1000000.0f); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC|UNIT_FLAG_NOT_SELECTABLE); summonsGenerator.DoAction(ACTION_STOP_SPAWNING); break; } events.ScheduleEvent(EVENT_SHADE_CHECK_DISTANCE, 1000); break; } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch(m_uiPhase) { case PHASE_SPEECH: { if (m_uiSpeechTimer < uiDiff) { m_uiSpeechTimer = 5000; ++m_uiSpeechCount; switch(m_uiSpeechCount) { case 1: DoScriptText(SAY_SPEECH_2, m_creature); break; case 2: DoScriptText(SAY_SPEECH_3, m_creature); break; case 3: DoScriptText(SAY_SPEECH_4, m_creature); break; case 4: m_uiPhase = PHASE_BALCONY; break; } } else m_uiSpeechTimer -= uiDiff; break; } case PHASE_BALCONY: { if (m_uiSummonTimer < uiDiff) { if (m_uiSummonCount >= MAX_WAVES) { DoScriptText(SAY_TELEPORT, m_creature); DoScriptText(EMOTE_TO_FRAY, m_creature); DoCastSpellIfCan(m_creature, SPELL_TELEPORT_RIGHT); m_uiPhase = PHASE_GROUND; return; } // npc, npc, npc, timer static uint32 const auiSummonData[MAX_WAVES][4] = { {NPC_UNREL_TRAINEE, 0, 0, 20000}, {NPC_UNREL_TRAINEE, 0, 0, 20000}, {NPC_UNREL_TRAINEE, 0, 0, 10000}, {NPC_UNREL_DEATH_KNIGHT, 0, 0, 10000}, {NPC_UNREL_TRAINEE, 0, 0, 15000}, {NPC_UNREL_DEATH_KNIGHT, 0, 0, 10000}, {NPC_UNREL_TRAINEE, 0, 0, 15000}, {NPC_UNREL_DEATH_KNIGHT, NPC_UNREL_TRAINEE, 0, 10000}, {NPC_UNREL_RIDER, 0, 0, 10000}, {NPC_UNREL_TRAINEE, 0, 0, 5000}, {NPC_UNREL_DEATH_KNIGHT, 0, 0, 15000}, {NPC_UNREL_TRAINEE, NPC_UNREL_RIDER, 0, 10000}, {NPC_UNREL_DEATH_KNIGHT, NPC_UNREL_DEATH_KNIGHT, 0, 10000}, {NPC_UNREL_TRAINEE, 0, 0, 10000}, {NPC_UNREL_RIDER, 0, 0, 5000}, {NPC_UNREL_DEATH_KNIGHT, 0, 0, 5000}, {NPC_UNREL_TRAINEE, 0, 0, 20000}, {NPC_UNREL_RIDER, NPC_UNREL_DEATH_KNIGHT, NPC_UNREL_TRAINEE, 15000}, {NPC_UNREL_TRAINEE, 0, 0, 30000}, }; SummonAdds(true, auiSummonData[m_uiSummonCount][0]); if (auiSummonData[m_uiSummonCount][1]) SummonAdds(true, auiSummonData[m_uiSummonCount][1]); if (auiSummonData[m_uiSummonCount][2]) SummonAdds(true, auiSummonData[m_uiSummonCount][2]); m_uiSummonTimer = auiSummonData[m_uiSummonCount][3]; ++m_uiSummonCount; } else m_uiSummonTimer -= uiDiff; break; } case PHASE_GROUND: case PHASE_END: { if (m_HarvestTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_HARVESTSOUL) == CAST_OK) { m_HarvestTimer = 15000; return; } } m_HarvestTimer -= uiDiff; if (m_uiPhase == PHASE_GROUND) { if (m_creature->GetHealthPercent() < 30.0f) { if (m_pInstance->IsInRightSideGothArea(m_creature)) { DoScriptText(EMOTE_GATE, m_creature); m_pInstance->SetData(TYPE_GOTHIK, SPECIAL); m_uiPhase = PHASE_END; m_uiShadowboltTimer = 2000; return; } } if (m_uiTeleportTimer < uiDiff) { uint32 uiTeleportSpell = m_pInstance->IsInRightSideGothArea(m_creature) ? SPELL_TELEPORT_LEFT : SPELL_TELEPORT_RIGHT; if (DoCastSpellIfCan(m_creature, uiTeleportSpell) == CAST_OK) { DoResetThreat(); m_uiTeleportTimer = 15000; m_uiShadowboltTimer = 2000; return; } } else m_uiTeleportTimer -= uiDiff; } if (m_uiShadowboltTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOWBOLT: SPELL_SHADOWBOLT_H) == CAST_OK) m_uiShadowboltTimer = 1500; } else m_uiShadowboltTimer -= uiDiff; DoMeleeAttackIfReady(); // possibly no melee at all break; } } }
void boss_attumen::boss_attumenAI::UpdateAI(const uint32 diff) { if(ResetTimer) { if(ResetTimer <= diff) { ResetTimer = 0; Unit* pMidnight = Unit::GetUnit(*me, Midnight); if(pMidnight) { pMidnight->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pMidnight->SetVisible(true); } Midnight = 0; me->SetVisible(false); me->Kill(me); } } else ResetTimer -= diff; //Return since we have no target if(!UpdateVictim()) return; if(me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) return; if(CleaveTimer <= diff) { DoCast(me->getVictim(), SPELL_SHADOWCLEAVE); CleaveTimer = urand(10000, 15000); } else CleaveTimer -= diff; if(CurseTimer <= diff) { DoCast(me->getVictim(), SPELL_INTANGIBLE_PRESENCE); CurseTimer = 30000; } else CurseTimer -= diff; if(RandomYellTimer <= diff) { DoScriptText(RAND(SAY_RANDOM1, SAY_RANDOM2), me); RandomYellTimer = urand(30000, 60000); } else RandomYellTimer -= diff; if(me->GetUInt32Value(UNIT_FIELD_DISPLAYID) == MOUNTED_DISPLAYID) { if(ChargeTimer <= diff) { Unit* target = NULL; std::list<HostileReference *> t_list = me->getThreatManager().getThreatList(); std::vector<Unit* > target_list; for(std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if(target && !target->IsWithinDist(me, ATTACK_DISTANCE, false)) target_list.push_back(target); target = NULL; } if(!target_list.empty()) target = *(target_list.begin()+rand()%target_list.size()); DoCast(target, SPELL_BERSERKER_CHARGE); ChargeTimer = 20000; } else ChargeTimer -= diff; } else { if(HealthBelowPct(25)) { Creature* pMidnight = Unit::GetCreature(*me, Midnight); if(pMidnight && pMidnight->GetTypeId() == TYPEID_UNIT) { CAST_AI(boss_midnight::boss_midnightAI, (pMidnight->AI()))->Mount(me); me->SetHealth(pMidnight->GetHealth()); DoResetThreat(); } } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Note: because the Vanish spell adds invisibility effect on the target, the timers won't be decreased during the vanish phase if (m_uiWaitTimer) { if (m_uiWaitTimer <= uiDiff) { // It's not very clear how to handle this spell if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { DoScriptText(urand(0, 1) ? SAY_SPECIAL_1 : SAY_SPECIAL_2, m_creature); DoResetThreat(); AttackStart(pTarget); pTarget->CastSpell(pTarget, SPELL_GARROTE, TRIGGERED_OLD_TRIGGERED); } m_uiWaitTimer = 0; } else m_uiWaitTimer -= uiDiff; // Don't user other abilities in vanish return; } if (!m_bEnrage && m_creature->GetHealthPercent() < 30.0f) { if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK) m_bEnrage = true; } // No other spells are cast after enrage if (!m_bEnrage) { if (m_uiVanishTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_VANISH) == CAST_OK) { m_uiVanishTimer = 30000; m_uiWaitTimer = 1000; } } else m_uiVanishTimer -= uiDiff; // Gouge highest aggro, and attack second highest if (m_uiGougeTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_GOUGE) == CAST_OK) m_uiGougeTimer = 40000; } else m_uiGougeTimer -= uiDiff; if (m_uiBlindTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_BLIND, SELECT_FLAG_PLAYER)) { if (DoCastSpellIfCan(pTarget, SPELL_BLIND) == CAST_OK) m_uiBlindTimer = 40000; } } else m_uiBlindTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Bat phase if (m_bIsPhaseOne) { // Phase Switch at 50% if (m_creature->GetHealthPercent() < 50.0f) { m_creature->RemoveAurasDueToSpell(SPELL_BAT_FORM); m_creature->SetLevitate(false); DoResetThreat(); m_bIsPhaseOne = false; return; } if (m_uiChargeTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_CHARGE) == CAST_OK) m_uiChargeTimer = urand(15000, 30000); } } else m_uiChargeTimer -= uiDiff; if (m_uiSwoopTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SWOOP) == CAST_OK) m_uiSwoopTimer = urand(4000, 9000); } else m_uiSwoopTimer -= uiDiff; if (m_uiSonicBurstTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SONIC_BURST) == CAST_OK) m_uiSonicBurstTimer = urand(8000, 13000); } else m_uiSonicBurstTimer -= uiDiff; if (m_uiSpawnBatsTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_FRENZIED_BATS) == CAST_OK) { DoScriptText(SAY_SHRIEK, m_creature); m_uiSpawnBatsTimer = 60000; } } else m_uiSpawnBatsTimer -= uiDiff; } // Troll phase else { if (m_uiShadowWordPainTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_WORD_PAIN) == CAST_OK) m_uiShadowWordPainTimer = urand(12000, 18000); } } else m_uiShadowWordPainTimer -= uiDiff; if (m_uiMindFlayTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MIND_FLAY) == CAST_OK) m_uiMindFlayTimer = 16000; } else m_uiMindFlayTimer -= uiDiff; if (m_uiChainMindFlayTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BLOOD_LEECH) == CAST_OK) m_uiChainMindFlayTimer = urand(15000, 30000); } else m_uiChainMindFlayTimer -= uiDiff; if (m_uiGreaterHealTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_GREATERHEAL, CAST_INTERRUPT_PREVIOUS) == CAST_OK) { DoScriptText(SAY_HEAL, m_creature); m_uiGreaterHealTimer = urand(25000, 35000); } } else m_uiGreaterHealTimer -= uiDiff; if (m_uiFlyingBatsTimer) { if (m_uiFlyingBatsTimer <= uiDiff) { // Note: the bat riders summoning and movement may need additional research for (uint8 i = 0; i < 3; ++i) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) m_creature->SummonCreature(NPC_BAT_RIDER, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ() + 15.0f, 0, TEMPSUMMON_DEAD_DESPAWN, 0); } DoScriptText(SAY_RAIN_FIRE, m_creature); m_uiFlyingBatsTimer = 0; } else m_uiFlyingBatsTimer -= uiDiff; } } 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_MANA_STORM: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true)) DoCast(target, SPELL_MANA_STORM); events.ScheduleEvent(EVENT_MANA_STORM, urand(7500, 12500)); break; case EVENT_CHILL: DoCastVictim(SPELL_CHILL); events.ScheduleEvent(EVENT_CHILL, urand(13000, 25000)); break; case EVENT_BREATH: DoCastVictim(SPELL_FROST_BREATH); events.ScheduleEvent(EVENT_BREATH, urand(10000, 15000)); break; case EVENT_TELEPORT: { Talk(SAY_TELEPORT); ThreatContainer::StorageType const& threatlist = me->getThreatManager().getThreatList(); for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) { if (Player* player = ObjectAccessor::GetPlayer(*me, (*i)->getUnitGuid())) DoTeleportPlayer(player, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+3, player->GetOrientation()); } DoResetThreat(); events.ScheduleEvent(EVENT_TELEPORT, 30000); break; } case EVENT_REFLECT: DoCast(me, SPELL_REFLECT); events.ScheduleEvent(EVENT_REFLECT, urand(20000, 35000)); break; case EVENT_CLEAVE: DoCastVictim(SPELL_CLEAVE); events.ScheduleEvent(EVENT_CLEAVE, 7000); break; default: break; } } if (HealthBelowPct(26) && !_enraged) { DoCast(me, SPELL_ENRAGE); _enraged = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if(phase == 2 && boss_phase == 1) { events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, urand(9000,17000)); events.RescheduleEvent(EVENT_OVERLOAD, urand(60000,125000)); events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, urand(20000,40000)); boss_phase++; } if(phase == 3 && boss_phase == 2) { events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, urand(9000,17000)); events.RescheduleEvent(EVENT_OVERLOAD, urand(60000,125000)); events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, urand(20000,40000)); DoCast(me, SPELL_STORMSHIELD); events.RescheduleEvent(EVENT_LIGHTNING_TENDRILS, urand(40000,80000)); } events.Update(diff); if(!me->HasAura(SPELL_OVERLOAD) && overload == true) { DoCast(63480); overload = false; } while (uint32 eventId = events.ExecuteEvent()) { switch(eventId) { case EVENT_ENRAGE: DoScriptText(SAY_BRUNDIR_BERSERK, me); DoCast(SPELL_BERSERK); break; case EVENT_CHAIN_LIGHTNING: if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) DoCast(pTarget, RAID_MODE(SPELL_CHAIN_LIGHTNING_N , SPELL_CHAIN_LIGHTNING_H)); events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, urand(9000,17000)); break; case EVENT_OVERLOAD: DoCast(SPELL_OVERLOAD); overload = true; events.ScheduleEvent(EVENT_OVERLOAD, urand(60000,125000)); break; case EVENT_LIGHTNING_WHIRL: DoCast(RAID_MODE(SPELL_LIGHTNING_WHIRL , SPELL_LIGHTNING_WHIRL_H)); DoCast(RAID_MODE(61916, 63482)); events.ScheduleEvent(EVENT_LIGHTNING_WHIRL, urand(20000,40000)); break; case EVENT_LIGHTNING_TENDRILS: DoCast(RAID_MODE(SPELL_LIGHTNING_TENDRILS, SPELL_LIGHTNING_TENDRILS_H)); DoCast(RAID_MODE(61886, 63485)); events.DelayEvents(15000, 5000); DoResetThreat(); break; } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 50)) { if (Dispell_Timer < diff) { DoCast(m_creature, SPELL_DISPELL); Dispell_Timer = 15000 + rand()%15000; }else Dispell_Timer -= diff; if (Renew_Timer < diff) { DoCast(m_creature, SPELL_RENEW); Renew_Timer = 20000 + rand()%10000; }else Renew_Timer -= diff; if (HolyWrath_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_HOLY_WRATH); HolyWrath_Timer = 15000 + rand()%10000; }else HolyWrath_Timer -= diff; if (HolyNova_Timer < diff) { TargetInRange = 0; for(uint8 i=0; i<10; ++i) { if (Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO,i)) if (m_creature->IsWithinMeleeRange(target)) TargetInRange++; } if (TargetInRange > 1) { DoCast(m_creature->getVictim(),SPELL_HOLY_NOVA); HolyNova_Timer = 1000; } else { HolyNova_Timer = 2000; } }else HolyNova_Timer -= diff; if (HolyFire_Timer < diff && TargetInRange < 3) { if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) DoCast(target, SPELL_HOLY_FIRE); HolyFire_Timer = 8000; }else HolyFire_Timer -= diff; } else { if (!PhaseTwo) { DoScriptText(SAY_TRANSFORM, m_creature); m_creature->InterruptNonMeleeSpells(false); DoCast(m_creature,SPELL_SNAKE_FORM); m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.00f); const CreatureInfo *cinfo = m_creature->GetCreatureInfo(); m_creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 25))); m_creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 25))); m_creature->UpdateDamagePhysical(BASE_ATTACK); DoResetThreat(); PhaseTwo = true; } if (PhaseTwo && PoisonCloud_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_POISON_CLOUD); PoisonCloud_Timer = 15000; }PoisonCloud_Timer -=diff; if (PhaseTwo && VenomSpit_Timer < diff) { if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) DoCast(target, SPELL_VENOMSPIT); VenomSpit_Timer = 15000 + rand()%5000; }else VenomSpit_Timer -= diff; if (PhaseTwo && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 11)) { if (!InBerserk) { m_creature->InterruptNonMeleeSpells(false); DoCast(m_creature, SPELL_BERSERK); InBerserk = true; } } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; //Check_Timer for the death of LorKhan and Zath. if (!WasDead && Check_Timer <= diff) { if (m_pInstance) { if (m_pInstance->GetData(TYPE_LORKHAN) == SPECIAL) { //Resurrect LorKhan if (Unit *pLorKhan = Unit::GetUnit((*me), m_pInstance->GetData64(DATA_LORKHAN))) { pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pLorKhan->setFaction(14); pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pLorKhan->SetFullHealth(); m_pInstance->SetData(TYPE_LORKHAN, DONE); } } if (m_pInstance->GetData(TYPE_ZATH) == SPECIAL) { //Resurrect Zath Unit *pZath = Unit::GetUnit((*me), m_pInstance->GetData64(DATA_ZATH)); if (pZath) { pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pZath->setFaction(14); pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pZath->SetFullHealth(); m_pInstance->SetData(TYPE_ZATH, DONE); } } } Check_Timer = 5000; } else Check_Timer -= diff; if (!PhaseTwo && MortalCleave_Timer <= diff) { DoCast(me->getVictim(), SPELL_MORTALCLEAVE); MortalCleave_Timer = 15000 + rand()%5000; } else MortalCleave_Timer -= diff; if (!PhaseTwo && Silence_Timer <= diff) { DoCast(me->getVictim(), SPELL_SILENCE); Silence_Timer = 20000 + rand()%5000; } else Silence_Timer -= diff; if (!PhaseTwo && !WasDead && !HealthAbovePct(5)) { me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetStandState(UNIT_STAND_STATE_SLEEP); me->AttackStop(); if (m_pInstance) m_pInstance->SetData(TYPE_THEKAL, SPECIAL); WasDead=true; } //Thekal will transform to Tiger if he died and was not resurrected after 10 seconds. if (!PhaseTwo && WasDead) { if (Resurrect_Timer <= diff) { DoCast(me, SPELL_TIGER_FORM); me->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.00f); me->SetStandState(UNIT_STAND_STATE_STAND); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFullHealth(); const CreatureTemplate *cinfo = me->GetCreatureInfo(); 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); DoResetThreat(); PhaseTwo = true; } else Resurrect_Timer -= diff; } if (me->IsFullHealth() && WasDead) { WasDead = false; } if (PhaseTwo) { if (Charge_Timer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,0)) { DoCast(pTarget, SPELL_CHARGE); DoResetThreat(); AttackStart(pTarget); } Charge_Timer = 15000 + rand()%7000; } else Charge_Timer -= diff; if (Frenzy_Timer <= diff) { DoCast(me, SPELL_FRENZY); Frenzy_Timer = 30000; } else Frenzy_Timer -= diff; if (ForcePunch_Timer <= diff) { DoCast(me->getVictim(), SPELL_SILENCE); ForcePunch_Timer = 16000 + rand()%5000; } else ForcePunch_Timer -= diff; if (SummonTigers_Timer <= diff) { DoCast(me->getVictim(), SPELL_SUMMONTIGERS); SummonTigers_Timer = 10000 + rand()%4000; } else SummonTigers_Timer -= diff; if (HealthBelowPct(11) && !Enraged) { DoCast(me, SPELL_ENRAGE); Enraged = true; } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (Teleport_Timer <= diff) { DoScriptText(SAY_TELEPORT, me); std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); for (i = m_threatlist.begin(); i!= m_threatlist.end(); ++i) { Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) { DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+3, pUnit->GetOrientation()); } } DoResetThreat(); Teleport_Timer = 30000; } else Teleport_Timer -= diff; // //MarkOfFrost_Timer // if (MarkOfFrost_Timer <= diff) // { // DoCast(me->getVictim(), SPELL_MARKOFFROST); // MarkOfFrost_Timer = 25000; // } else MarkOfFrost_Timer -= diff; //Chill_Timer if (Chill_Timer <= diff) { DoCast(me->getVictim(), SPELL_CHILL); Chill_Timer = 13000 + rand()%12000; } else Chill_Timer -= diff; //Breath_Timer if (Breath_Timer <= diff) { DoCast(me->getVictim(), SPELL_FROSTBREATH); Breath_Timer = 10000 + rand()%5000; } else Breath_Timer -= diff; //ManaStorm_Timer if (ManaStorm_Timer <= diff) { if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) DoCast(pTarget, SPELL_MANASTORM); ManaStorm_Timer = 7500 + rand()%5000; } else ManaStorm_Timer -= diff; //Reflect_Timer if (Reflect_Timer <= diff) { DoCast(me, SPELL_REFLECT); Reflect_Timer = 20000 + rand()%15000; } else Reflect_Timer -= diff; //Cleave_Timer if (Cleave_Timer <= diff) { DoCast(me->getVictim(), SPELL_CLEAVE); Cleave_Timer = 7000; } else Cleave_Timer -= diff; //Enrage_Timer if (me->GetHealth()*100 / me->GetMaxHealth() < 26 && !Enraged) { DoCast(me, SPELL_ENRAGE); Enraged = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch(getStage()) { case 0: if (timedQuery(SPELL_BONE_STRIKE, diff)) if (Unit* pTarget = doSelectRandomPlayer(SPELL_BONE_STRIKE_IMPALE, false, 60.0f, isHeroic())) if (doCast(SPELL_BONE_STRIKE, pTarget) == CAST_OK) { doSummonSpike(pTarget); switch (urand(0,1)) { case 0: DoScriptText(-1631003,m_creature,pTarget); break; case 1: DoScriptText(-1631004,m_creature,pTarget); break; case 2: DoScriptText(-1631005,m_creature,pTarget); break; }; }; if (timedQuery(SPELL_BONE_STORM, diff)) setStage(1); if (timedQuery(SPELL_CALL_COLD_FLAME, diff)) { if (urand(0,1)) doCast(SPELL_CALL_COLD_FLAME); else doCast(SPELL_CALL_COLD_FLAME_1); if (m_creature->GetHealthPercent() <= 30.0f) { if (urand(0,1)) doCast(SPELL_CALL_COLD_FLAME); else doCast(SPELL_CALL_COLD_FLAME_1); } } timedCast(SPELL_SABER_LASH, diff); DoMeleeAttackIfReady(); break; case 1: m_creature->InterruptNonMeleeSpells(true); doCast(SPELL_BONE_STORM); setStage(2); DoScriptText(-1631002,m_creature); DoResetThreat(); m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); m_creature->SetSpeedRate(MOVE_RUN, 3); m_creature->SetSpeedRate(MOVE_WALK, 3); break; case 2: if (!m_creature->IsNonMeleeSpellCasted(false)) setStage(3); break; case 3: if (isHeroic()) if (timedQuery(SPELL_BONE_STRIKE, diff, true)) if (Unit* pTarget = doSelectRandomPlayer(SPELL_BONE_STRIKE_IMPALE, false, 60.0f)) doSummonSpike(pTarget); if (timedQuery(SPELL_CALL_COLD_FLAME, diff, true) && m_creature->IsWithinDistInMap(m_creature->getVictim(),2.0f)) { pInstance->SetData(DATA_DIRECTION, (uint32)(1000*2.0f*M_PI_F*((float)urand(1,16)/16.0f))); // if (urand(0,1)) doCast(SPELL_CALL_COLD_FLAME); // else doCast(SPELL_CALL_COLD_FLAME_1); float fPosX, fPosY, fPosZ; m_creature->GetPosition(fPosX, fPosY, fPosZ); doSummon(NPC_COLD_FLAME, fPosX, fPosY, fPosZ); DoResetThreat(); if (Unit* pTarget = doSelectRandomPlayerAtRange(60.0f)) AttackStart(pTarget); } if (!hasAura(SPELL_BONE_STORM_STRIKE, m_creature) && !hasAura(SPELL_BONE_STORM, m_creature)) setStage(4); break; case 4: pInstance->SetData(DATA_DIRECTION, 0); m_creature->SetSpeedRate(MOVE_RUN, 1); m_creature->SetSpeedRate(MOVE_WALK, 1); // m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); setStage(0); break; default: break; } if (timedQuery(SPELL_BERSERK, diff)) { doCast(SPELL_BERSERK); DoScriptText(-1631008,m_creature); } }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch (m_uiPhase) { case PHASE_FAKE_DEATH: if (m_uiResurrectTimer < uiDiff) { // resurrect him in any case DoCastSpellIfCan(m_creature, SPELL_RESURRECT); m_uiPhase = PHASE_WAITING; if (m_pInstance) { CanPreventAddsResurrect(); m_pInstance->SetData(TYPE_THEKAL, IN_PROGRESS); } } else m_uiResurrectTimer -= uiDiff; // No break needed here case PHASE_WAITING: return; case PHASE_NORMAL: if (m_uiMortalCleaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MORTAL_CLEAVE) == CAST_OK) m_uiMortalCleaveTimer = urand(15000, 20000); } else m_uiMortalCleaveTimer -= uiDiff; if (m_uiSilenceTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_SILENCE) == CAST_OK) m_uiSilenceTimer = urand(20000, 25000); } } else m_uiSilenceTimer -= uiDiff; break; case PHASE_TIGER: if (m_uiChargeTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_CHARGE) == CAST_OK) { DoResetThreat(); AttackStart(pTarget); m_uiChargeTimer = urand(15000, 22000); } } } else m_uiChargeTimer -= uiDiff; if (m_uiFrenzyTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK) m_uiFrenzyTimer = 30000; } else m_uiFrenzyTimer -= uiDiff; if (m_uiForcePunchTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FORCE_PUNCH) == CAST_OK) m_uiForcePunchTimer = urand(16000, 21000); } else m_uiForcePunchTimer -= uiDiff; if (m_uiSummonTigersTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_TIGERS) == CAST_OK) m_uiSummonTigersTimer = 50000; } else m_uiSummonTigersTimer -= uiDiff; if (!m_bEnraged && m_creature->GetHealthPercent() < 11.0f) { if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) m_bEnraged = true; } break; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if(Check_Timer < diff) { if(!m_creature->IsWithinDistInMap(&wLoc, 80.0f)) EnterEvadeMode(); Check_Timer = 2000; }else Check_Timer -= diff; //Spell Enrage, when hp <= 20% gain enrage if (((m_creature->GetHealth()*100)/ m_creature->GetMaxHealth()) <= 20) { if(Enrage_Timer < diff) { m_creature->RemoveAurasDueToSpell(SPELL_ENRAGE); DoCast(m_creature,SPELL_ENRAGE); Enrage_Timer = 600000; InEnrage = true; }else Enrage_Timer -= diff; } //Spell Overrun if (Overrun_Timer < diff) { DoScriptText(RAND(SAY_OVERRUN_1, SAY_OVERRUN_2), m_creature); DoCast(m_creature->getVictim(),SPELL_OVERRUN); DoResetThreat(); Overrun_Timer = 25000 + rand()%15000; }else Overrun_Timer -= diff; //Spell Earthquake if (Quake_Timer < diff) { if (rand()%2) return; DoScriptText(RAND(SAY_EARTHQUAKE_1, SAY_EARTHQUAKE_2), m_creature); //remove enrage before casting earthquake because enrage + earthquake = 16000dmg over 8sec and all dead if (InEnrage) m_creature->RemoveAura(SPELL_ENRAGE, 0); DoCast(m_creature,SPELL_EARTHQUAKE); Enrage_Timer = 8000; Quake_Timer = 30000 + rand()%25000; }else Quake_Timer -= diff; //Spell Chain Lightning if (Chain_Timer < diff) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,1, GetSpellMaxRange(SPELL_CHAIN_LIGHTNING), true, m_creature->getVictimGUID()); if (!target) target = m_creature->getVictim(); if (target) DoCast(target,SPELL_CHAIN_LIGHTNING); Chain_Timer = 10000 + rand()%25000; }else Chain_Timer -= diff; //Spell Sunder Armor if (Armor_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_SUNDER_ARMOR); Armor_Timer = 10000 + rand()%15000; }else Armor_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch (m_uiPhase) { case PHASE_SPEECH: if (m_uiSpeechTimer < uiDiff) { switch (m_uiSpeech) { case 1: DoScriptText(SAY_SPEECH_1, m_creature); m_uiSpeechTimer = 4 * IN_MILLISECONDS; break; case 2: DoScriptText(SAY_SPEECH_2, m_creature); m_uiSpeechTimer = 6 * IN_MILLISECONDS; break; case 3: DoScriptText(SAY_SPEECH_3, m_creature); m_uiSpeechTimer = 5 * IN_MILLISECONDS; break; case 4: DoScriptText(SAY_SPEECH_4, m_creature); m_uiPhase = PHASE_BALCONY; break; } m_uiSpeech++; } else m_uiSpeechTimer -= uiDiff; // No break here case PHASE_BALCONY: // Do summoning if (m_uiTraineeTimer < uiDiff) { SummonAdds(true, NPC_UNREL_TRAINEE); m_uiTraineeTimer = 20 * IN_MILLISECONDS; } else m_uiTraineeTimer -= uiDiff; if (m_uiDeathKnightTimer < uiDiff) { SummonAdds(true, NPC_UNREL_DEATH_KNIGHT); m_uiDeathKnightTimer = 25 * IN_MILLISECONDS; } else m_uiDeathKnightTimer -= uiDiff; if (m_uiRiderTimer < uiDiff) { SummonAdds(true, NPC_UNREL_RIDER); m_uiRiderTimer = 30 * IN_MILLISECONDS; } else m_uiRiderTimer -= uiDiff; if (m_uiPhaseTimer < uiDiff) { m_uiPhase = PHASE_STOP_SUMMONING; m_uiPhaseTimer = 50 * IN_MILLISECONDS; } else m_uiPhaseTimer -= uiDiff; break; case PHASE_STOP_SUMMONING: if (m_uiPhaseTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT_RIGHT, CAST_TRIGGERED) == CAST_OK) { m_uiPhase = m_pInstance ? PHASE_TELEPORTING : PHASE_STOP_TELEPORTING; DoScriptText(SAY_TELEPORT, m_creature); DoScriptText(EMOTE_TO_FRAY, m_creature); // Remove Immunity m_creature->ApplySpellImmune(nullptr, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ALL, false); DoResetThreat(); m_creature->SetInCombatWithZone(); } } else m_uiPhaseTimer -= uiDiff; break; case PHASE_TELEPORTING: // Phase is only reached if m_pInstance is valid if (m_uiTeleportTimer < uiDiff) { uint32 uiTeleportSpell = m_pInstance->IsInRightSideGothArea(m_creature) ? SPELL_TELEPORT_LEFT : SPELL_TELEPORT_RIGHT; if (DoCastSpellIfCan(m_creature, uiTeleportSpell) == CAST_OK) { m_uiTeleportTimer = urand(30000, 45000); // Teleports between 30 seconds and 45 seconds. m_uiShadowboltTimer = 2 * IN_MILLISECONDS; } } else m_uiTeleportTimer -= uiDiff; if (m_creature->GetHealthPercent() <= 30.0f) { m_uiPhase = PHASE_STOP_TELEPORTING; ProcessCentralDoor(); // as the doors now open, recheck whether mobs are standing around m_uiControlZoneTimer = 1; } // no break here case PHASE_STOP_TELEPORTING: if (m_uiHarvestSoulTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_HARVESTSOUL) == CAST_OK) m_uiHarvestSoulTimer = 15 * IN_MILLISECONDS; } else m_uiHarvestSoulTimer -= uiDiff; if (m_uiShadowboltTimer) { if (m_uiShadowboltTimer <= uiDiff) m_uiShadowboltTimer = 0; else m_uiShadowboltTimer -= uiDiff; } // Shadowbold cooldown finished, cast when ready else if (!m_creature->IsNonMeleeSpellCasted(true)) { // Select valid target if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0, SPELL_SHADOWBOLT, SELECT_FLAG_IN_LOS)) DoCastSpellIfCan(pTarget, SPELL_SHADOWBOLT); } break; } // Control Check, if Death zone empty if (m_uiControlZoneTimer) { if (m_uiControlZoneTimer <= uiDiff) { m_uiControlZoneTimer = 0; if (m_pInstance && !HasPlayersInLeftSide()) { ProcessCentralDoor(); for (GuidList::const_iterator itr = m_lSummonedAddGuids.begin(); itr != m_lSummonedAddGuids.end(); ++itr) { if (Creature* pCreature = m_pInstance->instance->GetCreature(*itr)) { if (!pCreature->isInCombat()) pCreature->SetInCombatWithZone(); } } } } else m_uiControlZoneTimer -= uiDiff; } }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; //ArcaneExplosion_Timer if (ArcaneExplosion_Timer <= diff) { DoCast(me->getVictim(), SPELL_ARCANE_EXPLOSION); ArcaneExplosion_Timer = 8000 + rand()%10000; } else ArcaneExplosion_Timer -= diff; //If we are within range melee the target if (me->IsWithinMeleeRange(me->getVictim())) { //Make sure our attack is ready and we arn't currently casting if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false)) { me->AttackerStateUpdate(me->getVictim()); me->resetAttackTimer(); } }else { //EarthShock_Timer if (EarthShock_Timer <= diff) { DoCast(me->getVictim(), SPELL_EARTH_SHOCK); EarthShock_Timer = 1000; } else EarthShock_Timer -= diff; } //Blink_Timer if (Blink_Timer <= diff) { //DoCast(me, SPELL_BLINK); switch (urand(0,2)) { case 0: me->GetMap()->CreatureRelocation(me, -8340.782227,2083.814453,125.648788,0.0f); DoResetThreat(); break; case 1: me->GetMap()->CreatureRelocation(me, -8341.546875,2118.504639,133.058151,0.0f); DoResetThreat(); break; case 2: me->GetMap()->CreatureRelocation(me, -8318.822266,2058.231201,133.058151,0.0f); DoResetThreat(); break; } DoStopAttack(); Blink_Timer= 20000 + rand()%20000; } else Blink_Timer -= diff; int procent = (int) (me->GetHealth()*100 / me->GetMaxHealth() +0.5); //Summoning 2 Images and teleporting to a random position on 75% health if ((!Images75 && !IsImage) && (procent <= 75 && procent > 70)) DoSplit(75); //Summoning 2 Images and teleporting to a random position on 50% health if ((!Images50 && !IsImage) && (procent <= 50 && procent > 45)) DoSplit(50); //Summoning 2 Images and teleporting to a random position on 25% health if ((!Images25 && !IsImage) && (procent <= 25 && procent > 20)) DoSplit(25); //Invisible_Timer if (Invisible) { if (Invisible_Timer <= diff) { //Making Skeram visible after telporting me->SetVisibility(VISIBILITY_ON); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Invisible_Timer = 2500; Invisible = false; } else Invisible_Timer -= diff; } DoMeleeAttackIfReady(); }
void Revive() { DoResetThreat(); PauseCombatMovement(); Reset(); }
void DoSplit(int atPercent /* 75 50 25 */) { DoScriptText(SAY_SPLIT, me); ov_mycoordinates *place1 = new ov_mycoordinates(-8340.782227,2083.814453,125.648788,0); ov_mycoordinates *place2 = new ov_mycoordinates(-8341.546875,2118.504639,133.058151,0); ov_mycoordinates *place3 = new ov_mycoordinates(-8318.822266,2058.231201,133.058151,0); ov_mycoordinates *bossc=place1, *i1=place2, *i2=place3; switch (urand(0,2)) { case 0: bossc=place1; i1=place2; i2=place3; break; case 1: bossc=place2; i1=place1; i2=place3; break; case 2: bossc=place3; i1=place1; i2=place2; break; } for (uint16 i = 0; i < 41; ++i) { if (Player *pTarget = CAST_PLR(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))) { if (Group *pGrp = pTarget->GetGroup()) for (uint8 ico = 0; ico < TARGETICONCOUNT; ++ico) { //if (grp->m_targetIcons[ico] == me->GetGUID()) -- private member :( pGrp->SetTargetIcon(ico, 0, 0); } break; } } me->RemoveAllAuras(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetVisibility(VISIBILITY_OFF); me->GetMap()->CreatureRelocation(me, bossc->x, bossc->y, bossc->z, bossc->r); Invisible = true; delete place1; delete place2; delete place3; DoResetThreat(); DoStopAttack(); switch (atPercent) { case 75: Images75 = true; break; case 50: Images50 = true; break; case 25: Images25 = true; break; } Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); Creature *Image1 = me->SummonCreature(15263, i1->x, i1->y, i1->z, i1->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); if (Image1) { Image1->SetMaxHealth(me->GetMaxHealth() / 5); Image1->SetHealth(me->GetHealth() / 5); if (pTarget) Image1->AI()->AttackStart(pTarget); CAST_AI(boss_skeramAI, Image1->AI())->IsImage = true; } Creature *Image2 = me->SummonCreature(15263,i2->x, i2->y, i2->z, i2->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); if (Image2) { Image2->SetMaxHealth(me->GetMaxHealth() / 5); Image2->SetHealth(me->GetHealth() / 5); if (pTarget) Image2->AI()->AttackStart(pTarget); CAST_AI(boss_skeramAI, Image2->AI())->IsImage = true; } Invisible = true; }
void UpdateAI(const uint32 uiDiff) { switch (m_uiPhase) { // ***** Advisors phase ******** case PHASE_1_ADVISOR: { if (!m_uiPhaseTimer) return; if (m_uiPhaseTimer <= uiDiff) { if (!m_pInstance) return; switch(m_uiPhaseSubphase) { case 0: DoScriptText(SAY_INTRO_THALADRED, m_creature); m_uiPhaseTimer = 7000; break; case 1: if (Creature* pAdvisor = m_pInstance->GetSingleCreatureFromStorage(NPC_THALADRED)) { pAdvisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pAdvisor->SetInCombatWithZone(); } m_uiPhaseTimer = 0; break; case 2: DoScriptText(SAY_INTRO_SANGUINAR, m_creature); m_uiPhaseTimer = 12500; break; case 3: if (Creature* pAdvisor = m_pInstance->GetSingleCreatureFromStorage(NPC_SANGUINAR)) { pAdvisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pAdvisor->SetInCombatWithZone(); } m_uiPhaseTimer = 0; break; case 4: DoScriptText(SAY_INTRO_CAPERNIAN, m_creature); m_uiPhaseTimer = 7000; break; case 5: if (Creature* pAdvisor = m_pInstance->GetSingleCreatureFromStorage(NPC_CAPERNIAN)) { pAdvisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pAdvisor->SetInCombatWithZone(); } m_uiPhaseTimer = 0; break; case 6: DoScriptText(SAY_INTRO_TELONICUS, m_creature); m_uiPhaseTimer = 8400; break; case 7: if (Creature* pAdvisor = m_pInstance->GetSingleCreatureFromStorage(NPC_TELONICUS)) { pAdvisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pAdvisor->SetInCombatWithZone(); } m_uiPhaseTimer = 0; break; } ++m_uiPhaseSubphase; } else m_uiPhaseTimer -= uiDiff; break; } // ***** Weapons phase ******** case PHASE_2_WEAPON: { if (m_uiPhaseTimer < uiDiff) { // Switch to next phase, no matter if the weapons are killed or not if (DoCastSpellIfCan(m_creature, SPELL_RESURRECTION) == CAST_OK) { DoScriptText(SAY_PHASE3_ADVANCE, m_creature); m_uiPhaseSubphase = 0; m_uiPhaseTimer = 180000; m_uiPhase = PHASE_3_ADVISOR_ALL; } } else m_uiPhaseTimer -= uiDiff; break; } // ***** All advisors phase ******** case PHASE_3_ADVISOR_ALL: { if (m_uiPhaseTimer < uiDiff) { DoScriptText(SAY_PHASE4_INTRO2, m_creature); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoResetThreat(); m_creature->SetInCombatWithZone(); m_uiPhase = PHASE_4_SOLO; m_uiPhaseTimer = 30000; } else m_uiPhaseTimer -= uiDiff; break; } // ***** Solo phases ******** case PHASE_4_SOLO: case PHASE_7_GRAVITY: { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiGravityExpireTimer) { if (m_uiNetherBeamTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_NETHER_BEAM) == CAST_OK) m_uiNetherBeamTimer = urand(2000, 4000); } else m_uiNetherBeamTimer -= uiDiff; // Switch to the other spells after gravity lapse expired if (m_uiGravityExpireTimer <= uiDiff) m_uiGravityExpireTimer = 0; else m_uiGravityExpireTimer -= uiDiff; } else { if (m_uiFireballTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_FIREBALL) == CAST_OK) m_uiFireballTimer = urand(3000, 5000); } } else m_uiFireballTimer -= uiDiff; if (m_uiArcaneDisruptionTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_ARCANE_DISRUPTION) == CAST_OK) m_uiArcaneDisruptionTimer = 60000; } else m_uiArcaneDisruptionTimer -= uiDiff; if (m_uiFlameStrikeTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_FLAME_STRIKE) == CAST_OK) m_uiFlameStrikeTimer = 30000; } } else m_uiFlameStrikeTimer -= uiDiff; if (m_uiPhoenixTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_PHOENIX_ANIMATION) == CAST_OK) { DoScriptText(urand(0, 1) ? SAY_SUMMON_PHOENIX1 : SAY_SUMMON_PHOENIX2, m_creature); m_uiPhoenixTimer = 60000; } } else m_uiPhoenixTimer -= uiDiff; } DoMeleeAttackIfReady(); // ***** Phase 4 specific actions ******** if (m_uiPhase == PHASE_4_SOLO) { if (m_creature->GetHealthPercent() < 50.0f) { // ToDo: should he cast something here? m_creature->InterruptNonMeleeSpells(false); DoScriptText(SAY_PHASE5_NUTS, m_creature); SetCombatMovement(false); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MovePoint(POINT_ID_CENTER, aCenterPos[0], aCenterPos[1], aCenterPos[2]); m_uiPhase = PHASE_5_WAITING; } if (m_uiShockBarrierTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SHOCK_BARRIER) == CAST_OK) { m_uiPyroblastTimer = 1000; m_uiShockBarrierTimer = 60000; } } else m_uiShockBarrierTimer -= uiDiff; if (m_uiPyroblastTimer) { if (m_uiPyroblastTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_PYROBLAST) == CAST_OK) { DoScriptText(EMOTE_PYROBLAST, m_creature); m_uiPyroblastTimer = 0; } } else m_uiPyroblastTimer -= uiDiff; } if (m_uiMindControlTimer < uiDiff) { for (uint8 i = 0; i < MAX_MIND_CONTROL; ++i) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, SPELL_MIND_CONTROL, SELECT_FLAG_PLAYER)) DoCastSpellIfCan(pTarget, SPELL_MIND_CONTROL); } m_uiMindControlTimer = 60000; } else m_uiMindControlTimer -= uiDiff; } // ***** Phase 7 specific actions ******** if (m_uiPhase == PHASE_7_GRAVITY) { if (m_uiGravityLapseTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_GRAVITY_LAPSE) == CAST_OK) { DoScriptText(urand(0, 1) ? SAY_GRAVITYLAPSE1 : SAY_GRAVITYLAPSE2, m_creature);; m_uiGravityIndex = 0; m_uiNetherBeamTimer = 8000; m_uiNetherVaporTimer = 4000; m_uiGravityExpireTimer = 30000; m_uiGravityLapseTimer = 90000; } } else m_uiGravityLapseTimer -= uiDiff; if (m_uiShockBarrierTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SHOCK_BARRIER) == CAST_OK) m_uiShockBarrierTimer = 20000; } else m_uiShockBarrierTimer -= uiDiff; if (m_uiNetherVaporTimer) { if (m_uiNetherVaporTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_NETHER_VAPOR_SUMMON) == CAST_OK) m_uiNetherVaporTimer = 0; } else m_uiNetherVaporTimer -= uiDiff; } } } // ***** Phase 5 - transition ******** case PHASE_5_WAITING: // Nothing here; wait for boss to arive at point break; // ***** Phase 6 - explode the bridge ******** case PHASE_6_FLYING: if (m_uiExplodeTimer) { if (m_uiExplodeTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_EXPLODE) == CAST_OK) { if (m_pInstance) { m_pInstance->DoUseDoorOrButton(GO_KAEL_STATUE_LEFT); m_pInstance->DoUseDoorOrButton(GO_KAEL_STATUE_RIGHT); m_pInstance->DoUseDoorOrButton(GO_BRIDGE_WINDOW); } // Note: also Kael casts some other unk spells here m_uiPhaseTimer = 5000; m_uiExplodeTimer = 0; } } else m_uiExplodeTimer -= uiDiff; } if (m_uiPhaseTimer) { if (m_uiPhaseTimer <= uiDiff) { m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MovePoint(POINT_ID_CENTER, aCenterPos[0], aCenterPos[1], aCenterPos[2]); m_uiPhaseTimer = 0; } else m_uiPhaseTimer -= uiDiff; } break; } }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; //BloodSiphon_Timer if (BloodSiphon_Timer <= diff) { DoCast(me->getVictim(), SPELL_BLOODSIPHON); BloodSiphon_Timer = 90000; } else BloodSiphon_Timer -= diff; //CorruptedBlood_Timer if (CorruptedBlood_Timer <= diff) { DoCast(me->getVictim(), SPELL_CORRUPTEDBLOOD); CorruptedBlood_Timer = 30000 + rand()%15000; } else CorruptedBlood_Timer -= diff; //CauseInsanity_Timer /*if (CauseInsanity_Timer <= diff) { if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) DoCast(pTarget, SPELL_CAUSEINSANITY); CauseInsanity_Timer = 35000 + rand()%8000; } else CauseInsanity_Timer -= diff;*/ //WillOfHakkar_Timer if (WillOfHakkar_Timer <= diff) { if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) DoCast(pTarget, SPELL_WILLOFHAKKAR); WillOfHakkar_Timer = 25000 + rand()%10000; } else WillOfHakkar_Timer -= diff; if (!Enraged && Enrage_Timer <= diff) { DoCast(me, SPELL_ENRAGE); Enraged = true; } else Enrage_Timer -= diff; //Checking if Jeklik is dead. If not we cast her Aspect if (CheckJeklik_Timer <= diff) { if (m_pInstance) { if (m_pInstance->GetData(TYPE_JEKLIK) != DONE) { if (AspectOfJeklik_Timer <= diff) { DoCast(me->getVictim(), SPELL_ASPECT_OF_JEKLIK); AspectOfJeklik_Timer = 10000 + rand()%4000; } else AspectOfJeklik_Timer -= diff; } } CheckJeklik_Timer = 1000; } else CheckJeklik_Timer -= diff; //Checking if Venoxis is dead. If not we cast his Aspect if (CheckVenoxis_Timer <= diff) { if (m_pInstance) { if (m_pInstance->GetData(TYPE_VENOXIS) != DONE) { if (AspectOfVenoxis_Timer <= diff) { DoCast(me->getVictim(), SPELL_ASPECT_OF_VENOXIS); AspectOfVenoxis_Timer = 8000; } else AspectOfVenoxis_Timer -= diff; } } CheckVenoxis_Timer = 1000; } else CheckVenoxis_Timer -= diff; //Checking if Marli is dead. If not we cast her Aspect if (CheckMarli_Timer <= diff) { if (m_pInstance) { if (m_pInstance->GetData(TYPE_MARLI) != DONE) { if (AspectOfMarli_Timer <= diff) { DoCast(me->getVictim(), SPELL_ASPECT_OF_MARLI); AspectOfMarli_Timer = 10000; } else AspectOfMarli_Timer -= diff; } } CheckMarli_Timer = 1000; } else CheckMarli_Timer -= diff; //Checking if Thekal is dead. If not we cast his Aspect if (CheckThekal_Timer <= diff) { if (m_pInstance) { if (m_pInstance->GetData(TYPE_THEKAL) != DONE) { if (AspectOfThekal_Timer <= diff) { DoCast(me, SPELL_ASPECT_OF_THEKAL); AspectOfThekal_Timer = 15000; } else AspectOfThekal_Timer -= diff; } } CheckThekal_Timer = 1000; } else CheckThekal_Timer -= diff; //Checking if Arlokk is dead. If yes we cast her Aspect if (CheckArlokk_Timer <= diff) { if (m_pInstance) { if (m_pInstance->GetData(TYPE_ARLOKK) != DONE) { if (AspectOfArlokk_Timer <= diff) { DoCast(me, SPELL_ASPECT_OF_ARLOKK); DoResetThreat(); AspectOfArlokk_Timer = 10000 + rand()%5000; } else AspectOfArlokk_Timer -= diff; } } CheckArlokk_Timer = 1000; } else CheckArlokk_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiVisibleTimer) { if (m_uiVisibleTimer <= uiDiff) { // Restore visibility m_creature->SetVisibility(VISIBILITY_ON); if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) AttackStart(pTarget); m_uiVisibleTimer = 0; } else m_uiVisibleTimer -= uiDiff; // Do nothing while vanished return; } // Troll phase if (!m_bIsPhaseTwo) { if (m_uiShadowWordPainTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_WORD_PAIN) == CAST_OK) m_uiShadowWordPainTimer = 15000; } } else m_uiShadowWordPainTimer -= uiDiff; if (m_uiMarkTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_MARK_ARLOKK, SELECT_FLAG_PLAYER)) { if (DoCastSpellIfCan(pTarget, SPELL_MARK_ARLOKK) == CAST_OK) { DoScriptText(SAY_FEAST_PANTHER, m_creature, pTarget); m_uiMarkTimer = 30000; } } } else m_uiMarkTimer -= uiDiff; if (m_uiGougeTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_GOUGE) == CAST_OK) { if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(), -80); m_uiGougeTimer = urand(17000, 27000); } } else m_uiGougeTimer -= uiDiff; // Transform to Panther if (m_uiTransformTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_PANTHER_TRANSFORM) == CAST_OK) { m_uiTransformTimer = 80000; m_bIsPhaseTwo = true; } } else m_uiTransformTimer -= uiDiff; } // Panther phase else { if (m_uiRavageTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_RAVAGE) == CAST_OK) m_uiRavageTimer = urand(10000, 15000); } else m_uiRavageTimer -= uiDiff; if (m_uiTrashTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_TRASH) == CAST_OK) m_uiTrashTimer = urand(13000, 15000); } else m_uiTrashTimer -= uiDiff; if (m_uiWhirlwindTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_WHIRLWIND) == CAST_OK) m_uiWhirlwindTimer = 15000; } else m_uiWhirlwindTimer -= uiDiff; if (m_uiVanishTimer < uiDiff) { // Note: this is a workaround because we do not know the real vanish spell m_creature->SetVisibility(VISIBILITY_OFF); DoResetThreat(); m_uiVanishTimer = 85000; m_uiVisibleTimer = 45000; } else m_uiVanishTimer -= uiDiff; // Transform back if (m_uiTransformTimer < uiDiff) { m_creature->RemoveAurasDueToSpell(SPELL_PANTHER_TRANSFORM); m_uiTransformTimer = 30000; m_bIsPhaseTwo = false; } else m_uiTransformTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { // Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // ArcaneExplosion_Timer if (m_uiArcaneExplosionTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_ARCANE_EXPLOSION) == CAST_OK) m_uiArcaneExplosionTimer = urand(8000, 18000); } else m_uiArcaneExplosionTimer -= uiDiff; // True Fullfilment if (m_uiFullFillmentTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) { if (DoCastSpellIfCan(pTarget, SPELL_TRUE_FULFILLMENT) == CAST_OK) m_uiFullFillmentTimer = urand(20000, 30000); } } else m_uiFullFillmentTimer -= uiDiff; // Blink_Timer if (m_uiBlinkTimer < uiDiff) { switch (urand(0, 2)) { case 0: DoCastSpellIfCan(m_creature, SPELL_TELEPORT_1); break; case 1: DoCastSpellIfCan(m_creature, SPELL_TELEPORT_2); break; case 2: DoCastSpellIfCan(m_creature, SPELL_TELEPORT_3); break; } DoResetThreat(); if (m_creature->GetVisibility() != VISIBILITY_ON) m_creature->SetVisibility(VISIBILITY_ON); m_uiBlinkTimer = urand(10000, 30000); } else m_uiBlinkTimer -= uiDiff; // Summon images at 75%, 50% and 25% if (!m_bIsImage && m_creature->GetHealthPercent() < m_fHpCheck) { if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_IMAGES) == CAST_OK) { DoScriptText(SAY_SPLIT, m_creature); m_fHpCheck -= 25.0f; // Teleport shortly after the images are summoned and set invisible to clear the selection (Workaround alert!!!) m_creature->SetVisibility(VISIBILITY_OFF); m_uiBlinkTimer = 2000; } } // If we are within range melee the target if (m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) DoMeleeAttackIfReady(); else { if (!m_creature->IsNonMeleeSpellCasted(false)) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, SPELL_EARTH_SHOCK); } } }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (!HasVanished) { if (DeadlyPoisonTimer <= diff) { DoCast(me->getVictim(), SPELL_DEADLY_POISON); DeadlyPoisonTimer = 15000 + rand()%31 * 1000; } else DeadlyPoisonTimer -= diff; if (AppearEnvenomTimer <= diff) // Cast Envenom. This is cast 4 seconds after Vanish is over { DoCast(me->getVictim(), SPELL_ENVENOM); AppearEnvenomTimer = 90000; } else AppearEnvenomTimer -= diff; if (VanishTimer <= diff) // Disappear and stop attacking, but follow a random unit { if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) { VanishTimer = 30000; AppearEnvenomTimer= 28000; HasVanished = true; me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoResetThreat(); // Chase a unit. Check before DoMeleeAttackIfReady prevents from attacking me->AddThreat(pTarget, 500000.0f); me->GetMotionMaster()->MoveChase(pTarget); } } else VanishTimer -= diff; DoMeleeAttackIfReady(); } else { if (VanishTimer <= diff) // Become attackable and poison current target { Unit *pTarget = me->getVictim(); DoCast(pTarget, SPELL_DEADLY_POISON); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoResetThreat(); me->AddThreat(pTarget, 3000.0f); // Make Veras attack his target for a while, he will cast Envenom 4 seconds after. DeadlyPoisonTimer += 6000; VanishTimer = 90000; AppearEnvenomTimer = 4000; HasVanished = false; } else VanishTimer -= diff; if (AppearEnvenomTimer <= diff) // Appear 2 seconds before becoming attackable (Shifting out of vanish) { me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveChase(me->getVictim()); me->SetVisible(true); AppearEnvenomTimer = 6000; } else AppearEnvenomTimer -= diff; } }
void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; //Check_Timer for the death of LorKhan and Zath. if (!WasDead && Check_Timer < diff) { if (m_pInstance) { if (m_pInstance->GetData(TYPE_LORKHAN) == SPECIAL) { //Resurrect LorKhan if (Creature *pLorKhan = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_LORKHAN))) { pLorKhan->SetStandState(UNIT_STAND_STATE_STAND); pLorKhan->setFaction(14); pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pLorKhan->SetHealth(int(pLorKhan->GetMaxHealth()*1.0)); m_pInstance->SetData(TYPE_LORKHAN, DONE); } } if (m_pInstance->GetData(TYPE_ZATH) == SPECIAL) { //Resurrect Zath if (Creature *pZath = m_creature->GetMap()->GetCreature(m_pInstance->GetData64(DATA_ZATH))) { pZath->SetStandState(UNIT_STAND_STATE_STAND); pZath->setFaction(14); pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pZath->SetHealth(int(pZath->GetMaxHealth()*1.0)); m_pInstance->SetData(TYPE_ZATH, DONE); } } } Check_Timer = 5000; }else Check_Timer -= diff; if (!PhaseTwo && MortalCleave_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_MORTALCLEAVE); MortalCleave_Timer = urand(15000, 20000); }else MortalCleave_Timer -= diff; if (!PhaseTwo && Silence_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_SILENCE); Silence_Timer = urand(20000, 25000); }else Silence_Timer -= diff; if (!PhaseTwo && !WasDead && m_creature->GetHealthPercent() < 5.0f) { m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetStandState(UNIT_STAND_STATE_SLEEP); m_creature->AttackStop(); if (m_pInstance) m_pInstance->SetData(TYPE_THEKAL, SPECIAL); WasDead = true; } //Thekal will transform to Tiger if he died and was not resurrected after 10 seconds. if (!PhaseTwo && WasDead) { if (Resurrect_Timer < diff) { DoCastSpellIfCan(m_creature,SPELL_TIGER_FORM); m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.00f); m_creature->SetStandState(UNIT_STAND_STATE_STAND); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetHealth(int(m_creature->GetMaxHealth()*1.0)); const CreatureInfo *cinfo = m_creature->GetCreatureInfo(); m_creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40))); m_creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40))); m_creature->UpdateDamagePhysical(BASE_ATTACK); DoResetThreat(); PhaseTwo = true; }else Resurrect_Timer -= diff; } if (m_creature->GetHealthPercent() == 100.0f && WasDead) { WasDead = false; } if (PhaseTwo) { if (Charge_Timer < diff) { if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) { DoCastSpellIfCan(target,SPELL_CHARGE); DoResetThreat(); AttackStart(target); } Charge_Timer = urand(15000, 22000); }else Charge_Timer -= diff; if (Frenzy_Timer < diff) { DoCastSpellIfCan(m_creature,SPELL_FRENZY); Frenzy_Timer = 30000; }else Frenzy_Timer -= diff; if (ForcePunch_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_SILENCE); ForcePunch_Timer = urand(16000, 21000); }else ForcePunch_Timer -= diff; if (SummonTigers_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_SUMMONTIGERS); SummonTigers_Timer = urand(10000, 14000); }else SummonTigers_Timer -= diff; if (m_creature->GetHealthPercent() < 11.0f && !Enraged) { DoCastSpellIfCan(m_creature, SPELL_ENRAGE); Enraged = true; } } if (m_creature->getVictim()) // TODO - use correct check here, this only prevents crash DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiPhase == PHASE_GROUND) { if (m_uiPhaseTimer) // After PHASE_SKELETON_3 we won't have a balcony phase { if (m_uiPhaseTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT) == CAST_OK) { DoScriptText(EMOTE_TELEPORT, m_creature); m_creature->GetMotionMaster()->MoveIdle(); m_uiPhase = PHASE_BALCONY; ++m_uiPhaseSub; switch (m_uiPhaseSub) // Set Duration of Skeleton phase { case PHASE_SKELETON_1: m_uiPhaseTimer = 70000; break; case PHASE_SKELETON_2: m_uiPhaseTimer = 97000; break; case PHASE_SKELETON_3: m_uiPhaseTimer = 120000; break; } return; } } else m_uiPhaseTimer -= uiDiff; } if (m_uiBlinkTimer < uiDiff) { static uint32 const auiSpellBlink[4] = { SPELL_BLINK_1, SPELL_BLINK_2, SPELL_BLINK_3, SPELL_BLINK_4 }; if (DoCastSpellIfCan(m_creature, auiSpellBlink[urand(0, 3)]) == CAST_OK) { DoResetThreat(); m_uiBlinkTimer = 25000; } } else m_uiBlinkTimer -= uiDiff; if (m_uiCurseTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_CURSE_PLAGUEBRINGER); m_uiCurseTimer = 28000; } else m_uiCurseTimer -= uiDiff; if (m_uiSummonTimer < uiDiff) { DoScriptText(SAY_SUMMON, m_creature); DoScriptText(EMOTE_WARRIOR, m_creature); // It's not very clear how many warriors it should summon, so we'll just leave it as random for now if (urand(0, 1)) { static uint32 const auiSpellSummonPlaguedWarrior[3] = { SPELL_SUMMON_WARRIOR_1, SPELL_SUMMON_WARRIOR_2, SPELL_SUMMON_WARRIOR_3 }; for (uint8 i = 0; i < 2; ++i) DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedWarrior[urand(0, 2)], CAST_TRIGGERED); } else { DoCastSpellIfCan(m_creature, SPELL_SUMMON_WARRIOR_THREE, CAST_TRIGGERED); } m_uiSummonTimer = 30000; } else m_uiSummonTimer -= uiDiff; DoMeleeAttackIfReady(); } else // PHASE_BALCONY { if (m_uiPhaseTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT_RETURN) == CAST_OK) { DoScriptText(EMOTE_TELEPORT_RETURN, m_creature); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); switch (m_uiPhaseSub) { case PHASE_SKELETON_1: m_uiPhaseTimer = 110000; break; case PHASE_SKELETON_2: m_uiPhaseTimer = 180000; break; case PHASE_SKELETON_3: m_uiPhaseTimer = 0; // Go Berserk after third Balcony Phase DoCastSpellIfCan(m_creature, SPELL_BERSERK, CAST_TRIGGERED); break; } m_uiPhase = PHASE_GROUND; return; } } else m_uiPhaseTimer -= uiDiff; if (m_uiSummonTimer < uiDiff) { DoScriptText(EMOTE_SKELETON, m_creature); static uint32 const auiSpellSummonPlaguedChampion[10] = { SPELL_SUMMON_CHAMP01, SPELL_SUMMON_CHAMP02, SPELL_SUMMON_CHAMP03, SPELL_SUMMON_CHAMP04, SPELL_SUMMON_CHAMP05, SPELL_SUMMON_CHAMP06, SPELL_SUMMON_CHAMP07, SPELL_SUMMON_CHAMP08, SPELL_SUMMON_CHAMP09, SPELL_SUMMON_CHAMP10 }; static uint32 const auiSpellSummonPlaguedGuardian[4] = { SPELL_SUMMON_GUARD01, SPELL_SUMMON_GUARD02, SPELL_SUMMON_GUARD03, SPELL_SUMMON_GUARD04 }; // A bit unclear how many in each sub phase switch (m_uiPhaseSub) { case PHASE_SKELETON_1: { for (uint8 i = 0; i < 4; ++i) DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedChampion[urand(0, 9)], CAST_TRIGGERED); break; } case PHASE_SKELETON_2: { for (uint8 i = 0; i < 2; ++i) { DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedChampion[urand(0, 9)], CAST_TRIGGERED); DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedGuardian[urand(0, 3)], CAST_TRIGGERED); } break; } case PHASE_SKELETON_3: { for (uint8 i = 0; i < 4; ++i) DoCastSpellIfCan(m_creature, auiSpellSummonPlaguedGuardian[urand(0, 3)], CAST_TRIGGERED); break; } } m_uiSummonTimer = 30000; } else m_uiSummonTimer -= uiDiff; } }
void UpdateAI(const uint32 diff) { if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_CURSE: DoCastAOE(SPELL_CURSE_PLAGUEBRINGER); events.ScheduleEvent(EVENT_CURSE, urand(50000, 60000)); return; case EVENT_WARRIOR: Talk(SAY_SUMMON); SummonUndead(MOB_WARRIOR, RAID_MODE(2, 3)); events.ScheduleEvent(EVENT_WARRIOR, 30000); return; case EVENT_BLINK: DoCastAOE(SPELL_CRIPPLE, true); DoCastAOE(SPELL_BLINK); DoResetThreat(); events.ScheduleEvent(EVENT_BLINK, 40000); return; case EVENT_BALCONY: me->SetReactState(REACT_PASSIVE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->AttackStop(); me->RemoveAllAuras(); me->NearTeleportTo(TELE_X, TELE_Y, TELE_Z, TELE_O); events.Reset(); events.ScheduleEvent(EVENT_WAVE, urand(2000, 5000)); waveCount = 0; return; case EVENT_WAVE: Talk(SAY_SUMMON); switch (balconyCount) { case 0: SummonUndead(MOB_CHAMPION, RAID_MODE(2, 4)); break; case 1: SummonUndead(MOB_CHAMPION, RAID_MODE(1, 2)); SummonUndead(MOB_GUARDIAN, RAID_MODE(1, 2)); break; case 2: SummonUndead(MOB_GUARDIAN, RAID_MODE(2, 4)); break; default:SummonUndead(MOB_CHAMPION, RAID_MODE(5, 10)); SummonUndead(MOB_GUARDIAN, RAID_MODE(5, 10));break; } ++waveCount; events.ScheduleEvent(waveCount < 2 ? EVENT_WAVE : EVENT_GROUND, urand(30000, 45000)); return; case EVENT_GROUND: { ++balconyCount; float x, y, z, o; me->GetHomePosition(x, y, z, o); me->NearTeleportTo(x, y, z, o); events.ScheduleEvent(EVENT_BALCONY, 110000); EnterPhaseGround(); return; } } } if (me->HasReactState(REACT_AGGRESSIVE)) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 lastDiff) { if (!m_pInstance || !m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (!PhaseTwo && m_creature->GetHealthPercent() < 50.0f) { m_creature->RemoveAurasDueToSpell(SPELL_BAT_FORM); m_creature->SetFly(false); m_creature->SetObjectScale(1.5f); DoResetThreat(); PhaseTwo = true; } // SUMMON_BATS if (m_creature->GetHealthPercent() > 50.0f) { if (SpawnBats_Timer < lastDiff) { DoScriptText(TEXTE_SUMMON_BATS, m_creature); for (uint8 i = 0; i < 6; ++i) { Creature* Bat = m_creature->SummonCreature(11368, -12294.0f + frand(0.0f, 5.0f), -1382.0f + frand(0.0f, 5.0f), 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (Bat && Bat->AI()) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) Bat->AI()->AttackStart(pTarget); } } SpawnBats_Timer = 60000; } else SpawnBats_Timer -= lastDiff; } // SPAWN_FLYING_BAT if (PhaseTwo) { if (SpawnFlyingBats_Timer < lastDiff) { if (Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { Creature* FlyingBat = m_creature->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30 * 60 * 1000); if (FlyingBat && FlyingBat->AI()) { FlyingBat->AI()->AttackStart(target); DoScriptText(SAY_RAIN_FIRE, m_creature); } } SpawnFlyingBats_Timer = 10000; } else SpawnFlyingBats_Timer -= lastDiff; } if (m_creature->IsNonMeleeSpellCasted(false)) { m_uiDiff_Add += lastDiff; return; } DoMeleeAttackIfReady(); // GlobalCD non ecoule. if (m_uiGlobalCooldown > lastDiff) { m_uiDiff_Add += lastDiff; m_uiGlobalCooldown -= lastDiff; return; } uint32 diff = m_uiDiff_Add + lastDiff; m_uiDiff_Add = 0; skillStarted = false; // BAT FORM COMBAT (PHASE 1) if (!PhaseTwo) { // CHARGE if (Charge_Timer < diff) { if (!skillStarted) { if (m_creature->CastSpellOnNearestVictim(SPELL_CHARGE, 10.0f, 40.0f, false)) { skillStarted = true; Charge_Timer = urand(15000, 30000); m_uiGlobalCooldown = 1000; // Suivit d'une explosion sonore. if (SonicBurst_Timer < 8000) SonicBurst_Timer = 1000; } else Charge_Timer = 2000; } } else Charge_Timer -= diff; // SCREECH if (m_Screech_Timer < diff) { if (!skillStarted) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SCREECH) == CAST_OK) { skillStarted = true; m_Screech_Timer = 30000; m_uiGlobalCooldown = 1000; } else Charge_Timer = 1000; } } else m_Screech_Timer -= diff; // SONICBURST if (SonicBurst_Timer < diff) { if (!skillStarted) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SONICBURST) == CAST_OK) { skillStarted = true; SonicBurst_Timer = urand(20000, 24000); m_uiGlobalCooldown = 1000; } } } else SonicBurst_Timer -= diff; // SWOOP if (Swoop_Timer < diff) { if (!skillStarted) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SWOOP) == CAST_OK) { skillStarted = true; Swoop_Timer = urand(12000, 15000); m_uiGlobalCooldown = 1000; } } } else Swoop_Timer -= diff; // PIERCEARMOR if (PierceArmor_Timer < diff) { if (!skillStarted) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_PIERCEARMOR) == CAST_OK) { skillStarted = true; PierceArmor_Timer = urand(16000, 18000); m_uiGlobalCooldown = 1000; } } } else PierceArmor_Timer -= diff; } // TROLL FORM COMBAT (PHASE 2) else { // SHADOW_WORD_PAIN if (ShadowWordPain_Timer < diff) { if (!skillStarted) { if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(target, SPELL_SHADOW_WORD_PAIN) == CAST_OK) { ShadowWordPain_Timer = urand(8000, 12000); m_uiGlobalCooldown = 1000; skillStarted = true; } } } } else ShadowWordPain_Timer -= diff; // GREATER_HEAL if (GreaterHeal_Timer < diff) { if (!skillStarted) { m_creature->InterruptNonMeleeSpells(false); if (DoCastSpellIfCan(m_creature, SPELL_GREATER_HEAL) == CAST_OK) { //m_creature->MonsterTextEmote(NOST_TEXT(TEXTE_GRAND_SORT_SOIN), NULL, true); DoScriptText(TEXTE_GRAND_SORT_SOIN, m_creature); skillStarted = true; GreaterHeal_Timer = urand(20000, 25000); } } } else GreaterHeal_Timer -= diff; // MIND_FLAY if (MindFlay_Timer < diff) { if (!skillStarted) { m_creature->InterruptNonMeleeSpells(false); if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(target, SPELL_MIND_FLAY) == CAST_OK) { MindFlay_Timer = urand(25000, 30000); skillStarted = true; } } } } else MindFlay_Timer -= diff; // CURSE_OF_BLOOD if (CurseOfBlood_Timer < diff) { if (!skillStarted) { m_creature->InterruptNonMeleeSpells(false); if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(target, SPELL_CURSE_OF_BLOOD) == CAST_OK) { CurseOfBlood_Timer = urand(25000, 30000); skillStarted = true; } } } } else CurseOfBlood_Timer -= diff; } }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (!m_bDemonForm) { //Whirlwind_Timer if (m_uiWhirlwind_Timer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_WHIRLWIND); m_uiWhirlwind_Timer = 30000; }else m_uiWhirlwind_Timer -= uiDiff; //Switch_Timer if (!m_bIsFinalForm) { if (m_uiSwitch_Timer < uiDiff) { DoScriptText(SAY_SWITCH_TO_DEMON, m_creature); if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) { //set false, so MoveChase is not triggered in AttackStart SetCombatMovement(false); m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->MoveIdle(); m_creature->StopMoving(); } //switch to demon form m_creature->SetDisplayId(MODEL_DEMON); DoResetThreat(); m_bDemonForm = true; m_uiInnerDemon_Timer = 15000; m_uiSwitch_Timer = 60000; }else m_uiSwitch_Timer -= uiDiff; } } else { //inner demon if (m_uiInnerDemon_Timer < uiDiff) { DoScriptText(SAY_INNER_DEMONS, m_creature); if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); DoCastSpellIfCan(m_creature, SPELL_INSIDIOUS_WHISPER); m_uiInnerDemon_Timer = 60000; }else m_uiInnerDemon_Timer -= uiDiff; //chaos blast spam if (!m_creature->IsNonMeleeSpellCasted(false)) m_creature->CastSpell(m_creature->getVictim(), SPELL_CHAOS_BLAST, false); //Switch_Timer if (m_uiSwitch_Timer < uiDiff) { if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); //switch to nightelf form m_creature->SetDisplayId(MODEL_NIGHTELF); if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE) m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); //set true SetCombatMovement(true); DoResetThreat(); m_bDemonForm = false; m_uiWhirlwind_Timer = 18500; m_uiSwitch_Timer = 45000; }else m_uiSwitch_Timer -= uiDiff; } if (!m_bIsFinalForm && m_creature->GetHealthPercent() < 15.0f) { DoScriptText(SAY_FINAL_FORM, m_creature); //at this point he divides himself in two parts m_creature->SummonCreature(NPC_SHADOW_LEO, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); if (m_bDemonForm) { if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); //switch to nightelf form m_creature->SetDisplayId(MODEL_NIGHTELF); if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE) m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); //set true SetCombatMovement(true); DoResetThreat(); m_bDemonForm = false; } m_bIsFinalForm = true; } //m_uiEnrage_Timer if (m_uiEnrage_Timer < uiDiff) { if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); DoCastSpellIfCan(m_creature, SPELL_ENRAGE); m_uiEnrage_Timer = MINUTE*5*IN_MILLISECONDS; }else m_uiEnrage_Timer -= uiDiff; if (!m_bDemonForm) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiEvadeCheckCooldown < uiDiff) { Creature* pEmalon = m_creature->GetMap()->GetCreature( m_pInstance->GetData64(DATA_EMALON)); if ((pEmalon && pEmalon->IsInEvadeMode()) || (m_creature->GetDistance2d(-219.119f, -289.037f) > 80.0f)) { EnterEvadeMode(); return; } m_uiEvadeCheckCooldown = 2000; } else m_uiEvadeCheckCooldown -= uiDiff; if (m_bTimeToDie) { FakeDeath(); return; } if (m_bDead) { if (m_uiRespawnTimer < uiDiff) { m_creature->SetHealth(m_creature->GetMaxHealth()); m_creature->SetVisibility(VISIBILITY_OFF); Init(); m_creature->MonsterTextEmote("%s appears to defend Emalon!", 0, true); m_creature->SetInCombatWithZone(); DoResetThreat(); if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) m_creature->GetMotionMaster()->MoveChase(pTarget); } else m_uiRespawnTimer -= uiDiff; return; } if (m_uiOverchargedStacksCheckTimer < uiDiff) { m_uiOverchargedStacksCheckTimer = 2000; Aura* pAuraOvercharged = m_creature->GetAura(SPELL_OVERCHARGED, EFFECT_INDEX_0); if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10) { DoCastSpellIfCan(m_creature, SPELL_OVERCHARGED_BLAST); m_bTimeToDie = true; return; } } else m_uiOverchargedStacksCheckTimer -= uiDiff; if (m_uiShockTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK); m_uiShockTimer = 8000+rand()%4000; } else m_uiShockTimer -= uiDiff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { // handle elementals on OOC timer if (m_uiElementalTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_WATER_ELEMENT) == CAST_OK) m_uiElementalTimer = 20000; } else m_uiElementalTimer -= uiDiff; return; } if (m_uiBeamInitTimer) { if (m_uiBeamInitTimer <= uiDiff) { DoHandleBeamHelpers(false); m_uiBeamInitTimer = 0; } else m_uiBeamInitTimer -= uiDiff; } // corrupted form if (m_bCorruptedForm) { if (m_uiVileSludgeTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_VILE_SLUDGE) == CAST_OK) m_uiVileSludgeTimer = 15000; } } else m_uiVileSludgeTimer -= uiDiff; // Change to clean if (m_uiPosCheckTimer < uiDiff) { float fPosX, fPosY, fPosZ; m_creature->GetCombatStartPosition(fPosX, fPosY, fPosZ); if (m_creature->IsWithinDist2d(fPosX, fPosY, SWITCH_RADIUS)) { DoScriptText(SAY_SWITCH_TO_CLEAN, m_creature); m_creature->RemoveAurasDueToSpell(SPELL_CORRUPTION); m_uiMarkCount = 0; DoHandleBeamHelpers(false); DoResetThreat(); DoSpawnAdds(); m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_FROST); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false); m_bCorruptedForm = false; m_uiMarkTimer = 15000; } m_uiPosCheckTimer = 2000; } else m_uiPosCheckTimer -= uiDiff; } // clean form else { if (m_uiWaterTombTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_WATER_TOMB) == CAST_OK) m_uiWaterTombTimer = 7000; } } else m_uiWaterTombTimer -= uiDiff; // Change to corrupt if (m_uiPosCheckTimer < uiDiff) { float fPosX, fPosY, fPosZ; m_creature->GetCombatStartPosition(fPosX, fPosY, fPosZ); if (!m_creature->IsWithinDist2d(fPosX, fPosY, SWITCH_RADIUS)) { if (DoCastSpellIfCan(m_creature, SPELL_CORRUPTION) == CAST_OK) { DoScriptText(SAY_SWITCH_TO_CORRUPT, m_creature); m_uiMarkCount = 0; DoHandleBeamHelpers(true); DoResetThreat(); DoSpawnAdds(); m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, false); m_bCorruptedForm = true; m_uiMarkTimer = 15000; } } m_uiPosCheckTimer = 2000; } else m_uiPosCheckTimer -= uiDiff; } // Apply mark debuff if (m_uiMarkTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bCorruptedForm ? aMarkCorruption[m_uiMarkCount] : aMarkHydross[m_uiMarkCount]) == CAST_OK) { ++m_uiMarkCount; m_uiMarkTimer = 15000; // limit the mark counter to 6 if (m_uiMarkCount == MAX_HYDROSS_MARKS) m_uiMarkCount = MAX_HYDROSS_MARKS - 1; } } else m_uiMarkTimer -= uiDiff; if (m_uiEnrageTimer) { if (m_uiEnrageTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) m_uiEnrageTimer = 0; } else m_uiEnrageTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (me->getVictim() && me->isAlive()) { if (HealthAbovePct(50)) { if (Charge_Timer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_CHARGE); AttackStart(target); } Charge_Timer = urand(15000, 30000); } else Charge_Timer -= diff; if (SonicBurst_Timer <= diff) { DoCast(me->getVictim(), SPELL_SONICBURST); SonicBurst_Timer = urand(8000, 13000); } else SonicBurst_Timer -= diff; if (Screech_Timer <= diff) { DoCast(me->getVictim(), SPELL_SCREECH); Screech_Timer = urand(18000, 26000); } else Screech_Timer -= diff; if (SpawnBats_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); Creature* Bat = NULL; Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (target && Bat) Bat ->AI()->AttackStart(target); Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (target && Bat) Bat ->AI()->AttackStart(target); Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (target && Bat) Bat ->AI()->AttackStart(target); Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (target && Bat) Bat ->AI()->AttackStart(target); Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (target && Bat) Bat ->AI()->AttackStart(target); Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (target && Bat) Bat ->AI()->AttackStart(target); SpawnBats_Timer = 60000; } else SpawnBats_Timer -= diff; } else { if (PhaseTwo) { if (PhaseTwo && ShadowWordPain_Timer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_SHADOW_WORD_PAIN); ShadowWordPain_Timer = urand(12000, 18000); } } ShadowWordPain_Timer -=diff; if (MindFlay_Timer <= diff) { DoCast(me->getVictim(), SPELL_MIND_FLAY); MindFlay_Timer = 16000; } MindFlay_Timer -=diff; if (ChainMindFlay_Timer <= diff) { me->InterruptNonMeleeSpells(false); DoCast(me->getVictim(), SPELL_CHAIN_MIND_FLAY); ChainMindFlay_Timer = urand(15000, 30000); } ChainMindFlay_Timer -=diff; if (GreaterHeal_Timer <= diff) { me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_GREATERHEAL); GreaterHeal_Timer = urand(25000, 35000); } GreaterHeal_Timer -=diff; if (SpawnFlyingBats_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target) return; Creature* FlyingBat = me->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (FlyingBat) FlyingBat->AI()->AttackStart(target); SpawnFlyingBats_Timer = urand(10000, 15000); } else SpawnFlyingBats_Timer -=diff; } else { me->SetDisplayId(15219); DoResetThreat(); PhaseTwo = true; } } DoMeleeAttackIfReady(); } }